fitnesse.wikitext.parser.FrontMatter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fitnesse Show documentation
Show all versions of fitnesse Show documentation
The fully integrated standalone wiki, and acceptance testing framework.
package fitnesse.wikitext.parser;
import static fitnesse.util.StringUtils.isBlank;
public class FrontMatter extends SymbolType implements Rule, Translation {
public static final FrontMatter symbolType = new FrontMatter();
public static final SymbolType keyValueSymbolType = new SymbolType("KeyValue");
private static final String FRONT_MATTER_DELIMITER_LF = "---\n";
private static final String FRONT_MATTER_DELIMITER_CRLF = "---\r\n";
private static SymbolProvider SYMBOL_PROVIDER = new SymbolProvider(new SymbolType[] {
CloseFrontMatter.symbolType, SymbolType.Colon, SymbolType.Whitespace, SymbolType.Newline, SymbolType.Text
});
FrontMatter() {
super("FrontMatter");
wikiMatcher(new Matcher().startLine().string(FRONT_MATTER_DELIMITER_LF));
wikiMatcher(new Matcher().startLine().string(FRONT_MATTER_DELIMITER_CRLF));
wikiRule(this);
htmlTranslation(this);
}
@Override
public Maybe parse(Symbol current, Parser parser) {
if (current.getStartOffset() != 0) return Symbol.nothing;
final Symbol frontMatter = parser.parseToWithSymbols(CloseFrontMatter.symbolType, SYMBOL_PROVIDER, 0);
if (!parser.getCurrent().isType(CloseFrontMatter.symbolType)) return Symbol.nothing;
Maybe yaml = processYaml(current, frontMatter);
if (yaml.isNothing()) {
return Symbol.nothing;
}
return new Maybe<>(current);
}
private Maybe processYaml(Symbol yaml, Symbol symbolList) {
boolean addToPrevious = false;
String key = null, value = "";
for (Symbol symbol : symbolList.getChildren()) {
if (symbol.isType(SymbolType.Whitespace) && key == null) {
addToPrevious = true;
} else if (symbol.isType(SymbolType.Text) && key == null) {
key = symbol.getContent();
} else if (symbol.isType(SymbolType.Text) || symbol.isType(SymbolType.Whitespace) || (symbol.isType(SymbolType.Colon) && !isBlank(value))) {
value += symbol.getContent();
} else if (symbol.isType(SymbolType.Colon)) {
// Now start filling value
if (key == null) return Symbol.nothing;
} else if (symbol.isType(SymbolType.Newline)) {
if (key != null) {
if (addToPrevious)
yaml.getChildren().get(yaml.getChildren().size() - 1).add(yamlLine(key, value.trim()));
else
yaml.add(yamlLine(key, value.trim()));
}
key = null;
value = "";
addToPrevious = false;
} else {
// All possible alternatives should be covered now.
return Symbol.nothing;
}
}
return new Maybe<>(yaml);
}
private Symbol yamlLine(final String key, final String value) {
return new Symbol(keyValueSymbolType).add(key).add(value);
}
@Override
public String toTarget(Translator translator, Symbol symbol) {
return "";
}
private static class CloseFrontMatter extends SymbolType {
private static final CloseFrontMatter symbolType = new CloseFrontMatter();
private CloseFrontMatter() {
super("EndOfFrontMatter");
wikiMatcher(new Matcher().startLine().string(FRONT_MATTER_DELIMITER_LF));
wikiMatcher(new Matcher().startLine().string(FRONT_MATTER_DELIMITER_CRLF));
}
}
}