aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-markdown/src
diff options
context:
space:
mode:
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2014-05-09 12:28:47 +0200
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2014-05-09 15:15:52 +0200
commit2dfa1e9aa50829fd4d912ece7c38fc66787c233c (patch)
tree0280eaa883f7768bb7653571ba469a3a9395e9fd /sonar-markdown/src
parent008dcd97794317f200949b52fa1b5a6dd5fbb04d (diff)
downloadsonarqube-2dfa1e9aa50829fd4d912ece7c38fc66787c233c.tar.gz
sonarqube-2dfa1e9aa50829fd4d912ece7c38fc66787c233c.zip
SONAR-4681 Add support for blockquote
Diffstat (limited to 'sonar-markdown/src')
-rw-r--r--sonar-markdown/src/main/java/org/sonar/markdown/HtmlBlockquoteChannel.java106
-rw-r--r--sonar-markdown/src/main/java/org/sonar/markdown/Markdown.java1
-rw-r--r--sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java5
3 files changed, 112 insertions, 0 deletions
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 (&gt;) as a block of quoted text.
+ *
+ * E.g, the input:
+ * <pre>
+ * &gt; Yesterday it worked
+ * &gt; Today it is not working
+ * &gt; Software is like that
+ * </pre>
+ * will produce:
+ * {@literal<blockquote>}{@literal<p>}Yesterday it worked{@literal<br/>}
+ * Today it is not working{@literal<br/>}
+ * Software is like that{@literal</blockquote>}
+ * @since 4.4
+ */
+class HtmlBlockquoteChannel extends Channel<MarkdownOutput> {
+
+ 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("</blockquote>");
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ pendingBlockConstruction = false;
+ }
+ }
+
+ private class QuotedLineElementChannel extends RegexChannel<MarkdownOutput> {
+
+ protected QuotedLineElementChannel() {
+ super(">\\s[^\r\n]*+");
+ }
+
+ @Override
+ protected void consume(CharSequence token, MarkdownOutput output) {
+ if (!pendingBlockConstruction) {
+ output.append("<blockquote>");
+ pendingBlockConstruction = true;
+ }
+ output.append(token.subSequence(searchIndexOfFirstCharacter(token), token.length()));
+ output.append("<br/>");
+ }
+
+ 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<MarkdownOutput> {
+
+ 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("<h1>Top\r</h1><h2>Sub\r\n</h2><h3>Subsub\n</h3><h4></h4> 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("<blockquote>Yesterday it worked<br/>\nToday it is not working<br/>\r\nSoftware is like that<br/>\r</blockquote>");
+ }
@Test
public void shouldDecorateMixedOrderedAndUnorderedList() {