]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2384 Add support for html list and fix javadoc by escaping html tags
authorFreddy Mallet <freddy.mallet@gmail.com>
Sat, 23 Apr 2011 22:42:00 +0000 (00:42 +0200)
committerFreddy Mallet <freddy.mallet@gmail.com>
Sat, 23 Apr 2011 22:42:00 +0000 (00:42 +0200)
sonar-markdown/src/main/java/org/sonar/markdown/HtmlCodeChannel.java
sonar-markdown/src/main/java/org/sonar/markdown/HtmlEmphasisChannel.java
sonar-markdown/src/main/java/org/sonar/markdown/HtmlEndOfLineChannel.java
sonar-markdown/src/main/java/org/sonar/markdown/HtmlListChannel.java [new file with mode: 0644]
sonar-markdown/src/main/java/org/sonar/markdown/HtmlUrlChannel.java
sonar-markdown/src/main/java/org/sonar/markdown/MarkdownEngine.java
sonar-markdown/src/test/java/org/sonar/markdown/MarkdownEngineTest.java

index b2601557b34a2265d38d01a1acb4145ef20fd6d1..ed2591a0197a37a8461cbed3cad40f15d747eff0 100644 (file)
@@ -22,9 +22,9 @@ package org.sonar.markdown;
 import org.sonar.channel.RegexChannel;
 
 /**
- * Markdown treats double simple quotes ('') as indicators of code. Text wrapped with two '' will be wrapped with an HTML <code> tag.
+ * Markdown treats double simple quotes ('') as indicators of code. Text wrapped with two '' will be wrapped with an HTML {@literal <code>} tag.
  * 
- * E.g., the input ''printf()'' will produce <code>printf()</code>
+ * E.g., the input ''printf()'' will produce {@literal<code>}printf(){@literal</code>}
  */
 class HtmlCodeChannel extends RegexChannel<MarkdownOutput> {
 
index bb53dd8a43ead83b70781523072b7667defe1e69..da0c263cb137b98e662508bb5898ce6423407773 100644 (file)
@@ -22,9 +22,9 @@ package org.sonar.markdown;
 import org.sonar.channel.RegexChannel;
 
 /**
- * Markdown treats asterisks (*) as indicators of emphasis. Text wrapped with one * will be wrapped with an HTML <em> tag.
+ * Markdown treats asterisks (*) as indicators of emphasis. Text wrapped with one * will be wrapped with an HTML {@literal <em>} tag.
  * 
- * E.g., the input *word* will produce <em>work</word>
+ * E.g., the input *word* will produce {@literal <em>}work{@literal </word>}
  */
 class HtmlEmphasisChannel extends RegexChannel<MarkdownOutput> {
 
index e990b0a9584702aec89af489f1ea937f8a278df1..6ca806ed97cb2b2687e0f30f43a5adc37ec62d1f 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.markdown;
 import org.sonar.channel.RegexChannel;
 
 /**
- * Markdown replace any line return by an HTML <br/>
+ * Markdown replace any line return by an HTML {@literal <br/>}
  * tag.
  * 
  */
diff --git a/sonar-markdown/src/main/java/org/sonar/markdown/HtmlListChannel.java b/sonar-markdown/src/main/java/org/sonar/markdown/HtmlListChannel.java
new file mode 100644 (file)
index 0000000..0f71e4c
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.markdown;
+
+import org.sonar.channel.Channel;
+import org.sonar.channel.CodeReader;
+import org.sonar.channel.RegexChannel;
+
+class HtmlListChannel extends Channel<MarkdownOutput> {
+
+  private ListElementChannel listElement = new ListElementChannel();
+  private EndOfLine endOfLine = new EndOfLine();
+  private boolean pendingListConstruction;
+
+  @Override
+  public boolean consume(CodeReader code, MarkdownOutput output) {
+    try {
+      if (code.getColumnPosition() == 0 && listElement.consume(code, output)) {
+        while (endOfLine.consume(code, output) && listElement.consume(code, output)) {
+        }
+        output.append("</ul>");
+        return true;
+      }
+      return false;
+    } finally {
+      pendingListConstruction = false;
+    }
+  }
+
+  private class ListElementChannel extends RegexChannel<MarkdownOutput> {
+
+    public ListElementChannel() {
+      super("\\s*+\\*\\s[^\r\n]*+");
+    }
+
+    @Override
+    protected void consume(CharSequence token, MarkdownOutput output) {
+      if ( !pendingListConstruction) {
+        output.append("<ul>");
+        pendingListConstruction = true;
+      }
+      output.append("<li>");
+      output.append(token.subSequence(searchIndexOfFirstCharacter(token), token.length()));
+      output.append("</li>");
+    }
+
+    private int searchIndexOfFirstCharacter(CharSequence token) {
+      for (int index = 0; index < token.length(); index++) {
+        if (token.charAt(index) == '*') {
+          for (index++; index < token.length(); index++) {
+            if (token.charAt(index) != ' ') {
+              return index;
+            }
+          }
+        }
+      }
+      return token.length() - 1;
+    }
+  }
+
+  private class EndOfLine extends RegexChannel<MarkdownOutput> {
+
+    public EndOfLine() {
+      super("(\r?\n)|(\r)");
+    }
+
+    @Override
+    protected void consume(CharSequence token, MarkdownOutput output) {
+      output.append(token);
+    }
+  }
+}
index 7080a6abe3fb97460fb69c0b398ab47d1d6a5efb..2158c428f00eb7bb8f39495ec0d5e48637ceea1e 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.markdown;
 import org.sonar.channel.RegexChannel;
 
 /**
- * Markdown will wrap any URL with an HTML <a href="URL"> tag.
+ * Markdown will wrap any URL with an HTML {@literal <a href="URL">} tag.
  * 
  */
 class HtmlUrlChannel extends RegexChannel<MarkdownOutput> {
index 773126ac166935f461d0e86bd184f510e2489675..73c639e8182b6ca0a10731f7d34e22c0e2e68c72 100644 (file)
@@ -40,6 +40,7 @@ public class MarkdownEngine {
     markdownChannels.add(new HtmlUrlChannel());
     markdownChannels.add(new HtmlEndOfLineChannel());
     markdownChannels.add(new HtmlEmphasisChannel());
+    markdownChannels.add(new HtmlListChannel());
     markdownChannels.add(new HtmlCodeChannel());
     markdownChannels.add(new IdentifierAndNumberChannel());
     markdownChannels.add(new BlackholeChannel());
index 4054e9a97f6ea3bcb323e340b1f96aecc1cb3ebd..9579828af9bcfe5bcfdd3afe4e79841cbbcb7342 100644 (file)
@@ -35,6 +35,11 @@ public class MarkdownEngineTest {
   public void shouldDecorateEndOfLine() {
     assertThat(MarkdownEngine.convertToHtml("1\r2\r\n3\n"), is("1<br/>2<br/>3<br/>"));
   }
+  
+  @Test
+  public void shouldDecorateList() {
+    assertThat(MarkdownEngine.convertToHtml("  * one\r* two\r\n* three\n * \n *five"), is("<ul><li>one</li>\r<li>two</li>\r\n<li>three</li>\n<li> </li>\n</ul> *five"));
+  }
 
   @Test
   public void shouldDecorateCode() {