Skip to content

Commit

Permalink
[asciidoc] support conditional blocks in header
Browse files Browse the repository at this point in the history
  • Loading branch information
rmannibucau committed Dec 30, 2023
1 parent 25b685a commit 106e54a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
40 changes: 37 additions & 3 deletions asciidoc-java/src/main/java/io/yupiik/asciidoc/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1243,11 +1243,45 @@ private Map<String, String> readAttributes(final Reader reader) {
ofNullable(reader.nextLine()).map(String::strip).map(it -> ' ' + it).orElse("");
}
attributes.put(matcher.group("name"), value);
} else if (!attributes.isEmpty()) { // missing empty line separator
throw new IllegalArgumentException("Unknown line: '" + line + "'");
} else {
} else if (attributes.isEmpty()) {
reader.rewind();
break;
} else {
// simplistic macro handling, mainly for conditional blocks since we still are in headers
final var stripped = line.strip();
final int options = stripped.indexOf("[]");
if (stripped.length() - "[]".length() == options) { // endsWith
final int sep = stripped.indexOf("::");
if (sep > 0) {
final var macro = new Macro(
stripped.substring(0, sep),
stripped.substring(sep + "::".length(), options),
Map.of(), false);
if ("ifdef".equals(macro.name()) || "ifndef".equals(macro.name()) || "ifeval".equals(macro.name())) {
final var block = readIfBlock(reader);

final var ctx = new ConditionalBlock.Context() {
@Override
public String attribute(final String key) {
return attributes.getOrDefault(key, globalAttributes.get(key));
}
};
if (switch (macro.name()) {
case "ifdef" -> new ConditionalBlock.Ifdef(macro.label()).test(ctx);
case "ifndef" -> new ConditionalBlock.Ifndef(macro.label()).test(ctx);
case "ifeval" ->
new ConditionalBlock.Ifeval(parseCondition(macro.label().strip(), attributes)).test(ctx);
default -> false; // not possible
}) {
reader.insert(block);
}
continue;
}
}
}

// missing empty line separator
throw new IllegalArgumentException("Unknown line: '" + line + "'");
}
}
return attributes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public void reset() {
lineOffset = 0;
}

public void insert(final List<String> lines) {
this.lines.addAll(lineOffset, lines);
}

public void rewind() {
if (lineOffset > 0) {
lineOffset--;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,41 @@ void parseHeader() {
assertEquals(Map.of("attr-1", "v1", "attr-2", "v2"), header.attributes());
}

@Test
void parseHeaderWithConditionalBlocks() {
final var content = List.of("""
= Title
:idprefix:
:idseparator: -
ifndef::env-github[]
:toc: left
:icons: font
endif::[]
ifdef::env-github[]
:toc: macro
:caution-caption: :fire:
:important-caption: :exclamation:
:note-caption: :paperclip:
:tip-caption: :bulb:
:warning-caption: :warning:
endif::[]
""".split("\n"));
{
final var header = new Parser().parseHeader(new Reader(content));
assertEquals("Title", header.title());
assertEquals(Map.of("idprefix", "", "idseparator", "-", "toc", "left", "icons", "font"), header.attributes());
}
{
final var header = new Parser(Map.of("env-github", "true")).parseHeader(new Reader(content));
assertEquals("Title", header.title());
assertEquals(Map.of(
"idprefix", "", "idseparator", "-",
"toc", "macro",
"caution-caption", ":fire:", "important-caption", ":exclamation:",
"note-caption", ":paperclip:", "tip-caption", ":bulb:", "warning-caption", ":warning:"), header.attributes());
}
}

@Test
void parseHeaderAndContent() {
final var doc = new Parser().parse(List.of("= Title", "", "++++", "pass", "++++"), new Parser.ParserContext(null));
Expand Down

0 comments on commit 106e54a

Please sign in to comment.