/ src / theme / languages / latex.js
latex.js
  1  /*! `latex` grammar compiled for Highlight.js 11.10.0 */
  2    (function(){
  3      var hljsGrammar = (function () {
  4    'use strict';
  5  
  6    /*
  7    Language: LaTeX
  8    Author: Benedikt Wilde <bwilde@posteo.de>
  9    Website: https://www.latex-project.org
 10    Category: markup
 11    */
 12  
 13    /** @type LanguageFn */
 14    function latex(hljs) {
 15      const regex = hljs.regex;
 16      const KNOWN_CONTROL_WORDS = regex.either(...[
 17        '(?:NeedsTeXFormat|RequirePackage|GetIdInfo)',
 18        'Provides(?:Expl)?(?:Package|Class|File)',
 19        '(?:DeclareOption|ProcessOptions)',
 20        '(?:documentclass|usepackage|input|include)',
 21        'makeat(?:letter|other)',
 22        'ExplSyntax(?:On|Off)',
 23        '(?:new|renew|provide)?command',
 24        '(?:re)newenvironment',
 25        '(?:New|Renew|Provide|Declare)(?:Expandable)?DocumentCommand',
 26        '(?:New|Renew|Provide|Declare)DocumentEnvironment',
 27        '(?:(?:e|g|x)?def|let)',
 28        '(?:begin|end)',
 29        '(?:part|chapter|(?:sub){0,2}section|(?:sub)?paragraph)',
 30        'caption',
 31        '(?:label|(?:eq|page|name)?ref|(?:paren|foot|super)?cite)',
 32        '(?:alpha|beta|[Gg]amma|[Dd]elta|(?:var)?epsilon|zeta|eta|[Tt]heta|vartheta)',
 33        '(?:iota|(?:var)?kappa|[Ll]ambda|mu|nu|[Xx]i|[Pp]i|varpi|(?:var)rho)',
 34        '(?:[Ss]igma|varsigma|tau|[Uu]psilon|[Pp]hi|varphi|chi|[Pp]si|[Oo]mega)',
 35        '(?:frac|sum|prod|lim|infty|times|sqrt|leq|geq|left|right|middle|[bB]igg?)',
 36        '(?:[lr]angle|q?quad|[lcvdi]?dots|d?dot|hat|tilde|bar)'
 37      ].map(word => word + '(?![a-zA-Z@:_])'));
 38      const L3_REGEX = new RegExp([
 39        // A function \module_function_name:signature or \__module_function_name:signature,
 40        // where both module and function_name need at least two characters and
 41        // function_name may contain single underscores.
 42        '(?:__)?[a-zA-Z]{2,}_[a-zA-Z](?:_?[a-zA-Z])+:[a-zA-Z]*',
 43        // A variable \scope_module_and_name_type or \scope__module_ane_name_type,
 44        // where scope is one of l, g or c, type needs at least two characters
 45        // and module_and_name may contain single underscores.
 46        '[lgc]__?[a-zA-Z](?:_?[a-zA-Z])*_[a-zA-Z]{2,}',
 47        // A quark \q_the_name or \q__the_name or
 48        // scan mark \s_the_name or \s__vthe_name,
 49        // where variable_name needs at least two characters and
 50        // may contain single underscores.
 51        '[qs]__?[a-zA-Z](?:_?[a-zA-Z])+',
 52        // Other LaTeX3 macro names that are not covered by the three rules above.
 53        'use(?:_i)?:[a-zA-Z]*',
 54        '(?:else|fi|or):',
 55        '(?:if|cs|exp):w',
 56        '(?:hbox|vbox):n',
 57        '::[a-zA-Z]_unbraced',
 58        '::[a-zA-Z:]'
 59      ].map(pattern => pattern + '(?![a-zA-Z:_])').join('|'));
 60      const L2_VARIANTS = [
 61        { begin: /[a-zA-Z@]+/ }, // control word
 62        { begin: /[^a-zA-Z@]?/ } // control symbol
 63      ];
 64      const DOUBLE_CARET_VARIANTS = [
 65        { begin: /\^{6}[0-9a-f]{6}/ },
 66        { begin: /\^{5}[0-9a-f]{5}/ },
 67        { begin: /\^{4}[0-9a-f]{4}/ },
 68        { begin: /\^{3}[0-9a-f]{3}/ },
 69        { begin: /\^{2}[0-9a-f]{2}/ },
 70        { begin: /\^{2}[\u0000-\u007f]/ }
 71      ];
 72      const CONTROL_SEQUENCE = {
 73        className: 'keyword',
 74        begin: /\\/,
 75        relevance: 0,
 76        contains: [
 77          {
 78            endsParent: true,
 79            begin: KNOWN_CONTROL_WORDS
 80          },
 81          {
 82            endsParent: true,
 83            begin: L3_REGEX
 84          },
 85          {
 86            endsParent: true,
 87            variants: DOUBLE_CARET_VARIANTS
 88          },
 89          {
 90            endsParent: true,
 91            relevance: 0,
 92            variants: L2_VARIANTS
 93          }
 94        ]
 95      };
 96      const MACRO_PARAM = {
 97        className: 'params',
 98        relevance: 0,
 99        begin: /#+\d?/
100      };
101      const DOUBLE_CARET_CHAR = {
102        // relevance: 1
103        variants: DOUBLE_CARET_VARIANTS };
104      const SPECIAL_CATCODE = {
105        className: 'built_in',
106        relevance: 0,
107        begin: /[$&^_]/
108      };
109      const MAGIC_COMMENT = {
110        className: 'meta',
111        begin: /% ?!(T[eE]X|tex|BIB|bib)/,
112        end: '$',
113        relevance: 10
114      };
115      const COMMENT = hljs.COMMENT(
116        '%',
117        '$',
118        { relevance: 0 }
119      );
120      const EVERYTHING_BUT_VERBATIM = [
121        CONTROL_SEQUENCE,
122        MACRO_PARAM,
123        DOUBLE_CARET_CHAR,
124        SPECIAL_CATCODE,
125        MAGIC_COMMENT,
126        COMMENT
127      ];
128      const BRACE_GROUP_NO_VERBATIM = {
129        begin: /\{/,
130        end: /\}/,
131        relevance: 0,
132        contains: [
133          'self',
134          ...EVERYTHING_BUT_VERBATIM
135        ]
136      };
137      const ARGUMENT_BRACES = hljs.inherit(
138        BRACE_GROUP_NO_VERBATIM,
139        {
140          relevance: 0,
141          endsParent: true,
142          contains: [
143            BRACE_GROUP_NO_VERBATIM,
144            ...EVERYTHING_BUT_VERBATIM
145          ]
146        }
147      );
148      const ARGUMENT_BRACKETS = {
149        begin: /\[/,
150        end: /\]/,
151        endsParent: true,
152        relevance: 0,
153        contains: [
154          BRACE_GROUP_NO_VERBATIM,
155          ...EVERYTHING_BUT_VERBATIM
156        ]
157      };
158      const SPACE_GOBBLER = {
159        begin: /\s+/,
160        relevance: 0
161      };
162      const ARGUMENT_M = [ ARGUMENT_BRACES ];
163      const ARGUMENT_O = [ ARGUMENT_BRACKETS ];
164      const ARGUMENT_AND_THEN = function(arg, starts_mode) {
165        return {
166          contains: [ SPACE_GOBBLER ],
167          starts: {
168            relevance: 0,
169            contains: arg,
170            starts: starts_mode
171          }
172        };
173      };
174      const CSNAME = function(csname, starts_mode) {
175        return {
176          begin: '\\\\' + csname + '(?![a-zA-Z@:_])',
177          keywords: {
178            $pattern: /\\[a-zA-Z]+/,
179            keyword: '\\' + csname
180          },
181          relevance: 0,
182          contains: [ SPACE_GOBBLER ],
183          starts: starts_mode
184        };
185      };
186      const BEGIN_ENV = function(envname, starts_mode) {
187        return hljs.inherit(
188          {
189            begin: '\\\\begin(?=[ \t]*(\\r?\\n[ \t]*)?\\{' + envname + '\\})',
190            keywords: {
191              $pattern: /\\[a-zA-Z]+/,
192              keyword: '\\begin'
193            },
194            relevance: 0,
195          },
196          ARGUMENT_AND_THEN(ARGUMENT_M, starts_mode)
197        );
198      };
199      const VERBATIM_DELIMITED_EQUAL = (innerName = "string") => {
200        return hljs.END_SAME_AS_BEGIN({
201          className: innerName,
202          begin: /(.|\r?\n)/,
203          end: /(.|\r?\n)/,
204          excludeBegin: true,
205          excludeEnd: true,
206          endsParent: true
207        });
208      };
209      const VERBATIM_DELIMITED_ENV = function(envname) {
210        return {
211          className: 'string',
212          end: '(?=\\\\end\\{' + envname + '\\})'
213        };
214      };
215  
216      const VERBATIM_DELIMITED_BRACES = (innerName = "string") => {
217        return {
218          relevance: 0,
219          begin: /\{/,
220          starts: {
221            endsParent: true,
222            contains: [
223              {
224                className: innerName,
225                end: /(?=\})/,
226                endsParent: true,
227                contains: [
228                  {
229                    begin: /\{/,
230                    end: /\}/,
231                    relevance: 0,
232                    contains: [ "self" ]
233                  }
234                ],
235              }
236            ]
237          }
238        };
239      };
240      const VERBATIM = [
241        ...[
242          'verb',
243          'lstinline'
244        ].map(csname => CSNAME(csname, { contains: [ VERBATIM_DELIMITED_EQUAL() ] })),
245        CSNAME('mint', ARGUMENT_AND_THEN(ARGUMENT_M, { contains: [ VERBATIM_DELIMITED_EQUAL() ] })),
246        CSNAME('mintinline', ARGUMENT_AND_THEN(ARGUMENT_M, { contains: [
247          VERBATIM_DELIMITED_BRACES(),
248          VERBATIM_DELIMITED_EQUAL()
249        ] })),
250        CSNAME('url', { contains: [
251          VERBATIM_DELIMITED_BRACES("link"),
252          VERBATIM_DELIMITED_BRACES("link")
253        ] }),
254        CSNAME('hyperref', { contains: [ VERBATIM_DELIMITED_BRACES("link") ] }),
255        CSNAME('href', ARGUMENT_AND_THEN(ARGUMENT_O, { contains: [ VERBATIM_DELIMITED_BRACES("link") ] })),
256        ...[].concat(...[
257          '',
258          '\\*'
259        ].map(suffix => [
260          BEGIN_ENV('verbatim' + suffix, VERBATIM_DELIMITED_ENV('verbatim' + suffix)),
261          BEGIN_ENV('filecontents' + suffix, ARGUMENT_AND_THEN(ARGUMENT_M, VERBATIM_DELIMITED_ENV('filecontents' + suffix))),
262          ...[
263            '',
264            'B',
265            'L'
266          ].map(prefix =>
267            BEGIN_ENV(prefix + 'Verbatim' + suffix, ARGUMENT_AND_THEN(ARGUMENT_O, VERBATIM_DELIMITED_ENV(prefix + 'Verbatim' + suffix)))
268          )
269        ])),
270        BEGIN_ENV('minted', ARGUMENT_AND_THEN(ARGUMENT_O, ARGUMENT_AND_THEN(ARGUMENT_M, VERBATIM_DELIMITED_ENV('minted')))),
271      ];
272  
273      return {
274        name: 'LaTeX',
275        aliases: [ 'tex' ],
276        contains: [
277          ...VERBATIM,
278          ...EVERYTHING_BUT_VERBATIM
279        ]
280      };
281    }
282  
283    return latex;
284  
285  })();
286  
287      hljs.registerLanguage('latex', hljsGrammar);
288    })();