Skip to content

Commit a83469a

Browse files
committed
Merge pull request #49 from atlassian/issue-35-extensible-node-rendering
Make HTML rendering for nodes extensible (#35)
2 parents bdcf366 + a676945 commit a83469a

20 files changed

Lines changed: 754 additions & 459 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ android:
1616
- extra-android-m2repository
1717
- sys-img-armeabi-v7a-android-15
1818
script:
19-
- 'if [[ $TEST = java ]]; then mvn test; fi'
19+
- 'if [[ $TEST = java ]]; then mvn test -Dsurefire.useFile=false; fi'
2020
- 'if [[ $TEST = android ]]; then mvn install -DskipTests && cd commonmark-android-test && travis_retry ./.travis.sh; fi'

commonmark-ext-gfm-strikethrough/src/main/java/org/commonmark/ext/gfm/strikethrough/StrikethroughExtension.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import org.commonmark.Extension;
44
import org.commonmark.ext.gfm.strikethrough.internal.StrikethroughDelimiterProcessor;
5-
import org.commonmark.ext.gfm.strikethrough.internal.StrikethroughHtmlRenderer;
5+
import org.commonmark.ext.gfm.strikethrough.internal.StrikethroughNodeRenderer;
6+
import org.commonmark.html.renderer.NodeRenderer;
7+
import org.commonmark.html.renderer.NodeRendererContext;
8+
import org.commonmark.html.renderer.NodeRendererFactory;
69
import org.commonmark.parser.Parser;
710
import org.commonmark.html.HtmlRenderer;
811

@@ -33,7 +36,11 @@ public void extend(Parser.Builder parserBuilder) {
3336

3437
@Override
3538
public void extend(HtmlRenderer.Builder rendererBuilder) {
36-
rendererBuilder.customHtmlRenderer(new StrikethroughHtmlRenderer());
39+
rendererBuilder.nodeRendererFactory(new NodeRendererFactory() {
40+
@Override
41+
public NodeRenderer create(NodeRendererContext context) {
42+
return new StrikethroughNodeRenderer(context);
43+
}
44+
});
3745
}
38-
3946
}

commonmark-ext-gfm-strikethrough/src/main/java/org/commonmark/ext/gfm/strikethrough/internal/StrikethroughHtmlRenderer.java

Lines changed: 0 additions & 31 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.commonmark.ext.gfm.strikethrough.internal;
2+
3+
import org.commonmark.ext.gfm.strikethrough.Strikethrough;
4+
import org.commonmark.html.HtmlWriter;
5+
import org.commonmark.html.renderer.NodeRenderer;
6+
import org.commonmark.html.renderer.NodeRendererContext;
7+
import org.commonmark.node.Node;
8+
9+
import java.util.Collections;
10+
import java.util.Map;
11+
import java.util.Set;
12+
13+
public class StrikethroughNodeRenderer implements NodeRenderer {
14+
15+
private final NodeRendererContext context;
16+
private final HtmlWriter html;
17+
18+
public StrikethroughNodeRenderer(NodeRendererContext context) {
19+
this.context = context;
20+
this.html = context.getHtmlWriter();
21+
}
22+
23+
@Override
24+
public Set<Class<? extends Node>> getNodeTypes() {
25+
return Collections.<Class<? extends Node>>singleton(Strikethrough.class);
26+
}
27+
28+
@Override
29+
public void render(Node node) {
30+
Map<String, String> attributes = context.extendAttributes(node, Collections.<String, String>emptyMap());
31+
html.tag("del", attributes);
32+
renderChildren(node);
33+
html.tag("/del");
34+
}
35+
36+
private void renderChildren(Node parent) {
37+
Node node = parent.getFirstChild();
38+
while (node != null) {
39+
Node next = node.getNext();
40+
context.render(node);
41+
node = next;
42+
}
43+
}
44+
}

commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TablesExtension.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import org.commonmark.Extension;
44
import org.commonmark.ext.gfm.tables.internal.TableBlockParser;
5-
import org.commonmark.ext.gfm.tables.internal.TableHtmlRenderer;
5+
import org.commonmark.ext.gfm.tables.internal.TableNodeRenderer;
6+
import org.commonmark.html.renderer.NodeRenderer;
7+
import org.commonmark.html.renderer.NodeRendererContext;
8+
import org.commonmark.html.renderer.NodeRendererFactory;
69
import org.commonmark.parser.Parser;
710
import org.commonmark.html.HtmlRenderer;
811

@@ -33,7 +36,11 @@ public void extend(Parser.Builder parserBuilder) {
3336

3437
@Override
3538
public void extend(HtmlRenderer.Builder rendererBuilder) {
36-
rendererBuilder.customHtmlRenderer(new TableHtmlRenderer());
39+
rendererBuilder.nodeRendererFactory(new NodeRendererFactory() {
40+
@Override
41+
public NodeRenderer create(NodeRendererContext context) {
42+
return new TableNodeRenderer(context);
43+
}
44+
});
3745
}
38-
3946
}

commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableHtmlRenderer.java

Lines changed: 0 additions & 99 deletions
This file was deleted.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package org.commonmark.ext.gfm.tables.internal;
2+
3+
import org.commonmark.ext.gfm.tables.*;
4+
import org.commonmark.html.HtmlWriter;
5+
import org.commonmark.html.renderer.NodeRenderer;
6+
import org.commonmark.html.renderer.NodeRendererContext;
7+
import org.commonmark.node.Node;
8+
9+
import java.util.*;
10+
11+
public class TableNodeRenderer implements NodeRenderer {
12+
13+
private final HtmlWriter htmlWriter;
14+
private final NodeRendererContext context;
15+
16+
public TableNodeRenderer(NodeRendererContext context) {
17+
this.htmlWriter = context.getHtmlWriter();
18+
this.context = context;
19+
}
20+
21+
@Override
22+
public Set<Class<? extends Node>> getNodeTypes() {
23+
return new HashSet<>(Arrays.asList(
24+
TableBlock.class,
25+
TableHead.class,
26+
TableBody.class,
27+
TableRow.class,
28+
TableCell.class
29+
));
30+
}
31+
32+
@Override
33+
public void render(Node node) {
34+
if (node instanceof TableBlock) {
35+
renderBlock((TableBlock) node);
36+
} else if (node instanceof TableHead) {
37+
renderHead((TableHead) node);
38+
} else if (node instanceof TableBody) {
39+
renderBody((TableBody) node);
40+
} else if (node instanceof TableRow) {
41+
renderRow((TableRow) node);
42+
} else if (node instanceof TableCell) {
43+
renderCell((TableCell) node);
44+
}
45+
}
46+
47+
private void renderBlock(TableBlock tableBlock) {
48+
htmlWriter.line();
49+
htmlWriter.tag("table", getAttributes(tableBlock));
50+
renderChildren(tableBlock);
51+
htmlWriter.tag("/table");
52+
htmlWriter.line();
53+
}
54+
55+
private void renderHead(TableHead tableHead) {
56+
htmlWriter.line();
57+
htmlWriter.tag("thead", getAttributes(tableHead));
58+
renderChildren(tableHead);
59+
htmlWriter.tag("/thead");
60+
htmlWriter.line();
61+
}
62+
63+
private void renderBody(TableBody tableBody) {
64+
htmlWriter.line();
65+
htmlWriter.tag("tbody", getAttributes(tableBody));
66+
renderChildren(tableBody);
67+
htmlWriter.tag("/tbody");
68+
htmlWriter.line();
69+
}
70+
71+
private void renderRow(TableRow tableRow) {
72+
htmlWriter.line();
73+
htmlWriter.tag("tr", getAttributes(tableRow));
74+
renderChildren(tableRow);
75+
htmlWriter.tag("/tr");
76+
htmlWriter.line();
77+
}
78+
79+
private void renderCell(TableCell tableCell) {
80+
String tag = tableCell.isHeader() ? "th" : "td";
81+
htmlWriter.tag(tag, getCellAttributes(tableCell));
82+
renderChildren(tableCell);
83+
htmlWriter.tag("/" + tag);
84+
}
85+
86+
private Map<String, String> getAttributes(Node node) {
87+
return context.extendAttributes(node, Collections.<String, String>emptyMap());
88+
}
89+
90+
private Map<String, String> getCellAttributes(TableCell tableCell) {
91+
if (tableCell.getAlignment() != null) {
92+
return context.extendAttributes(tableCell, Collections.singletonMap("align", getAlignValue(tableCell.getAlignment())));
93+
} else {
94+
return context.extendAttributes(tableCell, Collections.<String, String>emptyMap());
95+
}
96+
}
97+
98+
private static String getAlignValue(TableCell.Alignment alignment) {
99+
switch (alignment) {
100+
case LEFT:
101+
return "left";
102+
case CENTER:
103+
return "center";
104+
case RIGHT:
105+
return "right";
106+
}
107+
throw new IllegalStateException("Unknown alignment: " + alignment);
108+
}
109+
110+
private void renderChildren(Node parent) {
111+
Node node = parent.getFirstChild();
112+
while (node != null) {
113+
Node next = node.getNext();
114+
context.render(node);
115+
node = next;
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)