1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package org.zwobble.mammoth.styles.parsing;
import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.support.Var;
import org.zwobble.mammoth.documents.NumberingLevel;
import org.zwobble.mammoth.styles.HtmlPath;
import org.zwobble.mammoth.styles.HtmlPathElement;
import org.zwobble.mammoth.styles.ParagraphMatcher;
import org.zwobble.mammoth.styles.StyleMapBuilder;
import java.math.BigInteger;
import java.util.Optional;
import static org.zwobble.mammoth.util.MammothMaps.map;
public class StyleMappingParser extends BaseParser<StyleMapBuilder> {
Rule StyleMapping(Var<StyleMapBuilder> styleMap) {
Var<ParagraphMatcher> paragraphMatcher = new Var<>();
Var<HtmlPath> path = new Var<>();
return Sequence(
ParagraphMatcher(paragraphMatcher), Whitespace(), "=>", Whitespace(), HtmlPath(path), EOI,
styleMap.set(styleMap.get().mapParagraph(ParagraphMatcher.ANY, HtmlPath.EMPTY)));
}
public Rule ParagraphMatcher(Var<ParagraphMatcher> matcher) {
Var<Optional<String>> styleId = new Var<>();
Var<Optional<String>> styleName = new Var<>();
Var<Optional<NumberingLevel>> numbering = new Var<>();
return Sequence(
"p", StyleId(styleId), StyleName(styleName), Numbering(numbering),
matcher.set(new ParagraphMatcher(styleId.get(), styleName.get(), numbering.get())));
}
Rule StyleId(Var<Optional<String>> styleId) {
return Sequence(styleId.set(Optional.empty()), Optional(".", Identifier(), styleId.set(Optional.of(match()))));
}
Rule StyleName(Var<Optional<String>> styleName) {
Var<String> value = new Var<>();
return Sequence(
styleName.set(Optional.empty()),
Optional("[style-name=", SingleQuotedString(value), "]", styleName.set(Optional.of(value.get()))));
}
Rule Numbering(Var<Optional<NumberingLevel>> numbering) {
Var<Boolean> isOrdered = new Var<>();
Var<BigInteger> level = new Var<>();
return Sequence(
numbering.set(Optional.empty()),
Optional(Sequence(
":", NumberingType(isOrdered), "(", Number(level), ")",
numbering.set(Optional.of(new NumberingLevel(level.get().subtract(BigInteger.ONE).toString(), isOrdered.get()))))));
}
Rule NumberingType(Var<Boolean> isOrdered) {
return FirstOf(
Sequence("ordered-list", isOrdered.set(true)),
Sequence("unordered-list", isOrdered.set(false)));
}
Rule Number(Var<BigInteger> level) {
return Sequence(
OneOrMore(CharRange('0', '9')),
level.set(new BigInteger(match())));
}
public Rule HtmlPath(Var<HtmlPath> htmlPath) {
ListVar<HtmlPathElement> elements = new ListVar<>();
return Sequence(Optional(HtmlPathElements(elements)), htmlPath.set(new HtmlPath(elements.build())));
}
Rule HtmlPathElements(ListVar<HtmlPathElement> elements) {
Var<HtmlPathElement> element = new Var<>();
return Sequence(
HtmlPathElement(element),
elements.append(element),
ZeroOrMore(Sequence(Whitespace(), Ch('>'), Whitespace(), HtmlPathElement(element), elements.append(element))));
}
Rule HtmlPathElement(Var<HtmlPathElement> element) {
ListVar<String> tagNames = new ListVar<>();
ListVar<String> classNames = new ListVar<>();
Var<Boolean> fresh = new Var<>();
return Sequence(
TagNames(tagNames),
ClassNames(classNames),
Fresh(fresh),
element.set(new HtmlPathElement(
tagNames.build(),
classNames.isEmpty() ? map() : map("class", String.join(" ", classNames.build())),
!fresh.get())));
}
Rule TagNames(ListVar<String> tagNames) {
return Sequence(
Identifier(),
tagNames.append(match()),
ZeroOrMore(Sequence("|", Identifier(), tagNames.append(match()))));
}
Rule ClassNames(ListVar<String> classNames) {
Var<String> className = new Var<>();
return ZeroOrMore(Sequence(ClassName(className), classNames.append(className)));
}
Rule ClassName(Var<String> className) {
return Sequence(".", Identifier(), className.set(match()));
}
Rule Fresh(Var<Boolean> fresh) {
return Sequence(fresh.set(false), Optional(":fresh", fresh.set(true)));
}
Rule SingleQuotedString(Var<String> value) {
return Sequence("'", ZeroOrMore(NoneOf("\'")), value.set(match()), "'");
}
Rule Identifier() {
return Sequence(
FirstOf(CharRange('a', 'z'), CharRange('A', 'Z')),
ZeroOrMore(FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), CharRange('0', '9'), Ch('-'), Ch('_'))));
}
Rule Whitespace() {
return ZeroOrMore(AnyOf(" \t"));
}
}
|