Mercurial
comparison .cms/lib/codemirror/mode/sparql/sparql.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE | |
3 | |
4 (function(mod) { | |
5 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
6 mod(require("../../lib/codemirror")); | |
7 else if (typeof define == "function" && define.amd) // AMD | |
8 define(["../../lib/codemirror"], mod); | |
9 else // Plain browser env | |
10 mod(CodeMirror); | |
11 })(function(CodeMirror) { | |
12 "use strict"; | |
13 | |
14 CodeMirror.defineMode("sparql", function(config) { | |
15 var indentUnit = config.indentUnit; | |
16 var curPunc; | |
17 | |
18 function wordRegexp(words) { | |
19 return new RegExp("^(?:" + words.join("|") + ")$", "i"); | |
20 } | |
21 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri", | |
22 "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample", | |
23 "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen", | |
24 "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends", | |
25 "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds", | |
26 "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384", | |
27 "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists", | |
28 "isblank", "isliteral", "a", "bind"]); | |
29 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe", | |
30 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional", | |
31 "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group", | |
32 "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union", | |
33 "true", "false", "with", | |
34 "data", "copy", "to", "move", "add", "create", "drop", "clear", "load", "into"]); | |
35 var operatorChars = /[*+\-<>=&|\^\/!\?]/; | |
36 var PN_CHARS = "[A-Za-z_\\-0-9]"; | |
37 var PREFIX_START = new RegExp("[A-Za-z]"); | |
38 var PREFIX_REMAINDER = new RegExp("((" + PN_CHARS + "|\\.)*(" + PN_CHARS + "))?:"); | |
39 | |
40 function tokenBase(stream, state) { | |
41 var ch = stream.next(); | |
42 curPunc = null; | |
43 if (ch == "$" || ch == "?") { | |
44 if(ch == "?" && stream.match(/\s/, false)){ | |
45 return "operator"; | |
46 } | |
47 stream.match(/^[A-Za-z0-9_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][A-Za-z0-9_\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]*/); | |
48 return "variable-2"; | |
49 } | |
50 else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { | |
51 stream.match(/^[^\s\u00a0>]*>?/); | |
52 return "atom"; | |
53 } | |
54 else if (ch == "\"" || ch == "'") { | |
55 state.tokenize = tokenLiteral(ch); | |
56 return state.tokenize(stream, state); | |
57 } | |
58 else if (/[{}\(\),\.;\[\]]/.test(ch)) { | |
59 curPunc = ch; | |
60 return "bracket"; | |
61 } | |
62 else if (ch == "#") { | |
63 stream.skipToEnd(); | |
64 return "comment"; | |
65 } | |
66 else if (operatorChars.test(ch)) { | |
67 return "operator"; | |
68 } | |
69 else if (ch == ":") { | |
70 eatPnLocal(stream); | |
71 return "atom"; | |
72 } | |
73 else if (ch == "@") { | |
74 stream.eatWhile(/[a-z\d\-]/i); | |
75 return "meta"; | |
76 } | |
77 else if (PREFIX_START.test(ch) && stream.match(PREFIX_REMAINDER)) { | |
78 eatPnLocal(stream); | |
79 return "atom"; | |
80 } | |
81 stream.eatWhile(/[_\w\d]/); | |
82 var word = stream.current(); | |
83 if (ops.test(word)) | |
84 return "builtin"; | |
85 else if (keywords.test(word)) | |
86 return "keyword"; | |
87 else | |
88 return "variable"; | |
89 } | |
90 | |
91 function eatPnLocal(stream) { | |
92 stream.match(/(\.(?=[\w_\-\\%])|[:\w_-]|\\[-\\_~.!$&'()*+,;=/?#@%]|%[a-f\d][a-f\d])+/i); | |
93 } | |
94 | |
95 function tokenLiteral(quote) { | |
96 return function(stream, state) { | |
97 var escaped = false, ch; | |
98 while ((ch = stream.next()) != null) { | |
99 if (ch == quote && !escaped) { | |
100 state.tokenize = tokenBase; | |
101 break; | |
102 } | |
103 escaped = !escaped && ch == "\\"; | |
104 } | |
105 return "string"; | |
106 }; | |
107 } | |
108 | |
109 function pushContext(state, type, col) { | |
110 state.context = {prev: state.context, indent: state.indent, col: col, type: type}; | |
111 } | |
112 function popContext(state) { | |
113 state.indent = state.context.indent; | |
114 state.context = state.context.prev; | |
115 } | |
116 | |
117 return { | |
118 startState: function() { | |
119 return {tokenize: tokenBase, | |
120 context: null, | |
121 indent: 0, | |
122 col: 0}; | |
123 }, | |
124 | |
125 token: function(stream, state) { | |
126 if (stream.sol()) { | |
127 if (state.context && state.context.align == null) state.context.align = false; | |
128 state.indent = stream.indentation(); | |
129 } | |
130 if (stream.eatSpace()) return null; | |
131 var style = state.tokenize(stream, state); | |
132 | |
133 if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { | |
134 state.context.align = true; | |
135 } | |
136 | |
137 if (curPunc == "(") pushContext(state, ")", stream.column()); | |
138 else if (curPunc == "[") pushContext(state, "]", stream.column()); | |
139 else if (curPunc == "{") pushContext(state, "}", stream.column()); | |
140 else if (/[\]\}\)]/.test(curPunc)) { | |
141 while (state.context && state.context.type == "pattern") popContext(state); | |
142 if (state.context && curPunc == state.context.type) { | |
143 popContext(state); | |
144 if (curPunc == "}" && state.context && state.context.type == "pattern") | |
145 popContext(state); | |
146 } | |
147 } | |
148 else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); | |
149 else if (/atom|string|variable/.test(style) && state.context) { | |
150 if (/[\}\]]/.test(state.context.type)) | |
151 pushContext(state, "pattern", stream.column()); | |
152 else if (state.context.type == "pattern" && !state.context.align) { | |
153 state.context.align = true; | |
154 state.context.col = stream.column(); | |
155 } | |
156 } | |
157 | |
158 return style; | |
159 }, | |
160 | |
161 indent: function(state, textAfter) { | |
162 var firstChar = textAfter && textAfter.charAt(0); | |
163 var context = state.context; | |
164 if (/[\]\}]/.test(firstChar)) | |
165 while (context && context.type == "pattern") context = context.prev; | |
166 | |
167 var closing = context && firstChar == context.type; | |
168 if (!context) | |
169 return 0; | |
170 else if (context.type == "pattern") | |
171 return context.col; | |
172 else if (context.align) | |
173 return context.col + (closing ? 0 : 1); | |
174 else | |
175 return context.indent + (closing ? 0 : indentUnit); | |
176 }, | |
177 | |
178 lineComment: "#" | |
179 }; | |
180 }); | |
181 | |
182 CodeMirror.defineMIME("application/sparql-query", "sparql"); | |
183 | |
184 }); |