Skip to content

Commit

Permalink
Add support for Example blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
abelsromero committed Oct 19, 2024
1 parent 24e2365 commit c5c13d8
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.maven.site.parser.processors.DescriptionListNodeProcessor;
import org.asciidoctor.maven.site.parser.processors.DocumentNodeProcessor;
import org.asciidoctor.maven.site.parser.processors.ExampleNodeProcessor;
import org.asciidoctor.maven.site.parser.processors.ImageNodeProcessor;
import org.asciidoctor.maven.site.parser.processors.ListItemNodeProcessor;
import org.asciidoctor.maven.site.parser.processors.ListingNodeProcessor;
Expand Down Expand Up @@ -35,6 +36,7 @@ public NodeSinker(Sink sink) {
nodeProcessors = Arrays.asList(
new DescriptionListNodeProcessor(sink, this),
new DocumentNodeProcessor(sink, this),
new ExampleNodeProcessor(sink, this),
new ImageNodeProcessor(sink, this),
new ListItemNodeProcessor(sink, this),
new ListingNodeProcessor(sink, this),
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class DocumentNodeProcessor extends AbstractSinkNodeProcessor implements
/**
* Constructor.
*
* @param sink Doxia {@link Sink}
* @param sink Doxia {@link Sink}
* @param nodeSinker
*/
public DocumentNodeProcessor(Sink sink, NodeSinker nodeSinker) {
super(sink, nodeSinker);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package org.asciidoctor.maven.site.parser.processors;

import java.nio.file.FileSystems;
import java.util.List;

import org.apache.maven.doxia.sink.Sink;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.maven.site.parser.NodeProcessor;
import org.asciidoctor.maven.site.parser.NodeSinker;

import javax.swing.text.html.HTML.Attribute;
import java.nio.file.FileSystems;

import static javax.swing.text.html.HTML.Attribute.ALT;
import static org.asciidoctor.maven.commons.StringUtils.isBlank;
import static javax.swing.text.html.HTML.Attribute.STYLE;
import static org.asciidoctor.maven.commons.StringUtils.isNotBlank;

/**
* Inline images are processed as paragraphs.
*
* @author abelsromero
* @since 3.0.0
* @since 3.1.0
*/
public class ExampleNodeProcessor extends AbstractSinkNodeProcessor implements NodeProcessor {

/**
* Constructor.
*
* @param sink Doxia {@link Sink}
* @param sink Doxia {@link Sink}
* @param nodeSinker
*/
public ExampleNodeProcessor(Sink sink) {
super(sink);
public ExampleNodeProcessor(Sink sink, NodeSinker nodeSinker) {
super(sink, nodeSinker);
}

@Override
Expand All @@ -39,14 +40,24 @@ public void process(StructuralNode node) {
// - For consistency
// - Using `figureCaption` requires wrapping the image in <figure> which adds indentation
final Sink sink = getSink();
// sink.division();

sink.division();
final String title = TitleExtractor.getText(node);
if (isNotBlank(title)) {
sink.division(SinkAttributes.of(Attribute.STYLE, Styles.CAPTION));
sink.division(SinkAttributes.of(STYLE, Styles.CAPTION));
sink.text(title);
sink.division_();
}
// sink.division_();

final List<StructuralNode> blocks = node.getBlocks();
if (!blocks.isEmpty()) {
sink.division(SinkAttributes.of(STYLE, Styles.EXAMPLE));
blocks.forEach(this::sink);
sink.division_();
}

sink.division_();

}

private String formatPath(String imagesdir, String target) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.asciidoctor.maven.site.parser.processors;

import javax.swing.text.html.HTML.Attribute;
import java.nio.file.FileSystems;

import org.apache.maven.doxia.sink.Sink;
Expand All @@ -9,6 +8,7 @@
import org.asciidoctor.maven.site.parser.NodeSinker;

import static javax.swing.text.html.HTML.Attribute.ALT;
import static javax.swing.text.html.HTML.Attribute.STYLE;
import static org.asciidoctor.maven.commons.StringUtils.isBlank;
import static org.asciidoctor.maven.commons.StringUtils.isNotBlank;

Expand Down Expand Up @@ -51,7 +51,7 @@ public void process(StructuralNode node) {
sink.figureGraphics(imagePath, !isBlank(alt) ? SinkAttributes.of(ALT, alt) : null);
final String title = TitleExtractor.getText(node);
if (isNotBlank(title)) {
sink.division(SinkAttributes.of(Attribute.STYLE, Styles.CAPTION));
sink.division(SinkAttributes.of(STYLE, Styles.CAPTION));
sink.text(title);
sink.division_();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,17 @@

class Styles {

public static final String CAPTION = "color: #7a2518; margin-bottom: .25em;";
public static final String CAPTION = new StringBuilder()
.append("color: #7a2518;")
.append("margin-bottom: .25em;")
.toString();


public static final String EXAMPLE = new StringBuilder()
.append("background: #fffef7;")
.append("border: 1px solid #e6e6e6;")
.append("border-color: #e0e0dc;")
.append("box-shadow: 0 1px 4px #e0e0dc;")
.append("padding: 1.25em;")
.toString();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package org.asciidoctor.maven.site.parser.processors;

import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Options;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.maven.site.parser.NodeProcessor;
import org.asciidoctor.maven.site.parser.processors.test.NodeProcessorTest;
import org.junit.jupiter.api.Test;

import static org.asciidoctor.maven.site.parser.processors.test.Html.*;
import static org.assertj.core.api.Assertions.assertThat;

@NodeProcessorTest(ExampleNodeProcessor.class)
class ExampleNodeProcessorTest {

public static final String EXAMPLE_TITLE_OPENING = "<div style=\"color: #7a2518;margin-bottom: .25em;\">";
public static final String EXAMPLE_CONTENT_OPENING = "<div style=\"background: #fffef7;border: 1px solid #e6e6e6;border-color: #e0e0dc;box-shadow: 0 1px 4px #e0e0dc;padding: 1.25em;\">";

private Asciidoctor asciidoctor;
private NodeProcessor nodeProcessor;
private StringWriter sinkWriter;

@Test
void should_convert_empty_example() {
String content = documentWithExample(null, null, List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(""));
}

@Test
void should_convert_minimal_example() {
String content = documentWithExample("SomeText", null, List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_CONTENT_OPENING +
p("SomeText") +
"</div>"));
}

@Test
void should_convert_example_with_title() {
String content = documentWithExample("SomeText", "The title", List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_TITLE_OPENING + "Example 1. The title</div>" +
EXAMPLE_CONTENT_OPENING +
p("SomeText") +
"</div>"));
}

@Test
void should_convert_example_with_title_without_caption() {
String content = documentWithExample("SomeText", "The title", List.of(":example-caption!:"));

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_TITLE_OPENING + "The title</div>" +
EXAMPLE_CONTENT_OPENING +
p("SomeText") +
"</div>"));
}

@Test
void should_convert_with_nested_link() {
final String link = "https://docs.asciidoctor.org/";
String content = documentWithExample(link, null, List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_CONTENT_OPENING +
p("<a href=\"https://docs.asciidoctor.org/\" class=\"bare\">https://docs.asciidoctor.org/</a>") +
"</div>"));
}

@Test
void should_convert_with_nested_table() {
final String table = "|===\n" +
"|Header 1 |Header 2\n" +
"|Column 1, row 1\n" +
"|Column 2, row 1\n" +
"|===";
String content = documentWithExample(table, null, List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_CONTENT_OPENING +
"<table class=\"bodyTable\">" +
"<tr class=\"a\"><td style=\"text-align: left;\">Header 1</td><td>Header 2</td></tr>" +
"<tr class=\"b\"><td style=\"text-align: left;\">Column 1, row 1</td><td>Column 2, row 1</td></tr>" +
"</table>" +
"</div>"));
}

@Test
void should_convert_with_nested_list() {
final String list = "* Un\n" +
"** Dos\n" +
"* Tres\n" +
"** Quatre";
String content = documentWithExample(list, null, List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_CONTENT_OPENING +
ul(
li("Un" + ul(li("Dos"))) +
li("Tres" + ul(li("Quatre")))
) +
"</div>"));
}

@Test
void should_convert_with_multiple_nested_elements() {
final String list = "* Un\n" +
"** Dos\n" +
"* Tres\n" +
"** Quatre";
final String link = "https://docs.asciidoctor.org/";
String content = documentWithExample(list + "\n\n" + link, null, List.of());

String html = process(content);

assertThat(html)
.isEqualTo(div(
EXAMPLE_CONTENT_OPENING +
ul(
li("Un" + ul(li("Dos"))) +
li("Tres" + ul(li("Quatre")))
) +
p("<a href=\"https://docs.asciidoctor.org/\" class=\"bare\">https://docs.asciidoctor.org/</a>") +
"</div>"));
}

private String documentWithExample(String text, String title, List<String> attributes) {
return "= Tile\n\n" + "== Section\n\n" +
(attributes.isEmpty() ? "" : attributes.stream().collect(Collectors.joining("\n"))) + "\n" +
(title == null ? "" : "." + title) + "\n" +
"====" + "\n" +
(text == null ? "" : text) + "\n" +
"====" + "\n";
}

private String process(String content) {
StructuralNode node = asciidoctor.load(content, Options.builder().build())
.findBy(Collections.singletonMap("context", ":example"))
.get(0);

nodeProcessor.process(node);

return removeLineBreaks(sinkWriter.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.asciidoctor.maven.site.parser.processors.test.NodeProcessorTest;
import org.junit.jupiter.api.Test;

import static org.asciidoctor.maven.site.parser.processors.test.Html.removeLineBreaks;
import static org.assertj.core.api.Assertions.assertThat;

@NodeProcessorTest(SectionNodeProcessor.class)
Expand Down Expand Up @@ -202,10 +203,6 @@ private String process(String content, int level, Attributes attributes) {
return removeLineBreaks(sinkWriter.toString().trim());
}

private static String removeLineBreaks(String html) {
return html.replaceAll("(\r)?\n", "");
}

private void reset(StringWriter sinkWriter) {
final StringBuffer buffer = sinkWriter.getBuffer();
buffer.setLength(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public static String monospace(String text) {
return htmlElement("code", text);
}

public static String div(String text) {
return htmlElement("div", text);
}

public static String ul(String... elements) {
return htmlElement("ul", String.join("", elements));
}
Expand All @@ -36,6 +40,10 @@ public static String dd(String text) {
return htmlElement("dd", text);
}

public static String p(String text) {
return htmlElement("p", text);
}

static String htmlElement(String element, String text) {
return htmlElement(element, null, text);
}
Expand All @@ -46,4 +54,8 @@ static String htmlElement(String element, String style, String text) {
}
return String.format("<%1$s style=\"%3$s\">%2$s</%1$s>", element, text, style).trim();
}

public static String removeLineBreaks(String html) {
return html.replaceAll("(\r)?\n", "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ NOTE: Unlike in Asciidoctor lists, descriptions are not surrounded by `<p>` and
** Support for numbered lines with `linenums`
** Support for AsciiDoc titles

* Examples

* Literal blocks
* Quotes

Expand Down

0 comments on commit c5c13d8

Please sign in to comment.