X-Git-Url: http://nitlanguage.org
diff --git a/src/web/api_docdown.nit b/src/web/api_docdown.nit
index bf4c80f..bbdc9db 100644
--- a/src/web/api_docdown.nit
+++ b/src/web/api_docdown.nit
@@ -19,20 +19,30 @@ import api_graph
intrude import doc_down
intrude import markdown::wikilinks
import doc_commands
+import model::model_index
-# Docdown handler accept docdown as POST data and render it as HTML
-class APIDocdown
- super APIHandler
-
+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, config.modelbuilder)
+ proc.emitter.decorator = new NitwebDecorator(view, modelbuilder)
return proc
end
+end
+
+redef class APIRouter
+ redef init do
+ super
+ use("/docdown/", new APIDocdown(config))
+ end
+end
+
+# Docdown handler accept docdown as POST data and render it as HTML
+class APIDocdown
+ super APIHandler
redef fun post(req, res) do
- res.html md_processor.process(req.body)
+ res.html config.md_processor.process(req.body)
end
end
@@ -48,6 +58,34 @@ class NitwebDecorator
# Modelbuilder used to access code
var modelbuilder: ModelBuilder
+ 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(view, name)
+ if mentity == null then
+ super
+ else
+ v.add ""
+ v.write_mentity_link(mentity, text.write_to_string)
+ v.add "
"
+ end
+ end
+
+ private fun try_find_mentity(view: ModelView, text: String): nullable MEntity do
+ var mentity = view.mentity_by_full_name(text)
+ if mentity != null then return mentity
+
+ var mentities = view.mentities_by_name(text)
+ 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
var link = token.link
if link == null then return
@@ -74,37 +112,94 @@ class NitwebInlineDecorator
end
end
-redef interface DocCommand
-
- # Emit the HTML related to the execution of this doc command
- fun render(v: MarkdownEmitter, token: TokenWikiLink, model: ModelView) do
- write_error(v, "Not yet implemented command `{token.link or else "null"}`")
- end
+redef class MarkdownEmitter
+ # Find the MEntity that matches `name`.
+ #
+ # Write an error if the entity is not found
+ fun find_mentity(model: ModelView, name: nullable String): nullable MEntity do
+ if name == null then
+ write_error("No MEntity found")
+ return null
+ end
+ # Lookup by full name
+ var mentity = model.mentity_by_full_name(name)
+ if mentity != null then return mentity
- # Find the MEntity ` with `full_name`.
- fun find_mentity(model: ModelView, full_name: nullable String): nullable MEntity do
- if full_name == null then return null
- return model.mentity_by_full_name(full_name.from_percent_encoding)
+ var mentities = model.mentities_by_name(name)
+ if mentities.is_empty then
+ var suggest = model.find(name, 3)
+ var msg = new Buffer
+ msg.append "No MEntity found for name `{name}`"
+ if suggest.not_empty then
+ msg.append " (suggestions: "
+ var i = 0
+ for s in suggest do
+ msg.append "`{s.full_name}`"
+ if i < suggest.length - 1 then msg.append ", "
+ i += 1
+ end
+ msg.append ")"
+ end
+ write_error(msg.write_to_string)
+ return null
+ else if mentities.length > 1 then
+ var msg = new Buffer
+ msg.append "Conflicts for name `{name}`"
+ msg.append " (conflicts: "
+ var i = 0
+ for s in mentities do
+ msg.append "`{s.full_name}`"
+ if i < mentities.length - 1 then msg.append ", "
+ i += 1
+ end
+ msg.append ")"
+ write_warning(msg.write_to_string)
+ end
+ return mentities.first
end
# Write a warning in the output
- fun write_warning(v: MarkdownEmitter, text: String) do
- v.emit_text "
Warning: {text}
" + fun write_warning(text: String) do + emit_text "Warning: {text}
" end # Write an error in the output - fun write_error(v: MarkdownEmitter, text: String) do - v.emit_text "Error: {text}
" + fun write_error(text: String) do + emit_text "Error: {text}
" end # Write a link to a mentity in the output - fun write_mentity_link(v: MarkdownEmitter, mentity: MEntity) do + fun write_mentity_link(mentity: MEntity, text: nullable String) do var link = mentity.web_url - var name = mentity.name + var name = text or else mentity.name var mdoc = mentity.mdoc_or_fallback var comment = null if mdoc != null then comment = mdoc.synopsis - v.decorator.add_link(v, link, name, comment) + decorator.add_link(self, link, name, comment) + end + + # Write a mentity list in the output + fun write_mentity_list(mentities: Collection[MEntity]) do + add "" @@ -254,16 +322,26 @@ end redef class GraphCommand redef fun render(v, token, model) do if args.is_empty then - write_error(v, "Expected one arg: the MEntity name") + v.write_error("Expected one arg: the MEntity name") return end var name = args.first - var mentity = find_mentity(model, name) - if mentity == null then - write_error(v, "No MEntity found for name `{name}`") - return - end + var mentity = v.find_mentity(model, name) + if mentity == null then return var g = new InheritanceGraph(mentity, model) v.add g.draw(3, 3).to_svg 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