From e3fa72d3073eed8fdad0f68180996110416c7c20 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Aug 2018 19:25:49 -0500 Subject: [PATCH 1/6] Added import markdown from URL funtionality --- pom.xml | 2 +- .../confluence/markdown/MarkdownMacro.java | 25 ++++++++++++++++--- src/main/resources/atlassian-plugin.xml | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 39dc27b..b5bd07f 100644 --- a/pom.xml +++ b/pom.xml @@ -104,7 +104,7 @@ 6.9.0 6.9.0 - 6.2.11 + 6.3.0 1.1 2.1.7 diff --git a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java index e7077bd..1e8f8f8 100644 --- a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java +++ b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java @@ -40,6 +40,8 @@ import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.options.MutableDataSet; +import java.net.*; +import java.io.*; //@Scanned public class MarkdownMacro extends BaseMacro implements Macro @@ -105,9 +107,26 @@ public class MarkdownMacro extends BaseMacro implements Macro Parser parser = Parser.builder(options).build(); HtmlRenderer renderer = HtmlRenderer.builder(options).build(); - - Node document = parser.parse(bodyContent); - String html = renderer.render(document ) + highlightjs; // "

This is Sparta

\n" + + String toParse = bodyContent; + if (parameters.get("URL") != null) { + try { + String urlParam = parameters.get("URL"); + URL importFrom = new URL(urlParam); + BufferedReader in = new BufferedReader( + new InputStreamReader(importFrom.openStream()) + ); + String inputLine; + toParse = ""; + while ((inputLine = in.readLine()) != null) { + toParse = toParse + "\n" + inputLine; + } + in.close(); + } + catch (IOException e) {} + } + Node document = parser.parse(toParse); + String html = renderer.render(document) + highlightjs; return html; } diff --git a/src/main/resources/atlassian-plugin.xml b/src/main/resources/atlassian-plugin.xml index 587e4da..82a6259 100644 --- a/src/main/resources/atlassian-plugin.xml +++ b/src/main/resources/atlassian-plugin.xml @@ -15,6 +15,7 @@ documentation-url="https://spec.commonmark.org/0.28/"> + Date: Wed, 8 Aug 2018 16:06:31 -0500 Subject: [PATCH 2/6] Removed URL parameter and updated MarkdownMacro.java to get URL from bodyContent. --- pom.xml | 2 ++ .../confluence/markdown/MarkdownMacro.java | 24 ++++++++++--------- src/main/resources/atlassian-plugin.xml | 5 +--- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index b5bd07f..61a5b82 100644 --- a/pom.xml +++ b/pom.xml @@ -90,6 +90,8 @@ ${confluence.version} ${confluence.data.version} + true + false diff --git a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java index 1e8f8f8..e748399 100644 --- a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java +++ b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java @@ -105,14 +105,13 @@ public class MarkdownMacro extends BaseMacro implements Macro " });\n" + ""; - Parser parser = Parser.builder(options).build(); - HtmlRenderer renderer = HtmlRenderer.builder(options).build(); - - String toParse = bodyContent; - if (parameters.get("URL") != null) { + if (bodyContent != null) { + Parser parser = Parser.builder(options).build(); + HtmlRenderer renderer = HtmlRenderer.builder(options).build(); + + String toParse = ""; try { - String urlParam = parameters.get("URL"); - URL importFrom = new URL(urlParam); + URL importFrom = new URL(bodyContent); BufferedReader in = new BufferedReader( new InputStreamReader(importFrom.openStream()) ); @@ -124,10 +123,13 @@ public class MarkdownMacro extends BaseMacro implements Macro in.close(); } catch (IOException e) {} - } - Node document = parser.parse(toParse); - String html = renderer.render(document) + highlightjs; - return html; + + Node document = parser.parse(toParse); + String html = renderer.render(document) + highlightjs; + return html; + }else { + return ""; + } } diff --git a/src/main/resources/atlassian-plugin.xml b/src/main/resources/atlassian-plugin.xml index 82a6259..e64267c 100644 --- a/src/main/resources/atlassian-plugin.xml +++ b/src/main/resources/atlassian-plugin.xml @@ -14,10 +14,7 @@ icon="/download/resources/com.atlassian.plugins.confluence.markdown.confluence-markdown-macro/images/pluginIcon.png" documentation-url="https://spec.commonmark.org/0.28/"> - - - - + Date: Wed, 8 Aug 2018 18:14:00 -0500 Subject: [PATCH 3/6] Seperated Markdown into two macros: Markdown and Markdown From URL --- pom.xml | 2 +- .../markdown/MarkdownFromURLMacro.java | 154 ++++++++++++++++++ .../confluence/markdown/MarkdownMacro.java | 33 +--- src/main/resources/atlassian-plugin.xml | 25 ++- .../markdown-from-url.properties | 3 + 5 files changed, 185 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java create mode 100644 src/main/resources/markdown-from-url-properties/markdown-from-url.properties diff --git a/pom.xml b/pom.xml index 61a5b82..d7b4abf 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ http://www.atlassian.com/ confluence-markdown-macro - This plugin provides a Markdown render macro for Confluence. + This plugin provides macros to render markdown for Confluence. atlassian-plugin diff --git a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java new file mode 100644 index 0000000..b4987b4 --- /dev/null +++ b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java @@ -0,0 +1,154 @@ +package com.atlassian.plugins.confluence.markdown; + +import com.atlassian.confluence.content.render.xhtml.ConversionContext; +import com.atlassian.confluence.content.render.xhtml.DefaultConversionContext; +import com.atlassian.confluence.content.render.xhtml.XhtmlException; +import com.atlassian.confluence.macro.Macro; +import com.atlassian.confluence.macro.MacroExecutionException; +import com.atlassian.confluence.xhtml.api.MacroDefinition; +import com.atlassian.confluence.xhtml.api.MacroDefinitionHandler; +import com.atlassian.confluence.xhtml.api.XhtmlContent; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import com.atlassian.renderer.RenderContext; +import com.atlassian.renderer.v2.RenderMode; +import com.atlassian.renderer.v2.macro.BaseMacro; +import com.atlassian.renderer.v2.macro.MacroException; + +//import com.atlassian.plugin.spring.scanner.annotation.component.Scanned; +import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport; +import com.atlassian.webresource.api.assembler.PageBuilderService; +import org.springframework.beans.factory.annotation.Autowired; + +import com.vladsch.flexmark.ast.Node; +import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughSubscriptExtension; +import com.vladsch.flexmark.ext.tables.TablesExtension; +import com.vladsch.flexmark.ext.ins.InsExtension; +import com.vladsch.flexmark.ext.definition.DefinitionExtension; +import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension; +import com.vladsch.flexmark.ext.footnotes.FootnoteExtension; +import com.vladsch.flexmark.ext.wikilink.WikiLinkExtension; +import com.vladsch.flexmark.ext.autolink.AutolinkExtension; +import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension; +import com.vladsch.flexmark.superscript.SuperscriptExtension; +import com.vladsch.flexmark.ext.youtube.embedded.YouTubeLinkExtension; +import com.vladsch.flexmark.html.HtmlRenderer; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.util.options.MutableDataSet; + +import java.net.*; +import java.io.*; + +//@Scanned +public class MarkdownFromURLMacro extends BaseMacro implements Macro +{ + + private final XhtmlContent xhtmlUtils; + + private PageBuilderService pageBuilderService; + + @Autowired + public MarkdownFromURLMacro(@ComponentImport PageBuilderService pageBuilderService, XhtmlContent xhtmlUtils) { + this.pageBuilderService = pageBuilderService; + this.xhtmlUtils = xhtmlUtils; + } + +// public MarkdownFromURLMacro(XhtmlContent xhtmlUtils) +// { +// this.xhtmlUtils = xhtmlUtils; +// } + + @Override + public BodyType getBodyType() + { + return BodyType.PLAIN_TEXT; + } + + @Override + public OutputType getOutputType() + { + return OutputType.BLOCK; + } + + @Override + public String execute(Map parameters, String bodyContent, ConversionContext conversionContext) throws MacroExecutionException + { + + + pageBuilderService.assembler().resources().requireWebResource("com.atlassian.plugins.confluence.markdown.confluence-markdown-macro:highlightjs"); + + MutableDataSet options = new MutableDataSet(); + + options.set(Parser.EXTENSIONS, Arrays.asList( + TablesExtension.create(), + StrikethroughSubscriptExtension.create(), + InsExtension.create(), + TaskListExtension.create(), + FootnoteExtension.create(), + WikiLinkExtension.create(), + DefinitionExtension.create(), + AnchorLinkExtension.create(), + AutolinkExtension.create(), + SuperscriptExtension.create(), + YouTubeLinkExtension.create() + + )); + + + String highlightjs = ""; + + if (bodyContent != null) { + Parser parser = Parser.builder(options).build(); + HtmlRenderer renderer = HtmlRenderer.builder(options).build(); + + String toParse = ""; + try { + URL importFrom = new URL(bodyContent); + BufferedReader in = new BufferedReader( + new InputStreamReader(importFrom.openStream()) + ); + String inputLine; + toParse = ""; + while ((inputLine = in.readLine()) != null) { + toParse = toParse + "\n" + inputLine; + } + in.close(); + } + catch (IOException e) {} + + Node document = parser.parse(toParse); + String html = renderer.render(document) + highlightjs; + return html; + }else { + return ""; + } + + } + + @Override + public boolean hasBody() { + return true; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public RenderMode getBodyRenderMode() { + return RenderMode.NO_RENDER; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String execute(Map map, String s, RenderContext renderContext) throws MacroException { + try { + return execute(map, s, new DefaultConversionContext(renderContext)); + } catch (MacroExecutionException e) { + throw new MacroException(e.getMessage(),e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java index e748399..e7077bd 100644 --- a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java +++ b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownMacro.java @@ -40,8 +40,6 @@ import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.options.MutableDataSet; -import java.net.*; -import java.io.*; //@Scanned public class MarkdownMacro extends BaseMacro implements Macro @@ -105,31 +103,12 @@ public class MarkdownMacro extends BaseMacro implements Macro " });\n" + ""; - if (bodyContent != null) { - Parser parser = Parser.builder(options).build(); - HtmlRenderer renderer = HtmlRenderer.builder(options).build(); - - String toParse = ""; - try { - URL importFrom = new URL(bodyContent); - BufferedReader in = new BufferedReader( - new InputStreamReader(importFrom.openStream()) - ); - String inputLine; - toParse = ""; - while ((inputLine = in.readLine()) != null) { - toParse = toParse + "\n" + inputLine; - } - in.close(); - } - catch (IOException e) {} - - Node document = parser.parse(toParse); - String html = renderer.render(document) + highlightjs; - return html; - }else { - return ""; - } + Parser parser = Parser.builder(options).build(); + HtmlRenderer renderer = HtmlRenderer.builder(options).build(); + + Node document = parser.parse(bodyContent); + String html = renderer.render(document ) + highlightjs; // "

