CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes45downloads
core.js2598 linesDownload Raw Back to lib
1/* eslint-disable no-multi-assign */2 3function deepFreeze(obj) {4  if (obj instanceof Map) {5    obj.clear =6      obj.delete =7      obj.set =8        function () {9          throw new Error('map is read-only');10        };11  } else if (obj instanceof Set) {12    obj.add =13      obj.clear =14      obj.delete =15        function () {16          throw new Error('set is read-only');17        };18  }19 20  // Freeze self21  Object.freeze(obj);22 23  Object.getOwnPropertyNames(obj).forEach((name) => {24    const prop = obj[name];25    const type = typeof prop;26 27    // Freeze prop if it is an object or function and also not already frozen28    if ((type === 'object' || type === 'function') && !Object.isFrozen(prop)) {29      deepFreeze(prop);30    }31  });32 33  return obj;34}35 36/** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */37/** @typedef {import('highlight.js').CompiledMode} CompiledMode */38/** @implements CallbackResponse */39 40class Response {41  /**42   * @param {CompiledMode} mode43   */44  constructor(mode) {45    // eslint-disable-next-line no-undefined46    if (mode.data === undefined) mode.data = {};47 48    this.data = mode.data;49    this.isMatchIgnored = false;50  }51 52  ignoreMatch() {53    this.isMatchIgnored = true;54  }55}56 57/**58 * @param {string} value59 * @returns {string}60 */61function escapeHTML(value) {62  return value63    .replace(/&/g, '&amp;')64    .replace(/</g, '&lt;')65    .replace(/>/g, '&gt;')66    .replace(/"/g, '&quot;')67    .replace(/'/g, '&#x27;');68}69 70/**71 * performs a shallow merge of multiple objects into one72 *73 * @template T74 * @param {T} original75 * @param {Record<string,any>[]} objects76 * @returns {T} a single new object77 */78function inherit$1(original, ...objects) {79  /** @type Record<string,any> */80  const result = Object.create(null);81 82  for (const key in original) {83    result[key] = original[key];84  }85  objects.forEach(function(obj) {86    for (const key in obj) {87      result[key] = obj[key];88    }89  });90  return /** @type {T} */ (result);91}92 93/**94 * @typedef {object} Renderer95 * @property {(text: string) => void} addText96 * @property {(node: Node) => void} openNode97 * @property {(node: Node) => void} closeNode98 * @property {() => string} value99 */100 101/** @typedef {{scope?: string, language?: string, sublanguage?: boolean}} Node */102/** @typedef {{walk: (r: Renderer) => void}} Tree */103/** */104 105const SPAN_CLOSE = '</span>';106 107/**108 * Determines if a node needs to be wrapped in <span>109 *110 * @param {Node} node */111const emitsWrappingTags = (node) => {112  // rarely we can have a sublanguage where language is undefined113  // TODO: track down why114  return !!node.scope;115};116 117/**118 *119 * @param {string} name120 * @param {{prefix:string}} options121 */122const scopeToCSSClass = (name, { prefix }) => {123  // sub-language124  if (name.startsWith("language:")) {125    return name.replace("language:", "language-");126  }127  // tiered scope: comment.line128  if (name.includes(".")) {129    const pieces = name.split(".");130    return [131      `${prefix}${pieces.shift()}`,132      ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`))133    ].join(" ");134  }135  // simple scope136  return `${prefix}${name}`;137};138 139/** @type {Renderer} */140class HTMLRenderer {141  /**142   * Creates a new HTMLRenderer143   *144   * @param {Tree} parseTree - the parse tree (must support `walk` API)145   * @param {{classPrefix: string}} options146   */147  constructor(parseTree, options) {148    this.buffer = "";149    this.classPrefix = options.classPrefix;150    parseTree.walk(this);151  }152 153  /**154   * Adds texts to the output stream155   *156   * @param {string} text */157  addText(text) {158    this.buffer += escapeHTML(text);159  }160 161  /**162   * Adds a node open to the output stream (if needed)163   *164   * @param {Node} node */165  openNode(node) {166    if (!emitsWrappingTags(node)) return;167 168    const className = scopeToCSSClass(node.scope,169      { prefix: this.classPrefix });170    this.span(className);171  }172 173  /**174   * Adds a node close to the output stream (if needed)175   *176   * @param {Node} node */177  closeNode(node) {178    if (!emitsWrappingTags(node)) return;179 180    this.buffer += SPAN_CLOSE;181  }182 183  /**184   * returns the accumulated buffer185  */186  value() {187    return this.buffer;188  }189 190  // helpers191 192  /**193   * Builds a span element194   *195   * @param {string} className */196  span(className) {197    this.buffer += `<span class="${className}">`;198  }199}200 201/** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */202/** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */203/** @typedef {import('highlight.js').Emitter} Emitter */204/**  */205 206/** @returns {DataNode} */207const newNode = (opts = {}) => {208  /** @type DataNode */209  const result = { children: [] };210  Object.assign(result, opts);211  return result;212};213 214class TokenTree {215  constructor() {216    /** @type DataNode */217    this.rootNode = newNode();218    this.stack = [this.rootNode];219  }220 221  get top() {222    return this.stack[this.stack.length - 1];223  }224 225  get root() { return this.rootNode; }226 227  /** @param {Node} node */228  add(node) {229    this.top.children.push(node);230  }231 232  /** @param {string} scope */233  openNode(scope) {234    /** @type Node */235    const node = newNode({ scope });236    this.add(node);237    this.stack.push(node);238  }239 240  closeNode() {241    if (this.stack.length > 1) {242      return this.stack.pop();243    }244    // eslint-disable-next-line no-undefined245    return undefined;246  }247 248  closeAllNodes() {249    while (this.closeNode());250  }251 252  toJSON() {253    return JSON.stringify(this.rootNode, null, 4);254  }255 256  /**257   * @typedef { import("./html_renderer").Renderer } Renderer258   * @param {Renderer} builder259   */260  walk(builder) {261    // this does not262    return this.constructor._walk(builder, this.rootNode);263    // this works264    // return TokenTree._walk(builder, this.rootNode);265  }266 267  /**268   * @param {Renderer} builder269   * @param {Node} node270   */271  static _walk(builder, node) {272    if (typeof node === "string") {273      builder.addText(node);274    } else if (node.children) {275      builder.openNode(node);276      node.children.forEach((child) => this._walk(builder, child));277      builder.closeNode(node);278    }279    return builder;280  }281 282  /**283   * @param {Node} node284   */285  static _collapse(node) {286    if (typeof node === "string") return;287    if (!node.children) return;288 289    if (node.children.every(el => typeof el === "string")) {290      // node.text = node.children.join("");291      // delete node.children;292      node.children = [node.children.join("")];293    } else {294      node.children.forEach((child) => {295        TokenTree._collapse(child);296      });297    }298  }299}300 301/**302  Currently this is all private API, but this is the minimal API necessary303  that an Emitter must implement to fully support the parser.304 305  Minimal interface:306 307  - addText(text)308  - __addSublanguage(emitter, subLanguageName)309  - startScope(scope)310  - endScope()311  - finalize()312  - toHTML()313 314*/315 316/**317 * @implements {Emitter}318 */319class TokenTreeEmitter extends TokenTree {320  /**321   * @param {*} options322   */323  constructor(options) {324    super();325    this.options = options;326  }327 328  /**329   * @param {string} text330   */331  addText(text) {332    if (text === "") { return; }333 334    this.add(text);335  }336 337  /** @param {string} scope */338  startScope(scope) {339    this.openNode(scope);340  }341 342  endScope() {343    this.closeNode();344  }345 346  /**347   * @param {Emitter & {root: DataNode}} emitter348   * @param {string} name349   */350  __addSublanguage(emitter, name) {351    /** @type DataNode */352    const node = emitter.root;353    if (name) node.scope = `language:${name}`;354 355    this.add(node);356  }357 358  toHTML() {359    const renderer = new HTMLRenderer(this, this.options);360    return renderer.value();361  }362 363  finalize() {364    this.closeAllNodes();365    return true;366  }367}368 369/**370 * @param {string} value371 * @returns {RegExp}372 * */373 374/**375 * @param {RegExp | string } re376 * @returns {string}377 */378function source(re) {379  if (!re) return null;380  if (typeof re === "string") return re;381 382  return re.source;383}384 385/**386 * @param {RegExp | string } re387 * @returns {string}388 */389function lookahead(re) {390  return concat('(?=', re, ')');391}392 393/**394 * @param {RegExp | string } re395 * @returns {string}396 */397function anyNumberOfTimes(re) {398  return concat('(?:', re, ')*');399}400 401/**402 * @param {RegExp | string } re403 * @returns {string}404 */405function optional(re) {406  return concat('(?:', re, ')?');407}408 409/**410 * @param {...(RegExp | string) } args411 * @returns {string}412 */413function concat(...args) {414  const joined = args.map((x) => source(x)).join("");415  return joined;416}417 418/**419 * @param { Array<string | RegExp | Object> } args420 * @returns {object}421 */422function stripOptionsFromArgs(args) {423  const opts = args[args.length - 1];424 425  if (typeof opts === 'object' && opts.constructor === Object) {426    args.splice(args.length - 1, 1);427    return opts;428  } else {429    return {};430  }431}432 433/** @typedef { {capture?: boolean} } RegexEitherOptions */434 435/**436 * Any of the passed expresssions may match437 *438 * Creates a huge this | this | that | that match439 * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args440 * @returns {string}441 */442function either(...args) {443  /** @type { object & {capture?: boolean} }  */444  const opts = stripOptionsFromArgs(args);445  const joined = '('446    + (opts.capture ? "" : "?:")447    + args.map((x) => source(x)).join("|") + ")";448  return joined;449}450 451/**452 * @param {RegExp | string} re453 * @returns {number}454 */455function countMatchGroups(re) {456  return (new RegExp(re.toString() + '|')).exec('').length - 1;457}458 459/**460 * Does lexeme start with a regular expression match at the beginning461 * @param {RegExp} re462 * @param {string} lexeme463 */464function startsWith(re, lexeme) {465  const match = re && re.exec(lexeme);466  return match && match.index === 0;467}468 469// BACKREF_RE matches an open parenthesis or backreference. To avoid470// an incorrect parse, it additionally matches the following:471// - [...] elements, where the meaning of parentheses and escapes change472// - other escape sequences, so we do not misparse escape sequences as473//   interesting elements474// - non-matching or lookahead parentheses, which do not capture. These475//   follow the '(' with a '?'.476const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;477 478// **INTERNAL** Not intended for outside usage479// join logically computes regexps.join(separator), but fixes the480// backreferences so they continue to match.481// it also places each individual regular expression into it's own482// match group, keeping track of the sequencing of those match groups483// is currently an exercise for the caller. :-)484/**485 * @param {(string | RegExp)[]} regexps486 * @param {{joinWith: string}} opts487 * @returns {string}488 */489function _rewriteBackreferences(regexps, { joinWith }) {490  let numCaptures = 0;491 492  return regexps.map((regex) => {493    numCaptures += 1;494    const offset = numCaptures;495    let re = source(regex);496    let out = '';497 498    while (re.length > 0) {499      const match = BACKREF_RE.exec(re);500      if (!match) {501        out += re;502        break;503      }504      out += re.substring(0, match.index);505      re = re.substring(match.index + match[0].length);506      if (match[0][0] === '\\' && match[1]) {507        // Adjust the backreference.508        out += '\\' + String(Number(match[1]) + offset);509      } else {510        out += match[0];511        if (match[0] === '(') {512          numCaptures++;513        }514      }515    }516    return out;517  }).map(re => `(${re})`).join(joinWith);518}519 520/** @typedef {import('highlight.js').Mode} Mode */521/** @typedef {import('highlight.js').ModeCallback} ModeCallback */522 523// Common regexps524const MATCH_NOTHING_RE = /\b\B/;525const IDENT_RE = '[a-zA-Z]\\w*';526const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*';527const NUMBER_RE = '\\b\\d+(\\.\\d+)?';528const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float529const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...530const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';531 532/**533* @param { Partial<Mode> & {binary?: string | RegExp} } opts534*/535const SHEBANG = (opts = {}) => {536  const beginShebang = /^#![ ]*\//;537  if (opts.binary) {538    opts.begin = concat(539      beginShebang,540      /.*\b/,541      opts.binary,542      /\b.*/);543  }544  return inherit$1({545    scope: 'meta',546    begin: beginShebang,547    end: /$/,548    relevance: 0,549    /** @type {ModeCallback} */550    "on:begin": (m, resp) => {551      if (m.index !== 0) resp.ignoreMatch();552    }553  }, opts);554};555 556// Common modes557const BACKSLASH_ESCAPE = {558  begin: '\\\\[\\s\\S]', relevance: 0559};560const APOS_STRING_MODE = {561  scope: 'string',562  begin: '\'',563  end: '\'',564  illegal: '\\n',565  contains: [BACKSLASH_ESCAPE]566};567const QUOTE_STRING_MODE = {568  scope: 'string',569  begin: '"',570  end: '"',571  illegal: '\\n',572  contains: [BACKSLASH_ESCAPE]573};574const PHRASAL_WORDS_MODE = {575  begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/576};577/**578 * Creates a comment mode579 *580 * @param {string | RegExp} begin581 * @param {string | RegExp} end582 * @param {Mode | {}} [modeOptions]583 * @returns {Partial<Mode>}584 */585const COMMENT = function(begin, end, modeOptions = {}) {586  const mode = inherit$1(587    {588      scope: 'comment',589      begin,590      end,591      contains: []592    },593    modeOptions594  );595  mode.contains.push({596    scope: 'doctag',597    // hack to avoid the space from being included. the space is necessary to598    // match here to prevent the plain text rule below from gobbling up doctags599    begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',600    end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,601    excludeBegin: true,602    relevance: 0603  });604  const ENGLISH_WORD = either(605    // list of common 1 and 2 letter words in English606    "I",607    "a",608    "is",609    "so",610    "us",611    "to",612    "at",613    "if",614    "in",615    "it",616    "on",617    // note: this is not an exhaustive list of contractions, just popular ones618    /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc619    /[A-Za-z]+[-][a-z]+/, // `no-way`, etc.620    /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences621  );622  // looking like plain text, more likely to be a comment623  mode.contains.push(624    {625      // TODO: how to include ", (, ) without breaking grammars that use these for626      // comment delimiters?627      // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/628      // ---629 630      // this tries to find sequences of 3 english words in a row (without any631      // "programming" type syntax) this gives us a strong signal that we've632      // TRULY found a comment - vs perhaps scanning with the wrong language.633      // It's possible to find something that LOOKS like the start of the634      // comment - but then if there is no readable text - good chance it is a635      // false match and not a comment.636      //637      // for a visual example please see:638      // https://github.com/highlightjs/highlight.js/issues/2827639 640      begin: concat(641        /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */642        '(',643        ENGLISH_WORD,644        /[.]?[:]?([.][ ]|[ ])/,645        '){3}') // look for 3 words in a row646    }647  );648  return mode;649};650const C_LINE_COMMENT_MODE = COMMENT('//', '$');651const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/');652const HASH_COMMENT_MODE = COMMENT('#', '$');653const NUMBER_MODE = {654  scope: 'number',655  begin: NUMBER_RE,656  relevance: 0657};658const C_NUMBER_MODE = {659  scope: 'number',660  begin: C_NUMBER_RE,661  relevance: 0662};663const BINARY_NUMBER_MODE = {664  scope: 'number',665  begin: BINARY_NUMBER_RE,666  relevance: 0667};668const REGEXP_MODE = {669  scope: "regexp",670  begin: /\/(?=[^/\n]*\/)/,671  end: /\/[gimuy]*/,672  contains: [673    BACKSLASH_ESCAPE,674    {675      begin: /\[/,676      end: /\]/,677      relevance: 0,678      contains: [BACKSLASH_ESCAPE]679    }680  ]681};682const TITLE_MODE = {683  scope: 'title',684  begin: IDENT_RE,685  relevance: 0686};687const UNDERSCORE_TITLE_MODE = {688  scope: 'title',689  begin: UNDERSCORE_IDENT_RE,690  relevance: 0691};692const METHOD_GUARD = {693  // excludes method names from keyword processing694  begin: '\\.\\s*' + UNDERSCORE_IDENT_RE,695  relevance: 0696};697 698/**699 * Adds end same as begin mechanics to a mode700 *701 * Your mode must include at least a single () match group as that first match702 * group is what is used for comparison703 * @param {Partial<Mode>} mode704 */705const END_SAME_AS_BEGIN = function(mode) {706  return Object.assign(mode,707    {708      /** @type {ModeCallback} */709      'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },710      /** @type {ModeCallback} */711      'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }712    });713};714 715var MODES = /*#__PURE__*/Object.freeze({716  __proto__: null,717  APOS_STRING_MODE: APOS_STRING_MODE,718  BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,719  BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,720  BINARY_NUMBER_RE: BINARY_NUMBER_RE,721  COMMENT: COMMENT,722  C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,723  C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,724  C_NUMBER_MODE: C_NUMBER_MODE,725  C_NUMBER_RE: C_NUMBER_RE,726  END_SAME_AS_BEGIN: END_SAME_AS_BEGIN,727  HASH_COMMENT_MODE: HASH_COMMENT_MODE,728  IDENT_RE: IDENT_RE,729  MATCH_NOTHING_RE: MATCH_NOTHING_RE,730  METHOD_GUARD: METHOD_GUARD,731  NUMBER_MODE: NUMBER_MODE,732  NUMBER_RE: NUMBER_RE,733  PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,734  QUOTE_STRING_MODE: QUOTE_STRING_MODE,735  REGEXP_MODE: REGEXP_MODE,736  RE_STARTERS_RE: RE_STARTERS_RE,737  SHEBANG: SHEBANG,738  TITLE_MODE: TITLE_MODE,739  UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,740  UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE741});742 743/**744@typedef {import('highlight.js').CallbackResponse} CallbackResponse745@typedef {import('highlight.js').CompilerExt} CompilerExt746*/747 748// Grammar extensions / plugins749// See: https://github.com/highlightjs/highlight.js/issues/2833750 751// Grammar extensions allow "syntactic sugar" to be added to the grammar modes752// without requiring any underlying changes to the compiler internals.753 754// `compileMatch` being the perfect small example of now allowing a grammar755// author to write `match` when they desire to match a single expression rather756// than being forced to use `begin`.  The extension then just moves `match` into757// `begin` when it runs.  Ie, no features have been added, but we've just made758// the experience of writing (and reading grammars) a little bit nicer.759 760// ------761 762// TODO: We need negative look-behind support to do this properly763/**764 * Skip a match if it has a preceding dot765 *766 * This is used for `beginKeywords` to prevent matching expressions such as767 * `bob.keyword.do()`. The mode compiler automatically wires this up as a768 * special _internal_ 'on:begin' callback for modes with `beginKeywords`769 * @param {RegExpMatchArray} match770 * @param {CallbackResponse} response771 */772function skipIfHasPrecedingDot(match, response) {773  const before = match.input[match.index - 1];774  if (before === ".") {775    response.ignoreMatch();776  }777}778 779/**780 *781 * @type {CompilerExt}782 */783function scopeClassName(mode, _parent) {784  // eslint-disable-next-line no-undefined785  if (mode.className !== undefined) {786    mode.scope = mode.className;787    delete mode.className;788  }789}790 791/**792 * `beginKeywords` syntactic sugar793 * @type {CompilerExt}794 */795function beginKeywords(mode, parent) {796  if (!parent) return;797  if (!mode.beginKeywords) return;798 799  // for languages with keywords that include non-word characters checking for800  // a word boundary is not sufficient, so instead we check for a word boundary801  // or whitespace - this does no harm in any case since our keyword engine802  // doesn't allow spaces in keywords anyways and we still check for the boundary803  // first804  mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)';805  mode.__beforeBegin = skipIfHasPrecedingDot;806  mode.keywords = mode.keywords || mode.beginKeywords;807  delete mode.beginKeywords;808 809  // prevents double relevance, the keywords themselves provide810  // relevance, the mode doesn't need to double it811  // eslint-disable-next-line no-undefined812  if (mode.relevance === undefined) mode.relevance = 0;813}814 815/**816 * Allow `illegal` to contain an array of illegal values817 * @type {CompilerExt}818 */819function compileIllegal(mode, _parent) {820  if (!Array.isArray(mode.illegal)) return;821 822  mode.illegal = either(...mode.illegal);823}824 825/**826 * `match` to match a single expression for readability827 * @type {CompilerExt}828 */829function compileMatch(mode, _parent) {830  if (!mode.match) return;831  if (mode.begin || mode.end) throw new Error("begin & end are not supported with match");832 833  mode.begin = mode.match;834  delete mode.match;835}836 837/**838 * provides the default 1 relevance to all modes839 * @type {CompilerExt}840 */841function compileRelevance(mode, _parent) {842  // eslint-disable-next-line no-undefined843  if (mode.relevance === undefined) mode.relevance = 1;844}845 846// allow beforeMatch to act as a "qualifier" for the match847// the full match begin must be [beforeMatch][begin]848const beforeMatchExt = (mode, parent) => {849  if (!mode.beforeMatch) return;850  // starts conflicts with endsParent which we need to make sure the child851  // rule is not matched multiple times852  if (mode.starts) throw new Error("beforeMatch cannot be used with starts");853 854  const originalMode = Object.assign({}, mode);855  Object.keys(mode).forEach((key) => { delete mode[key]; });856 857  mode.keywords = originalMode.keywords;858  mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));859  mode.starts = {860    relevance: 0,861    contains: [862      Object.assign(originalMode, { endsParent: true })863    ]864  };865  mode.relevance = 0;866 867  delete originalMode.beforeMatch;868};869 870// keywords that should have no default relevance value871const COMMON_KEYWORDS = [872  'of',873  'and',874  'for',875  'in',876  'not',877  'or',878  'if',879  'then',880  'parent', // common variable name881  'list', // common variable name882  'value' // common variable name883];884 885const DEFAULT_KEYWORD_SCOPE = "keyword";886 887/**888 * Given raw keywords from a language definition, compile them.889 *890 * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords891 * @param {boolean} caseInsensitive892 */893function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {894  /** @type {import("highlight.js/private").KeywordDict} */895  const compiledKeywords = Object.create(null);896 897  // input can be a string of keywords, an array of keywords, or a object with898  // named keys representing scopeName (which can then point to a string or array)899  if (typeof rawKeywords === 'string') {900    compileList(scopeName, rawKeywords.split(" "));901  } else if (Array.isArray(rawKeywords)) {902    compileList(scopeName, rawKeywords);903  } else {904    Object.keys(rawKeywords).forEach(function(scopeName) {905      // collapse all our objects back into the parent object906      Object.assign(907        compiledKeywords,908        compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)909      );910    });911  }912  return compiledKeywords;913 914  // ---915 916  /**917   * Compiles an individual list of keywords918   *919   * Ex: "for if when while|5"920   *921   * @param {string} scopeName922   * @param {Array<string>} keywordList923   */924  function compileList(scopeName, keywordList) {925    if (caseInsensitive) {926      keywordList = keywordList.map(x => x.toLowerCase());927    }928    keywordList.forEach(function(keyword) {929      const pair = keyword.split('|');930      compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];931    });932  }933}934 935/**936 * Returns the proper score for a given keyword937 *938 * Also takes into account comment keywords, which will be scored 0 UNLESS939 * another score has been manually assigned.940 * @param {string} keyword941 * @param {string} [providedScore]942 */943function scoreForKeyword(keyword, providedScore) {944  // manual scores always win over common keywords945  // so you can force a score of 1 if you really insist946  if (providedScore) {947    return Number(providedScore);948  }949 950  return commonKeyword(keyword) ? 0 : 1;951}952 953/**954 * Determines if a given keyword is common or not955 *956 * @param {string} keyword */957function commonKeyword(keyword) {958  return COMMON_KEYWORDS.includes(keyword.toLowerCase());959}960 961/*962 963For the reasoning behind this please see:964https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419965 966*/967 968/**969 * @type {Record<string, boolean>}970 */971const seenDeprecations = {};972 973/**974 * @param {string} message975 */976const error = (message) => {977  console.error(message);978};979 980/**981 * @param {string} message982 * @param {any} args983 */984const warn = (message, ...args) => {985  console.log(`WARN: ${message}`, ...args);986};987 988/**989 * @param {string} version990 * @param {string} message991 */992const deprecated = (version, message) => {993  if (seenDeprecations[`${version}/${message}`]) return;994 995  console.log(`Deprecated as of ${version}. ${message}`);996  seenDeprecations[`${version}/${message}`] = true;997};998 999/* eslint-disable no-throw-literal */1000 1001/**1002@typedef {import('highlight.js').CompiledMode} CompiledMode1003*/1004 1005const MultiClassError = new Error();1006 1007/**1008 * Renumbers labeled scope names to account for additional inner match1009 * groups that otherwise would break everything.1010 *1011 * Lets say we 3 match scopes:1012 *1013 *   { 1 => ..., 2 => ..., 3 => ... }1014 *1015 * So what we need is a clean match like this:1016 *1017 *   (a)(b)(c) => [ "a", "b", "c" ]1018 *1019 * But this falls apart with inner match groups:1020 *1021 * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ]1022 *1023 * Our scopes are now "out of alignment" and we're repeating `b` 3 times.1024 * What needs to happen is the numbers are remapped:1025 *1026 *   { 1 => ..., 2 => ..., 5 => ... }1027 *1028 * We also need to know that the ONLY groups that should be output1029 * are 1, 2, and 5.  This function handles this behavior.1030 *1031 * @param {CompiledMode} mode1032 * @param {Array<RegExp | string>} regexes1033 * @param {{key: "beginScope"|"endScope"}} opts1034 */1035function remapScopeNames(mode, regexes, { key }) {1036  let offset = 0;1037  const scopeNames = mode[key];1038  /** @type Record<number,boolean> */1039  const emit = {};1040  /** @type Record<number,string> */1041  const positions = {};1042 1043  for (let i = 1; i <= regexes.length; i++) {1044    positions[i + offset] = scopeNames[i];1045    emit[i + offset] = true;1046    offset += countMatchGroups(regexes[i - 1]);1047  }1048  // we use _emit to keep track of which match groups are "top-level" to avoid double1049  // output from inside match groups1050  mode[key] = positions;1051  mode[key]._emit = emit;1052  mode[key]._multi = true;1053}1054 1055/**1056 * @param {CompiledMode} mode1057 */1058function beginMultiClass(mode) {1059  if (!Array.isArray(mode.begin)) return;1060 1061  if (mode.skip || mode.excludeBegin || mode.returnBegin) {1062    error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");1063    throw MultiClassError;1064  }1065 1066  if (typeof mode.beginScope !== "object" || mode.beginScope === null) {1067    error("beginScope must be object");1068    throw MultiClassError;1069  }1070 1071  remapScopeNames(mode, mode.begin, { key: "beginScope" });1072  mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" });1073}1074 1075/**1076 * @param {CompiledMode} mode1077 */1078function endMultiClass(mode) {1079  if (!Array.isArray(mode.end)) return;1080 1081  if (mode.skip || mode.excludeEnd || mode.returnEnd) {1082    error("skip, excludeEnd, returnEnd not compatible with endScope: {}");1083    throw MultiClassError;1084  }1085 1086  if (typeof mode.endScope !== "object" || mode.endScope === null) {1087    error("endScope must be object");1088    throw MultiClassError;1089  }1090 1091  remapScopeNames(mode, mode.end, { key: "endScope" });1092  mode.end = _rewriteBackreferences(mode.end, { joinWith: "" });1093}1094 1095/**1096 * this exists only to allow `scope: {}` to be used beside `match:`1097 * Otherwise `beginScope` would necessary and that would look weird1098 1099  {1100    match: [ /def/, /\w+/ ]1101    scope: { 1: "keyword" , 2: "title" }1102  }1103 1104 * @param {CompiledMode} mode1105 */1106function scopeSugar(mode) {1107  if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {1108    mode.beginScope = mode.scope;1109    delete mode.scope;1110  }1111}1112 1113/**1114 * @param {CompiledMode} mode1115 */1116function MultiClass(mode) {1117  scopeSugar(mode);1118 1119  if (typeof mode.beginScope === "string") {1120    mode.beginScope = { _wrap: mode.beginScope };1121  }1122  if (typeof mode.endScope === "string") {1123    mode.endScope = { _wrap: mode.endScope };1124  }1125 1126  beginMultiClass(mode);1127  endMultiClass(mode);1128}1129 1130/**1131@typedef {import('highlight.js').Mode} Mode1132@typedef {import('highlight.js').CompiledMode} CompiledMode1133@typedef {import('highlight.js').Language} Language1134@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin1135@typedef {import('highlight.js').CompiledLanguage} CompiledLanguage1136*/1137 1138// compilation1139 1140/**1141 * Compiles a language definition result1142 *1143 * Given the raw result of a language definition (Language), compiles this so1144 * that it is ready for highlighting code.1145 * @param {Language} language1146 * @returns {CompiledLanguage}1147 */1148function compileLanguage(language) {1149  /**1150   * Builds a regex with the case sensitivity of the current language1151   *1152   * @param {RegExp | string} value1153   * @param {boolean} [global]1154   */1155  function langRe(value, global) {1156    return new RegExp(1157      source(value),1158      'm'1159      + (language.case_insensitive ? 'i' : '')1160      + (language.unicodeRegex ? 'u' : '')1161      + (global ? 'g' : '')1162    );1163  }1164 1165  /**1166    Stores multiple regular expressions and allows you to quickly search for1167    them all in a string simultaneously - returning the first match.  It does1168    this by creating a huge (a|b|c) regex - each individual item wrapped with ()1169    and joined by `|` - using match groups to track position.  When a match is1170    found checking which position in the array has content allows us to figure1171    out which of the original regexes / match groups triggered the match.1172 1173    The match object itself (the result of `Regex.exec`) is returned but also1174    enhanced by merging in any meta-data that was registered with the regex.1175    This is how we keep track of which mode matched, and what type of rule1176    (`illegal`, `begin`, end, etc).1177  */1178  class MultiRegex {1179    constructor() {1180      this.matchIndexes = {};1181      // @ts-ignore1182      this.regexes = [];1183      this.matchAt = 1;1184      this.position = 0;1185    }1186 1187    // @ts-ignore1188    addRule(re, opts) {1189      opts.position = this.position++;1190      // @ts-ignore1191      this.matchIndexes[this.matchAt] = opts;1192      this.regexes.push([opts, re]);1193      this.matchAt += countMatchGroups(re) + 1;1194    }1195 1196    compile() {1197      if (this.regexes.length === 0) {1198        // avoids the need to check length every time exec is called1199        // @ts-ignore1200        this.exec = () => null;

Showing the first 1,200 of 2598 lines. Download the file for the rest.

basant307/AI_Governance_Project · CoolFace