code-battles 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cjs/index.js +2150 -1952
  2. package/dist/cjs/styles.css +2 -1
  3. package/dist/cjs/types/components/DataTable.d.ts +21 -0
  4. package/dist/cjs/types/components/ResultStaticsTable.d.ts +3 -0
  5. package/dist/cjs/types/configuration.d.ts +0 -1
  6. package/dist/code_battles/battles.py +18 -2
  7. package/dist/code_battles/utilities.py +5 -1
  8. package/dist/esm/index.js +2151 -1953
  9. package/dist/esm/styles.css +2 -1
  10. package/dist/esm/types/components/DataTable.d.ts +21 -0
  11. package/dist/esm/types/components/ResultStaticsTable.d.ts +3 -0
  12. package/dist/esm/types/configuration.d.ts +0 -1
  13. package/dist/index.d.ts +0 -1
  14. package/dist/pyscript/codemirror-eKulCBrd.js +2 -0
  15. package/dist/pyscript/codemirror-eKulCBrd.js.map +1 -0
  16. package/dist/pyscript/codemirror_commands-BVu_0Pnj.js +2 -0
  17. package/dist/pyscript/codemirror_commands-BVu_0Pnj.js.map +1 -0
  18. package/dist/pyscript/codemirror_lang-python-a2LxSo5G.js +2 -0
  19. package/dist/pyscript/codemirror_lang-python-a2LxSo5G.js.map +1 -0
  20. package/dist/pyscript/codemirror_language-_2pXlKJ9.js +2 -0
  21. package/dist/pyscript/codemirror_language-_2pXlKJ9.js.map +1 -0
  22. package/dist/pyscript/codemirror_view-DMW9kQlJ.js +2 -0
  23. package/dist/pyscript/codemirror_view-DMW9kQlJ.js.map +1 -0
  24. package/dist/pyscript/core-DezwbZpG.js +4 -0
  25. package/dist/pyscript/core-DezwbZpG.js.map +1 -0
  26. package/dist/pyscript/core.js +1 -1
  27. package/dist/pyscript/deprecations-manager-B1bDno27.js +2 -0
  28. package/dist/pyscript/deprecations-manager-B1bDno27.js.map +1 -0
  29. package/dist/pyscript/donkey-DNl0ASkM.js +2 -0
  30. package/dist/pyscript/donkey-DNl0ASkM.js.map +1 -0
  31. package/dist/pyscript/error-DmRE4Y-7.js +2 -0
  32. package/dist/pyscript/error-DmRE4Y-7.js.map +1 -0
  33. package/dist/pyscript/index-DkgvWIf-.js +2 -0
  34. package/dist/pyscript/index-DkgvWIf-.js.map +1 -0
  35. package/dist/pyscript/mpy-BoY0tVRD.js +2 -0
  36. package/dist/pyscript/mpy-BoY0tVRD.js.map +1 -0
  37. package/dist/pyscript/py-DsQqgZuM.js +2 -0
  38. package/dist/pyscript/py-DsQqgZuM.js.map +1 -0
  39. package/dist/pyscript/py-editor-DZkG_or6.js +2 -0
  40. package/dist/pyscript/py-editor-DZkG_or6.js.map +1 -0
  41. package/dist/pyscript/py-game-D0Z4YnzZ.js +2 -0
  42. package/dist/pyscript/py-game-D0Z4YnzZ.js.map +1 -0
  43. package/dist/pyscript/py-terminal-DYHK7LJ0.js +2 -0
  44. package/dist/pyscript/py-terminal-DYHK7LJ0.js.map +1 -0
  45. package/dist/pyscript/service-worker.js +1 -0
  46. package/dist/pyscript/storage.js +1 -1
  47. package/dist/pyscript/storage.js.map +1 -1
  48. package/dist/pyscript/xterm-CVv2fC4I.js +2 -0
  49. package/dist/pyscript/xterm-CVv2fC4I.js.map +1 -0
  50. package/dist/pyscript/zip-D13-hp9W.js +2 -0
  51. package/dist/pyscript/zip-D13-hp9W.js.map +1 -0
  52. package/package.json +14 -14
