From 59853a52773ecbb686160d68481438264f90abaf Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Thu, 1 Oct 2020 12:33:11 +0200 Subject: [PATCH] YAML: Improved key pattern (#2561) --- components/prism-yaml.js | 15 +++++++++++---- components/prism-yaml.min.js | 2 +- tests/languages/yaml/key_feature.test | 10 ++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/components/prism-yaml.js b/components/prism-yaml.js index 3838926692..0ead359113 100644 --- a/components/prism-yaml.js +++ b/components/prism-yaml.js @@ -8,6 +8,12 @@ // https://yaml.org/spec/1.2/spec.html#c-ns-properties(n,c) var properties = '(?:' + tag.source + '(?:[ \t]+' + anchorOrAlias.source + ')?|' + anchorOrAlias.source + '(?:[ \t]+' + tag.source + ')?)'; + // https://yaml.org/spec/1.2/spec.html#ns-plain(n,c) + // This is a simplified version that doesn't support "#" and multiline keys + // All these long scarry character classes are simplified versions of YAML's characters + var plainKey = /(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source + .replace(//g, function () { return /[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source; }); + var string = /"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source; /** * @@ -31,9 +37,11 @@ }, 'comment': /#.*/, 'key': { - pattern: RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)[^\r\n{[\]},#\s]+?(?=\s*:\s)/.source - .replace(/<>/g, function () { return properties; })), + pattern: RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source + .replace(/<>/g, function () { return properties; }) + .replace(/<>/g, function () { return '(?:' + plainKey + '|' + string + ')'; })), lookbehind: true, + greedy: true, alias: 'atrule' }, 'directive': { @@ -57,8 +65,7 @@ alias: 'important' }, 'string': { - // \2 because of the lookbehind group - pattern: createValuePattern(/("|')(?:(?!\2)[^\\\r\n]|\\.)*\2/.source), + pattern: createValuePattern(string), lookbehind: true, greedy: true }, diff --git a/components/prism-yaml.min.js b/components/prism-yaml.min.js index f4be9e0b27..e46001ebd9 100644 --- a/components/prism-yaml.min.js +++ b/components/prism-yaml.min.js @@ -1 +1 @@ -!function(n){var t=/[*&][^\s[\]{},]+/,e=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+e.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+e.source+")?)";function a(n,t){t=(t||"").replace(/m/g,"")+"m";var e="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|]|}|\\s*#))".replace(/<>/g,function(){return r}).replace(/<>/g,function(){return n});return RegExp(e,t)}n.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\\2[^\r\n]+)*)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)[^\r\n{[\\]},#\\s]+?(?=\\s*:\\s)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:a("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:a("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:a("(\"|')(?:(?!\\2)[^\\\\\r\n]|\\\\.)*\\2"),lookbehind:!0,greedy:!0},number:{pattern:a("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:e,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},n.languages.yml=n.languages.yaml}(Prism); \ No newline at end of file +!function(e){var n=/[*&][^\s[\]{},]+/,t=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+t.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+t.source+")?)",a="(?:[^\\s\\x00-\\x08\\x0e-\\x1f!\"#%&'*,\\-:>?@[\\]`{|}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*".replace(//g,function(){return"[^\\s\\x00-\\x08\\x0e-\\x1f,[\\]{}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]"}),d="\"(?:[^\"\\\\\r\n]|\\\\.)*\"|'(?:[^'\\\\\r\n]|\\\\.)*'";function o(e,n){n=(n||"").replace(/m/g,"")+"m";var t="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|]|}|\\s*#))".replace(/<>/g,function(){return r}).replace(/<>/g,function(){return e});return RegExp(t,n)}e.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\\2[^\r\n]+)*)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\\s*:\\s)".replace(/<>/g,function(){return r}).replace(/<>/g,function(){return"(?:"+a+"|"+d+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:o("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:o("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:o("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:o(d),lookbehind:!0,greedy:!0},number:{pattern:o("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:t,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism); \ No newline at end of file diff --git a/tests/languages/yaml/key_feature.test b/tests/languages/yaml/key_feature.test index 98359b22e9..affda31feb 100644 --- a/tests/languages/yaml/key_feature.test +++ b/tests/languages/yaml/key_feature.test @@ -1,15 +1,21 @@ --- foo: 4 FooBar : 5 +hello the-world: 23 +"\"foo# : {}[]": 23 +'\'foo# : {}[]': 23 ---------------------------------------------------- [ ["punctuation", "---"], ["key", "foo"], ["punctuation", ":"], ["number", "4"], - ["key", "FooBar"], ["punctuation", ":"], ["number", "5"] + ["key", "FooBar"], ["punctuation", ":"], ["number", "5"], + ["key", "hello the-world"], ["punctuation", ":"], ["number", "23"], + ["key", "\"\\\"foo# : {}[]\""], ["punctuation", ":"], ["number", "23"], + ["key", "'\\'foo# : {}[]'"], ["punctuation", ":"], ["number", "23"] ] ---------------------------------------------------- -Checks for keys. \ No newline at end of file +Checks for keys.