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