scite-context-lexer-bibtex.lua /size: 6147 b    last modification: 2021-10-28 13:49
1local info = {
2    version   = 1.002,
3    comment   = "scintilla lpeg lexer for bibtex",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files",
7}
8
9local global, string, table, lpeg = _G, string, table, lpeg
10local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
11local type = type
12
13local lexers           = require("scite-context-lexer")
14
15local patterns         = lexers.patterns
16local token            = lexers.token
17
18local bibtexlexer      = lexers.new("bib","scite-context-lexer-bibtex")
19local bibtexwhitespace = bibtexlexer.whitespace
20
21local escape, left, right = P("\\"), P('{'), P('}')
22
23patterns.balanced = P {
24    [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
25    [2] = left * V(1) * right
26}
27
28-- taken from bibl-bib.lua
29
30local anything     = patterns.anything
31local percent      = P("%")
32local start        = P("@")
33local comma        = P(",")
34local hash         = P("#")
35local escape       = P("\\")
36local single       = P("'")
37local double       = P('"')
38local left         = P('{')
39local right        = P('}')
40local lineending   = S("\n\r")
41local space        = S(" \t\n\r\f")
42local spaces       = space^1
43local equal        = P("=")
44
45local keyword      = (R("az","AZ","09") + S("@_:-"))^1
46----- s_quoted     = ((escape*single) + spaces + (1-single))^0
47----- d_quoted     = ((escape*double) + spaces + (1-double))^0
48local s_quoted     = ((escape*single) + (1-single))^0
49local d_quoted     = ((escape*double) + (1-double))^0
50
51local balanced     = patterns.balanced
52
53local t_spacing    = token(bibtexwhitespace,space^1)
54local t_optionalws = token("default",space^1)^0
55
56local t_equal      = token("operator",equal)
57local t_left       = token("grouping",left)
58local t_right      = token("grouping",right)
59local t_comma      = token("operator",comma)
60local t_hash       = token("operator",hash)
61
62local t_s_value    = token("operator",single)
63                   * token("text",s_quoted)
64                   * token("operator",single)
65local t_d_value    = token("operator",double)
66                   * token("text",d_quoted)
67                   * token("operator",double)
68local t_b_value    = token("operator",left)
69                   * token("text",balanced)
70                   * token("operator",right)
71local t_r_value    = token("text",keyword)
72
73local t_keyword    = token("keyword",keyword)
74local t_key        = token("command",keyword)
75local t_label      = token("warning",keyword)
76
77local t_somevalue  = t_s_value + t_d_value + t_b_value + t_r_value
78local t_value      = t_somevalue
79                   * ((t_optionalws * t_hash * t_optionalws) * t_somevalue)^0
80
81local t_assignment = t_optionalws
82                   * t_key
83                   * t_optionalws
84                   * t_equal
85                   * t_optionalws
86                   * t_value
87
88local t_shortcut   = t_keyword
89                   * t_optionalws
90                   * t_left
91                   * t_optionalws
92                   * (t_assignment * t_comma^0)^0
93                   * t_optionalws
94                   * t_right
95
96local t_definition = t_keyword
97                   * t_optionalws
98                   * t_left
99                   * t_optionalws
100                   * t_label
101                   * t_optionalws
102                   * t_comma
103                   * (t_assignment * t_comma^0)^0
104                   * t_optionalws
105                   * t_right
106
107local t_comment    = t_keyword
108                   * t_optionalws
109                   * t_left
110                   * token("text",(1-t_right)^0)
111                   * t_optionalws
112                   * t_right
113
114local t_forget     = token("comment",percent^1 * (1-lineending)^0)
115
116local t_rest       = token("default",anything)
117
118-- this kind of lexing seems impossible as the size of the buffer passed to the lexer is not
119-- large enough .. but we can cheat and use this:
120--
121-- function OnOpen(filename) editor:Colourise(1,editor.TextLength) end -- or is it 0?
122
123-- somehow lexing fails on this more complex lexer when we insert something, there is no
124-- backtracking to whitespace when we have no embedded lexer, so we fake one ... this works
125-- to some extend but not in all cases (e.g. editing inside line fails) .. maybe i need to
126-- patch the dll ... (better not)
127
128local dummylexer = lexers.load("scite-context-lexer-dummy","bib-dum")
129
130local dummystart = token("embedded",P("\001")) -- an unlikely to be used character
131local dummystop  = token("embedded",P("\002")) -- an unlikely to be used character
132
133lexers.embed(bibtexlexer,dummylexer,dummystart,dummystop)
134
135-- maybe we need to define each functional block as lexer (some 4) so i'll do that when
136-- this issue is persistent ... maybe consider making a local lexer options (not load,
137-- just lexers.new or so) .. or maybe do the reverse, embed the main one in a dummy child
138
139bibtexlexer.rules = {
140    { "whitespace",  t_spacing    },
141    { "forget",      t_forget     },
142    { "shortcut",    t_shortcut   },
143    { "definition",  t_definition },
144    { "comment",     t_comment    },
145    { "rest",        t_rest       },
146}
147
148-- local t_assignment = t_key
149--                    * t_optionalws
150--                    * t_equal
151--                    * t_optionalws
152--                    * t_value
153--
154-- local t_shortcut   = t_keyword
155--                    * t_optionalws
156--                    * t_left
157--
158-- local t_definition = t_keyword
159--                    * t_optionalws
160--                    * t_left
161--                    * t_optionalws
162--                    * t_label
163--                    * t_optionalws
164--                    * t_comma
165--
166-- bibtexlexer.rules = {
167--     { "whitespace",  t_spacing    },
168--     { "assignment",  t_assignment },
169--     { "definition",  t_definition },
170--     { "shortcut",    t_shortcut   },
171--     { "right",       t_right      },
172--     { "comma",       t_comma      },
173--     { "forget",      t_forget     },
174--     { "comment",     t_comment    },
175--     { "rest",        t_rest       },
176-- }
177
178bibtexlexer.folding = {
179    ["{"] = { ["grouping"] =  1 },
180    ["}"] = { ["grouping"] = -1 },
181}
182
183return bibtexlexer
184