1if not modules then modules = { } end modules ['mtx-vscode'] = {
2 version = 1.000,
3 comment = "this script is experimental",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE",
6 license = "see context related readme files"
7}
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131local helpinfo = [[
132<?xml version="1.0"?>
133<application>
134 <metadata>
135 <entry name="name">mtx-vscode</entry>
136 <entry name="detail">vscode extension generator</entry>
137 <entry name="version">1.00</entry>
138 </metadata>
139 <flags>
140 <category name="basic">
141 <subcategory>
142 <flag name="generate"><short>generate extension in sync with current version</short></flag>
143 <flag name="program"><short>use the given binary (e.g. codium, default: code)</short></flag>
144 <flag name="start"><short>start vscode with extension context</short></flag>
145 <flag name="lsfile"><short>generate language server file (work in progress)</short></flag>
146 </subcategory>
147 </category>
148 </flags>
149 <examples>
150 <category>
151 <title>Example</title>
152 <subcategory>
153 <example><command>mtxrun --script vscode --generate e:/vscode/extensions</command></example>
154 <example><command>mtxrun --script vscode --generate</command></example>
155 <example><command>mtxrun --script vscode --start</command></example>
156 <example><command>mtxrun --script vscode --program=codium --start</command></example>
157 </subcategory>
158 </category>
159 </examples>
160</application>
161]]
162
163local application = logs.application {
164 name = "mtx-vscode",
165 banner = "vscode extension generator",
166 helpinfo = helpinfo,
167}
168
169local concat = table.concat
170
171local report = application.report
172
173scripts = scripts or { }
174scripts.vscode = scripts.vscode or { }
175
176local readmedata = [[
177These files are generated. You can use these extensions with for instance:
178
179 code.exe --extensions-dir <someplace>/tex/texmf-context/context/data/vscode/extensions --install-extension context
180
181There are examples of scripts and keybindings too.
182]]
183
184local function locate()
185 local name = resolvers.findfile("vscode-context.readme")
186 if name and name ~= "" then
187 local path = file.dirname(file.dirname(name))
188 if lfs.isdir(path) then
189 return path
190 end
191 end
192end
193
194function scripts.vscode.generate(targetpath)
195
196 local targetpath = targetpath or environment.files[1] or locate()
197
198 if not targetpath or targetpath == "" or not lfs.isdir(targetpath) then
199 report("invalid targetpath %a",targetpath)
200 return
201 end
202
203 local contextpath = string.gsub(targetpath,"\\","/") .. "/context"
204
205 dir.makedirs(contextpath)
206
207 if not lfs.chdir(contextpath) then
208 return
209 end
210
211 local syntaxpath = contextpath .. "/syntaxes"
212 local themepath = contextpath .. "/themes"
213 local taskpath = contextpath .. "/tasks"
214 local keybindingpath = contextpath .. "/keybindings"
215 local settingspath = contextpath .. "/settings"
216
217 dir.makedirs(syntaxpath)
218 dir.makedirs(themepath)
219 dir.makedirs(taskpath)
220 dir.makedirs(keybindingpath)
221 dir.makedirs(settingspath)
222
223 if not lfs.isdir(syntaxpath) then return end
224 if not lfs.isdir(themepath) then return end
225 if not lfs.isdir(taskpath) then return end
226 if not lfs.isdir(keybindingpath) then return end
227 if not lfs.isdir(settingspath) then return end
228
229
230
231 local languages = { }
232 local grammars = { }
233 local themes = { }
234 local tasks = { }
235 local keybindings = { }
236
237 local function registerlexer(lexer)
238
239 local category = lexer.category
240 local contextid = "context." .. category
241 local scope = "source." .. contextid
242
243 local setupfile = "./settings/context-settings-" .. category .. ".json"
244 local grammarfile = "./syntaxes/context-syntax-" .. category .. ".json"
245
246 local grammar = utilities.json.tojson {
247 name = contextid,
248 scopeName = scope,
249 version = lexer.version,
250 repository = lexer.repository,
251 patterns = lexer.patterns,
252 }
253
254 local setup = utilities.json.tojson(lexer.setup)
255
256 local suffixes = lexer.suffixes or { }
257 local extensions = { }
258
259 for i=1,#suffixes do
260 extensions[i] = "." .. string.gsub(suffixes[i],"%.","")
261 end
262
263 table.sort(extensions)
264
265 languages[#languages+1] = {
266 id = contextid,
267 extensions = #extensions > 0 and extensions or nil,
268 aliases = { lexer.description },
269 configuration = setupfile,
270 }
271
272 grammars[#grammars+1] = {
273 language = contextid,
274 scopeName = "source." .. contextid,
275 path = grammarfile,
276 }
277
278 report("saving grammar for %a in %a",category,grammarfile)
279 report("saving setup for %a in %a",category,setupfile)
280
281 io.savedata(grammarfile, grammar)
282 io.savedata(setupfile, setup)
283
284 end
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 local function registertheme(theme)
301
302 local category = theme.category
303 local filename = "./themes/" .. category .. ".json"
304
305 themes[#themes+1] = {
306 label = theme.description,
307 uiTheme = "vs",
308 path = filename,
309 }
310
311 local data = utilities.json.tojson {
312 ["$schema"] = "vscode://schemas/color-theme",
313 ["name"] = category,
314 ["colors"] = theme.colors,
315 ["tokenColors"] = theme.styles,
316 ["settings"] = theme.settings,
317 }
318
319 report("saving theme %a in %a",category,filename)
320
321 io.savedata(filename,data)
322
323 end
324
325 local function registertask(task)
326
327 local category = task.category
328 local filename = "./tasks/" .. category .. ".json"
329
330 tasks[#tasks+1] = {
331 label = task.description,
332 path = filename,
333 }
334
335 local data = utilities.json.tojson {
336 ["name"] = category,
337 ["tasks"] = task.tasks,
338 }
339
340 report("saving task %a in %a",category,filename)
341 io.savedata(filename,data)
342
343 end
344
345 local function registerkeybinding(keybinding)
346
347 local bindings = keybinding.keybindings
348
349 if bindings then
350
351 local category = keybinding.category
352 local filename = "./keybindings/" .. category .. ".json"
353
354 report("saving keybinding %a in %a",category,filename)
355
356 io.savedata(filename,utilities.json.tojson(bindings))
357
358 for i=1,#bindings do
359 keybindings[#keybindings+1] = bindings[i]
360 end
361
362 end
363 end
364
365 local function savepackage()
366
367 local packagefile = "package.json"
368 local whateverfile = "package.nls.json"
369 local readmefile = "vscode-context.readme"
370
371 local specification = utilities.json.tojson {
372 name = "context",
373 displayName = "ConTeXt",
374 description = "ConTeXt Syntax Highlighting",
375 publisher = "ConTeXt Development Team",
376 publisher = "cdt",
377 version = "1.0.0",
378 engines = {
379 vscode = "*"
380 },
381 categories = {
382 "Programming Languages",
383 "Lexers",
384 "Syntaxes"
385 },
386 contributes = {
387 languages = languages,
388 grammars = grammars,
389 themes = themes,
390 tasks = tasks,
391 keybindings = keybindings,
392 },
393
394 }
395
396 report("saving package in %a",packagefile)
397
398 io.savedata(packagefile,specification)
399
400 local whatever = utilities.json.tojson {
401 displayName = "ConTeXt",
402 description = "Provides syntax highlighting and bracket matching in ConTeXt files.",
403 }
404
405 report("saving whatever in %a",whateverfile)
406
407 io.savedata(whateverfile,whatever)
408
409 report("saving readme in %a",readmefile)
410
411 io.savedata(readmefile,readmedata)
412
413 end
414
415
416
417 do
418
419 local mycolors = {
420 red = "#7F0000",
421 green = "#007F00",
422 blue = "#00007F",
423 cyan = "#007F7F",
424 magenta = "#7F007F",
425 yellow = "#7F7F00",
426 orange = "#B07F00",
427 white = "#FFFFFF",
428 light = "#CFCFCF",
429 grey = "#808080",
430 dark = "#4F4F4F",
431 black = "#000000",
432 selection = "#F7F7F7",
433 logpanel = "#E7E7E7",
434 textpanel = "#CFCFCF",
435 linepanel = "#A7A7A7",
436 tippanel = "#444444",
437 right = "#0000FF",
438 wrong = "#FF0000",
439 default = "#000000",
440 reverse = "#FFFFFF",
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466 }
467
468 local colors = {
469 ["editor.background"] = mycolors.textpanel,
470 ["editor.foreground"] = mycolors.default,
471 ["editorLineNumber.foreground"] = mycolors.default,
472 ["editorIndentGuide.background"] = mycolors.textpanel,
473 ["editorBracketMatch.background"] = mycolors.textpanel,
474 ["editorBracketMatch.border"] = mycolors.orange,
475 ["editor.lineHighlightBackground"] = mycolors.textpanel,
476 ["focusBorder"] = mycolors.default,
477
478 ["activityBar.background"] = mycolors.default,
479
480 ["editorGutter.background"] = mycolors.linepanel,
481 ["editorGutter.foreground"] = mycolors.default,
482 ["editorGutter.border"] = mycolors.reverse,
483 ["sideBarTitle.foreground"] = mycolors.default,
484 ["sideBarSectionHeader.background"] = mycolors.linepanel,
485 ["sideBarSectionHeader.foreground"] = mycolors.default,
486
487 ["statusBar.foreground"] = mycolors.default,
488 ["statusBar.background"] = mycolors.linepanel,
489 ["statusBar.border"] = mycolors.reverse,
490 ["statusBar.noFolderForeground"] = mycolors.default,
491 ["statusBar.noFolderBackground"] = mycolors.linepanel,
492 ["statusBar.debuggingForeground"] = mycolors.default,
493 ["statusBar.debuggingBackground"] = mycolors.linepanel,
494
495 ["notification.background"] = mycolors.default,
496 }
497
498 local styles = {
499
500 { scope = "context.whitespace", settings = { } },
501 { scope = "context.default", settings = { foreground = mycolors.default } },
502 { scope = "context.number", settings = { foreground = mycolors.cyan } },
503 { scope = "context.comment", settings = { foreground = mycolors.yellow } },
504 { scope = "context.keyword", settings = { foreground = mycolors.blue, fontStyle = "bold" } },
505 { scope = "context.string", settings = { foreground = mycolors.magenta } },
506 { scope = "context.error", settings = { foreground = mycolors.red } },
507 { scope = "context.label", settings = { foreground = mycolors.red, fontStyle = "bold" } },
508 { scope = "context.nothing", settings = { } },
509 { scope = "context.class", settings = { foreground = mycolors.default, fontStyle = "bold" } },
510 { scope = "context.function", settings = { foreground = mycolors.default, fontStyle = "bold" } },
511 { scope = "context.constant", settings = { foreground = mycolors.cyan, fontStyle = "bold" } },
512 { scope = "context.operator", settings = { foreground = mycolors.blue } },
513 { scope = "context.regex", settings = { foreground = mycolors.magenta } },
514 { scope = "context.preprocessor", settings = { foreground = mycolors.yellow, fontStyle = "bold" } },
515 { scope = "context.tag", settings = { foreground = mycolors.cyan } },
516 { scope = "context.type", settings = { foreground = mycolors.blue } },
517 { scope = "context.variable", settings = { foreground = mycolors.default } },
518 { scope = "context.identifier", settings = { } },
519 { scope = "context.linenumber", settings = { background = mycolors.linepanel } },
520 { scope = "context.bracelight", settings = { foreground = mycolors.orange, fontStyle = "bold" } },
521 { scope = "context.bracebad", settings = { foreground = mycolors.orange, fontStyle = "bold" } },
522 { scope = "context.controlchar", settings = { } },
523 { scope = "context.indentguide", settings = { foreground = mycolors.linepanel, back = colors.reverse } },
524 { scope = "context.calltip", settings = { foreground = mycolors.reverse, back = colors.tippanel } },
525 { scope = "context.invisible", settings = { background = mycolors.orange } },
526 { scope = "context.quote", settings = { foreground = mycolors.blue, fontStyle = "bold" } },
527 { scope = "context.special", settings = { foreground = mycolors.blue } },
528 { scope = "context.extra", settings = { foreground = mycolors.yellow } },
529 { scope = "context.embedded", settings = { foreground = mycolors.default, fontStyle = "bold" } },
530 { scope = "context.char", settings = { foreground = mycolors.magenta } },
531 { scope = "context.reserved", settings = { foreground = mycolors.magenta, fontStyle = "bold" } },
532 { scope = "context.definition", settings = { foreground = mycolors.default, fontStyle = "bold" } },
533 { scope = "context.okay", settings = { foreground = mycolors.dark } },
534 { scope = "context.warning", settings = { foreground = mycolors.orange } },
535 { scope = "context.standout", settings = { foreground = mycolors.orange, fontStyle = "bold" } },
536 { scope = "context.command", settings = { foreground = mycolors.green, fontStyle = "bold" } },
537 { scope = "context.internal", settings = { foreground = mycolors.orange, fontStyle = "bold" } },
538 { scope = "context.preamble", settings = { foreground = mycolors.yellow } },
539 { scope = "context.grouping", settings = { foreground = mycolors.red } },
540 { scope = "context.primitive", settings = { foreground = mycolors.blue, fontStyle = "bold" } },
541 { scope = "context.plain", settings = { foreground = mycolors.dark, fontStyle = "bold" } },
542 { scope = "context.user", settings = { foreground = mycolors.green } },
543 { scope = "context.data", settings = { foreground = mycolors.cyan, fontStyle = "bold" } },
544 { scope = "context.text", settings = { foreground = mycolors.default } },
545
546 { scope = { "emphasis" }, settings = { fontStyle = "italic" } },
547 { scope = { "strong" }, settings = { fontStyle = "bold" } },
548
549 { scope = { "comment" }, settings = { foreground = mycolors.default } },
550 { scope = { "string" }, settings = { foreground = mycolors.magenta } },
551
552 {
553 scope = {
554 "constant.numeric",
555 "constant.language.null",
556 "variable.language.this",
557 "support.type.primitive",
558 "support.function",
559 "support.variable.dom",
560 "support.variable.property",
561 "support.variable.property",
562 "meta.property-name",
563 "meta.property-value",
564 "support.constant.handlebars"
565 },
566 settings = {
567 foreground = mycolors.cyan,
568 }
569 },
570
571 {
572 scope = {
573 "keyword",
574 "storage.modifier",
575 "storage.type",
576 "variable.parameter"
577 },
578 settings = {
579 foreground = mycolors.blue,
580 fontStyle = "bold",
581 }
582 },
583
584 {
585 scope = {
586 "entity.name.type",
587 "entity.other.inherited-class",
588 "meta.function-call",
589 "entity.other.attribute-name",
590 "entity.name.function.shell"
591 },
592 settings = {
593 foreground = mycolors.default,
594 }
595 },
596
597 {
598 scope = {
599 "entity.name.tag",
600 },
601 settings = {
602 foreground = mycolors.default,
603 }
604 },
605
606 }
607
608 registertheme {
609 category = "context",
610 description = "ConTeXt",
611 colors = colors,
612 styles = styles,
613 }
614
615
616
617 end
618
619 do
620
621 local presentation = {
622 echo = true,
623 reveal = "always",
624 focus = false,
625 panel = "shared",
626 showReuseMessage = false,
627 clear = true,
628 }
629
630
631
632 local tasks = {
633 {
634 group = "build",
635 label = "process tex file",
636 type = "shell",
637 command = "context --autogenerate --autopdf ${file}",
638 windows = { command = "context.exe --autogenerate --autopdf ${file}" },
639 },
640 {
641 group = "build",
642 label = "check tex file",
643 type = "shell",
644 command = "mtxrun --autogenerate --script check ${file}",
645 windows = { command = "mtxrun.exe --autogenerate --script check ${file}" },
646 },
647 {
648 group = "build",
649 label = "identify fonts",
650 type = "shell",
651 command = "mtxrun --script fonts --reload --force",
652 windows = { command = "mtxrun.exe --script fonts --reload --force" },
653 },
654 {
655 group = "build",
656 label = "process lua file",
657 type = "shell",
658 command = "mtxrun --script ${file}",
659 windows = { command = "mtxrun.exe --script ${file}" },
660 },
661 }
662
663 for i=1,#tasks do
664 local task = tasks[i]
665 if not task.windows then
666 task.windows = { command = task.command }
667 end
668 if not task.presentation then
669 task.presentation = presentation
670 end
671 end
672
673 registertask {
674 category = "context",
675 description = "ConTeXt Tasks",
676 tasks = tasks,
677 }
678
679 end
680
681 do
682
683 local keybindings = {
684 {
685
686 key = "ctrl-F12",
687 command = "workbench.action.tasks.runTask",
688 args = "process tex file",
689 when = "editorTextFocus && editorLangId == context.tex",
690 },
691 {
692
693 key = "F12",
694 command = "workbench.action.tasks.runTask",
695 args = "check tex file",
696 when = "editorTextFocus && editorLangId == context.tex",
697 },
698 {
699
700 key = "ctrl-F12",
701 command = "workbench.action.tasks.runTask",
702 args = "process lua file",
703 when = "editorTextFocus && editorLangId == context.cld",
704 }
705 }
706
707 registerkeybinding {
708 category = "context",
709 description = "ConTeXt Keybindings",
710 keybindings = keybindings,
711 }
712
713 end
714
715
716
717 local function loaddefinitions(name)
718 return table.load(resolvers.findfile(name))
719 end
720
721 local escapes = {
722 ["."] = "\\.",
723 ["-"] = "\\-",
724 ["+"] = "\\+",
725 ["*"] = "\\*",
726 ['"'] = '\\"',
727 ["'"] = "\\'",
728 ['^'] = '\\^',
729 ['$'] = '\\$',
730 ["|"] = "\\|",
731 ["\\"] = "\\\\",
732 ["["] = "\\[",
733 ["]"] = "\\]",
734 ["("] = "\\(",
735 [")"] = "\\)",
736 ["%"] = "\\%",
737 ["!"] = "\\!",
738 ["&"] = "\\&",
739 ["?"] = "\\?",
740 ["~"] = "\\~",
741 }
742
743 local function sorter(a,b)
744 return a > b
745 end
746
747 local function oneof(t)
748 local result = { }
749 table.sort(t,sorter)
750 for i=1,#t do
751 result[i] = string.gsub(t[i],".",escapes)
752 end
753 return concat(result,"|")
754 end
755
756 local function capture(str)
757 return "(" .. str .. ")"
758 end
759
760 local function captures(str)
761 return "\\*(" .. str .. ")\\*"
762 end
763
764 local function include(str)
765 return { include = str }
766 end
767
768 local function configuration(s)
769 if s then
770 local pairs = s.pairs
771 local comments = s.comments
772 return {
773 brackets = pairs,
774 autoClosingPairs = pairs,
775 surroundingPairs = pairs,
776 comments = {
777 lineComment = comments and comments.inline or nil,
778 blockComment = comments and comments.display or nil,
779 },
780 }
781 else
782 return { }
783 end
784 end
785
786
787
788
789 local mapping = {
790 ["context.default"] = "text source",
791 ["context.number"] = "constant.numeric",
792 ["context.comment"] = "comment",
793 ["context.keyword"] = "keyword",
794 ["context.string"] = "string source",
795 ["context.label"] = "meta.tag",
796 ["context.constant"] = "support.constant",
797 ["context.operator"] = "keyword.operator.js",
798 ["context.identifier"] = "support.variable",
799 ["context.quote"] = "string",
800 ["context.special"] = "unset",
801 ["context.extra"] = "unset",
802 ["context.embedded"] = "meta.embedded",
803 ["context.reserved"] = "unset",
804 ["context.definition"] = "keyword",
805 ["context.warning"] = "invalid",
806 ["context.command"] = "unset",
807 ["context.grouping"] = "unset",
808 ["context.primitive"] = "keyword",
809 ["context.plain"] = "unset",
810 ["context.user"] = "unset",
811 ["context.data"] = "text source",
812 ["context.text"] = "text source",
813 }
814
815 local function styler(namespace)
816 local done = { }
817 local style = function(what,where)
818 if not what or not where then
819 report()
820 report("? %-5s %-20s %s",namespace,what or "?",where or "?")
821 report()
822 os.exit()
823 end
824
825
826
827 local hash = what .. "." .. where
828 if done[hash] then
829 report("- %-5s %-20s %s",namespace,what,where)
830 else
831
832 done[hash] = true
833 end
834 return hash .. "." .. namespace
835 end
836 return style, function(what,where) return { name = style(what, where) } end
837 end
838
839 local function embedded(name)
840 return { { include = "source.context." .. name } }
841 end
842
843
844
845 do
846
847 local interface_lowlevel = loaddefinitions("scite-context-data-context.lua")
848 local interface_interfaces = loaddefinitions("scite-context-data-interfaces.lua")
849 local interface_tex = loaddefinitions("scite-context-data-tex.lua")
850
851 local constants = interface_lowlevel.constants
852 local helpers = interface_lowlevel.helpers
853 local interfaces = interface_interfaces.common
854 local primitives = { }
855 local overloaded = { }
856
857 for i=1,#helpers do
858 overloaded[helpers[i]] = true
859 end
860 for i=1,#constants do
861 overloaded[constants[i]] = true
862 end
863
864 local function add(data)
865 for k, v in next, data do
866 if v ~= "/" and v ~= "-" then
867 if not overloaded[v] then
868 primitives[#primitives+1] = v
869 end
870 v = "normal" .. v
871 if not overloaded[v] then
872 primitives[#primitives+1] = v
873 end
874 end
875 end
876 end
877
878 add(interface_tex.tex)
879 add(interface_tex.etex)
880 add(interface_tex.pdftex)
881 add(interface_tex.aleph)
882 add(interface_tex.omega)
883 add(interface_tex.luatex)
884 add(interface_tex.xetex)
885
886 local luacommands = {
887 "ctxlua", "ctxcommand", "ctxfunction",
888 "ctxlatelua", "ctxlatecommand",
889 "cldcommand", "cldcontext",
890 "luaexpr", "luascript", "luathread",
891 "directlua", "latelua",
892 }
893
894 local luaenvironments = {
895 "luacode",
896 "luasetups", "luaparameterset",
897 "ctxfunction", "ctxfunctiondefinition",
898 }
899
900 local mpscommands = {
901 "reusableMPgraphic", "usableMPgraphic",
902 "uniqueMPgraphic", "uniqueMPpagegraphic",
903 "useMPgraphic", "reuseMPgraphic",
904 "MPpositiongraphic",
905 }
906
907 local mpsenvironments_o = {
908 "MPpage"
909 }
910
911 local mpsenvironments_a = {
912 "MPcode", "useMPgraphic", "reuseMPgraphic",
913 "MPinclusions", "MPinitializations", "MPdefinitions", "MPextensions",
914 "MPgraphic", "MPcalculation",
915 }
916
917
918
919
920
921
922
923 local function words(list)
924 table.sort(list,sorter)
925 return "\\\\(" .. concat(list,"|") .. ")" .. "(?=[^a-zA-Z])"
926 end
927
928 local function bwords(list)
929 table.sort(list,sorter)
930 return "(\\\\(" .. concat(list,"|") .. "))\\s*(\\{)"
931 end
932
933 local function ewords()
934 return "(\\})"
935 end
936
937 local function environments(list)
938 table.sort(list,sorter)
939 last = concat(list,"|")
940 if #list > 1 then
941 last = "(?:" .. last .. ")"
942 end
943 return capture("\\\\start" .. last), capture("\\\\stop" .. last)
944 end
945
946 local capturedconstants = words(constants)
947 local capturedprimitives = words(primitives)
948 local capturedhelpers = words(helpers)
949 local capturedcommands = words(interfaces)
950 local capturedmpscommands = words(mpscommands)
951
952 local spaces = "\\s*"
953 local identifier = "[a-zA-Z\\_@!?\127-\255]+"
954
955 local comment = "%.*$\\n?"
956 local ifprimitive = "\\\\if[a-zA-Z\\_@!?\127-\255]*"
957 local csname = "\\\\[a-zA-Z\\_@!?\127-\255]+"
958 local csprefix = "\\\\(btx|xml)[a-z]+"
959 local cssuffix = "\\\\[a-z]+(btx|xml)[a-z]*"
960 local csreserved = "\\\\(\\?\\?|[a-z]\\!)[a-zA-Z\\_@!?\127-\255]+"
961
962 local luaenvironmentopen,
963 luaenvironmentclose = environments(luaenvironments)
964 local luacommandopen,
965 luacommandclose = environments(luacommands)
966
967 local mpsenvironmentopen_o,
968 mpsenvironmentclose_o = environments(mpsenvironments_o)
969 local mpsenvironmentopen_a,
970 mpsenvironmentclose_a = environments(mpsenvironments_a)
971
972 local argumentopen = capture("\\{")
973 local argumentclose = capture("\\}")
974 local argumentcontent = capture("[^\\}]*")
975
976 local optionopen = capture("\\[")
977 local optionclose = capture("\\]")
978 local optioncontent = capture("[^\\]]*")
979
980
981
982
983 local option = "(?:" .. optionopen .. optioncontent .. optionclose .. ")?"
984 local argument = "(?:" .. argumentopen .. argumentcontent .. argumentclose .. ")?"
985
986 local mpsenvironmentopen_o = mpsenvironmentopen_o .. spaces .. option .. spaces .. option
987 local mpsenvironmentopen_a = mpsenvironmentopen_a .. spaces .. argument .. spaces .. argument
988
989 local style, styled = styler("tex")
990
991 local capturedgroupings = oneof {
992 "{", "}", "$"
993 }
994
995 local capturedextras = oneof {
996 "~", "%", "^", "&", "_",
997 "-", "+", "/",
998 "'", "`",
999 "\\", "|",
1000 }
1001
1002 local capturedspecials = oneof {
1003 "(", ")", "[", "]", "<", ">",
1004 "#", "=", '"',
1005 }
1006
1007 local capturedescaped = "\\\\."
1008
1009 registerlexer {
1010
1011 category = "tex",
1012 description = "ConTeXt TEX",
1013 suffixes = { "tex", "mkiv", "mkvi", "mkix", "mkxi", "mkil", "mkxl", "mklx" },
1014 version = "1.0.0",
1015
1016 setup = configuration {
1017 pairs = {
1018 { "{", "}" },
1019 { "[", "]" },
1020 { "(", ")" },
1021 },
1022 comments = {
1023 inline = "%",
1024 },
1025 },
1026
1027 repository = {
1028
1029 comment = {
1030 name = style("context.comment", "comment"),
1031 match = comment,
1032 },
1033
1034 constant = {
1035 name = style("context.constant", "commands.constant"),
1036 match = capturedconstants,
1037 },
1038
1039 ifprimitive = {
1040 name = style("context.primitive", "commands.if"),
1041 match = ifprimitive,
1042 },
1043
1044 primitive = {
1045 name = style("context.primitive", "commands.primitive"),
1046 match = capturedprimitives,
1047 },
1048
1049 helper = {
1050 name = style("context.plain", "commands.plain"),
1051 match = capturedhelpers,
1052 },
1053
1054 command = {
1055 name = style("context.command", "commands.context"),
1056 match = capturedcommands,
1057 },
1058
1059 csname = {
1060 name = style("context.user", "commands.user"),
1061 match = csname,
1062 },
1063
1064 escaped = {
1065 name = style("context.command", "commands.escaped"),
1066 match = capturedescaped,
1067 },
1068
1069 subsystem_prefix = {
1070 name = style("context.embedded", "subsystem.prefix"),
1071 match = csprefix,
1072 },
1073
1074 subsystem_suffix = {
1075 name = style("context.embedded", "subsystem.suffix"),
1076 match = cssuffix,
1077 },
1078
1079 grouping = {
1080 name = style("context.grouping", "symbols.groups"),
1081 match = capturedgroupings,
1082 },
1083
1084 extra = {
1085 name = style("context.extra", "symbols.extras"),
1086 match = capturedextras,
1087 },
1088
1089 special = {
1090 name = style("context.special", "symbols.special"),
1091 match = capturedspecials,
1092 },
1093
1094 reserved = {
1095 name = style("context.reserved", "commands.reserved"),
1096 match = csreserved,
1097 },
1098
1099 lua_environment = {
1100 ["begin"] = luaenvironmentopen,
1101 ["end"] = luaenvironmentclose,
1102 patterns = embedded("cld"),
1103 beginCaptures = { ["0"] = styled("context.embedded", "lua.environment.open") },
1104 endCaptures = { ["0"] = styled("context.embedded", "lua.environment.close") },
1105 },
1106
1107 lua_command = {
1108 ["begin"] = luacommandopen,
1109 ["end"] = luacommandclose,
1110 patterns = embedded("cld"),
1111 beginCaptures = {
1112 ["1"] = styled("context.embedded", "lua.command.open"),
1113 ["2"] = styled("context.grouping", "lua.command.open"),
1114 },
1115 endCaptures = {
1116 ["1"] = styled("context.grouping", "lua.command.close"),
1117 },
1118
1119 },
1120
1121 metafun_environment_o = {
1122 ["begin"] = mpsenvironmentopen_o,
1123 ["end"] = mpsenvironmentclose_o,
1124 patterns = embedded("mps"),
1125 beginCaptures = {
1126 ["1"] = styled("context.embedded", "metafun.environment.start.o"),
1127 ["2"] = styled("context.embedded", "metafun.environment.open.o.1"),
1128 ["3"] = styled("context.warning", "metafun.environment.content.o.1"),
1129 ["4"] = styled("context.embedded", "metafun.environment.close.o.1"),
1130 ["5"] = styled("context.embedded", "metafun.environment.open.o.2"),
1131 ["6"] = styled("context.warning", "metafun.environment.content.o.2"),
1132 ["7"] = styled("context.embedded", "metafun.environment.close.o.2"),
1133 },
1134 endCaptures = {
1135 ["0"] = styled("context.embedded", "metafun.environment.stop.o")
1136 },
1137 },
1138
1139 metafun_environment_a = {
1140 ["begin"] = mpsenvironmentopen_a,
1141 ["end"] = mpsenvironmentclose_a,
1142 patterns = embedded("mps"),
1143 beginCaptures = {
1144 ["1"] = styled("context.embedded", "metafun.environment.start.a"),
1145 ["2"] = styled("context.embedded", "metafun.environment.open.a.1"),
1146 ["3"] = styled("context.warning", "metafun.environment.content.a.1"),
1147 ["4"] = styled("context.embedded", "metafun.environment.close.a.1"),
1148 ["5"] = styled("context.embedded", "metafun.environment.open.a.2"),
1149 ["6"] = styled("context.warning", "metafun.environment.content.a.2"),
1150 ["7"] = styled("context.embedded", "metafun.environment.close.a.2"),
1151 },
1152 endCaptures = {
1153 ["0"] = styled("context.embedded", "metafun.environment.stop.a")
1154 },
1155 },
1156
1157 metafun_command = {
1158 name = style("context.embedded", "metafun.command"),
1159 match = capturedmpscommands,
1160 },
1161
1162 },
1163
1164 patterns = {
1165 include("#comment"),
1166 include("#constant"),
1167 include("#lua_environment"),
1168 include("#lua_command"),
1169 include("#metafun_environment_o"),
1170 include("#metafun_environment_a"),
1171 include("#metafun_command"),
1172 include("#subsystem_prefix"),
1173 include("#subsystem_suffix"),
1174 include("#ifprimitive"),
1175 include("#helper"),
1176 include("#command"),
1177 include("#primitive"),
1178 include("#reserved"),
1179 include("#csname"),
1180 include("#escaped"),
1181 include("#grouping"),
1182 include("#special"),
1183 include("#extra"),
1184 },
1185
1186 }
1187
1188 end
1189
1190
1191
1192 do
1193
1194 local metapostprimitives = { }
1195 local metapostinternals = { }
1196 local metapostshortcuts = { }
1197 local metapostcommands = { }
1198
1199 local metafuninternals = { }
1200 local metafunshortcuts = { }
1201 local metafuncommands = { }
1202
1203 local mergedshortcuts = { }
1204 local mergedinternals = { }
1205
1206 do
1207
1208 local definitions = loaddefinitions("scite-context-data-metapost.lua")
1209
1210 if definitions then
1211 metapostprimitives = definitions.primitives or { }
1212 metapostinternals = definitions.internals or { }
1213 metapostshortcuts = definitions.shortcuts or { }
1214 metapostcommands = definitions.commands or { }
1215 end
1216
1217 local definitions = loaddefinitions("scite-context-data-metafun.lua")
1218
1219 if definitions then
1220 metafuninternals = definitions.internals or { }
1221 metafunshortcuts = definitions.shortcuts or { }
1222 metafuncommands = definitions.commands or { }
1223 end
1224
1225 for i=1,#metapostshortcuts do
1226 mergedshortcuts[#mergedshortcuts+1] = metapostshortcuts[i]
1227 end
1228 for i=1,#metafunshortcuts do
1229 mergedshortcuts[#mergedshortcuts+1] = metafunshortcuts[i]
1230 end
1231
1232 for i=1,#metapostinternals do
1233 mergedinternals[#mergedinternals+1] = metapostinternals[i]
1234 end
1235 for i=1,#metafuninternals do
1236 mergedinternals[#mergedinternals+1] = metafuninternals[i]
1237 end
1238
1239
1240 end
1241
1242 local function words(list)
1243 table.sort(list,sorter)
1244 return "(" .. concat(list,"|") .. ")" .. "(?=[^a-zA-Z\\_@!?\127-\255])"
1245 end
1246
1247 local capturedshortcuts = oneof(mergedshortcuts)
1248 local capturedinternals = words(mergedinternals)
1249 local capturedmetapostcommands = words(metapostcommands)
1250 local capturedmetafuncommands = words(metafuncommands)
1251 local capturedmetapostprimitives = words(metapostprimitives)
1252
1253 local capturedsuffixes = oneof {
1254 "#@", "@#", "#"
1255 }
1256 local capturedspecials = oneof {
1257 "#@", "@#", "#",
1258 "(", ")", "[", "]", "{", "}",
1259 "<", ">", "=", ":",
1260 '"',
1261 }
1262 local capturedexatras = oneof {
1263 "+-+", "++",
1264 "~", "%", "^", "&",
1265 "_", "-", "+", "*", "/",
1266 "`", "'", "|", "\\",
1267 }
1268
1269 local spaces = "\\s*"
1270 local mandatespaces = "\\s+"
1271
1272 local identifier = "[a-zA-Z\\_@!?\127-\255]+"
1273
1274 local decnumber = "[\\-]?[0-9]+(\\.[0-9]+)?([eE]\\-?[0-9]+)?"
1275
1276 local comment = "%.*$\\n?"
1277
1278 local stringopen = "\""
1279 local stringclose = stringopen
1280
1281 local qualifier = "[\\.]"
1282 local optionalqualifier = spaces .. qualifier .. spaces
1283
1284 local capturedstringopen = capture(stringopen)
1285 local capturedstringclose = capture(stringclose)
1286
1287 local capturedlua = capture("lua")
1288
1289 local capturedopen = capture("\\(")
1290 local capturedclose = capture("\\)")
1291
1292 local capturedtexopen = capture("(?:b|verbatim)tex") .. mandatespaces
1293 local capturedtexclose = mandatespaces .. capture("etex")
1294
1295 local texcommand = "\\[a-zA-Z\\_@!?\127-\255]+"
1296
1297 local style, styled = styler("mps")
1298
1299 registerlexer {
1300
1301 category = "mps",
1302 description = "ConTeXt MetaFun",
1303 suffixes = { "mp", "mpii", "mpiv", "mpxl" },
1304 version = "1.0.0",
1305
1306 setup = configuration {
1307 pairs = {
1308 { "{", "}" },
1309 { "[", "]" },
1310 { "(", ")" },
1311 },
1312 comments = {
1313 inline = "%",
1314 },
1315 },
1316
1317 repository = {
1318
1319 comment = {
1320 name = style("context.comment", "comment"),
1321 match = comment,
1322 },
1323
1324 internal = {
1325 name = style("context.reserved", "internal"),
1326 match = capturedshortcuts,
1327 },
1328
1329 shortcut = {
1330 name = style("context.data", "shortcut"),
1331 match = capturedinternals,
1332 },
1333
1334 helper = {
1335 name = style("context.command.metafun", "helper"),
1336 match = capturedmetafuncommands,
1337 },
1338
1339 plain = {
1340 name = style("context.plain", "plain"),
1341 match = capturedmetapostcommands,
1342 },
1343
1344 primitive = {
1345 name = style("context.primitive", "primitive"),
1346 match = capturedmetapostprimitives,
1347 },
1348
1349 quoted = {
1350 name = style("context.string", "string.text"),
1351 ["begin"] = stringopen,
1352 ["end"] = stringclose,
1353 beginCaptures = { ["0"] = styled("context.special", "string.open") },
1354 endCaptures = { ["0"] = styled("context.special", "string.close") },
1355 },
1356
1357 identifier = {
1358 name = style("context.default", "identifier"),
1359 match = identifier,
1360 },
1361
1362 suffix = {
1363 name = style("context.number", "suffix"),
1364 match = capturedsuffixes,
1365 },
1366
1367 special = {
1368 name = style("context.special", "special"),
1369 match = capturedspecials,
1370 },
1371
1372 number = {
1373 name = style("context.number", "number"),
1374 match = decnumber,
1375 },
1376
1377 extra = {
1378 name = "context.extra",
1379 match = capturedexatras,
1380 },
1381
1382 luacall = {
1383 ["begin"] = capturedlua .. spaces .. capturedopen .. spaces .. capturedstringopen,
1384 ["end"] = capturedstringclose .. spaces .. capturedclose,
1385 patterns = embedded("cld"),
1386 beginCaptures = {
1387 ["1"] = styled("context.embedded", "lua.command"),
1388 ["2"] = styled("context.special", "lua.open"),
1389 ["3"] = styled("context.special", "lua.text.open"),
1390 },
1391 endCaptures = {
1392 ["1"] = styled("context.special", "lua.text.close"),
1393 ["2"] = styled("context.special", "lua.close"),
1394 },
1395 },
1396
1397
1398
1399 luacall_suffixed = {
1400 name = style("context.embedded", "luacall"),
1401 ["begin"] = capturedlua,
1402 ["end"] = "(?!(" .. optionalqualifier .. identifier .. "))",
1403 patterns = {
1404 {
1405 match = qualifier,
1406
1407 name = style("context.default", "luacall.qualifier"),
1408 },
1409 }
1410 },
1411
1412 texlike = {
1413 name = style("context.warning","unexpected.tex"),
1414 match = texcommand,
1415 },
1416
1417 texstuff = {
1418 name = style("context.string", "tex"),
1419 ["begin"] = capturedtexopen,
1420 ["end"] = capturedtexclose,
1421 patterns = embedded("tex"),
1422 beginCaptures = { ["1"] = styled("context.primitive", "tex.open") },
1423 endCaptures = { ["1"] = styled("context.primitive", "tex.close") },
1424 },
1425
1426 },
1427
1428 patterns = {
1429 include("#comment"),
1430 include("#internal"),
1431 include("#shortcut"),
1432 include("#luacall_suffixed"),
1433 include("#luacall"),
1434 include("#helper"),
1435 include("#plain"),
1436 include("#primitive"),
1437 include("#texstuff"),
1438 include("#suffix"),
1439 include("#identifier"),
1440 include("#number"),
1441 include("#quoted"),
1442 include("#special"),
1443 include("#texlike"),
1444 include("#extra"),
1445 },
1446
1447 }
1448
1449 end
1450
1451
1452
1453 do
1454
1455 local function words(list)
1456 table.sort(list,sorter)
1457 return "(" .. concat(list,"|") .. ")" .. "(?=[^a-zA-Z])"
1458 end
1459
1460 local capturedkeywords = words {
1461 "and", "break", "do", "else", "elseif", "end", "false", "for", "function",
1462 "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true",
1463 "until", "while",
1464 }
1465
1466 local capturedbuiltin = words {
1467 "assert", "collectgarbage", "dofile", "error", "getmetatable",
1468 "ipairs", "load", "loadfile", "module", "next", "pairs",
1469 "pcall", "print", "rawequal", "rawget", "rawset", "require",
1470 "setmetatable", "tonumber", "tostring", "type", "unpack", "xpcall", "select",
1471 "string", "table", "coroutine", "debug", "file", "io", "lpeg", "math", "os", "package", "bit32", "utf8",
1472
1473 }
1474
1475 local capturedconstants = words {
1476 "_G", "_VERSION", "_M", "\\.\\.\\.", "_ENV",
1477 "__add", "__call", "__concat", "__div", "__idiv", "__eq", "__gc", "__index",
1478 "__le", "__lt", "__metatable", "__mode", "__mul", "__newindex",
1479 "__pow", "__sub", "__tostring", "__unm", "__len",
1480 "__pairs", "__ipairs",
1481 "__close",
1482 "NaN",
1483 "<const>", "<toclose>",
1484 }
1485
1486 local capturedcsnames = words {
1487 "commands",
1488 "context",
1489
1490
1491 "metafun",
1492 "metapost",
1493 "ctx[A-Za-z_]*",
1494 }
1495
1496 local capturedoperators = oneof {
1497 "+", "-", "*", "/", "%", "^",
1498 "#", "=", "<", ">",
1499 ";", ":", ",", ".",
1500 "{", "}", "[", "]", "(", ")",
1501 "|", "~", "'"
1502 }
1503
1504 local spaces = "\\s*"
1505
1506 local identifier = "[_\\w][_\\w0-9]*"
1507 local qualifier = "[\\.\\:]"
1508 local optionalqualifier = spaces .. "[\\.\\:]*" .. spaces
1509
1510 local doublequote = "\""
1511 local singlequote = "\'"
1512
1513 local doublecontent = "(?:\\\\\"|[^\"])*"
1514 local singlecontent = "(?:\\\\\'|[^\'])*"
1515
1516 local captureddouble = capture(doublequote) .. capture(doublecontent) .. capture(doublequote)
1517 local capturedsingle = capture(singlequote) .. capture(singlecontent) .. capture(singlequote)
1518
1519 local longcommentopen = "--\\[\\["
1520 local longcommentclose = "\\]\\]"
1521
1522 local longstringopen = "\\[(=*)\\["
1523 local longstringclose = "\\](\\2)\\]"
1524
1525 local shortcomment = "--.*$\\n?"
1526
1527 local hexnumber = "[\\-]?0[xX][A-Fa-f0-9]+(\\.[A-Fa-f0-9]+)?([eEpP]\\-?[A-Fa-f0-9]+)?"
1528 local decnumber = "[\\-]?[0-9]+(\\.[0-9]+)?([eEpP]\\-?[0-9]+)?"
1529
1530 local capturedidentifier = capture(identifier)
1531 local capturedgotodelimiter = capture("::")
1532 local capturedqualifier = capture(qualifier)
1533 local capturedgoto = capture("goto")
1534
1535 local style, styled = styler("lua")
1536
1537 local lualexer = {
1538
1539 category = "lua",
1540 description = "ConTeXt Lua",
1541
1542 version = "1.0.0",
1543
1544 setup = configuration {
1545 pairs = {
1546 { "(", ")" },
1547 { "{", "}" },
1548 { "[", "]" },
1549 },
1550 comments = {
1551 inline = "--",
1552 display = { "--[[", "]]" },
1553 },
1554 },
1555
1556 repository = {
1557
1558 shortcomment = {
1559 name = style("context.comment", "comment.short"),
1560 match = shortcomment,
1561 },
1562
1563 longcomment = {
1564 name = style("context.comment", "comment.long"),
1565 ["begin"] = longcommentopen,
1566 ["end"] = longcommentclose,
1567 },
1568
1569 keyword = {
1570 name = style("context.keyword", "reserved.keyword"),
1571 match = capturedkeywords,
1572 },
1573
1574 builtin = {
1575 name = style("context.plain", "reserved.builtin"),
1576 match = capturedbuiltin,
1577 },
1578
1579 constant = {
1580 name = style("context.data", "reserved.constants"),
1581 match = capturedconstants,
1582 },
1583
1584 csname = {
1585 name = style("context.user", "csname"),
1586 ["begin"] = capturedcsnames,
1587 ["end"] = "(?!(" .. optionalqualifier .. identifier .. "))",
1588 patterns = {
1589 {
1590 match = qualifier,
1591 name = style("context.operator", "csname.qualifier")
1592 },
1593 }
1594 },
1595
1596 identifier_keyword = {
1597 match = spaces .. capturedqualifier .. spaces .. capturedkeywords,
1598 captures = {
1599 ["1"] = styled("context.operator", "identifier.keyword"),
1600 ["2"] = styled("context.warning", "identifier.keyword"),
1601 },
1602 },
1603
1604 identifier_valid = {
1605 name = style("context.default", "identifier.valid"),
1606 match = identifier,
1607 },
1608
1609 ["goto"] = {
1610 match = capturedgoto .. spaces .. capturedidentifier,
1611 captures = {
1612 ["1"] = styled("context.keyword", "goto.keyword"),
1613 ["2"] = styled("context.grouping", "goto.target"),
1614 }
1615 },
1616
1617 label = {
1618 match = capturedgotodelimiter .. capturedidentifier .. capturedgotodelimiter,
1619 captures = {
1620 ["1"] = styled("context.keyword", "label.open"),
1621 ["2"] = styled("context.grouping", "label.target"),
1622 ["3"] = styled("context.keyword", "label.close"),
1623 }
1624 },
1625
1626 operator = {
1627 name = style("context.special", "operator"),
1628 match = capturedoperators,
1629 },
1630
1631 string_double = {
1632 match = captureddouble,
1633 captures = {
1634 ["1"] = styled("context.special", "doublequoted.open"),
1635 ["2"] = styled("context.string", "doublequoted.text"),
1636 ["3"] = styled("context.special", "doublequoted.close"),
1637 },
1638 },
1639
1640 string_single = {
1641 match = capturedsingle,
1642 captures = {
1643 ["1"] = styled("context.special", "singlequoted.open"),
1644 ["2"] = styled("context.string", "singlequoted.text"),
1645 ["3"] = styled("context.special", "singlequoted.close"),
1646 },
1647 },
1648
1649 string_long = {
1650 name = style("context.string", "long.text"),
1651 ["begin"] = longstringopen,
1652 ["end"] = longstringclose,
1653 beginCaptures = { ["0"] = styled("context.special", "string.long.open") },
1654 endCaptures = { ["0"] = styled("context.special", "string.long.close") },
1655 },
1656
1657 number_hex = {
1658 name = style("context.number", "hexnumber"),
1659 match = hexnumber,
1660 },
1661
1662 number = {
1663 name = style("context.number", "decnumber"),
1664 match = decnumber,
1665 },
1666
1667 },
1668
1669 patterns = {
1670 include("#keyword"),
1671 include("#buildin"),
1672 include("#constant"),
1673 include("#csname"),
1674 include("#goto"),
1675 include("#number_hex"),
1676 include("#number"),
1677 include("#identifier_keyword"),
1678 include("#identifier_valid"),
1679 include("#longcomment"),
1680 include("#string_long"),
1681 include("#string_double"),
1682 include("#string_single"),
1683 include("#shortcomment"),
1684 include("#label"),
1685 include("#operator"),
1686 },
1687
1688 }
1689
1690 local texstringopen = "\\\\!!bs"
1691 local texstringclose = "\\\\!!es"
1692 local texcommand = "\\\\[A-Za-z\127-\255@\\!\\?_]*"
1693
1694 local cldlexer = {
1695
1696 category = "cld",
1697 description = "ConTeXt CLD",
1698 suffixes = { "lmt", "lua", "luc", "cld", "tuc", "luj", "lum", "tma", "lfg", "luv", "lui" },
1699 version = lualexer.version,
1700 setup = lualexer.setup,
1701
1702 repository = {
1703
1704 texstring = {
1705 name = style("context.string", "texstring.text"),
1706 ["begin"] = texstringopen,
1707 ["end"] = texstringclose,
1708 beginCaptures = { ["0"] = styled("context.special", "texstring.open") },
1709 endCaptures = { ["0"] = styled("context.special", "texstring.close") },
1710 },
1711
1712
1713
1714
1715
1716 texcommand = {
1717 name = style("context.warning", "texcommand"),
1718 match = texcommand
1719 },
1720
1721 },
1722
1723 patterns = {
1724 include("#texstring"),
1725
1726 include("#texcommand"),
1727 },
1728
1729 }
1730
1731 table.merge (cldlexer.repository,lualexer.repository)
1732 table.imerge(cldlexer.patterns, lualexer.patterns)
1733
1734 registerlexer(lualexer)
1735 registerlexer(cldlexer)
1736
1737 end
1738
1739
1740
1741 local xmllexer, xmlconfiguration do
1742
1743 local spaces = "\\s*"
1744
1745 local namespace = "(?:[-\\w.]+:)?"
1746 local name = "[-\\w.:]+"
1747
1748 local equal = "="
1749
1750 local elementopen = "<"
1751 local elementclose = ">"
1752 local elementopenend = "</"
1753 local elementempty = "/?"
1754 local elementnoclose = "?:([^>]*)"
1755
1756 local entity = "&.*?;"
1757
1758 local doublequote = "\""
1759 local singlequote = "\'"
1760
1761 local doublecontent = "(?:\\\\\"|[^\"])*"
1762 local singlecontent = "(?:\\\\\'|[^\'])*"
1763
1764 local captureddouble = capture(doublequote) .. capture(doublecontent) .. capture(doublequote)
1765 local capturedsingle = capture(singlequote) .. capture(singlecontent) .. capture(singlequote)
1766
1767 local capturednamespace = capture(namespace)
1768 local capturedname = capture(name)
1769 local capturedopen = capture(elementopen)
1770 local capturedclose = capture(elementclose)
1771 local capturedempty = capture(elementempty)
1772 local capturedopenend = capture(elementopenend)
1773
1774 local cdataopen = "<!\\[CDATA\\["
1775 local cdataclose = "]]>"
1776
1777 local commentopen = "<!--"
1778 local commentclose = "-->"
1779
1780 local processingopen = "<\\?"
1781 local processingclose = "\\?>"
1782
1783 local instructionopen = processingopen .. name
1784 local instructionclose = processingclose
1785
1786 local xmlopen = processingopen .. "xml"
1787 local xmlclose = processingclose
1788
1789 local luaopen = processingopen .. "lua"
1790 local luaclose = processingclose
1791
1792 local style, styled = styler("xml")
1793
1794 registerlexer {
1795
1796 category = "xml",
1797 description = "ConTeXt XML",
1798 suffixes = {
1799 "xml", "xsl", "xsd", "fo", "exa", "rlb", "rlg", "rlv", "rng",
1800 "xfdf", "xslt", "dtd", "lmx", "htm", "html", "xhtml", "ctx",
1801 "export", "svg", "xul",
1802 },
1803 version = "1.0.0",
1804
1805 setup = configuration {
1806 comments = {
1807 display = { "<!--", "-->" },
1808 },
1809 },
1810
1811 repository = {
1812
1813 attribute_double = {
1814 match = capturednamespace .. capturedname .. spaces .. equal .. spaces .. captureddouble,
1815 captures = {
1816 ["1"] = styled("context.plain", "attribute.double.namespace"),
1817 ["2"] = styled("context.constant", "attribute.double.name"),
1818 ["3"] = styled("context.special", "attribute.double.open"),
1819 ["4"] = styled("context.string", "attribute.double.text"),
1820 ["5"] = styled("context.special", "attribute.double.close"),
1821 },
1822 },
1823
1824 attribute_single = {
1825 match = capturednamespace .. capturedname .. spaces .. equal .. spaces .. capturedsingle,
1826 captures = {
1827 ["1"] = styled("context.plain", "attribute.single.namespace"),
1828 ["2"] = styled("context.constant", "attribute.single.name"),
1829 ["3"] = styled("context.special", "attribute.single.open"),
1830 ["4"] = styled("context.string", "attribute.single.text"),
1831 ["5"] = styled("context.special", "attribute.single.close"),
1832 },
1833 },
1834
1835 attributes = {
1836 patterns = {
1837 include("#attribute_double"),
1838 include("#attribute_single"),
1839 }
1840 },
1841
1842 entity = {
1843 name = style("context.constant", "entity"),
1844 match = entity,
1845 },
1846
1847 instruction = {
1848 name = style("context.default", "instruction.text"),
1849 ["begin"] = instructionopen,
1850 ["end"] = instructionclose,
1851 beginCaptures = { ["0"] = styled("context.command", "instruction.open") },
1852 endCaptures = { ["0"] = styled("context.command", "instruction.close") },
1853 },
1854
1855 instruction_xml = {
1856 ["begin"] = xmlopen,
1857 ["end"] = xmlclose,
1858 beginCaptures = { ["0"] = styled("context.command", "instruction.xml.open") },
1859 endCaptures = { ["0"] = styled("context.command", "instruction.xml.close") },
1860 patterns = { include("#attributes") }
1861 },
1862
1863 instruction_lua = {
1864 ["begin"] = luaopen,
1865 ["end"] = luaclose,
1866 patterns = embedded("cld"),
1867 beginCaptures = { ["0"] = styled("context.command", "instruction.lua.open") },
1868 endCaptures = { ["0"] = styled("context.command", "instruction.lua.close") },
1869 },
1870
1871 cdata = {
1872 name = style("context.default", "cdata.text"),
1873 ["begin"] = cdataopen,
1874 ["end"] = cdataclose,
1875 beginCaptures = { ["0"] = styled("context.command", "cdata.open") },
1876 endCaptures = { ["0"] = styled("context.command", "cdata.close") },
1877 },
1878
1879 comment = {
1880 name = style("context.comment", "comment.text"),
1881 ["begin"] = commentopen,
1882 ["end"] = commentclose,
1883 beginCaptures = { ["0"] = styled("context.command", "comment.open") },
1884 endCaptures = { ["0"] = styled("context.command", "comment.close") },
1885 },
1886
1887 open = {
1888 ["begin"] = capturedopen .. capturednamespace .. capturedname,
1889 ["end"] = capturedempty .. capturedclose,
1890 patterns = { include("#attributes") },
1891 beginCaptures = {
1892 ["1"] = styled("context.keyword", "open.open"),
1893 ["2"] = styled("context.plain", "open.namespace"),
1894 ["3"] = styled("context.keyword", "open.name"),
1895 },
1896 endCaptures = {
1897 ["1"] = styled("context.keyword", "open.empty"),
1898 ["2"] = styled("context.keyword", "open.close"),
1899 },
1900 },
1901
1902 close = {
1903 match = capturedopenend .. capturednamespace .. capturedname .. spaces .. capturedclose,
1904 captures = {
1905 ["1"] = styled("context.keyword", "close.open"),
1906 ["2"] = styled("context.plain", "close.namespace"),
1907 ["3"] = styled("context.keyword", "close.name"),
1908 ["4"] = styled("context.keyword", "close.close"),
1909 },
1910 },
1911
1912 element_error = {
1913 name = style("context.error","error"),
1914 match = elementopen .. elementnoclose .. elementclose,
1915 },
1916
1917 },
1918
1919 patterns = {
1920
1921 include("#comment"),
1922 include("#cdata"),
1923
1924 include("#instruction_xml"),
1925 include("#instruction_lua"),
1926 include("#instruction"),
1927 include("#close"),
1928 include("#open"),
1929 include("#element_error"),
1930 include("#entity"),
1931 },
1932
1933 }
1934
1935 end
1936
1937
1938
1939
1940 do
1941
1942 local spaces = "\\s*"
1943 local open = "{"
1944 local close = "}"
1945 local hash = "#"
1946 local equal = "="
1947 local comma = ","
1948
1949 local doublequote = "\""
1950 local doublecontent = "(?:\\\\\"|[^\"])*"
1951
1952 local singlequote = "\'"
1953 local singlecontent = "(?:\\\\\'|[^\'])*"
1954
1955 local groupopen = "{"
1956 local groupclose = "}"
1957 local groupcontent = "(?:\\\\{|\\\\}|[^\\{\\}])*"
1958
1959 local shortcut = "@(?:string|String|STRING)"
1960 local comment = "@(?:comment|Comment|COMMENT)"
1961
1962 local keyword = "[a-zA-Z0-9\\_@:\\-]+"
1963
1964 local capturedcomment = spaces .. capture(comment) .. spaces
1965 local capturedshortcut = spaces .. capture(shortcut) .. spaces
1966 local capturedkeyword = spaces .. capture(keyword) .. spaces
1967 local capturedopen = spaces .. capture(open) .. spaces
1968 local capturedclose = spaces .. capture(close) .. spaces
1969 local capturedequal = spaces .. capture(equal) .. spaces
1970 local capturedcomma = spaces .. capture(comma) .. spaces
1971 local capturedhash = spaces .. capture(hash) .. spaces
1972
1973 local captureddouble = spaces .. capture(doublequote) .. capture(doublecontent) .. capture(doublequote) .. spaces
1974 local capturedsingle = spaces .. capture(singlequote) .. capture(singlecontent) .. capture(singlequote) .. spaces
1975 local capturedgroup = spaces .. capture(groupopen) .. capture(groupcontent) .. capture(groupclose) .. spaces
1976
1977 local forget = "%.*$\\n?"
1978
1979 local style, styled = styler("bibtex")
1980
1981 registerlexer {
1982
1983 category = "bibtex",
1984 description = "ConTeXt bibTeX",
1985 suffixes = { "bib", "btx" },
1986 version = "1.0.0",
1987
1988 setup = configuration {
1989 pairs = {
1990 { "{", "}" },
1991 },
1992 comments = {
1993 inline = "%",
1994 },
1995 },
1996
1997 repository = {
1998
1999 forget = {
2000 name = style("context.comment", "comment.comment.inline"),
2001 match = forget,
2002 },
2003
2004 comment = {
2005 name = style("context.comment", "comment.comment.content"),
2006 ["begin"] = capturedcomment .. capturedopen,
2007 ["end"] = capturedclose,
2008 beginCaptures = {
2009 ["1"] = styled("context.keyword", "comment.name"),
2010 ["2"] = styled("context.grouping", "comment.open"),
2011 },
2012 endCaptures = {
2013 ["1"] = styled("context.grouping", "comment.close"),
2014 },
2015 },
2016
2017
2018
2019 string_double = {
2020 match = capturedkeyword .. capturedequal .. captureddouble,
2021 captures = {
2022 ["1"] = styled("context.command","doublequoted.key"),
2023 ["2"] = styled("context.operator","doublequoted.equal"),
2024 ["3"] = styled("context.special", "doublequoted.open"),
2025 ["4"] = styled("context.text", "doublequoted.text"),
2026 ["5"] = styled("context.special", "doublequoted.close"),
2027 },
2028 },
2029
2030 string_single = {
2031 match = capturedkeyword .. capturedequal .. capturedsingle,
2032 captures = {
2033 ["1"] = styled("context.command","singlequoted.key"),
2034 ["2"] = styled("context.operator","singlequoted.equal"),
2035 ["3"] = styled("context.special", "singlequoted.open"),
2036 ["4"] = styled("context.text", "singlequoted.text"),
2037 ["5"] = styled("context.special", "singlequoted.close"),
2038 },
2039 },
2040
2041 string_grouped = {
2042 match = capturedkeyword .. capturedequal .. capturedgroup,
2043 captures = {
2044 ["1"] = styled("context.command","grouped.key"),
2045 ["2"] = styled("context.operator","grouped.equal"),
2046 ["3"] = styled("context.operator", "grouped.open"),
2047 ["4"] = styled("context.text", "grouped.text"),
2048 ["5"] = styled("context.operator", "grouped.close"),
2049 },
2050 },
2051
2052 string_value = {
2053 match = capturedkeyword .. capturedequal .. capturedkeyword,
2054 captures = {
2055 ["1"] = styled("context.command", "value.key"),
2056 ["2"] = styled("context.operator", "value.equal"),
2057 ["3"] = styled("context.text", "value.text"),
2058 },
2059 },
2060
2061 string_concat = {
2062 patterns = {
2063 {
2064 match = capturedhash .. captureddouble,
2065 captures = {
2066 ["1"] = styled("context.operator","concat.doublequoted.concatinator"),
2067 ["2"] = styled("context.special", "concat.doublequoted.open"),
2068 ["3"] = styled("context.text", "concat.doublequoted.text"),
2069 ["4"] = styled("context.special", "concat.doublequoted.close"),
2070 }
2071 },
2072 {
2073 match = capturedhash .. capturedsingle,
2074 captures = {
2075 ["1"] = styled("context.operator","concat.singlequoted.concatinator"),
2076 ["2"] = styled("context.special", "concat.singlequoted.open"),
2077 ["3"] = styled("context.text", "concat.singlequoted.text"),
2078 ["4"] = styled("context.special", "concat.singlequoted.close"),
2079 },
2080 },
2081 {
2082 match = capturedhash .. capturedgroup,
2083 captures = {
2084 ["1"] = styled("context.operator","concat.grouped.concatinator"),
2085 ["2"] = styled("context.operator", "concat.grouped.open"),
2086 ["3"] = styled("context.text", "concat.grouped.text"),
2087 ["4"] = styled("context.operator", "concat.grouped.close"),
2088 },
2089 },
2090 {
2091 match = capturedhash .. capturedkeyword,
2092 captured = {
2093 ["1"] = styled("context.operator","concat.value.concatinator"),
2094 ["2"] = styled("context.text", "concat.value.text"),
2095 },
2096 },
2097 },
2098 },
2099
2100 separator = {
2101 match = capturedcomma,
2102 name = style("context.operator","definition.separator"),
2103 },
2104
2105 definition = {
2106 name = style("context.warning","definition.error"),
2107 ["begin"] = capturedkeyword .. capturedopen .. capturedkeyword .. capturedcomma,
2108 ["end"] = capturedclose,
2109 beginCaptures = {
2110 ["1"] = styled("context.keyword", "definition.category"),
2111 ["2"] = styled("context.grouping", "definition.open"),
2112 ["3"] = styled("context.warning", "definition.label.text"),
2113 ["3"] = styled("context.operator", "definition.label.separator"),
2114 },
2115 endCaptures = {
2116 ["1"] = styled("context.grouping", "definition.close"),
2117 },
2118 patterns = {
2119 include("#string_double"),
2120 include("#string_single"),
2121 include("#string_grouped"),
2122 include("#string_value"),
2123 include("#string_concat"),
2124 include("#separator"),
2125 },
2126 },
2127
2128 concatinator = {
2129 match = capturedhash,
2130 name = style("context.operator","definition.concatinator"),
2131 },
2132
2133 shortcut = {
2134 name = style("context.warning","shortcut.error"),
2135 ["begin"] = capturedshortcut .. capturedopen,
2136 ["end"] = capturedclose,
2137 beginCaptures = {
2138 ["1"] = styled("context.keyword", "shortcut.name"),
2139 ["2"] = styled("context.grouping", "shortcut.open"),
2140 },
2141 endCaptures = {
2142 ["1"] = styled("context.grouping", "shortcut.close"),
2143 },
2144 patterns = {
2145 include("#string_double"),
2146 include("#string_single"),
2147 include("#string_grouped"),
2148 include("#string_value"),
2149 include("#string_concat"),
2150 },
2151 },
2152
2153 },
2154
2155 patterns = {
2156 include("#forget"),
2157 include("#comment"),
2158 include("#shortcut"),
2159 include("#definition"),
2160 },
2161
2162 }
2163
2164 end
2165
2166
2167
2168 do
2169
2170
2171
2172 local function words(list)
2173 table.sort(list,sorter)
2174 local str = concat(list,"|")
2175 return "(" .. str .. "|" .. string.upper(str) .. ")" .. "(?=[^a-zA-Z])"
2176 end
2177
2178 local capturedkeywords = words {
2179 "absolute", "action", "add", "after", "all", "allocate", "alter", "and", "any",
2180 "are", "array", "as", "asc", "asensitive", "assertion", "asymmetric", "at",
2181 "atomic", "authorization", "avg", "before", "begin", "between", "bigint",
2182 "binary", "bit", "bit_length", "blob", "boolean", "both", "breadth", "by",
2183 "call", "called", "cascade", "cascaded", "case", "cast", "catalog", "char",
2184 "char_length", "character", "character_length", "check", "clob", "close",
2185 "coalesce", "collate", "collation", "column", "commit", "condition", "connect",
2186 "connection", "constraint", "constraints", "constructor", "contains", "continue",
2187 "convert", "corresponding", "count", "create", "cross", "cube", "current",
2188 "current_date", "current_default_transform_group", "current_path",
2189 "current_role", "current_time", "current_timestamp",
2190 "current_transform_group_for_type", "current_user", "cursor", "cycle", "data",
2191 "date", "day", "deallocate", "dec", "decimal", "declare", "default",
2192 "deferrable", "deferred", "delete", "depth", "deref", "desc", "describe",
2193 "descriptor", "deterministic", "diagnostics", "disconnect", "distinct", "do",
2194 "domain", "double", "drop", "dynamic", "each", "element", "else", "elseif",
2195 "end", "equals", "escape", "except", "exception", "exec", "execute", "exists",
2196 "exit", "external", "extract", "false", "fetch", "filter", "first", "float",
2197 "for", "foreign", "found", "free", "from", "full", "function", "general", "get",
2198 "global", "go", "goto", "grant", "group", "grouping", "handler", "having",
2199 "hold", "hour", "identity", "if", "immediate", "in", "indicator", "initially",
2200 "inner", "inout", "input", "insensitive", "insert", "int", "integer",
2201 "intersect", "interval", "into", "is", "isolation", "iterate", "join", "key",
2202 "language", "large", "last", "lateral", "leading", "leave", "left", "level",
2203 "like", "local", "localtime", "localtimestamp", "locator", "loop", "lower",
2204 "map", "match", "max", "member", "merge", "method", "min", "minute", "modifies",
2205 "module", "month", "multiset", "names", "national", "natural", "nchar", "nclob",
2206 "new", "next", "no", "none", "not", "null", "nullif", "numeric", "object",
2207 "octet_length", "of", "old", "on", "only", "open", "option", "or", "order",
2208 "ordinality", "out", "outer", "output", "over", "overlaps", "pad", "parameter",
2209 "partial", "partition", "path", "position", "precision", "prepare", "preserve",
2210 "primary", "prior", "privileges", "procedure", "public", "range", "read",
2211 "reads", "real", "recursive", "ref", "references", "referencing", "relative",
2212 "release", "repeat", "resignal", "restrict", "result", "return", "returns",
2213 "revoke", "right", "role", "rollback", "rollup", "routine", "row", "rows",
2214 "savepoint", "schema", "scope", "scroll", "search", "second", "section",
2215 "select", "sensitive", "session", "session_user", "set", "sets", "signal",
2216 "similar", "size", "smallint", "some", "space", "specific", "specifictype",
2217 "sql", "sqlcode", "sqlerror", "sqlexception", "sqlstate", "sqlwarning", "start",
2218 "state", "static", "submultiset", "substring", "sum", "symmetric", "system",
2219 "system_user", "table", "tablesample", "temporary", "then", "time", "timestamp",
2220 "timezone_hour", "timezone_minute", "to", "trailing", "transaction", "translate",
2221 "translation", "treat", "trigger", "trim", "true", "under", "undo", "union",
2222 "unique", "unknown", "unnest", "until", "update", "upper", "usage", "user",
2223 "using", "value", "values", "varchar", "varying", "view", "when", "whenever",
2224 "where", "while", "window", "with", "within", "without", "work", "write", "year",
2225 "zone",
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236 local captureddialects = words {
2237 "a", "abort", "abs", "access", "ada", "admin", "aggregate", "alias", "also",
2238 "always", "analyse", "analyze", "assignment", "attribute", "attributes", "audit",
2239 "auto_increment", "avg_row_length", "backup", "backward", "bernoulli", "bitvar",
2240 "bool", "break", "browse", "bulk", "c", "cache", "cardinality", "catalog_name",
2241 "ceil", "ceiling", "chain", "change", "character_set_catalog",
2242 "character_set_name", "character_set_schema", "characteristics", "characters",
2243 "checked", "checkpoint", "checksum", "class", "class_origin", "cluster",
2244 "clustered", "cobol", "collation_catalog", "collation_name", "collation_schema",
2245 "collect", "column_name", "columns", "command_function", "command_function_code",
2246 "comment", "committed", "completion", "compress", "compute", "condition_number",
2247 "connection_name", "constraint_catalog", "constraint_name", "constraint_schema",
2248 "containstable", "conversion", "copy", "corr", "covar_pop", "covar_samp",
2249 "createdb", "createrole", "createuser", "csv", "cume_dist", "cursor_name",
2250 "database", "databases", "datetime", "datetime_interval_code",
2251 "datetime_interval_precision", "day_hour", "day_microsecond", "day_minute",
2252 "day_second", "dayofmonth", "dayofweek", "dayofyear", "dbcc", "defaults",
2253 "defined", "definer", "degree", "delay_key_write", "delayed", "delimiter",
2254 "delimiters", "dense_rank", "deny", "derived", "destroy", "destructor",
2255 "dictionary", "disable", "disk", "dispatch", "distinctrow", "distributed", "div",
2256 "dual", "dummy", "dump", "dynamic_function", "dynamic_function_code", "enable",
2257 "enclosed", "encoding", "encrypted", "end-exec", "enum", "errlvl", "escaped",
2258 "every", "exclude", "excluding", "exclusive", "existing", "exp", "explain",
2259 "fields", "file", "fillfactor", "final", "float4", "float8", "floor", "flush",
2260 "following", "force", "fortran", "forward", "freetext", "freetexttable",
2261 "freeze", "fulltext", "fusion", "g", "generated", "granted", "grants",
2262 "greatest", "header", "heap", "hierarchy", "high_priority", "holdlock", "host",
2263 "hosts", "hour_microsecond", "hour_minute", "hour_second", "identified",
2264 "identity_insert", "identitycol", "ignore", "ilike", "immutable",
2265 "implementation", "implicit", "include", "including", "increment", "index",
2266 "infile", "infix", "inherit", "inherits", "initial", "initialize", "insert_id",
2267 "instance", "instantiable", "instead", "int1", "int2", "int3", "int4", "int8",
2268 "intersection", "invoker", "isam", "isnull", "k", "key_member", "key_type",
2269 "keys", "kill", "lancompiler", "last_insert_id", "least", "length", "less",
2270 "limit", "lineno", "lines", "listen", "ln", "load", "location", "lock", "login",
2271 "logs", "long", "longblob", "longtext", "low_priority", "m", "matched",
2272 "max_rows", "maxextents", "maxvalue", "mediumblob", "mediumint", "mediumtext",
2273 "message_length", "message_octet_length", "message_text", "middleint",
2274 "min_rows", "minus", "minute_microsecond", "minute_second", "minvalue",
2275 "mlslabel", "mod", "mode", "modify", "monthname", "more", "move", "mumps",
2276 "myisam", "name", "nesting", "no_write_to_binlog", "noaudit", "nocheck",
2277 "nocompress", "nocreatedb", "nocreaterole", "nocreateuser", "noinherit",
2278 "nologin", "nonclustered", "normalize", "normalized", "nosuperuser", "nothing",
2279 "notify", "notnull", "nowait", "nullable", "nulls", "number", "octets", "off",
2280 "offline", "offset", "offsets", "oids", "online", "opendatasource", "openquery",
2281 "openrowset", "openxml", "operation", "operator", "optimize", "optionally",
2282 "options", "ordering", "others", "outfile", "overlay", "overriding", "owner",
2283 "pack_keys", "parameter_mode", "parameter_name", "parameter_ordinal_position",
2284 "parameter_specific_catalog", "parameter_specific_name",
2285 "parameter_specific_schema", "parameters", "pascal", "password", "pctfree",
2286 "percent", "percent_rank", "percentile_cont", "percentile_disc", "placing",
2287 "plan", "pli", "postfix", "power", "preceding", "prefix", "preorder", "prepared",
2288 "print", "proc", "procedural", "process", "processlist", "purge", "quote",
2289 "raid0", "raiserror", "rank", "raw", "readtext", "recheck", "reconfigure",
2290 "regexp", "regr_avgx", "regr_avgy", "regr_count", "regr_intercept", "regr_r2",
2291 "regr_slope", "regr_sxx", "regr_sxy", "regr_syy", "reindex", "reload", "rename",
2292 "repeatable", "replace", "replication", "require", "reset", "resource",
2293 "restart", "restore", "returned_cardinality", "returned_length",
2294 "returned_octet_length", "returned_sqlstate", "rlike", "routine_catalog",
2295 "routine_name", "routine_schema", "row_count", "row_number", "rowcount",
2296 "rowguidcol", "rowid", "rownum", "rule", "save", "scale", "schema_name",
2297 "schemas", "scope_catalog", "scope_name", "scope_schema", "second_microsecond",
2298 "security", "self", "separator", "sequence", "serializable", "server_name",
2299 "setof", "setuser", "share", "show", "shutdown", "simple", "soname", "source",
2300 "spatial", "specific_name", "sql_big_result", "sql_big_selects",
2301 "sql_big_tables", "sql_calc_found_rows", "sql_log_off", "sql_log_update",
2302 "sql_low_priority_updates", "sql_select_limit", "sql_small_result",
2303 "sql_warnings", "sqlca", "sqrt", "ssl", "stable", "starting", "statement",
2304 "statistics", "status", "stddev_pop", "stddev_samp", "stdin", "stdout",
2305 "storage", "straight_join", "strict", "string", "structure", "style",
2306 "subclass_origin", "sublist", "successful", "superuser", "synonym", "sysdate",
2307 "sysid", "table_name", "tables", "tablespace", "temp", "template", "terminate",
2308 "terminated", "text", "textsize", "than", "ties", "tinyblob", "tinyint",
2309 "tinytext", "toast", "top", "top_level_count", "tran", "transaction_active",
2310 "transactions_committed", "transactions_rolled_back", "transform", "transforms",
2311 "trigger_catalog", "trigger_name", "trigger_schema", "truncate", "trusted",
2312 "tsequal", "type", "uescape", "uid", "unbounded", "uncommitted", "unencrypted",
2313 "unlisten", "unlock", "unnamed", "unsigned", "updatetext", "use",
2314 "user_defined_type_catalog", "user_defined_type_code", "user_defined_type_name",
2315 "user_defined_type_schema", "utc_date", "utc_time", "utc_timestamp", "vacuum",
2316 "valid", "validate", "validator", "var_pop", "var_samp", "varbinary", "varchar2",
2317 "varcharacter", "variable", "variables", "verbose", "volatile", "waitfor",
2318 "width_bucket", "writetext", "x509", "xor", "year_month", "zerofill",
2319 }
2320
2321 local capturedoperators = oneof {
2322 "+", "-", "*", "/",
2323 "%", "^", "!", "&", "|", "?", "~",
2324 "=", "<", ">",
2325 ";", ":", ".",
2326 "{", "}", "[", "]", "(", ")",
2327 }
2328
2329 local spaces = "\\s*"
2330 local identifier = "[a-zA-Z\\_][a-zA-Z0-9\\_]*"
2331
2332 local comment = "%.*$\\n?"
2333 local commentopen = "/\\*"
2334 local commentclose = "\\*/"
2335
2336 local doublequote = "\""
2337 local singlequote = "\'"
2338 local reversequote = "`"
2339
2340 local doublecontent = "(?:\\\\\"|[^\"])*"
2341 local singlecontent = "(?:\\\\\'|[^\'])*"
2342 local reversecontent = "(?:\\\\`|[^`])*"
2343
2344 local decnumber = "[\\-]?[0-9]+(\\.[0-9]+)?([eEpP]\\-?[0-9]+)?"
2345
2346 local captureddouble = capture(doublequote) .. capture(doublecontent) .. capture(doublequote)
2347 local capturedsingle = capture(singlequote) .. capture(singlecontent) .. capture(singlequote)
2348 local capturedreverse = capture(reversequote) .. capture(reversecontent) .. capture(reversequote)
2349
2350 local style, styled = styler("sql")
2351
2352 registerlexer {
2353
2354 category = "sql",
2355 description = "ConTeXt SQL",
2356 suffixes = { "sql" },
2357 version = "1.0.0",
2358
2359 setup = configuration {
2360
2361
2362
2363
2364 },
2365
2366 repository = {
2367
2368 comment_short = {
2369 name = style("context.comment", "comment.comment"),
2370 match = comment,
2371 },
2372
2373 comment_long = {
2374 name = style("context.comment", "comment.text"),
2375 ["begin"] = commentopen,
2376 ["end"] = commentclose,
2377 beginCaptures = { ["0"] = styled("context.command", "comment.open") },
2378 endCaptures = { ["0"] = styled("context.command", "comment.close") },
2379 },
2380
2381 keyword_standard = {
2382 name = style("context.keyword", "reserved.standard"),
2383 match = capturedkeywords,
2384 },
2385
2386 keyword_dialect = {
2387 name = style("context.keyword", "reserved.dialect"),
2388 match = captureddialects,
2389 },
2390
2391 operator = {
2392 name = style("context.special", "operator"),
2393 match = capturedoperators,
2394
2395 },
2396
2397 identifier = {
2398 name = style("context.text", "identifier"),
2399 match = identifier,
2400 },
2401
2402 string_double = {
2403 match = captureddouble,
2404 captures = {
2405 ["1"] = styled("context.special", "doublequoted.open"),
2406 ["2"] = styled("context.text", "doublequoted.text"),
2407 ["3"] = styled("context.special", "doublequoted.close"),
2408 },
2409 },
2410
2411 string_single = {
2412 match = capturedsingle,
2413 captures = {
2414 ["1"] = styled("context.special", "singlequoted.open"),
2415 ["2"] = styled("context.text", "singlequoted.text"),
2416 ["3"] = styled("context.special", "singlequoted.close"),
2417 },
2418 },
2419
2420 string_reverse = {
2421 match = capturedreverse,
2422 captures = {
2423 ["1"] = styled("context.special", "reversequoted.open"),
2424 ["2"] = styled("context.text", "reversequoted.text"),
2425 ["3"] = styled("context.special", "reversequoted.close"),
2426 },
2427 },
2428
2429 number = {
2430 name = style("context.number", "number"),
2431 match = decnumber,
2432 },
2433
2434 },
2435
2436 patterns = {
2437 include("#keyword_standard"),
2438 include("#keyword_dialect"),
2439 include("#identifier"),
2440 include("#string_double"),
2441 include("#string_single"),
2442 include("#string_reverse"),
2443 include("#comment_long"),
2444 include("#comment_short"),
2445 include("#number"),
2446 include("#operator"),
2447 },
2448
2449 }
2450
2451 end
2452
2453
2454
2455 do
2456
2457 local operators = oneof {
2458 "*", "+", "-", "/",
2459 ",", ".", ":", ";",
2460 "(", ")", "<", ">", "{", "}", "[", "]",
2461 "#", "=", "?", "@", "|", " ", "!","$", "%", "&", "\\", "^", "-", "_", "`", "~",
2462 }
2463
2464 local spaces = "\\s*"
2465
2466 local text = "[a-zA-Z0-9]|" .. operators
2467
2468 local doublequote = "\""
2469 local singlequote = "\'"
2470
2471 local termopen = "<"
2472 local termclose = ">"
2473 local termcontent = "([a-zA-Z][a-zA-Z0-9\\-]*)"
2474
2475 local becomes = "::="
2476 local extra = "|"
2477
2478 local captureddouble = capture(doublequote) .. capture(text) .. capture(doublequote)
2479 local capturedsingle = capture(singlequote) .. capture(text) .. capture(singlequote)
2480 local capturedterm = capture(termopen) .. capture(termcontent) .. capture(termclose)
2481
2482 local style, styled = styler("bnf")
2483
2484 registerlexer {
2485
2486 category = "bnf",
2487 description = "ConTeXt BNF",
2488 suffixes = { "bnf" },
2489 version = "1.0.0",
2490
2491 setup = configuration {
2492 pairs = {
2493 { "<", ">" },
2494 },
2495 },
2496
2497 repository = {
2498
2499 term = {
2500 match = capturedterm,
2501 captures = {
2502 ["1"] = styled("context.command", "term.open"),
2503 ["2"] = styled("context.text", "term.text"),
2504 ["3"] = styled("context.command", "term.close"),
2505 },
2506 },
2507
2508 text_single = {
2509 match = capturedsingle,
2510 captures = {
2511 ["1"] = styled("context.special", "singlequoted.open"),
2512 ["2"] = styled("context.text", "singlequoted.text"),
2513 ["3"] = styled("context.special", "singlequoted.close"),
2514 },
2515 },
2516
2517 text_double = {
2518 match = captureddouble,
2519 captures = {
2520 ["1"] = styled("context.special", "doublequoted.open"),
2521 ["2"] = styled("context.text", "doublequoted.text"),
2522 ["3"] = styled("context.special", "doublequoted.close"),
2523 },
2524 },
2525
2526 becomes = {
2527 name = style("context.operator", "symbol.becomes"),
2528 match = becomes,
2529 },
2530
2531 extra = {
2532 name = style("context.extra", "symbol.extra"),
2533 match = extra,
2534 },
2535
2536 },
2537
2538 patterns = {
2539 include("#term"),
2540 include("#text_single"),
2541 include("#text_reverse"),
2542 include("#becomes"),
2543 include("#extra"),
2544 },
2545
2546 }
2547
2548 end
2549
2550 do
2551
2552
2553
2554
2555 local function words(list)
2556 table.sort(list,sorter)
2557 return "\\b(" .. concat(list,"|") .. ")\\b"
2558 end
2559
2560 local capturedkeywords = words {
2561
2562 "asm", "auto", "break", "case", "const", "continue", "default", "do", "else",
2563 "extern", "false", "for", "goto", "if", "inline", "register", "return",
2564 "sizeof", "static", "switch", "true", "typedef", "volatile", "while",
2565 "restrict",
2566
2567 "_Bool", "_Complex", "_Pragma", "_Imaginary",
2568
2569 "catch", "class", "const_cast", "delete", "dynamic_cast", "explicit",
2570 "export", "friend", "mutable", "namespace", "new", "operator", "private",
2571 "protected", "public", "signals", "slots", "reinterpret_cast",
2572 "static_assert", "static_cast", "template", "this", "throw", "try", "typeid",
2573 "typename", "using", "virtual"
2574 }
2575
2576 local captureddatatypes = words {
2577 "bool", "char", "double", "enum", "float", "int", "long", "short", "signed",
2578 "struct", "union", "unsigned", "void"
2579 }
2580
2581 local capturedluatex = words {
2582 "word", "halfword", "quarterword", "scaled", "pointer", "glueratio",
2583 }
2584
2585 local capturedmacros = words {
2586 "define", "elif", "else", "endif", "error", "if", "ifdef", "ifndef", "import",
2587 "include", "line", "pragma", "undef", "using", "warning"
2588 }
2589
2590 local operators = oneof {
2591 "*", "+", "-", "/",
2592 "%", "^", "!", "&", "?", "~", "|",
2593 "=", "<", ">",
2594 ";", ":", ".",
2595 "{", "}", "[", "]", "(", ")",
2596 }
2597
2598 local spaces = "\\s*"
2599
2600 local identifier = "[A-Za-z_][A-Za-z_0-9]*"
2601
2602 local comment = "//.*$\\n?"
2603 local commentopen = "/\\*"
2604 local commentclose = "\\*/"
2605
2606 local doublequote = "\""
2607 local singlequote = "\'"
2608 local reversequote = "`"
2609
2610 local doublecontent = "(?:\\\\\"|[^\"])*"
2611 local singlecontent = "(?:\\\\\'|[^\'])*"
2612
2613 local captureddouble = capture(doublequote) .. capture(doublecontent) .. capture(doublequote)
2614 local capturedsingle = capture(singlequote) .. capture(singlecontent) .. capture(singlequote)
2615
2616 local texopen = "/\\*tex"
2617 local texclose = "\\*/"
2618
2619 local hexnumber = "[\\-]?0[xX][A-Fa-f0-9]+(\\.[A-Fa-f0-9]+)?([eEpP]\\-?[A-Fa-f0-9]+)?"
2620 local decnumber = "[\\-]?[0-9]+(\\.[0-9]+)?([eEpP]\\-?[0-9]+)?"
2621
2622 local capturedmacros = spaces .. capture("#") .. spaces .. capturedmacros
2623
2624 local style, styled = styler("c")
2625
2626 registerlexer {
2627
2628 category = "cpp",
2629 description = "ConTeXt C",
2630 suffixes = { "c", "h", "cpp", "hpp" },
2631 version = "1.0.0",
2632
2633 setup = configuration {
2634 pairs = {
2635 { "{", "}" },
2636 { "[", "]" },
2637 { "(", ")" },
2638 },
2639 },
2640
2641 repository = {
2642
2643 keyword = {
2644 match = capturedkeywords,
2645 name = style("context.keyword","c"),
2646 },
2647
2648 datatype = {
2649 match = captureddatatypes,
2650 name = style("context.keyword","datatype"),
2651 },
2652
2653 luatex = {
2654 match = capturedluatex,
2655 name = style("context.command","luatex"),
2656 },
2657
2658 macro = {
2659 match = capturedmacros,
2660 captures = {
2661 ["1"] = styled("context.data","macro.tag"),
2662 ["2"] = styled("context.data","macro.name"),
2663 }
2664 },
2665
2666 texcomment = {
2667 ["begin"] = texopen,
2668 ["end"] = texclose,
2669 patterns = embedded("tex"),
2670 beginCaptures = { ["0"] = styled("context.comment", "tex.open") },
2671 endCaptures = { ["0"] = styled("context.comment", "tex.close") },
2672 },
2673
2674 longcomment = {
2675 name = style("context.comment","long"),
2676 ["begin"] = commentopen,
2677 ["end"] = commentclose,
2678 },
2679
2680 shortcomment = {
2681 name = style("context.comment","short"),
2682 match = comment,
2683 },
2684
2685 identifier = {
2686 name = style("context.default","identifier"),
2687 match = identifier,
2688 },
2689
2690 operator = {
2691 name = style("context.operator","any"),
2692 match = operators,
2693 },
2694
2695 string_double = {
2696 match = captureddouble,
2697 captures = {
2698 ["1"] = styled("context.special", "doublequoted.open"),
2699 ["2"] = styled("context.string", "doublequoted.text"),
2700 ["3"] = styled("context.special", "doublequoted.close"),
2701 },
2702 },
2703
2704 string_single = {
2705 match = capturedsingle,
2706 captures = {
2707 ["1"] = styled("context.special", "singlequoted.open"),
2708 ["2"] = styled("context.string", "singlequoted.text"),
2709 ["3"] = styled("context.special", "singlequoted.close"),
2710 },
2711 },
2712
2713 hexnumber = {
2714 name = style("context.number","hex"),
2715 match = hexnumber,
2716 },
2717
2718 decnumber = {
2719 name = style("context.number","dec"),
2720 match = decnumber,
2721 },
2722
2723 },
2724
2725 patterns = {
2726 include("#keyword"),
2727 include("#datatype"),
2728 include("#luatex"),
2729 include("#identifier"),
2730 include("#macro"),
2731 include("#string_double"),
2732 include("#string_single"),
2733 include("#texcomment"),
2734 include("#longcomment"),
2735 include("#shortcomment"),
2736 include("#hexnumber"),
2737 include("#decnumber"),
2738 include("#operator"),
2739 },
2740
2741 }
2742
2743 end
2744
2745
2746
2747 do
2748
2749
2750
2751 local spaces = "\\s*"
2752
2753 local reserved = oneof { "true" ,"false" , "null" }
2754 local reference = "R"
2755
2756 local dictionaryopen = "<<"
2757 local dictionaryclose = ">>"
2758
2759 local arrayopen = "\\["
2760 local arrayclose = "\\]"
2761
2762 local stringopen = "\\("
2763 local stringcontent = "(?:\\\\[\\(\\)]|[^\\(\\)])*"
2764 local stringclose = "\\)"
2765
2766 local hexstringopen = "<"
2767 local hexstringcontent = "[^>]*"
2768 local hexstringclose = ">"
2769
2770 local unicodebomb = "feff"
2771
2772 local objectopen = "obj"
2773 local objectclose = "endobj"
2774
2775 local streamopen = "^stream$"
2776 local streamclose = "^endstream$"
2777
2778 local name = "/[^\\s<>/\\[\\]\\(\\)]+"
2779 local integer = "[\\-]?[0-9]+"
2780 local real = "[\\-]?[0-9]*[\\.]?[0-9]+"
2781
2782 local capturedcardinal = "([0-9]+)"
2783
2784 local captureddictionaryopen = capture(dictionaryopen)
2785 local captureddictionaryclose = capture(dictionaryclose)
2786
2787 local capturedarrayopen = capture(arrayopen)
2788 local capturedarrayclose = capture(arrayclose)
2789
2790 local capturedobjectopen = capture(objectopen)
2791 local capturedobjectclose = capture(objectclose)
2792
2793 local capturedname = capture(name)
2794 local capturedinteger = capture(integer)
2795 local capturedreal = capture(real)
2796 local capturedreserved = capture(reserved)
2797 local capturedreference = capture(reference)
2798
2799 local capturedunicode = capture(hexstringopen) .. capture(unicodebomb) .. capture(hexstringcontent) .. capture(hexstringclose)
2800 local capturedunicode = capture(hexstringopen) .. capture(unicodebomb) .. capture(hexstringcontent) .. capture(hexstringclose)
2801 local capturedwhatsit = capture(hexstringopen) .. capture(hexstringcontent) .. capture(hexstringclose)
2802 local capturedstring = capture(stringopen) .. capture(stringcontent) .. capture(stringclose)
2803
2804 local style, styled = styler("pdf")
2805
2806
2807
2808 registerlexer {
2809
2810 category = "pdf",
2811 description = "ConTeXt PDF",
2812 suffixes = { "pdf" },
2813 version = "1.0.0",
2814
2815 setup = configuration {
2816 pairs = {
2817 { "<", ">" },
2818 { "[", "]" },
2819 { "(", ")" },
2820 },
2821 },
2822
2823 repository = {
2824
2825 comment = {
2826 name = style("context.comment","comment"),
2827 match = "%.*$\\n?",
2828 },
2829
2830 content = {
2831 patterns = {
2832 { include = "#dictionary" },
2833 { include = "#stream" },
2834 { include = "#array" },
2835 {
2836 name = style("context.constant","object.content.name"),
2837 match = capturedname,
2838 },
2839 {
2840 match = capturedcardinal .. spaces .. capturedcardinal .. spaces .. capturedreference,
2841 captures = {
2842 ["1"] = styled("context.warning","content.reference.1"),
2843 ["2"] = styled("context.warning","content.reference.2"),
2844 ["3"] = styled("context.command","content.reference.3"),
2845 }
2846 },
2847 {
2848 name = style("context.number","content.real"),
2849 match = capturedreal,
2850 },
2851 {
2852 name = style("context.number","content.integer"),
2853 match = capturedinteger,
2854 },
2855 {
2856 match = capturedstring,
2857 captures = {
2858 ["1"] = styled("context.quote","content.string.open"),
2859 ["2"] = styled("context.string","content.string.text"),
2860 ["3"] = styled("context.quote","content.string.close"),
2861 }
2862 },
2863 {
2864 name = style("context.number","content.reserved"),
2865 match = capturedreserved,
2866 },
2867 {
2868 match = capturedunicode,
2869 captures = {
2870 ["1"] = styled("context.quote","content.unicode.open"),
2871 ["2"] = styled("context.plain","content.unicode.bomb"),
2872 ["3"] = styled("context.string","content.unicode.text"),
2873 ["4"] = styled("context.quote","content.unicode.close"),
2874 }
2875 },
2876 {
2877 match = capturedwhatsit,
2878 captures = {
2879 ["1"] = styled("context.quote","content.whatsit.open"),
2880 ["2"] = styled("context.string","content.whatsit.text"),
2881 ["3"] = styled("context.quote","content.whatsit.close"),
2882 }
2883 },
2884 },
2885 },
2886
2887 object = {
2888 ["begin"] = capturedcardinal .. spaces .. capturedcardinal .. spaces .. capturedobjectopen,
2889 ["end"] = capturedobjectclose,
2890 patterns = { { include = "#content" } },
2891 beginCaptures = {
2892 ["1"] = styled("context.warning","object.1"),
2893 ["2"] = styled("context.warning","object.2"),
2894 ["3"] = styled("context.keyword", "object.open")
2895 },
2896 endCaptures = {
2897 ["1"] = styled("context.keyword", "object.close")
2898 },
2899 },
2900
2901 array = {
2902 ["begin"] = capturedarrayopen,
2903 ["end"] = capturedarrayclose,
2904 patterns = { { include = "#content" } },
2905 beginCaptures = { ["1"] = styled("context.grouping", "array.open") },
2906 endCaptures = { ["1"] = styled("context.grouping", "array.close") },
2907 },
2908
2909 dictionary = {
2910 ["begin"] = captureddictionaryopen,
2911 ["end"] = captureddictionaryclose,
2912 beginCaptures = { ["1"] = styled("context.grouping", "dictionary.open") },
2913 endCaptures = { ["1"] = styled("context.grouping", "dictionary.close") },
2914 patterns = {
2915 {
2916 ["begin"] = capturedname .. spaces,
2917 ["end"] = "(?=[>])",
2918 beginCaptures = { ["1"] = styled("context.command", "dictionary.name") },
2919 patterns = { { include = "#content" } },
2920 },
2921 },
2922 },
2923
2924 xref = {
2925 ["begin"] = "xref" .. spaces,
2926 ["end"] = "(?=[^0-9])",
2927 captures = {
2928 ["0"] = styled("context.keyword", "xref.1"),
2929 },
2930 patterns = {
2931 {
2932 ["begin"] = capturedcardinal .. spaces .. capturedcardinal .. spaces,
2933 ["end"] = "(?=[^0-9])",
2934 captures = {
2935 ["1"] = styled("context.number", "xref.2"),
2936 ["2"] = styled("context.number", "xref.3"),
2937 },
2938 patterns = {
2939 {
2940 ["begin"] = capturedcardinal .. spaces .. capturedcardinal .. spaces .. "([fn])" .. spaces,
2941 ["end"] = "(?=.)",
2942 captures = {
2943 ["1"] = styled("context.number", "xref.4"),
2944 ["2"] = styled("context.number", "xref.5"),
2945 ["3"] = styled("context.keyword", "xref.6"),
2946 },
2947 },
2948 },
2949 },
2950 },
2951 },
2952
2953 startxref = {
2954 ["begin"] = "startxref" .. spaces,
2955 ["end"] = "(?=[^0-9])",
2956 captures = {
2957 ["0"] = styled("context.keyword", "startxref.1"),
2958 },
2959 patterns = {
2960 {
2961 ["begin"] = capturedcardinal .. spaces,
2962 ["end"] = "(?=.)",
2963 captures = {
2964 ["1"] = styled("context.number", "startxref.2"),
2965 },
2966 },
2967 },
2968 },
2969
2970 trailer = {
2971 name = style("context.keyword", "trailer"),
2972 match = "trailer",
2973 },
2974
2975 stream = {
2976 ["begin"] = streamopen,
2977 ["end"] = streamclose,
2978 beginCaptures = { ["0"] = styled("context.keyword", "stream.open") },
2979 endCaptures = { ["0"] = styled("context.keyword", "stream.close") },
2980 },
2981
2982 },
2983
2984 patterns = {
2985 include("#object"),
2986 include("#comment"),
2987 include("#trailer"),
2988 include("#dictionary"),
2989 include("#startxref"),
2990 include("#xref"),
2991 },
2992
2993 }
2994
2995 end
2996
2997
2998
2999
3000
3001 do
3002
3003 local spaces = "\\s*"
3004 local separator = "\\,"
3005 local becomes = "\\:"
3006
3007 local arrayopen = "\\["
3008 local arrayclose = "\\]"
3009
3010 local hashopen = "\\{"
3011 local hashclose = "\\}"
3012
3013 local stringopen = "\""
3014 local stringcontent = "(?:\\\\\"|[^\"])*"
3015 local stringclose = stringopen
3016
3017 local reserved = oneof { "true", "false", "null" }
3018
3019 local hexnumber = "[\\-]?0[xX][A-Fa-f0-9]+(\\.[A-Fa-f0-9]+)?([eEpP]\\-?[A-Fa-f0-9]+)?"
3020 local decnumber = "[\\-]?[0-9]+(\\.[0-9]+)?([eEpP]\\-?[0-9]+)?"
3021
3022 local capturedarrayopen = capture(arrayopen)
3023 local capturedarrayclose = capture(arrayclose)
3024 local capturedhashopen = capture(hashopen)
3025 local capturedhashclose = capture(hashclose)
3026
3027 local capturedreserved = capture(reserved)
3028 local capturedbecomes = capture(becomes)
3029 local capturedseparator = capture(separator)
3030 local capturedstring = capture(stringopen) .. capture(stringcontent) .. capture(stringclose)
3031 local capturedhexnumber = capture(hexnumber)
3032 local captureddecnumber = capture(decnumber)
3033
3034 local style, styled = styler("json")
3035
3036 registerlexer {
3037
3038 category = "json",
3039 description = "ConTeXt JSON",
3040 suffixes = { "json" },
3041 version = "1.0.0",
3042
3043 setup = configuration {
3044 pairs = {
3045 { "{", "}" },
3046 { "[", "]" },
3047 },
3048 },
3049
3050 repository = {
3051
3052 separator = {
3053 name = style("context.operator","separator"),
3054 match = spaces .. capturedseparator,
3055 },
3056
3057 reserved = {
3058 name = style("context.primitive","reserved"),
3059 match = spaces .. capturedreserved,
3060 },
3061
3062 hexnumber = {
3063 name = style("context.number","hex"),
3064 match = spaces .. capturedhexnumber,
3065 },
3066
3067 decnumber = {
3068 name = style("context.number","dec"),
3069 match = spaces .. captureddecnumber,
3070 },
3071
3072 string = {
3073 match = spaces .. capturedstring,
3074 captures = {
3075 ["1"] = styled("context.quote","string.open"),
3076 ["2"] = styled("context.string","string.text"),
3077 ["3"] = styled("context.quote","string.close"),
3078 },
3079 },
3080
3081 kv_reserved = {
3082 match = capturedstring .. spaces .. capturedbecomes .. spaces .. capturedreserved,
3083 captures = {
3084 ["1"] = styled("context.quote", "reserved.key.open"),
3085 ["2"] = styled("context.text", "reserved.key.text"),
3086 ["3"] = styled("context.quote", "reserved.key.close"),
3087 ["4"] = styled("context.operator", "reserved.becomes"),
3088 ["5"] = styled("context.primitive","reserved.value"),
3089 }
3090 },
3091
3092 kv_hexnumber = {
3093 match = capturedstring .. spaces .. capturedbecomes .. spaces .. capturedhexnumber,
3094 captures = {
3095 ["1"] = styled("context.quote", "hex.key.open"),
3096 ["2"] = styled("context.text", "hex.key.text"),
3097 ["3"] = styled("context.quote", "hex.key.close"),
3098 ["4"] = styled("context.operator","hex.becomes"),
3099 ["5"] = styled("context.number", "hex.value"),
3100 }
3101 },
3102
3103 kv_decnumber = {
3104 match = capturedstring .. spaces .. capturedbecomes .. spaces .. captureddecnumber,
3105 captures = {
3106 ["1"] = styled("context.quote", "dec.key.open"),
3107 ["2"] = styled("context.text", "dec.key.text"),
3108 ["3"] = styled("context.quote", "dec.key.close"),
3109 ["4"] = styled("context.operator","dec.becomes"),
3110 ["5"] = styled("context.number", "dec.value"),
3111 }
3112 },
3113
3114 kv_string = {
3115 match = capturedstring .. spaces .. capturedbecomes .. spaces .. capturedstring,
3116 captures = {
3117 ["1"] = styled("context.quote", "string.key.open"),
3118 ["2"] = styled("context.text", "string.key.text"),
3119 ["3"] = styled("context.quote", "string.key.close"),
3120 ["4"] = styled("context.operator","string.becomes"),
3121 ["5"] = styled("context.quote", "string.value.open"),
3122 ["6"] = styled("context.string", "string.value.text"),
3123 ["7"] = styled("context.quote", "string.value.close"),
3124 },
3125 },
3126
3127 kv_array = {
3128 ["begin"] = capturedstring .. spaces .. capturedbecomes .. spaces .. capturedarrayopen,
3129 ["end"] = arrayclose,
3130 beginCaptures = {
3131 ["1"] = styled("context.quote", "array.key.open"),
3132 ["2"] = styled("context.text", "array.key.text"),
3133 ["3"] = styled("context.quote", "array.key.close"),
3134 ["4"] = styled("context.operator","array.becomes"),
3135 ["5"] = styled("context.grouping","array.value.open")
3136 },
3137 endCaptures = {
3138 ["0"] = styled("context.grouping","array.value.close")
3139 },
3140 patterns = { include("#content") },
3141 },
3142
3143 kv_hash = {
3144 ["begin"] = capturedstring .. spaces .. capturedbecomes .. spaces .. capturedhashopen,
3145 ["end"] = hashclose,
3146 beginCaptures = {
3147 ["1"] = styled("context.quote", "hash.key.open"),
3148 ["2"] = styled("context.text", "hash.key.text"),
3149 ["3"] = styled("context.quote", "hash.key.close"),
3150 ["4"] = styled("context.operator","hash.becomes"),
3151 ["5"] = styled("context.grouping","hash.value.open")
3152 },
3153 endCaptures = {
3154 ["0"] = styled("context.grouping","hash.value.close")
3155 },
3156 patterns = { include("#kv_content") },
3157 },
3158
3159 content = {
3160 patterns = {
3161 include("#string"),
3162 include("#hexnumber"),
3163 include("#decnumber"),
3164 include("#reserved"),
3165 include("#hash"),
3166 include("#array"),
3167 include("#separator"),
3168 },
3169 },
3170
3171 kv_content = {
3172 patterns = {
3173 include("#kv_string"),
3174 include("#kv_hexnumber"),
3175 include("#kv_decnumber"),
3176 include("#kv_reserved"),
3177 include("#kv_hash"),
3178 include("#kv_array"),
3179 include("#separator"),
3180 },
3181 },
3182
3183 array = {
3184 ["begin"] = arrayopen,
3185 ["end"] = arrayclose,
3186 beginCaptures = { ["0"] = styled("context.grouping","array.open") },
3187 endCaptures = { ["0"] = styled("context.grouping","array.close") },
3188 patterns = { include("#content") },
3189 },
3190
3191 hash = {
3192 ["begin"] = hashopen,
3193 ["end"] = hashclose,
3194 beginCaptures = { ["0"] = styled("context.grouping","hash.open") },
3195 endCaptures = { ["0"] = styled("context.grouping","hash.close") },
3196 patterns = { include("#kv_content") },
3197 },
3198
3199 },
3200
3201 patterns = {
3202 include("#content"),
3203 },
3204
3205 }
3206
3207 end
3208
3209 savepackage()
3210
3211end
3212
3213
3214
3215function scripts.vscode.ls(forcedinterface)
3216
3217 local interfaces = forcedinterfaces or environment.files or userinterfaces
3218 if not interfaces.en then
3219
3220 interfaces = { "en" }
3221 end
3222
3223 local filename = "context-en.xml"
3224 local xmlfile = resolvers.findfile(filename) or ""
3225 if xmlfile == "" then
3226 report("unable to locate %a",filename)
3227 return
3228 end
3229
3230 local filename = "mult-def.lua"
3231 local deffile = resolvers.findfile(filename) or ""
3232 if deffile == "" then
3233 report("unable to locate %a",filename)
3234 return
3235 end
3236 local interface = dofile(deffile)
3237 if not interface or not next(interface) then
3238 report("invalid file %a",filename)
3239 return
3240 end
3241 local variables = interface.variables
3242 local constants = interface.constants
3243 local commands = interface.commands
3244 local elements = interface.elements
3245
3246 local collected = { }
3247
3248 report("loading %a",xmlfile)
3249 local xmlroot = xml.load(xmlfile)
3250
3251 local interfaces = { "en" }
3252
3253
3254
3255
3256
3257 local function arguments(e)
3258 local p = { }
3259 for e in xml.collected(e,"/cd:arguments/*") do
3260 local tg = e.tg
3261 if tg == "keywords" then
3262 local a = { }
3263 for e in xml.collected(e,"/*") do
3264 a[#a+1] = {
3265 name = e.at.type
3266 }
3267 end
3268 p[#p+1] = {
3269 type = tg,
3270 attributes = #a > 0 and a or nil,
3271 optional = e.at.optional == "yes" or nil
3272 }
3273 elseif tg == "assignments" then
3274 local a = { }
3275 for e in xml.collected(e,"/parameter") do
3276
3277 local c = { }
3278 for e in xml.collected(e,"/constant") do
3279 c[#c+1] = e.at.type
3280 end
3281
3282
3283
3284
3285
3286 a[#a+1] = {
3287 name = e.at.name .. "=" .. concat(c, " ")
3288 }
3289 end
3290 p[#p+1] = {
3291 type = tg,
3292 attributes = #a > 0 and a or nil,
3293 optional = e.at.optional == "yes" or nil
3294 }
3295 else
3296 p[#p+1] = {
3297 type = tg,
3298 optional = e.at.optional == "yes" or nil
3299 }
3300 end
3301 end
3302 return p
3303 end
3304
3305 local function details(e, f)
3306 local d = { "\\" .. f }
3307 local n = 0
3308 for e in xml.collected(e,"/cd:arguments/*") do
3309 local tg = e.tg
3310 if tg == "keywords" then
3311 n = n + 1
3312 if e.at.optional == "yes" then
3313 d[#d+1] = "[optional " .. n .. ":..,..]"
3314 else
3315 d[#d+1] = "[mandate " .. n .. ":..,..]"
3316 end
3317 elseif tg == "assignments" then
3318 n = n + 1
3319 if e.at.optional == "yes" then
3320 d[#d+1] = "[optional " .. n .. ":key=val,key=val,..]"
3321 else
3322 d[#d+1] = "[mandate " .. n .. ":key=val,key=val,..]"
3323 end
3324 else
3325 d[#d+1] = "{ content }"
3326 end
3327 end
3328 return concat(d, " ")
3329 end
3330
3331
3332
3333
3334 local function documentation(c)
3335 local d = { c.detail }
3336 local p = c.params
3337 if p then
3338 local n = 0
3339 for i=1,#p do
3340 local pi = p[i]
3341 local ti = pi.type
3342 local ai = pi.attributes
3343 if ti == "keywords" then
3344 n = n + 1
3345 if pi.optional then
3346 d[#d+1] = "[optional keywords " .. n .. "]"
3347 else
3348 d[#d+1] = "[mandate keywords " .. n .. "]"
3349 end
3350 if ai then
3351 local t = { }
3352 for j=1,#ai do
3353 t[#t+1] = ai[j].name
3354 end
3355 if #t > 0 then
3356 d[#d+1] = concat(t," ")
3357 end
3358 end
3359 elseif ti == "assignments" then
3360 n = n + 1
3361 if pi.optional then
3362 d[#d+1] = "[optional assignments " .. n .. "]"
3363 else
3364 d[#d+1] = "[mandate assignments " .. n .. "]"
3365 end
3366 if ai then
3367 local t = { }
3368 for j=1,#ai do
3369 t[#t+1] = ai[j].name
3370 end
3371 if #t > 0 then
3372 d[#d+1] = concat(t,"\n")
3373 end
3374 end
3375 else
3376 if pi.optional then
3377 d[#d+1] = "{ optional content }"
3378 else
3379 d[#d+1] = "{ mandate content }"
3380 end
3381 end
3382 end
3383 end
3384 c.documentation = concat(d,"\n")
3385
3386 end
3387
3388 if not xml.expand then
3389
3390 function xml.expand(root,pattern,whatever)
3391 local collected = xml.applylpath(root,pattern)
3392 if collected then
3393 for c=1,#collected do
3394 local e = collected[c]
3395 local p = e.__p__
3396 if p then
3397 local d = p.dt
3398 local n = e.ni
3399 local t = whatever(e,p)
3400 if type(t) == "table" then
3401 d[n] = t[1]
3402 for i=2,#t do
3403 n = n + 1
3404 table.insert(d,n,t[i])
3405 end
3406 elseif t then
3407 d[n] = t
3408 end
3409 end
3410 end
3411 end
3412 end
3413 end
3414
3415 do
3416 local c = { }
3417 xml.expand(xmlroot,"/cd:interface/cd:interface/cd:command/**/inherit",function(e)
3418 local f = c[e.at.name]
3419 if not f then
3420 f = xml.first(xmlroot,"/cd:interface/cd:interface/cd:command[@name='" .. e.at.name .. "']/cd:arguments")
3421 c[e.at.name] = f
3422 end
3423 return f and f.dt
3424 end)
3425 end
3426
3427 for i=1,#interfaces do
3428 local interface = interfaces[i]
3429 local start = elements.start[interface] or elements.start.en
3430 local stop = elements.stop [interface] or elements.stop .en
3431 for e in xml.collected(xmlroot,"cd:interface/cd:command") do
3432 local at = e.at
3433 local name = at["name"] or ""
3434 local type = at["type"]
3435 if name ~= "" then
3436 local c = commands[name]
3437 local n = (c and (c[interface] or c.en)) or c or name
3438 local sequence = xml.all(e,"/cd:sequence/*")
3439 if at.generated == "yes" then
3440
3441 elseif type ~= "environment" then
3442 collected[#collected+1] = {
3443 name = n,
3444 detail = details(e, n),
3445 params = arguments(e),
3446 }
3447 else
3448 local f = start .. n
3449 collected[#collected+1] = {
3450 name = f,
3451 start = f,
3452 stop = stop .. n,
3453 detail = details(e, f),
3454 params = arguments(e),
3455 }
3456 end
3457 end
3458 end
3459 end
3460 for i=1,#collected do
3461 documentation(collected[i])
3462 end
3463 local jsonname = "vscode-context-ls.json"
3464
3465 report("")
3466 report("vscode ls file saved: %s",jsonname)
3467 report("")
3468 io.savedata(jsonname,utilities.json.tojson(collected))
3469
3470end
3471
3472function scripts.vscode.start()
3473 local path = locate()
3474 if path then
3475 local codecmd = environment.arguments.program or "code"
3476
3477
3478 local command = 'start "vs code context" ' .. codecmd .. ' --reuse-window --extensions-dir "' .. path .. '" --verbose --force --install-extension cdt.context'
3479 report("running command: %s",command)
3480 os.execute(command)
3481 end
3482end
3483
3484if environment.arguments.generate then
3485 scripts.vscode.generate()
3486elseif environment.arguments.lsfile then
3487 scripts.vscode.ls()
3488elseif environment.arguments.start then
3489 scripts.vscode.start()
3490elseif environment.arguments.exporthelp then
3491 application.export(environment.arguments.exporthelp,environment.files[1])
3492else
3493 application.help()
3494end
3495
3496
3497
3498
3499 |