lib/markdown: merge processor and emitter
authorAlexandre Terrasa <alexandre@moz-code.org>
Wed, 11 Oct 2017 03:11:51 +0000 (23:11 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Wed, 11 Oct 2017 03:11:51 +0000 (23:11 -0400)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

12 files changed:
contrib/nitiwiki/src/wiki_html.nit
contrib/nitiwiki/src/wiki_links.nit
lib/markdown/markdown.nit
lib/markdown/nitmd.nit
lib/markdown/test_markdown.nit
lib/markdown/wikilinks.nit
src/doc/doc_down.nit
src/doc/doc_phases/doc_readme.nit
src/doc/html_templates/html_templates.nit
src/nitcatalog.nit
src/testing/testing_doc.nit
src/web/api_docdown.nit

index 15ae4d7..d82bcb6 100644 (file)
@@ -50,7 +50,7 @@ redef class Nitiwiki
        # Markdown processor used for inline element such as titles in TOC.
        private var inline_processor: MarkdownProcessor is lazy do
                var proc = new MarkdownProcessor
-               proc.emitter.decorator = new InlineDecorator
+               proc.decorator = new InlineDecorator
                return proc
        end
 
index 33dc61f..7d81633 100644 (file)
@@ -168,7 +168,7 @@ redef class WikiEntry
                var blocks = sidebar.blocks
                for i in [0..blocks.length[ do
                        blocks[i] = md_proc.process(blocks[i].to_s).write_to_string
-                       md_proc.emitter.decorator.headlines.clear
+                       md_proc.decorator.headlines.clear
                end
        end
 end
@@ -212,7 +212,7 @@ redef class WikiArticle
                super
                if not is_dirty and not wiki.force_render or not has_source then return
                content = md_proc.process(md.as(not null))
-               headlines.add_all(md_proc.emitter.decorator.headlines)
+               headlines.add_all(md_proc.decorator.headlines)
        end
 end
 
@@ -243,8 +243,7 @@ class NitiwikiMdProcessor
        var context: WikiEntry
 
        init do
-               emitter = new MarkdownEmitter(self)
-               emitter.decorator = new NitiwikiDecorator(wiki, context)
+               decorator = new NitiwikiDecorator(wiki, context)
        end
 end
 
@@ -259,7 +258,7 @@ class NitiwikiDecorator
        var context: WikiEntry
 
        redef fun add_wikilink(v, token) do
-               var wiki = v.processor.as(NitiwikiMdProcessor).wiki
+               var wiki = v.as(NitiwikiMdProcessor).wiki
                var target: nullable WikiEntry = null
                var anchor: nullable String = null
                var link = token.link
index e842298..1a84b0e 100644 (file)
@@ -30,9 +30,6 @@ import template
 # SEE: `String::md_to_html` for a shortcut.
 class MarkdownProcessor
 
-       # `MarkdownEmitter` used for ouput.
-       var emitter: MarkdownEmitter is noinit, protected writable
-
        # Work in extended mode (default).
        #
        # Behavior changes when using extended mode:
@@ -141,8 +138,6 @@ class MarkdownProcessor
        # Default = `false`
        var no_location = false is writable
 
-       init do self.emitter = new MarkdownEmitter(self)
-
        # Process the mardown `input` string and return the processed output.
        fun process(input: String): Writable do
                # init processor
@@ -155,7 +150,7 @@ class MarkdownProcessor
                parent.remove_surrounding_empty_lines
                recurse(parent, false)
                # output processed text
-               return emitter.emit(parent.kind)
+               return emit(parent.kind)
        end
 
        # Split `input` string into `MDLines` and create a parent `MDBlock` with it.
@@ -498,25 +493,6 @@ class MarkdownProcessor
                return -1
        end
 
-       # Location used for next parsed token.
-       #
-       # This location can be changed by the emitter to adjust with `\n` found
-       # in the input.
-       private fun current_loc: MDLocation do return emitter.current_loc
-end
-
-# Emit output corresponding to blocks content.
-#
-# Blocks are created by a previous pass in `MarkdownProcessor`.
-# The emitter use a `Decorator` to select the output format.
-class MarkdownEmitter
-
-       # Kind of processor used for parsing.
-       type PROCESSOR: MarkdownProcessor
-
-       # Processor containing link refs.
-       var processor: PROCESSOR
-
        # Kind of decorator used for decoration.
        type DECORATOR: Decorator
 
@@ -527,8 +503,7 @@ class MarkdownEmitter
        end
 
        # Create a new `MarkdownEmitter` using a custom `decorator`.
-       init with_decorator(processor: PROCESSOR, decorator: DECORATOR) do
-               init processor
+       init with_decorator(decorator: DECORATOR) do
                self.decorator = decorator
        end
 
@@ -559,7 +534,7 @@ class MarkdownEmitter
                                current_loc.line_start += 1
                                current_loc.column_start = -current_pos
                        end
-                       var mt = processor.token_at(text, current_pos)
+                       var mt = token_at(text, current_pos)
                        if (token != null and not token isa TokenNone) and
                        (mt.is_same_type(token) or
                        (token isa TokenEmStar and mt isa TokenStrongStar) or
@@ -662,72 +637,72 @@ end
 # Default decorator used is `HTMLDecorator`.
 interface Decorator
 
-       # Kind of emitter used for decoration.
-       type EMITTER: MarkdownEmitter
+       # Kind of processor used
+       type PROCESSOR: MarkdownProcessor
 
        # Render a single plain char.
        #
        # Redefine this method to add special escaping for plain text.
-       fun add_char(v: EMITTER, c: Char) do v.addc c
+       fun add_char(v: PROCESSOR, c: Char) do v.addc c
 
        # Render a ruler block.
-       fun add_ruler(v: EMITTER, block: BlockRuler) is abstract
+       fun add_ruler(v: PROCESSOR, block: BlockRuler) is abstract
 
        # Render a headline block with corresponding level.
-       fun add_headline(v: EMITTER, block: BlockHeadline) is abstract
+       fun add_headline(v: PROCESSOR, block: BlockHeadline) is abstract
 
        # Render a paragraph block.
-       fun add_paragraph(v: EMITTER, block: BlockParagraph) is abstract
+       fun add_paragraph(v: PROCESSOR, block: BlockParagraph) is abstract
 
        # Render a code or fence block.
-       fun add_code(v: EMITTER, block: BlockCode) is abstract
+       fun add_code(v: PROCESSOR, block: BlockCode) is abstract
 
        # Render a blockquote.
-       fun add_blockquote(v: EMITTER, block: BlockQuote) is abstract
+       fun add_blockquote(v: PROCESSOR, block: BlockQuote) is abstract
 
        # Render an unordered list.
-       fun add_unorderedlist(v: EMITTER, block: BlockUnorderedList) is abstract
+       fun add_unorderedlist(v: PROCESSOR, block: BlockUnorderedList) is abstract
 
        # Render an ordered list.
-       fun add_orderedlist(v: EMITTER, block: BlockOrderedList) is abstract
+       fun add_orderedlist(v: PROCESSOR, block: BlockOrderedList) is abstract
 
        # Render a list item.
-       fun add_listitem(v: EMITTER, block: BlockListItem) is abstract
+       fun add_listitem(v: PROCESSOR, block: BlockListItem) is abstract
 
        # Render an emphasis text.
-       fun add_em(v: EMITTER, text: Text) is abstract
+       fun add_em(v: PROCESSOR, text: Text) is abstract
 
        # Render a strong text.
-       fun add_strong(v: EMITTER, text: Text) is abstract
+       fun add_strong(v: PROCESSOR, text: Text) is abstract
 
        # Render a strike text.
        #
        # Extended mode only (see `MarkdownProcessor::ext_mode`)
-       fun add_strike(v: EMITTER, text: Text) is abstract
+       fun add_strike(v: PROCESSOR, text: Text) is abstract
 
        # Render a link.
-       fun add_link(v: EMITTER, link: Text, name: Text, comment: nullable Text) is abstract
+       fun add_link(v: PROCESSOR, link: Text, name: Text, comment: nullable Text) is abstract
 
        # Render an image.
-       fun add_image(v: EMITTER, link: Text, name: Text, comment: nullable Text) is abstract
+       fun add_image(v: PROCESSOR, link: Text, name: Text, comment: nullable Text) is abstract
 
        # Render an abbreviation.
-       fun add_abbr(v: EMITTER, name: Text, comment: Text) is abstract
+       fun add_abbr(v: PROCESSOR, name: Text, comment: Text) is abstract
 
        # Render a code span reading from a buffer.
-       fun add_span_code(v: EMITTER, buffer: Text, from, to: Int) is abstract
+       fun add_span_code(v: PROCESSOR, buffer: Text, from, to: Int) is abstract
 
        # Render a text and escape it.
-       fun append_value(v: EMITTER, value: Text) is abstract
+       fun append_value(v: PROCESSOR, value: Text) is abstract
 
        # Render code text from buffer and escape it.
-       fun append_code(v: EMITTER, buffer: Text, from, to: Int) is abstract
+       fun append_code(v: PROCESSOR, buffer: Text, from, to: Int) is abstract
 
        # Render a character escape.
-       fun escape_char(v: EMITTER, char: Char) is abstract
+       fun escape_char(v: PROCESSOR, char: Char) is abstract
 
        # Render a line break
-       fun add_line_break(v: EMITTER) is abstract
+       fun add_line_break(v: PROCESSOR) is abstract
 
        # Generate a new html valid id from a `String`.
        fun strip_id(txt: String): String is abstract
@@ -1157,10 +1132,10 @@ abstract class Block
        var block: MDBlock
 
        # Output `self` using `v.decorator`.
-       fun emit(v: MarkdownEmitter) do v.emit_in(self)
+       fun emit(v: MarkdownProcessor) do v.emit_in(self)
 
        # Emit the containts of `self`, lines or blocks.
-       fun emit_in(v: MarkdownEmitter) do
+       fun emit_in(v: MarkdownProcessor) do
                block.remove_surrounding_empty_lines
                if block.has_lines then
                        emit_lines(v)
@@ -1170,7 +1145,7 @@ abstract class Block
        end
 
        # Emit lines contained in `block`.
-       fun emit_lines(v: MarkdownEmitter) do
+       fun emit_lines(v: MarkdownProcessor) do
                var tpl = v.push_buffer
                var line = block.first_line
                while line != null do
@@ -1188,7 +1163,7 @@ abstract class Block
        end
 
        # Emit sub-blocks contained in `block`.
-       fun emit_blocks(v: MarkdownEmitter) do
+       fun emit_blocks(v: MarkdownProcessor) do
                var block = self.block.first_block
                while block != null do
                        v.push_loc(block.location)
@@ -1984,7 +1959,7 @@ abstract class Token
        var char: Char
 
        # Output that token using `MarkdownEmitter::decorator`.
-       fun emit(v: MarkdownEmitter) do v.decorator.add_char(v, char)
+       fun emit(v: MarkdownProcessor) do v.decorator.add_char(v, char)
 end
 
 # A token without a specific meaning.
@@ -2054,7 +2029,7 @@ abstract class TokenCode
        redef fun emit(v) do
                var current_text = v.current_text.as(not null)
                var a = pos + next_pos + 1
-               var b = v.processor.find_token(current_text, a, self)
+               var b = v.find_token(current_text, a, self)
                if b > 0 then
                        v.current_pos = b + next_pos
                        while a < b and current_text[a] == ' ' do a += 1
@@ -2113,10 +2088,10 @@ abstract class TokenLinkOrImage
        end
 
        # Emit the hyperlink as link or image.
-       private fun emit_hyper(v: MarkdownEmitter) is abstract
+       private fun emit_hyper(v: MarkdownProcessor) is abstract
 
        # Check if the link is a valid link.
-       private fun check_link(v: MarkdownEmitter, out: FlatBuffer, start: Int, token: Token): Int do
+       private fun check_link(v: MarkdownProcessor, out: FlatBuffer, start: Int, token: Token): Int do
                var md = v.current_text
                if md == null then return -1
                var pos
@@ -2134,8 +2109,8 @@ abstract class TokenLinkOrImage
                pos = md.skip_spaces(pos)
                if pos < start then
                        var tid = name.as(not null).write_to_string.to_lower
-                       if v.processor.link_refs.has_key(tid) then
-                               var lr = v.processor.link_refs[tid]
+                       if v.link_refs.has_key(tid) then
+                               var lr = v.link_refs[tid]
                                is_abbrev = lr.is_abbrev
                                link = lr.link
                                comment = lr.title
@@ -2184,15 +2159,15 @@ abstract class TokenLinkOrImage
                                id = name
                        end
                        var tid = id.as(not null).write_to_string.to_lower
-                       if v.processor.link_refs.has_key(tid) then
-                               var lr = v.processor.link_refs[tid]
+                       if v.link_refs.has_key(tid) then
+                               var lr = v.link_refs[tid]
                                link = lr.link
                                comment = lr.title
                        end
                else
                        var tid = name.as(not null).write_to_string.replace("\n", " ").to_lower
-                       if v.processor.link_refs.has_key(tid) then
-                               var lr = v.processor.link_refs[tid]
+                       if v.link_refs.has_key(tid) then
+                               var lr = v.link_refs[tid]
                                link = lr.link
                                comment = lr.title
                                pos = old_pos
@@ -2244,7 +2219,7 @@ class TokenHTML
 
        # Is the HTML valid?
        # Also take care of link and mailto shortcuts.
-       private fun check_html(v: MarkdownEmitter, out: FlatBuffer, md: Text, start: Int): Int do
+       private fun check_html(v: MarkdownProcessor, out: FlatBuffer, md: Text, start: Int): Int do
                # check for auto links
                var tmp = new FlatBuffer
                var pos = md.read_until(tmp, start + 1, ':', ' ', '>', '\n')
index 41d28c1..83e457d 100644 (file)
@@ -49,9 +49,9 @@ var to = opt_to.value
 if to == null or to == "html" then
        # Noop
 else if to == "md" then
-       processor.emitter.decorator = new MdDecorator
+       processor.decorator = new MdDecorator
 else if to == "man" then
-       processor.emitter.decorator = new ManDecorator
+       processor.decorator = new ManDecorator
 else
        print "Unknown output format: {to}"
        exit 1
index ad58649..b08f5b4 100644 (file)
@@ -2735,7 +2735,7 @@ class TestHTMLDecorator
 # c
 """
                var proc = new MarkdownProcessor
-               var decorator = proc.emitter.decorator.as(HTMLDecorator)
+               var decorator = proc.decorator.as(HTMLDecorator)
                proc.process(test)
                var res = ""
                for id, headline in decorator.headlines do
@@ -2852,7 +2852,7 @@ class TestBlockLocation
                ]
                var string =
                "# Title\n* li1\n* li2"
-               proc.emitter.decorator = new TestBlockDecorator(stack)
+               proc.decorator = new TestBlockDecorator(stack)
                proc.process(string)
        end
 
@@ -2870,7 +2870,7 @@ some code
 
 1. li1
 1. li2"""
-               proc.emitter.decorator = new TestBlockDecorator(stack)
+               proc.decorator = new TestBlockDecorator(stack)
                proc.process(string)
        end
 
@@ -2879,7 +2879,7 @@ some code
                        "BlockHeadline: 1,1--1,8",
                        "BlockHeadline: 3,1--3,10"]
                var string ="""# Title\n\n## Title 2"""
-               proc.emitter.decorator = new TestBlockDecorator(stack)
+               proc.decorator = new TestBlockDecorator(stack)
                proc.process(string)
        end
 end
index 7606321..ea174c2 100644 (file)
@@ -41,7 +41,7 @@ end
 redef class Decorator
 
        # Renders a `[[wikilink]]` item.
-       fun add_wikilink(v: EMITTER, token: TokenWikiLink) do
+       fun add_wikilink(v: PROCESSOR, token: TokenWikiLink) do
                if token.name != null then
                        v.add "[[{token.name.as(not null).to_s}|{token.link.as(not null).to_s}]]"
                else
index eedfdf6..7873b64 100644 (file)
@@ -64,7 +64,7 @@ redef class MDoc
        # Renders markdown line as a HTML comment block.
        private fun lines_to_html(lines: Array[String]): Writable do
                var res = new Template
-               var decorator = markdown_proc.emitter.decorator.as(NitdocDecorator)
+               var decorator = markdown_proc.decorator.as(NitdocDecorator)
                decorator.current_mdoc = self
                res.add "<div class=\"nitdoc\">"
                # do not use DocUnit as synopsys
@@ -199,7 +199,7 @@ redef class Model
        # Get a markdown processor for Nitdoc comments.
        var nitdoc_md_processor: MarkdownProcessor is lazy, writable do
                var proc = new MarkdownProcessor
-               proc.emitter.decorator = new NitdocDecorator
+               proc.decorator = new NitdocDecorator
                return proc
        end
 
@@ -208,7 +208,7 @@ redef class Model
        # This processor is specificaly designed to inlinable doc elements like synopsys.
        var nitdoc_inline_processor: MarkdownProcessor is lazy, writable do
                var proc = new MarkdownProcessor
-               proc.emitter.decorator = new InlineDecorator
+               proc.decorator = new InlineDecorator
                return proc
        end
 end
index a31f107..9eee60b 100644 (file)
@@ -57,17 +57,16 @@ redef class ReadmePage
                        v.warning(null, self, "Empty README for group `{mentity}`")
                        return
                end
-               var proc = new MarkdownProcessor
-               proc.emitter = new ReadmeMdEmitter(proc, self, v)
-               proc.emitter.decorator = new ReadmeDecorator
+               var proc = new ReadmeMdProcessor(self, v)
+               proc.decorator = new ReadmeDecorator
                var md = mdoc.content.join("\n")
                proc.process(md)
        end
 end
 
 # Markdown emitter used to produce the `ReadmeArticle`.
-class ReadmeMdEmitter
-       super MarkdownEmitter
+class ReadmeMdProcessor
+       super MarkdownProcessor
 
        # Readme page being decorated.
        var page: ReadmePage
@@ -92,7 +91,7 @@ class ReadmeMdEmitter
        #
        # Called from `add_headline`.
        private fun open_section(lvl: Int, title: String) do
-               var section = new ReadmeSection(title.escape_to_c, title, lvl, processor)
+               var section = new ReadmeSection(title.escape_to_c, title, lvl, self)
                var current_section = self.current_section
                if current_section == null then
                        page.root.add_child(section)
@@ -137,7 +136,7 @@ class ReadmeMdEmitter
        private fun open_article do
                var section: DocComposite = page.root
                if current_section != null then section = current_section.as(not null)
-               var article = new ReadmeArticle("mdarticle-{section.children.length}", null, processor)
+               var article = new ReadmeArticle("mdarticle-{section.children.length}", null, self)
                section.add_child(article)
                context.add article
                push_article article
@@ -191,7 +190,7 @@ class ReadmeDecorator
        # Parser used to process doc commands
        var parser = new DocCommandParser
 
-       redef type EMITTER: ReadmeMdEmitter
+       redef type PROCESSOR: ReadmeMdProcessor
 
        redef fun add_headline(v, block) do
                var txt = block.block.first_line.as(not null).value
@@ -226,7 +225,7 @@ class ReadmeDecorator
        end
 
        # Renders a link to a mentity.
-       private fun add_mentity_link(v: EMITTER, mentity: MEntity, name, comment: nullable Text) do
+       private fun add_mentity_link(v: PROCESSOR, mentity: MEntity, name, comment: nullable Text) do
                # TODO real link
                var link = mentity.full_name
                if name == null then name = mentity.name
@@ -241,7 +240,7 @@ end
 redef class DocCommand
 
        # Render the content of the doc command.
-       fun render(v: ReadmeMdEmitter, token: TokenWikiLink) is abstract
+       fun render(v: ReadmeMdProcessor, token: TokenWikiLink) is abstract
 end
 
 redef class CommentCommand
index 290f04b..a7a5b9a 100644 (file)
@@ -578,7 +578,7 @@ end
 
 redef class ReadmeSection
        redef var html_id is lazy do
-               return markdown_processor.emitter.decorator.strip_id(html_title.as(not null).to_s)
+               return markdown_processor.decorator.strip_id(html_title.as(not null).to_s)
        end
 
        redef var html_title is lazy do
index c116234..629222a 100644 (file)
@@ -187,7 +187,7 @@ redef class Catalog
        do
                # Register `self` to the global NitdocDecorator
                # FIXME this is ugly. But no better idea at the moment.
-               modelbuilder.model.nitdoc_md_processor.emitter.decorator.as(NitdocDecorator).catalog = self
+               modelbuilder.model.nitdoc_md_processor.decorator.as(NitdocDecorator).catalog = self
        end
 
        # The output directory where to generate pages
index a17c8ab..0121162 100644 (file)
@@ -44,7 +44,7 @@ class NitUnitExecutor
        var mdproc = new MarkdownProcessor
 
        init do
-               mdproc.emitter.decorator = new NitunitDecorator(self)
+               mdproc.decorator = new NitunitDecorator(self)
        end
 
        # The associated documentation object
index a5ca012..84dcc8c 100644 (file)
@@ -25,7 +25,7 @@ redef class NitwebConfig
        # Specific Markdown processor to use within Nitweb
        var md_processor: MarkdownProcessor is lazy do
                var proc = new MarkdownProcessor
-               proc.emitter.decorator = new NitwebDecorator(view, modelbuilder)
+               proc.decorator = new NitwebDecorator(view, modelbuilder)
                return proc
        end
 end
@@ -106,7 +106,7 @@ class NitwebInlineDecorator
        end
 end
 
-redef class MarkdownEmitter
+redef class MarkdownProcessor
 
        # Parser used to process doc commands
        var parser = new DocCommandParser
@@ -226,7 +226,7 @@ end
 redef class DocCommand
 
        # Emit the HTML related to the execution of this doc command
-       fun render(v: MarkdownEmitter, token: TokenWikiLink, model: ModelView) do
+       fun render(v: MarkdownProcessor, token: TokenWikiLink, model: ModelView) do
                v.write_error("not yet implemented command `{token.link or else "null"}`")
        end
 end
@@ -253,7 +253,7 @@ redef class CommentCommand
                end
                v.add "</h3>"
                if not opts.has_key("no-comment") then
-                       v.add v.processor.process(mdoc.comment).write_to_string
+                       v.add v.process(mdoc.comment).write_to_string
                end
        end
 end