Skip to content

Commit

Permalink
Validate inline images are correctly presented (#949)
Browse files Browse the repository at this point in the history
Validate inline images are correctly presented in
  * Paragraphs
  * Preamble
  * Tables
  * Lists
  * Captions
* Fix in table, image captions and section titles

Fixes #937
  • Loading branch information
abelsromero committed Oct 20, 2024
1 parent e870c8c commit e6e8e8e
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void process(StructuralNode node) {
final String title = TitleCaptionExtractor.getText(node);
if (isNotBlank(title)) {
sink.division(SinkAttributes.of(STYLE, Styles.CAPTION));
sink.text(title);
sink.rawText(title);
sink.division_();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void process(StructuralNode node) {
final String title = TitleCaptionExtractor.getText(node);
if (isNotBlank(title)) {
sink.division(SinkAttributes.of(STYLE, Styles.CAPTION));
sink.text(title);
sink.rawText(title);
sink.division_();
}
sink.division_();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.asciidoctor.maven.commons.StringUtils.isNotBlank;

/**
* Section title processor.
* Supports 'sectnum' and 'sectnum' attributes.
Expand Down Expand Up @@ -48,9 +50,11 @@ public void process(StructuralNode node) {
if (level == 0) {
// Kept for completeness, real document title is treated in
// DocumentNodeProcessor
sink.sectionTitle1();
sink.text(formattedTitle);
sink.sectionTitle1_();
if (isNotBlank(formattedTitle)) {
sink.sectionTitle1();
sink.rawText(formattedTitle);
sink.sectionTitle1_();
}
} else {
// Asciidoctor supports up o 6 levels, but Xhtml5BaseSink only up to 5
int siteLevel = level + 1;
Expand All @@ -61,7 +65,7 @@ public void process(StructuralNode node) {
}
sink.sectionTitle(siteLevel, null);
anchor(sink, (Section) node);
sink.text(formattedTitle);
sink.rawText(formattedTitle);
sink.sectionTitle_(siteLevel);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void processCaption(StructuralNode node, Sink sink) {
// getCaption returns
// - "" when '[caption=]'
// - null when ':table-caption!:
sink.text(title);
sink.rawText(title);
sink.tableCaption_();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package org.asciidoctor.maven.site.parser.processors;

import java.io.StringWriter;
import java.util.Collections;

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 java.io.StringWriter;
import java.util.Collections;

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

@NodeProcessorTest(ParagraphNodeProcessor.class)
Expand All @@ -26,7 +27,7 @@ void should_convert_minimal_paragraph() {
String html = process(content);

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

@Test
Expand All @@ -36,7 +37,7 @@ void should_convert_paragraph_with_bold_markup() {
String html = process(content);

assertThat(html)
.isEqualTo("<p>Some <strong>text</strong></p>");
.isEqualTo(p("Some <strong>text</strong>"));
}

@Test
Expand All @@ -46,7 +47,7 @@ void should_convert_paragraph_with_italics_markup() {
String html = process(content);

assertThat(html)
.isEqualTo("<p>Some <em>text</em></p>");
.isEqualTo(p("Some <em>text</em>"));
}

@Test
Expand All @@ -56,17 +57,17 @@ void should_convert_paragraph_with_monospace_markup() {
String html = process(content);

assertThat(html)
.isEqualTo("<p>Some <code>text</code></p>");
.isEqualTo(p("Some <code>text</code>"));
}

@Test
void should_convert_paragraph_with_inline_image() {
String content = documentWithParagraph("image:images/tiger.png[Kitty]");
String content = documentWithParagraph("An inline image image:images/tiger.png[Kitty] here!");

String html = process(content);

assertThat(html)
.isEqualTo("<p><span class=\"image\"><img src=\"images/tiger.png\" alt=\"Kitty\"></span></p>");
.isEqualTo(p("An inline image <span class=\"image\"><img src=\"images/tiger.png\" alt=\"Kitty\"></span> here!"));
}

private String documentWithParagraph(String text) {
Expand All @@ -75,8 +76,8 @@ private String documentWithParagraph(String text) {

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

nodeProcessor.process(node);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,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.p;
import static org.assertj.core.api.Assertions.assertThat;

@NodeProcessorTest(PreambleNodeProcessor.class)
Expand All @@ -26,9 +27,7 @@ void should_convert_preamble() {
String html = process(content);

assertThat(html)
.isEqualTo("<p>This is a preamble." +
System.lineSeparator() +
"With two lines.</p>");
.isEqualTo(p("This is a preamble." + System.lineSeparator() + "With two lines."));
}

@Test
Expand All @@ -38,7 +37,29 @@ void should_convert_preamble_with_markup() {
String html = process(content);

assertThat(html)
.isEqualTo("<p>This <strong>is</strong> <em>a</em> simple <code>preamble</code>.</p>");
.isEqualTo(p("This <strong>is</strong> <em>a</em> simple <code>preamble</code>."));
}

@Test
void should_convert_preamble_with_link() {
final String link = "https://docs.asciidoctor.org/";
String content = documentWithPreamble("There's link " + link + " in the preamble.");

String html = process(content);

assertThat(html)
.isEqualTo(p("There&#8217;s link <a href=\"https://docs.asciidoctor.org/\" class=\"bare\">https://docs.asciidoctor.org/</a> in the preamble."));
}

@Test
void should_convert_preamble_with_inline_image() {
final String inlineImage = "image:images/tiger.png[Kitty]";
String content = documentWithPreamble("An inline image " + inlineImage + " here!");

String html = process(content);

assertThat(html)
.isEqualTo(p("An inline image <span class=\"image\"><img src=\"images/tiger.png\" alt=\"Kitty\"></span> here!"));
}

private String documentWithPreamble() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
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.Nested;
import org.junit.jupiter.api.Test;

import static java.util.Collections.emptyList;
import static org.asciidoctor.maven.site.parser.processors.TableNodeProcessorTest.DocumentBuilder.CaptionOptions.*;
import static org.asciidoctor.maven.site.parser.processors.TableNodeProcessorTest.DocumentBuilder.documentWithTable;
import static org.asciidoctor.maven.site.parser.processors.test.Html.Attributes.STYLE;
import static org.asciidoctor.maven.site.parser.processors.test.Html.td;
import static org.asciidoctor.maven.site.parser.processors.test.Html.tr;
import static org.asciidoctor.maven.site.parser.processors.test.StringTestUtils.removeLineBreaks;
import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -135,6 +140,65 @@ void should_convert_table_with_labels_disabled_globally() {
.isEqualTo(expectedTableWithoutLabel());
}

@Nested
class WhenCellContains {

@Test
void formatted_text() {
final String formattedContent = "This *is* _a_ simple `cell`";
String content = documentWithTable(false, noCaption, List.of(formattedContent, "Something else"));

String html = process(content);

assertThat(html)
.isEqualTo("<table class=\"bodyTable\">" +
tr("a", td("JRuby", textAlignLeft()) + td("Java")) +
tr("b", td("Rubinius", textAlignLeft()) + td("Ruby")) +
tr("a",
td("This <strong>is</strong> <em>a</em> simple <code>cell</code>", textAlignLeft()) +
td("Something else")) +
"</table>");
}

@Test
void links() {
final String link = "https://docs.asciidoctor.org/";
String content = documentWithTable(false, noCaption, List.of("With links " + link + ".", "Something else"));

String html = process(content);

assertThat(html)
.isEqualTo("<table class=\"bodyTable\">" +
tr("a", td("JRuby", textAlignLeft()) + td("Java")) +
tr("b", td("Rubinius", textAlignLeft()) + td("Ruby")) +
tr("a",
td("With links <a href=\"https://docs.asciidoctor.org/\" class=\"bare\">https://docs.asciidoctor.org/</a>.", textAlignLeft()) +
td("Something else")) +
"</table>");
}

@Test
void inline_images() {
final String inlineImage = "image:images/tiger.png[Kitty]";
String content = documentWithTable(false, noCaption, List.of("Something first", "With inline (" + inlineImage + ") images."));

String html = process(content);

assertThat(html)
.isEqualTo("<table class=\"bodyTable\">" +
tr("a", td("JRuby", textAlignLeft()) + td("Java")) +
tr("b", td("Rubinius", textAlignLeft()) + td("Ruby")) +
tr("a",
td("Something first", textAlignLeft()) +
td("With inline (<span class=\"image\"><img src=\"images/tiger.png\" alt=\"Kitty\"></span>) images.")) +
"</table>");
}

private Map<String, String> textAlignLeft() {
return Map.of(STYLE, "text-align: left;");
}
}

private static String expectedNoLabelBeginning() {
return "<table class=\"bodyTable\">" +
"<caption style=\"" + CAPTION_STYLE + "\">Table caption&#8230;&#8203;or title</caption>";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package org.asciidoctor.maven.site.parser.processors.test;

import java.util.Map;
import java.util.stream.Collectors;

import static org.asciidoctor.maven.site.parser.processors.test.Html.Attributes.CLASS;
import static org.asciidoctor.maven.site.parser.processors.test.Html.Attributes.STYLE;

public class Html {

public static final String LIST_STYLE_TYPE_DECIMAL = "list-style-type: decimal;";
Expand All @@ -25,7 +31,7 @@ public static String ul(String... elements) {
}

public static String ol(String style, String... elements) {
return htmlElement("ol", style, String.join("", elements));
return htmlElement("ol", String.join("", elements), Map.of(STYLE, style));
}

public static String li(String text) {
Expand All @@ -44,14 +50,36 @@ public static String p(String text) {
return htmlElement("p", text);
}

public static String tr(String className, String text) {
return htmlElement("tr", text, Map.of(CLASS, className));
}

public static String td(String text) {
return htmlElement("td", text, Map.of());
}

public static String td(String text, Map<String, String> attributes) {
return htmlElement("td", text, attributes);
}

static String htmlElement(String element, String text) {
return htmlElement(element, null, text);
return htmlElement(element, text, Map.of());
}

static String htmlElement(String element, String style, String text) {
if (style == null) {
return String.format("<%1$s>%2$s</%1$s>", element, text).trim();
static String htmlElement(String element, String text, Map<String, String> attributes) {
if (!attributes.isEmpty()) {
String formattedAttributes = attributes.entrySet()
.stream()
.map(entry -> String.format("%s=\"%s\"", entry.getKey(), entry.getValue()))
.collect(Collectors.joining(" "));
return String.format("<%1$s %3$s>%2$s</%1$s>", element, text, formattedAttributes).trim();
}
return String.format("<%1$s style=\"%3$s\">%2$s</%1$s>", element, text, style).trim();

return String.format("<%1$s>%2$s</%1$s>", element, text).trim();
}

public final class Attributes {
public static final String STYLE = "style";
public static final String CLASS = "class";
}
}

0 comments on commit e6e8e8e

Please sign in to comment.