index.cjs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var common = require('@lezer/common');
  4. let nextTagID = 0;
  5. /// Highlighting tags are markers that denote a highlighting category.
  6. /// They are [associated](#highlight.styleTags) with parts of a syntax
  7. /// tree by a language mode, and then mapped to an actual CSS style by
  8. /// a [highlighter](#highlight.Highlighter).
  9. ///
  10. /// Because syntax tree node types and highlight styles have to be
  11. /// able to talk the same language, CodeMirror uses a mostly _closed_
  12. /// [vocabulary](#highlight.tags) of syntax tags (as opposed to
  13. /// traditional open string-based systems, which make it hard for
  14. /// highlighting themes to cover all the tokens produced by the
  15. /// various languages).
  16. ///
  17. /// It _is_ possible to [define](#highlight.Tag^define) your own
  18. /// highlighting tags for system-internal use (where you control both
  19. /// the language package and the highlighter), but such tags will not
  20. /// be picked up by regular highlighters (though you can derive them
  21. /// from standard tags to allow highlighters to fall back to those).
  22. class Tag {
  23. /// @internal
  24. constructor(
  25. /// The set of this tag and all its parent tags, starting with
  26. /// this one itself and sorted in order of decreasing specificity.
  27. set,
  28. /// The base unmodified tag that this one is based on, if it's
  29. /// modified @internal
  30. base,
  31. /// The modifiers applied to this.base @internal
  32. modified) {
  33. this.set = set;
  34. this.base = base;
  35. this.modified = modified;
  36. /// @internal
  37. this.id = nextTagID++;
  38. }
  39. /// Define a new tag. If `parent` is given, the tag is treated as a
  40. /// sub-tag of that parent, and
  41. /// [highlighters](#highlight.tagHighlighter) that don't mention
  42. /// this tag will try to fall back to the parent tag (or grandparent
  43. /// tag, etc).
  44. static define(parent) {
  45. if (parent === null || parent === void 0 ? void 0 : parent.base)
  46. throw new Error("Can not derive from a modified tag");
  47. let tag = new Tag([], null, []);
  48. tag.set.push(tag);
  49. if (parent)
  50. for (let t of parent.set)
  51. tag.set.push(t);
  52. return tag;
  53. }
  54. /// Define a tag _modifier_, which is a function that, given a tag,
  55. /// will return a tag that is a subtag of the original. Applying the
  56. /// same modifier to a twice tag will return the same value (`m1(t1)
  57. /// == m1(t1)`) and applying multiple modifiers will, regardless or
  58. /// order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
  59. ///
  60. /// When multiple modifiers are applied to a given base tag, each
  61. /// smaller set of modifiers is registered as a parent, so that for
  62. /// example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
  63. /// `m1(m3(t1)`, and so on.
  64. static defineModifier() {
  65. let mod = new Modifier;
  66. return (tag) => {
  67. if (tag.modified.indexOf(mod) > -1)
  68. return tag;
  69. return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a, b) => a.id - b.id));
  70. };
  71. }
  72. }
  73. let nextModifierID = 0;
  74. class Modifier {
  75. constructor() {
  76. this.instances = [];
  77. this.id = nextModifierID++;
  78. }
  79. static get(base, mods) {
  80. if (!mods.length)
  81. return base;
  82. let exists = mods[0].instances.find(t => t.base == base && sameArray(mods, t.modified));
  83. if (exists)
  84. return exists;
  85. let set = [], tag = new Tag(set, base, mods);
  86. for (let m of mods)
  87. m.instances.push(tag);
  88. let configs = permute(mods);
  89. for (let parent of base.set)
  90. for (let config of configs)
  91. set.push(Modifier.get(parent, config));
  92. return tag;
  93. }
  94. }
  95. function sameArray(a, b) {
  96. return a.length == b.length && a.every((x, i) => x == b[i]);
  97. }
  98. function permute(array) {
  99. let result = [array];
  100. for (let i = 0; i < array.length; i++) {
  101. for (let a of permute(array.slice(0, i).concat(array.slice(i + 1))))
  102. result.push(a);
  103. }
  104. return result;
  105. }
  106. /// This function is used to add a set of tags to a language syntax
  107. /// via [`NodeSet.extend`](#common.NodeSet.extend) or
  108. /// [`LRParser.configure`](#lr.LRParser.configure).
  109. ///
  110. /// The argument object maps node selectors to [highlighting
  111. /// tags](#highlight.Tag) or arrays of tags.
  112. ///
  113. /// Node selectors may hold one or more (space-separated) node paths.
  114. /// Such a path can be a [node name](#common.NodeType.name), or
  115. /// multiple node names (or `*` wildcards) separated by slash
  116. /// characters, as in `"Block/Declaration/VariableName"`. Such a path
  117. /// matches the final node but only if its direct parent nodes are the
  118. /// other nodes mentioned. A `*` in such a path matches any parent,
  119. /// but only a single level—wildcards that match multiple parents
  120. /// aren't supported, both for efficiency reasons and because Lezer
  121. /// trees make it rather hard to reason about what they would match.)
  122. ///
  123. /// A path can be ended with `/...` to indicate that the tag assigned
  124. /// to the node should also apply to all child nodes, even if they
  125. /// match their own style (by default, only the innermost style is
  126. /// used).
  127. ///
  128. /// When a path ends in `!`, as in `Attribute!`, no further matching
  129. /// happens for the node's child nodes, and the entire node gets the
  130. /// given style.
  131. ///
  132. /// In this notation, node names that contain `/`, `!`, `*`, or `...`
  133. /// must be quoted as JSON strings.
  134. ///
  135. /// For example:
  136. ///
  137. /// ```javascript
  138. /// parser.withProps(
  139. /// styleTags({
  140. /// // Style Number and BigNumber nodes
  141. /// "Number BigNumber": tags.number,
  142. /// // Style Escape nodes whose parent is String
  143. /// "String/Escape": tags.escape,
  144. /// // Style anything inside Attributes nodes
  145. /// "Attributes!": tags.meta,
  146. /// // Add a style to all content inside Italic nodes
  147. /// "Italic/...": tags.emphasis,
  148. /// // Style InvalidString nodes as both `string` and `invalid`
  149. /// "InvalidString": [tags.string, tags.invalid],
  150. /// // Style the node named "/" as punctuation
  151. /// '"/"': tags.punctuation
  152. /// })
  153. /// )
  154. /// ```
  155. function styleTags(spec) {
  156. let byName = Object.create(null);
  157. for (let prop in spec) {
  158. let tags = spec[prop];
  159. if (!Array.isArray(tags))
  160. tags = [tags];
  161. for (let part of prop.split(" "))
  162. if (part) {
  163. let pieces = [], mode = 2 /* Normal */, rest = part;
  164. for (let pos = 0;;) {
  165. if (rest == "..." && pos > 0 && pos + 3 == part.length) {
  166. mode = 1 /* Inherit */;
  167. break;
  168. }
  169. let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
  170. if (!m)
  171. throw new RangeError("Invalid path: " + part);
  172. pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]);
  173. pos += m[0].length;
  174. if (pos == part.length)
  175. break;
  176. let next = part[pos++];
  177. if (pos == part.length && next == "!") {
  178. mode = 0 /* Opaque */;
  179. break;
  180. }
  181. if (next != "/")
  182. throw new RangeError("Invalid path: " + part);
  183. rest = part.slice(pos);
  184. }
  185. let last = pieces.length - 1, inner = pieces[last];
  186. if (!inner)
  187. throw new RangeError("Invalid path: " + part);
  188. let rule = new Rule(tags, mode, last > 0 ? pieces.slice(0, last) : null);
  189. byName[inner] = rule.sort(byName[inner]);
  190. }
  191. }
  192. return ruleNodeProp.add(byName);
  193. }
  194. const ruleNodeProp = new common.NodeProp();
  195. class Rule {
  196. constructor(tags, mode, context, next) {
  197. this.tags = tags;
  198. this.mode = mode;
  199. this.context = context;
  200. this.next = next;
  201. }
  202. sort(other) {
  203. if (!other || other.depth < this.depth) {
  204. this.next = other;
  205. return this;
  206. }
  207. other.next = this.sort(other.next);
  208. return other;
  209. }
  210. get depth() { return this.context ? this.context.length : 0; }
  211. }
  212. /// Define a [highlighter](#highlight.Highlighter) from an array of
  213. /// tag/class pairs. Classes associated with more specific tags will
  214. /// take precedence.
  215. function tagHighlighter(tags, options) {
  216. let map = Object.create(null);
  217. for (let style of tags) {
  218. if (!Array.isArray(style.tag))
  219. map[style.tag.id] = style.class;
  220. else
  221. for (let tag of style.tag)
  222. map[tag.id] = style.class;
  223. }
  224. let { scope, all = null } = options || {};
  225. return {
  226. style: (tags) => {
  227. let cls = all;
  228. for (let tag of tags) {
  229. for (let sub of tag.set) {
  230. let tagClass = map[sub.id];
  231. if (tagClass) {
  232. cls = cls ? cls + " " + tagClass : tagClass;
  233. break;
  234. }
  235. }
  236. }
  237. return cls;
  238. },
  239. scope: scope
  240. };
  241. }
  242. function highlightTags(highlighters, tags) {
  243. let result = null;
  244. for (let highlighter of highlighters) {
  245. let value = highlighter.style(tags);
  246. if (value)
  247. result = result ? result + " " + value : value;
  248. }
  249. return result;
  250. }
  251. /// Highlight the given [tree](#common.Tree) with the given
  252. /// [highlighter](#highlight.Highlighter).
  253. function highlightTree(tree, highlighter,
  254. /// Assign styling to a region of the text. Will be called, in order
  255. /// of position, for any ranges where more than zero classes apply.
  256. /// `classes` is a space separated string of CSS classes.
  257. putStyle,
  258. /// The start of the range to highlight.
  259. from = 0,
  260. /// The end of the range.
  261. to = tree.length) {
  262. let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle);
  263. builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters);
  264. builder.flush(to);
  265. }
  266. class HighlightBuilder {
  267. constructor(at, highlighters, span) {
  268. this.at = at;
  269. this.highlighters = highlighters;
  270. this.span = span;
  271. this.class = "";
  272. }
  273. startSpan(at, cls) {
  274. if (cls != this.class) {
  275. this.flush(at);
  276. if (at > this.at)
  277. this.at = at;
  278. this.class = cls;
  279. }
  280. }
  281. flush(to) {
  282. if (to > this.at && this.class)
  283. this.span(this.at, to, this.class);
  284. }
  285. highlightRange(cursor, from, to, inheritedClass, highlighters) {
  286. let { type, from: start, to: end } = cursor;
  287. if (start >= to || end <= from)
  288. return;
  289. if (type.isTop)
  290. highlighters = this.highlighters.filter(h => !h.scope || h.scope(type));
  291. let cls = inheritedClass;
  292. let rule = type.prop(ruleNodeProp), opaque = false;
  293. while (rule) {
  294. if (!rule.context || cursor.matchContext(rule.context)) {
  295. let tagCls = highlightTags(highlighters, rule.tags);
  296. if (tagCls) {
  297. if (cls)
  298. cls += " ";
  299. cls += tagCls;
  300. if (rule.mode == 1 /* Inherit */)
  301. inheritedClass += (inheritedClass ? " " : "") + tagCls;
  302. else if (rule.mode == 0 /* Opaque */)
  303. opaque = true;
  304. }
  305. break;
  306. }
  307. rule = rule.next;
  308. }
  309. this.startSpan(cursor.from, cls);
  310. if (opaque)
  311. return;
  312. let mounted = cursor.tree && cursor.tree.prop(common.NodeProp.mounted);
  313. if (mounted && mounted.overlay) {
  314. let inner = cursor.node.enter(mounted.overlay[0].from + start, 1);
  315. let innerHighlighters = this.highlighters.filter(h => !h.scope || h.scope(mounted.tree.type));
  316. let hasChild = cursor.firstChild();
  317. for (let i = 0, pos = start;; i++) {
  318. let next = i < mounted.overlay.length ? mounted.overlay[i] : null;
  319. let nextPos = next ? next.from + start : end;
  320. let rangeFrom = Math.max(from, pos), rangeTo = Math.min(to, nextPos);
  321. if (rangeFrom < rangeTo && hasChild) {
  322. while (cursor.from < rangeTo) {
  323. this.highlightRange(cursor, rangeFrom, rangeTo, inheritedClass, highlighters);
  324. this.startSpan(Math.min(to, cursor.to), cls);
  325. if (cursor.to >= nextPos || !cursor.nextSibling())
  326. break;
  327. }
  328. }
  329. if (!next || nextPos > to)
  330. break;
  331. pos = next.to + start;
  332. if (pos > from) {
  333. this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), inheritedClass, innerHighlighters);
  334. this.startSpan(pos, cls);
  335. }
  336. }
  337. if (hasChild)
  338. cursor.parent();
  339. }
  340. else if (cursor.firstChild()) {
  341. do {
  342. if (cursor.to <= from)
  343. continue;
  344. if (cursor.from >= to)
  345. break;
  346. this.highlightRange(cursor, from, to, inheritedClass, highlighters);
  347. this.startSpan(Math.min(to, cursor.to), cls);
  348. } while (cursor.nextSibling());
  349. cursor.parent();
  350. }
  351. }
  352. }
  353. const t = Tag.define;
  354. const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t();
  355. /// The default set of highlighting [tags](#highlight.Tag).
  356. ///
  357. /// This collection is heavily biased towards programming languages,
  358. /// and necessarily incomplete. A full ontology of syntactic
  359. /// constructs would fill a stack of books, and be impractical to
  360. /// write themes for. So try to make do with this set. If all else
  361. /// fails, [open an
  362. /// issue](https://github.com/codemirror/codemirror.next) to propose a
  363. /// new tag, or [define](#highlight.Tag^define) a local custom tag for
  364. /// your use case.
  365. ///
  366. /// Note that it is not obligatory to always attach the most specific
  367. /// tag possible to an element—if your grammar can't easily
  368. /// distinguish a certain type of element (such as a local variable),
  369. /// it is okay to style it as its more general variant (a variable).
  370. ///
  371. /// For tags that extend some parent tag, the documentation links to
  372. /// the parent.
  373. const tags = {
  374. /// A comment.
  375. comment,
  376. /// A line [comment](#highlight.tags.comment).
  377. lineComment: t(comment),
  378. /// A block [comment](#highlight.tags.comment).
  379. blockComment: t(comment),
  380. /// A documentation [comment](#highlight.tags.comment).
  381. docComment: t(comment),
  382. /// Any kind of identifier.
  383. name,
  384. /// The [name](#highlight.tags.name) of a variable.
  385. variableName: t(name),
  386. /// A type [name](#highlight.tags.name).
  387. typeName: typeName,
  388. /// A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
  389. tagName: t(typeName),
  390. /// A property or field [name](#highlight.tags.name).
  391. propertyName: propertyName,
  392. /// An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
  393. attributeName: t(propertyName),
  394. /// The [name](#highlight.tags.name) of a class.
  395. className: t(name),
  396. /// A label [name](#highlight.tags.name).
  397. labelName: t(name),
  398. /// A namespace [name](#highlight.tags.name).
  399. namespace: t(name),
  400. /// The [name](#highlight.tags.name) of a macro.
  401. macroName: t(name),
  402. /// A literal value.
  403. literal,
  404. /// A string [literal](#highlight.tags.literal).
  405. string,
  406. /// A documentation [string](#highlight.tags.string).
  407. docString: t(string),
  408. /// A character literal (subtag of [string](#highlight.tags.string)).
  409. character: t(string),
  410. /// An attribute value (subtag of [string](#highlight.tags.string)).
  411. attributeValue: t(string),
  412. /// A number [literal](#highlight.tags.literal).
  413. number,
  414. /// An integer [number](#highlight.tags.number) literal.
  415. integer: t(number),
  416. /// A floating-point [number](#highlight.tags.number) literal.
  417. float: t(number),
  418. /// A boolean [literal](#highlight.tags.literal).
  419. bool: t(literal),
  420. /// Regular expression [literal](#highlight.tags.literal).
  421. regexp: t(literal),
  422. /// An escape [literal](#highlight.tags.literal), for example a
  423. /// backslash escape in a string.
  424. escape: t(literal),
  425. /// A color [literal](#highlight.tags.literal).
  426. color: t(literal),
  427. /// A URL [literal](#highlight.tags.literal).
  428. url: t(literal),
  429. /// A language keyword.
  430. keyword,
  431. /// The [keyword](#highlight.tags.keyword) for the self or this
  432. /// object.
  433. self: t(keyword),
  434. /// The [keyword](#highlight.tags.keyword) for null.
  435. null: t(keyword),
  436. /// A [keyword](#highlight.tags.keyword) denoting some atomic value.
  437. atom: t(keyword),
  438. /// A [keyword](#highlight.tags.keyword) that represents a unit.
  439. unit: t(keyword),
  440. /// A modifier [keyword](#highlight.tags.keyword).
  441. modifier: t(keyword),
  442. /// A [keyword](#highlight.tags.keyword) that acts as an operator.
  443. operatorKeyword: t(keyword),
  444. /// A control-flow related [keyword](#highlight.tags.keyword).
  445. controlKeyword: t(keyword),
  446. /// A [keyword](#highlight.tags.keyword) that defines something.
  447. definitionKeyword: t(keyword),
  448. /// A [keyword](#highlight.tags.keyword) related to defining or
  449. /// interfacing with modules.
  450. moduleKeyword: t(keyword),
  451. /// An operator.
  452. operator,
  453. /// An [operator](#highlight.tags.operator) that defines something.
  454. derefOperator: t(operator),
  455. /// Arithmetic-related [operator](#highlight.tags.operator).
  456. arithmeticOperator: t(operator),
  457. /// Logical [operator](#highlight.tags.operator).
  458. logicOperator: t(operator),
  459. /// Bit [operator](#highlight.tags.operator).
  460. bitwiseOperator: t(operator),
  461. /// Comparison [operator](#highlight.tags.operator).
  462. compareOperator: t(operator),
  463. /// [Operator](#highlight.tags.operator) that updates its operand.
  464. updateOperator: t(operator),
  465. /// [Operator](#highlight.tags.operator) that defines something.
  466. definitionOperator: t(operator),
  467. /// Type-related [operator](#highlight.tags.operator).
  468. typeOperator: t(operator),
  469. /// Control-flow [operator](#highlight.tags.operator).
  470. controlOperator: t(operator),
  471. /// Program or markup punctuation.
  472. punctuation,
  473. /// [Punctuation](#highlight.tags.punctuation) that separates
  474. /// things.
  475. separator: t(punctuation),
  476. /// Bracket-style [punctuation](#highlight.tags.punctuation).
  477. bracket,
  478. /// Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
  479. /// tokens).
  480. angleBracket: t(bracket),
  481. /// Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
  482. /// tokens).
  483. squareBracket: t(bracket),
  484. /// Parentheses (usually `(` and `)` tokens). Subtag of
  485. /// [bracket](#highlight.tags.bracket).
  486. paren: t(bracket),
  487. /// Braces (usually `{` and `}` tokens). Subtag of
  488. /// [bracket](#highlight.tags.bracket).
  489. brace: t(bracket),
  490. /// Content, for example plain text in XML or markup documents.
  491. content,
  492. /// [Content](#highlight.tags.content) that represents a heading.
  493. heading,
  494. /// A level 1 [heading](#highlight.tags.heading).
  495. heading1: t(heading),
  496. /// A level 2 [heading](#highlight.tags.heading).
  497. heading2: t(heading),
  498. /// A level 3 [heading](#highlight.tags.heading).
  499. heading3: t(heading),
  500. /// A level 4 [heading](#highlight.tags.heading).
  501. heading4: t(heading),
  502. /// A level 5 [heading](#highlight.tags.heading).
  503. heading5: t(heading),
  504. /// A level 6 [heading](#highlight.tags.heading).
  505. heading6: t(heading),
  506. /// A prose separator (such as a horizontal rule).
  507. contentSeparator: t(content),
  508. /// [Content](#highlight.tags.content) that represents a list.
  509. list: t(content),
  510. /// [Content](#highlight.tags.content) that represents a quote.
  511. quote: t(content),
  512. /// [Content](#highlight.tags.content) that is emphasized.
  513. emphasis: t(content),
  514. /// [Content](#highlight.tags.content) that is styled strong.
  515. strong: t(content),
  516. /// [Content](#highlight.tags.content) that is part of a link.
  517. link: t(content),
  518. /// [Content](#highlight.tags.content) that is styled as code or
  519. /// monospace.
  520. monospace: t(content),
  521. /// [Content](#highlight.tags.content) that has a strike-through
  522. /// style.
  523. strikethrough: t(content),
  524. /// Inserted text in a change-tracking format.
  525. inserted: t(),
  526. /// Deleted text.
  527. deleted: t(),
  528. /// Changed text.
  529. changed: t(),
  530. /// An invalid or unsyntactic element.
  531. invalid: t(),
  532. /// Metadata or meta-instruction.
  533. meta,
  534. /// [Metadata](#highlight.tags.meta) that applies to the entire
  535. /// document.
  536. documentMeta: t(meta),
  537. /// [Metadata](#highlight.tags.meta) that annotates or adds
  538. /// attributes to a given syntactic element.
  539. annotation: t(meta),
  540. /// Processing instruction or preprocessor directive. Subtag of
  541. /// [meta](#highlight.tags.meta).
  542. processingInstruction: t(meta),
  543. /// [Modifier](#highlight.Tag^defineModifier) that indicates that a
  544. /// given element is being defined. Expected to be used with the
  545. /// various [name](#highlight.tags.name) tags.
  546. definition: Tag.defineModifier(),
  547. /// [Modifier](#highlight.Tag^defineModifier) that indicates that
  548. /// something is constant. Mostly expected to be used with
  549. /// [variable names](#highlight.tags.variableName).
  550. constant: Tag.defineModifier(),
  551. /// [Modifier](#highlight.Tag^defineModifier) used to indicate that
  552. /// a [variable](#highlight.tags.variableName) or [property
  553. /// name](#highlight.tags.propertyName) is being called or defined
  554. /// as a function.
  555. function: Tag.defineModifier(),
  556. /// [Modifier](#highlight.Tag^defineModifier) that can be applied to
  557. /// [names](#highlight.tags.name) to indicate that they belong to
  558. /// the language's standard environment.
  559. standard: Tag.defineModifier(),
  560. /// [Modifier](#highlight.Tag^defineModifier) that indicates a given
  561. /// [names](#highlight.tags.name) is local to some scope.
  562. local: Tag.defineModifier(),
  563. /// A generic variant [modifier](#highlight.Tag^defineModifier) that
  564. /// can be used to tag language-specific alternative variants of
  565. /// some common tag. It is recommended for themes to define special
  566. /// forms of at least the [string](#highlight.tags.string) and
  567. /// [variable name](#highlight.tags.variableName) tags, since those
  568. /// come up a lot.
  569. special: Tag.defineModifier()
  570. };
  571. /// This is a highlighter that adds stable, predictable classes to
  572. /// tokens, for styling with external CSS.
  573. ///
  574. /// The following tags are mapped to their name prefixed with `"tok-"`
  575. /// (for example `"tok-comment"`):
  576. ///
  577. /// * [`link`](#highlight.tags.link)
  578. /// * [`heading`](#highlight.tags.heading)
  579. /// * [`emphasis`](#highlight.tags.emphasis)
  580. /// * [`strong`](#highlight.tags.strong)
  581. /// * [`keyword`](#highlight.tags.keyword)
  582. /// * [`atom`](#highlight.tags.atom)
  583. /// * [`bool`](#highlight.tags.bool)
  584. /// * [`url`](#highlight.tags.url)
  585. /// * [`labelName`](#highlight.tags.labelName)
  586. /// * [`inserted`](#highlight.tags.inserted)
  587. /// * [`deleted`](#highlight.tags.deleted)
  588. /// * [`literal`](#highlight.tags.literal)
  589. /// * [`string`](#highlight.tags.string)
  590. /// * [`number`](#highlight.tags.number)
  591. /// * [`variableName`](#highlight.tags.variableName)
  592. /// * [`typeName`](#highlight.tags.typeName)
  593. /// * [`namespace`](#highlight.tags.namespace)
  594. /// * [`className`](#highlight.tags.className)
  595. /// * [`macroName`](#highlight.tags.macroName)
  596. /// * [`propertyName`](#highlight.tags.propertyName)
  597. /// * [`operator`](#highlight.tags.operator)
  598. /// * [`comment`](#highlight.tags.comment)
  599. /// * [`meta`](#highlight.tags.meta)
  600. /// * [`punctuation`](#highlight.tags.punctuation)
  601. /// * [`invalid`](#highlight.tags.invalid)
  602. ///
  603. /// In addition, these mappings are provided:
  604. ///
  605. /// * [`regexp`](#highlight.tags.regexp),
  606. /// [`escape`](#highlight.tags.escape), and
  607. /// [`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
  608. /// are mapped to `"tok-string2"`
  609. /// * [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
  610. /// to `"tok-variableName2"`
  611. /// * [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
  612. /// to `"tok-variableName tok-local"`
  613. /// * [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
  614. /// to `"tok-variableName tok-definition"`
  615. /// * [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
  616. /// to `"tok-propertyName tok-definition"`
  617. const classHighlighter = tagHighlighter([
  618. { tag: tags.link, class: "tok-link" },
  619. { tag: tags.heading, class: "tok-heading" },
  620. { tag: tags.emphasis, class: "tok-emphasis" },
  621. { tag: tags.strong, class: "tok-strong" },
  622. { tag: tags.keyword, class: "tok-keyword" },
  623. { tag: tags.atom, class: "tok-atom" },
  624. { tag: tags.bool, class: "tok-bool" },
  625. { tag: tags.url, class: "tok-url" },
  626. { tag: tags.labelName, class: "tok-labelName" },
  627. { tag: tags.inserted, class: "tok-inserted" },
  628. { tag: tags.deleted, class: "tok-deleted" },
  629. { tag: tags.literal, class: "tok-literal" },
  630. { tag: tags.string, class: "tok-string" },
  631. { tag: tags.number, class: "tok-number" },
  632. { tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" },
  633. { tag: tags.variableName, class: "tok-variableName" },
  634. { tag: tags.local(tags.variableName), class: "tok-variableName tok-local" },
  635. { tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" },
  636. { tag: tags.special(tags.variableName), class: "tok-variableName2" },
  637. { tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" },
  638. { tag: tags.typeName, class: "tok-typeName" },
  639. { tag: tags.namespace, class: "tok-namespace" },
  640. { tag: tags.className, class: "tok-className" },
  641. { tag: tags.macroName, class: "tok-macroName" },
  642. { tag: tags.propertyName, class: "tok-propertyName" },
  643. { tag: tags.operator, class: "tok-operator" },
  644. { tag: tags.comment, class: "tok-comment" },
  645. { tag: tags.meta, class: "tok-meta" },
  646. { tag: tags.invalid, class: "tok-invalid" },
  647. { tag: tags.punctuation, class: "tok-punctuation" }
  648. ]);
  649. exports.Tag = Tag;
  650. exports.classHighlighter = classHighlighter;
  651. exports.highlightTree = highlightTree;
  652. exports.styleTags = styleTags;
  653. exports.tagHighlighter = tagHighlighter;
  654. exports.tags = tags;