123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- /**
- * @param {string} value
- * @returns {RegExp}
- * */
- /**
- * @param {RegExp | string } re
- * @returns {string}
- */
- function source(re) {
- if (!re) return null;
- if (typeof re === "string") return re;
- return re.source;
- }
- /**
- * Any of the passed expresssions may match
- *
- * Creates a huge this | this | that | that match
- * @param {(RegExp | string)[] } args
- * @returns {string}
- */
- function either(...args) {
- const joined = '(' + args.map((x) => source(x)).join("|") + ")";
- return joined;
- }
- /*
- Language: LaTeX
- Author: Benedikt Wilde <bwilde@posteo.de>
- Website: https://www.latex-project.org
- Category: markup
- */
- /** @type LanguageFn */
- function latex(hljs) {
- const KNOWN_CONTROL_WORDS = either(...[
- '(?:NeedsTeXFormat|RequirePackage|GetIdInfo)',
- 'Provides(?:Expl)?(?:Package|Class|File)',
- '(?:DeclareOption|ProcessOptions)',
- '(?:documentclass|usepackage|input|include)',
- 'makeat(?:letter|other)',
- 'ExplSyntax(?:On|Off)',
- '(?:new|renew|provide)?command',
- '(?:re)newenvironment',
- '(?:New|Renew|Provide|Declare)(?:Expandable)?DocumentCommand',
- '(?:New|Renew|Provide|Declare)DocumentEnvironment',
- '(?:(?:e|g|x)?def|let)',
- '(?:begin|end)',
- '(?:part|chapter|(?:sub){0,2}section|(?:sub)?paragraph)',
- 'caption',
- '(?:label|(?:eq|page|name)?ref|(?:paren|foot|super)?cite)',
- '(?:alpha|beta|[Gg]amma|[Dd]elta|(?:var)?epsilon|zeta|eta|[Tt]heta|vartheta)',
- '(?:iota|(?:var)?kappa|[Ll]ambda|mu|nu|[Xx]i|[Pp]i|varpi|(?:var)rho)',
- '(?:[Ss]igma|varsigma|tau|[Uu]psilon|[Pp]hi|varphi|chi|[Pp]si|[Oo]mega)',
- '(?:frac|sum|prod|lim|infty|times|sqrt|leq|geq|left|right|middle|[bB]igg?)',
- '(?:[lr]angle|q?quad|[lcvdi]?dots|d?dot|hat|tilde|bar)'
- ].map(word => word + '(?![a-zA-Z@:_])'));
- const L3_REGEX = new RegExp([
- // A function \module_function_name:signature or \__module_function_name:signature,
- // where both module and function_name need at least two characters and
- // function_name may contain single underscores.
- '(?:__)?[a-zA-Z]{2,}_[a-zA-Z](?:_?[a-zA-Z])+:[a-zA-Z]*',
- // A variable \scope_module_and_name_type or \scope__module_ane_name_type,
- // where scope is one of l, g or c, type needs at least two characters
- // and module_and_name may contain single underscores.
- '[lgc]__?[a-zA-Z](?:_?[a-zA-Z])*_[a-zA-Z]{2,}',
- // A quark \q_the_name or \q__the_name or
- // scan mark \s_the_name or \s__vthe_name,
- // where variable_name needs at least two characters and
- // may contain single underscores.
- '[qs]__?[a-zA-Z](?:_?[a-zA-Z])+',
- // Other LaTeX3 macro names that are not covered by the three rules above.
- 'use(?:_i)?:[a-zA-Z]*',
- '(?:else|fi|or):',
- '(?:if|cs|exp):w',
- '(?:hbox|vbox):n',
- '::[a-zA-Z]_unbraced',
- '::[a-zA-Z:]'
- ].map(pattern => pattern + '(?![a-zA-Z:_])').join('|'));
- const L2_VARIANTS = [
- {begin: /[a-zA-Z@]+/}, // control word
- {begin: /[^a-zA-Z@]?/} // control symbol
- ];
- const DOUBLE_CARET_VARIANTS = [
- {begin: /\^{6}[0-9a-f]{6}/},
- {begin: /\^{5}[0-9a-f]{5}/},
- {begin: /\^{4}[0-9a-f]{4}/},
- {begin: /\^{3}[0-9a-f]{3}/},
- {begin: /\^{2}[0-9a-f]{2}/},
- {begin: /\^{2}[\u0000-\u007f]/}
- ];
- const CONTROL_SEQUENCE = {
- className: 'keyword',
- begin: /\\/,
- relevance: 0,
- contains: [
- {
- endsParent: true,
- begin: KNOWN_CONTROL_WORDS
- },
- {
- endsParent: true,
- begin: L3_REGEX
- },
- {
- endsParent: true,
- variants: DOUBLE_CARET_VARIANTS
- },
- {
- endsParent: true,
- relevance: 0,
- variants: L2_VARIANTS
- }
- ]
- };
- const MACRO_PARAM = {
- className: 'params',
- relevance: 0,
- begin: /#+\d?/
- };
- const DOUBLE_CARET_CHAR = {
- // relevance: 1
- variants: DOUBLE_CARET_VARIANTS
- };
- const SPECIAL_CATCODE = {
- className: 'built_in',
- relevance: 0,
- begin: /[$&^_]/
- };
- const MAGIC_COMMENT = {
- className: 'meta',
- begin: '% !TeX',
- end: '$',
- relevance: 10
- };
- const COMMENT = hljs.COMMENT(
- '%',
- '$',
- {
- relevance: 0
- }
- );
- const EVERYTHING_BUT_VERBATIM = [
- CONTROL_SEQUENCE,
- MACRO_PARAM,
- DOUBLE_CARET_CHAR,
- SPECIAL_CATCODE,
- MAGIC_COMMENT,
- COMMENT
- ];
- const BRACE_GROUP_NO_VERBATIM = {
- begin: /\{/, end: /\}/,
- relevance: 0,
- contains: ['self', ...EVERYTHING_BUT_VERBATIM]
- };
- const ARGUMENT_BRACES = hljs.inherit(
- BRACE_GROUP_NO_VERBATIM,
- {
- relevance: 0,
- endsParent: true,
- contains: [BRACE_GROUP_NO_VERBATIM, ...EVERYTHING_BUT_VERBATIM]
- }
- );
- const ARGUMENT_BRACKETS = {
- begin: /\[/,
- end: /\]/,
- endsParent: true,
- relevance: 0,
- contains: [BRACE_GROUP_NO_VERBATIM, ...EVERYTHING_BUT_VERBATIM]
- };
- const SPACE_GOBBLER = {
- begin: /\s+/,
- relevance: 0
- };
- const ARGUMENT_M = [ARGUMENT_BRACES];
- const ARGUMENT_O = [ARGUMENT_BRACKETS];
- const ARGUMENT_AND_THEN = function(arg, starts_mode) {
- return {
- contains: [SPACE_GOBBLER],
- starts: {
- relevance: 0,
- contains: arg,
- starts: starts_mode
- }
- };
- };
- const CSNAME = function(csname, starts_mode) {
- return {
- begin: '\\\\' + csname + '(?![a-zA-Z@:_])',
- keywords: {$pattern: /\\[a-zA-Z]+/, keyword: '\\' + csname},
- relevance: 0,
- contains: [SPACE_GOBBLER],
- starts: starts_mode
- };
- };
- const BEGIN_ENV = function(envname, starts_mode) {
- return hljs.inherit(
- {
- begin: '\\\\begin(?=[ \t]*(\\r?\\n[ \t]*)?\\{' + envname + '\\})',
- keywords: {$pattern: /\\[a-zA-Z]+/, keyword: '\\begin'},
- relevance: 0,
- },
- ARGUMENT_AND_THEN(ARGUMENT_M, starts_mode)
- );
- };
- const VERBATIM_DELIMITED_EQUAL = (innerName = "string") => {
- return hljs.END_SAME_AS_BEGIN({
- className: innerName,
- begin: /(.|\r?\n)/,
- end: /(.|\r?\n)/,
- excludeBegin: true,
- excludeEnd: true,
- endsParent: true
- });
- };
- const VERBATIM_DELIMITED_ENV = function(envname) {
- return {
- className: 'string',
- end: '(?=\\\\end\\{' + envname + '\\})'
- };
- };
- const VERBATIM_DELIMITED_BRACES = (innerName = "string") => {
- return {
- relevance: 0,
- begin: /\{/,
- starts: {
- endsParent: true,
- contains: [
- {
- className: innerName,
- end: /(?=\})/,
- endsParent:true,
- contains: [
- {
- begin: /\{/,
- end: /\}/,
- relevance: 0,
- contains: ["self"]
- }
- ],
- }
- ]
- }
- };
- };
- const VERBATIM = [
- ...['verb', 'lstinline'].map(csname => CSNAME(csname, {contains: [VERBATIM_DELIMITED_EQUAL()]})),
- CSNAME('mint', ARGUMENT_AND_THEN(ARGUMENT_M, {contains: [VERBATIM_DELIMITED_EQUAL()]})),
- CSNAME('mintinline', ARGUMENT_AND_THEN(ARGUMENT_M, {contains: [VERBATIM_DELIMITED_BRACES(), VERBATIM_DELIMITED_EQUAL()]})),
- CSNAME('url', {contains: [VERBATIM_DELIMITED_BRACES("link"), VERBATIM_DELIMITED_BRACES("link")]}),
- CSNAME('hyperref', {contains: [VERBATIM_DELIMITED_BRACES("link")]}),
- CSNAME('href', ARGUMENT_AND_THEN(ARGUMENT_O, {contains: [VERBATIM_DELIMITED_BRACES("link")]})),
- ...[].concat(...['', '\\*'].map(suffix => [
- BEGIN_ENV('verbatim' + suffix, VERBATIM_DELIMITED_ENV('verbatim' + suffix)),
- BEGIN_ENV('filecontents' + suffix, ARGUMENT_AND_THEN(ARGUMENT_M, VERBATIM_DELIMITED_ENV('filecontents' + suffix))),
- ...['', 'B', 'L'].map(prefix =>
- BEGIN_ENV(prefix + 'Verbatim' + suffix, ARGUMENT_AND_THEN(ARGUMENT_O, VERBATIM_DELIMITED_ENV(prefix + 'Verbatim' + suffix)))
- )
- ])),
- BEGIN_ENV('minted', ARGUMENT_AND_THEN(ARGUMENT_O, ARGUMENT_AND_THEN(ARGUMENT_M, VERBATIM_DELIMITED_ENV('minted')))),
- ];
- return {
- name: 'LaTeX',
- aliases: ['tex'],
- contains: [
- ...VERBATIM,
- ...EVERYTHING_BUT_VERBATIM
- ]
- };
- }
- module.exports = latex;
|