diff options
author | Jean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com> | 2014-05-09 12:28:47 +0200 |
---|---|---|
committer | Jean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com> | 2014-05-09 15:15:52 +0200 |
commit | 2dfa1e9aa50829fd4d912ece7c38fc66787c233c (patch) | |
tree | 0280eaa883f7768bb7653571ba469a3a9395e9fd /sonar-markdown/src | |
parent | 008dcd97794317f200949b52fa1b5a6dd5fbb04d (diff) | |
download | sonarqube-2dfa1e9aa50829fd4d912ece7c38fc66787c233c.tar.gz sonarqube-2dfa1e9aa50829fd4d912ece7c38fc66787c233c.zip |
SONAR-4681 Add support for blockquote
Diffstat (limited to 'sonar-markdown/src')
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 (>) as a block of quoted text. + * + * E.g, the input: + * <pre> + * > Yesterday it worked + * > Today it is not working + * > 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() { |