highlight: extract HTML stuff from highlight into htmlight
[nit.git] / src / highlight.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Highlighting of Nit AST
16 module highlight
17
18 import frontend
19 import astutil
20
21 # Visitor used to produce a HTML tree based on a AST on a `Source`
22 class AbstractHighlightVisitor
23 # The first line to generate, null if start at the first line
24 var first_line: nullable Int = null is writable
25
26 # The last line to generate, null if finish at the last line
27 var last_line: nullable Int = null is writable
28
29 # When highlighting a node, show its messages (errors, warnings), if any.
30 #
31 # default: true
32 var show_messages = true is writable
33
34 # When highlighting a node, also consider the loose tokens around it.
35 #
36 # Loose tokens are tokens discarded from the AST but attached before
37 # or after some non-loose tokens. See `Token::is_loose`.
38 #
39 # When this flag is set to `true`, the loose tokens that are before the
40 # first token and after the last token are also highlighted.
41 #
42 # Default: false.
43 var include_loose_tokens = false is writable
44
45 # When highlighting a node, the first and the last lines are fully included.
46 #
47 # If the highlighted node starts (or ends) in the middle of a line,
48 # this flags forces the whole line to be highlighted.
49 #
50 # Default: false
51 var include_whole_lines = false is writable
52
53 # Highlight a AST element.
54 fun highlight_node(n: ANode)
55 do
56 n.parentize_tokens
57
58 var f
59 var l
60
61 if n isa Token then
62 f = n
63 l = n
64 else
65 assert n isa Prod
66 f = n.first_token
67 if f == null then return
68 l = n.last_token
69 if l == null then return
70 end
71
72 if include_loose_tokens then
73 if f.prev_looses.not_empty then f = f.prev_looses.first
74 if l.next_looses.not_empty then l = l.next_looses.last
75 end
76
77 var line = first_line
78 if line != null then
79 while f.location.line_start < line do
80 f = f.next_token
81 if f == null then return
82 end
83 end
84
85 line = last_line
86 if line != null then
87 while l.location.line_end > line do
88 l = l.prev_token
89 if l == null then return
90 end
91 end
92
93 if include_whole_lines then
94 f = f.first_real_token_in_line
95 l = l.last_real_token_in_line
96 end
97
98 do_highlight(f, l)
99 end
100
101 # Highlight a full lexed source file.
102 #
103 # REQUIRE `source.first_token != null`
104 fun highlight_source(source: SourceFile)
105 do
106 do_highlight(source.first_token.as(not null), null)
107 end
108
109 # Low-level highlighting between 2 tokens
110 protected fun do_highlight(first_token: Token, last_token: nullable Token) is abstract
111 end