C3 Monaco Custom Syntax Highlighting - construct.net

25/2/2025, 17:02:33

  1. // ==UserScript==
  2. // @name C3 Monaco Custom Syntax Highlighting - construct.net
  3. // @namespace Violentmonkey Scripts
  4. // @match https://editor.construct.net/*
  5. // @grant none
  6. // @version 1.0
  7. // @author Clovelt
  8. // @description 25/2/2025, 17:02:33
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12.  
  13. const myCustomTokenizer = {
  14. defaultToken: 'invalid',
  15.  
  16. keywords: [
  17. 'text', 'choice', 'wait', 'goto', 'comment',
  18. 'ShakeScreen', 'Overlay', 'psychicEffect', 'tweenInteractable', 'setLayoutEffect', 'setLayerEffect',
  19. 'setAnim', 'fadeInteractable', 'setSpriteAnim', 'invertUI', 'interactablesSetShake', 'interactablesShake', 'interactablesGlow', 'interactablesGlowColor',
  20. 'playSound', 'playMusic', 'setAudioEffect',
  21. 'dialog.toggleShow', 'toggleLayerVisible', 'goToLayout',
  22. 'setDialogLines', 'saveGame', 'questTrackerAdd', 'questTrackerRemove',
  23. 'pan', 'panInt', 'panBack'
  24. ],
  25.  
  26. operators: [
  27. '=', '<', '<=', '>', '>=', '==', '!=', '?', ':', '|', '&'
  28. ],
  29.  
  30. symbols: /[=<>!?|&]+/,
  31.  
  32. tokenizer: {
  33. root: [
  34. [/^#.*/, 'keyword'], // Secciones en negrita
  35. [/^:.*/, 'comment'], // Comentarios (líneas que comienzan con ":")
  36. [/^(\w+)(?=\s*:)/, 'variable.parameter'], // Nombres de hablantes en azul
  37. [/\b[a-zA-Z_]\w*(?=\s*\()/, 'keyword'], // Funciones en color diferente
  38. [/\b[a-zA-Z_]\w*\b/, 'identifier'], // Identificadores generales (evita conflicto con funciones)
  39. [/\(/, { token: 'delimiter.parenthesis', bracket: '@open' }],
  40. [/\)/, { token: 'delimiter.parenthesis', bracket: '@close' }],
  41. [/"([^"\\]|\\.)*"/, 'string.special'], // Cadenas en funciones en naranja
  42. [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }],
  43. [/\/\*/, 'comment', '@comment'],
  44. [/\/\/.*$/, 'comment'],
  45. [/[^:\n]+/, ''], // Diálogo normal sin formato especial
  46. ],
  47.  
  48. comment: [
  49. [/[^*]+/, 'comment'],
  50. [/\*\//, 'comment', '@pop'],
  51. [/./, 'comment']
  52. ],
  53.  
  54. string: [
  55. [/[^\\"]+/, 'string'],
  56. [/\\./, 'string.escape'],
  57. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }]
  58. ],
  59.  
  60. whitespace: [
  61. [/[ \t\r\n]+/, 'white'],
  62. [/\/\*/, 'comment', '@comment'],
  63. [/\/\/.*$/, 'comment']
  64. ],
  65. },
  66. };
  67.  
  68. const waitForMonaco = setInterval(() => {
  69. if (typeof MonacoEnvironment !== 'undefined' && MonacoEnvironment.monaco) {
  70. clearInterval(waitForMonaco); // Stop checking once Monaco is ready
  71.  
  72. (async () => {
  73. const monaco = MonacoEnvironment.monaco;
  74.  
  75. // Retrieve all languages
  76. const allLangs = await monaco.languages.getLanguages();
  77. const jsLangDef = allLangs.find(({ id }) => id === 'javascript');
  78.  
  79. if (!jsLangDef) {
  80. console.error("JavaScript language not found!");
  81. return;
  82. }
  83.  
  84. // Load the language configuration and tokenizer
  85. const { conf, language: jsLang } = await jsLangDef.loader();
  86. if (!jsLang) {
  87. console.error("Failed to load JavaScript language configuration.");
  88. return;
  89. }
  90.  
  91. // Apply the stored tokenizer
  92. for (let key in myCustomTokenizer) {
  93. const value = myCustomTokenizer[key];
  94.  
  95. if (key === 'tokenizer') {
  96. for (let category in value) {
  97. const tokenDefs = value[category];
  98.  
  99. if (!jsLang.tokenizer.hasOwnProperty(category)) {
  100. jsLang.tokenizer[category] = [];
  101. }
  102.  
  103. if (Array.isArray(tokenDefs)) {
  104. jsLang.tokenizer[category].unshift(...tokenDefs);
  105. }
  106. }
  107. } else if (Array.isArray(value)) {
  108. if (!jsLang.hasOwnProperty(key)) {
  109. jsLang[key] = [];
  110. }
  111. jsLang[key].unshift(...value);
  112. }
  113. }
  114.  
  115. console.log("Custom tokenizer applied successfully!");
  116. })();
  117. }
  118. }, 100); // Check every 100ms until Monaco is available