From 2dfa1e9aa50829fd4d912ece7c38fc66787c233c Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Fri, 9 May 2014 12:28:47 +0200 Subject: [PATCH] SONAR-4681 Add support for blockquote --- .../sonar/markdown/HtmlBlockquoteChannel.java | 106 ++++++++++++++++++ .../java/org/sonar/markdown/Markdown.java | 1 + .../java/org/sonar/markdown/MarkdownTest.java | 5 + 3 files changed, 112 insertions(+) create mode 100644 sonar-markdown/src/main/java/org/sonar/markdown/HtmlBlockquoteChannel.java diff --git a/sonar-markdown/src/main/java/org/sonar/markdown/HtmlBlockquoteChannel.java b/sonar-markdown/src/main/java/org/sonar/markdown/HtmlBlockquoteChannel.java new file mode 100644 index 00000000000..c236e15a19f --- /dev/null +++ b/sonar-markdown/src/main/java/org/sonar/markdown/HtmlBlockquoteChannel.java @@ -0,0 +1,106 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.markdown; + +import org.sonar.channel.Channel; +import org.sonar.channel.CodeReader; +import org.sonar.channel.RegexChannel; + +/** + * Markdown treats lines starting with a greater than sign (>) as a block of quoted text. + * + * E.g, the input: + *
+ * > Yesterday it worked
+ * > Today it is not working
+ * > Software is like that
+ * 
+ * will produce: + * {@literal
}{@literal

}Yesterday it worked{@literal
} + * Today it is not working{@literal
} + * Software is like that{@literal

} + * @since 4.4 + */ +class HtmlBlockquoteChannel extends Channel { + + private QuotedLineElementChannel quotedLineElement = new QuotedLineElementChannel(); + private EndOfLine endOfLine = new EndOfLine(); + private boolean pendingBlockConstruction; + + @Override + public boolean consume(CodeReader code, MarkdownOutput output) { + try { + if (code.getColumnPosition() == 0) { + if (quotedLineElement.consume(code, output)) { + while (endOfLine.consume(code, output) && quotedLineElement.consume(code, output)) { + // consume input + } + output.append(""); + return true; + } + } + return false; + } finally { + pendingBlockConstruction = false; + } + } + + private class QuotedLineElementChannel extends RegexChannel { + + protected QuotedLineElementChannel() { + super(">\\s[^\r\n]*+"); + } + + @Override + protected void consume(CharSequence token, MarkdownOutput output) { + if (!pendingBlockConstruction) { + output.append("
"); + pendingBlockConstruction = true; + } + output.append(token.subSequence(searchIndexOfFirstCharacter(token), token.length())); + output.append("
"); + } + + private int searchIndexOfFirstCharacter(CharSequence token) { + for (int index = 0; index < token.length(); index++) { + if (token.charAt(index) == '>') { + while (++ index < token.length()) { + if (token.charAt(index) != ' ') { + return index; + } + } + } + } + return token.length() - 1; + } + } + + private static final class EndOfLine extends RegexChannel { + + public EndOfLine() { + super("(\r?\n)|(\r)"); + } + + @Override + protected void consume(CharSequence token, MarkdownOutput output) { + output.append(token); + } + } +} diff --git a/sonar-markdown/src/main/java/org/sonar/markdown/Markdown.java b/sonar-markdown/src/main/java/org/sonar/markdown/Markdown.java index 79f3c939d84..acdb58a6ebd 100644 --- a/sonar-markdown/src/main/java/org/sonar/markdown/Markdown.java +++ b/sonar-markdown/src/main/java/org/sonar/markdown/Markdown.java @@ -35,6 +35,7 @@ public final class Markdown { .addChannel(new HtmlEndOfLineChannel()) .addChannel(new HtmlEmphasisChannel()) .addChannel(new HtmlListChannel()) + .addChannel(new HtmlBlockquoteChannel()) .addChannel(new HtmlHeadingChannel()) .addChannel(new HtmlCodeChannel()) .addChannel(new HtmlMultilineCodeChannel()) diff --git a/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java b/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java index d2e78c4d4d0..0f96cf2a59f 100644 --- a/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java +++ b/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java @@ -58,6 +58,11 @@ public class MarkdownTest { .isEqualTo("

Top\r

Sub\r\n

Subsub\n

1.five"); } + @Test + public void shouldDecorateBlockquote() { + assertThat(Markdown.convertToHtml("> Yesterday it worked\n> Today it is not working\r\n> Software is like that\r")) + .isEqualTo("
Yesterday it worked
\nToday it is not working
\r\nSoftware is like that
\r
"); + } @Test public void shouldDecorateMixedOrderedAndUnorderedList() { -- 2.39.5