This is Sparta

\n" + return html; } diff --git a/src/main/resources/atlassian-plugin.xml b/src/main/resources/atlassian-plugin.xml index e64267c..0acb029 100644 --- a/src/main/resources/atlassian-plugin.xml +++ b/src/main/resources/atlassian-plugin.xml @@ -7,24 +7,41 @@ images/pluginLogo.png true - - + - - + + + + + + + + + + diff --git a/src/main/resources/markdown-from-url-properties/markdown-from-url.properties b/src/main/resources/markdown-from-url-properties/markdown-from-url.properties new file mode 100644 index 0000000..57128de --- /dev/null +++ b/src/main/resources/markdown-from-url-properties/markdown-from-url.properties @@ -0,0 +1,3 @@ +com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.label=Markdown From URL +com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.desc=This macro imports Markdown from a URL and renders it into HTML. +com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.body.desc=Type URL here \ No newline at end of file From 804c46098115f273c001c15c72cc7fc34be9f4c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Aug 2018 18:20:10 -0500 Subject: [PATCH 4/6] Deleted code meant for testing. --- .../markdown-from-url-properties/markdown-from-url.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/markdown-from-url-properties/markdown-from-url.properties b/src/main/resources/markdown-from-url-properties/markdown-from-url.properties index 57128de..9fe6aa3 100644 --- a/src/main/resources/markdown-from-url-properties/markdown-from-url.properties +++ b/src/main/resources/markdown-from-url-properties/markdown-from-url.properties @@ -1,3 +1,2 @@ com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.label=Markdown From URL -com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.desc=This macro imports Markdown from a URL and renders it into HTML. -com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.body.desc=Type URL here \ No newline at end of file +com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.desc=This macro imports Markdown from a URL and renders it into HTML. \ No newline at end of file From 27dcf6d8bf7b411c0a8473105942182ff34edb9c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2018 16:27:26 -0600 Subject: [PATCH 5/6] Added error handling for a variety of errors. --- .../markdown/MarkdownFromURLMacro.java | 95 ++++++++++++------- .../markdown-from-url.properties | 2 +- 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java index b4987b4..0b6a390 100644 --- a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java +++ b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java @@ -24,6 +24,7 @@ import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport; import com.atlassian.webresource.api.assembler.PageBuilderService; import org.springframework.beans.factory.annotation.Autowired; + import com.vladsch.flexmark.ast.Node; import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughSubscriptExtension; import com.vladsch.flexmark.ext.tables.TablesExtension; @@ -40,6 +41,7 @@ import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.options.MutableDataSet; + import java.net.*; import java.io.*; @@ -78,37 +80,44 @@ public class MarkdownFromURLMacro extends BaseMacro implements Macro public String execute(Map parameters, String bodyContent, ConversionContext conversionContext) throws MacroExecutionException { - - pageBuilderService.assembler().resources().requireWebResource("com.atlassian.plugins.confluence.markdown.confluence-markdown-macro:highlightjs"); - - MutableDataSet options = new MutableDataSet(); - - options.set(Parser.EXTENSIONS, Arrays.asList( - TablesExtension.create(), - StrikethroughSubscriptExtension.create(), - InsExtension.create(), - TaskListExtension.create(), - FootnoteExtension.create(), - WikiLinkExtension.create(), - DefinitionExtension.create(), - AnchorLinkExtension.create(), - AutolinkExtension.create(), - SuperscriptExtension.create(), - YouTubeLinkExtension.create() - - )); - - - String highlightjs = ""; - if (bodyContent != null) { + pageBuilderService.assembler().resources().requireWebResource("com.atlassian.plugins.confluence.markdown.confluence-markdown-macro:highlightjs"); + + MutableDataSet options = new MutableDataSet(); + + options.set(Parser.EXTENSIONS, Arrays.asList( + TablesExtension.create(), + StrikethroughSubscriptExtension.create(), + InsExtension.create(), + TaskListExtension.create(), + FootnoteExtension.create(), + WikiLinkExtension.create(), + DefinitionExtension.create(), + AnchorLinkExtension.create(), + AutolinkExtension.create(), + SuperscriptExtension.create(), + YouTubeLinkExtension.create() + + )); + + + String highlightjs = ""; + + class privateRepositoryException extends Exception { + public privateRepositoryException(String message) { + super(message); + } + } + Parser parser = Parser.builder(options).build(); HtmlRenderer renderer = HtmlRenderer.builder(options).build(); + String exceptionsToReturn = ""; + String html = ""; String toParse = ""; try { URL importFrom = new URL(bodyContent); @@ -116,21 +125,39 @@ public class MarkdownFromURLMacro extends BaseMacro implements Macro new InputStreamReader(importFrom.openStream()) ); String inputLine; - toParse = ""; while ((inputLine = in.readLine()) != null) { toParse = toParse + "\n" + inputLine; } in.close(); + toParse = toParse.trim(); + if (toParse.startsWith("\n\n OpenID transaction in progress")) { + throw new privateRepositoryException("Cannot import from private repository."); + }else { + Node document = parser.parse(toParse); + html = renderer.render(document) + highlightjs; + } + } + catch (MalformedURLException u) { + exceptionsToReturn = exceptionsToReturn + "Error with Markdown From URL macro: Invalid URL.
Please enter a valid URL. If you are not trying to import markdown from a URL, use the Markdown macro instead of the Markdown from URL macro.
For support visit our Q&A in the Atlassian Community. You can ask a new question by clicking the \"Create\" button on the top right of the Q&A.
"; + } + catch (privateRepositoryException p) { + exceptionsToReturn = exceptionsToReturn + "Error with Markdown From URL macro: Importing from private Bitbucket repositories is not supported.
Please make your repository public before importing. Alternatively, you can copy and paste your markdown into the Markdown macro.
If you are allowed access, you can find the markdown file here.
For support visit our Q&A in the Atlassian Community. You can ask a new question by clicking the \"Create\" button on the top right of the Q&A.
"; + } + catch (FileNotFoundException f) { + exceptionsToReturn = exceptionsToReturn + "Error with Markdown From URL macro: URL does not exist.
" + bodyContent + "
Please double check your URL. Perhaps you made a typo or perhaps the page has been moved.
This can also be caused by changing the Github repository containing the file from public to private. If this is the case go back to the raw file and re-copy the link.
For support visit our Q&A in the Atlassian Community. You can ask a new question by clicking the \"Create\" button on the top right of the Q&A.
"; + } + catch (IOException e) { + exceptionsToReturn = exceptionsToReturn + "Error with Markdown From URL macro: Unexpected error.
" + e.toString() + "
For support visit our Q&A in the Atlassian Community. You can ask a new question by clicking the \"Create\" button on the top right of the Q&A.
"; + } + finally { + if (exceptionsToReturn != "") { + html = "

