Skip to content

Commit 6f74c61

Browse files
author
Torsten Krause
committed
Allow more fine-grained Html generation
1 parent f6e7a9e commit 6f74c61

File tree

16 files changed

+470
-147
lines changed

16 files changed

+470
-147
lines changed

module/core/src/main/java/io/markdom/handler/html/AbstractHtmlDocumentMarkdomHandler.java

Lines changed: 211 additions & 38 deletions
Large diffs are not rendered by default.

module/core/src/main/java/io/markdom/handler/html/DefaultHtmlDelegate.java

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,87 +4,98 @@
44

55
import io.markdom.common.MarkdomEmphasisLevel;
66
import io.markdom.common.MarkdomHeadingLevel;
7-
import io.markdom.util.Attributes;
8-
import io.markdom.util.Elements;
7+
import io.markdom.util.Attribute;
8+
import io.markdom.util.CharacterData;
9+
import io.markdom.util.Element;
10+
import io.markdom.util.Gap;
11+
import io.markdom.util.Nodes;
12+
import io.markdom.util.Text;
913

1014
public class DefaultHtmlDelegate implements HtmlDelegate {
1115

1216
@Override
13-
public Elements onCodeBlock(String code, Optional<String> hint) {
14-
return new Elements().add("pre").add("code");
17+
public Nodes onDocument(Gap gap) {
18+
return new Nodes().add(gap);
1519
}
1620

1721
@Override
18-
public Elements onDivisionBlock() {
19-
return new Elements().add("hr");
22+
public Nodes onCodeBlock(String code, Optional<String> hint) {
23+
return new Nodes().add(new Element("pre").add(new Element("code").add(new CharacterData(code))));
2024
}
2125

2226
@Override
23-
public Elements onHeadingBlock(MarkdomHeadingLevel level) {
24-
return new Elements().add("h" + (level.ordinal() + 1));
27+
public Nodes onDivisionBlock() {
28+
return new Nodes().add(new Element("hr"));
2529
}
2630

2731
@Override
28-
public Elements onOrderdListBlock(Integer startIndex) {
29-
return new Elements().add("ol", new Attributes().add("start", Integer.toString(startIndex)));
32+
public Nodes onHeadingBlock(MarkdomHeadingLevel level, Gap gap) {
33+
return new Nodes().add(new Element("h" + (level.ordinal() + 1)).add(gap));
3034
}
3135

3236
@Override
33-
public Elements onParagraphBlock() {
34-
return new Elements().add("p");
37+
public Nodes onOrderdListBlock(Integer startIndex, Gap gap) {
38+
return new Nodes().add(new Element("ol").add(new Attribute("start", Integer.toString(startIndex))).add(gap));
3539
}
3640

3741
@Override
38-
public Elements onQuoteBlock() {
39-
return new Elements().add("blockquote");
42+
public Nodes onParagraphBlock(Gap gap) {
43+
return new Nodes().add(new Element("p").add(gap));
4044
}
4145

4246
@Override
43-
public Elements onUnorderedListBlock() {
44-
return new Elements().add("ul");
47+
public Nodes onQuoteBlock(Gap gap) {
48+
return new Nodes().add(new Element("blockquote").add(gap));
4549
}
4650

4751
@Override
48-
public Elements onListItem() {
49-
return new Elements().add("li");
52+
public Nodes onUnorderedListBlock(Gap gap) {
53+
return new Nodes().add(new Element("ul").add(gap));
5054
}
5155

5256
@Override
53-
public Elements onCodeContent(String code) {
54-
return new Elements().add("code");
57+
public Nodes onListItem(Gap gap) {
58+
return new Nodes().add(new Element("li").add(gap));
5559
}
5660

5761
@Override
58-
public Elements onEmphasisContent(MarkdomEmphasisLevel level) {
62+
public Nodes onCodeContent(String code) {
63+
return new Nodes().add(new Element("code").add(new Text(code)));
64+
}
65+
66+
@Override
67+
public Nodes onEmphasisContent(MarkdomEmphasisLevel level, Gap gap) {
5968
switch (level) {
60-
case LEVEL_1:
61-
return new Elements().add("em");
62-
case LEVEL_2:
63-
return new Elements().add("strong");
69+
case LEVEL_1:
70+
return new Nodes().add(new Element("em").add(gap));
71+
case LEVEL_2:
72+
return new Nodes().add(new Element("strong").add(gap));
6473
}
6574
throw new InternalError("Unexpected emphasis level: " + level);
6675
}
6776

6877
@Override
69-
public Elements onImageContent(String uri, Optional<String> title, Optional<String> alternative) {
70-
Attributes attributes = new Attributes().add("src", uri).add("title", title).add("alt", alternative);
71-
return new Elements().add("img", attributes);
78+
public Nodes onImageContent(String uri, Optional<String> title, Optional<String> alternative) {
79+
return new Nodes().add(new Element("img").add(new Attribute("src", uri)).add(map("title", title)).add(map("alt", alternative)));
7280
}
7381

7482
@Override
75-
public Elements onLineBreakContent() {
76-
return new Elements().add("br");
83+
public Nodes onLineBreakContent() {
84+
return new Nodes().add(new Element("br"));
7785
}
7886

7987
@Override
80-
public Elements onLinkContent(String uri, Optional<String> title) {
81-
Attributes attributes = new Attributes().add("href", uri).add("title", title);
82-
return new Elements().add("a", attributes);
88+
public Nodes onLinkContent(String uri, Optional<String> title, Gap gap) {
89+
return new Nodes().add(new Element("a").add(new Attribute("href", uri)).add(map("title", title)).add(gap));
8390
}
8491

8592
@Override
86-
public Elements onTextContent(String text) {
87-
return new Elements();
93+
public Nodes onTextContent(String text) {
94+
return new Nodes().add(new Text(text));
95+
}
96+
97+
private Optional<Attribute> map(String key, Optional<String> value) {
98+
return value.map(actualValue -> new Attribute(key, actualValue));
8899
}
89100

90101
}

module/core/src/main/java/io/markdom/handler/html/HtmlDelegate.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,39 @@
44

55
import io.markdom.common.MarkdomEmphasisLevel;
66
import io.markdom.common.MarkdomHeadingLevel;
7-
import io.markdom.util.Elements;
7+
import io.markdom.util.Gap;
8+
import io.markdom.util.Nodes;
89

910
public interface HtmlDelegate {
1011

11-
public Elements onCodeBlock(String code, Optional<String> hint);
12+
public Nodes onDocument(Gap gap);
1213

13-
public Elements onDivisionBlock();
14+
public Nodes onCodeBlock(String code, Optional<String> hint);
1415

15-
public Elements onHeadingBlock(MarkdomHeadingLevel level);
16+
public Nodes onDivisionBlock();
1617

17-
public Elements onOrderdListBlock(Integer startIndex);
18+
public Nodes onHeadingBlock(MarkdomHeadingLevel level, Gap gap);
1819

19-
public Elements onParagraphBlock();
20+
public Nodes onOrderdListBlock(Integer startIndex, Gap gap);
2021

21-
public Elements onQuoteBlock();
22+
public Nodes onParagraphBlock(Gap gap);
2223

23-
public Elements onUnorderedListBlock();
24+
public Nodes onQuoteBlock(Gap gap);
2425

25-
public Elements onListItem();
26+
public Nodes onUnorderedListBlock(Gap gap);
2627

27-
public Elements onCodeContent(String code);
28+
public Nodes onListItem(Gap gap);
2829

29-
public Elements onEmphasisContent(MarkdomEmphasisLevel level);
30+
public Nodes onCodeContent(String code);
3031

31-
public Elements onImageContent(String uri, Optional<String> title, Optional<String> alternative);
32+
public Nodes onEmphasisContent(MarkdomEmphasisLevel level, Gap gap);
3233

33-
public Elements onLineBreakContent();
34+
public Nodes onImageContent(String uri, Optional<String> title, Optional<String> alternative);
3435

35-
public Elements onLinkContent(String uri, Optional<String> title);
36+
public Nodes onLineBreakContent();
3637

37-
public Elements onTextContent(String text);
38+
public Nodes onLinkContent(String uri, Optional<String> title, Gap gap);
39+
40+
public Nodes onTextContent(String text);
3841

3942
}

module/core/src/main/java/io/markdom/handler/xml/AbstractXmlDocumentMarkdomHandler.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.markdom.common.MarkdomKeys;
1010
import io.markdom.common.MarkdomSchemas;
1111
import io.markdom.handler.MarkdomHandler;
12+
import io.markdom.util.Attribute;
1213
import io.markdom.util.Attributes;
1314

1415
public abstract class AbstractXmlDocumentMarkdomHandler<Result> implements MarkdomHandler<Result> {
@@ -29,7 +30,7 @@ public final void onBlockBegin(MarkdomBlockType type) {
2930

3031
@Override
3132
public final void onCodeBlock(String code, Optional<String> hint) {
32-
setAttributes(new Attributes().add(MarkdomKeys.HINT, hint));
33+
setAttributes(new Attributes().add(map(MarkdomKeys.HINT, hint)));
3334
setCharacterData(code);
3435
}
3536

@@ -44,7 +45,7 @@ public final void onDivisionBlock() {
4445

4546
@Override
4647
public final void onHeadingBlockBegin(MarkdomHeadingLevel level) {
47-
setAttributes(new Attributes().add(MarkdomKeys.LEVEL, Integer.toString(level.ordinal() + 1)));
48+
setAttributes(new Attributes().add(new Attribute(MarkdomKeys.LEVEL, Integer.toString(level.ordinal() + 1))));
4849
}
4950

5051
@Override
@@ -53,7 +54,7 @@ public final void onHeadingBlockEnd(MarkdomHeadingLevel level) {
5354

5455
@Override
5556
public final void onOrderedListBlockBegin(Integer startIndex) {
56-
setAttributes(new Attributes().add(MarkdomKeys.START_INDEX, Integer.toString(startIndex)));
57+
setAttributes(new Attributes().add(new Attribute(MarkdomKeys.START_INDEX, Integer.toString(startIndex))));
5758
}
5859

5960
@Override
@@ -135,7 +136,7 @@ public final void onCodeContent(String code) {
135136

136137
@Override
137138
public final void onEmphasisContentBegin(MarkdomEmphasisLevel level) {
138-
setAttributes(new Attributes().add(MarkdomKeys.LEVEL, Integer.toString(level.ordinal() + 1)));
139+
setAttributes(new Attributes().add(new Attribute(MarkdomKeys.LEVEL, Integer.toString(level.ordinal() + 1))));
139140
}
140141

141142
@Override
@@ -144,18 +145,18 @@ public final void onEmphasisContentEnd(MarkdomEmphasisLevel level) {
144145

145146
@Override
146147
public final void onImageContent(String uri, Optional<String> title, Optional<String> alternative) {
147-
setAttributes(new Attributes().add(MarkdomKeys.URI, uri).add(MarkdomKeys.TITLE, title).add(MarkdomKeys.ALTERNATIVE,
148-
alternative));
148+
setAttributes(new Attributes().add(new Attribute(MarkdomKeys.URI, uri)).add(map(MarkdomKeys.TITLE, title))
149+
.add(map(MarkdomKeys.ALTERNATIVE, alternative)));
149150
}
150151

151152
@Override
152153
public final void onLineBreakContent(Boolean hard) {
153-
setAttributes(new Attributes().add(MarkdomKeys.HARD, Boolean.toString(hard)));
154+
setAttributes(new Attributes().add(new Attribute(MarkdomKeys.HARD, Boolean.toString(hard))));
154155
}
155156

156157
@Override
157158
public final void onLinkContentBegin(String uri, Optional<String> title) {
158-
setAttributes(new Attributes().add(MarkdomKeys.URI, uri).add(MarkdomKeys.TITLE, title));
159+
setAttributes(new Attributes().add(new Attribute(MarkdomKeys.URI, uri)).add(map(MarkdomKeys.TITLE, title)));
159160
}
160161

161162
@Override
@@ -193,8 +194,12 @@ public final void onDocumentEnd() {
193194
endDocument();
194195
}
195196

197+
private Optional<Attribute> map(String key, Optional<String> value) {
198+
return value.map(actualValue -> new Attribute(key, actualValue));
199+
}
200+
196201
protected abstract void beginDocument(String dtdQualifiedName, String dtdPublicId, String dtdSystemId, String rootTagName,
197-
String documentVersion, String xmlnsNameSpace);
202+
String documentVersion, String xmlnsNameSpace);
198203

199204
protected abstract void pushElement(String tagName);
200205

module/handler/html-jsoup/src/test/java/io/markdom/handler/html/jsoup/JsoupHtmlDocumentMarkdomHandlerTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public void handleExampleObject() {
2929

3030
Document exampleDocument = Jsoup.parse(TestHelper.readExampleHtml());
3131
exampleDocument.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
32+
33+
System.out.println(html);
3234

3335
assertThat(html, CompareMatcher.isIdenticalTo(exampleDocument.html()).ignoreWhitespace());
3436

module/util/src/main/java/io/markdom/util/Attributes.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,8 @@ public Attributes add(Attribute attribute) {
1717
return this;
1818
}
1919

20-
public Attributes add(String key, Optional<String> value) {
21-
if (ObjectHelper.notNull("optional value", value).isPresent()) {
22-
attributes.add(new Attribute(key, value.get()));
23-
}
24-
return this;
25-
}
26-
27-
public Attributes add(String key, String value) {
28-
attributes.add(new Attribute(key, value));
20+
public Attributes add(Optional<Attribute> attribute) {
21+
ObjectHelper.notNull("attribute", attribute).map(this::add);
2922
return this;
3023
}
3124

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.markdom.util;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public final class CharacterData implements Node {
7+
8+
private final String text;
9+
10+
public CharacterData(String text) {
11+
this.text = ObjectHelper.notNull("text", text);
12+
}
13+
14+
@Override
15+
public <Result> Result select(NodeSelection<Result> selection) {
16+
return selection.select(this);
17+
}
18+
19+
}
Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,46 @@
11
package io.markdom.util;
22

3-
import java.util.Iterator;
3+
import java.util.Optional;
44

55
import lombok.Data;
66

77
@Data
8-
public final class Element implements Iterable<Attribute> {
8+
public final class Element implements Node {
99

1010
private final String tagName;
1111

12-
private final Attributes attributes;
12+
private final Attributes attributes;
13+
14+
private final Nodes nodes;
1315

1416
public Element(String tagName) {
15-
this(tagName, new Attributes());
17+
this(tagName, new Attributes(), new Nodes());
1618
}
1719

18-
public Element(String tagName, Attributes attributes) {
20+
public Element(String tagName, Attributes attributes, Nodes nodes) {
1921
this.tagName = ObjectHelper.notNull("tag name", tagName);
2022
this.attributes = ObjectHelper.notNull("attributes", attributes);
23+
this.nodes = ObjectHelper.notNull("nodes", nodes);
24+
}
25+
26+
public Element add(Attribute attribute) {
27+
attributes.add(ObjectHelper.notNull("attribute", attribute));
28+
return this;
29+
}
30+
31+
public Element add(Optional<Attribute> attribute) {
32+
ObjectHelper.notNull("attribute", attribute).map(this::add);
33+
return this;
34+
}
35+
36+
public Element add(Node node) {
37+
nodes.add(ObjectHelper.notNull("node", node));
38+
return this;
2139
}
2240

2341
@Override
24-
public Iterator<Attribute> iterator() {
25-
return attributes.iterator();
42+
public <Result> Result select(NodeSelection<Result> selection) {
43+
return selection.select(this);
2644
}
2745

2846
}

0 commit comments

Comments
 (0)