]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4681 Add support for headings in SQ Markdown
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Wed, 7 May 2014 16:21:00 +0000 (18:21 +0200)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Wed, 7 May 2014 16:21:07 +0000 (18:21 +0200)
sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java [new file with mode: 0644]
sonar-markdown/src/main/java/org/sonar/markdown/Markdown.java
sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java

diff --git a/sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java b/sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java
new file mode 100644 (file)
index 0000000..e2dc004
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.RegexChannel;
+
+/**
+ * Headings are triggered by equal signs at the beginning of a line. The depth of the heading is determined by the number
+ * of equal signs (up to 6).
+ *
+ * E.g., the input:
+ * <pre>
+ * = Level 1
+ * == Level 2
+ * === Level 3
+ * ==== Level 4
+ * ===== Level 5
+ * ====== Level 6
+ * </pre>
+ * will produce:
+ * <pre>
+ * {@literal<h1>}Level 1{@literal</h1>}
+ * {@literal<h2>}Level 2{@literal</h2>}
+ * {@literal<h3>}Level 3{@literal</h3>}
+ * {@literal<h4>}Level 4{@literal</h4>}
+ * {@literal<h5>}Level 5{@literal</h5>}
+ * {@literal<h6>}Level 6{@literal</h6>}
+ * </pre>
+ * @since 4.4
+ *
+ */
+public class HtmlHeadingChannel extends RegexChannel<MarkdownOutput> {
+
+  private static final int MAX_HEADING_DEPTH = 6;
+
+  public HtmlHeadingChannel() {
+    super("\\s*=+\\s[^\r\n]*+[\r\n]*");
+  }
+
+  @Override
+  protected void consume(CharSequence token, MarkdownOutput output) {
+    int index = 0;
+    int headingLevel = 0;
+    while(index < token.length() && Character.isWhitespace(token.charAt(index))) {
+      index ++;
+    }
+    while(index < token.length() && index <= MAX_HEADING_DEPTH && token.charAt(index) == '=') {
+      index ++;
+      headingLevel ++;
+    }
+    while(index < token.length() && Character.isWhitespace(token.charAt(index))) {
+      index ++;
+    }
+    CharSequence headingText = token.subSequence(index, token.length());
+
+    output.append("<h" + headingLevel + ">");
+    output.append(headingText);
+    output.append("</h" + headingLevel + ">");
+  }
+}
index f1ea0a3a4e7dfe4f65df99b540af1d4b96a4e503..79f3c939d8491e9aa49a1c02ac78fb05a914f5f7 100644 (file)
@@ -35,6 +35,7 @@ public final class Markdown {
       .addChannel(new HtmlEndOfLineChannel())
       .addChannel(new HtmlEmphasisChannel())
       .addChannel(new HtmlListChannel())
+      .addChannel(new HtmlHeadingChannel())
       .addChannel(new HtmlCodeChannel())
       .addChannel(new HtmlMultilineCodeChannel())
       .addChannel(new IdentifierAndNumberChannel())
index 13b0099976a47c7e69dc9da0bc6042c63073078f..d2e78c4d4d0387ad09f999dd53169345ed881954 100644 (file)
@@ -52,6 +52,13 @@ public class MarkdownTest {
     assertThat(Markdown.convertToHtml("1. \r1.")).isEqualTo("<ol><li> </li>\r</ol>1.");
   }
 
+  @Test
+  public void shouldDecorateHeadings() {
+    assertThat(Markdown.convertToHtml("  = Top\r== Sub\r\n=== Subsub\n ==== \n 1.five"))
+        .isEqualTo("<h1>Top\r</h1><h2>Sub\r\n</h2><h3>Subsub\n</h3><h4></h4> 1.five");
+  }
+
+
   @Test
   public void shouldDecorateMixedOrderedAndUnorderedList() {
     assertThat(Markdown.convertToHtml("  1. one\r* two\r\n1. three\n * \n 1.five"))