Personal website
at master 99 lines 4.0 kB view raw
1(function (Prism) { 2 3 var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/; 4 var modName = /\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g, function () { return keyword.source; }); 5 6 Prism.languages.cpp = Prism.languages.extend('c', { 7 'class-name': [ 8 { 9 pattern: RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source 10 .replace(/<keyword>/g, function () { return keyword.source; })), 11 lookbehind: true 12 }, 13 // This is intended to capture the class name of method implementations like: 14 // void foo::bar() const {} 15 // However! The `foo` in the above example could also be a namespace, so we only capture the class name if 16 // it starts with an uppercase letter. This approximation should give decent results. 17 /\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/, 18 // This will capture the class name before destructors like: 19 // Foo::~Foo() {} 20 /\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i, 21 // This also intends to capture the class name of method implementations but here the class has template 22 // parameters, so it can't be a namespace (until C++ adds generic namespaces). 23 /\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/ 24 ], 25 'keyword': keyword, 26 'number': { 27 pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i, 28 greedy: true 29 }, 30 'operator': />>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, 31 'boolean': /\b(?:false|true)\b/ 32 }); 33 34 Prism.languages.insertBefore('cpp', 'string', { 35 'module': { 36 // https://en.cppreference.com/w/cpp/language/modules 37 pattern: RegExp( 38 /(\b(?:import|module)\s+)/.source + 39 '(?:' + 40 // header-name 41 /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source + 42 '|' + 43 // module name or partition or both 44 /<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g, function () { return modName; }) + 45 ')' 46 ), 47 lookbehind: true, 48 greedy: true, 49 inside: { 50 'string': /^[<"][\s\S]+/, 51 'operator': /:/, 52 'punctuation': /\./ 53 } 54 }, 55 'raw-string': { 56 pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, 57 alias: 'string', 58 greedy: true 59 } 60 }); 61 62 Prism.languages.insertBefore('cpp', 'keyword', { 63 'generic-function': { 64 pattern: /\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i, 65 inside: { 66 'function': /^\w+/, 67 'generic': { 68 pattern: /<[\s\S]+/, 69 alias: 'class-name', 70 inside: Prism.languages.cpp 71 } 72 } 73 } 74 }); 75 76 Prism.languages.insertBefore('cpp', 'operator', { 77 'double-colon': { 78 pattern: /::/, 79 alias: 'punctuation' 80 } 81 }); 82 83 Prism.languages.insertBefore('cpp', 'class-name', { 84 // the base clause is an optional list of parent classes 85 // https://en.cppreference.com/w/cpp/language/class 86 'base-clause': { 87 pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/, 88 lookbehind: true, 89 greedy: true, 90 inside: Prism.languages.extend('cpp', {}) 91 } 92 }); 93 94 Prism.languages.insertBefore('inside', 'double-colon', { 95 // All untokenized words that are not namespaces should be class names 96 'class-name': /\b[a-z_]\w*\b(?!\s*::)/i 97 }, Prism.languages.cpp['base-clause']); 98 99}(Prism));