package fitnesse.wikitext.parser;
import fitnesse.wiki.PageData;
import fitnesse.wiki.PathParser;
import java.util.Collection;
import java.util.Collections;
public class Include extends SymbolType implements Rule, Translation {
private static final String[] setUpSymbols = new String[] {"COLLAPSE_SETUP"};
private static final String includeHelpOption = "-h";
public static final String TEARDOWN = "teardown";
public Include() {
super("Include");
wikiMatcher(new Matcher().startLineOrCell().string("!include"));
wikiRule(this);
htmlTranslation(this);
}
@Override
public Maybe<Symbol> parse(Symbol current, Parser parser) {
Symbol next = parser.moveNext(1);
if (!next.isType(SymbolType.Whitespace)) return Symbol.nothing;
next = parser.moveNext(1);
String option = "";
if ((next.isType(SymbolType.Text) && next.getContent().startsWith("-")) || next.isType(SymbolType.DateFormatOption)) {
option = next.getContent() + (next.isType(SymbolType.DateFormatOption) ? parser.moveNext(1).getContent() : "");
next = parser.moveNext(1);
if (!next.isType(SymbolType.Whitespace)) return Symbol.nothing;
next = parser.moveNext(1);
}
current.add(option);
if (!next.isType(SymbolType.Text) && !next.isType(WikiWord.symbolType)) return Symbol.nothing;
String includedPageName = next.getContent();
while (parser.peek().isType(SymbolType.Text) || parser.peek().isType(WikiWord.symbolType)) {
Symbol remainderOfPageName = parser.moveNext(1);
includedPageName += remainderOfPageName.getContent();
}
SourcePage sourcePage = parser.getPage().getNamedPage();
// Record the page name anyway, since we might want to show an error if it's invalid
if (PathParser.isWikiPath(includedPageName)) {
current.add(new Symbol(new WikiWord(sourcePage), includedPageName));
} else {
current.add(includedPageName);
}
Maybe<SourcePage> includedPage = sourcePage.findIncludedPage(includedPageName);
if (includedPage.isNothing()) {
current.add("").add(new Symbol(SymbolType.Style, "error").add(includedPage.because()));
}
else if (includeHelpOption.equals(option)) {
String helpText = includedPage.getValue().getProperty(PageData.PropertyHELP);
current.add("").add(Parser.make(
parser.getPage(),helpText).parse());
} else {
current.childAt(1).putProperty(WikiWord.WITH_EDIT, "true");
ParsingPage included = option.equals("-setup") || option.equals("-teardown")
? parser.getPage()
: parser.getPage().copyForNamedPage(includedPage.getValue());
current.add("").add(Parser.make(
included,
includedPage.getValue().getContent())
.parse());
if (option.equals("-setup")) current.evaluateVariables(setUpSymbols, parser.getVariableSource());
}
// Remove trailing newline so we do not introduce excessive whitespace in the page.
if (parser.peek().isType(SymbolType.Newline)) {
parser.moveNext(1);
}
return new Maybe<>(current);
}
@Override
public String toTarget(Translator translator, Symbol symbol) {
if (symbol.getChildren().size() < 4) {
return translator.translate(symbol.childAt(2));
}
String option = symbol.childAt(0).getContent();
if (option.equals("-seamless")) {
return translator.translate(symbol.childAt(3));
} else if (includeHelpOption.equals(option)) {
return translator.translate(symbol.childAt(3));
} else {
String collapseState = stateForOption(option, symbol);
String title = "Included page: "
+ translator.translate(symbol.childAt(1));
Collection<String> extraCollapsibleClass =
option.equals("-teardown") ? Collections.singleton(TEARDOWN) : Collections.<String>emptySet();
return Collapsible.generateHtml(collapseState, title, translator.translate(symbol.childAt(3)), extraCollapsibleClass);
}
}
private String stateForOption(String option, Symbol symbol) {
return ((option.equals("-setup") || option.equals("-teardown")) && symbol.getVariable("COLLAPSE_SETUP", "true").equals("true"))
|| option.equals("-c")
? Collapsible.CLOSED
: "";
}
}