Closes #7
diff --git a/core/src/main/java/org/tautua/markdownpapers/HtmlEmitter.java b/core/src/main/java/org/tautua/markdownpapers/HtmlEmitter.java
index de98d25..97ae31d 100644
--- a/core/src/main/java/org/tautua/markdownpapers/HtmlEmitter.java
+++ b/core/src/main/java/org/tautua/markdownpapers/HtmlEmitter.java
@@ -30,7 +30,6 @@
*/
public class HtmlEmitter implements Visitor {
private Appendable buffer;
- private Document document;
private Stack<Node> markupStack = new DequeStack<Node>();
public HtmlEmitter(Appendable buffer) {
@@ -71,7 +70,6 @@
}
public void visit(Document node) {
- document = node;
visitChildrenAndAppendSeparator(node, EOL);
}
@@ -150,7 +148,10 @@
@Override
public void visit(LineBreak node) {
- append("<br/>");
+ Line l = (Line) node.jjtGetParent();
+ if(!l.isEnding()) {
+ append("<br/>");
+ }
}
public void visit(Link node) {
@@ -220,24 +221,17 @@
}
public void visit(Paragraph node) {
- if (containsHR(node)) {
- visitChildrenAndAppendSeparator(node, EOL);
- } else if (isMarkup(node)) {
- switchToMarkup(node);
- visitChildrenAndAppendSeparator(node, EOL);
- } else {
- Node parent = node.jjtGetParent();
- if(parent instanceof Item) {
- if (!((Item)parent).isLoose()) {
- visitChildrenAndAppendSeparator(node, EOL);
- return;
- }
+ Node parent = node.jjtGetParent();
+ if(parent instanceof Item) {
+ if (!((Item)parent).isLoose()) {
+ visitChildrenAndAppendSeparator(node, EOL);
+ return;
}
- append("<p>");
- visitChildrenAndAppendSeparator(node, EOL);
- append("</p>");
- append(EOL);
}
+ append("<p>");
+ visitChildrenAndAppendSeparator(node, EOL);
+ append("</p>");
+ append(EOL);
}
public void visit(Ruler node) {
@@ -257,6 +251,28 @@
throw new IllegalArgumentException("can not process this element");
}
+ public void visit(Tag node) {
+ append("<");
+ append(node.getName());
+ for (TagAttribute attribute : node.getAttributes()) {
+ append(SPACE);
+ append(attribute.getName());
+ append("=\"");
+ append(attribute.getValue());
+ append("\"");
+ }
+
+ if(node.jjtGetNumChildren() == 0) {
+ append("/>");
+ } else {
+ append(">");
+ node.childrenAccept(this);
+ append("</");
+ append(node.getName());
+ append(">");
+ }
+ }
+
public void visit(EmptyTag node) {
append("<");
append(node.getName());
diff --git a/core/src/main/java/org/tautua/markdownpapers/Markdown.java b/core/src/main/java/org/tautua/markdownpapers/Markdown.java
index 090b4dc..fe4d9b1 100644
--- a/core/src/main/java/org/tautua/markdownpapers/Markdown.java
+++ b/core/src/main/java/org/tautua/markdownpapers/Markdown.java
@@ -31,6 +31,6 @@
Parser parser = new Parser(in);
HtmlEmitter emitter = new HtmlEmitter(out);
Document document = parser.parse();
- emitter.visit(document);
+ document.accept(emitter);
}
}
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/ClosingTag.java b/core/src/main/java/org/tautua/markdownpapers/ast/ClosingTag.java
index b65fbcb..c182574 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/ClosingTag.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/ClosingTag.java
@@ -25,10 +25,6 @@
super(id);
}
- public void setName(String name) {
- this.name = name;
- }
-
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/Emphasis.java b/core/src/main/java/org/tautua/markdownpapers/ast/Emphasis.java
index 4f8595e..fcd6aa0 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/Emphasis.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/Emphasis.java
@@ -31,28 +31,33 @@
return text;
}
+ public void setText(String text) {
+ this.text = text;
+ }
+
public Type getType() {
return type;
}
+ public void setType(Type type) {
+ this.type = type;
+ }
+
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
- public void makeItalic(String text) {
+ public void makeItalic() {
type = Type.ITALIC;
- this.text = text;
}
- public void makeBold(String text) {
+ public void makeBold() {
type = Type.BOLD;
- this.text = text;
}
- public void makeItalicAndBold(String text) {
+ public void makeItalicAndBold() {
type = Type.ITALIC_AND_BOLD;
- this.text = text;
}
public static enum Type {
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/EmptyTag.java b/core/src/main/java/org/tautua/markdownpapers/ast/EmptyTag.java
index 8f387e5..dddf445 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/EmptyTag.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/EmptyTag.java
@@ -23,28 +23,11 @@
* @author Larry Ruiz
*/
public class EmptyTag extends Tag {
- private java.util.List<TagAttribute> attributes = new ArrayList();
public EmptyTag(int id) {
super(id);
}
- public void setName(String name) {
- this.name = name;
- }
-
- public java.util.List<TagAttribute> getAttributes() {
- return attributes;
- }
-
- public void setAttributes(List<TagAttribute> attributes) {
- this.attributes = attributes;
- }
-
- public void addAttr(TagAttribute attribute) {
- attributes.add(attribute);
- }
-
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/Line.java b/core/src/main/java/org/tautua/markdownpapers/ast/Line.java
index f536273..b2decb0 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/Line.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/Line.java
@@ -20,6 +20,8 @@
* @author Larry Ruiz
*/
public class Line extends SimpleNode {
+ private boolean ending = false;
+
public Line(int id) {
super(id);
}
@@ -28,6 +30,14 @@
public void accept(Visitor visitor) {
visitor.visit(this);
}
+
+ public void ending() {
+ this.ending = true;
+ }
+
+ public boolean isEnding() {
+ return ending;
+ }
public boolean isEmpty() {
return children.length == 0;
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/OpeningTag.java b/core/src/main/java/org/tautua/markdownpapers/ast/OpeningTag.java
index edaaf61..e6c77a2 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/OpeningTag.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/OpeningTag.java
@@ -23,7 +23,6 @@
* @author Larry Ruiz
*/
public class OpeningTag extends Tag {
- private java.util.List<TagAttribute> attributes = new ArrayList<TagAttribute>();
private ClosingTag closingTag;
@@ -31,21 +30,7 @@
super(id);
}
- public void setName(String name) {
- this.name = name;
- }
- public java.util.List<TagAttribute> getAttributes() {
- return attributes;
- }
-
- public void setAttributes(List<TagAttribute> attributes) {
- this.attributes = attributes;
- }
-
- public void addAttr(TagAttribute attribute) {
- attributes.add(attribute);
- }
public ClosingTag getClosingTag() {
return closingTag;
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/Paragraph.java b/core/src/main/java/org/tautua/markdownpapers/ast/Paragraph.java
index 3235849..ea51293 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/Paragraph.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/Paragraph.java
@@ -25,6 +25,16 @@
}
@Override
+ public void jjtAddChild(Node n, int i) {
+ int j = jjtGetNumChildren();
+ if(i >= j) {
+ Line l = (Line)n;
+ l.ending();
+ }
+ super.jjtAddChild(n, i);
+ }
+
+ @Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/Tag.java b/core/src/main/java/org/tautua/markdownpapers/ast/Tag.java
index 744ab85..8194cb1 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/Tag.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/Tag.java
@@ -16,12 +16,15 @@
package org.tautua.markdownpapers.ast;
+import java.util.*;
+
/**
* @author Larry Ruiz
*/
public class Tag extends SimpleNode {
protected String name;
-
+ private java.util.List<TagAttribute> attributes = new ArrayList<TagAttribute>();
+
public Tag(int i) {
super(i);
}
@@ -29,4 +32,21 @@
public String getName() {
return name;
}
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public java.util.List<TagAttribute> getAttributes() {
+ return attributes;
+ }
+
+ public void addAttribute(TagAttribute attribute) {
+ attributes.add(attribute);
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visit(this);
+ }
}
diff --git a/core/src/main/java/org/tautua/markdownpapers/ast/Visitor.java b/core/src/main/java/org/tautua/markdownpapers/ast/Visitor.java
index 721f0e8..d41d960 100644
--- a/core/src/main/java/org/tautua/markdownpapers/ast/Visitor.java
+++ b/core/src/main/java/org/tautua/markdownpapers/ast/Visitor.java
@@ -66,5 +66,7 @@
void visit(SimpleNode node);
+ void visit(Tag node);
+
void visit(Text node);
}
diff --git a/core/src/main/jjtree/Markdown.jjt b/core/src/main/jjtree/Markdown.jjt
index 756fe88..2a1164d 100644
--- a/core/src/main/jjtree/Markdown.jjt
+++ b/core/src/main/jjtree/Markdown.jjt
@@ -41,12 +41,10 @@
String val(Token t) {
String i = t.image;
- if (t.kind == EMPHASIS_BOLD || (t.kind == CODE_SPAN && i.startsWith("``"))) {
+ if (t.kind == CODE_SPAN && i.startsWith("``")) {
i = i.substring(2, i.length() - 2);
- } else if (t.any(CODE_SPAN, EMPHASIS_ITALIC)) {
+ } else if (t.kind == CODE_SPAN) {
i = i.substring(1, i.length() - 1);
- } else if (t.any(EMPHASIS_ITALIC_BOLD)) {
- i = i.substring(3, i.length() - 3);
} else if(t.kind == ESCAPED_CHAR) {
i = String.valueOf(i.charAt(1));
}
@@ -190,7 +188,8 @@
Item item = (Item)stack.peek();
- return newline && t.any(PLUS, MINUS, STAR, NUMBERING) && item.getIndentation() == t.beginColumn;
+ return newline && t.any(PLUS, MINUS, STAR, NUMBERING) && (getToken(i).kind == SPACE || getToken(i).kind == TAB)
+ && item.getIndentation() == t.beginColumn;
}
boolean TextLookahead() {
@@ -247,9 +246,10 @@
List list = (List)stack.peek();
- return t.any(PLUS, MINUS, STAR, NUMBERING) && list.getIndentation() == t.beginColumn;
+ return t.any(PLUS, MINUS, STAR, NUMBERING) && (getToken(i).kind == SPACE || getToken(i).kind == TAB)
+ && list.getIndentation() == t.beginColumn;
}
-
+
boolean QuoteInsideTitleLookahead(int quoteKind) {
if (getToken(1).kind == quoteKind) {
Token t;
@@ -263,6 +263,11 @@
return getToken(1).none(EOL, EOF);
}
+
+ boolean NotClosingTag() {
+ return !(getToken(1).kind == LT && getToken(2).kind == SLASH
+ && getToken(3).kind == CHAR_SEQUENCE && getToken(4).kind == GT);
+ }
}
PARSER_END(Parser)
@@ -298,34 +303,21 @@
}
TOKEN : {
- < MINUS_RULER : "-" ( (" "){0,2} )? "-" ( ( (" "){0,2} )? "-" )+ >
- | < STAR_RULER : "*" ( (" "){0,2} )? "*" ( ( (" "){0,2} )? "*" )+ >
- | < UNDERSCORE_RULER : "_" ( (" "){0,2} )? "_" ( ( (" "){0,2} )? "_" )+ >
-}
-
-TOKEN : {
< COMMENT_OPEN : "<!--" >
| < COMMENT_CLOSE : "-->" >
}
TOKEN : {
< CODE_SPAN : "`" ( ~["`", "\r", "\n"] )+ "`" | "`" "`" ( ~["'", "\r", "\n"] )+ "`" "`" >
- | < EMPHASIS_ITALIC : "*" <EMP_A> ( ( ~["*", "\r", "\n"] )* <EMP_A> )? "*"
- | "_" <EMP_U> ( ( ~["_", "\r", "\n"] )* <EMP_U> )? "_">
- | < EMPHASIS_BOLD : "**" <EMP_A> ( ( ~["*", "\r", "\n"] )* <EMP_A> )? "**"
- | "__" <EMP_U> ( ( ~["_", "\r", "\n"] )* <EMP_U> )? "__">
- | < EMPHASIS_ITALIC_BOLD : "***" <EMP_A> ( ( ~["*", "\r", "\n"] )* <EMP_A> )? "***"
- | "___" <EMP_U> ( ( ~["_", "\r", "\n"] )* <EMP_U> )? "___">
| < NUMBERING : ( ["0"-"9"] )+ "." >
- | < #EMP_A : ~["*", " ", "\t", "\r", "\n"] >
- | < #EMP_U : ~["_", " ", "\t", "\r", "\n"] >
}
TOKEN : {
< CHAR_ENTITY_REF : "&" ( ["a"-"z", "A"-"Z"] )+ ";" >
| < NUMERIC_CHAR_REF : "&" ( ( ["0"-"9"] ){1,4} | "x" ( ["0"-"9", "a"-"f", "A"-"F"] ){1,4} ) ";" >
| < ESCAPED_CHAR : "\\" ["{", "}", "[", "]", "(", ")", "\\", "`", "_", ">", "#", ".", "!", "+", "-", "*"] >
- | < CHAR_SEQUENCE : ( ~["=", "#", "&", "*", "\"", "'", "`", ":", "<", ">", "(", ")", "[", "]", " ", "\\", "/", "\t", "\r", "\n", "!", "_"] )+ >
+ | < CHAR_SEQUENCE : ( ~["=", "#", "&", "*", "\"", "'", "`", ":", "<", ">", "(", ")", "[", "]", " "
+ , "\\", "/", "\t", "\r", "\n", "!", "_", "-", "+"] )+ >
}
void Document() #Document : {} {
@@ -337,29 +329,32 @@
}
void Element() : {} {
- LOOKAHEAD( ResourceDefinition() ) DocumentElement() | BlockElement()
-}
-
-void DocumentElement() : {} {
- ResourceDefinition()
+ LOOKAHEAD( ResourceDefinition() ) ResourceDefinition()
+ | BlockElement()
}
void BlockElement() : {} {
- LOOKAHEAD( Ruler() ( <EOL> | <EOF> ) ) Ruler()
- | LOOKAHEAD( Header() ( <EOL> | <EOF> ) ) Header()
- | LOOKAHEAD( EmptyLine() ) Whitespace()
- | LOOKAHEAD( CodeLine() ) Code()
- | LOOKAHEAD( QuotePrefix() ) Quote()
- | LOOKAHEAD( ( InsignificantWhitespace() )? ( <PLUS> | <MINUS> | <STAR> | <NUMBERING> ) ( <SPACE> | <TAB> ) ) List()
- | LOOKAHEAD( Comment() ) Comment()
- | Paragraph()
+ LOOKAHEAD( EmptyLine() ) Whitespace()
+ | LOOKAHEAD( CodeLinePrefix() ) Code()
+ |
+ (
+ ( InsignificantWhitespace() )?
+ (
+ LOOKAHEAD( QuotePrefix() ) Quote()
+ | LOOKAHEAD( Ruler() ( <EOL> | <EOF> ) ) Ruler()
+ | LOOKAHEAD( Header() ( <EOL> | <EOF> ) ) Header()
+ | LOOKAHEAD( Comment() ) Comment()
+ | HtmlBlock()
+ | LOOKAHEAD(2) List()
+ | Paragraph()
+ )
+ )
}
-/*
-void HtmlBlock() : {} {
- Tag()
+public void HtmlBlock() : {} {
+ Tag() ( Whitespace() )?
}
-*/
+
void Whitespace() : {} {
( <SPACE> | <TAB> )+
}
@@ -400,8 +395,7 @@
}{
(
( < EQ > )+ { level = 1; }
- | < MINUS_RULER > { level = 2; }
- | < MINUS > { level = 2; }
+ | ( < MINUS > )+ { level = 2; }
)
{
return level;
@@ -409,7 +403,12 @@
}
void Ruler() #Ruler : {} {
- ( InsignificantWhitespace() )? ( <UNDERSCORE_RULER> | <MINUS_RULER> | <STAR_RULER> ) ( Whitespace() )?
+ (
+ "-" ( LOOKAHEAD(3) " " (" ")? )? "-" ( LOOKAHEAD(3) ( " " (" ")? )? "-" )+
+ | "*" ( LOOKAHEAD(3) " " (" ")? )? "*" ( LOOKAHEAD(3) ( " " (" ")? )? "*" )+
+ | "_" ( LOOKAHEAD(3) " " (" ")? )? "_" ( LOOKAHEAD(3) ( " " (" ")? )? "_" )+
+ )
+ ( Whitespace() )?
}
void Quote() #Quote : {
@@ -431,7 +430,7 @@
}
void QuotePrefix() : {} {
- ( InsignificantWhitespace() )? <GT> ( <SPACE> )?
+ <GT> ( <SPACE> )?
}
void Code() #Code : {} {
@@ -471,9 +470,6 @@
| t = <COMMENT_CLOSE>
| t = <COLON>
| t = <DOUBLE_QUOTE>
- | t = <EMPHASIS_ITALIC>
- | t = <EMPHASIS_BOLD>
- | t = <EMPHASIS_ITALIC_BOLD>
| t = <EQ>
| t = <ESCAPED_CHAR>
| t = <GT>
@@ -483,7 +479,6 @@
| t = <LPAREN>
| t = <LT>
| t = <MINUS>
- | t = <MINUS_RULER>
| t = <PLUS>
| t = <RBRACKET>
| t = <RPAREN>
@@ -492,9 +487,7 @@
| t = <SLASH>
| t = <SPACE>
| t = <STAR>
- | t = <STAR_RULER>
| t = <UNDERSCORE>
- | t = <UNDERSCORE_RULER>
) { jjtThis.append(t.image); }
| t = <TAB> { jjtThis.append(toWhitespace(prev, t)); }
) { prev = t; }
@@ -506,7 +499,7 @@
String n = null;
Resource resource;
} {
- ( <SPACE> ( <SPACE> ( <SPACE> )? )? )?
+ ( InsignificantWhitespace() )?
"[" n = refname() "]" { jjtThis.setId(n); }
( <SPACE> )? ":"
( Whitespace() )?
@@ -532,21 +525,20 @@
stack.push(jjtThis);
Token t;
} {
- (
- (
- t = <PLUS>
- | t = <MINUS>
- | t = <STAR>
- | t = <NUMBERING> { jjtThis.makeOrdered(); }
- )
- ( <SPACE> | <TAB> )
- ) { jjtThis.setIndentation(t.beginColumn); }
+ t = ItemPrefix()
+ {
+ if(t.kind == NUMBERING) {
+ jjtThis.makeOrdered();
+ }
+ jjtThis.setIndentation(t.beginColumn);
+ }
Paragraph()
(
+ (
LOOKAHEAD( {ParagraphLookahead()} ) <EOL> ( LOOKAHEAD( EmptyLine() ) ( Whitespace() )? <EOL> )* Paragraph() { jjtThis.makeLoose(); }
| LOOKAHEAD( {LooseLookahead()} ) <EOL> ( Whitespace() )? { jjtThis.makeLoose(); }
| LOOKAHEAD( {ListLookahead()} ) <EOL> ( LOOKAHEAD( EmptyLine() ) ( Whitespace() )? <EOL> )* List()
-
+ )
)*
{
Item item = (Item)stack.pop();
@@ -557,6 +549,34 @@
}
}
+Token ItemPrefix() : {
+ Token t;
+} {
+ (
+ (
+ t = <PLUS>
+ | t = <MINUS>
+ | t = <STAR>
+ | t = <NUMBERING>
+ )
+ ( <SPACE> | <TAB> )
+ )
+ { return t; }
+}
+
+/*
+void ItemBody() : {} {
+ Paragraph()
+ (
+ (
+ LOOKAHEAD( {ParagraphLookahead()} ) <EOL> ( LOOKAHEAD( EmptyLine() ) ( Whitespace() )? <EOL> )* Paragraph() { jjtThis.makeLoose(); }
+ | LOOKAHEAD( {LooseLookahead()} ) <EOL> ( Whitespace() )? { jjtThis.makeLoose(); }
+ | LOOKAHEAD( {ListLookahead()} ) <EOL> ( LOOKAHEAD( EmptyLine() ) ( Whitespace() )? <EOL> )* List()
+ )
+ )*
+}
+*/
+
void Paragraph() #Paragraph : {} {
Line()
( LOOKAHEAD( {LineLookahead()} ) <EOL> ( <SPACE> | <TAB> | <GT> )* Line() )*
@@ -567,19 +587,19 @@
(
CharRef()
| CodeSpan()
- | Emphasis()
- | LOOKAHEAD( InlineURL() ) InlineURL()
- | LOOKAHEAD( Tag() ) Tag()
- | LOOKAHEAD( Image() ) Image()
| LOOKAHEAD( Link() ) Link()
+ | LOOKAHEAD( Image() ) Image()
+ | LOOKAHEAD( InlineURL() ) InlineURL()
+ | LOOKAHEAD( Emphasis() ) Emphasis()
| LOOKAHEAD( LineBreak() <EOL> ) LineBreak()
+ | LOOKAHEAD(4) Tag()
| Text()
)
)+
}
void LineBreak() #LineBreak : {} {
- <SPACE> <SPACE>
+ <SPACE> <SPACE>
}
void Text() #Text : {
@@ -602,11 +622,34 @@
}
void Emphasis() #Emphasis : {
+ StringBuilder buff = new StringBuilder();
Token t;
+ int flag = 1;
} {
- t = <EMPHASIS_ITALIC> { jjtThis.makeItalic(val(t)); }
- | t = <EMPHASIS_BOLD> { jjtThis.makeBold(val(t)); }
- | t = <EMPHASIS_ITALIC_BOLD> { jjtThis.makeItalicAndBold(val(t)); }
+ (
+ <UNDERSCORE> ( <UNDERSCORE> { flag = 2; } ( <UNDERSCORE> { flag = 3; } )? )?
+ ( t = EmphasisText() | t = <STAR> ) { buff.append(t.image); }
+ (
+ ( <SPACE> { buff.append(" "); } )?
+ ( t = EmphasisText() | t = <STAR> ) { buff.append(t.image); }
+ )*
+ <UNDERSCORE> ( <UNDERSCORE> ( <UNDERSCORE> )? )?
+ |
+ <STAR> ( <STAR> { flag = 2; } ( <STAR> { flag = 3; } )? )?
+ ( t = EmphasisText() | t = <UNDERSCORE> ) { buff.append(t.image); }
+ (
+ ( <SPACE> { buff.append(" "); } )?
+ ( t = EmphasisText() | t = <UNDERSCORE> ) { buff.append(t.image); }
+ )*
+ <STAR> ( <STAR> ( <STAR> )? )?
+ ) {
+ jjtThis.setText(buff.toString());
+ if (flag == 2) {
+ jjtThis.makeBold();
+ } else if (flag == 3) {
+ jjtThis.makeItalicAndBold();
+ }
+ }
}
void Comment() #Comment : {
@@ -650,13 +693,11 @@
} {
"["
(
- CharRef()
- | CodeSpan()
- | Emphasis()
- | LOOKAHEAD( InlineURL() ) InlineURL()
- | LOOKAHEAD( Image() ) Image()
- | LOOKAHEAD( Link() ) Link()
- | LOOKAHEAD( {getToken(1).none(RBRACKET, EOL, EOF)} ) Text()
+ LinkInlineElements()
+ |
+ "[" #Text { ((Text)jjtree.peekNode()).append("["); }
+ LinkInlineElements()
+ "]" #Text { ((Text)jjtree.peekNode()).append("]"); }
| <EOL> #Text { ((Text)jjtree.peekNode()).append("\n"); }
)+
"]"
@@ -698,64 +739,38 @@
)?
}
-void Tag() : {
+void Tag() #Tag : {
Token t;
TagAttribute attribute;
- java.util.List<TagAttribute> attributes = new java.util.ArrayList<TagAttribute>();
} {
+ "<" t = <CHAR_SEQUENCE> { jjtThis.setName(t.image); }
+ ( LOOKAHEAD(2) ( <SPACE> )+ attribute = TagAttribute() { jjtThis.addAttribute(attribute); } )* ( <SPACE> )*
(
- LOOKAHEAD(2)
- "<" "/" t = <CHAR_SEQUENCE> <GT> #ClosingTag
- {
- ClosingTag closing = ((ClosingTag)jjtree.peekNode());
- closing.setName(t.image);
- if (markupStack.size() > 0) {
- OpeningTag opening = (OpeningTag)markupStack.peek();
- if (opening.getName().equals(closing.getName())) {
- opening.setClosingTag(closing);
- markupStack.pop();
- } else {
- markupStack.clear();
- }
+ LOOKAHEAD(2)
+ "/" ">"
+ |
+ try {
+ ">"
+ ( LOOKAHEAD(2) ( TextNode() | Tag() ) )*
+ "<" "/" <CHAR_SEQUENCE> ( <SPACE> )* ">"
+ } catch (ParseException e) {
+ // failsafe
}
- }
- |
- "<" t = <CHAR_SEQUENCE>
- (
- LOOKAHEAD( ( <SPACE> )+ <CHAR_SEQUENCE> )
- ( <SPACE> )+ attribute = TagAttribute() { attributes.add(attribute); }
- )* ( <SPACE> )*
- (
- "/" ">" #EmptyTag { EmptyTag emptytag = (EmptyTag)jjtree.peekNode(); emptytag.setName(t.image); emptytag.setAttributes(attributes); }
- | ">" #OpeningTag { OpeningTag opening = (OpeningTag)jjtree.peekNode(); opening.setName(t.image); opening.setAttributes(attributes); markupStack.push(opening); })
)
}
TagAttribute TagAttribute() : {
StringBuilder buff = new StringBuilder();
- Token attrName;
+ Token name;
Token t;
} {
- attrName = <CHAR_SEQUENCE> "="
+ name = <CHAR_SEQUENCE> "="
(
"\""
(
(
- t = <CODE_SPAN>
- | t = <ESCAPED_CHAR>
- | t = <SPACE>
- | t = <TAB>
- | t = <CHAR_SEQUENCE>
- | t = "&"
- | t = "("
- | t = ")"
- | t = "<"
- | t = ">"
- | t = "/"
- | t = "\\"
+ t = TagAttributeText()
| t = "'"
- | t = "`"
-
) { buff.append(t.image); }
)*
"\""
@@ -763,27 +778,14 @@
"'"
(
(
- t = <CODE_SPAN>
- | t = <ESCAPED_CHAR>
- | t = <SPACE>
- | t = <TAB>
- | t = <CHAR_SEQUENCE>
- | t = "&"
- | t = "("
- | t = ")"
- | t = "<"
- | t = ">"
- | t = "/"
- | t = "\\"
+ t = TagAttributeText()
| t = "\""
- | t = "`"
-
) { buff.append(t.image); }
)*
"'"
)
{
- return new TagAttribute(attrName.image, buff.toString());
+ return new TagAttribute(name.image, buff.toString());
}
}
@@ -806,6 +808,7 @@
| t = <SPACE>
| t = <TAB>
| t = <CHAR_SEQUENCE>
+ | t = <UNDERSCORE>
) { buff.append(t.image); }
)+
{ return buff.toString(); }
@@ -915,13 +918,12 @@
| t = <COLON>
| t = <DOUBLE_QUOTE>
| t = <EQ>
- | t = <ESCAPED_CHAR> { t.image = val(t); }
+ | t = <ESCAPED_CHAR>
| t = <GT>
| t = <LBRACKET>
| t = <LPAREN>
| t = <LT>
| t = <MINUS>
- | t = <MINUS_RULER>
| t = <NUMBERING>
| t = <PLUS>
| t = <RBRACKET>
@@ -931,9 +933,133 @@
| t = <SLASH>
| t = <SPACE>
| t = <STAR>
- | t = <STAR_RULER>
| t = <TAB>
| t = <UNDERSCORE>
- | t = <UNDERSCORE_RULER>
- ) { return t.image; }
+ ) { return val(t); }
}
+
+Token EmphasisText() : {
+ Token t;
+} {
+ (
+ t = <AMPERSAND>
+ | t = <BACKSLASH>
+ | t = <BACKTICK>
+ | t = <BANG>
+ | t = <CHAR_SEQUENCE>
+ | t = <COMMENT_CLOSE>
+ | t = <COMMENT_OPEN>
+ | t = <COLON>
+ | t = <DOUBLE_QUOTE>
+ | t = <EQ>
+ | t = <ESCAPED_CHAR>
+ | t = <GT>
+ | t = <LBRACKET>
+ | t = <LPAREN>
+ | t = <LT>
+ | t = <MINUS>
+ | t = <NUMBERING>
+ | t = <PLUS>
+ | t = <RBRACKET>
+ | t = <RPAREN>
+ | t = <SHARP>
+ | t = <SINGLE_QUOTE>
+ | t = <SLASH>
+ | t = <TAB>
+ ) { return t; }
+}
+
+void LinkInlineElements() : {} {
+ CharRef()
+ | CodeSpan()
+ | LOOKAHEAD( Emphasis() ) Emphasis()
+ | LOOKAHEAD( InlineURL() ) InlineURL()
+ | LOOKAHEAD( Image() ) Image()
+ | LinkText()
+}
+
+void LinkText() #Text : {
+ Token t;
+} {
+ (
+ t = <AMPERSAND>
+ | t = <BACKSLASH>
+ | t = <BACKTICK>
+ | t = <BANG>
+ | t = <CHAR_SEQUENCE>
+ | t = <COMMENT_CLOSE>
+ | t = <COMMENT_OPEN>
+ | t = <COLON>
+ | t = <DOUBLE_QUOTE>
+ | t = <EQ>
+ | t = <ESCAPED_CHAR>
+ | t = <GT>
+ | t = <LPAREN>
+ | t = <LT>
+ | t = <MINUS>
+ | t = <NUMBERING>
+ | t = <PLUS>
+ | t = <RPAREN>
+ | t = <SHARP>
+ | t = <SINGLE_QUOTE>
+ | t = <SLASH>
+ | t = <SPACE>
+ | t = <STAR>
+ | t = <TAB>
+ | t = <UNDERSCORE>
+ ) { jjtThis.append(t.image); }
+}
+
+Token TagAttributeText() : {
+ Token t;
+} {
+ (
+ t = <CODE_SPAN>
+ | t = <ESCAPED_CHAR>
+ | t = <SPACE>
+ | t = <TAB>
+ | t = <CHAR_SEQUENCE>
+ | t = "&"
+ | t = "("
+ | t = ")"
+ | t = "<"
+ | t = ">"
+ | t = "/"
+ | t = "\\"
+ | t = "`"
+ ) { return t; }
+}
+
+void TextNode() #Text : {
+ Token t;
+} {
+ (
+ t = <AMPERSAND>
+ | t = <BACKSLASH>
+ | t = <BACKTICK>
+ | t = <BANG>
+ | t = <CHAR_SEQUENCE>
+ | t = <COMMENT_CLOSE>
+ | t = <COMMENT_OPEN>
+ | t = <COLON>
+ | t = <DOUBLE_QUOTE>
+ | t = <EQ>
+ | t = <EOL>
+ | t = <ESCAPED_CHAR>
+ | t = <GT>
+ | t = <LBRACKET>
+ | t = <LPAREN>
+ | t = <MINUS>
+ | t = <NUMBERING>
+ | t = <PLUS>
+ | t = <RBRACKET>
+ | t = <RPAREN>
+ | t = <SHARP>
+ | t = <SINGLE_QUOTE>
+ | t = <SLASH>
+ | t = <SPACE>
+ | t = <STAR>
+ | t = <TAB>
+ | t = <UNDERSCORE>
+ ) { jjtThis.append(t.image); }
+}
\ No newline at end of file
diff --git a/core/src/test/java/org/tautua/markdownpapers/MarkdownPapersTest.java b/core/src/test/java/org/tautua/markdownpapers/MarkdownPapersTest.java
index 825d064..8d52b55 100644
--- a/core/src/test/java/org/tautua/markdownpapers/MarkdownPapersTest.java
+++ b/core/src/test/java/org/tautua/markdownpapers/MarkdownPapersTest.java
@@ -35,10 +35,12 @@
return Arrays.asList(new Object[][]{
{"code"},
{"comments"},
+ {"emphasis"},
{"headers"},
{"images"},
- {"inline"},
+ {"inline"},
{"linebreak"},
+ {"links"},
{"list"},
{"paragraphs"},
{"quoteAndList"},
diff --git a/core/src/test/resources/others/emphasis.html b/core/src/test/resources/others/emphasis.html
new file mode 100644
index 0000000..5249be1
--- /dev/null
+++ b/core/src/test/resources/others/emphasis.html
@@ -0,0 +1,7 @@
+<p>Hi <strong>John Doe</strong></p>
+
+<ul>
+ <li>notemphasis *</li>
+</ul>
+
+<p>** notbold **</p>
diff --git a/core/src/test/resources/others/emphasis.text b/core/src/test/resources/others/emphasis.text
new file mode 100644
index 0000000..88ee6b1
--- /dev/null
+++ b/core/src/test/resources/others/emphasis.text
@@ -0,0 +1,5 @@
+Hi **John Doe**
+
+* notemphasis *
+
+** notbold **
\ No newline at end of file
diff --git a/core/src/test/resources/others/linebreak.html b/core/src/test/resources/others/linebreak.html
index 16860bb..acbcb13 100644
--- a/core/src/test/resources/others/linebreak.html
+++ b/core/src/test/resources/others/linebreak.html
@@ -1,2 +1,7 @@
-<p>there is a line break at the end <br/>
-another line.</p>
\ No newline at end of file
+<p>There is a line break at the end, <br/>
+ this will be in another line.</p>
+
+<p>Not linebreak in the ending line</p>
+
+<p>Paragraph with two lines,
+Not linebreak in the ending line</p>
\ No newline at end of file
diff --git a/core/src/test/resources/others/linebreak.text b/core/src/test/resources/others/linebreak.text
index 59e52bb..72adb1d 100644
--- a/core/src/test/resources/others/linebreak.text
+++ b/core/src/test/resources/others/linebreak.text
@@ -1,2 +1,7 @@
-there is a line break at the end
-another line.
\ No newline at end of file
+There is a line break at the end,
+this will be in another line.
+
+Not linebreak in the ending line
+
+Paragraph with two lines,
+Not linebreak in the ending line
\ No newline at end of file
diff --git a/core/src/test/resources/others/links.html b/core/src/test/resources/others/links.html
new file mode 100644
index 0000000..63805b3
--- /dev/null
+++ b/core/src/test/resources/others/links.html
@@ -0,0 +1,3 @@
+<p><a href="http://localhost/path_to#id">text</a></p>
+
+<p><a href="http://localhost/path_to_file#id">text 2</a></p>
\ No newline at end of file
diff --git a/core/src/test/resources/others/links.text b/core/src/test/resources/others/links.text
new file mode 100644
index 0000000..9b6b1c8
--- /dev/null
+++ b/core/src/test/resources/others/links.text
@@ -0,0 +1,7 @@
+[text][id]
+
+[text 2][id_2]
+
+[id]: http://localhost/path_to#id
+[id_2]: http://localhost/path_to_file#id
+
diff --git a/core/src/test/resources/others/snippets.html b/core/src/test/resources/others/snippets.html
index 90e45d9..0c8a804 100644
--- a/core/src/test/resources/others/snippets.html
+++ b/core/src/test/resources/others/snippets.html
@@ -1,13 +1,7 @@
<p><em>emphasis</em></p>
-<ul>
-<li>notemphasis *</li>
-</ul>
-
<p><strong>bold</strong></p>
-<p>** notbold **</p>
-
<p>hello world !</p>
<p>lorem ipsum ________</p>
\ No newline at end of file
diff --git a/core/src/test/resources/others/snippets.text b/core/src/test/resources/others/snippets.text
index 2c136e6..02a14c8 100644
--- a/core/src/test/resources/others/snippets.text
+++ b/core/src/test/resources/others/snippets.text
@@ -1,11 +1,7 @@
*emphasis*
-* notemphasis *
-
**bold**
-** notbold **
-
hello world !
lorem ipsum ________
diff --git a/core/src/test/resources/others/tags.html b/core/src/test/resources/others/tags.html
index 71bd829..38b8bc8 100644
--- a/core/src/test/resources/others/tags.html
+++ b/core/src/test/resources/others/tags.html
@@ -1 +1,5 @@
-<span attr="\\backslashes\\">bar</span>
\ No newline at end of file
+<div>
+<p>
+ABC
+</p>
+</div>
diff --git a/core/src/test/resources/others/tags.text b/core/src/test/resources/others/tags.text
index 71bd829..1301e7b 100644
--- a/core/src/test/resources/others/tags.text
+++ b/core/src/test/resources/others/tags.text
@@ -1 +1,5 @@
-<span attr="\\backslashes\\">bar</span>
\ No newline at end of file
+<div>
+<p>
+ABC
+</p>
+</div>
\ No newline at end of file
diff --git a/core/src/test/resources/others/underscore.html b/core/src/test/resources/others/underscore.html
index d33d0ff..60f6020 100644
--- a/core/src/test/resources/others/underscore.html
+++ b/core/src/test/resources/others/underscore.html
@@ -1,7 +1,7 @@
<h1> First header</h1>
<ul>
- <li>Invisible underscore: _, c.<br/></li>
+ <li>Invisible underscore: _, c.</li>
</ul>
<h1> Second header</h1>
diff --git a/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownParser.java b/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownParser.java
index a108819..2ceb003 100644
--- a/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownParser.java
+++ b/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownParser.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2011, TAUTUA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package org.tautua.markdownpapers.doxia;
import org.apache.maven.doxia.parser.AbstractParser;
diff --git a/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownSiteModule.java b/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownSiteModule.java
index f2d9ba3..f2d053a 100644
--- a/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownSiteModule.java
+++ b/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/MarkdownSiteModule.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2011, TAUTUA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package org.tautua.markdownpapers.doxia;
import org.apache.maven.doxia.module.site.AbstractSiteModule;
diff --git a/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/SinkEventEmitter.java b/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/SinkEventEmitter.java
index 7f28d90..0d150fa 100644
--- a/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/SinkEventEmitter.java
+++ b/doxia-module/src/main/java/org/tautua/markdownpapers/doxia/SinkEventEmitter.java
@@ -20,15 +20,18 @@
import org.apache.maven.doxia.sink.SinkEventAttributeSet;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.tautua.markdownpapers.ast.*;
+import org.tautua.markdownpapers.util.DequeStack;
+import org.tautua.markdownpapers.util.Stack;
-import java.util.Stack;
+
+import static org.tautua.markdownpapers.util.Utils.SPACE;
/**
* Generate doxia events that are going to be consume by a corresponding sink
* @author Larry Ruiz, Aug 25, 2010
*/
public class SinkEventEmitter implements Visitor {
- private Stack<Header> stack = new Stack<Header>();
+ private Stack<Header> stack = new DequeStack<Header>();
private Sink sink;
public SinkEventEmitter(Sink sink) {
@@ -66,7 +69,7 @@
public void visit(Document node) {
sink.body();
node.childrenAccept(this);
- while(!stack.isEmpty()) {
+ while(!(stack.size() == 0)) {
sink.section_(stack.pop().getLevel());
}
sink.body_();
@@ -102,14 +105,14 @@
}
public void visit(Header node) {
- if(stack.isEmpty()) {
+ if(stack.size() == 0) {
stack.push(node);
} else if(stack.peek().getLevel() < node.getLevel()) {
stack.push(node);
} else {
do {
sink.section_(stack.pop().getLevel());
- } while(!stack.isEmpty() && stack.peek().getLevel() >= node.getLevel());
+ } while(!(stack.size() == 0) && stack.peek().getLevel() >= node.getLevel());
stack.push(node);
}
sink.section(node.getLevel(), null);
@@ -221,6 +224,22 @@
throw new UnsupportedOperationException();
}
+ public void visit(Tag node) {
+ sink.rawText("<");
+ sink.rawText(node.getName());
+ appendAttributes(node.getAttributes());
+
+ if(node.jjtGetNumChildren() == 0) {
+ sink.rawText("/>");
+ } else {
+ sink.rawText(">");
+ node.childrenAccept(this);
+ sink.rawText("</");
+ sink.rawText(node.getName());
+ sink.rawText(">");
+ }
+ }
+
public void visit(Text node) {
sink.text(node.getValue());
}