@matdata/yasqe 5.12.0 → 5.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,6 +40,9 @@ export interface State {
40
40
  seenWhereClause: boolean;
41
41
  constructVariables: { [varName: string]: string };
42
42
  whereVariables: { [varName: string]: string };
43
+ pendingToken: Token | undefined;
44
+ bracketStack: Array<{ type: string; level: number }>;
45
+ bracketLevel: number;
43
46
  }
44
47
  export interface Token {
45
48
  quotePos: "end" | "start" | "content" | undefined;
@@ -292,7 +295,7 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
292
295
  {
293
296
  name: "PNAME_LN",
294
297
  regex: new RegExp("^" + PNAME_LN),
295
- style: "string-2",
298
+ style: "string",
296
299
  },
297
300
 
298
301
  {
@@ -322,6 +325,16 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
322
325
  }
323
326
 
324
327
  function tokenBase(stream: CodeMirror.StringStream, state: State) {
328
+ // If we have a pending token from a previous split, consume it from stream and return style
329
+ if (state.pendingToken) {
330
+ const token = state.pendingToken;
331
+ state.pendingToken = undefined;
332
+ // Advance the stream by the length of the pending token
333
+ stream.pos += token.string.length;
334
+ // Don't parse, just return the style
335
+ return token.style;
336
+ }
337
+
325
338
  function nextToken(): Token {
326
339
  let consumed: string[];
327
340
  if (state.inLiteral) {
@@ -375,6 +388,39 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
375
388
  for (var i = 0; i < terminals.length; ++i) {
376
389
  consumed = stream.match(terminals[i].regex as any, true, false) as any;
377
390
  if (consumed) {
391
+ // Special handling for PNAME_LN: split into prefix (string-2) and local name (string)
392
+ if (terminals[i].name === "PNAME_LN") {
393
+ const fullString = consumed[0];
394
+ const colonIndex = fullString.indexOf(":");
395
+ if (colonIndex >= 0) {
396
+ const prefixPart = fullString.substring(0, colonIndex + 1);
397
+ const localPart = fullString.substring(colonIndex + 1);
398
+
399
+ // Store the local name part for next token call
400
+ if (localPart.length > 0) {
401
+ state.pendingToken = {
402
+ cat: "PNAME_LN_LOCAL",
403
+ style: "string",
404
+ string: localPart,
405
+ start: stream.start + prefixPart.length,
406
+ quotePos: undefined,
407
+ };
408
+
409
+ // Back up the stream to just after the prefix part
410
+ stream.pos = stream.start + prefixPart.length;
411
+
412
+ // Return the prefix part
413
+ return {
414
+ cat: "PNAME_LN_PREFIX",
415
+ style: "string-2",
416
+ string: prefixPart,
417
+ start: stream.start,
418
+ quotePos: undefined,
419
+ };
420
+ }
421
+ }
422
+ }
423
+
378
424
  return {
379
425
  cat: terminals[i].name,
380
426
  style: terminals[i].style,
@@ -398,14 +444,45 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
398
444
 
399
445
  // Punctuation
400
446
  consumed = stream.match(grammar.punct, true, false) as any;
401
- if (consumed)
447
+ if (consumed) {
448
+ const punctChar = consumed[0];
449
+ let style = "punc";
450
+
451
+ // Rainbow bracket colorization (only for curly braces)
452
+ // Parentheses and square brackets always have the same color
453
+ if (punctChar === "{") {
454
+ // Opening curly brace - rainbow color
455
+ state.bracketStack.push({ type: punctChar, level: state.bracketLevel });
456
+ style = "bracket bracket-level-" + (state.bracketLevel % 4);
457
+ state.bracketLevel++;
458
+ } else if (punctChar === "}") {
459
+ // Closing curly brace - rainbow color
460
+ if (state.bracketStack.length > 0) {
461
+ const last = state.bracketStack.pop();
462
+ if (last) {
463
+ state.bracketLevel = last.level;
464
+ style = "bracket bracket-level-" + (last.level % 4);
465
+ }
466
+ } else {
467
+ // Unmatched closing bracket
468
+ style = "bracket bracket-mismatch";
469
+ }
470
+ } else if (punctChar === "[" || punctChar === "(") {
471
+ // Opening parenthesis or square bracket - constant color
472
+ style = "bracket bracket-paren";
473
+ } else if (punctChar === "]" || punctChar === ")") {
474
+ // Closing parenthesis or square bracket - constant color
475
+ style = "bracket bracket-paren";
476
+ }
477
+
402
478
  return {
403
479
  cat: stream.current(),
404
- style: "punc",
480
+ style: style,
405
481
  string: consumed[0],
406
482
  start: stream.start,
407
483
  quotePos: undefined,
408
484
  };
485
+ }
409
486
 
410
487
  // Token is invalid
411
488
  // better consume something anyway, or else we're stuck
@@ -498,6 +575,12 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
498
575
 
499
576
  const tokenOb = nextToken();
500
577
 
578
+ // If this is a pending token (second part of a split), just return its style without parsing
579
+ if (tokenOb.cat === "PNAME_LN_LOCAL") {
580
+ state.possibleCurrent = state.possibleNext;
581
+ return tokenOb.style;
582
+ }
583
+
501
584
  if (tokenOb.cat == "<invalid_token>") {
502
585
  // set error state, and
503
586
  if (state.OK == true) {
@@ -517,7 +600,8 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
517
600
  // or failure
518
601
  var finished = false;
519
602
  var topSymbol;
520
- const tokenCat = tokenOb.cat;
603
+ // Treat PNAME_LN_PREFIX as PNAME_LN for parsing purposes
604
+ const tokenCat = tokenOb.cat === "PNAME_LN_PREFIX" ? "PNAME_LN" : tokenOb.cat;
521
605
  if (state.possibleFullIri && tokenOb.string === ">") {
522
606
  state.possibleFullIri = false;
523
607
  }
@@ -576,7 +660,10 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
576
660
  }
577
661
 
578
662
  //check whether a used prefix is actually defined
579
- if (!state.inPrefixDecl && (tokenCat === "PNAME_NS" || tokenCat === "PNAME_LN")) {
663
+ if (
664
+ !state.inPrefixDecl &&
665
+ (tokenCat === "PNAME_NS" || tokenCat === "PNAME_LN" || tokenCat === "PNAME_LN_PREFIX")
666
+ ) {
580
667
  const colonIndex = tokenOb.string.indexOf(":");
581
668
  if (colonIndex >= 0) {
582
669
  const prefNs = tokenOb.string.slice(0, colonIndex);
@@ -747,6 +834,9 @@ export default function (config: CodeMirror.EditorConfiguration): CodeMirror.Mod
747
834
  seenWhereClause: false,
748
835
  constructVariables: {},
749
836
  whereVariables: {},
837
+ pendingToken: undefined,
838
+ bracketStack: [],
839
+ bracketLevel: 0,
750
840
  };
751
841
  },
752
842
  indent: indent,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@matdata/yasqe",
3
3
  "description": "Yet Another SPARQL Query Editor",
4
- "version": "5.12.0",
4
+ "version": "5.13.0",
5
5
  "main": "build/yasqe.min.js",
6
6
  "types": "build/ts/src/index.d.ts",
7
7
  "license": "MIT",
@@ -22,6 +22,28 @@
22
22
  font-size: 19px;
23
23
  }
24
24
  }
25
+
26
+ // Rainbow bracket colors for default theme
27
+ .cm-s-default {
28
+ span.cm-bracket-level-0 {
29
+ color: #ffd700;
30
+ } // Gold
31
+ span.cm-bracket-level-1 {
32
+ color: #da70d6;
33
+ } // Orchid
34
+ span.cm-bracket-level-2 {
35
+ color: #6bb0cc;
36
+ } // Sky blue
37
+ span.cm-bracket-level-3 {
38
+ color: #439143;
39
+ } // Pale green
40
+ span.cm-bracket-paren {
41
+ color: #997;
42
+ } // Constant color for () and []
43
+ span.cm-bracket-mismatch {
44
+ color: #f00;
45
+ } // Red for mismatched brackets
46
+ }
25
47
  // Put these outside of yasqe as the root element can be changed
26
48
  .CodeMirror-hints.default {
27
49
  max-width: 1000px;