package/dist/cjs/index.js CHANGED
@@ -376,8 +376,8 @@ const updatePointModifier = () => {
376
376
  if (results[round.players.join(", ")] &&
377
377
  results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
378
378
  for (const result of results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
379
- const first = round.players[result[0]];
380
- const second = round.players[result[1]];
379
+ const first = round.players[result.places[0]];
380
+ const second = round.players[result.places[1]];
381
381
  if (!pointModifier[first]) {
382
382
  pointModifier[first] = 0;
383
383
  }
@@ -886,9 +886,9 @@ function requireCheckPropTypes () {
886
886
  var printWarning = function() {};
887
887
 
888
888
  if (process.env.NODE_ENV !== 'production') {
889
- var ReactPropTypesSecret = requireReactPropTypesSecret();
889
+ var ReactPropTypesSecret = /*@__PURE__*/ requireReactPropTypesSecret();
890
890
  var loggedTypeFailures = {};
891
- var has = requireHas();
891
+ var has = /*@__PURE__*/ requireHas();
892
892
 
893
893
  printWarning = function(text) {
894
894
  var message = 'Warning: ' + text;
@@ -997,9 +997,9 @@ function requireFactoryWithTypeCheckers () {
997
997
  var ReactIs = requireReactIs();
998
998
  var assign = requireObjectAssign();
999
999
 
1000
- var ReactPropTypesSecret = requireReactPropTypesSecret();
1001
- var has = requireHas();
1002
- var checkPropTypes = requireCheckPropTypes();
1000
+ var ReactPropTypesSecret = /*@__PURE__*/ requireReactPropTypesSecret();
1001
+ var has = /*@__PURE__*/ requireHas();
1002
+ var checkPropTypes = /*@__PURE__*/ requireCheckPropTypes();
1003
1003
 
1004
1004
  var printWarning = function() {};
1005
1005
 
@@ -1612,7 +1612,7 @@ function requireFactoryWithThrowingShims () {
1612
1612
  if (hasRequiredFactoryWithThrowingShims) return factoryWithThrowingShims;
1613
1613
  hasRequiredFactoryWithThrowingShims = 1;
1614
1614
 
1615
- var ReactPropTypesSecret = requireReactPropTypesSecret();
1615
+ var ReactPropTypesSecret = /*@__PURE__*/ requireReactPropTypesSecret();
1616
1616
 
1617
1617
  function emptyFunction() {}
1618
1618
  function emptyFunctionWithReset() {}
@@ -1676,20 +1676,27 @@ function requireFactoryWithThrowingShims () {
1676
1676
  * LICENSE file in the root directory of this source tree.
1677
1677
  */
1678
1678
 
1679
- if (process.env.NODE_ENV !== 'production') {
1680
- var ReactIs = requireReactIs();
1681
-
1682
- // By explicitly using `prop-types` you are opting into new development behavior.
1683
- // http://fb.me/prop-types-in-prod
1684
- var throwOnDirectAccess = true;
1685
- propTypes.exports = requireFactoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
1686
- } else {
1687
- // By explicitly using `prop-types` you are opting into new production behavior.
1688
- // http://fb.me/prop-types-in-prod
1689
- propTypes.exports = requireFactoryWithThrowingShims()();
1679
+ var hasRequiredPropTypes;
1680
+
1681
+ function requirePropTypes () {
1682
+ if (hasRequiredPropTypes) return propTypes.exports;
1683
+ hasRequiredPropTypes = 1;
1684
+ if (process.env.NODE_ENV !== 'production') {
1685
+ var ReactIs = requireReactIs();
1686
+
1687
+ // By explicitly using `prop-types` you are opting into new development behavior.
1688
+ // http://fb.me/prop-types-in-prod
1689
+ var throwOnDirectAccess = true;
1690
+ propTypes.exports = /*@__PURE__*/ requireFactoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
1691
+ } else {
1692
+ // By explicitly using `prop-types` you are opting into new production behavior.
1693
+ // http://fb.me/prop-types-in-prod
1694
+ propTypes.exports = /*@__PURE__*/ requireFactoryWithThrowingShims()();
1695
+ }
1696
+ return propTypes.exports;
1690
1697
  }
1691
1698
 
1692
- var propTypesExports = propTypes.exports;
1699
+ var propTypesExports = /*@__PURE__*/ requirePropTypes();
1693
1700
 
1694
1701
  function _classCallCheck(instance, Constructor) {
1695
1702
  if (!(instance instanceof Constructor)) {
@@ -2530,7 +2537,7 @@ const RunSimulationBlock = () => {
2530
2537
  };
2531
2538
  const startRunNoUI = () => {
2532
2539
  setRunningNoUI(true);
2533
- runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
2540
+ runNoUI(getFullParameters(), apis, playerBots, seed.toString(), true);
2534
2541
  };
2535
2542
  const startRunNoUIN = (n) => {
2536
2543
  setLocalStorage("Results", {});
@@ -2567,7 +2574,7 @@ const RunSimulationBlock = () => {
2567
2574
  const currentResults = results[playerBots.join(", ")][JSON.stringify(getFullParameters())];
2568
2575
  const winCounts = {};
2569
2576
  for (const result of currentResults) {
2570
- const winner = playerBots[result[0]];
2577
+ const winner = playerBots[result.places[0]];
2571
2578
  if (!winCounts[winner]) {
2572
2579
  winCounts[winner] = 1;
2573
2580
  }
@@ -2788,6 +2795,155 @@ const NotFoundPage = () => {
2788
2795
  React.createElement("p", null, "Make sure the URL is correct.")));
2789
2796
  };
2790
2797
 
2798
+ const DataTable = ({ tableName, data, renderValue, renderHead, disableSort, hideIfEmpty, selectable, selectedRows, setSelectedRows, defaultSort, defaultReversed, stickyFirstColumn, }) => {
2799
+ var _a, _b;
2800
+ const [sortByColumn, setSortByColumn] = React.useState(defaultSort !== null && defaultSort !== void 0 ? defaultSort : 0);
2801
+ const [reversed, setReversed] = React.useState(defaultReversed !== null && defaultReversed !== void 0 ? defaultReversed : false);
2802
+ const [search, setSearch] = React.useState("");
2803
+ const theme = core.useMantineTheme();
2804
+ const colorScheme = hooks.useColorScheme();
2805
+ if (hideIfEmpty && data.body.length === 0) {
2806
+ return React.createElement(React.Fragment, null);
2807
+ }
2808
+ const reverseValue = reversed ? -1 : 1;
2809
+ const id = (_, __, value) => value;
2810
+ renderValue = renderValue !== null && renderValue !== void 0 ? renderValue : id;
2811
+ const headId = (value) => value;
2812
+ renderHead = renderHead !== null && renderHead !== void 0 ? renderHead : headId;
2813
+ const bodyIndices = [];
2814
+ for (let i = 0; i < data.body.length; i++) {
2815
+ bodyIndices.push(i);
2816
+ }
2817
+ const sortedIndices = bodyIndices
2818
+ .filter((i) => data.body[i].some((x, j) => {
2819
+ var _a;
2820
+ return (x === null || x === void 0 ? void 0 : x.includes(search)) ||
2821
+ ((_a = renderValue(i, data.head[j], x)) === null || _a === void 0 ? void 0 : _a.toString().includes(search));
2822
+ }))
2823
+ .sort((a, b) => {
2824
+ var _a, _b;
2825
+ if (disableSort) {
2826
+ return 1;
2827
+ }
2828
+ const aValue = (_a = data.body[a][sortByColumn]) !== null && _a !== void 0 ? _a : "";
2829
+ const bValue = (_b = data.body[b][sortByColumn]) !== null && _b !== void 0 ? _b : "";
2830
+ let difference = parseInt(bValue) - parseInt(aValue);
2831
+ if (isNaN(difference)) {
2832
+ return reverseValue * (aValue === null || aValue === void 0 ? void 0 : aValue.localeCompare(bValue));
2833
+ }
2834
+ return reverseValue * difference;
2835
+ });
2836
+ const displayData = {
2837
+ head: data.head.map(renderHead),
2838
+ body: sortedIndices.map((rowIndex) => data.body[rowIndex].map((value, columnIndex) => renderValue(rowIndex, data.head[columnIndex], value))),
2839
+ };
2840
+ return (React.createElement(React.Fragment, null,
2841
+ React.createElement(core.TextInput, { mb: "xs", w: 400, maw: "100%", placeholder: "Search", leftSection: React.createElement("i", { className: "fa-solid fa-magnifying-glass" }), rightSection: search !== "" ? (React.createElement(core.ActionIcon, { onClick: () => setSearch(""), variant: "transparent", color: "default", size: 15 },
2842
+ React.createElement("i", { className: "fa-solid fa-xmark" }))) : undefined, value: search, onChange: (e) => setSearch(e.currentTarget.value) }),
2843
+ React.createElement("div", { style: { maxWidth: "100%", overflow: "auto", maxHeight: 500 } },
2844
+ React.createElement(core.Table, { horizontalSpacing: 7.5, verticalSpacing: 7.5 },
2845
+ React.createElement(core.Table.Thead, { style: {
2846
+ position: "sticky",
2847
+ top: 0,
2848
+ backgroundColor: colorScheme === "dark" ? theme.colors.dark[7] : "white",
2849
+ zIndex: 101,
2850
+ } },
2851
+ React.createElement(core.Table.Tr, { h: 1 },
2852
+ selectable && React.createElement(core.Table.Th, null), (_a = displayData.head) === null || _a === void 0 ? void 0 :
2853
+ _a.map((element, columnIndex) => (React.createElement(core.Table.Th, { key: columnIndex, style: {
2854
+ padding: 0,
2855
+ verticalAlign: "top",
2856
+ height: "inherit",
2857
+ } }, element !== "" && (React.createElement(core.UnstyledButton, { h: "100%", className: "control", style: {
2858
+ display: "flex",
2859
+ flexDirection: "column",
2860
+ minWidth: 100,
2861
+ }, onClick: disableSort
2862
+ ? undefined
2863
+ : () => {
2864
+ if (sortByColumn === columnIndex) {
2865
+ setReversed((r) => !r);
2866
+ }
2867
+ else {
2868
+ setSortByColumn(columnIndex);
2869
+ }
2870
+ } },
2871
+ disableSort || (React.createElement("i", { style: { fontSize: 14, marginBottom: 5 }, className: sortByColumn === columnIndex
2872
+ ? reversed
2873
+ ? "fa-solid fa-sort-up"
2874
+ : "fa-solid fa-sort-down"
2875
+ : "fa-solid fa-sort" })),
2876
+ element))))))),
2877
+ React.createElement(core.Table.Tbody, null, (_b = displayData.body) === null || _b === void 0 ? void 0 : _b.map((row, rowIndex) => {
2878
+ const realIndex = sortedIndices[rowIndex];
2879
+ return (React.createElement(core.Table.Tr, { key: rowIndex },
2880
+ selectable && (React.createElement(core.Table.Td, null,
2881
+ React.createElement(core.Checkbox, { checked: selectedRows === null || selectedRows === void 0 ? void 0 : selectedRows.includes(realIndex), onChange: (e) => {
2882
+ if (setSelectedRows) {
2883
+ if (e.currentTarget.checked) {
2884
+ setSelectedRows((s) => [...s, realIndex]);
2885
+ }
2886
+ else {
2887
+ setSelectedRows((s) => s.filter((x) => x !== realIndex));
2888
+ }
2889
+ }
2890
+ } }))),
2891
+ row.map((value, valueIndex) => (React.createElement(core.Table.Td, { key: valueIndex, style: Object.assign({ whiteSpace: "nowrap" }, (stickyFirstColumn && valueIndex === 0
2892
+ ? {
2893
+ position: "sticky",
2894
+ right: 0,
2895
+ backgroundColor: colorScheme === "dark"
2896
+ ? theme.colors.dark[7]
2897
+ : "white",
2898
+ zIndex: 100,
2899
+ }
2900
+ : {})) }, value)))));
2901
+ }))))));
2902
+ };
2903
+
2904
+ const ResultStatisticsTable = () => {
2905
+ var _a, _b, _c, _d, _e;
2906
+ const [results] = useLocalStorage({
2907
+ key: "Results",
2908
+ defaultValue: {},
2909
+ });
2910
+ const [rounds] = useLocalStorage({
2911
+ key: "Rounds",
2912
+ defaultValue: [],
2913
+ });
2914
+ const [currentRound] = useLocalStorage({
2915
+ key: "Current Round",
2916
+ defaultValue: 0,
2917
+ });
2918
+ const navigate = reactRouterDom.useNavigate();
2919
+ const round = rounds[currentRound];
2920
+ if (!round) {
2921
+ return React.createElement(React.Fragment, null);
2922
+ }
2923
+ const statistics = Object.keys((_d = (_c = ((_b = Object.values((_a = Object.values(results !== null && results !== void 0 ? results : {})[0]) !== null && _a !== void 0 ? _a : {})[0]) !== null && _b !== void 0 ? _b : [])[0]) === null || _c === void 0 ? void 0 : _c.statistics) !== null && _d !== void 0 ? _d : {});
2924
+ const roundResults = ((_e = (results !== null && results !== void 0 ? results : {})[round.players.join(", ")]) !== null && _e !== void 0 ? _e : {})[JSON.stringify(round.parameters)];
2925
+ if (!roundResults) {
2926
+ return React.createElement(React.Fragment, null);
2927
+ }
2928
+ return (React.createElement("div", { style: {
2929
+ display: "flex",
2930
+ flexDirection: "column",
2931
+ alignItems: "center",
2932
+ marginTop: 10,
2933
+ } },
2934
+ React.createElement(DataTable, { tableName: "Results", data: {
2935
+ head: ["Seed"].concat(statistics),
2936
+ body: roundResults.map((result) => [result.seed].concat(statistics.map((statistic) => { var _a; return ((_a = result === null || result === void 0 ? void 0 : result.statistics) !== null && _a !== void 0 ? _a : {})[statistic].toString(); }))),
2937
+ }, renderValue: (rowIndex, columnName, value) => {
2938
+ if (columnName === "Seed") {
2939
+ return (React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), onClick: () => navigate(`/simulation/${round.players.map(encodeURIComponent).join(",")}?seed=${value}&${Object.keys(round.parameters)
2940
+ .map((p) => `${p}=${encodeURIComponent(round.parameters[p])}`)
2941
+ .join("&")}`) }, "Play"));
2942
+ }
2943
+ return React.createElement(React.Fragment, { key: rowIndex }, value);
2944
+ } })));
2945
+ };
2946
+
2791
2947
  let currentParameters;
2792
2948
  let currentPlayers;
2793
2949
  const Round = () => {
@@ -2881,7 +3037,7 @@ const Round = () => {
2881
3037
  if (results[round.players.join(", ")] !== undefined) {
2882
3038
  const currentResults = results[round.players.join(", ")][JSON.stringify(round.parameters)];
2883
3039
  for (const result of currentResults) {
2884
- const winner = round.players[result[0]];
3040
+ const winner = round.players[result.places[0]];
2885
3041
  if (!winCounts[winner]) {
2886
3042
  winCounts[winner] = 1;
2887
3043
  }
@@ -2908,6 +3064,9 @@ const Round = () => {
2908
3064
  winCounts[winner]))))),
2909
3065
  React.createElement("td", null,
2910
3066
  React.createElement(core.Button.Group, { orientation: "vertical" },
3067
+ React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-hand-pointer" }), size: "xs", onClick: () => {
3068
+ setLocalStorage("Current Round", index);
3069
+ } }, "Select"),
2911
3070
  React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.players.map(encodeURIComponent).join(",")}?showcase=true&${Object.keys(round.parameters)
2912
3071
  .map((p) => `${p}=${encodeURIComponent(round.parameters[p])}`)
2913
3072
  .join("&")}`) }, "Simulate"),
@@ -2981,7 +3140,8 @@ const Round = () => {
2981
3140
  flexDirection: clientWidth >= 700 ? "row" : "column",
2982
3141
  } },
2983
3142
  React.createElement(TournamentBlock, { title: "Before", inline: true }),
2984
- React.createElement(TournamentBlock, { title: "After", inline: true, pointModifier: pointModifier }))))));
3143
+ React.createElement(TournamentBlock, { title: "After", inline: true, pointModifier: pointModifier }))),
3144
+ React.createElement(ResultStatisticsTable, null))));
2985
3145
  };
2986
3146
 
2987
3147
  const SettingsPage = () => {
@@ -3417,7 +3577,7 @@ const TopPane = () => {
3417
3577
  };
3418
3578
 
3419
3579
  const CodeBattles = ({ configuration, routes, blocks }) => {
3420
- var _a, _b, _c, _d, _e, _f, _g, _h;
3580
+ var _a, _b, _c, _d, _e, _f;
3421
3581
  const colorScheme = hooks.useColorScheme();
3422
3582
  const firebase = app.initializeApp(configuration.firebase);
3423
3583
  const firestore$1 = firestore.getFirestore(firebase);
@@ -3428,7 +3588,6 @@ const CodeBattles = ({ configuration, routes, blocks }) => {
3428
3588
  locale: (_b = (_a = configuration.dates) === null || _a === void 0 ? void 0 : _a.locale) !== null && _b !== void 0 ? _b : "en",
3429
3589
  firstDayOfWeek: (_d = (_c = configuration.dates) === null || _c === void 0 ? void 0 : _c.firstDayOfWeek) !== null && _d !== void 0 ? _d : 0,
3430
3590
  weekendDays: (_f = (_e = configuration.dates) === null || _e === void 0 ? void 0 : _e.weekendDays) !== null && _f !== void 0 ? _f : [],
3431
- timezone: (_h = (_g = configuration.dates) === null || _g === void 0 ? void 0 : _g.timezone) !== null && _h !== void 0 ? _h : "UTC",
3432
3591
  } },
3433
3592
  React.createElement(reactRouterDom.BrowserRouter, null,
3434
3593
  React.createElement(notifications.Notifications, null),
@@ -3465,2272 +3624,2303 @@ const CodeBattles = ({ configuration, routes, blocks }) => {
3465
3624
 
3466
3625
  var prism = {exports: {}};
3467
3626
 
3468
- (function (module) {
3469
- /* **********************************************
3470
- Begin prism-core.js
3471
- ********************************************** */
3627
+ var hasRequiredPrism;
3472
3628
 
3473
- /// <reference lib="WebWorker"/>
3629
+ function requirePrism () {
3630
+ if (hasRequiredPrism) return prism.exports;
3631
+ hasRequiredPrism = 1;
3632
+ (function (module) {
3633
+ /* **********************************************
3634
+ Begin prism-core.js
3635
+ ********************************************** */
3474
3636
 
3475
- var _self = (typeof window !== 'undefined')
3476
- ? window // if in browser
3477
- : (
3478
- (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
3479
- ? self // if in worker
3480
- : {} // if in node js
3481
- );
3482
-
3483
- /**
3484
- * Prism: Lightweight, robust, elegant syntax highlighting
3485
- *
3486
- * @license MIT <https://opensource.org/licenses/MIT>
3487
- * @author Lea Verou <https://lea.verou.me>
3488
- * @namespace
3489
- * @public
3490
- */
3491
- var Prism = (function (_self) {
3637
+ /// <reference lib="WebWorker"/>
3492
3638
 
3493
- // Private helper vars
3494
- var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
3495
- var uniqueId = 0;
3639
+ var _self = (typeof window !== 'undefined')
3640
+ ? window // if in browser
3641
+ : (
3642
+ (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
3643
+ ? self // if in worker
3644
+ : {} // if in node js
3645
+ );
3496
3646
 
3497
- // The grammar object for plaintext
3498
- var plainTextGrammar = {};
3647
+ /**
3648
+ * Prism: Lightweight, robust, elegant syntax highlighting
3649
+ *
3650
+ * @license MIT <https://opensource.org/licenses/MIT>
3651
+ * @author Lea Verou <https://lea.verou.me>
3652
+ * @namespace
3653
+ * @public
3654
+ */
3655
+ var Prism = (function (_self) {
3499
3656
 
3657
+ // Private helper vars
3658
+ var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
3659
+ var uniqueId = 0;
3500
3660
 
3501
- var _ = {
3502
- /**
3503
- * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
3504
- * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
3505
- * additional languages or plugins yourself.
3506
- *
3507
- * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
3508
- *
3509
- * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
3510
- * empty Prism object into the global scope before loading the Prism script like this:
3511
- *
3512
- * ```js
3513
- * window.Prism = window.Prism || {};
3514
- * Prism.manual = true;
3515
- * // add a new <script> to load Prism's script
3516
- * ```
3517
- *
3518
- * @default false
3519
- * @type {boolean}
3520
- * @memberof Prism
3521
- * @public
3522
- */
3523
- manual: _self.Prism && _self.Prism.manual,
3524
- /**
3525
- * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
3526
- * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
3527
- * own worker, you don't want it to do this.
3528
- *
3529
- * By setting this value to `true`, Prism will not add its own listeners to the worker.
3530
- *
3531
- * You obviously have to change this value before Prism executes. To do this, you can add an
3532
- * empty Prism object into the global scope before loading the Prism script like this:
3533
- *
3534
- * ```js
3535
- * window.Prism = window.Prism || {};
3536
- * Prism.disableWorkerMessageHandler = true;
3537
- * // Load Prism's script
3538
- * ```
3539
- *
3540
- * @default false
3541
- * @type {boolean}
3542
- * @memberof Prism
3543
- * @public
3544
- */
3545
- disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
3661
+ // The grammar object for plaintext
3662
+ var plainTextGrammar = {};
3546
3663
 
3547
- /**
3548
- * A namespace for utility methods.
3549
- *
3550
- * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
3551
- * change or disappear at any time.
3552
- *
3553
- * @namespace
3554
- * @memberof Prism
3555
- */
3556
- util: {
3557
- encode: function encode(tokens) {
3558
- if (tokens instanceof Token) {
3559
- return new Token(tokens.type, encode(tokens.content), tokens.alias);
3560
- } else if (Array.isArray(tokens)) {
3561
- return tokens.map(encode);
3562
- } else {
3563
- return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
3564
- }
3565
- },
3566
3664
 
3665
+ var _ = {
3567
3666
  /**
3568
- * Returns the name of the type of the given value.
3667
+ * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
3668
+ * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
3669
+ * additional languages or plugins yourself.
3569
3670
  *
3570
- * @param {any} o
3571
- * @returns {string}
3572
- * @example
3573
- * type(null) === 'Null'
3574
- * type(undefined) === 'Undefined'
3575
- * type(123) === 'Number'
3576
- * type('foo') === 'String'
3577
- * type(true) === 'Boolean'
3578
- * type([1, 2]) === 'Array'
3579
- * type({}) === 'Object'
3580
- * type(String) === 'Function'
3581
- * type(/abc+/) === 'RegExp'
3671
+ * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
3672
+ *
3673
+ * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
3674
+ * empty Prism object into the global scope before loading the Prism script like this:
3675
+ *
3676
+ * ```js
3677
+ * window.Prism = window.Prism || {};
3678
+ * Prism.manual = true;
3679
+ * // add a new <script> to load Prism's script
3680
+ * ```
3681
+ *
3682
+ * @default false
3683
+ * @type {boolean}
3684
+ * @memberof Prism
3685
+ * @public
3582
3686
  */
3583
- type: function (o) {
3584
- return Object.prototype.toString.call(o).slice(8, -1);
3585
- },
3586
-
3687
+ manual: _self.Prism && _self.Prism.manual,
3587
3688
  /**
3588
- * Returns a unique number for the given object. Later calls will still return the same number.
3689
+ * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
3690
+ * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
3691
+ * own worker, you don't want it to do this.
3692
+ *
3693
+ * By setting this value to `true`, Prism will not add its own listeners to the worker.
3694
+ *
3695
+ * You obviously have to change this value before Prism executes. To do this, you can add an
3696
+ * empty Prism object into the global scope before loading the Prism script like this:
3589
3697
  *
3590
- * @param {Object} obj
3591
- * @returns {number}
3698
+ * ```js
3699
+ * window.Prism = window.Prism || {};
3700
+ * Prism.disableWorkerMessageHandler = true;
3701
+ * // Load Prism's script
3702
+ * ```
3703
+ *
3704
+ * @default false
3705
+ * @type {boolean}
3706
+ * @memberof Prism
3707
+ * @public
3592
3708
  */
3593
- objId: function (obj) {
3594
- if (!obj['__id']) {
3595
- Object.defineProperty(obj, '__id', { value: ++uniqueId });
3596
- }
3597
- return obj['__id'];
3598
- },
3709
+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
3599
3710
 
3600
3711
  /**
3601
- * Creates a deep clone of the given object.
3712
+ * A namespace for utility methods.
3602
3713
  *
3603
- * The main intended use of this function is to clone language definitions.
3714
+ * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
3715
+ * change or disappear at any time.
3604
3716
  *
3605
- * @param {T} o
3606
- * @param {Record<number, any>} [visited]
3607
- * @returns {T}
3608
- * @template T
3717
+ * @namespace
3718
+ * @memberof Prism
3609
3719
  */
3610
- clone: function deepClone(o, visited) {
3611
- visited = visited || {};
3612
-
3613
- var clone; var id;
3614
- switch (_.util.type(o)) {
3615
- case 'Object':
3616
- id = _.util.objId(o);
3617
- if (visited[id]) {
3618
- return visited[id];
3619
- }
3620
- clone = /** @type {Record<string, any>} */ ({});
3621
- visited[id] = clone;
3720
+ util: {
3721
+ encode: function encode(tokens) {
3722
+ if (tokens instanceof Token) {
3723
+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
3724
+ } else if (Array.isArray(tokens)) {
3725
+ return tokens.map(encode);
3726
+ } else {
3727
+ return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
3728
+ }
3729
+ },
3730
+
3731
+ /**
3732
+ * Returns the name of the type of the given value.
3733
+ *
3734
+ * @param {any} o
3735
+ * @returns {string}
3736
+ * @example
3737
+ * type(null) === 'Null'
3738
+ * type(undefined) === 'Undefined'
3739
+ * type(123) === 'Number'
3740
+ * type('foo') === 'String'
3741
+ * type(true) === 'Boolean'
3742
+ * type([1, 2]) === 'Array'
3743
+ * type({}) === 'Object'
3744
+ * type(String) === 'Function'
3745
+ * type(/abc+/) === 'RegExp'
3746
+ */
3747
+ type: function (o) {
3748
+ return Object.prototype.toString.call(o).slice(8, -1);
3749
+ },
3622
3750
 
3623
- for (var key in o) {
3624
- if (o.hasOwnProperty(key)) {
3625
- clone[key] = deepClone(o[key], visited);
3751
+ /**
3752
+ * Returns a unique number for the given object. Later calls will still return the same number.
3753
+ *
3754
+ * @param {Object} obj
3755
+ * @returns {number}
3756
+ */
3757
+ objId: function (obj) {
3758
+ if (!obj['__id']) {
3759
+ Object.defineProperty(obj, '__id', { value: ++uniqueId });
3760
+ }
3761
+ return obj['__id'];
3762
+ },
3763
+
3764
+ /**
3765
+ * Creates a deep clone of the given object.
3766
+ *
3767
+ * The main intended use of this function is to clone language definitions.
3768
+ *
3769
+ * @param {T} o
3770
+ * @param {Record<number, any>} [visited]
3771
+ * @returns {T}
3772
+ * @template T
3773
+ */
3774
+ clone: function deepClone(o, visited) {
3775
+ visited = visited || {};
3776
+
3777
+ var clone; var id;
3778
+ switch (_.util.type(o)) {
3779
+ case 'Object':
3780
+ id = _.util.objId(o);
3781
+ if (visited[id]) {
3782
+ return visited[id];
3626
3783
  }
3627
- }
3784
+ clone = /** @type {Record<string, any>} */ ({});
3785
+ visited[id] = clone;
3786
+
3787
+ for (var key in o) {
3788
+ if (o.hasOwnProperty(key)) {
3789
+ clone[key] = deepClone(o[key], visited);
3790
+ }
3791
+ }
3792
+
3793
+ return /** @type {any} */ (clone);
3628
3794
 
3629
- return /** @type {any} */ (clone);
3795
+ case 'Array':
3796
+ id = _.util.objId(o);
3797
+ if (visited[id]) {
3798
+ return visited[id];
3799
+ }
3800
+ clone = [];
3801
+ visited[id] = clone;
3802
+
3803
+ (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
3804
+ clone[i] = deepClone(v, visited);
3805
+ });
3806
+
3807
+ return /** @type {any} */ (clone);
3808
+
3809
+ default:
3810
+ return o;
3811
+ }
3812
+ },
3630
3813
 
3631
- case 'Array':
3632
- id = _.util.objId(o);
3633
- if (visited[id]) {
3634
- return visited[id];
3814
+ /**
3815
+ * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
3816
+ *
3817
+ * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
3818
+ *
3819
+ * @param {Element} element
3820
+ * @returns {string}
3821
+ */
3822
+ getLanguage: function (element) {
3823
+ while (element) {
3824
+ var m = lang.exec(element.className);
3825
+ if (m) {
3826
+ return m[1].toLowerCase();
3635
3827
  }
3636
- clone = [];
3637
- visited[id] = clone;
3828
+ element = element.parentElement;
3829
+ }
3830
+ return 'none';
3831
+ },
3638
3832
 
3639
- (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
3640
- clone[i] = deepClone(v, visited);
3641
- });
3833
+ /**
3834
+ * Sets the Prism `language-xxxx` class of the given element.
3835
+ *
3836
+ * @param {Element} element
3837
+ * @param {string} language
3838
+ * @returns {void}
3839
+ */
3840
+ setLanguage: function (element, language) {
3841
+ // remove all `language-xxxx` classes
3842
+ // (this might leave behind a leading space)
3843
+ element.className = element.className.replace(RegExp(lang, 'gi'), '');
3844
+
3845
+ // add the new `language-xxxx` class
3846
+ // (using `classList` will automatically clean up spaces for us)
3847
+ element.classList.add('language-' + language);
3848
+ },
3849
+
3850
+ /**
3851
+ * Returns the script element that is currently executing.
3852
+ *
3853
+ * This does __not__ work for line script element.
3854
+ *
3855
+ * @returns {HTMLScriptElement | null}
3856
+ */
3857
+ currentScript: function () {
3858
+ if (typeof document === 'undefined') {
3859
+ return null;
3860
+ }
3861
+ if (document.currentScript && document.currentScript.tagName === 'SCRIPT' && 1 < 2 /* hack to trip TS' flow analysis */) {
3862
+ return /** @type {any} */ (document.currentScript);
3863
+ }
3642
3864
 
3643
- return /** @type {any} */ (clone);
3865
+ // IE11 workaround
3866
+ // we'll get the src of the current script by parsing IE11's error stack trace
3867
+ // this will not work for inline scripts
3868
+
3869
+ try {
3870
+ throw new Error();
3871
+ } catch (err) {
3872
+ // Get file src url from stack. Specifically works with the format of stack traces in IE.
3873
+ // A stack will look like this:
3874
+ //
3875
+ // Error
3876
+ // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
3877
+ // at Global code (http://localhost/components/prism-core.js:606:1)
3878
+
3879
+ var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1];
3880
+ if (src) {
3881
+ var scripts = document.getElementsByTagName('script');
3882
+ for (var i in scripts) {
3883
+ if (scripts[i].src == src) {
3884
+ return scripts[i];
3885
+ }
3886
+ }
3887
+ }
3888
+ return null;
3889
+ }
3890
+ },
3644
3891
 
3645
- default:
3646
- return o;
3892
+ /**
3893
+ * Returns whether a given class is active for `element`.
3894
+ *
3895
+ * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
3896
+ * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
3897
+ * given class is just the given class with a `no-` prefix.
3898
+ *
3899
+ * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
3900
+ * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
3901
+ * ancestors have the given class or the negated version of it, then the default activation will be returned.
3902
+ *
3903
+ * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
3904
+ * version of it, the class is considered active.
3905
+ *
3906
+ * @param {Element} element
3907
+ * @param {string} className
3908
+ * @param {boolean} [defaultActivation=false]
3909
+ * @returns {boolean}
3910
+ */
3911
+ isActive: function (element, className, defaultActivation) {
3912
+ var no = 'no-' + className;
3913
+
3914
+ while (element) {
3915
+ var classList = element.classList;
3916
+ if (classList.contains(className)) {
3917
+ return true;
3918
+ }
3919
+ if (classList.contains(no)) {
3920
+ return false;
3921
+ }
3922
+ element = element.parentElement;
3923
+ }
3924
+ return !!defaultActivation;
3647
3925
  }
3648
3926
  },
3649
3927
 
3650
3928
  /**
3651
- * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
3929
+ * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
3652
3930
  *
3653
- * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
3654
- *
3655
- * @param {Element} element
3656
- * @returns {string}
3931
+ * @namespace
3932
+ * @memberof Prism
3933
+ * @public
3657
3934
  */
3658
- getLanguage: function (element) {
3659
- while (element) {
3660
- var m = lang.exec(element.className);
3661
- if (m) {
3662
- return m[1].toLowerCase();
3935
+ languages: {
3936
+ /**
3937
+ * The grammar for plain, unformatted text.
3938
+ */
3939
+ plain: plainTextGrammar,
3940
+ plaintext: plainTextGrammar,
3941
+ text: plainTextGrammar,
3942
+ txt: plainTextGrammar,
3943
+
3944
+ /**
3945
+ * Creates a deep copy of the language with the given id and appends the given tokens.
3946
+ *
3947
+ * If a token in `redef` also appears in the copied language, then the existing token in the copied language
3948
+ * will be overwritten at its original position.
3949
+ *
3950
+ * ## Best practices
3951
+ *
3952
+ * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
3953
+ * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
3954
+ * understand the language definition because, normally, the order of tokens matters in Prism grammars.
3955
+ *
3956
+ * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
3957
+ * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
3958
+ *
3959
+ * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
3960
+ * @param {Grammar} redef The new tokens to append.
3961
+ * @returns {Grammar} The new language created.
3962
+ * @public
3963
+ * @example
3964
+ * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
3965
+ * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
3966
+ * // at its original position
3967
+ * 'comment': { ... },
3968
+ * // CSS doesn't have a 'color' token, so this token will be appended
3969
+ * 'color': /\b(?:red|green|blue)\b/
3970
+ * });
3971
+ */
3972
+ extend: function (id, redef) {
3973
+ var lang = _.util.clone(_.languages[id]);
3974
+
3975
+ for (var key in redef) {
3976
+ lang[key] = redef[key];
3977
+ }
3978
+
3979
+ return lang;
3980
+ },
3981
+
3982
+ /**
3983
+ * Inserts tokens _before_ another token in a language definition or any other grammar.
3984
+ *
3985
+ * ## Usage
3986
+ *
3987
+ * This helper method makes it easy to modify existing languages. For example, the CSS language definition
3988
+ * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
3989
+ * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
3990
+ * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
3991
+ * this:
3992
+ *
3993
+ * ```js
3994
+ * Prism.languages.markup.style = {
3995
+ * // token
3996
+ * };
3997
+ * ```
3998
+ *
3999
+ * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
4000
+ * before existing tokens. For the CSS example above, you would use it like this:
4001
+ *
4002
+ * ```js
4003
+ * Prism.languages.insertBefore('markup', 'cdata', {
4004
+ * 'style': {
4005
+ * // token
4006
+ * }
4007
+ * });
4008
+ * ```
4009
+ *
4010
+ * ## Special cases
4011
+ *
4012
+ * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
4013
+ * will be ignored.
4014
+ *
4015
+ * This behavior can be used to insert tokens after `before`:
4016
+ *
4017
+ * ```js
4018
+ * Prism.languages.insertBefore('markup', 'comment', {
4019
+ * 'comment': Prism.languages.markup.comment,
4020
+ * // tokens after 'comment'
4021
+ * });
4022
+ * ```
4023
+ *
4024
+ * ## Limitations
4025
+ *
4026
+ * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
4027
+ * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
4028
+ * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
4029
+ * deleting properties which is necessary to insert at arbitrary positions.
4030
+ *
4031
+ * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
4032
+ * Instead, it will create a new object and replace all references to the target object with the new one. This
4033
+ * can be done without temporarily deleting properties, so the iteration order is well-defined.
4034
+ *
4035
+ * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
4036
+ * you hold the target object in a variable, then the value of the variable will not change.
4037
+ *
4038
+ * ```js
4039
+ * var oldMarkup = Prism.languages.markup;
4040
+ * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
4041
+ *
4042
+ * assert(oldMarkup !== Prism.languages.markup);
4043
+ * assert(newMarkup === Prism.languages.markup);
4044
+ * ```
4045
+ *
4046
+ * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
4047
+ * object to be modified.
4048
+ * @param {string} before The key to insert before.
4049
+ * @param {Grammar} insert An object containing the key-value pairs to be inserted.
4050
+ * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
4051
+ * object to be modified.
4052
+ *
4053
+ * Defaults to `Prism.languages`.
4054
+ * @returns {Grammar} The new grammar object.
4055
+ * @public
4056
+ */
4057
+ insertBefore: function (inside, before, insert, root) {
4058
+ root = root || /** @type {any} */ (_.languages);
4059
+ var grammar = root[inside];
4060
+ /** @type {Grammar} */
4061
+ var ret = {};
4062
+
4063
+ for (var token in grammar) {
4064
+ if (grammar.hasOwnProperty(token)) {
4065
+
4066
+ if (token == before) {
4067
+ for (var newToken in insert) {
4068
+ if (insert.hasOwnProperty(newToken)) {
4069
+ ret[newToken] = insert[newToken];
4070
+ }
4071
+ }
4072
+ }
4073
+
4074
+ // Do not insert token which also occur in insert. See #1525
4075
+ if (!insert.hasOwnProperty(token)) {
4076
+ ret[token] = grammar[token];
4077
+ }
4078
+ }
4079
+ }
4080
+
4081
+ var old = root[inside];
4082
+ root[inside] = ret;
4083
+
4084
+ // Update references in other language definitions
4085
+ _.languages.DFS(_.languages, function (key, value) {
4086
+ if (value === old && key != inside) {
4087
+ this[key] = ret;
4088
+ }
4089
+ });
4090
+
4091
+ return ret;
4092
+ },
4093
+
4094
+ // Traverse a language definition with Depth First Search
4095
+ DFS: function DFS(o, callback, type, visited) {
4096
+ visited = visited || {};
4097
+
4098
+ var objId = _.util.objId;
4099
+
4100
+ for (var i in o) {
4101
+ if (o.hasOwnProperty(i)) {
4102
+ callback.call(o, i, o[i], type || i);
4103
+
4104
+ var property = o[i];
4105
+ var propertyType = _.util.type(property);
4106
+
4107
+ if (propertyType === 'Object' && !visited[objId(property)]) {
4108
+ visited[objId(property)] = true;
4109
+ DFS(property, callback, null, visited);
4110
+ } else if (propertyType === 'Array' && !visited[objId(property)]) {
4111
+ visited[objId(property)] = true;
4112
+ DFS(property, callback, i, visited);
4113
+ }
4114
+ }
3663
4115
  }
3664
- element = element.parentElement;
3665
4116
  }
3666
- return 'none';
3667
4117
  },
3668
4118
 
4119
+ plugins: {},
4120
+
3669
4121
  /**
3670
- * Sets the Prism `language-xxxx` class of the given element.
4122
+ * This is the most high-level function in Prism’s API.
4123
+ * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
4124
+ * each one of them.
4125
+ *
4126
+ * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
3671
4127
  *
3672
- * @param {Element} element
3673
- * @param {string} language
3674
- * @returns {void}
4128
+ * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
4129
+ * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
4130
+ * @memberof Prism
4131
+ * @public
3675
4132
  */
3676
- setLanguage: function (element, language) {
3677
- // remove all `language-xxxx` classes
3678
- // (this might leave behind a leading space)
3679
- element.className = element.className.replace(RegExp(lang, 'gi'), '');
3680
-
3681
- // add the new `language-xxxx` class
3682
- // (using `classList` will automatically clean up spaces for us)
3683
- element.classList.add('language-' + language);
4133
+ highlightAll: function (async, callback) {
4134
+ _.highlightAllUnder(document, async, callback);
3684
4135
  },
3685
4136
 
3686
4137
  /**
3687
- * Returns the script element that is currently executing.
4138
+ * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
4139
+ * {@link Prism.highlightElement} on each one of them.
3688
4140
  *
3689
- * This does __not__ work for line script element.
4141
+ * The following hooks will be run:
4142
+ * 1. `before-highlightall`
4143
+ * 2. `before-all-elements-highlight`
4144
+ * 3. All hooks of {@link Prism.highlightElement} for each element.
3690
4145
  *
3691
- * @returns {HTMLScriptElement | null}
4146
+ * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
4147
+ * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
4148
+ * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
4149
+ * @memberof Prism
4150
+ * @public
3692
4151
  */
3693
- currentScript: function () {
3694
- if (typeof document === 'undefined') {
3695
- return null;
3696
- }
3697
- if (document.currentScript && document.currentScript.tagName === 'SCRIPT' && 1 < 2 /* hack to trip TS' flow analysis */) {
3698
- return /** @type {any} */ (document.currentScript);
3699
- }
4152
+ highlightAllUnder: function (container, async, callback) {
4153
+ var env = {
4154
+ callback: callback,
4155
+ container: container,
4156
+ selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
4157
+ };
3700
4158
 
3701
- // IE11 workaround
3702
- // we'll get the src of the current script by parsing IE11's error stack trace
3703
- // this will not work for inline scripts
3704
-
3705
- try {
3706
- throw new Error();
3707
- } catch (err) {
3708
- // Get file src url from stack. Specifically works with the format of stack traces in IE.
3709
- // A stack will look like this:
3710
- //
3711
- // Error
3712
- // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
3713
- // at Global code (http://localhost/components/prism-core.js:606:1)
3714
-
3715
- var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1];
3716
- if (src) {
3717
- var scripts = document.getElementsByTagName('script');
3718
- for (var i in scripts) {
3719
- if (scripts[i].src == src) {
3720
- return scripts[i];
3721
- }
3722
- }
3723
- }
3724
- return null;
4159
+ _.hooks.run('before-highlightall', env);
4160
+
4161
+ env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
4162
+
4163
+ _.hooks.run('before-all-elements-highlight', env);
4164
+
4165
+ for (var i = 0, element; (element = env.elements[i++]);) {
4166
+ _.highlightElement(element, async === true, env.callback);
3725
4167
  }
3726
4168
  },
3727
4169
 
3728
4170
  /**
3729
- * Returns whether a given class is active for `element`.
4171
+ * Highlights the code inside a single element.
3730
4172
  *
3731
- * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
3732
- * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
3733
- * given class is just the given class with a `no-` prefix.
4173
+ * The following hooks will be run:
4174
+ * 1. `before-sanity-check`
4175
+ * 2. `before-highlight`
4176
+ * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
4177
+ * 4. `before-insert`
4178
+ * 5. `after-highlight`
4179
+ * 6. `complete`
3734
4180
  *
3735
- * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
3736
- * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
3737
- * ancestors have the given class or the negated version of it, then the default activation will be returned.
4181
+ * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
4182
+ * the element's language.
3738
4183
  *
3739
- * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
3740
- * version of it, the class is considered active.
4184
+ * @param {Element} element The element containing the code.
4185
+ * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
4186
+ * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
4187
+ * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
4188
+ * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
3741
4189
  *
3742
- * @param {Element} element
3743
- * @param {string} className
3744
- * @param {boolean} [defaultActivation=false]
3745
- * @returns {boolean}
4190
+ * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
4191
+ * asynchronous highlighting to work. You can build your own bundle on the
4192
+ * [Download page](https://prismjs.com/download.html).
4193
+ * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
4194
+ * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
4195
+ * @memberof Prism
4196
+ * @public
3746
4197
  */
3747
- isActive: function (element, className, defaultActivation) {
3748
- var no = 'no-' + className;
4198
+ highlightElement: function (element, async, callback) {
4199
+ // Find language
4200
+ var language = _.util.getLanguage(element);
4201
+ var grammar = _.languages[language];
4202
+
4203
+ // Set language on the element, if not present
4204
+ _.util.setLanguage(element, language);
4205
+
4206
+ // Set language on the parent, for styling
4207
+ var parent = element.parentElement;
4208
+ if (parent && parent.nodeName.toLowerCase() === 'pre') {
4209
+ _.util.setLanguage(parent, language);
4210
+ }
3749
4211
 
3750
- while (element) {
3751
- var classList = element.classList;
3752
- if (classList.contains(className)) {
3753
- return true;
3754
- }
3755
- if (classList.contains(no)) {
3756
- return false;
3757
- }
3758
- element = element.parentElement;
4212
+ var code = element.textContent;
4213
+
4214
+ var env = {
4215
+ element: element,
4216
+ language: language,
4217
+ grammar: grammar,
4218
+ code: code
4219
+ };
4220
+
4221
+ function insertHighlightedCode(highlightedCode) {
4222
+ env.highlightedCode = highlightedCode;
4223
+
4224
+ _.hooks.run('before-insert', env);
4225
+
4226
+ env.element.innerHTML = env.highlightedCode;
4227
+
4228
+ _.hooks.run('after-highlight', env);
4229
+ _.hooks.run('complete', env);
4230
+ callback && callback.call(env.element);
3759
4231
  }
3760
- return !!defaultActivation;
3761
- }
3762
- },
3763
4232
 
3764
- /**
3765
- * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
3766
- *
3767
- * @namespace
3768
- * @memberof Prism
3769
- * @public
3770
- */
3771
- languages: {
3772
- /**
3773
- * The grammar for plain, unformatted text.
3774
- */
3775
- plain: plainTextGrammar,
3776
- plaintext: plainTextGrammar,
3777
- text: plainTextGrammar,
3778
- txt: plainTextGrammar,
4233
+ _.hooks.run('before-sanity-check', env);
4234
+
4235
+ // plugins may change/add the parent/element
4236
+ parent = env.element.parentElement;
4237
+ if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
4238
+ parent.setAttribute('tabindex', '0');
4239
+ }
4240
+
4241
+ if (!env.code) {
4242
+ _.hooks.run('complete', env);
4243
+ callback && callback.call(env.element);
4244
+ return;
4245
+ }
4246
+
4247
+ _.hooks.run('before-highlight', env);
4248
+
4249
+ if (!env.grammar) {
4250
+ insertHighlightedCode(_.util.encode(env.code));
4251
+ return;
4252
+ }
4253
+
4254
+ if (async && _self.Worker) {
4255
+ var worker = new Worker(_.filename);
4256
+
4257
+ worker.onmessage = function (evt) {
4258
+ insertHighlightedCode(evt.data);
4259
+ };
4260
+
4261
+ worker.postMessage(JSON.stringify({
4262
+ language: env.language,
4263
+ code: env.code,
4264
+ immediateClose: true
4265
+ }));
4266
+ } else {
4267
+ insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
4268
+ }
4269
+ },
3779
4270
 
3780
4271
  /**
3781
- * Creates a deep copy of the language with the given id and appends the given tokens.
3782
- *
3783
- * If a token in `redef` also appears in the copied language, then the existing token in the copied language
3784
- * will be overwritten at its original position.
3785
- *
3786
- * ## Best practices
4272
+ * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
4273
+ * and the language definitions to use, and returns a string with the HTML produced.
3787
4274
  *
3788
- * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
3789
- * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
3790
- * understand the language definition because, normally, the order of tokens matters in Prism grammars.
4275
+ * The following hooks will be run:
4276
+ * 1. `before-tokenize`
4277
+ * 2. `after-tokenize`
4278
+ * 3. `wrap`: On each {@link Token}.
3791
4279
  *
3792
- * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
3793
- * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
4280
+ * @param {string} text A string with the code to be highlighted.
4281
+ * @param {Grammar} grammar An object containing the tokens to use.
3794
4282
  *
3795
- * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
3796
- * @param {Grammar} redef The new tokens to append.
3797
- * @returns {Grammar} The new language created.
4283
+ * Usually a language definition like `Prism.languages.markup`.
4284
+ * @param {string} language The name of the language definition passed to `grammar`.
4285
+ * @returns {string} The highlighted HTML.
4286
+ * @memberof Prism
3798
4287
  * @public
3799
4288
  * @example
3800
- * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
3801
- * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
3802
- * // at its original position
3803
- * 'comment': { ... },
3804
- * // CSS doesn't have a 'color' token, so this token will be appended
3805
- * 'color': /\b(?:red|green|blue)\b/
3806
- * });
4289
+ * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
3807
4290
  */
3808
- extend: function (id, redef) {
3809
- var lang = _.util.clone(_.languages[id]);
3810
-
3811
- for (var key in redef) {
3812
- lang[key] = redef[key];
4291
+ highlight: function (text, grammar, language) {
4292
+ var env = {
4293
+ code: text,
4294
+ grammar: grammar,
4295
+ language: language
4296
+ };
4297
+ _.hooks.run('before-tokenize', env);
4298
+ if (!env.grammar) {
4299
+ throw new Error('The language "' + env.language + '" has no grammar.');
3813
4300
  }
3814
-
3815
- return lang;
4301
+ env.tokens = _.tokenize(env.code, env.grammar);
4302
+ _.hooks.run('after-tokenize', env);
4303
+ return Token.stringify(_.util.encode(env.tokens), env.language);
3816
4304
  },
3817
4305
 
3818
4306
  /**
3819
- * Inserts tokens _before_ another token in a language definition or any other grammar.
4307
+ * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
4308
+ * and the language definitions to use, and returns an array with the tokenized code.
3820
4309
  *
3821
- * ## Usage
4310
+ * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
3822
4311
  *
3823
- * This helper method makes it easy to modify existing languages. For example, the CSS language definition
3824
- * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
3825
- * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
3826
- * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
3827
- * this:
4312
+ * This method could be useful in other contexts as well, as a very crude parser.
3828
4313
  *
3829
- * ```js
3830
- * Prism.languages.markup.style = {
3831
- * // token
3832
- * };
3833
- * ```
4314
+ * @param {string} text A string with the code to be highlighted.
4315
+ * @param {Grammar} grammar An object containing the tokens to use.
3834
4316
  *
3835
- * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
3836
- * before existing tokens. For the CSS example above, you would use it like this:
3837
- *
3838
- * ```js
3839
- * Prism.languages.insertBefore('markup', 'cdata', {
3840
- * 'style': {
3841
- * // token
4317
+ * Usually a language definition like `Prism.languages.markup`.
4318
+ * @returns {TokenStream} An array of strings and tokens, a token stream.
4319
+ * @memberof Prism
4320
+ * @public
4321
+ * @example
4322
+ * let code = `var foo = 0;`;
4323
+ * let tokens = Prism.tokenize(code, Prism.languages.javascript);
4324
+ * tokens.forEach(token => {
4325
+ * if (token instanceof Prism.Token && token.type === 'number') {
4326
+ * console.log(`Found numeric literal: ${token.content}`);
3842
4327
  * }
3843
4328
  * });
3844
- * ```
3845
- *
3846
- * ## Special cases
3847
- *
3848
- * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
3849
- * will be ignored.
3850
- *
3851
- * This behavior can be used to insert tokens after `before`:
3852
- *
3853
- * ```js
3854
- * Prism.languages.insertBefore('markup', 'comment', {
3855
- * 'comment': Prism.languages.markup.comment,
3856
- * // tokens after 'comment'
3857
- * });
3858
- * ```
3859
- *
3860
- * ## Limitations
3861
- *
3862
- * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
3863
- * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
3864
- * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
3865
- * deleting properties which is necessary to insert at arbitrary positions.
3866
- *
3867
- * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
3868
- * Instead, it will create a new object and replace all references to the target object with the new one. This
3869
- * can be done without temporarily deleting properties, so the iteration order is well-defined.
3870
- *
3871
- * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
3872
- * you hold the target object in a variable, then the value of the variable will not change.
3873
- *
3874
- * ```js
3875
- * var oldMarkup = Prism.languages.markup;
3876
- * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
3877
- *
3878
- * assert(oldMarkup !== Prism.languages.markup);
3879
- * assert(newMarkup === Prism.languages.markup);
3880
- * ```
3881
- *
3882
- * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
3883
- * object to be modified.
3884
- * @param {string} before The key to insert before.
3885
- * @param {Grammar} insert An object containing the key-value pairs to be inserted.
3886
- * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
3887
- * object to be modified.
3888
- *
3889
- * Defaults to `Prism.languages`.
3890
- * @returns {Grammar} The new grammar object.
3891
- * @public
3892
4329
  */
3893
- insertBefore: function (inside, before, insert, root) {
3894
- root = root || /** @type {any} */ (_.languages);
3895
- var grammar = root[inside];
3896
- /** @type {Grammar} */
3897
- var ret = {};
3898
-
3899
- for (var token in grammar) {
3900
- if (grammar.hasOwnProperty(token)) {
3901
-
3902
- if (token == before) {
3903
- for (var newToken in insert) {
3904
- if (insert.hasOwnProperty(newToken)) {
3905
- ret[newToken] = insert[newToken];
3906
- }
3907
- }
3908
- }
3909
-
3910
- // Do not insert token which also occur in insert. See #1525
3911
- if (!insert.hasOwnProperty(token)) {
3912
- ret[token] = grammar[token];
3913
- }
4330
+ tokenize: function (text, grammar) {
4331
+ var rest = grammar.rest;
4332
+ if (rest) {
4333
+ for (var token in rest) {
4334
+ grammar[token] = rest[token];
3914
4335
  }
4336
+
4337
+ delete grammar.rest;
3915
4338
  }
3916
4339
 
3917
- var old = root[inside];
3918
- root[inside] = ret;
4340
+ var tokenList = new LinkedList();
4341
+ addAfter(tokenList, tokenList.head, text);
3919
4342
 
3920
- // Update references in other language definitions
3921
- _.languages.DFS(_.languages, function (key, value) {
3922
- if (value === old && key != inside) {
3923
- this[key] = ret;
3924
- }
3925
- });
4343
+ matchGrammar(text, tokenList, grammar, tokenList.head, 0);
3926
4344
 
3927
- return ret;
4345
+ return toArray(tokenList);
3928
4346
  },
3929
4347
 
3930
- // Traverse a language definition with Depth First Search
3931
- DFS: function DFS(o, callback, type, visited) {
3932
- visited = visited || {};
3933
-
3934
- var objId = _.util.objId;
3935
-
3936
- for (var i in o) {
3937
- if (o.hasOwnProperty(i)) {
3938
- callback.call(o, i, o[i], type || i);
4348
+ /**
4349
+ * @namespace
4350
+ * @memberof Prism
4351
+ * @public
4352
+ */
4353
+ hooks: {
4354
+ all: {},
4355
+
4356
+ /**
4357
+ * Adds the given callback to the list of callbacks for the given hook.
4358
+ *
4359
+ * The callback will be invoked when the hook it is registered for is run.
4360
+ * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
4361
+ *
4362
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
4363
+ *
4364
+ * @param {string} name The name of the hook.
4365
+ * @param {HookCallback} callback The callback function which is given environment variables.
4366
+ * @public
4367
+ */
4368
+ add: function (name, callback) {
4369
+ var hooks = _.hooks.all;
4370
+
4371
+ hooks[name] = hooks[name] || [];
4372
+
4373
+ hooks[name].push(callback);
4374
+ },
3939
4375
 
3940
- var property = o[i];
3941
- var propertyType = _.util.type(property);
4376
+ /**
4377
+ * Runs a hook invoking all registered callbacks with the given environment variables.
4378
+ *
4379
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
4380
+ *
4381
+ * @param {string} name The name of the hook.
4382
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
4383
+ * @public
4384
+ */
4385
+ run: function (name, env) {
4386
+ var callbacks = _.hooks.all[name];
4387
+
4388
+ if (!callbacks || !callbacks.length) {
4389
+ return;
4390
+ }
3942
4391
 
3943
- if (propertyType === 'Object' && !visited[objId(property)]) {
3944
- visited[objId(property)] = true;
3945
- DFS(property, callback, null, visited);
3946
- } else if (propertyType === 'Array' && !visited[objId(property)]) {
3947
- visited[objId(property)] = true;
3948
- DFS(property, callback, i, visited);
3949
- }
4392
+ for (var i = 0, callback; (callback = callbacks[i++]);) {
4393
+ callback(env);
3950
4394
  }
3951
4395
  }
3952
- }
3953
- },
4396
+ },
4397
+
4398
+ Token: Token
4399
+ };
4400
+ _self.Prism = _;
4401
+
3954
4402
 
3955
- plugins: {},
4403
+ // Typescript note:
4404
+ // The following can be used to import the Token type in JSDoc:
4405
+ //
4406
+ // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
3956
4407
 
3957
4408
  /**
3958
- * This is the most high-level function in Prism’s API.
3959
- * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
3960
- * each one of them.
4409
+ * Creates a new token.
3961
4410
  *
3962
- * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
3963
- *
3964
- * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
3965
- * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
3966
- * @memberof Prism
4411
+ * @param {string} type See {@link Token#type type}
4412
+ * @param {string | TokenStream} content See {@link Token#content content}
4413
+ * @param {string|string[]} [alias] The alias(es) of the token.
4414
+ * @param {string} [matchedStr=""] A copy of the full string this token was created from.
4415
+ * @class
4416
+ * @global
3967
4417
  * @public
3968
4418
  */
3969
- highlightAll: function (async, callback) {
3970
- _.highlightAllUnder(document, async, callback);
3971
- },
4419
+ function Token(type, content, alias, matchedStr) {
4420
+ /**
4421
+ * The type of the token.
4422
+ *
4423
+ * This is usually the key of a pattern in a {@link Grammar}.
4424
+ *
4425
+ * @type {string}
4426
+ * @see GrammarToken
4427
+ * @public
4428
+ */
4429
+ this.type = type;
4430
+ /**
4431
+ * The strings or tokens contained by this token.
4432
+ *
4433
+ * This will be a token stream if the pattern matched also defined an `inside` grammar.
4434
+ *
4435
+ * @type {string | TokenStream}
4436
+ * @public
4437
+ */
4438
+ this.content = content;
4439
+ /**
4440
+ * The alias(es) of the token.
4441
+ *
4442
+ * @type {string|string[]}
4443
+ * @see GrammarToken
4444
+ * @public
4445
+ */
4446
+ this.alias = alias;
4447
+ // Copy of the full string this token was created from
4448
+ this.length = (matchedStr || '').length | 0;
4449
+ }
3972
4450
 
3973
4451
  /**
3974
- * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
3975
- * {@link Prism.highlightElement} on each one of them.
4452
+ * A token stream is an array of strings and {@link Token Token} objects.
3976
4453
  *
3977
- * The following hooks will be run:
3978
- * 1. `before-highlightall`
3979
- * 2. `before-all-elements-highlight`
3980
- * 3. All hooks of {@link Prism.highlightElement} for each element.
4454
+ * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
4455
+ * them.
4456
+ *
4457
+ * 1. No adjacent strings.
4458
+ * 2. No empty strings.
4459
+ *
4460
+ * The only exception here is the token stream that only contains the empty string and nothing else.
3981
4461
  *
3982
- * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
3983
- * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
3984
- * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
3985
- * @memberof Prism
4462
+ * @typedef {Array<string | Token>} TokenStream
4463
+ * @global
3986
4464
  * @public
3987
4465
  */
3988
- highlightAllUnder: function (container, async, callback) {
3989
- var env = {
3990
- callback: callback,
3991
- container: container,
3992
- selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
3993
- };
3994
-
3995
- _.hooks.run('before-highlightall', env);
3996
-
3997
- env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
3998
-
3999
- _.hooks.run('before-all-elements-highlight', env);
4000
-
4001
- for (var i = 0, element; (element = env.elements[i++]);) {
4002
- _.highlightElement(element, async === true, env.callback);
4003
- }
4004
- },
4005
4466
 
4006
4467
  /**
4007
- * Highlights the code inside a single element.
4468
+ * Converts the given token or token stream to an HTML representation.
4008
4469
  *
4009
4470
  * The following hooks will be run:
4010
- * 1. `before-sanity-check`
4011
- * 2. `before-highlight`
4012
- * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
4013
- * 4. `before-insert`
4014
- * 5. `after-highlight`
4015
- * 6. `complete`
4471
+ * 1. `wrap`: On each {@link Token}.
4016
4472
  *
4017
- * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
4018
- * the element's language.
4019
- *
4020
- * @param {Element} element The element containing the code.
4021
- * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
4022
- * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
4023
- * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
4024
- * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
4025
- *
4026
- * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
4027
- * asynchronous highlighting to work. You can build your own bundle on the
4028
- * [Download page](https://prismjs.com/download.html).
4029
- * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
4030
- * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
4031
- * @memberof Prism
4032
- * @public
4473
+ * @param {string | Token | TokenStream} o The token or token stream to be converted.
4474
+ * @param {string} language The name of current language.
4475
+ * @returns {string} The HTML representation of the token or token stream.
4476
+ * @memberof Token
4477
+ * @static
4033
4478
  */
4034
- highlightElement: function (element, async, callback) {
4035
- // Find language
4036
- var language = _.util.getLanguage(element);
4037
- var grammar = _.languages[language];
4038
-
4039
- // Set language on the element, if not present
4040
- _.util.setLanguage(element, language);
4041
-
4042
- // Set language on the parent, for styling
4043
- var parent = element.parentElement;
4044
- if (parent && parent.nodeName.toLowerCase() === 'pre') {
4045
- _.util.setLanguage(parent, language);
4046
- }
4047
-
4048
- var code = element.textContent;
4049
-
4050
- var env = {
4051
- element: element,
4052
- language: language,
4053
- grammar: grammar,
4054
- code: code
4055
- };
4056
-
4057
- function insertHighlightedCode(highlightedCode) {
4058
- env.highlightedCode = highlightedCode;
4059
-
4060
- _.hooks.run('before-insert', env);
4061
-
4062
- env.element.innerHTML = env.highlightedCode;
4063
-
4064
- _.hooks.run('after-highlight', env);
4065
- _.hooks.run('complete', env);
4066
- callback && callback.call(env.element);
4067
- }
4068
-
4069
- _.hooks.run('before-sanity-check', env);
4070
-
4071
- // plugins may change/add the parent/element
4072
- parent = env.element.parentElement;
4073
- if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
4074
- parent.setAttribute('tabindex', '0');
4075
- }
4076
-
4077
- if (!env.code) {
4078
- _.hooks.run('complete', env);
4079
- callback && callback.call(env.element);
4080
- return;
4081
- }
4082
-
4083
- _.hooks.run('before-highlight', env);
4084
-
4085
- if (!env.grammar) {
4086
- insertHighlightedCode(_.util.encode(env.code));
4087
- return;
4479
+ Token.stringify = function stringify(o, language) {
4480
+ if (typeof o == 'string') {
4481
+ return o;
4088
4482
  }
4089
-
4090
- if (async && _self.Worker) {
4091
- var worker = new Worker(_.filename);
4092
-
4093
- worker.onmessage = function (evt) {
4094
- insertHighlightedCode(evt.data);
4095
- };
4096
-
4097
- worker.postMessage(JSON.stringify({
4098
- language: env.language,
4099
- code: env.code,
4100
- immediateClose: true
4101
- }));
4102
- } else {
4103
- insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
4483
+ if (Array.isArray(o)) {
4484
+ var s = '';
4485
+ o.forEach(function (e) {
4486
+ s += stringify(e, language);
4487
+ });
4488
+ return s;
4104
4489
  }
4105
- },
4106
4490
 
4107
- /**
4108
- * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
4109
- * and the language definitions to use, and returns a string with the HTML produced.
4110
- *
4111
- * The following hooks will be run:
4112
- * 1. `before-tokenize`
4113
- * 2. `after-tokenize`
4114
- * 3. `wrap`: On each {@link Token}.
4115
- *
4116
- * @param {string} text A string with the code to be highlighted.
4117
- * @param {Grammar} grammar An object containing the tokens to use.
4118
- *
4119
- * Usually a language definition like `Prism.languages.markup`.
4120
- * @param {string} language The name of the language definition passed to `grammar`.
4121
- * @returns {string} The highlighted HTML.
4122
- * @memberof Prism
4123
- * @public
4124
- * @example
4125
- * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
4126
- */
4127
- highlight: function (text, grammar, language) {
4128
4491
  var env = {
4129
- code: text,
4130
- grammar: grammar,
4492
+ type: o.type,
4493
+ content: stringify(o.content, language),
4494
+ tag: 'span',
4495
+ classes: ['token', o.type],
4496
+ attributes: {},
4131
4497
  language: language
4132
4498
  };
4133
- _.hooks.run('before-tokenize', env);
4134
- if (!env.grammar) {
4135
- throw new Error('The language "' + env.language + '" has no grammar.');
4136
- }
4137
- env.tokens = _.tokenize(env.code, env.grammar);
4138
- _.hooks.run('after-tokenize', env);
4139
- return Token.stringify(_.util.encode(env.tokens), env.language);
4140
- },
4141
4499
 
4142
- /**
4143
- * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
4144
- * and the language definitions to use, and returns an array with the tokenized code.
4145
- *
4146
- * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
4147
- *
4148
- * This method could be useful in other contexts as well, as a very crude parser.
4149
- *
4150
- * @param {string} text A string with the code to be highlighted.
4151
- * @param {Grammar} grammar An object containing the tokens to use.
4152
- *
4153
- * Usually a language definition like `Prism.languages.markup`.
4154
- * @returns {TokenStream} An array of strings and tokens, a token stream.
4155
- * @memberof Prism
4156
- * @public
4157
- * @example
4158
- * let code = `var foo = 0;`;
4159
- * let tokens = Prism.tokenize(code, Prism.languages.javascript);
4160
- * tokens.forEach(token => {
4161
- * if (token instanceof Prism.Token && token.type === 'number') {
4162
- * console.log(`Found numeric literal: ${token.content}`);
4163
- * }
4164
- * });
4165
- */
4166
- tokenize: function (text, grammar) {
4167
- var rest = grammar.rest;
4168
- if (rest) {
4169
- for (var token in rest) {
4170
- grammar[token] = rest[token];
4500
+ var aliases = o.alias;
4501
+ if (aliases) {
4502
+ if (Array.isArray(aliases)) {
4503
+ Array.prototype.push.apply(env.classes, aliases);
4504
+ } else {
4505
+ env.classes.push(aliases);
4171
4506
  }
4172
-
4173
- delete grammar.rest;
4174
4507
  }
4175
4508
 
4176
- var tokenList = new LinkedList();
4177
- addAfter(tokenList, tokenList.head, text);
4509
+ _.hooks.run('wrap', env);
4178
4510
 
4179
- matchGrammar(text, tokenList, grammar, tokenList.head, 0);
4511
+ var attributes = '';
4512
+ for (var name in env.attributes) {
4513
+ attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
4514
+ }
4180
4515
 
4181
- return toArray(tokenList);
4182
- },
4516
+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
4517
+ };
4183
4518
 
4184
4519
  /**
4185
- * @namespace
4186
- * @memberof Prism
4187
- * @public
4520
+ * @param {RegExp} pattern
4521
+ * @param {number} pos
4522
+ * @param {string} text
4523
+ * @param {boolean} lookbehind
4524
+ * @returns {RegExpExecArray | null}
4188
4525
  */
4189
- hooks: {
4190
- all: {},
4191
-
4192
- /**
4193
- * Adds the given callback to the list of callbacks for the given hook.
4194
- *
4195
- * The callback will be invoked when the hook it is registered for is run.
4196
- * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
4197
- *
4198
- * One callback function can be registered to multiple hooks and the same hook multiple times.
4199
- *
4200
- * @param {string} name The name of the hook.
4201
- * @param {HookCallback} callback The callback function which is given environment variables.
4202
- * @public
4203
- */
4204
- add: function (name, callback) {
4205
- var hooks = _.hooks.all;
4206
-
4207
- hooks[name] = hooks[name] || [];
4208
-
4209
- hooks[name].push(callback);
4210
- },
4211
-
4212
- /**
4213
- * Runs a hook invoking all registered callbacks with the given environment variables.
4214
- *
4215
- * Callbacks will be invoked synchronously and in the order in which they were registered.
4216
- *
4217
- * @param {string} name The name of the hook.
4218
- * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
4219
- * @public
4220
- */
4221
- run: function (name, env) {
4222
- var callbacks = _.hooks.all[name];
4223
-
4224
- if (!callbacks || !callbacks.length) {
4225
- return;
4226
- }
4227
-
4228
- for (var i = 0, callback; (callback = callbacks[i++]);) {
4229
- callback(env);
4230
- }
4526
+ function matchPattern(pattern, pos, text, lookbehind) {
4527
+ pattern.lastIndex = pos;
4528
+ var match = pattern.exec(text);
4529
+ if (match && lookbehind && match[1]) {
4530
+ // change the match to remove the text matched by the Prism lookbehind group
4531
+ var lookbehindLength = match[1].length;
4532
+ match.index += lookbehindLength;
4533
+ match[0] = match[0].slice(lookbehindLength);
4231
4534
  }
4232
- },
4233
-
4234
- Token: Token
4235
- };
4236
- _self.Prism = _;
4237
-
4238
-
4239
- // Typescript note:
4240
- // The following can be used to import the Token type in JSDoc:
4241
- //
4242
- // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
4535
+ return match;
4536
+ }
4243
4537
 
4244
- /**
4245
- * Creates a new token.
4246
- *
4247
- * @param {string} type See {@link Token#type type}
4248
- * @param {string | TokenStream} content See {@link Token#content content}
4249
- * @param {string|string[]} [alias] The alias(es) of the token.
4250
- * @param {string} [matchedStr=""] A copy of the full string this token was created from.
4251
- * @class
4252
- * @global
4253
- * @public
4254
- */
4255
- function Token(type, content, alias, matchedStr) {
4256
- /**
4257
- * The type of the token.
4258
- *
4259
- * This is usually the key of a pattern in a {@link Grammar}.
4260
- *
4261
- * @type {string}
4262
- * @see GrammarToken
4263
- * @public
4264
- */
4265
- this.type = type;
4266
- /**
4267
- * The strings or tokens contained by this token.
4268
- *
4269
- * This will be a token stream if the pattern matched also defined an `inside` grammar.
4270
- *
4271
- * @type {string | TokenStream}
4272
- * @public
4273
- */
4274
- this.content = content;
4275
4538
  /**
4276
- * The alias(es) of the token.
4539
+ * @param {string} text
4540
+ * @param {LinkedList<string | Token>} tokenList
4541
+ * @param {any} grammar
4542
+ * @param {LinkedListNode<string | Token>} startNode
4543
+ * @param {number} startPos
4544
+ * @param {RematchOptions} [rematch]
4545
+ * @returns {void}
4546
+ * @private
4277
4547
  *
4278
- * @type {string|string[]}
4279
- * @see GrammarToken
4280
- * @public
4548
+ * @typedef RematchOptions
4549
+ * @property {string} cause
4550
+ * @property {number} reach
4281
4551
  */
4282
- this.alias = alias;
4283
- // Copy of the full string this token was created from
4284
- this.length = (matchedStr || '').length | 0;
4285
- }
4286
-
4287
- /**
4288
- * A token stream is an array of strings and {@link Token Token} objects.
4289
- *
4290
- * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
4291
- * them.
4292
- *
4293
- * 1. No adjacent strings.
4294
- * 2. No empty strings.
4295
- *
4296
- * The only exception here is the token stream that only contains the empty string and nothing else.
4297
- *
4298
- * @typedef {Array<string | Token>} TokenStream
4299
- * @global
4300
- * @public
4301
- */
4302
-
4303
- /**
4304
- * Converts the given token or token stream to an HTML representation.
4305
- *
4306
- * The following hooks will be run:
4307
- * 1. `wrap`: On each {@link Token}.
4308
- *
4309
- * @param {string | Token | TokenStream} o The token or token stream to be converted.
4310
- * @param {string} language The name of current language.
4311
- * @returns {string} The HTML representation of the token or token stream.
4312
- * @memberof Token
4313
- * @static
4314
- */
4315
- Token.stringify = function stringify(o, language) {
4316
- if (typeof o == 'string') {
4317
- return o;
4318
- }
4319
- if (Array.isArray(o)) {
4320
- var s = '';
4321
- o.forEach(function (e) {
4322
- s += stringify(e, language);
4323
- });
4324
- return s;
4325
- }
4326
-
4327
- var env = {
4328
- type: o.type,
4329
- content: stringify(o.content, language),
4330
- tag: 'span',
4331
- classes: ['token', o.type],
4332
- attributes: {},
4333
- language: language
4334
- };
4335
-
4336
- var aliases = o.alias;
4337
- if (aliases) {
4338
- if (Array.isArray(aliases)) {
4339
- Array.prototype.push.apply(env.classes, aliases);
4340
- } else {
4341
- env.classes.push(aliases);
4342
- }
4343
- }
4344
-
4345
- _.hooks.run('wrap', env);
4346
-
4347
- var attributes = '';
4348
- for (var name in env.attributes) {
4349
- attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
4350
- }
4351
-
4352
- return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
4353
- };
4354
-
4355
- /**
4356
- * @param {RegExp} pattern
4357
- * @param {number} pos
4358
- * @param {string} text
4359
- * @param {boolean} lookbehind
4360
- * @returns {RegExpExecArray | null}
4361
- */
4362
- function matchPattern(pattern, pos, text, lookbehind) {
4363
- pattern.lastIndex = pos;
4364
- var match = pattern.exec(text);
4365
- if (match && lookbehind && match[1]) {
4366
- // change the match to remove the text matched by the Prism lookbehind group
4367
- var lookbehindLength = match[1].length;
4368
- match.index += lookbehindLength;
4369
- match[0] = match[0].slice(lookbehindLength);
4370
- }
4371
- return match;
4372
- }
4373
-
4374
- /**
4375
- * @param {string} text
4376
- * @param {LinkedList<string | Token>} tokenList
4377
- * @param {any} grammar
4378
- * @param {LinkedListNode<string | Token>} startNode
4379
- * @param {number} startPos
4380
- * @param {RematchOptions} [rematch]
4381
- * @returns {void}
4382
- * @private
4383
- *
4384
- * @typedef RematchOptions
4385
- * @property {string} cause
4386
- * @property {number} reach
4387
- */
4388
- function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
4389
- for (var token in grammar) {
4390
- if (!grammar.hasOwnProperty(token) || !grammar[token]) {
4391
- continue;
4392
- }
4393
-
4394
- var patterns = grammar[token];
4395
- patterns = Array.isArray(patterns) ? patterns : [patterns];
4396
-
4397
- for (var j = 0; j < patterns.length; ++j) {
4398
- if (rematch && rematch.cause == token + ',' + j) {
4399
- return;
4552
+ function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
4553
+ for (var token in grammar) {
4554
+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
4555
+ continue;
4400
4556
  }
4401
4557
 
4402
- var patternObj = patterns[j];
4403
- var inside = patternObj.inside;
4404
- var lookbehind = !!patternObj.lookbehind;
4405
- var greedy = !!patternObj.greedy;
4406
- var alias = patternObj.alias;
4558
+ var patterns = grammar[token];
4559
+ patterns = Array.isArray(patterns) ? patterns : [patterns];
4407
4560
 
4408
- if (greedy && !patternObj.pattern.global) {
4409
- // Without the global flag, lastIndex won't work
4410
- var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
4411
- patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
4412
- }
4413
-
4414
- /** @type {RegExp} */
4415
- var pattern = patternObj.pattern || patternObj;
4416
-
4417
- for ( // iterate the token list and keep track of the current token/string position
4418
- var currentNode = startNode.next, pos = startPos;
4419
- currentNode !== tokenList.tail;
4420
- pos += currentNode.value.length, currentNode = currentNode.next
4421
- ) {
4422
-
4423
- if (rematch && pos >= rematch.reach) {
4424
- break;
4561
+ for (var j = 0; j < patterns.length; ++j) {
4562
+ if (rematch && rematch.cause == token + ',' + j) {
4563
+ return;
4425
4564
  }
4426
4565
 
4427
- var str = currentNode.value;
4566
+ var patternObj = patterns[j];
4567
+ var inside = patternObj.inside;
4568
+ var lookbehind = !!patternObj.lookbehind;
4569
+ var greedy = !!patternObj.greedy;
4570
+ var alias = patternObj.alias;
4428
4571
 
4429
- if (tokenList.length > text.length) {
4430
- // Something went terribly wrong, ABORT, ABORT!
4431
- return;
4572
+ if (greedy && !patternObj.pattern.global) {
4573
+ // Without the global flag, lastIndex won't work
4574
+ var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
4575
+ patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
4432
4576
  }
4433
4577
 
4434
- if (str instanceof Token) {
4435
- continue;
4436
- }
4578
+ /** @type {RegExp} */
4579
+ var pattern = patternObj.pattern || patternObj;
4437
4580
 
4438
- var removeCount = 1; // this is the to parameter of removeBetween
4439
- var match;
4581
+ for ( // iterate the token list and keep track of the current token/string position
4582
+ var currentNode = startNode.next, pos = startPos;
4583
+ currentNode !== tokenList.tail;
4584
+ pos += currentNode.value.length, currentNode = currentNode.next
4585
+ ) {
4440
4586
 
4441
- if (greedy) {
4442
- match = matchPattern(pattern, pos, text, lookbehind);
4443
- if (!match || match.index >= text.length) {
4587
+ if (rematch && pos >= rematch.reach) {
4444
4588
  break;
4445
4589
  }
4446
4590
 
4447
- var from = match.index;
4448
- var to = match.index + match[0].length;
4449
- var p = pos;
4591
+ var str = currentNode.value;
4450
4592
 
4451
- // find the node that contains the match
4452
- p += currentNode.value.length;
4453
- while (from >= p) {
4454
- currentNode = currentNode.next;
4455
- p += currentNode.value.length;
4593
+ if (tokenList.length > text.length) {
4594
+ // Something went terribly wrong, ABORT, ABORT!
4595
+ return;
4456
4596
  }
4457
- // adjust pos (and p)
4458
- p -= currentNode.value.length;
4459
- pos = p;
4460
4597
 
4461
- // the current node is a Token, then the match starts inside another Token, which is invalid
4462
- if (currentNode.value instanceof Token) {
4598
+ if (str instanceof Token) {
4463
4599
  continue;
4464
4600
  }
4465
4601
 
4466
- // find the last node which is affected by this match
4467
- for (
4468
- var k = currentNode;
4469
- k !== tokenList.tail && (p < to || typeof k.value === 'string');
4470
- k = k.next
4471
- ) {
4472
- removeCount++;
4473
- p += k.value.length;
4474
- }
4475
- removeCount--;
4602
+ var removeCount = 1; // this is the to parameter of removeBetween
4603
+ var match;
4476
4604
 
4477
- // replace with the new match
4478
- str = text.slice(pos, p);
4479
- match.index -= pos;
4480
- } else {
4481
- match = matchPattern(pattern, 0, str, lookbehind);
4482
- if (!match) {
4483
- continue;
4605
+ if (greedy) {
4606
+ match = matchPattern(pattern, pos, text, lookbehind);
4607
+ if (!match || match.index >= text.length) {
4608
+ break;
4609
+ }
4610
+
4611
+ var from = match.index;
4612
+ var to = match.index + match[0].length;
4613
+ var p = pos;
4614
+
4615
+ // find the node that contains the match
4616
+ p += currentNode.value.length;
4617
+ while (from >= p) {
4618
+ currentNode = currentNode.next;
4619
+ p += currentNode.value.length;
4620
+ }
4621
+ // adjust pos (and p)
4622
+ p -= currentNode.value.length;
4623
+ pos = p;
4624
+
4625
+ // the current node is a Token, then the match starts inside another Token, which is invalid
4626
+ if (currentNode.value instanceof Token) {
4627
+ continue;
4628
+ }
4629
+
4630
+ // find the last node which is affected by this match
4631
+ for (
4632
+ var k = currentNode;
4633
+ k !== tokenList.tail && (p < to || typeof k.value === 'string');
4634
+ k = k.next
4635
+ ) {
4636
+ removeCount++;
4637
+ p += k.value.length;
4638
+ }
4639
+ removeCount--;
4640
+
4641
+ // replace with the new match
4642
+ str = text.slice(pos, p);
4643
+ match.index -= pos;
4644
+ } else {
4645
+ match = matchPattern(pattern, 0, str, lookbehind);
4646
+ if (!match) {
4647
+ continue;
4648
+ }
4484
4649
  }
4485
- }
4486
4650
 
4487
- // eslint-disable-next-line no-redeclare
4488
- var from = match.index;
4489
- var matchStr = match[0];
4490
- var before = str.slice(0, from);
4491
- var after = str.slice(from + matchStr.length);
4651
+ // eslint-disable-next-line no-redeclare
4652
+ var from = match.index;
4653
+ var matchStr = match[0];
4654
+ var before = str.slice(0, from);
4655
+ var after = str.slice(from + matchStr.length);
4492
4656
 
4493
- var reach = pos + str.length;
4494
- if (rematch && reach > rematch.reach) {
4495
- rematch.reach = reach;
4496
- }
4657
+ var reach = pos + str.length;
4658
+ if (rematch && reach > rematch.reach) {
4659
+ rematch.reach = reach;
4660
+ }
4497
4661
 
4498
- var removeFrom = currentNode.prev;
4662
+ var removeFrom = currentNode.prev;
4499
4663
 
4500
- if (before) {
4501
- removeFrom = addAfter(tokenList, removeFrom, before);
4502
- pos += before.length;
4503
- }
4664
+ if (before) {
4665
+ removeFrom = addAfter(tokenList, removeFrom, before);
4666
+ pos += before.length;
4667
+ }
4504
4668
 
4505
- removeRange(tokenList, removeFrom, removeCount);
4669
+ removeRange(tokenList, removeFrom, removeCount);
4506
4670
 
4507
- var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
4508
- currentNode = addAfter(tokenList, removeFrom, wrapped);
4671
+ var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
4672
+ currentNode = addAfter(tokenList, removeFrom, wrapped);
4509
4673
 
4510
- if (after) {
4511
- addAfter(tokenList, currentNode, after);
4512
- }
4674
+ if (after) {
4675
+ addAfter(tokenList, currentNode, after);
4676
+ }
4513
4677
 
4514
- if (removeCount > 1) {
4515
- // at least one Token object was removed, so we have to do some rematching
4516
- // this can only happen if the current pattern is greedy
4678
+ if (removeCount > 1) {
4679
+ // at least one Token object was removed, so we have to do some rematching
4680
+ // this can only happen if the current pattern is greedy
4517
4681
 
4518
- /** @type {RematchOptions} */
4519
- var nestedRematch = {
4520
- cause: token + ',' + j,
4521
- reach: reach
4522
- };
4523
- matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
4682
+ /** @type {RematchOptions} */
4683
+ var nestedRematch = {
4684
+ cause: token + ',' + j,
4685
+ reach: reach
4686
+ };
4687
+ matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
4524
4688
 
4525
- // the reach might have been extended because of the rematching
4526
- if (rematch && nestedRematch.reach > rematch.reach) {
4527
- rematch.reach = nestedRematch.reach;
4689
+ // the reach might have been extended because of the rematching
4690
+ if (rematch && nestedRematch.reach > rematch.reach) {
4691
+ rematch.reach = nestedRematch.reach;
4692
+ }
4528
4693
  }
4529
4694
  }
4530
4695
  }
4531
4696
  }
4532
4697
  }
4533
- }
4534
4698
 
4535
- /**
4536
- * @typedef LinkedListNode
4537
- * @property {T} value
4538
- * @property {LinkedListNode<T> | null} prev The previous node.
4539
- * @property {LinkedListNode<T> | null} next The next node.
4540
- * @template T
4541
- * @private
4542
- */
4699
+ /**
4700
+ * @typedef LinkedListNode
4701
+ * @property {T} value
4702
+ * @property {LinkedListNode<T> | null} prev The previous node.
4703
+ * @property {LinkedListNode<T> | null} next The next node.
4704
+ * @template T
4705
+ * @private
4706
+ */
4543
4707
 
4544
- /**
4545
- * @template T
4546
- * @private
4547
- */
4548
- function LinkedList() {
4549
- /** @type {LinkedListNode<T>} */
4550
- var head = { value: null, prev: null, next: null };
4551
- /** @type {LinkedListNode<T>} */
4552
- var tail = { value: null, prev: head, next: null };
4553
- head.next = tail;
4554
-
4555
- /** @type {LinkedListNode<T>} */
4556
- this.head = head;
4557
- /** @type {LinkedListNode<T>} */
4558
- this.tail = tail;
4559
- this.length = 0;
4560
- }
4708
+ /**
4709
+ * @template T
4710
+ * @private
4711
+ */
4712
+ function LinkedList() {
4713
+ /** @type {LinkedListNode<T>} */
4714
+ var head = { value: null, prev: null, next: null };
4715
+ /** @type {LinkedListNode<T>} */
4716
+ var tail = { value: null, prev: head, next: null };
4717
+ head.next = tail;
4718
+
4719
+ /** @type {LinkedListNode<T>} */
4720
+ this.head = head;
4721
+ /** @type {LinkedListNode<T>} */
4722
+ this.tail = tail;
4723
+ this.length = 0;
4724
+ }
4561
4725
 
4562
- /**
4563
- * Adds a new node with the given value to the list.
4564
- *
4565
- * @param {LinkedList<T>} list
4566
- * @param {LinkedListNode<T>} node
4567
- * @param {T} value
4568
- * @returns {LinkedListNode<T>} The added node.
4569
- * @template T
4570
- */
4571
- function addAfter(list, node, value) {
4572
- // assumes that node != list.tail && values.length >= 0
4573
- var next = node.next;
4726
+ /**
4727
+ * Adds a new node with the given value to the list.
4728
+ *
4729
+ * @param {LinkedList<T>} list
4730
+ * @param {LinkedListNode<T>} node
4731
+ * @param {T} value
4732
+ * @returns {LinkedListNode<T>} The added node.
4733
+ * @template T
4734
+ */
4735
+ function addAfter(list, node, value) {
4736
+ // assumes that node != list.tail && values.length >= 0
4737
+ var next = node.next;
4574
4738
 
4575
- var newNode = { value: value, prev: node, next: next };
4576
- node.next = newNode;
4577
- next.prev = newNode;
4578
- list.length++;
4739
+ var newNode = { value: value, prev: node, next: next };
4740
+ node.next = newNode;
4741
+ next.prev = newNode;
4742
+ list.length++;
4579
4743
 
4580
- return newNode;
4581
- }
4582
- /**
4583
- * Removes `count` nodes after the given node. The given node will not be removed.
4584
- *
4585
- * @param {LinkedList<T>} list
4586
- * @param {LinkedListNode<T>} node
4587
- * @param {number} count
4588
- * @template T
4589
- */
4590
- function removeRange(list, node, count) {
4591
- var next = node.next;
4592
- for (var i = 0; i < count && next !== list.tail; i++) {
4593
- next = next.next;
4744
+ return newNode;
4594
4745
  }
4595
- node.next = next;
4596
- next.prev = node;
4597
- list.length -= i;
4598
- }
4599
- /**
4600
- * @param {LinkedList<T>} list
4601
- * @returns {T[]}
4602
- * @template T
4603
- */
4604
- function toArray(list) {
4605
- var array = [];
4606
- var node = list.head.next;
4607
- while (node !== list.tail) {
4608
- array.push(node.value);
4609
- node = node.next;
4746
+ /**
4747
+ * Removes `count` nodes after the given node. The given node will not be removed.
4748
+ *
4749
+ * @param {LinkedList<T>} list
4750
+ * @param {LinkedListNode<T>} node
4751
+ * @param {number} count
4752
+ * @template T
4753
+ */
4754
+ function removeRange(list, node, count) {
4755
+ var next = node.next;
4756
+ for (var i = 0; i < count && next !== list.tail; i++) {
4757
+ next = next.next;
4758
+ }
4759
+ node.next = next;
4760
+ next.prev = node;
4761
+ list.length -= i;
4762
+ }
4763
+ /**
4764
+ * @param {LinkedList<T>} list
4765
+ * @returns {T[]}
4766
+ * @template T
4767
+ */
4768
+ function toArray(list) {
4769
+ var array = [];
4770
+ var node = list.head.next;
4771
+ while (node !== list.tail) {
4772
+ array.push(node.value);
4773
+ node = node.next;
4774
+ }
4775
+ return array;
4610
4776
  }
4611
- return array;
4612
- }
4613
4777
 
4614
4778
 
4615
- if (!_self.document) {
4616
- if (!_self.addEventListener) {
4617
- // in Node.js
4618
- return _;
4619
- }
4779
+ if (!_self.document) {
4780
+ if (!_self.addEventListener) {
4781
+ // in Node.js
4782
+ return _;
4783
+ }
4620
4784
 
4621
- if (!_.disableWorkerMessageHandler) {
4622
- // In worker
4623
- _self.addEventListener('message', function (evt) {
4624
- var message = JSON.parse(evt.data);
4625
- var lang = message.language;
4626
- var code = message.code;
4627
- var immediateClose = message.immediateClose;
4628
-
4629
- _self.postMessage(_.highlight(code, _.languages[lang], lang));
4630
- if (immediateClose) {
4631
- _self.close();
4632
- }
4633
- }, false);
4634
- }
4785
+ if (!_.disableWorkerMessageHandler) {
4786
+ // In worker
4787
+ _self.addEventListener('message', function (evt) {
4788
+ var message = JSON.parse(evt.data);
4789
+ var lang = message.language;
4790
+ var code = message.code;
4791
+ var immediateClose = message.immediateClose;
4792
+
4793
+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
4794
+ if (immediateClose) {
4795
+ _self.close();
4796
+ }
4797
+ }, false);
4798
+ }
4635
4799
 
4636
- return _;
4637
- }
4800
+ return _;
4801
+ }
4638
4802
 
4639
- // Get current script and highlight
4640
- var script = _.util.currentScript();
4803
+ // Get current script and highlight
4804
+ var script = _.util.currentScript();
4641
4805
 
4642
- if (script) {
4643
- _.filename = script.src;
4806
+ if (script) {
4807
+ _.filename = script.src;
4644
4808
 
4645
- if (script.hasAttribute('data-manual')) {
4646
- _.manual = true;
4809
+ if (script.hasAttribute('data-manual')) {
4810
+ _.manual = true;
4811
+ }
4647
4812
  }
4648
- }
4649
4813
 
4650
- function highlightAutomaticallyCallback() {
4651
- if (!_.manual) {
4652
- _.highlightAll();
4814
+ function highlightAutomaticallyCallback() {
4815
+ if (!_.manual) {
4816
+ _.highlightAll();
4817
+ }
4653
4818
  }
4654
- }
4655
4819
 
4656
- if (!_.manual) {
4657
- // If the document state is "loading", then we'll use DOMContentLoaded.
4658
- // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
4659
- // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
4660
- // might take longer one animation frame to execute which can create a race condition where only some plugins have
4661
- // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
4662
- // See https://github.com/PrismJS/prism/issues/2102
4663
- var readyState = document.readyState;
4664
- if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
4665
- document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
4666
- } else {
4667
- if (window.requestAnimationFrame) {
4668
- window.requestAnimationFrame(highlightAutomaticallyCallback);
4820
+ if (!_.manual) {
4821
+ // If the document state is "loading", then we'll use DOMContentLoaded.
4822
+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
4823
+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
4824
+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
4825
+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
4826
+ // See https://github.com/PrismJS/prism/issues/2102
4827
+ var readyState = document.readyState;
4828
+ if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
4829
+ document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
4669
4830
  } else {
4670
- window.setTimeout(highlightAutomaticallyCallback, 16);
4831
+ if (window.requestAnimationFrame) {
4832
+ window.requestAnimationFrame(highlightAutomaticallyCallback);
4833
+ } else {
4834
+ window.setTimeout(highlightAutomaticallyCallback, 16);
4835
+ }
4671
4836
  }
4672
4837
  }
4673
- }
4674
4838
 
4675
- return _;
4839
+ return _;
4676
4840
 
4677
- }(_self));
4841
+ }(_self));
4678
4842
 
4679
- if (module.exports) {
4680
- module.exports = Prism;
4681
- }
4843
+ if (module.exports) {
4844
+ module.exports = Prism;
4845
+ }
4682
4846
 
4683
- // hack for components to work correctly in node.js
4684
- if (typeof commonjsGlobal !== 'undefined') {
4685
- commonjsGlobal.Prism = Prism;
4686
- }
4687
-
4688
- // some additional documentation/types
4689
-
4690
- /**
4691
- * The expansion of a simple `RegExp` literal to support additional properties.
4692
- *
4693
- * @typedef GrammarToken
4694
- * @property {RegExp} pattern The regular expression of the token.
4695
- * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
4696
- * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
4697
- * @property {boolean} [greedy=false] Whether the token is greedy.
4698
- * @property {string|string[]} [alias] An optional alias or list of aliases.
4699
- * @property {Grammar} [inside] The nested grammar of this token.
4700
- *
4701
- * The `inside` grammar will be used to tokenize the text value of each token of this kind.
4702
- *
4703
- * This can be used to make nested and even recursive language definitions.
4704
- *
4705
- * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
4706
- * each another.
4707
- * @global
4708
- * @public
4709
- */
4710
-
4711
- /**
4712
- * @typedef Grammar
4713
- * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
4714
- * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
4715
- * @global
4716
- * @public
4717
- */
4718
-
4719
- /**
4720
- * A function which will invoked after an element was successfully highlighted.
4721
- *
4722
- * @callback HighlightCallback
4723
- * @param {Element} element The element successfully highlighted.
4724
- * @returns {void}
4725
- * @global
4726
- * @public
4727
- */
4728
-
4729
- /**
4730
- * @callback HookCallback
4731
- * @param {Object<string, any>} env The environment variables of the hook.
4732
- * @returns {void}
4733
- * @global
4734
- * @public
4735
- */
4736
-
4737
-
4738
- /* **********************************************
4739
- Begin prism-markup.js
4740
- ********************************************** */
4741
-
4742
- Prism.languages.markup = {
4743
- 'comment': {
4744
- pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
4745
- greedy: true
4746
- },
4747
- 'prolog': {
4748
- pattern: /<\?[\s\S]+?\?>/,
4749
- greedy: true
4750
- },
4751
- 'doctype': {
4752
- // https://www.w3.org/TR/xml/#NT-doctypedecl
4753
- pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
4754
- greedy: true,
4755
- inside: {
4756
- 'internal-subset': {
4757
- pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
4758
- lookbehind: true,
4759
- greedy: true,
4760
- inside: null // see below
4761
- },
4762
- 'string': {
4763
- pattern: /"[^"]*"|'[^']*'/,
4764
- greedy: true
4765
- },
4766
- 'punctuation': /^<!|>$|[[\]]/,
4767
- 'doctype-tag': /^DOCTYPE/i,
4768
- 'name': /[^\s<>'"]+/
4769
- }
4770
- },
4771
- 'cdata': {
4772
- pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
4773
- greedy: true
4774
- },
4775
- 'tag': {
4776
- pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
4777
- greedy: true,
4778
- inside: {
4779
- 'tag': {
4780
- pattern: /^<\/?[^\s>\/]+/,
4781
- inside: {
4782
- 'punctuation': /^<\/?/,
4783
- 'namespace': /^[^\s>\/:]+:/
4784
- }
4785
- },
4786
- 'special-attr': [],
4787
- 'attr-value': {
4788
- pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
4789
- inside: {
4790
- 'punctuation': [
4791
- {
4792
- pattern: /^=/,
4793
- alias: 'attr-equals'
4794
- },
4795
- {
4796
- pattern: /^(\s*)["']|["']$/,
4797
- lookbehind: true
4798
- }
4799
- ]
4800
- }
4801
- },
4802
- 'punctuation': /\/?>/,
4803
- 'attr-name': {
4804
- pattern: /[^\s>\/]+/,
4805
- inside: {
4806
- 'namespace': /^[^\s>\/:]+:/
4807
- }
4808
- }
4809
-
4810
- }
4811
- },
4812
- 'entity': [
4813
- {
4814
- pattern: /&[\da-z]{1,8};/i,
4815
- alias: 'named-entity'
4816
- },
4817
- /&#x?[\da-f]{1,8};/i
4818
- ]
4819
- };
4820
-
4821
- Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
4822
- Prism.languages.markup['entity'];
4823
- Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
4824
-
4825
- // Plugin to make entity title show the real entity, idea by Roman Komarov
4826
- Prism.hooks.add('wrap', function (env) {
4827
-
4828
- if (env.type === 'entity') {
4829
- env.attributes['title'] = env.content.replace(/&amp;/, '&');
4847
+ // hack for components to work correctly in node.js
4848
+ if (typeof commonjsGlobal !== 'undefined') {
4849
+ commonjsGlobal.Prism = Prism;
4830
4850
  }
4831
- });
4832
4851
 
4833
- Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
4852
+ // some additional documentation/types
4853
+
4834
4854
  /**
4835
- * Adds an inlined language to markup.
4855
+ * The expansion of a simple `RegExp` literal to support additional properties.
4836
4856
  *
4837
- * An example of an inlined language is CSS with `<style>` tags.
4857
+ * @typedef GrammarToken
4858
+ * @property {RegExp} pattern The regular expression of the token.
4859
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
4860
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
4861
+ * @property {boolean} [greedy=false] Whether the token is greedy.
4862
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
4863
+ * @property {Grammar} [inside] The nested grammar of this token.
4838
4864
  *
4839
- * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
4840
- * case insensitive.
4841
- * @param {string} lang The language key.
4842
- * @example
4843
- * addInlined('style', 'css');
4865
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
4866
+ *
4867
+ * This can be used to make nested and even recursive language definitions.
4868
+ *
4869
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
4870
+ * each another.
4871
+ * @global
4872
+ * @public
4844
4873
  */
4845
- value: function addInlined(tagName, lang) {
4846
- var includedCdataInside = {};
4847
- includedCdataInside['language-' + lang] = {
4848
- pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
4849
- lookbehind: true,
4850
- inside: Prism.languages[lang]
4851
- };
4852
- includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
4853
4874
 
4854
- var inside = {
4855
- 'included-cdata': {
4856
- pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
4857
- inside: includedCdataInside
4858
- }
4859
- };
4860
- inside['language-' + lang] = {
4861
- pattern: /[\s\S]+/,
4862
- inside: Prism.languages[lang]
4863
- };
4864
-
4865
- var def = {};
4866
- def[tagName] = {
4867
- pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
4868
- lookbehind: true,
4869
- greedy: true,
4870
- inside: inside
4871
- };
4875
+ /**
4876
+ * @typedef Grammar
4877
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
4878
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
4879
+ * @global
4880
+ * @public
4881
+ */
4872
4882
 
4873
- Prism.languages.insertBefore('markup', 'cdata', def);
4874
- }
4875
- });
4876
- Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
4877
4883
  /**
4878
- * Adds an pattern to highlight languages embedded in HTML attributes.
4884
+ * A function which will invoked after an element was successfully highlighted.
4879
4885
  *
4880
- * An example of an inlined language is CSS with `style` attributes.
4881
- *
4882
- * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
4883
- * case insensitive.
4884
- * @param {string} lang The language key.
4885
- * @example
4886
- * addAttribute('style', 'css');
4886
+ * @callback HighlightCallback
4887
+ * @param {Element} element The element successfully highlighted.
4888
+ * @returns {void}
4889
+ * @global
4890
+ * @public
4887
4891
  */
4888
- value: function (attrName, lang) {
4889
- Prism.languages.markup.tag.inside['special-attr'].push({
4890
- pattern: RegExp(
4891
- /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
4892
- 'i'
4893
- ),
4894
- lookbehind: true,
4892
+
4893
+ /**
4894
+ * @callback HookCallback
4895
+ * @param {Object<string, any>} env The environment variables of the hook.
4896
+ * @returns {void}
4897
+ * @global
4898
+ * @public
4899
+ */
4900
+
4901
+
4902
+ /* **********************************************
4903
+ Begin prism-markup.js
4904
+ ********************************************** */
4905
+
4906
+ Prism.languages.markup = {
4907
+ 'comment': {
4908
+ pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
4909
+ greedy: true
4910
+ },
4911
+ 'prolog': {
4912
+ pattern: /<\?[\s\S]+?\?>/,
4913
+ greedy: true
4914
+ },
4915
+ 'doctype': {
4916
+ // https://www.w3.org/TR/xml/#NT-doctypedecl
4917
+ pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
4918
+ greedy: true,
4919
+ inside: {
4920
+ 'internal-subset': {
4921
+ pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
4922
+ lookbehind: true,
4923
+ greedy: true,
4924
+ inside: null // see below
4925
+ },
4926
+ 'string': {
4927
+ pattern: /"[^"]*"|'[^']*'/,
4928
+ greedy: true
4929
+ },
4930
+ 'punctuation': /^<!|>$|[[\]]/,
4931
+ 'doctype-tag': /^DOCTYPE/i,
4932
+ 'name': /[^\s<>'"]+/
4933
+ }
4934
+ },
4935
+ 'cdata': {
4936
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
4937
+ greedy: true
4938
+ },
4939
+ 'tag': {
4940
+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
4941
+ greedy: true,
4895
4942
  inside: {
4896
- 'attr-name': /^[^\s=]+/,
4943
+ 'tag': {
4944
+ pattern: /^<\/?[^\s>\/]+/,
4945
+ inside: {
4946
+ 'punctuation': /^<\/?/,
4947
+ 'namespace': /^[^\s>\/:]+:/
4948
+ }
4949
+ },
4950
+ 'special-attr': [],
4897
4951
  'attr-value': {
4898
- pattern: /=[\s\S]+/,
4952
+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
4899
4953
  inside: {
4900
- 'value': {
4901
- pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
4902
- lookbehind: true,
4903
- alias: [lang, 'language-' + lang],
4904
- inside: Prism.languages[lang]
4905
- },
4906
4954
  'punctuation': [
4907
4955
  {
4908
4956
  pattern: /^=/,
4909
4957
  alias: 'attr-equals'
4910
4958
  },
4911
- /"|'/
4959
+ {
4960
+ pattern: /^(\s*)["']|["']$/,
4961
+ lookbehind: true
4962
+ }
4912
4963
  ]
4913
4964
  }
4965
+ },
4966
+ 'punctuation': /\/?>/,
4967
+ 'attr-name': {
4968
+ pattern: /[^\s>\/]+/,
4969
+ inside: {
4970
+ 'namespace': /^[^\s>\/:]+:/
4971
+ }
4914
4972
  }
4973
+
4915
4974
  }
4916
- });
4917
- }
4918
- });
4975
+ },
4976
+ 'entity': [
4977
+ {
4978
+ pattern: /&[\da-z]{1,8};/i,
4979
+ alias: 'named-entity'
4980
+ },
4981
+ /&#x?[\da-f]{1,8};/i
4982
+ ]
4983
+ };
4919
4984
 
4920
- Prism.languages.html = Prism.languages.markup;
4921
- Prism.languages.mathml = Prism.languages.markup;
4922
- Prism.languages.svg = Prism.languages.markup;
4985
+ Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
4986
+ Prism.languages.markup['entity'];
4987
+ Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
4923
4988
 
4924
- Prism.languages.xml = Prism.languages.extend('markup', {});
4925
- Prism.languages.ssml = Prism.languages.xml;
4926
- Prism.languages.atom = Prism.languages.xml;
4927
- Prism.languages.rss = Prism.languages.xml;
4989
+ // Plugin to make entity title show the real entity, idea by Roman Komarov
4990
+ Prism.hooks.add('wrap', function (env) {
4928
4991
 
4992
+ if (env.type === 'entity') {
4993
+ env.attributes['title'] = env.content.replace(/&amp;/, '&');
4994
+ }
4995
+ });
4929
4996
 
4930
- /* **********************************************
4931
- Begin prism-css.js
4932
- ********************************************** */
4997
+ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
4998
+ /**
4999
+ * Adds an inlined language to markup.
5000
+ *
5001
+ * An example of an inlined language is CSS with `<style>` tags.
5002
+ *
5003
+ * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
5004
+ * case insensitive.
5005
+ * @param {string} lang The language key.
5006
+ * @example
5007
+ * addInlined('style', 'css');
5008
+ */
5009
+ value: function addInlined(tagName, lang) {
5010
+ var includedCdataInside = {};
5011
+ includedCdataInside['language-' + lang] = {
5012
+ pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
5013
+ lookbehind: true,
5014
+ inside: Prism.languages[lang]
5015
+ };
5016
+ includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
4933
5017
 
4934
- (function (Prism) {
5018
+ var inside = {
5019
+ 'included-cdata': {
5020
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
5021
+ inside: includedCdataInside
5022
+ }
5023
+ };
5024
+ inside['language-' + lang] = {
5025
+ pattern: /[\s\S]+/,
5026
+ inside: Prism.languages[lang]
5027
+ };
4935
5028
 
4936
- var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
5029
+ var def = {};
5030
+ def[tagName] = {
5031
+ pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
5032
+ lookbehind: true,
5033
+ greedy: true,
5034
+ inside: inside
5035
+ };
4937
5036
 
4938
- Prism.languages.css = {
4939
- 'comment': /\/\*[\s\S]*?\*\//,
4940
- 'atrule': {
4941
- pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
4942
- inside: {
4943
- 'rule': /^@[\w-]+/,
4944
- 'selector-function-argument': {
4945
- pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
4946
- lookbehind: true,
4947
- alias: 'selector'
4948
- },
4949
- 'keyword': {
4950
- pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
4951
- lookbehind: true
5037
+ Prism.languages.insertBefore('markup', 'cdata', def);
5038
+ }
5039
+ });
5040
+ Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
5041
+ /**
5042
+ * Adds an pattern to highlight languages embedded in HTML attributes.
5043
+ *
5044
+ * An example of an inlined language is CSS with `style` attributes.
5045
+ *
5046
+ * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
5047
+ * case insensitive.
5048
+ * @param {string} lang The language key.
5049
+ * @example
5050
+ * addAttribute('style', 'css');
5051
+ */
5052
+ value: function (attrName, lang) {
5053
+ Prism.languages.markup.tag.inside['special-attr'].push({
5054
+ pattern: RegExp(
5055
+ /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
5056
+ 'i'
5057
+ ),
5058
+ lookbehind: true,
5059
+ inside: {
5060
+ 'attr-name': /^[^\s=]+/,
5061
+ 'attr-value': {
5062
+ pattern: /=[\s\S]+/,
5063
+ inside: {
5064
+ 'value': {
5065
+ pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
5066
+ lookbehind: true,
5067
+ alias: [lang, 'language-' + lang],
5068
+ inside: Prism.languages[lang]
5069
+ },
5070
+ 'punctuation': [
5071
+ {
5072
+ pattern: /^=/,
5073
+ alias: 'attr-equals'
5074
+ },
5075
+ /"|'/
5076
+ ]
5077
+ }
5078
+ }
4952
5079
  }
4953
- // See rest below
4954
- }
4955
- },
4956
- 'url': {
4957
- // https://drafts.csswg.org/css-values-3/#urls
4958
- pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
4959
- greedy: true,
4960
- inside: {
4961
- 'function': /^url/i,
4962
- 'punctuation': /^\(|\)$/,
4963
- 'string': {
4964
- pattern: RegExp('^' + string.source + '$'),
4965
- alias: 'url'
5080
+ });
5081
+ }
5082
+ });
5083
+
5084
+ Prism.languages.html = Prism.languages.markup;
5085
+ Prism.languages.mathml = Prism.languages.markup;
5086
+ Prism.languages.svg = Prism.languages.markup;
5087
+
5088
+ Prism.languages.xml = Prism.languages.extend('markup', {});
5089
+ Prism.languages.ssml = Prism.languages.xml;
5090
+ Prism.languages.atom = Prism.languages.xml;
5091
+ Prism.languages.rss = Prism.languages.xml;
5092
+
5093
+
5094
+ /* **********************************************
5095
+ Begin prism-css.js
5096
+ ********************************************** */
5097
+
5098
+ (function (Prism) {
5099
+
5100
+ var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
5101
+
5102
+ Prism.languages.css = {
5103
+ 'comment': /\/\*[\s\S]*?\*\//,
5104
+ 'atrule': {
5105
+ pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
5106
+ inside: {
5107
+ 'rule': /^@[\w-]+/,
5108
+ 'selector-function-argument': {
5109
+ pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
5110
+ lookbehind: true,
5111
+ alias: 'selector'
5112
+ },
5113
+ 'keyword': {
5114
+ pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
5115
+ lookbehind: true
5116
+ }
5117
+ // See rest below
4966
5118
  }
4967
- }
4968
- },
4969
- 'selector': {
4970
- pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
4971
- lookbehind: true
4972
- },
4973
- 'string': {
4974
- pattern: string,
4975
- greedy: true
4976
- },
4977
- 'property': {
4978
- pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
4979
- lookbehind: true
4980
- },
4981
- 'important': /!important\b/i,
4982
- 'function': {
4983
- pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
4984
- lookbehind: true
4985
- },
4986
- 'punctuation': /[(){};:,]/
4987
- };
5119
+ },
5120
+ 'url': {
5121
+ // https://drafts.csswg.org/css-values-3/#urls
5122
+ pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
5123
+ greedy: true,
5124
+ inside: {
5125
+ 'function': /^url/i,
5126
+ 'punctuation': /^\(|\)$/,
5127
+ 'string': {
5128
+ pattern: RegExp('^' + string.source + '$'),
5129
+ alias: 'url'
5130
+ }
5131
+ }
5132
+ },
5133
+ 'selector': {
5134
+ pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
5135
+ lookbehind: true
5136
+ },
5137
+ 'string': {
5138
+ pattern: string,
5139
+ greedy: true
5140
+ },
5141
+ 'property': {
5142
+ pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
5143
+ lookbehind: true
5144
+ },
5145
+ 'important': /!important\b/i,
5146
+ 'function': {
5147
+ pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
5148
+ lookbehind: true
5149
+ },
5150
+ 'punctuation': /[(){};:,]/
5151
+ };
4988
5152
 
4989
- Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
5153
+ Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
4990
5154
 
4991
- var markup = Prism.languages.markup;
4992
- if (markup) {
4993
- markup.tag.addInlined('style', 'css');
4994
- markup.tag.addAttribute('style', 'css');
4995
- }
5155
+ var markup = Prism.languages.markup;
5156
+ if (markup) {
5157
+ markup.tag.addInlined('style', 'css');
5158
+ markup.tag.addAttribute('style', 'css');
5159
+ }
4996
5160
 
4997
- }(Prism));
5161
+ }(Prism));
4998
5162
 
4999
5163
 
5000
- /* **********************************************
5001
- Begin prism-clike.js
5002
- ********************************************** */
5164
+ /* **********************************************
5165
+ Begin prism-clike.js
5166
+ ********************************************** */
5003
5167
 
5004
- Prism.languages.clike = {
5005
- 'comment': [
5006
- {
5007
- pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
5008
- lookbehind: true,
5168
+ Prism.languages.clike = {
5169
+ 'comment': [
5170
+ {
5171
+ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
5172
+ lookbehind: true,
5173
+ greedy: true
5174
+ },
5175
+ {
5176
+ pattern: /(^|[^\\:])\/\/.*/,
5177
+ lookbehind: true,
5178
+ greedy: true
5179
+ }
5180
+ ],
5181
+ 'string': {
5182
+ pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
5009
5183
  greedy: true
5010
5184
  },
5011
- {
5012
- pattern: /(^|[^\\:])\/\/.*/,
5185
+ 'class-name': {
5186
+ pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
5013
5187
  lookbehind: true,
5014
- greedy: true
5015
- }
5016
- ],
5017
- 'string': {
5018
- pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
5019
- greedy: true
5020
- },
5021
- 'class-name': {
5022
- pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
5023
- lookbehind: true,
5024
- inside: {
5025
- 'punctuation': /[.\\]/
5026
- }
5027
- },
5028
- 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
5029
- 'boolean': /\b(?:false|true)\b/,
5030
- 'function': /\b\w+(?=\()/,
5031
- 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
5032
- 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
5033
- 'punctuation': /[{}[\];(),.:]/
5034
- };
5188
+ inside: {
5189
+ 'punctuation': /[.\\]/
5190
+ }
5191
+ },
5192
+ 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
5193
+ 'boolean': /\b(?:false|true)\b/,
5194
+ 'function': /\b\w+(?=\()/,
5195
+ 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
5196
+ 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
5197
+ 'punctuation': /[{}[\];(),.:]/
5198
+ };
5035
5199
 
5036
5200
 
5037
- /* **********************************************
5038
- Begin prism-javascript.js
5039
- ********************************************** */
5201
+ /* **********************************************
5202
+ Begin prism-javascript.js
5203
+ ********************************************** */
5040
5204
 
5041
- Prism.languages.javascript = Prism.languages.extend('clike', {
5042
- 'class-name': [
5043
- Prism.languages.clike['class-name'],
5044
- {
5045
- pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
5046
- lookbehind: true
5047
- }
5048
- ],
5049
- 'keyword': [
5050
- {
5051
- pattern: /((?:^|\})\s*)catch\b/,
5052
- lookbehind: true
5053
- },
5054
- {
5055
- pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
5205
+ Prism.languages.javascript = Prism.languages.extend('clike', {
5206
+ 'class-name': [
5207
+ Prism.languages.clike['class-name'],
5208
+ {
5209
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
5210
+ lookbehind: true
5211
+ }
5212
+ ],
5213
+ 'keyword': [
5214
+ {
5215
+ pattern: /((?:^|\})\s*)catch\b/,
5216
+ lookbehind: true
5217
+ },
5218
+ {
5219
+ pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
5220
+ lookbehind: true
5221
+ },
5222
+ ],
5223
+ // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
5224
+ 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
5225
+ 'number': {
5226
+ pattern: RegExp(
5227
+ /(^|[^\w$])/.source +
5228
+ '(?:' +
5229
+ (
5230
+ // constant
5231
+ /NaN|Infinity/.source +
5232
+ '|' +
5233
+ // binary integer
5234
+ /0[bB][01]+(?:_[01]+)*n?/.source +
5235
+ '|' +
5236
+ // octal integer
5237
+ /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
5238
+ '|' +
5239
+ // hexadecimal integer
5240
+ /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
5241
+ '|' +
5242
+ // decimal bigint
5243
+ /\d+(?:_\d+)*n/.source +
5244
+ '|' +
5245
+ // decimal number (integer or float) but no bigint
5246
+ /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
5247
+ ) +
5248
+ ')' +
5249
+ /(?![\w$])/.source
5250
+ ),
5056
5251
  lookbehind: true
5057
5252
  },
5058
- ],
5059
- // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
5060
- 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
5061
- 'number': {
5062
- pattern: RegExp(
5063
- /(^|[^\w$])/.source +
5064
- '(?:' +
5065
- (
5066
- // constant
5067
- /NaN|Infinity/.source +
5068
- '|' +
5069
- // binary integer
5070
- /0[bB][01]+(?:_[01]+)*n?/.source +
5071
- '|' +
5072
- // octal integer
5073
- /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
5074
- '|' +
5075
- // hexadecimal integer
5076
- /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
5077
- '|' +
5078
- // decimal bigint
5079
- /\d+(?:_\d+)*n/.source +
5253
+ 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
5254
+ });
5255
+
5256
+ Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
5257
+
5258
+ Prism.languages.insertBefore('javascript', 'keyword', {
5259
+ 'regex': {
5260
+ pattern: RegExp(
5261
+ // lookbehind
5262
+ // eslint-disable-next-line regexp/no-dupe-characters-character-class
5263
+ /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
5264
+ // Regex pattern:
5265
+ // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
5266
+ // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
5267
+ // with the only syntax, so we have to define 2 different regex patterns.
5268
+ /\//.source +
5269
+ '(?:' +
5270
+ /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
5080
5271
  '|' +
5081
- // decimal number (integer or float) but no bigint
5082
- /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
5083
- ) +
5084
- ')' +
5085
- /(?![\w$])/.source
5086
- ),
5087
- lookbehind: true
5088
- },
5089
- 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
5090
- });
5091
-
5092
- Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
5093
-
5094
- Prism.languages.insertBefore('javascript', 'keyword', {
5095
- 'regex': {
5096
- pattern: RegExp(
5097
- // lookbehind
5098
- // eslint-disable-next-line regexp/no-dupe-characters-character-class
5099
- /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
5100
- // Regex pattern:
5101
- // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
5102
- // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
5103
- // with the only syntax, so we have to define 2 different regex patterns.
5104
- /\//.source +
5105
- '(?:' +
5106
- /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
5107
- '|' +
5108
- // `v` flag syntax. This supports 3 levels of nested character classes.
5109
- /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
5110
- ')' +
5111
- // lookahead
5112
- /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
5113
- ),
5114
- lookbehind: true,
5115
- greedy: true,
5116
- inside: {
5117
- 'regex-source': {
5118
- pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
5119
- lookbehind: true,
5120
- alias: 'language-regex',
5121
- inside: Prism.languages.regex
5122
- },
5123
- 'regex-delimiter': /^\/|\/$/,
5124
- 'regex-flags': /^[a-z]+$/,
5125
- }
5126
- },
5127
- // This must be declared before keyword because we use "function" inside the look-forward
5128
- 'function-variable': {
5129
- pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
5130
- alias: 'function'
5131
- },
5132
- 'parameter': [
5133
- {
5134
- pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
5135
- lookbehind: true,
5136
- inside: Prism.languages.javascript
5137
- },
5138
- {
5139
- pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
5272
+ // `v` flag syntax. This supports 3 levels of nested character classes.
5273
+ /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
5274
+ ')' +
5275
+ // lookahead
5276
+ /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
5277
+ ),
5140
5278
  lookbehind: true,
5141
- inside: Prism.languages.javascript
5279
+ greedy: true,
5280
+ inside: {
5281
+ 'regex-source': {
5282
+ pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
5283
+ lookbehind: true,
5284
+ alias: 'language-regex',
5285
+ inside: Prism.languages.regex
5286
+ },
5287
+ 'regex-delimiter': /^\/|\/$/,
5288
+ 'regex-flags': /^[a-z]+$/,
5289
+ }
5142
5290
  },
5143
- {
5144
- pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
5145
- lookbehind: true,
5146
- inside: Prism.languages.javascript
5291
+ // This must be declared before keyword because we use "function" inside the look-forward
5292
+ 'function-variable': {
5293
+ pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
5294
+ alias: 'function'
5147
5295
  },
5148
- {
5149
- pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
5150
- lookbehind: true,
5151
- inside: Prism.languages.javascript
5152
- }
5153
- ],
5154
- 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
5155
- });
5156
-
5157
- Prism.languages.insertBefore('javascript', 'string', {
5158
- 'hashbang': {
5159
- pattern: /^#!.*/,
5160
- greedy: true,
5161
- alias: 'comment'
5162
- },
5163
- 'template-string': {
5164
- pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
5165
- greedy: true,
5166
- inside: {
5167
- 'template-punctuation': {
5168
- pattern: /^`|`$/,
5169
- alias: 'string'
5296
+ 'parameter': [
5297
+ {
5298
+ pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
5299
+ lookbehind: true,
5300
+ inside: Prism.languages.javascript
5170
5301
  },
5171
- 'interpolation': {
5172
- pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
5302
+ {
5303
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
5173
5304
  lookbehind: true,
5174
- inside: {
5175
- 'interpolation-punctuation': {
5176
- pattern: /^\$\{|\}$/,
5177
- alias: 'punctuation'
5178
- },
5179
- rest: Prism.languages.javascript
5180
- }
5305
+ inside: Prism.languages.javascript
5181
5306
  },
5182
- 'string': /[\s\S]+/
5307
+ {
5308
+ pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
5309
+ lookbehind: true,
5310
+ inside: Prism.languages.javascript
5311
+ },
5312
+ {
5313
+ pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
5314
+ lookbehind: true,
5315
+ inside: Prism.languages.javascript
5316
+ }
5317
+ ],
5318
+ 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
5319
+ });
5320
+
5321
+ Prism.languages.insertBefore('javascript', 'string', {
5322
+ 'hashbang': {
5323
+ pattern: /^#!.*/,
5324
+ greedy: true,
5325
+ alias: 'comment'
5326
+ },
5327
+ 'template-string': {
5328
+ pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
5329
+ greedy: true,
5330
+ inside: {
5331
+ 'template-punctuation': {
5332
+ pattern: /^`|`$/,
5333
+ alias: 'string'
5334
+ },
5335
+ 'interpolation': {
5336
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
5337
+ lookbehind: true,
5338
+ inside: {
5339
+ 'interpolation-punctuation': {
5340
+ pattern: /^\$\{|\}$/,
5341
+ alias: 'punctuation'
5342
+ },
5343
+ rest: Prism.languages.javascript
5344
+ }
5345
+ },
5346
+ 'string': /[\s\S]+/
5347
+ }
5348
+ },
5349
+ 'string-property': {
5350
+ pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
5351
+ lookbehind: true,
5352
+ greedy: true,
5353
+ alias: 'property'
5183
5354
  }
5184
- },
5185
- 'string-property': {
5186
- pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
5187
- lookbehind: true,
5188
- greedy: true,
5189
- alias: 'property'
5190
- }
5191
- });
5355
+ });
5192
5356
 
5193
- Prism.languages.insertBefore('javascript', 'operator', {
5194
- 'literal-property': {
5195
- pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
5196
- lookbehind: true,
5197
- alias: 'property'
5198
- },
5199
- });
5357
+ Prism.languages.insertBefore('javascript', 'operator', {
5358
+ 'literal-property': {
5359
+ pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
5360
+ lookbehind: true,
5361
+ alias: 'property'
5362
+ },
5363
+ });
5200
5364
 
5201
- if (Prism.languages.markup) {
5202
- Prism.languages.markup.tag.addInlined('script', 'javascript');
5365
+ if (Prism.languages.markup) {
5366
+ Prism.languages.markup.tag.addInlined('script', 'javascript');
5203
5367
 
5204
- // add attribute support for all DOM events.
5205
- // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
5206
- Prism.languages.markup.tag.addAttribute(
5207
- /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
5208
- 'javascript'
5209
- );
5210
- }
5368
+ // add attribute support for all DOM events.
5369
+ // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
5370
+ Prism.languages.markup.tag.addAttribute(
5371
+ /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
5372
+ 'javascript'
5373
+ );
5374
+ }
5211
5375
 
5212
- Prism.languages.js = Prism.languages.javascript;
5376
+ Prism.languages.js = Prism.languages.javascript;
5213
5377
 
5214
5378
 
5215
- /* **********************************************
5216
- Begin prism-file-highlight.js
5217
- ********************************************** */
5379
+ /* **********************************************
5380
+ Begin prism-file-highlight.js
5381
+ ********************************************** */
5218
5382
 
5219
- (function () {
5383
+ (function () {
5220
5384
 
5221
- if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5222
- return;
5223
- }
5385
+ if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5386
+ return;
5387
+ }
5224
5388
 
5225
- // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
5226
- if (!Element.prototype.matches) {
5227
- Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
5228
- }
5389
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
5390
+ if (!Element.prototype.matches) {
5391
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
5392
+ }
5229
5393
 
5230
- var LOADING_MESSAGE = 'Loading…';
5231
- var FAILURE_MESSAGE = function (status, message) {
5232
- return '✖ Error ' + status + ' while fetching file: ' + message;
5233
- };
5234
- var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
5235
-
5236
- var EXTENSIONS = {
5237
- 'js': 'javascript',
5238
- 'py': 'python',
5239
- 'rb': 'ruby',
5240
- 'ps1': 'powershell',
5241
- 'psm1': 'powershell',
5242
- 'sh': 'bash',
5243
- 'bat': 'batch',
5244
- 'h': 'c',
5245
- 'tex': 'latex'
5246
- };
5394
+ var LOADING_MESSAGE = 'Loading…';
5395
+ var FAILURE_MESSAGE = function (status, message) {
5396
+ return '✖ Error ' + status + ' while fetching file: ' + message;
5397
+ };
5398
+ var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
5399
+
5400
+ var EXTENSIONS = {
5401
+ 'js': 'javascript',
5402
+ 'py': 'python',
5403
+ 'rb': 'ruby',
5404
+ 'ps1': 'powershell',
5405
+ 'psm1': 'powershell',
5406
+ 'sh': 'bash',
5407
+ 'bat': 'batch',
5408
+ 'h': 'c',
5409
+ 'tex': 'latex'
5410
+ };
5247
5411
 
5248
- var STATUS_ATTR = 'data-src-status';
5249
- var STATUS_LOADING = 'loading';
5250
- var STATUS_LOADED = 'loaded';
5251
- var STATUS_FAILED = 'failed';
5412
+ var STATUS_ATTR = 'data-src-status';
5413
+ var STATUS_LOADING = 'loading';
5414
+ var STATUS_LOADED = 'loaded';
5415
+ var STATUS_FAILED = 'failed';
5252
5416
 
5253
- var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
5254
- + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
5417
+ var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
5418
+ + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
5255
5419
 
5256
- /**
5257
- * Loads the given file.
5258
- *
5259
- * @param {string} src The URL or path of the source file to load.
5260
- * @param {(result: string) => void} success
5261
- * @param {(reason: string) => void} error
5262
- */
5263
- function loadFile(src, success, error) {
5264
- var xhr = new XMLHttpRequest();
5265
- xhr.open('GET', src, true);
5266
- xhr.onreadystatechange = function () {
5267
- if (xhr.readyState == 4) {
5268
- if (xhr.status < 400 && xhr.responseText) {
5269
- success(xhr.responseText);
5270
- } else {
5271
- if (xhr.status >= 400) {
5272
- error(FAILURE_MESSAGE(xhr.status, xhr.statusText));
5420
+ /**
5421
+ * Loads the given file.
5422
+ *
5423
+ * @param {string} src The URL or path of the source file to load.
5424
+ * @param {(result: string) => void} success
5425
+ * @param {(reason: string) => void} error
5426
+ */
5427
+ function loadFile(src, success, error) {
5428
+ var xhr = new XMLHttpRequest();
5429
+ xhr.open('GET', src, true);
5430
+ xhr.onreadystatechange = function () {
5431
+ if (xhr.readyState == 4) {
5432
+ if (xhr.status < 400 && xhr.responseText) {
5433
+ success(xhr.responseText);
5273
5434
  } else {
5274
- error(FAILURE_EMPTY_MESSAGE);
5435
+ if (xhr.status >= 400) {
5436
+ error(FAILURE_MESSAGE(xhr.status, xhr.statusText));
5437
+ } else {
5438
+ error(FAILURE_EMPTY_MESSAGE);
5439
+ }
5275
5440
  }
5276
5441
  }
5277
- }
5278
- };
5279
- xhr.send(null);
5280
- }
5442
+ };
5443
+ xhr.send(null);
5444
+ }
5281
5445
 
5282
- /**
5283
- * Parses the given range.
5284
- *
5285
- * This returns a range with inclusive ends.
5286
- *
5287
- * @param {string | null | undefined} range
5288
- * @returns {[number, number | undefined] | undefined}
5289
- */
5290
- function parseRange(range) {
5291
- var m = /^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(range || '');
5292
- if (m) {
5293
- var start = Number(m[1]);
5294
- var comma = m[2];
5295
- var end = m[3];
5296
-
5297
- if (!comma) {
5298
- return [start, start];
5299
- }
5300
- if (!end) {
5301
- return [start, undefined];
5446
+ /**
5447
+ * Parses the given range.
5448
+ *
5449
+ * This returns a range with inclusive ends.
5450
+ *
5451
+ * @param {string | null | undefined} range
5452
+ * @returns {[number, number | undefined] | undefined}
5453
+ */
5454
+ function parseRange(range) {
5455
+ var m = /^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(range || '');
5456
+ if (m) {
5457
+ var start = Number(m[1]);
5458
+ var comma = m[2];
5459
+ var end = m[3];
5460
+
5461
+ if (!comma) {
5462
+ return [start, start];
5463
+ }
5464
+ if (!end) {
5465
+ return [start, undefined];
5466
+ }
5467
+ return [start, Number(end)];
5302
5468
  }
5303
- return [start, Number(end)];
5469
+ return undefined;
5304
5470
  }
5305
- return undefined;
5306
- }
5307
5471
 
5308
- Prism.hooks.add('before-highlightall', function (env) {
5309
- env.selector += ', ' + SELECTOR;
5310
- });
5472
+ Prism.hooks.add('before-highlightall', function (env) {
5473
+ env.selector += ', ' + SELECTOR;
5474
+ });
5311
5475
 
5312
- Prism.hooks.add('before-sanity-check', function (env) {
5313
- var pre = /** @type {HTMLPreElement} */ (env.element);
5314
- if (pre.matches(SELECTOR)) {
5315
- env.code = ''; // fast-path the whole thing and go to complete
5476
+ Prism.hooks.add('before-sanity-check', function (env) {
5477
+ var pre = /** @type {HTMLPreElement} */ (env.element);
5478
+ if (pre.matches(SELECTOR)) {
5479
+ env.code = ''; // fast-path the whole thing and go to complete
5316
5480
 
5317
- pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
5481
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
5318
5482
 
5319
- // add code element with loading message
5320
- var code = pre.appendChild(document.createElement('CODE'));
5321
- code.textContent = LOADING_MESSAGE;
5483
+ // add code element with loading message
5484
+ var code = pre.appendChild(document.createElement('CODE'));
5485
+ code.textContent = LOADING_MESSAGE;
5322
5486
 
5323
- var src = pre.getAttribute('data-src');
5487
+ var src = pre.getAttribute('data-src');
5324
5488
 
5325
- var language = env.language;
5326
- if (language === 'none') {
5327
- // the language might be 'none' because there is no language set;
5328
- // in this case, we want to use the extension as the language
5329
- var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
5330
- language = EXTENSIONS[extension] || extension;
5331
- }
5489
+ var language = env.language;
5490
+ if (language === 'none') {
5491
+ // the language might be 'none' because there is no language set;
5492
+ // in this case, we want to use the extension as the language
5493
+ var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
5494
+ language = EXTENSIONS[extension] || extension;
5495
+ }
5332
5496
 
5333
- // set language classes
5334
- Prism.util.setLanguage(code, language);
5335
- Prism.util.setLanguage(pre, language);
5497
+ // set language classes
5498
+ Prism.util.setLanguage(code, language);
5499
+ Prism.util.setLanguage(pre, language);
5336
5500
 
5337
- // preload the language
5338
- var autoloader = Prism.plugins.autoloader;
5339
- if (autoloader) {
5340
- autoloader.loadLanguages(language);
5341
- }
5501
+ // preload the language
5502
+ var autoloader = Prism.plugins.autoloader;
5503
+ if (autoloader) {
5504
+ autoloader.loadLanguages(language);
5505
+ }
5342
5506
 
5343
- // load file
5344
- loadFile(
5345
- src,
5346
- function (text) {
5347
- // mark as loaded
5348
- pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
5507
+ // load file
5508
+ loadFile(
5509
+ src,
5510
+ function (text) {
5511
+ // mark as loaded
5512
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
5349
5513
 
5350
- // handle data-range
5351
- var range = parseRange(pre.getAttribute('data-range'));
5352
- if (range) {
5353
- var lines = text.split(/\r\n?|\n/g);
5514
+ // handle data-range
5515
+ var range = parseRange(pre.getAttribute('data-range'));
5516
+ if (range) {
5517
+ var lines = text.split(/\r\n?|\n/g);
5354
5518
 
5355
- // the range is one-based and inclusive on both ends
5356
- var start = range[0];
5357
- var end = range[1] == null ? lines.length : range[1];
5519
+ // the range is one-based and inclusive on both ends
5520
+ var start = range[0];
5521
+ var end = range[1] == null ? lines.length : range[1];
5358
5522
 
5359
- if (start < 0) { start += lines.length; }
5360
- start = Math.max(0, Math.min(start - 1, lines.length));
5361
- if (end < 0) { end += lines.length; }
5362
- end = Math.max(0, Math.min(end, lines.length));
5523
+ if (start < 0) { start += lines.length; }
5524
+ start = Math.max(0, Math.min(start - 1, lines.length));
5525
+ if (end < 0) { end += lines.length; }
5526
+ end = Math.max(0, Math.min(end, lines.length));
5363
5527
 
5364
- text = lines.slice(start, end).join('\n');
5528
+ text = lines.slice(start, end).join('\n');
5365
5529
 
5366
- // add data-start for line numbers
5367
- if (!pre.hasAttribute('data-start')) {
5368
- pre.setAttribute('data-start', String(start + 1));
5530
+ // add data-start for line numbers
5531
+ if (!pre.hasAttribute('data-start')) {
5532
+ pre.setAttribute('data-start', String(start + 1));
5533
+ }
5369
5534
  }
5370
- }
5371
5535
 
5372
- // highlight code
5373
- code.textContent = text;
5374
- Prism.highlightElement(code);
5375
- },
5376
- function (error) {
5377
- // mark as failed
5378
- pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
5536
+ // highlight code
5537
+ code.textContent = text;
5538
+ Prism.highlightElement(code);
5539
+ },
5540
+ function (error) {
5541
+ // mark as failed
5542
+ pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
5379
5543
 
5380
- code.textContent = error;
5381
- }
5382
- );
5383
- }
5384
- });
5544
+ code.textContent = error;
5545
+ }
5546
+ );
5547
+ }
5548
+ });
5385
5549
 
5386
- Prism.plugins.fileHighlight = {
5387
- /**
5388
- * Executes the File Highlight plugin for all matching `pre` elements under the given container.
5389
- *
5390
- * Note: Elements which are already loaded or currently loading will not be touched by this method.
5391
- *
5392
- * @param {ParentNode} [container=document]
5393
- */
5394
- highlight: function highlight(container) {
5395
- var elements = (container || document).querySelectorAll(SELECTOR);
5550
+ Prism.plugins.fileHighlight = {
5551
+ /**
5552
+ * Executes the File Highlight plugin for all matching `pre` elements under the given container.
5553
+ *
5554
+ * Note: Elements which are already loaded or currently loading will not be touched by this method.
5555
+ *
5556
+ * @param {ParentNode} [container=document]
5557
+ */
5558
+ highlight: function highlight(container) {
5559
+ var elements = (container || document).querySelectorAll(SELECTOR);
5396
5560
 
5397
- for (var i = 0, element; (element = elements[i++]);) {
5398
- Prism.highlightElement(element);
5561
+ for (var i = 0, element; (element = elements[i++]);) {
5562
+ Prism.highlightElement(element);
5563
+ }
5399
5564
  }
5400
- }
5401
- };
5402
-
5403
- var logged = false;
5404
- /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
5405
- Prism.fileHighlight = function () {
5406
- if (!logged) {
5407
- console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
5408
- logged = true;
5409
- }
5410
- Prism.plugins.fileHighlight.highlight.apply(this, arguments);
5411
- };
5565
+ };
5412
5566
 
5413
- }());
5414
- } (prism));
5415
-
5416
- Prism.languages.python = {
5417
- 'comment': {
5418
- pattern: /(^|[^\\])#.*/,
5419
- lookbehind: true,
5420
- greedy: true
5421
- },
5422
- 'string-interpolation': {
5423
- pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
5424
- greedy: true,
5425
- inside: {
5426
- 'interpolation': {
5427
- // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
5428
- pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,
5429
- lookbehind: true,
5430
- inside: {
5431
- 'format-spec': {
5432
- pattern: /(:)[^:(){}]+(?=\}$)/,
5433
- lookbehind: true
5434
- },
5435
- 'conversion-option': {
5436
- pattern: /![sra](?=[:}]$)/,
5437
- alias: 'punctuation'
5438
- },
5439
- rest: null
5567
+ var logged = false;
5568
+ /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
5569
+ Prism.fileHighlight = function () {
5570
+ if (!logged) {
5571
+ console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
5572
+ logged = true;
5440
5573
  }
5441
- },
5442
- 'string': /[\s\S]+/
5443
- }
5444
- },
5445
- 'triple-quoted-string': {
5446
- pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,
5447
- greedy: true,
5448
- alias: 'string'
5449
- },
5450
- 'string': {
5451
- pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
5452
- greedy: true
5453
- },
5454
- 'function': {
5455
- pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
5456
- lookbehind: true
5457
- },
5458
- 'class-name': {
5459
- pattern: /(\bclass\s+)\w+/i,
5460
- lookbehind: true
5461
- },
5462
- 'decorator': {
5463
- pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m,
5464
- lookbehind: true,
5465
- alias: ['annotation', 'punctuation'],
5466
- inside: {
5467
- 'punctuation': /\./
5468
- }
5469
- },
5470
- 'keyword': /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
5471
- 'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
5472
- 'boolean': /\b(?:False|None|True)\b/,
5473
- 'number': /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,
5474
- 'operator': /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
5475
- 'punctuation': /[{}[\];(),.:]/
5476
- };
5574
+ Prism.plugins.fileHighlight.highlight.apply(this, arguments);
5575
+ };
5477
5576
 
5478
- Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python;
5577
+ }());
5578
+ } (prism));
5579
+ return prism.exports;
5580
+ }
5479
5581
 
5480
- Prism.languages.py = Prism.languages.python;
5582
+ requirePrism();
5481
5583
 
5482
- (function () {
5584
+ var prismPython = {};
5483
5585
 
5484
- if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5485
- return;
5486
- }
5586
+ var hasRequiredPrismPython;
5487
5587
 
5488
- /**
5489
- * Plugin name which is used as a class name for <pre> which is activating the plugin
5490
- *
5491
- * @type {string}
5492
- */
5493
- var PLUGIN_NAME = 'line-numbers';
5588
+ function requirePrismPython () {
5589
+ if (hasRequiredPrismPython) return prismPython;
5590
+ hasRequiredPrismPython = 1;
5591
+ Prism.languages.python = {
5592
+ 'comment': {
5593
+ pattern: /(^|[^\\])#.*/,
5594
+ lookbehind: true,
5595
+ greedy: true
5596
+ },
5597
+ 'string-interpolation': {
5598
+ pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
5599
+ greedy: true,
5600
+ inside: {
5601
+ 'interpolation': {
5602
+ // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
5603
+ pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,
5604
+ lookbehind: true,
5605
+ inside: {
5606
+ 'format-spec': {
5607
+ pattern: /(:)[^:(){}]+(?=\}$)/,
5608
+ lookbehind: true
5609
+ },
5610
+ 'conversion-option': {
5611
+ pattern: /![sra](?=[:}]$)/,
5612
+ alias: 'punctuation'
5613
+ },
5614
+ rest: null
5615
+ }
5616
+ },
5617
+ 'string': /[\s\S]+/
5618
+ }
5619
+ },
5620
+ 'triple-quoted-string': {
5621
+ pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,
5622
+ greedy: true,
5623
+ alias: 'string'
5624
+ },
5625
+ 'string': {
5626
+ pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
5627
+ greedy: true
5628
+ },
5629
+ 'function': {
5630
+ pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
5631
+ lookbehind: true
5632
+ },
5633
+ 'class-name': {
5634
+ pattern: /(\bclass\s+)\w+/i,
5635
+ lookbehind: true
5636
+ },
5637
+ 'decorator': {
5638
+ pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m,
5639
+ lookbehind: true,
5640
+ alias: ['annotation', 'punctuation'],
5641
+ inside: {
5642
+ 'punctuation': /\./
5643
+ }
5644
+ },
5645
+ 'keyword': /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
5646
+ 'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
5647
+ 'boolean': /\b(?:False|None|True)\b/,
5648
+ 'number': /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,
5649
+ 'operator': /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
5650
+ 'punctuation': /[{}[\];(),.:]/
5651
+ };
5494
5652
 
5495
- /**
5496
- * Regular expression used for determining line breaks
5497
- *
5498
- * @type {RegExp}
5499
- */
5500
- var NEW_LINE_EXP = /\n(?!$)/g;
5653
+ Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python;
5501
5654
 
5655
+ Prism.languages.py = Prism.languages.python;
5656
+ return prismPython;
5657
+ }
5502
5658
 
5503
- /**
5504
- * Global exports
5505
- */
5506
- var config = Prism.plugins.lineNumbers = {
5507
- /**
5508
- * Get node for provided line number
5509
- *
5510
- * @param {Element} element pre element
5511
- * @param {number} number line number
5512
- * @returns {Element|undefined}
5513
- */
5514
- getLine: function (element, number) {
5515
- if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_NAME)) {
5516
- return;
5517
- }
5659
+ requirePrismPython();
5518
5660
 
5519
- var lineNumberRows = element.querySelector('.line-numbers-rows');
5520
- if (!lineNumberRows) {
5521
- return;
5522
- }
5523
- var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
5524
- var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
5661
+ var prismLineNumbers = {};
5525
5662
 
5526
- if (number < lineNumberStart) {
5527
- number = lineNumberStart;
5528
- }
5529
- if (number > lineNumberEnd) {
5530
- number = lineNumberEnd;
5531
- }
5663
+ var hasRequiredPrismLineNumbers;
5532
5664
 
5533
- var lineIndex = number - lineNumberStart;
5665
+ function requirePrismLineNumbers () {
5666
+ if (hasRequiredPrismLineNumbers) return prismLineNumbers;
5667
+ hasRequiredPrismLineNumbers = 1;
5668
+ (function () {
5534
5669
 
5535
- return lineNumberRows.children[lineIndex];
5536
- },
5670
+ if (typeof Prism === 'undefined' || typeof document === 'undefined') {
5671
+ return;
5672
+ }
5537
5673
 
5538
5674
  /**
5539
- * Resizes the line numbers of the given element.
5675
+ * Plugin name which is used as a class name for <pre> which is activating the plugin
5540
5676
  *
5541
- * This function will not add line numbers. It will only resize existing ones.
5542
- *
5543
- * @param {HTMLElement} element A `<pre>` element with line numbers.
5544
- * @returns {void}
5677
+ * @type {string}
5545
5678
  */
5546
- resize: function (element) {
5547
- resizeElements([element]);
5548
- },
5679
+ var PLUGIN_NAME = 'line-numbers';
5549
5680
 
5550
5681
  /**
5551
- * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
5552
- * the current viewport.
5553
- *
5554
- * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
5682
+ * Regular expression used for determining line breaks
5555
5683
  *
5556
- * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
5557
- *
5558
- * @type {boolean}
5684
+ * @type {RegExp}
5559
5685
  */
5560
- assumeViewportIndependence: true
5561
- };
5686
+ var NEW_LINE_EXP = /\n(?!$)/g;
5562
5687
 
5563
- /**
5564
- * Resizes the given elements.
5565
- *
5566
- * @param {HTMLElement[]} elements
5567
- */
5568
- function resizeElements(elements) {
5569
- elements = elements.filter(function (e) {
5570
- var codeStyles = getStyles(e);
5571
- var whiteSpace = codeStyles['white-space'];
5572
- return whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line';
5573
- });
5574
5688
 
5575
- if (elements.length == 0) {
5576
- return;
5577
- }
5689
+ /**
5690
+ * Global exports
5691
+ */
5692
+ var config = Prism.plugins.lineNumbers = {
5693
+ /**
5694
+ * Get node for provided line number
5695
+ *
5696
+ * @param {Element} element pre element
5697
+ * @param {number} number line number
5698
+ * @returns {Element|undefined}
5699
+ */
5700
+ getLine: function (element, number) {
5701
+ if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_NAME)) {
5702
+ return;
5703
+ }
5578
5704
 
5579
- var infos = elements.map(function (element) {
5580
- var codeElement = element.querySelector('code');
5581
- var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
5582
- if (!codeElement || !lineNumbersWrapper) {
5583
- return undefined;
5584
- }
5705
+ var lineNumberRows = element.querySelector('.line-numbers-rows');
5706
+ if (!lineNumberRows) {
5707
+ return;
5708
+ }
5709
+ var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
5710
+ var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
5711
+
5712
+ if (number < lineNumberStart) {
5713
+ number = lineNumberStart;
5714
+ }
5715
+ if (number > lineNumberEnd) {
5716
+ number = lineNumberEnd;
5717
+ }
5585
5718
 
5586
- /** @type {HTMLElement} */
5587
- var lineNumberSizer = element.querySelector('.line-numbers-sizer');
5588
- var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
5719
+ var lineIndex = number - lineNumberStart;
5720
+
5721
+ return lineNumberRows.children[lineIndex];
5722
+ },
5723
+
5724
+ /**
5725
+ * Resizes the line numbers of the given element.
5726
+ *
5727
+ * This function will not add line numbers. It will only resize existing ones.
5728
+ *
5729
+ * @param {HTMLElement} element A `<pre>` element with line numbers.
5730
+ * @returns {void}
5731
+ */
5732
+ resize: function (element) {
5733
+ resizeElements([element]);
5734
+ },
5735
+
5736
+ /**
5737
+ * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
5738
+ * the current viewport.
5739
+ *
5740
+ * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
5741
+ *
5742
+ * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
5743
+ *
5744
+ * @type {boolean}
5745
+ */
5746
+ assumeViewportIndependence: true
5747
+ };
5589
5748
 
5590
- if (!lineNumberSizer) {
5591
- lineNumberSizer = document.createElement('span');
5592
- lineNumberSizer.className = 'line-numbers-sizer';
5749
+ /**
5750
+ * Resizes the given elements.
5751
+ *
5752
+ * @param {HTMLElement[]} elements
5753
+ */
5754
+ function resizeElements(elements) {
5755
+ elements = elements.filter(function (e) {
5756
+ var codeStyles = getStyles(e);
5757
+ var whiteSpace = codeStyles['white-space'];
5758
+ return whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line';
5759
+ });
5593
5760
 
5594
- codeElement.appendChild(lineNumberSizer);
5761
+ if (elements.length == 0) {
5762
+ return;
5595
5763
  }
5596
5764
 
5597
- lineNumberSizer.innerHTML = '0';
5598
- lineNumberSizer.style.display = 'block';
5765
+ var infos = elements.map(function (element) {
5766
+ var codeElement = element.querySelector('code');
5767
+ var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
5768
+ if (!codeElement || !lineNumbersWrapper) {
5769
+ return undefined;
5770
+ }
5599
5771
 
5600
- var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
5601
- lineNumberSizer.innerHTML = '';
5772
+ /** @type {HTMLElement} */
5773
+ var lineNumberSizer = element.querySelector('.line-numbers-sizer');
5774
+ var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
5602
5775
 
5603
- return {
5604
- element: element,
5605
- lines: codeLines,
5606
- lineHeights: [],
5607
- oneLinerHeight: oneLinerHeight,
5608
- sizer: lineNumberSizer,
5609
- };
5610
- }).filter(Boolean);
5611
-
5612
- infos.forEach(function (info) {
5613
- var lineNumberSizer = info.sizer;
5614
- var lines = info.lines;
5615
- var lineHeights = info.lineHeights;
5616
- var oneLinerHeight = info.oneLinerHeight;
5617
-
5618
- lineHeights[lines.length - 1] = undefined;
5619
- lines.forEach(function (line, index) {
5620
- if (line && line.length > 1) {
5621
- var e = lineNumberSizer.appendChild(document.createElement('span'));
5622
- e.style.display = 'block';
5623
- e.textContent = line;
5624
- } else {
5625
- lineHeights[index] = oneLinerHeight;
5776
+ if (!lineNumberSizer) {
5777
+ lineNumberSizer = document.createElement('span');
5778
+ lineNumberSizer.className = 'line-numbers-sizer';
5779
+
5780
+ codeElement.appendChild(lineNumberSizer);
5626
5781
  }
5782
+
5783
+ lineNumberSizer.innerHTML = '0';
5784
+ lineNumberSizer.style.display = 'block';
5785
+
5786
+ var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
5787
+ lineNumberSizer.innerHTML = '';
5788
+
5789
+ return {
5790
+ element: element,
5791
+ lines: codeLines,
5792
+ lineHeights: [],
5793
+ oneLinerHeight: oneLinerHeight,
5794
+ sizer: lineNumberSizer,
5795
+ };
5796
+ }).filter(Boolean);
5797
+
5798
+ infos.forEach(function (info) {
5799
+ var lineNumberSizer = info.sizer;
5800
+ var lines = info.lines;
5801
+ var lineHeights = info.lineHeights;
5802
+ var oneLinerHeight = info.oneLinerHeight;
5803
+
5804
+ lineHeights[lines.length - 1] = undefined;
5805
+ lines.forEach(function (line, index) {
5806
+ if (line && line.length > 1) {
5807
+ var e = lineNumberSizer.appendChild(document.createElement('span'));
5808
+ e.style.display = 'block';
5809
+ e.textContent = line;
5810
+ } else {
5811
+ lineHeights[index] = oneLinerHeight;
5812
+ }
5813
+ });
5627
5814
  });
5628
- });
5629
5815
 
5630
- infos.forEach(function (info) {
5631
- var lineNumberSizer = info.sizer;
5632
- var lineHeights = info.lineHeights;
5816
+ infos.forEach(function (info) {
5817
+ var lineNumberSizer = info.sizer;
5818
+ var lineHeights = info.lineHeights;
5633
5819
 
5634
- var childIndex = 0;
5635
- for (var i = 0; i < lineHeights.length; i++) {
5636
- if (lineHeights[i] === undefined) {
5637
- lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height;
5820
+ var childIndex = 0;
5821
+ for (var i = 0; i < lineHeights.length; i++) {
5822
+ if (lineHeights[i] === undefined) {
5823
+ lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height;
5824
+ }
5638
5825
  }
5639
- }
5640
- });
5826
+ });
5641
5827
 
5642
- infos.forEach(function (info) {
5643
- var lineNumberSizer = info.sizer;
5644
- var wrapper = info.element.querySelector('.line-numbers-rows');
5828
+ infos.forEach(function (info) {
5829
+ var lineNumberSizer = info.sizer;
5830
+ var wrapper = info.element.querySelector('.line-numbers-rows');
5645
5831
 
5646
- lineNumberSizer.style.display = 'none';
5647
- lineNumberSizer.innerHTML = '';
5832
+ lineNumberSizer.style.display = 'none';
5833
+ lineNumberSizer.innerHTML = '';
5648
5834
 
5649
- info.lineHeights.forEach(function (height, lineNumber) {
5650
- wrapper.children[lineNumber].style.height = height + 'px';
5835
+ info.lineHeights.forEach(function (height, lineNumber) {
5836
+ wrapper.children[lineNumber].style.height = height + 'px';
5837
+ });
5651
5838
  });
5652
- });
5653
- }
5654
-
5655
- /**
5656
- * Returns style declarations for the element
5657
- *
5658
- * @param {Element} element
5659
- */
5660
- function getStyles(element) {
5661
- if (!element) {
5662
- return null;
5663
5839
  }
5664
5840
 
5665
- return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
5666
- }
5841
+ /**
5842
+ * Returns style declarations for the element
5843
+ *
5844
+ * @param {Element} element
5845
+ */
5846
+ function getStyles(element) {
5847
+ if (!element) {
5848
+ return null;
5849
+ }
5667
5850
 
5668
- var lastWidth = undefined;
5669
- window.addEventListener('resize', function () {
5670
- if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
5671
- return;
5851
+ return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
5672
5852
  }
5673
- lastWidth = window.innerWidth;
5674
5853
 
5675
- resizeElements(Array.prototype.slice.call(document.querySelectorAll('pre.' + PLUGIN_NAME)));
5676
- });
5854
+ var lastWidth = undefined;
5855
+ window.addEventListener('resize', function () {
5856
+ if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
5857
+ return;
5858
+ }
5859
+ lastWidth = window.innerWidth;
5677
5860
 
5678
- Prism.hooks.add('complete', function (env) {
5679
- if (!env.code) {
5680
- return;
5681
- }
5861
+ resizeElements(Array.prototype.slice.call(document.querySelectorAll('pre.' + PLUGIN_NAME)));
5862
+ });
5682
5863
 
5683
- var code = /** @type {Element} */ (env.element);
5684
- var pre = /** @type {HTMLElement} */ (code.parentNode);
5864
+ Prism.hooks.add('complete', function (env) {
5865
+ if (!env.code) {
5866
+ return;
5867
+ }
5685
5868
 
5686
- // works only for <code> wrapped inside <pre> (not inline)
5687
- if (!pre || !/pre/i.test(pre.nodeName)) {
5688
- return;
5689
- }
5869
+ var code = /** @type {Element} */ (env.element);
5870
+ var pre = /** @type {HTMLElement} */ (code.parentNode);
5690
5871
 
5691
- // Abort if line numbers already exists
5692
- if (code.querySelector('.line-numbers-rows')) {
5693
- return;
5694
- }
5872
+ // works only for <code> wrapped inside <pre> (not inline)
5873
+ if (!pre || !/pre/i.test(pre.nodeName)) {
5874
+ return;
5875
+ }
5695
5876
 
5696
- // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
5697
- if (!Prism.util.isActive(code, PLUGIN_NAME)) {
5698
- return;
5699
- }
5877
+ // Abort if line numbers already exists
5878
+ if (code.querySelector('.line-numbers-rows')) {
5879
+ return;
5880
+ }
5700
5881
 
5701
- // Remove the class 'line-numbers' from the <code>
5702
- code.classList.remove(PLUGIN_NAME);
5703
- // Add the class 'line-numbers' to the <pre>
5704
- pre.classList.add(PLUGIN_NAME);
5882
+ // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
5883
+ if (!Prism.util.isActive(code, PLUGIN_NAME)) {
5884
+ return;
5885
+ }
5705
5886
 
5706
- var match = env.code.match(NEW_LINE_EXP);
5707
- var linesNum = match ? match.length + 1 : 1;
5708
- var lineNumbersWrapper;
5887
+ // Remove the class 'line-numbers' from the <code>
5888
+ code.classList.remove(PLUGIN_NAME);
5889
+ // Add the class 'line-numbers' to the <pre>
5890
+ pre.classList.add(PLUGIN_NAME);
5709
5891
 
5710
- var lines = new Array(linesNum + 1).join('<span></span>');
5892
+ var match = env.code.match(NEW_LINE_EXP);
5893
+ var linesNum = match ? match.length + 1 : 1;
5894
+ var lineNumbersWrapper;
5711
5895
 
5712
- lineNumbersWrapper = document.createElement('span');
5713
- lineNumbersWrapper.setAttribute('aria-hidden', 'true');
5714
- lineNumbersWrapper.className = 'line-numbers-rows';
5715
- lineNumbersWrapper.innerHTML = lines;
5896
+ var lines = new Array(linesNum + 1).join('<span></span>');
5716
5897
 
5717
- if (pre.hasAttribute('data-start')) {
5718
- pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
5719
- }
5898
+ lineNumbersWrapper = document.createElement('span');
5899
+ lineNumbersWrapper.setAttribute('aria-hidden', 'true');
5900
+ lineNumbersWrapper.className = 'line-numbers-rows';
5901
+ lineNumbersWrapper.innerHTML = lines;
5902
+
5903
+ if (pre.hasAttribute('data-start')) {
5904
+ pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
5905
+ }
5906
+
5907
+ env.element.appendChild(lineNumbersWrapper);
5720
5908
 
5721
- env.element.appendChild(lineNumbersWrapper);
5909
+ resizeElements([pre]);
5722
5910
 
5723
- resizeElements([pre]);
5911
+ Prism.hooks.run('line-numbers', env);
5912
+ });
5724
5913
 
5725
- Prism.hooks.run('line-numbers', env);
5726
- });
5914
+ Prism.hooks.add('line-numbers', function (env) {
5915
+ env.plugins = env.plugins || {};
5916
+ env.plugins.lineNumbers = true;
5917
+ });
5727
5918
 
5728
- Prism.hooks.add('line-numbers', function (env) {
5729
- env.plugins = env.plugins || {};
5730
- env.plugins.lineNumbers = true;
5731
- });
5919
+ }());
5920
+ return prismLineNumbers;
5921
+ }
5732
5922
 
5733
- }());
5923
+ requirePrismLineNumbers();
5734
5924
 
5735
5925
  const initialize = () => {
5736
5926
  // @ts-ignore
@@ -5750,7 +5940,11 @@ const initialize = () => {
5750
5940
  }
5751
5941
  };
5752
5942
  // @ts-ignore
5753
- window.setResults = (playerNames, places, parameters, verbose) => {
5943
+ window.setResults = (playerNames, seed, places, statistics, parameters, verbose) => {
5944
+ // @ts-ignore
5945
+ parameters = parameters.toJs();
5946
+ // @ts-ignore
5947
+ statistics = statistics.toJs();
5754
5948
  const results = getLocalStorage("Results");
5755
5949
  if (!results[playerNames.join(", ")]) {
5756
5950
  results[playerNames.join(", ")] = {};
@@ -5758,7 +5952,11 @@ const initialize = () => {
5758
5952
  if (!results[playerNames.join(", ")][JSON.stringify(parameters)]) {
5759
5953
  results[playerNames.join(", ")][JSON.stringify(parameters)] = [];
5760
5954
  }
5761
- results[playerNames.join(", ")][JSON.stringify(parameters)].push(places);
5955
+ results[playerNames.join(", ")][JSON.stringify(parameters)].push({
5956
+ seed,
5957
+ places,
5958
+ statistics,
5959
+ });
5762
5960
  setLocalStorage("Results", results);
5763
5961
  updatePointModifier();
5764
5962
  // @ts-ignore