From 9c7bc820787ff30cd33b25d00f438ea60873c478 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Tue, 19 May 2020 02:30:59 +0200 Subject: [PATCH] Markup: Added tokens inside DOCTYPE (#2349) --- components/prism-markup.js | 21 ++++- components/prism-markup.min.js | 2 +- prism.js | 21 ++++- tests/languages/markup/doctype_feature.test | 97 +++++++++++++++++++-- 4 files changed, 130 insertions(+), 11 deletions(-) diff --git a/components/prism-markup.js b/components/prism-markup.js index af51c86a49..63dbf16c46 100644 --- a/components/prism-markup.js +++ b/components/prism-markup.js @@ -2,8 +2,24 @@ Prism.languages.markup = { 'comment': //, 'prolog': /<\?[\s\S]+?\?>/, 'doctype': { + // https://www.w3.org/TR/xml/#NT-doctypedecl pattern: /"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i, - greedy: true + greedy: true, + inside: { + 'internal-subset': { + pattern: /(\[)[\s\S]+(?=\]>$)/, + lookbehind: true, + greedy: true, + inside: null // see below + }, + 'string': { + pattern: /"[^"]*"|'[^']*'/, + greedy: true + }, + 'punctuation': /^$|[[\]]/, + 'doctype-tag': /^DOCTYPE/, + 'name': /[^\s<>'"]+/ + } }, 'cdata': //i, 'tag': { @@ -50,9 +66,10 @@ Prism.languages.markup = { Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = Prism.languages.markup['entity']; +Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup; // Plugin to make entity title show the real entity, idea by Roman Komarov -Prism.hooks.add('wrap', function(env) { +Prism.hooks.add('wrap', function (env) { if (env.type === 'entity') { env.attributes['title'] = env.content.replace(/&/, '&'); diff --git a/components/prism-markup.min.js b/components/prism-markup.min.js index 16a1fd1363..1882d5795e 100644 --- a/components/prism-markup.min.js +++ b/components/prism-markup.min.js @@ -1 +1 @@ -Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^]*?>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; \ No newline at end of file +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^]*?>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; \ No newline at end of file diff --git a/prism.js b/prism.js index 8a136e94b7..f257ebf27c 100644 --- a/prism.js +++ b/prism.js @@ -738,8 +738,24 @@ Prism.languages.markup = { 'comment': //, 'prolog': /<\?[\s\S]+?\?>/, 'doctype': { + // https://www.w3.org/TR/xml/#NT-doctypedecl pattern: /"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i, - greedy: true + greedy: true, + inside: { + 'internal-subset': { + pattern: /(\[)[\s\S]+(?=\]>$)/, + lookbehind: true, + greedy: true, + inside: null // see below + }, + 'string': { + pattern: /"[^"]*"|'[^']*'/, + greedy: true + }, + 'punctuation': /^$|[[\]]/, + 'doctype-tag': /^DOCTYPE/, + 'name': /[^\s<>'"]+/ + } }, 'cdata': //i, 'tag': { @@ -786,9 +802,10 @@ Prism.languages.markup = { Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = Prism.languages.markup['entity']; +Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup; // Plugin to make entity title show the real entity, idea by Roman Komarov -Prism.hooks.add('wrap', function(env) { +Prism.hooks.add('wrap', function (env) { if (env.type === 'entity') { env.attributes['title'] = env.content.replace(/&/, '&'); diff --git a/tests/languages/markup/doctype_feature.test b/tests/languages/markup/doctype_feature.test index 8c3d955f37..4ba9ee2175 100644 --- a/tests/languages/markup/doctype_feature.test +++ b/tests/languages/markup/doctype_feature.test @@ -15,12 +15,97 @@ ---------------------------------------------------- [ - ["doctype", ""], - ["doctype", ""], - ["doctype", ""], - ["doctype", ""], - ["doctype", "\r\n]>"], - ["doctype", "\r\n\t\r\n\t\r\n]>"] + ["doctype", [ + ["punctuation", ""] + ]], + ["doctype", [ + ["punctuation", ""] + ]], + ["doctype", [ + ["punctuation", ""] + ]], + ["doctype", [ + ["punctuation", ""] + ]], + ["doctype", [ + ["punctuation", ""] + ]] + ]], + ["punctuation", "]"], + ["punctuation", ">"] + ]], + ["doctype", [ + ["punctuation", ""] + ]], + ["tag", [ + ["tag", [ + ["punctuation", "<"], + "!ELEMENT" + ]], + ["attr-name", [ + "subject" + ]], + ["attr-name", [ + "(#PCDATA)" + ]], + ["punctuation", ">"] + ]], + ["comment", ""] + ]], + ["punctuation", "]"], + ["punctuation", ">"] + ]] ] ----------------------------------------------------