Skip to content

Commit

Permalink
[DOXIA-746] Sink API: add method for block comment
Browse files Browse the repository at this point in the history
Add tests for consecutive comments
  • Loading branch information
kwin committed Oct 13, 2024
1 parent b054e54 commit 5221a72
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ public void lineBreakOpportunity(SinkEventAttributes attributes) {
/** {@inheritDoc} */
@Override
public void pageBreak() {
comment(" PB ");
comment(" PB ", false);
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -1444,34 +1444,44 @@ public void rawText(String text) {
}
}

/** {@inheritDoc} */
@Override
public void comment(String comment) {
comment(comment, false);
}

/** {@inheritDoc} */
@Override
public void comment(String comment, boolean isBlockComment) {
if (comment != null) {
final String originalComment = comment;
write(encodeAsHtmlComment(comment, isBlockComment, getLocationLogPrefix()));
}
}

// http://www.w3.org/TR/2000/REC-xml-20001006#sec-comments
while (comment.contains("--")) {
comment = comment.replace("--", "- -");
}
public static String encodeAsHtmlComment(String comment, boolean isBlockComment, String locationLogPrefix) {
final String originalComment = comment;

if (comment.endsWith("-")) {
comment += " ";
}
// http://www.w3.org/TR/2000/REC-xml-20001006#sec-comments
while (comment.contains("--")) {
comment = comment.replace("--", "- -");
}

if (!originalComment.equals(comment)) {
LOGGER.warn(
"{}Modified invalid comment '{}' to '{}'", getLocationLogPrefix(), originalComment, comment);
}
if (comment.endsWith("-")) {
comment += " ";
}

final StringBuilder buffer = new StringBuilder(comment.length() + 7);
if (!originalComment.equals(comment)) {
LOGGER.warn("{}Modified invalid comment '{}' to '{}'", locationLogPrefix, originalComment, comment);
}

buffer.append(LESS_THAN).append(BANG).append(MINUS).append(MINUS);
buffer.append(comment);
buffer.append(MINUS).append(MINUS).append(GREATER_THAN);
final StringBuilder buffer = new StringBuilder(comment.length() + 7);

write(buffer.toString());
buffer.append(LESS_THAN).append(BANG).append(MINUS).append(MINUS);
buffer.append(comment);
buffer.append(MINUS).append(MINUS).append(GREATER_THAN);
if (isBlockComment) {
buffer.append(EOL);
}
return buffer.toString();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,54 @@ public void testComment() {
assertEquals(expected, actual, "Wrong comment!");
}

/**
* Checks the line separator between two consecutive comments.
*/
@Test
public void testTwoConsecutiveInlineComments() {
String comment = "Simple comment";
sink.comment(comment);
sink.comment(comment);
sink.flush();
sink.close();
assertEquals(getCommentBlock(comment) + getCommentBlock(comment), testWriter.toString(), "Wrong comment!");
}

/**
* Checks the line separator between two consecutive comments.
*/
@Test
public void testTwoConsecutiveBlockComments() {
String comment = "Simple comment";
sink.comment(comment, true);
sink.comment(comment, true);
sink.flush();
sink.close();
assertEquals(
getCommentBlock(comment) + EOL + getCommentBlock(comment) + EOL,
testWriter.toString(),
"Wrong comment!");
}

/**
* Checks the line separator between comment and paragraph (in most markup languages a block element which needs to start in the new line)
*/
@Test
public void testCommentFollowedByParagraph() {
String comment = "Simple comment";
sink.comment(comment);
sink.paragraph();
sink.text("Paragraph");
sink.paragraph_();
sink.flush();
sink.close();

String actual = testWriter.toString();
String expected = getCommentBlockFollowedByParagraph(comment, "Paragraph");

assertEquals(expected, actual, "Wrong comment!");
}

// ----------------------------------------------------------------------
// Utility methods
// ----------------------------------------------------------------------
Expand Down Expand Up @@ -1545,6 +1593,15 @@ protected String getOutputDir() {
*/
protected abstract String getCommentBlock(String text);

/**
* Returns a comment block generated by this sink followed by a paragraph block
* @param text The text to use.
* @return The result of invoking a comment block followed by a paragraph block on the current sink.
* @see #testCommentFollowedByParagraph()
* @since 2.1.0
*/
protected abstract String getCommentBlockFollowedByParagraph(String comment, String paragraph);

protected final void verifyValignSup(String text) {
sink.text("ValignSup", new SinkEventAttributeSet(SinkEventAttributes.VALIGN, "sup"));
sink.flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1855,7 +1855,7 @@ private class Comment extends Block {
/** {@inheritDoc} */
public void traverse() throws AptParseException {
if (isEmitComments()) {
AptParser.this.sink.comment(text);
AptParser.this.sink.comment(text, true);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,6 @@ public void head(SinkEventAttributes attributes) {
public void head_() {
headerFlag = false;

if (!startFlag) {
write(EOL);
}
write(HEADER_START_MARKUP + EOL);
if (title != null) {
write(" " + title + EOL);
Expand Down Expand Up @@ -839,7 +836,12 @@ public void rawText(String text) {

/** {@inheritDoc} */
public void comment(String comment) {
rawText((startFlag ? "" : EOL) + COMMENT + COMMENT + comment);
comment(comment, false);
}

@Override
public void comment(String comment, boolean isBlockComment) {
rawText("" + COMMENT + COMMENT + comment + EOL); // comments are always block comments in APT
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,36 @@ public void testCommentsBeforeTitle() throws Exception {
+ " -----" + EOL + " Test DOXIA-379"));
}

@Test
public void testCommentsAfterParagraph() throws Exception {
SinkEventTestingSink sink = new SinkEventTestingSink();
try (Reader reader = getTestReader("test/comments2")) {
createParser().parse(reader, sink);
}

Iterator<SinkEventElement> it = sink.getEventList().iterator();

assertSinkEquals(
it,
"head",
"head_",
"body",
"section1",
"sectionTitle1",
"text",
"sectionTitle1_",
"paragraph",
"text",
"paragraph_",
"comment", // a comment implicitly ends a paragraph (similar to an empty line)
"comment",
"paragraph",
"text",
"paragraph_",
"section1_",
"body_");
}

@Test
public void testSnippet() throws Exception {
// DOXIA-259
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,24 @@ private static String getSpecialCharacters(char c) {

/** {@inheritDoc} */
protected String getCommentBlock(String text) {
return "~~" + text;
return "~~" + text + EOL;
}

@Override
protected String getCommentBlockFollowedByParagraph(String comment, String paragraph) {
return getCommentBlock(comment) + getParagraphBlock(paragraph);
}

/* Overwrite the test from AbstractSinkTest as EOLs are part of getCommentBlock(...) */
@Test
public void testTwoConsecutiveBlockComments() {
final Sink sink = getSink();
String comment = "Simple comment";
sink.comment(comment, true);
sink.comment(comment, true);
sink.flush();
sink.close();
assertEquals(getCommentBlock(comment) + getCommentBlock(comment), getSinkContent(), "Wrong comment!");
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Section Title

paragraph
~~ some comment
~~ another comment
text
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.AbstractTextSink;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.sink.impl.Xhtml5BaseSink;
import org.apache.maven.doxia.util.HtmlTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -93,13 +94,13 @@ public class MarkdownSink extends AbstractTextSink implements MarkdownMarkup {

private String figureSrc;

/** Most important contextual metadata (of the surrounding element) */
/** Most important contextual metadata (of elements). This contains information about necessary escaping rules, potential prefixes and newlines */
enum ElementContext {
HEAD("head", Type.GENERIC_CONTAINER, null, true),
BODY("body", Type.GENERIC_CONTAINER, MarkdownSink::escapeMarkdown),
// only the elements, which affect rendering of children and are different from BODY or HEAD are listed here
FIGURE("", Type.INLINE, MarkdownSink::escapeMarkdown, true),
CODE_BLOCK("code block", Type.LEAF_BLOCK, null, false),
CODE_BLOCK("code block", Type.LEAF_BLOCK, null),
CODE_SPAN("code span", Type.INLINE, null),
TABLE_CAPTION("table caption", Type.INLINE, MarkdownSink::escapeMarkdown),
TABLE_CELL(
Expand Down Expand Up @@ -269,8 +270,8 @@ private void ensureBeginningOfLine() {
}

/**
* Ensures that the {@link #writer} is either at the beginning or preceded by a blank line.
* Optionally writes a blank line to ensure that.
* Ensures that the {@link #writer} is preceded by a blank line.
* Optionally writes a blank line or just line delimiter to ensure that.
*/
private void ensureBlankLine() {
// prevent duplicate blank lines
Expand Down Expand Up @@ -882,7 +883,12 @@ public void rawText(String text) {

@Override
public void comment(String comment) {
rawText(COMMENT_START + comment + COMMENT_END);
comment(comment, false);
}

@Override
public void comment(String comment, boolean isBlockComment) {
rawText(Xhtml5BaseSink.encodeAsHtmlComment(comment, isBlockComment, getLocationLogPrefix()));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,14 @@ private String getEscapedText(String text) {
return text.replaceAll("\\\\|\\`|\\*|_|\\{|\\}|\\[|\\]|\\(|\\)|#|\\+|\\-|\\.|\\!", "\\\\$0");
}

/** {@inheritDoc} */
@Override
protected String getCommentBlock(String text) {
return "<!-- " + text + " -->";
return "<!--" + toXmlComment(text) + "-->";
}

@Override
protected String getCommentBlockFollowedByParagraph(String comment, String paragraph) {
return getCommentBlock(comment) + EOL + EOL + getParagraphBlock(paragraph); // paragraph separated by blank line
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,13 @@ public void testLinkWithTarget() {
assertEquals("<a href=\"name\"></a><a target=\"nirvana\" href=\"name\"></a>", writer.toString());
}

/** {@inheritDoc} */
@Override
protected String getCommentBlock(String text) {
return "<!--" + toXmlComment(text) + "-->";
}

@Override
protected String getCommentBlockFollowedByParagraph(String comment, String paragraph) {
return getCommentBlock(comment) + getParagraphBlock(paragraph); // no line break in between
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,13 @@ public void testHead() {
assertTrue(actual.contains(expected), actual);
}

/** {@inheritDoc} */
@Override
protected String getCommentBlock(String text) {
return "<!--" + toXmlComment(text) + "-->";
}

@Override
protected String getCommentBlockFollowedByParagraph(String comment, String paragraph) {
return getCommentBlock(comment) + getParagraphBlock(paragraph); // no line break in between
}
}
11 changes: 11 additions & 0 deletions doxia-sink-api/src/main/java/org/apache/maven/doxia/sink/Sink.java
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,17 @@ public interface Sink extends AutoCloseable {
*/
void comment(String comment);

/**
* Add a comment. The default implementation will just call {@link #comment(String)}.
*
* @param comment The comment to write.
* @param isBlockComment If <code>true</code> this is a block comment, i.e. nothing should follow on the same line
* @since 2.1
*/
default void comment(String comment, boolean isBlockComment) {
comment(comment);
}

/**
* Add an unknown event. This may be used by parsers to notify a general Sink about
* an event that doesn't fit into any event defined by the Sink API.
Expand Down

0 comments on commit 5221a72

Please sign in to comment.