src/doc/commands/templates: rename `templates_html` in `html_model`
[nit.git] / src / doc / commands / commands_html.nit
index c712e6c..2d485f6 100644 (file)
 # Render commands results as HTML
 module commands_html
 
-import commands::commands_graph
-import commands::commands_usage
-import commands::commands_ini
-import commands::commands_main
+import commands_catalog
+import commands_graph
+import commands_ini
+import commands_main
+import commands_parser
+import commands_usage
 
-import templates::templates_html
-import doc_down
-import highlight
+import templates::html_model
+intrude import markdown::wikilinks
 
 redef class DocCommand
 
@@ -125,11 +126,37 @@ redef class CmdEntityLink
        end
 end
 
-redef class CmdEntityCode
+redef class CmdCode
        redef fun to_html do
-               var output = render_code(node)
-               if output == null then return ""
-               return "<pre>{output.write_to_string}</pre>"
+               var node = self.node
+               if node == null then return ""
+
+               var code = render_code(node)
+               return "<pre>{code.write_to_string}</pre>"
+       end
+
+       redef fun render_code(node) do
+               if format == "html" then
+                       var hl = new CmdHtmlightVisitor
+                       hl.show_infobox = false
+                       hl.highlight_node node
+                       return hl.html
+               end
+               return super
+       end
+end
+
+# Custom HtmlightVisitor for commands
+#
+# We create a new subclass so its behavior can be refined in clients without
+# breaking the main implementation.
+class CmdHtmlightVisitor
+       super HtmlightVisitor
+
+       redef fun hrefto(mentity) do
+               if mentity isa MClassDef then return mentity.mclass.html_url
+               if mentity isa MPropDef then return mentity.mproperty.html_url
+               return mentity.html_url
        end
 end
 
@@ -334,12 +361,104 @@ redef class CmdTesting
        end
 end
 
-# Misc
+# MDoc
 
-redef class CmdHtmlightVisitor
-       redef fun hrefto(mentity) do
-               if mentity isa MClassDef then return mentity.mclass.html_url
-               if mentity isa MPropDef then return mentity.mproperty.html_url
-               return mentity.html_url
+# Custom Markdown processor able to process doc commands
+class CmdDecorator
+       super NitdocDecorator
+
+       redef type PROCESSOR: CmdMarkdownProcessor
+
+       # Model used by wikilink commands to find entities
+       var model: Model
+
+       # Filter to apply if any
+       var filter: nullable ModelFilter
+
+       redef fun add_span_code(v, buffer, from, to) do
+               var text = new FlatBuffer
+               buffer.read(text, from, to)
+               var name = text.write_to_string
+               name = name.replace("nullable ", "")
+               var mentity = try_find_mentity(name)
+               if mentity == null then
+                       super
+               else
+                       v.add "<code>"
+                       v.emit_text mentity.html_link.write_to_string
+                       v.add "</code>"
+               end
+       end
+
+       private fun try_find_mentity(text: String): nullable MEntity do
+               var mentity = model.mentity_by_full_name(text, filter)
+               if mentity != null then return mentity
+
+               var mentities = model.mentities_by_name(text, filter)
+               if mentities.is_empty then
+                       return null
+               else if mentities.length > 1 then
+                       # TODO smart resolve conflicts
+               end
+               return mentities.first
+       end
+
+       redef fun add_wikilink(v, token) do
+               v.render_wikilink(token, model)
+       end
+end
+
+# Same as `InlineDecorator` but with wikilink commands handling
+class CmdInlineDecorator
+       super InlineDecorator
+
+       redef type PROCESSOR: CmdMarkdownProcessor
+
+       # Model used by wikilink commands to find entities
+       var model: Model
+
+       redef fun add_wikilink(v, token) do
+               v.render_wikilink(token, model)
+       end
+end
+
+# Custom MarkdownEmitter for commands
+class CmdMarkdownProcessor
+       super MarkdownProcessor
+
+       # Parser used to process doc commands
+       var parser: CommandParser
+
+       # Render a wikilink
+       fun render_wikilink(token: TokenWikiLink, model: Model) do
+               var link = token.link
+               if link == null then return
+               var name = token.name
+               if name != null then link = "{name} | {link}"
+
+               var command = parser.parse(link.write_to_string)
+               var error = parser.error
+
+               if error isa CmdError then
+                       emit_text error.to_html.write_to_string
+                       return
+               end
+               if error isa CmdWarning then
+                       emit_text error.to_html.write_to_string
+               end
+               add command.as(not null).to_html
+       end
+end
+
+redef class Text
+       # Read `self` between `nstart` and `nend` (excluded) and writte chars to `out`.
+       private fun read(out: FlatBuffer, nstart, nend: Int): Int do
+               var pos = nstart
+               while pos < length and pos < nend do
+                       out.add self[pos]
+                       pos += 1
+               end
+               if pos == length then return -1
+               return pos
        end
 end