" + exceptionsToReturn + "

"; + } + return html; } - catch (IOException e) {} - - Node document = parser.parse(toParse); - String html = renderer.render(document) + highlightjs; - return html; }else { return ""; } - } @Override diff --git a/src/main/resources/markdown-from-url-properties/markdown-from-url.properties b/src/main/resources/markdown-from-url-properties/markdown-from-url.properties index 9fe6aa3..503e17c 100644 --- a/src/main/resources/markdown-from-url-properties/markdown-from-url.properties +++ b/src/main/resources/markdown-from-url-properties/markdown-from-url.properties @@ -1,2 +1,2 @@ com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.label=Markdown From URL -com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.desc=This macro imports Markdown from a URL and renders it into HTML. \ No newline at end of file +com.atlassian.plugins.confluence.markdown.confluence-markdown-macro.markdown-from-url.desc=This macro dynamically imports Markdown from a URL and renders it into HTML. \ No newline at end of file From 1fddfb3f1702cd949734ca629bdffcf7690e5251 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Sep 2018 11:16:01 -0600 Subject: [PATCH 6/6] Fixed bug with syntax highlighting when importing from URL --- .../plugins/confluence/markdown/MarkdownFromURLMacro.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java index 0b6a390..386c139 100644 --- a/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java +++ b/src/main/java/com/atlassian/plugins/confluence/markdown/MarkdownFromURLMacro.java @@ -102,7 +102,7 @@ public class MarkdownFromURLMacro extends BaseMacro implements Macro String highlightjs = "";