| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 | /** * @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;}/** * @param {...(RegExp | string) } args * @returns {string} */function concat(...args) {  const joined = args.map((x) => source(x)).join("");  return joined;}/** * 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: PerlAuthor: Peter Leonov <gojpeg@yandex.ru>Website: https://www.perl.orgCategory: common*//** @type LanguageFn */function perl(hljs) {  const KEYWORDS = [    'abs',    'accept',    'alarm',    'and',    'atan2',    'bind',    'binmode',    'bless',    'break',    'caller',    'chdir',    'chmod',    'chomp',    'chop',    'chown',    'chr',    'chroot',    'close',    'closedir',    'connect',    'continue',    'cos',    'crypt',    'dbmclose',    'dbmopen',    'defined',    'delete',    'die',    'do',    'dump',    'each',    'else',    'elsif',    'endgrent',    'endhostent',    'endnetent',    'endprotoent',    'endpwent',    'endservent',    'eof',    'eval',    'exec',    'exists',    'exit',    'exp',    'fcntl',    'fileno',    'flock',    'for',    'foreach',    'fork',    'format',    'formline',    'getc',    'getgrent',    'getgrgid',    'getgrnam',    'gethostbyaddr',    'gethostbyname',    'gethostent',    'getlogin',    'getnetbyaddr',    'getnetbyname',    'getnetent',    'getpeername',    'getpgrp',    'getpriority',    'getprotobyname',    'getprotobynumber',    'getprotoent',    'getpwent',    'getpwnam',    'getpwuid',    'getservbyname',    'getservbyport',    'getservent',    'getsockname',    'getsockopt',    'given',    'glob',    'gmtime',    'goto',    'grep',    'gt',    'hex',    'if',    'index',    'int',    'ioctl',    'join',    'keys',    'kill',    'last',    'lc',    'lcfirst',    'length',    'link',    'listen',    'local',    'localtime',    'log',    'lstat',    'lt',    'ma',    'map',    'mkdir',    'msgctl',    'msgget',    'msgrcv',    'msgsnd',    'my',    'ne',    'next',    'no',    'not',    'oct',    'open',    'opendir',    'or',    'ord',    'our',    'pack',    'package',    'pipe',    'pop',    'pos',    'print',    'printf',    'prototype',    'push',    'q|0',    'qq',    'quotemeta',    'qw',    'qx',    'rand',    'read',    'readdir',    'readline',    'readlink',    'readpipe',    'recv',    'redo',    'ref',    'rename',    'require',    'reset',    'return',    'reverse',    'rewinddir',    'rindex',    'rmdir',    'say',    'scalar',    'seek',    'seekdir',    'select',    'semctl',    'semget',    'semop',    'send',    'setgrent',    'sethostent',    'setnetent',    'setpgrp',    'setpriority',    'setprotoent',    'setpwent',    'setservent',    'setsockopt',    'shift',    'shmctl',    'shmget',    'shmread',    'shmwrite',    'shutdown',    'sin',    'sleep',    'socket',    'socketpair',    'sort',    'splice',    'split',    'sprintf',    'sqrt',    'srand',    'stat',    'state',    'study',    'sub',    'substr',    'symlink',    'syscall',    'sysopen',    'sysread',    'sysseek',    'system',    'syswrite',    'tell',    'telldir',    'tie',    'tied',    'time',    'times',    'tr',    'truncate',    'uc',    'ucfirst',    'umask',    'undef',    'unless',    'unlink',    'unpack',    'unshift',    'untie',    'until',    'use',    'utime',    'values',    'vec',    'wait',    'waitpid',    'wantarray',    'warn',    'when',    'while',    'write',    'x|0',    'xor',    'y|0'  ];  // https://perldoc.perl.org/perlre#Modifiers  const REGEX_MODIFIERS = /[dualxmsipngr]{0,12}/; // aa and xx are valid, making max length 12  const PERL_KEYWORDS = {    $pattern: /[\w.]+/,    keyword: KEYWORDS.join(" ")  };  const SUBST = {    className: 'subst',    begin: '[$@]\\{',    end: '\\}',    keywords: PERL_KEYWORDS  };  const METHOD = {    begin: /->\{/,    end: /\}/    // contains defined later  };  const VAR = {    variants: [      {        begin: /\$\d/      },      {        begin: concat(          /[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,          // negative look-ahead tries to avoid matching patterns that are not          // Perl at all like $ident$, @ident@, etc.          `(?![A-Za-z])(?![@$%])`        )      },      {        begin: /[$%@][^\s\w{]/,        relevance: 0      }    ]  };  const STRING_CONTAINS = [    hljs.BACKSLASH_ESCAPE,    SUBST,    VAR  ];  const REGEX_DELIMS = [    /!/,    /\//,    /\|/,    /\?/,    /'/,    /"/, // valid but infrequent and weird    /#/ // valid but infrequent and weird  ];  /**   * @param {string|RegExp} prefix   * @param {string|RegExp} open   * @param {string|RegExp} close   */  const PAIRED_DOUBLE_RE = (prefix, open, close = '\\1') => {    const middle = (close === '\\1')      ? close      : concat(close, open);    return concat(      concat("(?:", prefix, ")"),      open,      /(?:\\.|[^\\\/])*?/,      middle,      /(?:\\.|[^\\\/])*?/,      close,      REGEX_MODIFIERS    );  };  /**   * @param {string|RegExp} prefix   * @param {string|RegExp} open   * @param {string|RegExp} close   */  const PAIRED_RE = (prefix, open, close) => {    return concat(      concat("(?:", prefix, ")"),      open,      /(?:\\.|[^\\\/])*?/,      close,      REGEX_MODIFIERS    );  };  const PERL_DEFAULT_CONTAINS = [    VAR,    hljs.HASH_COMMENT_MODE,    hljs.COMMENT(      /^=\w/,      /=cut/,      {        endsWithParent: true      }    ),    METHOD,    {      className: 'string',      contains: STRING_CONTAINS,      variants: [        {          begin: 'q[qwxr]?\\s*\\(',          end: '\\)',          relevance: 5        },        {          begin: 'q[qwxr]?\\s*\\[',          end: '\\]',          relevance: 5        },        {          begin: 'q[qwxr]?\\s*\\{',          end: '\\}',          relevance: 5        },        {          begin: 'q[qwxr]?\\s*\\|',          end: '\\|',          relevance: 5        },        {          begin: 'q[qwxr]?\\s*<',          end: '>',          relevance: 5        },        {          begin: 'qw\\s+q',          end: 'q',          relevance: 5        },        {          begin: '\'',          end: '\'',          contains: [ hljs.BACKSLASH_ESCAPE ]        },        {          begin: '"',          end: '"'        },        {          begin: '`',          end: '`',          contains: [ hljs.BACKSLASH_ESCAPE ]        },        {          begin: /\{\w+\}/,          relevance: 0        },        {          begin: '-?\\w+\\s*=>',          relevance: 0        }      ]    },    {      className: 'number',      begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',      relevance: 0    },    { // regexp container      begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',      keywords: 'split return print reverse grep',      relevance: 0,      contains: [        hljs.HASH_COMMENT_MODE,        {          className: 'regexp',          variants: [            // allow matching common delimiters            { begin: PAIRED_DOUBLE_RE("s|tr|y", either(...REGEX_DELIMS)) },            // and then paired delmis            { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\(", "\\)") },            { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\[", "\\]") },            { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\{", "\\}") }          ],          relevance: 2        },        {          className: 'regexp',          variants: [            {              // could be a comment in many languages so do not count              // as relevant              begin: /(m|qr)\/\//,              relevance: 0            },            // prefix is optional with /regex/            { begin: PAIRED_RE("(?:m|qr)?", /\//, /\//)},            // allow matching common delimiters            { begin: PAIRED_RE("m|qr", either(...REGEX_DELIMS), /\1/)},            // allow common paired delmins            { begin: PAIRED_RE("m|qr", /\(/, /\)/)},            { begin: PAIRED_RE("m|qr", /\[/, /\]/)},            { begin: PAIRED_RE("m|qr", /\{/, /\}/)}          ]        }      ]    },    {      className: 'function',      beginKeywords: 'sub',      end: '(\\s*\\(.*?\\))?[;{]',      excludeEnd: true,      relevance: 5,      contains: [ hljs.TITLE_MODE ]    },    {      begin: '-\\w\\b',      relevance: 0    },    {      begin: "^__DATA__$",      end: "^__END__$",      subLanguage: 'mojolicious',      contains: [        {          begin: "^@@.*",          end: "$",          className: "comment"        }      ]    }  ];  SUBST.contains = PERL_DEFAULT_CONTAINS;  METHOD.contains = PERL_DEFAULT_CONTAINS;  return {    name: 'Perl',    aliases: [      'pl',      'pm'    ],    keywords: PERL_KEYWORDS,    contains: PERL_DEFAULT_CONTAINS  };}module.exports = perl;
 |