Skip to content

Commit fa299a6

Browse files
committed
README: Add usage example for AttributeProvider (#64)
1 parent add7fee commit fa299a6

2 files changed

Lines changed: 89 additions & 26 deletions

File tree

README.md

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,60 @@ class WordCountVisitor extends AbstractVisitor {
9999
}
100100
```
101101

102-
#### Customize HTML rendering
102+
#### Add or change attributes of HTML elements
103103

104-
Sometimes you might want to customize how HTML is rendered, or you added
105-
custom node subclasses that you want to render to HTML. Both can be done
106-
using node renderers.
104+
Sometimes you might want to customize how HTML is rendered. If all you
105+
want to do is add or change attributes on some elements, there's a
106+
simple way to do that.
107107

108-
In this example, we're changing the rendering of indented code blocks:
108+
In this example, we register a factory for an `AttributeProvider` on the
109+
renderer to set a `class="border"` attribute on `img` elements.
109110

110111
```java
111112
Parser parser = Parser.builder().build();
112-
HtmlNodeRendererFactory factory = new HtmlNodeRendererFactory() {
113+
HtmlRenderer renderer = HtmlRenderer.builder()
114+
.attributeProviderFactory(new AttributeProviderFactory() {
115+
public AttributeProvider create(AttributeProviderContext context) {
116+
return new ImageAttributeProvider();
117+
}
118+
})
119+
.build();
120+
121+
Node document = parser.parse("![text](/url.png)");
122+
renderer.render(document);
123+
// "<p><img src=\"/url.png\" alt=\"text\" class=\"border\" /></p>\n"
124+
125+
class ImageAttributeProvider implements AttributeProvider {
113126
@Override
114-
public NodeRenderer create(HtmlNodeRendererContext context) {
115-
return new IndentedCodeBlockNodeRenderer(context);
127+
public void setAttributes(Node node, Map<String, String> attributes) {
128+
if (node instanceof Image) {
129+
attributes.put("class", "border");
130+
}
116131
}
117-
};
118-
HtmlRenderer renderer = HtmlRenderer.builder().nodeRendererFactory(factory).build();
132+
}
133+
```
134+
135+
#### Customize HTML rendering
136+
137+
If you want to do more than just change attributes, there's also a way
138+
to take complete control over how HTML is rendered.
139+
140+
In this example, we're changing the rendering of indented code blocks to
141+
only wrap them in `pre` instead of `pre` and `code`:
142+
143+
```java
144+
Parser parser = Parser.builder().build();
145+
HtmlRenderer renderer = HtmlRenderer.builder()
146+
.nodeRendererFactory(new HtmlNodeRendererFactory() {
147+
public NodeRenderer create(HtmlNodeRendererContext context) {
148+
return new IndentedCodeBlockNodeRenderer(context);
149+
}
150+
})
151+
.build();
119152

120153
Node document = parser.parse("Example:\n\n code");
121-
renderer.render(document); // "<p>Example:</p>\n<pre>code\n</pre>\n"
154+
renderer.render(document);
155+
// "<p>Example:</p>\n<pre>code\n</pre>\n"
122156

123157
class IndentedCodeBlockNodeRenderer implements NodeRenderer {
124158

@@ -147,6 +181,15 @@ class IndentedCodeBlockNodeRenderer implements NodeRenderer {
147181
}
148182
```
149183

184+
#### Add your own node types
185+
186+
In case you want to store additional data in the document or have custom
187+
elements in the resulting HTML, you can create your own subclass of
188+
`CustomNode` and add instances as child nodes to existing nodes.
189+
190+
To define the HTML rendering for them, you can use a `NodeRenderer` as
191+
explained above.
192+
150193
### API documentation
151194

152195
Javadocs are available online on

commonmark/src/test/java/org/commonmark/test/UsageExampleTest.java

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
package org.commonmark.test;
22

3-
import org.commonmark.node.AbstractVisitor;
4-
import org.commonmark.node.IndentedCodeBlock;
5-
import org.commonmark.node.Node;
6-
import org.commonmark.node.Text;
3+
import org.commonmark.node.*;
74
import org.commonmark.parser.Parser;
85
import org.commonmark.renderer.NodeRenderer;
9-
import org.commonmark.renderer.html.HtmlNodeRendererContext;
10-
import org.commonmark.renderer.html.HtmlNodeRendererFactory;
11-
import org.commonmark.renderer.html.HtmlRenderer;
12-
import org.commonmark.renderer.html.HtmlWriter;
6+
import org.commonmark.renderer.html.*;
137
import org.junit.Test;
148

159
import java.util.Collections;
10+
import java.util.Map;
1611
import java.util.Set;
1712

1813
import static org.junit.Assert.assertEquals;
@@ -36,16 +31,32 @@ public void visitor() {
3631
assertEquals(4, visitor.wordCount);
3732
}
3833

34+
@Test
35+
public void addAttributes() {
36+
Parser parser = Parser.builder().build();
37+
HtmlRenderer renderer = HtmlRenderer.builder()
38+
.attributeProviderFactory(new AttributeProviderFactory() {
39+
public AttributeProvider create(AttributeProviderContext context) {
40+
return new ImageAttributeProvider();
41+
}
42+
})
43+
.build();
44+
45+
Node document = parser.parse("![text](/url.png)");
46+
assertEquals("<p><img src=\"/url.png\" alt=\"text\" class=\"border\" /></p>\n",
47+
renderer.render(document));
48+
}
49+
3950
@Test
4051
public void customizeRendering() {
4152
Parser parser = Parser.builder().build();
42-
HtmlNodeRendererFactory factory = new HtmlNodeRendererFactory() {
43-
@Override
44-
public NodeRenderer create(HtmlNodeRendererContext context) {
45-
return new IndentedCodeBlockNodeRenderer(context);
46-
}
47-
};
48-
HtmlRenderer renderer = HtmlRenderer.builder().nodeRendererFactory(factory).build();
53+
HtmlRenderer renderer = HtmlRenderer.builder()
54+
.nodeRendererFactory(new HtmlNodeRendererFactory() {
55+
public NodeRenderer create(HtmlNodeRendererContext context) {
56+
return new IndentedCodeBlockNodeRenderer(context);
57+
}
58+
})
59+
.build();
4960

5061
Node document = parser.parse("Example:\n\n code");
5162
assertEquals("<p>Example:</p>\n<pre>code\n</pre>\n", renderer.render(document));
@@ -67,6 +78,15 @@ public void visit(Text text) {
6778
}
6879
}
6980

81+
class ImageAttributeProvider implements AttributeProvider {
82+
@Override
83+
public void setAttributes(Node node, Map<String, String> attributes) {
84+
if (node instanceof Image) {
85+
attributes.put("class", "border");
86+
}
87+
}
88+
}
89+
7090
class IndentedCodeBlockNodeRenderer implements NodeRenderer {
7191

7292
private final HtmlWriter html;

0 commit comments

Comments
 (0)