Mercurial
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 156:cd35e600ae34 | 157:2db6253f355d |
|---|---|
| 1 /*! `c` grammar compiled for Highlight.js 11.11.1 */ | |
| 2 (function(){ | |
| 3 var hljsGrammar = (function () { | |
| 4 'use strict'; | |
| 5 | |
| 6 /* | |
| 7 Language: C | |
| 8 Category: common, system | |
| 9 Website: https://en.wikipedia.org/wiki/C_(programming_language) | |
| 10 */ | |
| 11 | |
| 12 /** @type LanguageFn */ | |
| 13 function c(hljs) { | |
| 14 const regex = hljs.regex; | |
| 15 // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does | |
| 16 // not include such support nor can we be sure all the grammars depending | |
| 17 // on it would desire this behavior | |
| 18 const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] }); | |
| 19 const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)'; | |
| 20 const NAMESPACE_RE = '[a-zA-Z_]\\w*::'; | |
| 21 const TEMPLATE_ARGUMENT_RE = '<[^<>]+>'; | |
| 22 const FUNCTION_TYPE_RE = '(' | |
| 23 + DECLTYPE_AUTO_RE + '|' | |
| 24 + regex.optional(NAMESPACE_RE) | |
| 25 + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE) | |
| 26 + ')'; | |
| 27 | |
| 28 | |
| 29 const TYPES = { | |
| 30 className: 'type', | |
| 31 variants: [ | |
| 32 { begin: '\\b[a-z\\d_]*_t\\b' }, | |
| 33 { match: /\batomic_[a-z]{3,6}\b/ } | |
| 34 ] | |
| 35 | |
| 36 }; | |
| 37 | |
| 38 // https://en.cppreference.com/w/cpp/language/escape | |
| 39 // \\ \x \xFF \u2837 \u00323747 \374 | |
| 40 const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)'; | |
| 41 const STRINGS = { | |
| 42 className: 'string', | |
| 43 variants: [ | |
| 44 { | |
| 45 begin: '(u8?|U|L)?"', | |
| 46 end: '"', | |
| 47 illegal: '\\n', | |
| 48 contains: [ hljs.BACKSLASH_ESCAPE ] | |
| 49 }, | |
| 50 { | |
| 51 begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)", | |
| 52 end: '\'', | |
| 53 illegal: '.' | |
| 54 }, | |
| 55 hljs.END_SAME_AS_BEGIN({ | |
| 56 begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/, | |
| 57 end: /\)([^()\\ ]{0,16})"/ | |
| 58 }) | |
| 59 ] | |
| 60 }; | |
| 61 | |
| 62 const NUMBERS = { | |
| 63 className: 'number', | |
| 64 variants: [ | |
| 65 { match: /\b(0b[01']+)/ }, | |
| 66 { match: /(-?)\b([\d']+(\.[\d']*)?|\.[\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)/ }, | |
| 67 { 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)?)/ }, | |
| 68 { match: /(-?)\b\d+(?:'\d+)*(?:\.\d*(?:'\d*)*)?(?:[eE][-+]?\d+)?/ } | |
| 69 ], | |
| 70 relevance: 0 | |
| 71 }; | |
| 72 | |
| 73 const PREPROCESSOR = { | |
| 74 className: 'meta', | |
| 75 begin: /#\s*[a-z]+\b/, | |
| 76 end: /$/, | |
| 77 keywords: { keyword: | |
| 78 'if else elif endif define undef warning error line ' | |
| 79 + 'pragma _Pragma ifdef ifndef elifdef elifndef include' }, | |
| 80 contains: [ | |
| 81 { | |
| 82 begin: /\\\n/, | |
| 83 relevance: 0 | |
| 84 }, | |
| 85 hljs.inherit(STRINGS, { className: 'string' }), | |
| 86 { | |
| 87 className: 'string', | |
| 88 begin: /<.*?>/ | |
| 89 }, | |
| 90 C_LINE_COMMENT_MODE, | |
| 91 hljs.C_BLOCK_COMMENT_MODE | |
| 92 ] | |
| 93 }; | |
| 94 | |
| 95 const TITLE_MODE = { | |
| 96 className: 'title', | |
| 97 begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE, | |
| 98 relevance: 0 | |
| 99 }; | |
| 100 | |
| 101 const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\('; | |
| 102 | |
| 103 const C_KEYWORDS = [ | |
| 104 "asm", | |
| 105 "auto", | |
| 106 "break", | |
| 107 "case", | |
| 108 "continue", | |
| 109 "default", | |
| 110 "do", | |
| 111 "else", | |
| 112 "enum", | |
| 113 "extern", | |
| 114 "for", | |
| 115 "fortran", | |
| 116 "goto", | |
| 117 "if", | |
| 118 "inline", | |
| 119 "register", | |
| 120 "restrict", | |
| 121 "return", | |
| 122 "sizeof", | |
| 123 "typeof", | |
| 124 "typeof_unqual", | |
| 125 "struct", | |
| 126 "switch", | |
| 127 "typedef", | |
| 128 "union", | |
| 129 "volatile", | |
| 130 "while", | |
| 131 "_Alignas", | |
| 132 "_Alignof", | |
| 133 "_Atomic", | |
| 134 "_Generic", | |
| 135 "_Noreturn", | |
| 136 "_Static_assert", | |
| 137 "_Thread_local", | |
| 138 // aliases | |
| 139 "alignas", | |
| 140 "alignof", | |
| 141 "noreturn", | |
| 142 "static_assert", | |
| 143 "thread_local", | |
| 144 // not a C keyword but is, for all intents and purposes, treated exactly like one. | |
| 145 "_Pragma" | |
| 146 ]; | |
| 147 | |
| 148 const C_TYPES = [ | |
| 149 "float", | |
| 150 "double", | |
| 151 "signed", | |
| 152 "unsigned", | |
| 153 "int", | |
| 154 "short", | |
| 155 "long", | |
| 156 "char", | |
| 157 "void", | |
| 158 "_Bool", | |
| 159 "_BitInt", | |
| 160 "_Complex", | |
| 161 "_Imaginary", | |
| 162 "_Decimal32", | |
| 163 "_Decimal64", | |
| 164 "_Decimal96", | |
| 165 "_Decimal128", | |
| 166 "_Decimal64x", | |
| 167 "_Decimal128x", | |
| 168 "_Float16", | |
| 169 "_Float32", | |
| 170 "_Float64", | |
| 171 "_Float128", | |
| 172 "_Float32x", | |
| 173 "_Float64x", | |
| 174 "_Float128x", | |
| 175 // modifiers | |
| 176 "const", | |
| 177 "static", | |
| 178 "constexpr", | |
| 179 // aliases | |
| 180 "complex", | |
| 181 "bool", | |
| 182 "imaginary" | |
| 183 ]; | |
| 184 | |
| 185 const KEYWORDS = { | |
| 186 keyword: C_KEYWORDS, | |
| 187 type: C_TYPES, | |
| 188 literal: 'true false NULL', | |
| 189 // TODO: apply hinting work similar to what was done in cpp.js | |
| 190 built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream ' | |
| 191 + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set ' | |
| 192 + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos ' | |
| 193 + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' | |
| 194 + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' | |
| 195 + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' | |
| 196 + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' | |
| 197 + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' | |
| 198 + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr', | |
| 199 }; | |
| 200 | |
| 201 const EXPRESSION_CONTAINS = [ | |
| 202 PREPROCESSOR, | |
| 203 TYPES, | |
| 204 C_LINE_COMMENT_MODE, | |
| 205 hljs.C_BLOCK_COMMENT_MODE, | |
| 206 NUMBERS, | |
| 207 STRINGS | |
| 208 ]; | |
| 209 | |
| 210 const EXPRESSION_CONTEXT = { | |
| 211 // This mode covers expression context where we can't expect a function | |
| 212 // definition and shouldn't highlight anything that looks like one: | |
| 213 // `return some()`, `else if()`, `(x*sum(1, 2))` | |
| 214 variants: [ | |
| 215 { | |
| 216 begin: /=/, | |
| 217 end: /;/ | |
| 218 }, | |
| 219 { | |
| 220 begin: /\(/, | |
| 221 end: /\)/ | |
| 222 }, | |
| 223 { | |
| 224 beginKeywords: 'new throw return else', | |
| 225 end: /;/ | |
| 226 } | |
| 227 ], | |
| 228 keywords: KEYWORDS, | |
| 229 contains: EXPRESSION_CONTAINS.concat([ | |
| 230 { | |
| 231 begin: /\(/, | |
| 232 end: /\)/, | |
| 233 keywords: KEYWORDS, | |
| 234 contains: EXPRESSION_CONTAINS.concat([ 'self' ]), | |
| 235 relevance: 0 | |
| 236 } | |
| 237 ]), | |
| 238 relevance: 0 | |
| 239 }; | |
| 240 | |
| 241 const FUNCTION_DECLARATION = { | |
| 242 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, | |
| 243 returnBegin: true, | |
| 244 end: /[{;=]/, | |
| 245 excludeEnd: true, | |
| 246 keywords: KEYWORDS, | |
| 247 illegal: /[^\w\s\*&:<>.]/, | |
| 248 contains: [ | |
| 249 { // to prevent it from being confused as the function title | |
| 250 begin: DECLTYPE_AUTO_RE, | |
| 251 keywords: KEYWORDS, | |
| 252 relevance: 0 | |
| 253 }, | |
| 254 { | |
| 255 begin: FUNCTION_TITLE, | |
| 256 returnBegin: true, | |
| 257 contains: [ hljs.inherit(TITLE_MODE, { className: "title.function" }) ], | |
| 258 relevance: 0 | |
| 259 }, | |
| 260 // allow for multiple declarations, e.g.: | |
| 261 // extern void f(int), g(char); | |
| 262 { | |
| 263 relevance: 0, | |
| 264 match: /,/ | |
| 265 }, | |
| 266 { | |
| 267 className: 'params', | |
| 268 begin: /\(/, | |
| 269 end: /\)/, | |
| 270 keywords: KEYWORDS, | |
| 271 relevance: 0, | |
| 272 contains: [ | |
| 273 C_LINE_COMMENT_MODE, | |
| 274 hljs.C_BLOCK_COMMENT_MODE, | |
| 275 STRINGS, | |
| 276 NUMBERS, | |
| 277 TYPES, | |
| 278 // Count matching parentheses. | |
| 279 { | |
| 280 begin: /\(/, | |
| 281 end: /\)/, | |
| 282 keywords: KEYWORDS, | |
| 283 relevance: 0, | |
| 284 contains: [ | |
| 285 'self', | |
| 286 C_LINE_COMMENT_MODE, | |
| 287 hljs.C_BLOCK_COMMENT_MODE, | |
| 288 STRINGS, | |
| 289 NUMBERS, | |
| 290 TYPES | |
| 291 ] | |
| 292 } | |
| 293 ] | |
| 294 }, | |
| 295 TYPES, | |
| 296 C_LINE_COMMENT_MODE, | |
| 297 hljs.C_BLOCK_COMMENT_MODE, | |
| 298 PREPROCESSOR | |
| 299 ] | |
| 300 }; | |
| 301 | |
| 302 return { | |
| 303 name: "C", | |
| 304 aliases: [ 'h' ], | |
| 305 keywords: KEYWORDS, | |
| 306 // Until differentiations are added between `c` and `cpp`, `c` will | |
| 307 // not be auto-detected to avoid auto-detect conflicts between C and C++ | |
| 308 disableAutodetect: true, | |
| 309 illegal: '</', | |
| 310 contains: [].concat( | |
| 311 EXPRESSION_CONTEXT, | |
| 312 FUNCTION_DECLARATION, | |
| 313 EXPRESSION_CONTAINS, | |
| 314 [ | |
| 315 PREPROCESSOR, | |
| 316 { | |
| 317 begin: hljs.IDENT_RE + '::', | |
| 318 keywords: KEYWORDS | |
| 319 }, | |
| 320 { | |
| 321 className: 'class', | |
| 322 beginKeywords: 'enum class struct union', | |
| 323 end: /[{;:<>=]/, | |
| 324 contains: [ | |
| 325 { beginKeywords: "final class struct" }, | |
| 326 hljs.TITLE_MODE | |
| 327 ] | |
| 328 } | |
| 329 ]), | |
| 330 exports: { | |
| 331 preprocessor: PREPROCESSOR, | |
| 332 strings: STRINGS, | |
| 333 keywords: KEYWORDS | |
| 334 } | |
| 335 }; | |
| 336 } | |
| 337 | |
| 338 return c; | |
| 339 | |
| 340 })(); | |
| 341 | |
| 342 hljs.registerLanguage('c', hljsGrammar); | |
| 343 })(); |