Skip to content

Commit a0ab120

Browse files
committed
[asciidoc](#31) ensure admonitions are block friendly
1 parent 5d20225 commit a0ab120

File tree

3 files changed

+74
-29
lines changed

3 files changed

+74
-29
lines changed

asciidoc-java/src/main/java/io/yupiik/asciidoc/parser/Parser.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ private List<Element> doParse(final Reader reader, final Predicate<String> conti
231231
options = null;
232232
} else if (stripped.startsWith(".") && !stripped.startsWith("..") && !stripped.startsWith(". ")) {
233233
options = merge(options, Map.of("title", stripped.substring(1).strip()));
234+
} else if (Objects.equals("====", stripped)) {
235+
elements.add(parseOpenBlock(reader, options, resolver, attributes, "===="));
236+
options = null;
234237
} else if (stripped.startsWith("=")) {
235238
reader.rewind();
236239
elements.add(parseSection(reader, options, resolver, attributes));
@@ -242,7 +245,7 @@ private List<Element> doParse(final Reader reader, final Predicate<String> conti
242245
elements.add(parseCodeBlock(reader, options, resolver, attributes, "```"));
243246
options = null;
244247
} else if (Objects.equals("--", stripped)) {
245-
elements.add(parseOpenBlock(reader, options, resolver, attributes));
248+
elements.add(parseOpenBlock(reader, options, resolver, attributes, "--"));
246249
options = null;
247250
} else if (stripped.startsWith("|===")) {
248251
elements.add(parseTable(reader, options, resolver, attributes, stripped));
@@ -336,13 +339,14 @@ private String subs(final String value, final Map<String, String> opts) {
336339
}
337340

338341
private OpenBlock parseOpenBlock(final Reader reader, final Map<String, String> options,
339-
final ContentResolver resolver, final Map<String, String> currentAttributes) {
342+
final ContentResolver resolver, final Map<String, String> currentAttributes,
343+
final String end) {
340344
final var content = new ArrayList<String>();
341345
String next;
342-
while ((next = reader.nextLine()) != null && !Objects.equals("--", next.strip())) {
346+
while ((next = reader.nextLine()) != null && !Objects.equals(end, next.strip())) {
343347
content.add(next);
344348
}
345-
if (next != null && !next.startsWith("--")) {
349+
if (next != null && !next.startsWith(end)) {
346350
reader.rewind();
347351
}
348352
return new OpenBlock(doParse(new Reader(content), l -> true, resolver, currentAttributes, true), options == null ? Map.of() : options);
@@ -1274,7 +1278,7 @@ private void readContinuation(final Reader reader, final String prefix,
12741278
}
12751279

12761280
private boolean isBlock(final String strippedLine) {
1277-
return "----".equals(strippedLine) || "```".equals(strippedLine) || "--".equals(strippedLine) || "++++".equals(strippedLine);
1281+
return "====".equals(strippedLine) || "----".equals(strippedLine) || "```".equals(strippedLine) || "--".equals(strippedLine) || "++++".equals(strippedLine);
12781282
}
12791283

12801284
private void addTextElements(final String line, final int i, final int end,

asciidoc-java/src/main/java/io/yupiik/asciidoc/renderer/html/AsciidoctorLikeHtmlRenderer.java

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -722,31 +722,38 @@ public void visitPassthroughBlock(final PassthroughBlock element) {
722722

723723
@Override
724724
public void visitOpenBlock(final OpenBlock element) {
725-
state.stackChain(element.children(), () -> {
726-
boolean skipDiv = false;
727-
if (element.options().get("abstract") != null) {
728-
builder.append(" <div");
729-
writeCommonAttributes(element.options(), c -> "abstract quoteblock" + (c == null ? "" : (' ' + c)));
730-
builder.append(">\n");
731-
} else if (element.options().get("partintro") != null) {
732-
builder.append(" <div");
733-
writeCommonAttributes(element.options(), c -> "openblock " + (c == null ? "" : (' ' + c)));
725+
switch (element.options().getOrDefault("", "")) {
726+
case "NOTE" -> visitAsAdmonition(Admonition.Level.NOTE, element);
727+
case "TIP" -> visitAsAdmonition(Admonition.Level.TIP, element);
728+
case "IMPORTANT" -> visitAsAdmonition(Admonition.Level.IMPORTANT, element);
729+
case "WARNING" -> visitAsAdmonition(Admonition.Level.WARNING, element);
730+
case "CAUTION" -> visitAsAdmonition(Admonition.Level.CAUTION, element);
731+
default -> state.stackChain(element.children(), () -> {
732+
boolean skipDiv = false;
733+
if (element.options().get("abstract") != null) {
734+
builder.append(" <div");
735+
writeCommonAttributes(element.options(), c -> "abstract quoteblock" + (c == null ? "" : (' ' + c)));
736+
builder.append(">\n");
737+
} else if (element.options().get("partintro") != null) {
738+
builder.append(" <div");
739+
writeCommonAttributes(element.options(), c -> "openblock " + (c == null ? "" : (' ' + c)));
740+
builder.append(">\n");
741+
} else {
742+
skipDiv = true;
743+
}
744+
writeBlockTitle(element.options());
745+
builder.append(" <div");
746+
if (skipDiv) {
747+
writeCommonAttributes(element.options(), c -> "content" + (c == null ? "" : (' ' + c)));
748+
}
734749
builder.append(">\n");
735-
} else {
736-
skipDiv = true;
737-
}
738-
writeBlockTitle(element.options());
739-
builder.append(" <div");
740-
if (skipDiv) {
741-
writeCommonAttributes(element.options(), c -> "content" + (c == null ? "" : (' ' + c)));
742-
}
743-
builder.append(">\n");
744-
Visitor.super.visitOpenBlock(element);
745-
builder.append(" </div>\n");
746-
if (!skipDiv) {
747-
builder.append(" </div>\n");
748-
}
749-
});
750+
Visitor.super.visitOpenBlock(element);
751+
builder.append(" </div>\n");
752+
if (!skipDiv) {
753+
builder.append(" </div>\n");
754+
}
755+
});
756+
}
750757
}
751758

752759
@Override
@@ -1132,6 +1139,18 @@ private int extractNumbers(final String col) {
11321139
}
11331140
}
11341141

1142+
private void visitAsAdmonition(final Admonition.Level level, final OpenBlock element) {
1143+
visitAdmonition(new Admonition(
1144+
level, element.children().size() == 1 ?
1145+
element.children().get(0) :
1146+
new Paragraph(element.children(),
1147+
element.options().size() == 1 ?
1148+
Map.of() :
1149+
element.options().entrySet().stream()
1150+
.filter(it -> !"".equals(it.getKey()))
1151+
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue)))));
1152+
}
1153+
11351154
@Getter
11361155
public static class Configuration {
11371156
private String sectionTag = "div";

asciidoc-java/src/test/java/io/yupiik/asciidoc/renderer/html/AsciidoctorLikeHtmlRendererTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,28 @@ void admonition() {
416416
""");
417417
}
418418

419+
@Test
420+
void admonitionBlock() {
421+
assertRenderingContent("[WARNING]\n" +
422+
"====\n" +
423+
"An admonition block may contain complex content.\n" +
424+
"====", """
425+
<div class="admonitionblock warning">
426+
<table>
427+
<tbody>
428+
<tr>
429+
<td class="icon">
430+
<div class="title">WARNING</div>
431+
</td>
432+
<td class="content">
433+
An admonition block may contain complex content. </td>
434+
</tr>
435+
</tbody>
436+
</table>
437+
</div>
438+
""");
439+
}
440+
419441
@Test
420442
void table() {
421443
assertRenderingContent("""

0 commit comments

Comments
 (0)