Mercurial
diff third_party/highlight/languages/c.js @ 157:2db6253f355d
[ThirdParty] Added highlight library for better readability on blog.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Tue, 13 Jan 2026 19:18:47 -0800 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/third_party/highlight/languages/c.js Tue Jan 13 19:18:47 2026 -0800 @@ -0,0 +1,343 @@ +/*! `c` grammar compiled for Highlight.js 11.11.1 */ + (function(){ + var hljsGrammar = (function () { + 'use strict'; + + /* + Language: C + Category: common, system + Website: https://en.wikipedia.org/wiki/C_(programming_language) + */ + + /** @type LanguageFn */ + function c(hljs) { + const regex = hljs.regex; + // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does + // not include such support nor can we be sure all the grammars depending + // on it would desire this behavior + const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] }); + const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)'; + const NAMESPACE_RE = '[a-zA-Z_]\\w*::'; + const TEMPLATE_ARGUMENT_RE = '<[^<>]+>'; + const FUNCTION_TYPE_RE = '(' + + DECLTYPE_AUTO_RE + '|' + + regex.optional(NAMESPACE_RE) + + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE) + + ')'; + + + const TYPES = { + className: 'type', + variants: [ + { begin: '\\b[a-z\\d_]*_t\\b' }, + { match: /\batomic_[a-z]{3,6}\b/ } + ] + + }; + + // https://en.cppreference.com/w/cpp/language/escape + // \\ \x \xFF \u2837 \u00323747 \374 + const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)'; + const STRINGS = { + className: 'string', + variants: [ + { + begin: '(u8?|U|L)?"', + end: '"', + illegal: '\\n', + contains: [ hljs.BACKSLASH_ESCAPE ] + }, + { + begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)", + end: '\'', + illegal: '.' + }, + hljs.END_SAME_AS_BEGIN({ + begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/, + end: /\)([^()\\ ]{0,16})"/ + }) + ] + }; + + const NUMBERS = { + className: 'number', + variants: [ + { match: /\b(0b[01']+)/ }, + { match: /(-?)\b([\d']+(\.[\d']*)?|\.[\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)/ }, + { match: /(-?)\b(0[xX][a-fA-F0-9]+(?:'[a-fA-F0-9]+)*(?:\.[a-fA-F0-9]*(?:'[a-fA-F0-9]*)*)?(?:[pP][-+]?[0-9]+)?(l|L)?(u|U)?)/ }, + { match: /(-?)\b\d+(?:'\d+)*(?:\.\d*(?:'\d*)*)?(?:[eE][-+]?\d+)?/ } + ], + relevance: 0 + }; + + const PREPROCESSOR = { + className: 'meta', + begin: /#\s*[a-z]+\b/, + end: /$/, + keywords: { keyword: + 'if else elif endif define undef warning error line ' + + 'pragma _Pragma ifdef ifndef elifdef elifndef include' }, + contains: [ + { + begin: /\\\n/, + relevance: 0 + }, + hljs.inherit(STRINGS, { className: 'string' }), + { + className: 'string', + begin: /<.*?>/ + }, + C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE + ] + }; + + const TITLE_MODE = { + className: 'title', + begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE, + relevance: 0 + }; + + const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\('; + + const C_KEYWORDS = [ + "asm", + "auto", + "break", + "case", + "continue", + "default", + "do", + "else", + "enum", + "extern", + "for", + "fortran", + "goto", + "if", + "inline", + "register", + "restrict", + "return", + "sizeof", + "typeof", + "typeof_unqual", + "struct", + "switch", + "typedef", + "union", + "volatile", + "while", + "_Alignas", + "_Alignof", + "_Atomic", + "_Generic", + "_Noreturn", + "_Static_assert", + "_Thread_local", + // aliases + "alignas", + "alignof", + "noreturn", + "static_assert", + "thread_local", + // not a C keyword but is, for all intents and purposes, treated exactly like one. + "_Pragma" + ]; + + const C_TYPES = [ + "float", + "double", + "signed", + "unsigned", + "int", + "short", + "long", + "char", + "void", + "_Bool", + "_BitInt", + "_Complex", + "_Imaginary", + "_Decimal32", + "_Decimal64", + "_Decimal96", + "_Decimal128", + "_Decimal64x", + "_Decimal128x", + "_Float16", + "_Float32", + "_Float64", + "_Float128", + "_Float32x", + "_Float64x", + "_Float128x", + // modifiers + "const", + "static", + "constexpr", + // aliases + "complex", + "bool", + "imaginary" + ]; + + const KEYWORDS = { + keyword: C_KEYWORDS, + type: C_TYPES, + literal: 'true false NULL', + // TODO: apply hinting work similar to what was done in cpp.js + built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream ' + + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set ' + + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos ' + + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' + + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' + + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' + + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' + + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' + + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr', + }; + + const EXPRESSION_CONTAINS = [ + PREPROCESSOR, + TYPES, + C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + NUMBERS, + STRINGS + ]; + + const EXPRESSION_CONTEXT = { + // This mode covers expression context where we can't expect a function + // definition and shouldn't highlight anything that looks like one: + // `return some()`, `else if()`, `(x*sum(1, 2))` + variants: [ + { + begin: /=/, + end: /;/ + }, + { + begin: /\(/, + end: /\)/ + }, + { + beginKeywords: 'new throw return else', + end: /;/ + } + ], + keywords: KEYWORDS, + contains: EXPRESSION_CONTAINS.concat([ + { + begin: /\(/, + end: /\)/, + keywords: KEYWORDS, + contains: EXPRESSION_CONTAINS.concat([ 'self' ]), + relevance: 0 + } + ]), + relevance: 0 + }; + + const FUNCTION_DECLARATION = { + begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, + returnBegin: true, + end: /[{;=]/, + excludeEnd: true, + keywords: KEYWORDS, + illegal: /[^\w\s\*&:<>.]/, + contains: [ + { // to prevent it from being confused as the function title + begin: DECLTYPE_AUTO_RE, + keywords: KEYWORDS, + relevance: 0 + }, + { + begin: FUNCTION_TITLE, + returnBegin: true, + contains: [ hljs.inherit(TITLE_MODE, { className: "title.function" }) ], + relevance: 0 + }, + // allow for multiple declarations, e.g.: + // extern void f(int), g(char); + { + relevance: 0, + match: /,/ + }, + { + className: 'params', + begin: /\(/, + end: /\)/, + keywords: KEYWORDS, + relevance: 0, + contains: [ + C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + STRINGS, + NUMBERS, + TYPES, + // Count matching parentheses. + { + begin: /\(/, + end: /\)/, + keywords: KEYWORDS, + relevance: 0, + contains: [ + 'self', + C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + STRINGS, + NUMBERS, + TYPES + ] + } + ] + }, + TYPES, + C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + PREPROCESSOR + ] + }; + + return { + name: "C", + aliases: [ 'h' ], + keywords: KEYWORDS, + // Until differentiations are added between `c` and `cpp`, `c` will + // not be auto-detected to avoid auto-detect conflicts between C and C++ + disableAutodetect: true, + illegal: '</', + contains: [].concat( + EXPRESSION_CONTEXT, + FUNCTION_DECLARATION, + EXPRESSION_CONTAINS, + [ + PREPROCESSOR, + { + begin: hljs.IDENT_RE + '::', + keywords: KEYWORDS + }, + { + className: 'class', + beginKeywords: 'enum class struct union', + end: /[{;:<>=]/, + contains: [ + { beginKeywords: "final class struct" }, + hljs.TITLE_MODE + ] + } + ]), + exports: { + preprocessor: PREPROCESSOR, + strings: STRINGS, + keywords: KEYWORDS + } + }; + } + + return c; + +})(); + + hljs.registerLanguage('c', hljsGrammar); + })(); \ No newline at end of file