lib/markdown: add fence meta delcaration to ext mode.
authorAlexandre Terrasa <alexandre@moz-code.org>
Thu, 25 Sep 2014 03:17:29 +0000 (23:17 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Thu, 20 Nov 2014 03:17:38 +0000 (22:17 -0500)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

lib/markdown/markdown.nit
lib/markdown/test_markdown.nit

index 664b145..ad5e9a8 100644 (file)
@@ -69,6 +69,26 @@ class MarkdownProcessor
        #               end
        #               ```
        #
+       # * Code blocks meta
+       #
+       #   If you want to use syntax highlighting tools, most of them need to know what kind
+       #   of language they are highlighting.
+       #   You can add an optional language identifier after the fence declaration to output
+       #   it in the HTML render.
+       #
+       #               ```nit
+       #               import markdown
+       #
+       #               print "# Hello World!".md_to_html
+       #               ```
+       #
+       #   Becomes
+       #
+       #               <pre class="nit"><code>import markdown
+       #
+       #               print "Hello World!".md_to_html
+       #               </code></pre>
+       #
        # * Underscores (Emphasis)
        #
        #   Underscores in the middle of a word like:
@@ -667,7 +687,11 @@ class HTMLDecorator
        end
 
        redef fun add_code(v, block) do
-               v.add "<pre><code>"
+               if block isa BlockFence and block.meta != null then
+                       v.add "<pre class=\"{block.meta.to_s}\"><code>"
+               else
+                       v.add "<pre><code>"
+               end
                v.emit_in block
                v.add "</code></pre>\n"
        end
@@ -1105,6 +1129,9 @@ end
 class BlockFence
        super BlockCode
 
+       # Any string found after fence token.
+       var meta: nullable Text
+
        # Fence code lines start at 0 spaces.
        redef var line_start = 0
 end
@@ -1624,7 +1651,8 @@ class LineFence
                else
                        block = v.current_block.split(v.current_block.last_line.as(not null))
                end
-               block.kind = new BlockFence(block)
+               var meta = block.first_line.value.meta_from_fence
+               block.kind = new BlockFence(block, meta)
                block.first_line.clear
                var last = block.last_line
                if last != null and v.line_kind(last) isa LineFence then
@@ -2363,6 +2391,18 @@ redef class Text
                return pos
        end
 
+       # Extract string found at end of fence opening.
+       private fun meta_from_fence: nullable Text do
+               for i in [0..chars.length[ do
+                       var c = chars[i]
+                       print c
+                       if c != ' ' and c != '`' and c != '~' then
+                               return substring_from(i).trim
+                       end
+               end
+               return null
+       end
+
        # Is `self` an unsafe HTML element?
        private fun is_html_unsafe: Bool do return html_unsafe_tags.has(self.write_to_string)
 
index cc010ce..6a49039 100644 (file)
@@ -567,6 +567,22 @@ Here is an example of AppleScript:
                assert res == exp
        end
 
+       fun test_process_code_ext5 do
+               var processor = new MarkdownProcessor
+               processor.ext_mode = true
+               var test = """
+```nit
+print "Hello World!"
+```
+"""
+               var exp = """
+<pre class="nit"><code>print "Hello World!"
+</code></pre>
+"""
+               var res = processor.process(test).write_to_string
+               assert res == exp
+       end
+
        fun test_process_nesting1 do
                var test = """
 > ## This is a header.