");
+ html.append(escaped ? code : escape(code, true));
+ html.append("\n
");
+ } else {
+ html.append("");
+ html.append(escaped ? code : escape(code, true));
+ html.append("\n
");
+ }
+ }
+
+ @Override
+ public void blockquote(String quote) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void html(String html) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void heading(String text, int level, String raw) {
+ html.append(""); + } + + @Override + public void endParagraph() { + html.append("
\n"); + } + + @Override + public void table(String header, String body) { + // TODO Auto-generated method stub + + } + + @Override + public void tablerow(String content) { + // TODO Auto-generated method stub + + } + + @Override + public void tablecell(String content, String flags) { + // TODO Auto-generated method stub + + } + + @Override + public void startEm() { + html.append(""); + } + + @Override + public void endEm() { + html.append(""); + } + + @Override + public void startStrong() { + html.append(""); + } + + @Override + public void endStrong() { + html.append(""); + } + + @Override + public void codespan(String text) { + html.append("");
+ html.append(text);
+ html.append("
");
+ }
+
+ @Override
+ public void br() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void del(String text) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void link(String href, String title, String text) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void image(String href, String title, String text) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void text(String text) {
+ html.append(text);
+ }
+
+ @Override
+ public String toString() {
+ return html.toString();
+ }
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Helpers.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Helpers.java
new file mode 100644
index 000000000..4646fb0a6
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Helpers.java
@@ -0,0 +1,22 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public class Helpers {
+
+ public static String escape(String html) {
+ return escape(html, false);
+ }
+
+ public static String escape(String html, boolean encode) {
+ return html
+ .replaceAll(!encode ? "&(?!#?\\w+;)" : "&", "&")
+ .replaceAll("<", "<")
+ .replaceAll(">", ">")
+ .replaceAll("\"", """)
+ .replaceAll("'", "'");
+ }
+
+ public static boolean isEmpty(String s) {
+ return s == null || s.length() < 1;
+ }
+
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/IRenderer.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/IRenderer.java
new file mode 100644
index 000000000..f08dc0403
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/IRenderer.java
@@ -0,0 +1,51 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public interface IRenderer {
+
+ void code(String code, String lang, boolean escaped);
+
+ void blockquote(String quote);
+
+ void html(String html);
+
+ void heading(String text, int level, String raw);
+
+ void hr();
+
+ void list(String body, boolean ordered);
+
+ void listitem(String text);
+
+ void startParagraph();
+
+ void endParagraph();
+
+ void table(String header, String body);
+
+ void tablerow(String content);
+
+ void tablecell(String content, String flags);
+
+ void startEm();
+
+ void endEm();
+
+ void startStrong();
+
+ void endStrong();
+
+ void codespan(String text);
+
+ void br();
+
+ void del(String text);
+
+ void link(String href, String title, String text);
+
+ void image(String href, String title, String text);
+
+ void text(String text);
+
+
+
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/InlineLexer.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/InlineLexer.java
new file mode 100644
index 000000000..1ad321237
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/InlineLexer.java
@@ -0,0 +1,79 @@
+package org.eclipse.tm4e.markdown.marked;
+
+import static org.eclipse.tm4e.markdown.marked.Helpers.escape;
+import static org.eclipse.tm4e.markdown.marked.Helpers.isEmpty;
+
+import java.util.regex.Matcher;
+public class InlineLexer {
+
+ private Options options;
+ private InlineRules rules;
+ private final IRenderer renderer;
+
+ public InlineLexer(Object links, Options options, IRenderer renderer) {
+ this.options = options != null ? options : Options.DEFAULTS;
+ // this.links = links;
+ this.rules = InlineRules.normal;
+ this.renderer = renderer;
+ // this.renderer = this.options.renderer || new Renderer;
+ // this.renderer.options = this.options;
+
+ // if (!this.links) {
+ // throw new
+ // Error('Tokens array requires a `links` property.');
+ // }
+
+ if (this.options.gfm) {
+ if (this.options.breaks) {
+ this.rules = InlineRules.breaks;
+ } else {
+ this.rules = InlineRules.gfm;
+ }
+ } else if (this.options.pedantic) {
+ this.rules = InlineRules.pedantic;
+ }
+ }
+
+ public void output(String src) {
+ Matcher cap = null;
+ while (!isEmpty(src)) {
+
+ // strong
+ if ((cap = this.rules.strong.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ this.renderer.startStrong();
+ this.output(!isEmpty(cap.group(2)) ? cap.group(2) : cap.group(1));
+ this.renderer.endStrong();
+ continue;
+ }
+
+ // em
+ if ((cap = this.rules.em.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ this.renderer.startEm();
+ this.output(!isEmpty(cap.group(2)) ? cap.group(2) : cap.group(1));
+ this.renderer.endEm();
+ continue;
+ }
+
+ // code
+ if ((cap = this.rules.code.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ this.renderer.codespan(escape(cap.group(2), true));
+ continue;
+ }
+
+ // text
+ if ((cap = this.rules.text.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ this.renderer.text(escape(this.smartypants(cap.group(0))));
+ continue;
+ }
+ }
+ }
+
+ private String smartypants(String text) {
+ return text;
+ }
+
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/InlineRules.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/InlineRules.java
new file mode 100644
index 000000000..e6054841c
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/InlineRules.java
@@ -0,0 +1,94 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public class InlineRules {
+
+ private static final String INLINE_INSIDE = "(?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*";
+ private static final String INLINE_HREF = "\\s*([\\s\\S]*?)>?(?:\\s+['\"]([\\s\\S]*?)['\"])?\\s*";
+
+ public static final InlineRules normal = normal();
+
+ public static final InlineRules pedantic = pedantic();
+
+ public static final InlineRules gfm = gfm();
+
+ public static final InlineRules breaks = breaks();
+
+ public final RegExp escape;
+ public final RegExp autolink;
+ public final RegExp url;
+ public final RegExp tag;
+ public final RegExp link;
+ public final RegExp reflink;
+ public final RegExp nolink;
+ public final RegExp strong;
+ public final RegExp em;
+ public final RegExp code;
+ public final RegExp br;
+ public final RegExp del;
+ public final RegExp text;
+
+ public InlineRules(RegExp escape, RegExp autolink, RegExp url, RegExp tag, RegExp link, RegExp reflink,
+ RegExp nolink, RegExp strong, RegExp em, RegExp code, RegExp br, RegExp del, RegExp text) {
+ this.escape = escape;
+ this.autolink = autolink;
+ this.url = url;
+ this.tag = tag;
+ this.link = link;
+ this.reflink = reflink;
+ this.nolink = nolink;
+ this.strong = strong;
+ this.em = em;
+ this.code = code;
+ this.br = br;
+ this.del = del;
+ this.text = text;
+ }
+
+ private static InlineRules inline() {
+ RegExp escape = new RegExp("^\\\\([\\\\`*{}\\[\\]()#+\\-.!_>])");
+ RegExp autolink = new RegExp("^<([^ >]+(@|:\\/)[^ >]+)>");
+ RegExp url = RegExp.noop();
+ RegExp tag = new RegExp("^|^<\\/?\\w+(?:\"[^\"]*\"|'[^']*'|[^'\">])*?>");
+ RegExp link = new RegExp("^!?\\[(inside)\\]\\(href\\)");
+ RegExp reflink = new RegExp("^!?\\[(inside)\\]\\s*\\[([^\\]]*)\\]");
+ RegExp nolink = new RegExp("^!?\\[((?:\\[[^\\]]*\\]|[^\\[\\]])*)\\]");
+ RegExp strong = new RegExp("^__([\\s\\S]+?)__(?!_)|^\\*\\*([\\s\\S]+?)\\*\\*(?!\\*)");
+ RegExp em = new RegExp("^\\b_((?:[^_]|__)+?)_\\b|^\\*((?:\\*\\*|[\\s\\S])+?)\\*(?!\\*)");
+ RegExp code = new RegExp("^(`+)\\s*([\\s\\S]*?[^`])\\s*\\1(?!`)");
+ RegExp br = new RegExp("^ {2,}\\n(?!\\s*$)");
+ RegExp del = RegExp.noop();
+ RegExp text = new RegExp("^[\\s\\S]+?(?=[\\\\ 1) {
+ this.tokens.add(new Token(TokenType.space));
+ }
+ }
+
+ // code
+ // if ((cap = this.rules.code.exec(src)) != null) {
+ // src = src.substring(cap.group(0).length());
+ // cap = cap.group(0).matches("^ {4}", "");
+ // String text = !this.options.pedantic
+ // ? cap.replace(/\n+$/, '')
+ // : cap;
+ // this.tokens.add(new Token(TokenType.type));
+ // continue;
+ // }
+
+ // fences (gfm)
+ if ((cap = this.rules.fences.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ String lang = cap.group(2);
+ String text = !isEmpty(cap.group(3)) ? cap.group(3) : "";
+ this.tokens.add(new Token(TokenType.code, lang, text));
+ continue;
+ }
+
+ // heading
+ if ((cap = this.rules.heading.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ String text = cap.group(2);
+ int depth = cap.group(1).length();
+ this.tokens.add(new Token(TokenType.heading, text, depth));
+ continue;
+ }
+
+ // table no leading pipe (gfm)
+ // TODO
+
+ // lheading
+ if ((cap = this.rules.lheading.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ String text = cap.group(1);
+ int depth = cap.group(2).equals("=") ? 1 : 2;
+ this.tokens.add(new Token(TokenType.heading, text, depth));
+ continue;
+ }
+
+ // hr
+ if ((cap = this.rules.hr.exec(src)) != null) {
+ src = src.substring(cap.group(0).length());
+ this.tokens.add(new Token(TokenType.hr));
+ continue;
+ }
+
+ // top-level paragraph
+ if (top && ((cap = this.rules.paragraph.exec(src)) != null)) {
+ src = src.substring(cap.group(0).length());
+ String text = cap.group(1).charAt(cap.group(1).length() - 1) == '\n' ? cap.group(1) : cap.group(1);
+ this.tokens.add(new Token(TokenType.paragraph, text));
+ continue;
+ }
+ }
+ return this.tokens;
+ }
+
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Marked.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Marked.java
new file mode 100644
index 000000000..76cc646fe
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Marked.java
@@ -0,0 +1,13 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public class Marked {
+
+ public static IRenderer parse(String src) {
+ return process(src, null);
+ }
+
+ public static IRenderer process(String src, Options opt) {
+
+ return Parser.parse(Lexer.lex(src, opt), opt);
+ }
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Options.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Options.java
new file mode 100644
index 000000000..229594d20
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Options.java
@@ -0,0 +1,10 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public class Options {
+
+ public static final Options DEFAULTS = new Options();
+ public boolean gfm = true;
+ public boolean breaks;
+ public boolean pedantic;
+ public boolean tables;
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Parser.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Parser.java
new file mode 100644
index 000000000..201c71445
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Parser.java
@@ -0,0 +1,70 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public class Parser {
+
+ private Tokens tokens;
+ private Token token;
+ private Options options;
+ private InlineLexer inline;
+ private IRenderer renderer;
+
+ public Parser(Options options) {
+ this.tokens = new Tokens();
+ this.token = null;
+ this.options = options != null ? options : Options.DEFAULTS;
+ this.renderer = new HTMLRenderer();
+ }
+
+ public static IRenderer parse(Tokens src, Options options) {
+ Parser parser = new Parser(options);
+ return parser.parse(src);
+ }
+
+ private IRenderer parse(Tokens src) {
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
+ this.tokens = src.reverse();
+
+ // var out = '';
+ while (this.next()) {
+ // out += this.tok();
+ this.tok();
+ }
+
+ return renderer;
+ }
+
+ /**
+ * Next Token
+ */
+ private boolean next() {
+ return ((this.token = this.tokens.pop()) != null);
+ }
+
+ /**
+ * Parse Current Token
+ */
+ private void tok() {
+ switch (this.token.type) {
+ case space:
+ break;
+ case hr:
+ this.renderer.hr();
+ break;
+ case heading:
+ // this.renderer.heading(this.inline.output(this.token.text),
+ // this.token.depth, this.token.text);
+ this.renderer.heading(this.token.text, this.token.depth, this.token.text);
+ break;
+ case code:
+ this.renderer.code(this.token.text, this.token.lang, this.token.escaped);
+ break;
+ case paragraph:
+ this.renderer.startParagraph();
+ this.inline.output(this.token.text);
+ this.renderer.endParagraph();
+ break;
+ }
+
+ }
+
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/RegExp.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/RegExp.java
new file mode 100644
index 000000000..05e65b599
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/RegExp.java
@@ -0,0 +1,57 @@
+package org.eclipse.tm4e.markdown.marked;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RegExp {
+
+ protected String source;
+ private Pattern pattern;
+
+ public RegExp(String source) {
+ this.source = source;
+ }
+
+ public Matcher exec(String s) {
+ if (source == null) {
+ return null;
+ }
+ if (pattern == null) {
+ pattern = Pattern.compile(source);
+ }
+ Matcher matcher = pattern.matcher(s);
+ if (matcher.find()) {
+ return matcher;
+ }
+ return null;
+ }
+
+ public RegExp replace(String name, RegExp val) {
+ return replace(name, val.source);
+ }
+
+ public RegExp replace(String name, String val) {
+ if (name == null)
+ return new RegExp(this.source);
+ val = val.replaceAll("(^|[^\\[])\\^", "$1");
+ this.source = this.source.replaceFirst(name, Matcher.quoteReplacement(val));
+ return this;
+ }
+
+ public RegExp replaceAll(String name, RegExp val) {
+ return replaceAll(name, val.source);
+ }
+
+ public RegExp replaceAll(String name, String val) {
+ if (name == null)
+ return new RegExp(this.source);
+ val = val.replaceAll("(^|[^\\[])\\^", "$1");
+ this.source = this.source.replaceAll(name, Matcher.quoteReplacement(val));
+ return this;
+ }
+
+ public static final RegExp noop() {
+ return new RegExp(null);
+ };
+
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Token.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Token.java
new file mode 100644
index 000000000..26124c31b
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Token.java
@@ -0,0 +1,34 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public class Token {
+
+ public final TokenType type;
+ public final String text;
+ public final int depth;
+ public final String lang;
+ public final boolean escaped;
+
+ public Token(TokenType type) {
+ this(type, null);
+ }
+
+ public Token(TokenType type, String text) {
+ this(type, text, -1);
+ }
+
+ public Token(TokenType type, String text, int depth) {
+ this(type, text, depth, null, false);
+ }
+
+ public Token(TokenType type, String lang, String text) {
+ this(type, text, -1, lang, false);
+ }
+
+ private Token(TokenType type, String text, int depth, String lang, boolean escaped) {
+ this.type = type;
+ this.text = text;
+ this.depth = depth;
+ this.lang = lang;
+ this.escaped = escaped;
+ }
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/TokenType.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/TokenType.java
new file mode 100644
index 000000000..35b54e728
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/TokenType.java
@@ -0,0 +1,6 @@
+package org.eclipse.tm4e.markdown.marked;
+
+public enum TokenType {
+
+ space, hr, heading, code, table, blockquote_start, blockquote_end, list_start, list_end, list_item_start, list_item_end, loose_item_start, html, paragraph, text;
+}
diff --git a/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Tokens.java b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Tokens.java
new file mode 100644
index 000000000..658ff5980
--- /dev/null
+++ b/org.eclipse.tm4e.markdown/src/main/java/org/eclipse/tm4e/markdown/marked/Tokens.java
@@ -0,0 +1,22 @@
+package org.eclipse.tm4e.markdown.marked;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class Tokens extends ArrayList