Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOXIA-746] Sink API: add method for block comment #236

Merged
merged 3 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ public void comment(String comment) {
delegate.comment(comment);
}

@Override
public void comment(String comment, boolean endsWithLineBreak) {
delegate.comment(comment, endsWithLineBreak);
}

@Override
public void unknown(String name, Object[] requiredParams, SinkEventAttributes attributes) {
delegate.unknown(name, requiredParams, attributes);
Expand Down
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 endsWithLineBreak) {
if (comment != null) {
final String originalComment = comment;
write(encodeAsHtmlComment(comment, endsWithLineBreak, 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 endsWithLineBreak, 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 (endsWithLineBreak) {
buffer.append(EOL);
}
return buffer.toString();
michael-o marked this conversation as resolved.
Show resolved Hide resolved
}

/**
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 @@ -287,6 +287,11 @@ public void rawText(String text) {
addEvent("rawText", new Object[] {text});
}

@Override
public void comment(String comment, boolean endsWithLineBreak) {
addEvent("comment", new Object[] {comment, endsWithLineBreak});
}

@Override
public void comment(String comment) {
addEvent("comment", new Object[] {comment});
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 endsWithLineBreak) {
rawText("" + COMMENT + COMMENT + comment + EOL); // comments always end with a line break in APT
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,32 @@ 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();

assertSinkStartsWith(
it,
"head",
"head_",
"body",
"section1",
"sectionTitle1",
"text",
"sectionTitle1_",
"paragraph",
"text",
"paragraph_");
assertSinkEquals(it.next(), "comment", "some comment", Boolean.TRUE);
assertSinkEquals(it.next(), "comment", "another comment", Boolean.TRUE);
assertSinkEquals(it, "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 endsWithLineBreak) {
rawText(Xhtml5BaseSink.encodeAsHtmlComment(comment, endsWithLineBreak, 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
}
}
13 changes: 13 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 @@ -1718,12 +1718,25 @@ public interface Sink extends AutoCloseable {

/**
* Add a comment.
* Semantically the same as {@link #comment(String, boolean)} with second argument being {@code false}.
*
* @param comment The comment to write.
* @since 1.1
* @see #comment(String, boolean)
*/
void comment(String comment);

/**
* Add a comment. The default implementation will just call {@link #comment(String)}.
*
* @param comment The comment to write.
* @param endsWithLineBreak If {@code true} comment ends with a line break, i.e. nothing else should follow on the same line
* @since 2.1
*/
default void comment(String comment, boolean endsWithLineBreak) {
comment(comment);
}
kwin marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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