X-Git-Url: http://nitlanguage.org diff --git a/src/highlight.nit b/src/highlight.nit index 39a042a..424824f 100644 --- a/src/highlight.nit +++ b/src/highlight.nit @@ -48,13 +48,87 @@ class HighlightVisitor html.add_class("nitcode") end + # When highlighting a node, also consider the loose tokens around it. + # + # Loose tokens are tokens discarded from the AST but attached before + # or after some non-loose tokens. See `Token::is_loose`. + # + # When this flag is set to `true`, the loose tokens that are before the + # first token and after the last token are also highlighted. + # + # Default: false. + var include_loose_tokens = false is writable + + # When highlighting a node, the first and the last lines are fully included. + # + # If the highlighted node starts (or ends) in the middle of a line, + # this flags forces the whole line to be highlighted. + # + # Default: false + var include_whole_lines = false is writable + # The entry-point of the highlighting. # Will fill `html` with the generated HTML content. fun enter_visit(n: ANode) do n.parentize_tokens - var s = n.location.file - htmlize(s.first_token.as(not null), s.last_token.as(not null)) + + var f + var l + + if n isa Token then + f = n + l = n + else + assert n isa Prod + f = n.first_token + if f == null then return + l = n.last_token + if l == null then return + end + + if include_loose_tokens then + if f.prev_looses.not_empty then f = f.prev_looses.first + if l.next_looses.not_empty then l = l.next_looses.last + end + + if include_whole_lines then + f = f.first_real_token_in_line + l = l.last_real_token_in_line + end + + htmlize(f, l) + end + + private fun full_tag(anode: ANode, hv: HighlightVisitor): nullable HTMLTag + do + var tag = anode.make_tag(hv) + if tag == null then return null + var infobox = anode.infobox(hv) + if infobox == null and anode isa Token then + var pa = anode.parent + if pa != null then + var c = anode + if c isa TId or c isa TClassid or c isa TAttrid or c isa TokenLiteral or c isa TokenOperator or c isa TComment and pa isa ADoc then + infobox = pa.decorate_tag(hv, tag, anode) + end + end + end + var messages = anode.location.messages + if messages != null then + tag.css("border-bottom", "solid 2px red") + if infobox == null then + infobox = new HInfoBox(hv, "Messages") + end + var c = infobox.new_dropdown("{messages.length} message(s)", "") + for m in messages do + c.open("li").append(m.text) + end + end + if infobox != null then + tag.attach_infobox(infobox) + end + return tag end # Produce HTML between two tokens @@ -79,11 +153,9 @@ class HighlightVisitor if c0 != null then starting = c0.starting_prods if starting != null then for p in starting do if not p.is_block then continue - var tag = p.make_tag(hv) + var tag = full_tag(p, hv) if tag == null then continue tag.add_class("foldable") - var infobox = p.infobox(hv) - if infobox != null then tag.attach_infobox(infobox) stack2.add(html) html.add tag html = tag @@ -108,10 +180,8 @@ class HighlightVisitor starting = c.starting_prods if starting != null then for p in starting do if not p.is_span then continue - var tag = p.make_tag(hv) + var tag = full_tag(p, hv) if tag == null then continue - var infobox = p.infobox(hv) - if infobox != null then tag.attach_infobox(infobox) stack2.add(html) html.add tag html = tag @@ -122,17 +192,8 @@ class HighlightVisitor if c isa TEol then html.append "\n" else - var tag = c.make_tag(hv) - var pa = c.parent - var infobox = null - if c isa TId or c isa TClassid or c isa TAttrid or c isa TokenLiteral or c isa TokenOperator then - assert c != null - if pa != null then infobox = pa.decorate_tag(hv, tag, c) - else if c isa TComment and pa isa ADoc then - infobox = pa.decorate_tag(hv, tag, c) - end - if infobox != null then tag.attach_infobox(infobox) - html.add tag + var tag = full_tag(c, hv) + if tag != null then html.add tag end # Handle ending span productions @@ -165,8 +226,8 @@ class HighlightVisitor c = n end - assert stack.is_empty - assert stack2.is_empty + #assert stack.is_empty + #assert stack2.is_empty end # Return a default CSS content related to CSS classes used in the `html` tree. @@ -334,7 +395,7 @@ redef class MModule # The module HTML page fun href: String do - return name + ".html" + return c_name + ".html" end redef fun linkto do return linkto_text(name) @@ -355,7 +416,7 @@ redef class MClassDef res.new_field("class").text(mclass.name) else res.new_field("redef class").text(mclass.name) - res.new_field("intro").add mclass.intro.linkto_text("in {mclass.intro.mmodule.to_s}") + res.new_field("intro").add mclass.intro.linkto_text("in {mclass.intro_mmodule.to_s}") end var mdoc = self.mdoc if mdoc == null then mdoc = mclass.intro.mdoc @@ -566,7 +627,6 @@ redef class MSignature end redef class CallSite - super HInfoBoxable redef fun infobox(v) do var res = new HInfoBox(v, "call {mpropdef}") @@ -638,6 +698,7 @@ redef class AStdClassdef end redef fun decorate_tag(v, res, token) do + if not token isa TClassid then return null res.add_class("nc_def") var md = mclassdef @@ -723,7 +784,7 @@ redef class AVardeclExpr end end -redef class AForExpr +redef class AForGroup redef fun decorate_tag(v, res, token) do if not token isa TId then return null