From 39ed16fb8944a228159531a1b0398058db9e2f60 Mon Sep 17 00:00:00 2001 From: Torben Leth Date: Sat, 8 Aug 2026 19:48:04 +0200 Subject: [PATCH] Fix highlightjs_al for Highlight.js v11 Two corrections to the AL grammar, and a rebuilt dist. The preprocessor mode uses the `meta-keyword` keyword group, which Highlight.js replaced with a nested `.meta .keyword` scope in v11 (highlightjs/highlight.js#3167, VERSION_11_UPGRADE.md). The default and mainstream themes no longer style the old class, so the directive keywords render unstyled: before: #pragma ... after: #pragma ... Auto-detection is also disabled. Running Highlight.js's 192 core detect fixtures with this grammar registered, AL takes exactly one that is not its own: cal, the C/AL fixture. That is expected, since C/AL is AL's predecessor and the two are near identical to a heuristic, and it is the situation the third party guide names as the reason to set disableAutodetect. Explicit registration and language-al are unaffected; highlightAuto callers lose AL detection. dist/al.min.js is regenerated, since it is committed here and is the only artifact consumers can load while the package is unpublished. Verified against a Highlight.js 11.11.2 build with this package linked into extra/. --- highlightjs_al/dist/al.min.js | 29 ++++++++++++++++++++++++++++- highlightjs_al/src/al.js | 8 +++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/highlightjs_al/dist/al.min.js b/highlightjs_al/dist/al.min.js index 161caf0..da5c715 100644 --- a/highlightjs_al/dist/al.min.js +++ b/highlightjs_al/dist/al.min.js @@ -1 +1,28 @@ -hljs.registerLanguage("al",function(){"use strict";return function(e){var t=["codeunit|10","enum","enumextension|10","page","pageextension|10","permissionset","permissionsetextension|10","profile","query","report","reportextension","table","tableextension|10","xmlport|10"],n=["pagecustomization|10","dotnet","controladdin|10","interface","entitlement","assembly"],i=t.concat(n),a={className:"number",variants:[e.NUMBER_MODE,{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)L"}],relevance:0},r="("+e.IDENT_RE+'|"([^"]|"")*")',o=[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],s={className:"class",begin:"("+t.join("|")+")\\s+(\\d+)\\s+"+r,returnBegin:!0,end:"{",contains:[{beginKeywords:t.join(" ")+" extends implements"},e.NUMBER_MODE,e.TITLE_MODE,e.C_BLOCK_COMMENT_MODE]},l={className:"class",begin:"[^:]\\s*("+n.join("|")+")\\s+"+r,returnBegin:!0,end:"{",contains:[{beginKeywords:n.join(" ")+" extends implements"},e.NUMBER_MODE,e.TITLE_MODE,e.C_BLOCK_COMMENT_MODE]},c={className:"function",beginKeywords:"procedure trigger",returnBegin:!0,end:/\(/,excludeEnd:!0,contains:[{beginKeywords:"procedure trigger"},e.TITLE_MODE].concat(o)};return{name:"AL",aliases:["al"],case_insensitive:!0,keywords:{keyword:["array","asserterror|10","begin","break","case","do","downto","else","end","event","exit","for","foreach","if","in","indataset|10","interface","internal","local|10","of","procedure|10","protected","repeat","runonclient","securityfiltering|10","suppressdispose|10","temporary","then","to","trigger|10","until","var","while","with","withevents|10"].concat(i).concat(["and","div","mod","not","or","xor"]).concat(["action","actions|10","add","addafter","addbefore","addfirst","addlast","area|10","assembly","chartpart","column","cuegroup","customizes","dataitem","dataset","elements|10","extends","field","fieldattribute","fieldelement","fieldgroup|10","fieldgroups|10","fields|10","filter","fixed","grid","group","implements","key","keys","label","labels","layout|10","modify","moveafter","movebefore","movefirst","movelast","part","repeater","requestpage|10","schema","separator","systempart","tableelement","textattribute","textelement","type","value"]).join(" "),built_in:"action array automation biginteger bigtext blob boolean byte char clienttype code codeunit connectiontype database dataclassification datascope date dateformula datetime decimal defaultlayout dialog dictionary dotnet dotnetassembly dotnettypedeclaration duration enum errorinfo errortype executioncontext executionmode fieldclass fieldref fieldtype file filterpagebuilder guid httpclient httpcontent httpheaders httprequestmessage httpresponsemessage instream integer joker jsonarray jsonobject jsontoken jsonvalue keyref list moduledependencyinfo moduleinfo none notification notificationscope objecttype option outstream page pageresult query record recordid recordref report reportformat securityfilter securityfiltering sessionsettings table tableconnectiontype tablefilter testaction testfield testfilterfield testpage testpermissions testrequestpage text textbuilder textconst textencoding time transactionmodel transactiontype variant verbosity version view views webserviceactioncontext webserviceactionresultcode xmlattribute xmlattributecollection xmlcdata xmlcomment xmldeclaration xmldocument xmldocumenttype xmlelement xmlnamespacemanager xmlnametable xmlnode xmlnodelist xmlport xmlprocessinginstruction xmlreadoptions xmltext xmlwriteoptions",literal:"false true"},illegal:/\/\*/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef region endregion pragma"}},{variants:[{className:"string",begin:"'",end:"'",illegal:"\\n"}]},{begin:'"',end:'"',illegal:"\\n",relevance:0},a,{className:"number",begin:"\\b\\d+(\\.\\d+)?(DT|D|T)",relevance:0},s,l,c]}}}()); \ No newline at end of file +/*! `al` grammar compiled for Highlight.js 11.11.2 */ +(()=>{var e=(()=>{"use strict";return e=>{ +var t=["codeunit|10","enum","enumextension|10","page","pageextension|10","permissionset","permissionsetextension|10","profile","query","report","reportextension","table","tableextension|10","xmlport|10"],n=["pagecustomization|10","dotnet","controladdin|10","interface","entitlement","assembly"],a=t.concat(n),i={ +className:"number",variants:[e.NUMBER_MODE,{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)L"}],relevance:0 +},r="("+e.IDENT_RE+'|"([^"]|"")*")',o=[e.COMMENT("///","$",{returnBegin:!0, +contains:[{className:"doctag",variants:[{begin:"///",relevance:0}]}] +}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],s={className:"class", +begin:"("+t.join("|")+")\\s+(\\d+)\\s+"+r,returnBegin:!0,end:"{",contains:[{ +beginKeywords:t.join(" ")+" extends implements" +},e.NUMBER_MODE,e.TITLE_MODE,e.C_BLOCK_COMMENT_MODE]},l={className:"class", +begin:"[^:]\\s*("+n.join("|")+")\\s+"+r,returnBegin:!0,end:"{",contains:[{ +beginKeywords:n.join(" ")+" extends implements" +},e.NUMBER_MODE,e.TITLE_MODE,e.C_BLOCK_COMMENT_MODE]},d={className:"function", +beginKeywords:"procedure trigger",returnBegin:!0,end:/\(/,excludeEnd:!0, +contains:[{beginKeywords:"procedure trigger"},e.TITLE_MODE].concat(o)};return{ +name:"AL",aliases:["al"],case_insensitive:!0,disableAutodetect:!0,keywords:{ +keyword:["array","asserterror|10","begin","break","case","do","downto","else","end","event","exit","for","foreach","if","in","indataset|10","interface","internal","local|10","namespace","of","procedure|10","protected","repeat","runonclient","securityfiltering|10","suppressdispose|10","temporary","then","to","trigger|10","until","using","var","while","with","withevents|10"].concat(a).concat(["and","div","mod","not","or","xor"]).concat(["action","actions|10","add","addafter","addbefore","addfirst","addlast","area|10","assembly","chartpart","column","cuegroup","customizes","dataitem","dataset","elements|10","extends","field","fieldattribute","fieldelement","fieldgroup|10","fieldgroups|10","fields|10","filter","fixed","grid","group","implements","key","keys","label","labels","layout|10","modify","moveafter","movebefore","movefirst","movelast","part","repeater","requestpage|10","schema","separator","systempart","tableelement","textattribute","textelement","type","value"]).join(" "), +built_in:"action analysisview analysisviews array automation biginteger bigtext blob boolean byte char clienttype code codeunit connectiontype database dataclassification datascope date dateformula datetime decimal defaultlayout dialog dictionary dotnet dotnetassembly dotnettypedeclaration duration enum errorinfo errortype executioncontext executionmode fieldclass fieldref fieldtype file filterpagebuilder guid httpclient httpcontent httpheaders httprequestmessage httpresponsemessage instream integer joker jsonarray jsonobject jsontoken jsonvalue keyref list moduledependencyinfo moduleinfo none notification notificationscope objecttype option outstream page pageresult query record recordid recordref report reportformat securityfilter securityfiltering sessionsettings table tableconnectiontype tablefilter testaction testfield testfilterfield testpage testpermissions testrequestpage text textbuilder textconst textencoding time transactionmodel transactiontype variant verbosity version view views webserviceactioncontext webserviceactionresultcode xmlattribute xmlattributecollection xmlcdata xmlcomment xmldeclaration xmldocument xmldocumenttype xmlelement xmlnamespacemanager xmlnametable xmlnode xmlnodelist xmlport xmlprocessinginstruction xmlreadoptions xmltext xmlwriteoptions", +literal:"false true"},illegal:/\/\*/,contains:[e.COMMENT("///","$",{ +returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0 +}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", +end:"$",keywords:{ +keyword:"if else elif endif define undef region endregion pragma"}},{variants:[{ +className:"string",begin:"'",end:"'",illegal:"\\n"}]},{begin:'"',end:'"', +illegal:"\\n",relevance:0},i,{className:"number", +begin:"\\b\\d+(\\.\\d+)?(DT|D|T)",relevance:0},s,l,d]}}})() +;hljs.registerLanguage("al",e)})(); \ No newline at end of file diff --git a/highlightjs_al/src/al.js b/highlightjs_al/src/al.js index ab30dcb..57d2cc3 100644 --- a/highlightjs_al/src/al.js +++ b/highlightjs_al/src/al.js @@ -361,6 +361,12 @@ export default function(hljs) { name: 'AL', aliases: ['al'], case_insensitive: true, + // AL wins Highlight.js's own C/AL detection fixture, which is not + // surprising given C/AL is AL's predecessor and the two look almost + // identical to a heuristic. Auto-detection is therefore disabled, as + // Highlight.js recommends when a grammar cannot pass the detect suite. + // Explicit registration and language-al are unaffected. + disableAutodetect: true, keywords: KEYWORDS, illegal: /\/\*/, contains: [ @@ -387,7 +393,7 @@ export default function(hljs) { className: 'meta', begin: '#', end: '$', keywords: { - 'meta-keyword': 'if else elif endif define undef region endregion pragma' + keyword: 'if else elif endif define undef region endregion pragma' } }, STRING,