l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

crystal.js (5958B)


      1 /*
      2 Language: Crystal
      3 Author: TSUYUSATO Kitsune <make.just.on@gmail.com>
      4 Website: https://crystal-lang.org
      5 */
      6 
      7 /** @type LanguageFn */
      8 function crystal(hljs) {
      9   var INT_SUFFIX = '(_*[ui](8|16|32|64|128))?';
     10   var FLOAT_SUFFIX = '(_*f(32|64))?';
     11   var CRYSTAL_IDENT_RE = '[a-zA-Z_]\\w*[!?=]?';
     12   var CRYSTAL_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|[=!]~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~|]|//|//=|&[-+*]=?|&\\*\\*|\\[\\][=?]?';
     13   var CRYSTAL_PATH_RE = '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?';
     14   var CRYSTAL_KEYWORDS = {
     15     $pattern: CRYSTAL_IDENT_RE,
     16     keyword:
     17       'abstract alias annotation as as? asm begin break case class def do else elsif end ensure enum extend for fun if ' +
     18       'include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? ' +
     19       'return require select self sizeof struct super then type typeof union uninitialized unless until verbatim when while with yield ' +
     20       '__DIR__ __END_LINE__ __FILE__ __LINE__',
     21     literal: 'false nil true'
     22   };
     23   var SUBST = {
     24     className: 'subst',
     25     begin: '#{', end: '}',
     26     keywords: CRYSTAL_KEYWORDS
     27   };
     28   var EXPANSION = {
     29     className: 'template-variable',
     30     variants: [
     31       {begin: '\\{\\{', end: '\\}\\}'},
     32       {begin: '\\{%', end: '%\\}'}
     33     ],
     34     keywords: CRYSTAL_KEYWORDS
     35   };
     36 
     37   function recursiveParen(begin, end) {
     38     var
     39     contains = [{begin: begin, end: end}];
     40     contains[0].contains = contains;
     41     return contains;
     42   }
     43   var STRING = {
     44     className: 'string',
     45     contains: [hljs.BACKSLASH_ESCAPE, SUBST],
     46     variants: [
     47       {begin: /'/, end: /'/},
     48       {begin: /"/, end: /"/},
     49       {begin: /`/, end: /`/},
     50       {begin: '%[Qwi]?\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
     51       {begin: '%[Qwi]?\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
     52       {begin: '%[Qwi]?{', end: '}', contains: recursiveParen('{', '}')},
     53       {begin: '%[Qwi]?<', end: '>', contains: recursiveParen('<', '>')},
     54       {begin: '%[Qwi]?\\|', end: '\\|'},
     55       {begin: /<<-\w+$/, end: /^\s*\w+$/},
     56     ],
     57     relevance: 0,
     58   };
     59   var Q_STRING = {
     60     className: 'string',
     61     variants: [
     62       {begin: '%q\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
     63       {begin: '%q\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
     64       {begin: '%q{', end: '}', contains: recursiveParen('{', '}')},
     65       {begin: '%q<', end: '>', contains: recursiveParen('<', '>')},
     66       {begin: '%q\\|', end: '\\|'},
     67       {begin: /<<-'\w+'$/, end: /^\s*\w+$/},
     68     ],
     69     relevance: 0,
     70   };
     71   var REGEXP = {
     72     begin: '(?!%})(' + hljs.RE_STARTERS_RE + '|\\n|\\b(case|if|select|unless|until|when|while)\\b)\\s*',
     73     keywords: 'case if select unless until when while',
     74     contains: [
     75       {
     76         className: 'regexp',
     77         contains: [hljs.BACKSLASH_ESCAPE, SUBST],
     78         variants: [
     79           {begin: '//[a-z]*', relevance: 0},
     80           {begin: '/(?!\\/)', end: '/[a-z]*'},
     81         ]
     82       }
     83     ],
     84     relevance: 0
     85   };
     86   var REGEXP2 = {
     87     className: 'regexp',
     88     contains: [hljs.BACKSLASH_ESCAPE, SUBST],
     89     variants: [
     90       {begin: '%r\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
     91       {begin: '%r\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
     92       {begin: '%r{', end: '}', contains: recursiveParen('{', '}')},
     93       {begin: '%r<', end: '>', contains: recursiveParen('<', '>')},
     94       {begin: '%r\\|', end: '\\|'},
     95     ],
     96     relevance: 0
     97   };
     98   var ATTRIBUTE = {
     99     className: 'meta',
    100     begin: '@\\[', end: '\\]',
    101     contains: [
    102       hljs.inherit(hljs.QUOTE_STRING_MODE, {className: 'meta-string'})
    103     ]
    104   };
    105   var CRYSTAL_DEFAULT_CONTAINS = [
    106     EXPANSION,
    107     STRING,
    108     Q_STRING,
    109     REGEXP2,
    110     REGEXP,
    111     ATTRIBUTE,
    112     hljs.HASH_COMMENT_MODE,
    113     {
    114       className: 'class',
    115       beginKeywords: 'class module struct', end: '$|;',
    116       illegal: /=/,
    117       contains: [
    118         hljs.HASH_COMMENT_MODE,
    119         hljs.inherit(hljs.TITLE_MODE, {begin: CRYSTAL_PATH_RE}),
    120         {begin: '<'} // relevance booster for inheritance
    121       ]
    122     },
    123     {
    124       className: 'class',
    125       beginKeywords: 'lib enum union', end: '$|;',
    126       illegal: /=/,
    127       contains: [
    128         hljs.HASH_COMMENT_MODE,
    129         hljs.inherit(hljs.TITLE_MODE, {begin: CRYSTAL_PATH_RE}),
    130       ],
    131       relevance: 10
    132     },
    133     {
    134       beginKeywords: 'annotation', end: '$|;',
    135       illegal: /=/,
    136       contains: [
    137         hljs.HASH_COMMENT_MODE,
    138         hljs.inherit(hljs.TITLE_MODE, {begin: CRYSTAL_PATH_RE}),
    139       ],
    140       relevance: 10
    141     },
    142     {
    143       className: 'function',
    144       beginKeywords: 'def', end: /\B\b/,
    145       contains: [
    146         hljs.inherit(hljs.TITLE_MODE, {
    147           begin: CRYSTAL_METHOD_RE,
    148           endsParent: true
    149         })
    150       ]
    151     },
    152     {
    153       className: 'function',
    154       beginKeywords: 'fun macro', end: /\B\b/,
    155       contains: [
    156         hljs.inherit(hljs.TITLE_MODE, {
    157           begin: CRYSTAL_METHOD_RE,
    158           endsParent: true
    159         })
    160       ],
    161       relevance: 5
    162     },
    163     {
    164       className: 'symbol',
    165       begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
    166       relevance: 0
    167     },
    168     {
    169       className: 'symbol',
    170       begin: ':',
    171       contains: [STRING, {begin: CRYSTAL_METHOD_RE}],
    172       relevance: 0
    173     },
    174     {
    175       className: 'number',
    176       variants: [
    177         { begin: '\\b0b([01_]+)' + INT_SUFFIX },
    178         { begin: '\\b0o([0-7_]+)' + INT_SUFFIX },
    179         { begin: '\\b0x([A-Fa-f0-9_]+)' + INT_SUFFIX },
    180         { begin: '\\b([1-9][0-9_]*[0-9]|[0-9])(\\.[0-9][0-9_]*)?([eE]_*[-+]?[0-9_]*)?' + FLOAT_SUFFIX + '(?!_)' },
    181         { begin: '\\b([1-9][0-9_]*|0)' + INT_SUFFIX }
    182       ],
    183       relevance: 0
    184     }
    185   ];
    186   SUBST.contains = CRYSTAL_DEFAULT_CONTAINS;
    187   EXPANSION.contains = CRYSTAL_DEFAULT_CONTAINS.slice(1); // without EXPANSION
    188 
    189   return {
    190     name: 'Crystal',
    191     aliases: ['cr'],
    192     keywords: CRYSTAL_KEYWORDS,
    193     contains: CRYSTAL_DEFAULT_CONTAINS
    194   };
    195 }
    196 
    197 module.exports = crystal;