@quarto/jupyterlab-quarto 0.1.44 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +48 -15
  3. package/lib/__tests__/jupyterlab_quarto.spec.d.ts +3 -0
  4. package/lib/__tests__/jupyterlab_quarto.spec.js +9 -0
  5. package/lib/ast/ast.d.ts +2 -0
  6. package/lib/ast/ast.js +40 -0
  7. package/lib/const.d.ts +4 -0
  8. package/lib/const.js +11 -0
  9. package/lib/hooks/codemirror.d.ts +5 -0
  10. package/lib/hooks/codemirror.js +77 -0
  11. package/lib/index.d.ts +5 -0
  12. package/lib/index.js +61 -0
  13. package/lib/manager.d.ts +8 -0
  14. package/lib/manager.js +115 -0
  15. package/lib/plugins/callouts.d.ts +2 -0
  16. package/lib/plugins/callouts.js +210 -0
  17. package/lib/plugins/cites.d.ts +2 -0
  18. package/lib/plugins/cites.js +166 -0
  19. package/lib/plugins/decorator.d.ts +2 -0
  20. package/lib/plugins/decorator.js +58 -0
  21. package/lib/plugins/divs.d.ts +5 -0
  22. package/lib/plugins/divs.js +111 -0
  23. package/lib/plugins/figure-divs.d.ts +2 -0
  24. package/lib/plugins/figure-divs.js +54 -0
  25. package/lib/plugins/figures.d.ts +16 -0
  26. package/lib/plugins/figures.js +98 -0
  27. package/lib/plugins/gridtables/common/gridtables/GetCells.d.ts +7 -0
  28. package/lib/plugins/gridtables/common/gridtables/GetCells.js +43 -0
  29. package/lib/plugins/gridtables/common/gridtables/GetColumnWidths.d.ts +7 -0
  30. package/lib/plugins/gridtables/common/gridtables/GetColumnWidths.js +22 -0
  31. package/lib/plugins/gridtables/common/markdown-it/ColumnAlignments.d.ts +7 -0
  32. package/lib/plugins/gridtables/common/markdown-it/ColumnAlignments.js +12 -0
  33. package/lib/plugins/gridtables/common/markdown-it/EmitTable.d.ts +4 -0
  34. package/lib/plugins/gridtables/common/markdown-it/EmitTable.js +64 -0
  35. package/lib/plugins/gridtables/common/markdown-it/GetCharCodeAtStartOfLine.d.ts +8 -0
  36. package/lib/plugins/gridtables/common/markdown-it/GetCharCodeAtStartOfLine.js +17 -0
  37. package/lib/plugins/gridtables/common/markdown-it/GetLine.d.ts +2 -0
  38. package/lib/plugins/gridtables/common/markdown-it/GetLine.js +9 -0
  39. package/lib/plugins/gridtables/common/markdown-it/ParseTable.d.ts +3 -0
  40. package/lib/plugins/gridtables/common/markdown-it/ParseTable.js +152 -0
  41. package/lib/plugins/gridtables/common/markdown-it/ParseTableResult.d.ts +12 -0
  42. package/lib/plugins/gridtables/common/markdown-it/ParseTableResult.js +17 -0
  43. package/lib/plugins/gridtables/index.d.ts +1 -0
  44. package/lib/plugins/gridtables/index.js +10 -0
  45. package/lib/plugins/gridtables/interfaces/markdown-it/IState.d.ts +10 -0
  46. package/lib/plugins/gridtables/interfaces/markdown-it/IState.js +5 -0
  47. package/lib/plugins/gridtables/interfaces/markdown-it/IToken.d.ts +6 -0
  48. package/lib/plugins/gridtables/interfaces/markdown-it/IToken.js +5 -0
  49. package/lib/plugins/gridtables/interfaces/markdown-it/TRuleFunction.d.ts +3 -0
  50. package/lib/plugins/gridtables/interfaces/markdown-it/TRuleFunction.js +5 -0
  51. package/lib/plugins/gridtables/rules/gridtable.d.ts +3 -0
  52. package/lib/plugins/gridtables/rules/gridtable.js +25 -0
  53. package/lib/plugins/index.d.ts +15 -0
  54. package/lib/plugins/index.js +21 -0
  55. package/lib/plugins/math.d.ts +6 -0
  56. package/lib/plugins/math.js +179 -0
  57. package/lib/plugins/mermaid/index.d.ts +4 -0
  58. package/lib/plugins/mermaid/index.js +60 -0
  59. package/lib/plugins/shortcodes.d.ts +3 -0
  60. package/lib/plugins/shortcodes.js +32 -0
  61. package/lib/plugins/spans.d.ts +2 -0
  62. package/lib/plugins/spans.js +37 -0
  63. package/lib/plugins/table-captions.d.ts +2 -0
  64. package/lib/plugins/table-captions.js +72 -0
  65. package/lib/plugins/utils/html.d.ts +11 -0
  66. package/lib/plugins/utils/html.js +50 -0
  67. package/lib/plugins/utils/markdownit.d.ts +15 -0
  68. package/lib/plugins/utils/markdownit.js +46 -0
  69. package/lib/plugins/utils/tok.d.ts +7 -0
  70. package/lib/plugins/utils/tok.js +13 -0
  71. package/lib/plugins/yaml.d.ts +2 -0
  72. package/lib/plugins/yaml.js +330 -0
  73. package/lib/providers/attrs.d.ts +1 -0
  74. package/lib/providers/attrs.js +15 -0
  75. package/lib/providers/callouts.d.ts +1 -0
  76. package/lib/providers/callouts.js +15 -0
  77. package/lib/providers/cites.d.ts +1 -0
  78. package/lib/providers/cites.js +15 -0
  79. package/lib/providers/decorator.d.ts +1 -0
  80. package/lib/providers/decorator.js +15 -0
  81. package/lib/providers/deflist.d.ts +1 -0
  82. package/lib/providers/deflist.js +15 -0
  83. package/lib/providers/divs.d.ts +1 -0
  84. package/lib/providers/divs.js +27 -0
  85. package/lib/providers/figure-divs.d.ts +1 -0
  86. package/lib/providers/figure-divs.js +15 -0
  87. package/lib/providers/figures.d.ts +1 -0
  88. package/lib/providers/figures.js +15 -0
  89. package/lib/providers/footnotes.d.ts +1 -0
  90. package/lib/providers/footnotes.js +15 -0
  91. package/lib/providers/gridtables.d.ts +1 -0
  92. package/lib/providers/gridtables.js +15 -0
  93. package/lib/providers/math.d.ts +1 -0
  94. package/lib/providers/math.js +104 -0
  95. package/lib/providers/mermaid.d.ts +1 -0
  96. package/lib/providers/mermaid.js +17 -0
  97. package/lib/providers/provider.d.ts +3 -0
  98. package/lib/providers/provider.js +12 -0
  99. package/lib/providers/shortcodes.d.ts +1 -0
  100. package/lib/providers/shortcodes.js +15 -0
  101. package/lib/providers/spans.d.ts +1 -0
  102. package/lib/providers/spans.js +15 -0
  103. package/lib/providers/sub.d.ts +1 -0
  104. package/lib/providers/sub.js +15 -0
  105. package/lib/providers/sup.d.ts +1 -0
  106. package/lib/providers/sup.js +15 -0
  107. package/lib/providers/table-captions.d.ts +1 -0
  108. package/lib/providers/table-captions.js +15 -0
  109. package/lib/providers/tasklists.d.ts +1 -0
  110. package/lib/providers/tasklists.js +15 -0
  111. package/lib/providers/yaml.d.ts +1 -0
  112. package/lib/providers/yaml.js +15 -0
  113. package/lib/types.d.ts +43 -0
  114. package/lib/types.js +1 -0
  115. package/lib/widgets.d.ts +14 -0
  116. package/lib/widgets.js +57 -0
  117. package/package.json +105 -39
  118. package/style/base.css +34 -33
  119. package/style/index.css +1 -1
  120. package/schema/plugin.json +0 -8
  121. package/src/@types/markdown-it-deflist.d.ts +0 -10
  122. package/src/@types/markdown-it-footnote.d.ts +0 -10
  123. package/src/@types/markdown-it-gridtables.d.ts +0 -10
  124. package/src/@types/markdown-it-implicit-figures.d.ts +0 -10
  125. package/src/@types/markdown-it-sub.d.ts +0 -10
  126. package/src/@types/markdown-it-sup.d.ts +0 -10
  127. package/src/@types/markdown-it-task-lists.d.ts +0 -10
@@ -0,0 +1,98 @@
1
+ /*
2
+ * figures.ts
3
+ *
4
+ * Copyright (C) 2020-2023 Posit Software, PBC
5
+ *
6
+ */
7
+ import { kTokParaClose, kTokParaOpen } from './utils/tok';
8
+ export const kTokFigureOpen = 'figure_open';
9
+ export const kTokFigureClose = 'figure_close';
10
+ export const kTokFigCaptionOpen = 'figcaption_open';
11
+ export const kTokFigCaptionClose = 'figcaption_close';
12
+ export const mutateToFigureTok = (token, type) => {
13
+ token.type = type === 'open' ? kTokFigureOpen : kTokFigureClose;
14
+ token.tag = 'figure';
15
+ };
16
+ export function figuresPlugin(md, options) {
17
+ options = options || {};
18
+ md.core.ruler.before('linkify', 'implicit_figures', state => {
19
+ // reset tabIndex on md.render()
20
+ let tabIndex = 1;
21
+ // do not process first and last token
22
+ for (let i = 1, l = state.tokens.length; i < l - 1; ++i) {
23
+ const token = state.tokens[i];
24
+ if (token.type !== 'inline') {
25
+ continue;
26
+ }
27
+ // children: image alone, or link_open -> image -> link_close
28
+ if (!token.children ||
29
+ (token.children.length !== 1 && token.children.length !== 3)) {
30
+ continue;
31
+ }
32
+ // one child, should be img
33
+ if (token.children.length === 1 && token.children[0].type !== 'image') {
34
+ continue;
35
+ }
36
+ // three children, should be image enclosed in link
37
+ if (token.children.length === 3 &&
38
+ (token.children[0].type !== 'link_open' ||
39
+ token.children[1].type !== 'image' ||
40
+ token.children[2].type !== 'link_close')) {
41
+ continue;
42
+ }
43
+ // prev token is paragraph open
44
+ if (i !== 0 && state.tokens[i - 1].type !== kTokParaOpen) {
45
+ continue;
46
+ }
47
+ // next token is paragraph close
48
+ if (i !== l - 1 && state.tokens[i + 1].type !== kTokParaClose) {
49
+ continue;
50
+ }
51
+ // The image
52
+ const image = token.children.length === 1 ? token.children[0] : token.children[1];
53
+ // The image must have a caption to count as a figure
54
+ if (!image.children || image.children.length === 0) {
55
+ continue;
56
+ }
57
+ // We have inline token containing an image only.
58
+ // Previous token is paragraph open.
59
+ // Next token is paragraph close.
60
+ // Lets replace the paragraph tokens with figure tokens.
61
+ const figure = state.tokens[i - 1];
62
+ mutateToFigureTok(figure, 'open');
63
+ mutateToFigureTok(state.tokens[i + 1], 'close');
64
+ if (options.dataType === true) {
65
+ state.tokens[i - 1].attrPush(['data-type', 'image']);
66
+ }
67
+ if (options.link === true && token.children.length === 1) {
68
+ token.children.unshift(new state.Token('link_open', 'a', 1));
69
+ const src = image.attrGet('src');
70
+ if (src !== null) {
71
+ token.children[0].attrPush(['href', src]);
72
+ }
73
+ token.children.push(new state.Token('link_close', 'a', -1));
74
+ }
75
+ if (options.figcaption === true) {
76
+ if (image.children && image.children.length) {
77
+ token.children.push(new state.Token(kTokFigCaptionOpen, 'figcaption', 1));
78
+ token.children.splice(token.children.length, 0, ...image.children);
79
+ token.children.push(new state.Token(kTokFigCaptionClose, 'figcaption', -1));
80
+ image.children.length = 0;
81
+ }
82
+ }
83
+ if (options.copyAttrs && image.attrs) {
84
+ const f = options.copyAttrs === true ? '' : options.copyAttrs;
85
+ figure.attrs = image.attrs.filter(([k]) => k.match(f));
86
+ }
87
+ if (options.tabindex === true) {
88
+ // add a tabindex property
89
+ // you could use this with css-tricks.com/expanding-images-html5
90
+ state.tokens[i - 1].attrPush(['tabindex', String(tabIndex)]);
91
+ tabIndex++;
92
+ }
93
+ if (options.lazyLoading === true) {
94
+ image.attrPush(['loading', 'lazy']);
95
+ }
96
+ }
97
+ });
98
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * getCells parses the lines found for a certain row, and transforms these to
3
+ * the separate cell lines.
4
+ *
5
+ * @param lines The lines for the row.
6
+ */
7
+ export default function getCells(lines: string[][]): string[][];
@@ -0,0 +1,43 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * getCells parses the lines found for a certain row, and transforms these to
7
+ * the separate cell lines.
8
+ *
9
+ * @param lines The lines for the row.
10
+ */
11
+ export default function getCells(lines) {
12
+ const cells = [];
13
+ for (let i = 0; i < lines[0].length; i++) {
14
+ let cell = [];
15
+ for (let j = 0; j < lines.length; j++) {
16
+ const s = trimEnd(lines[j][i]);
17
+ if (s.length === 0 && cell.length === 0) {
18
+ // skip leading empty lines
19
+ continue;
20
+ }
21
+ cell.push(s);
22
+ }
23
+ // remove trailing empty lines
24
+ let j = cell.length - 1;
25
+ for (; j >= 0; j--) {
26
+ if (cell[j].length > 0) {
27
+ break;
28
+ }
29
+ }
30
+ if (j < cell.length - 1) {
31
+ cell = cell.slice(0, j + 1);
32
+ }
33
+ cells.push(cell);
34
+ }
35
+ return cells;
36
+ }
37
+ function trimEnd(s) {
38
+ const trimmed = s.trim();
39
+ if (trimmed.length === 0) {
40
+ return '';
41
+ }
42
+ return s.slice(0, s.indexOf(trimmed) + trimmed.length);
43
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * getColumnWidths parses the provided line and returns the associated column widths.
3
+ *
4
+ * @param line The separator line to parse for the column widths.
5
+ * @returns The column widths for the provided line, or an empty array if the line is invalid.
6
+ */
7
+ export default function getColumnWidths(line: string): number[];
@@ -0,0 +1,22 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * getColumnWidths parses the provided line and returns the associated column widths.
7
+ *
8
+ * @param line The separator line to parse for the column widths.
9
+ * @returns The column widths for the provided line, or an empty array if the line is invalid.
10
+ */
11
+ export default function getColumnWidths(line) {
12
+ // try to parse as a row separator line
13
+ let columnMatch = line.substr(1).match(/[:-][-]+[:-]\+/g);
14
+ if (columnMatch === null) {
15
+ // try to parse as a header separator line
16
+ columnMatch = line.substr(1).match(/[:=][=]+[:=]\+/g);
17
+ }
18
+ if (columnMatch === null) {
19
+ return [];
20
+ }
21
+ return columnMatch.map(s => s.length);
22
+ }
@@ -0,0 +1,7 @@
1
+ declare enum ColumnAlignments {
2
+ None = "",
3
+ Left = "left",
4
+ Center = "center",
5
+ Right = "right"
6
+ }
7
+ export default ColumnAlignments;
@@ -0,0 +1,12 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var ColumnAlignments;
6
+ (function (ColumnAlignments) {
7
+ ColumnAlignments["None"] = "";
8
+ ColumnAlignments["Left"] = "left";
9
+ ColumnAlignments["Center"] = "center";
10
+ ColumnAlignments["Right"] = "right";
11
+ })(ColumnAlignments || (ColumnAlignments = {}));
12
+ export default ColumnAlignments;
@@ -0,0 +1,4 @@
1
+ import * as MarkdownIt from 'markdown-it';
2
+ import IState from '../../interfaces/markdown-it/IState';
3
+ import ParseTableResult from './ParseTableResult';
4
+ export default function emitTable(md: MarkdownIt, state: IState, result: ParseTableResult): void;
@@ -0,0 +1,64 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import getCells from '../gridtables/GetCells';
6
+ import ColumnAlignments from './ColumnAlignments';
7
+ export default function emitTable(md, state, result) {
8
+ let offsets = result.SeparatorLineOffsets;
9
+ let token = state.push('table_open', 'table', 1);
10
+ token.map = [offsets[0], offsets[offsets.length - 1]];
11
+ if (result.HeaderLines.length > 0) {
12
+ // emit table header
13
+ const token = state.push('thead_open', 'thead', 1);
14
+ token.map = [offsets[0], offsets[1]];
15
+ const cells = getCells(result.HeaderLines);
16
+ processRow(md, state, 'th', result.ColumnAlignments, offsets[0], offsets[1], cells);
17
+ state.push('thead_close', 'thead', -1);
18
+ offsets = offsets.slice(1);
19
+ }
20
+ // emit table body
21
+ token = state.push('tbody_open', 'tbody', 1);
22
+ token.map = [offsets[0], offsets[offsets.length - 1]];
23
+ for (let i = 0; i < result.RowLines.length; i++) {
24
+ const cells = getCells(result.RowLines[i]);
25
+ processRow(md, state, 'td', result.ColumnAlignments, offsets[i], offsets[i + 1], cells);
26
+ }
27
+ state.push('tbody_close', 'tbody', -1);
28
+ state.push('table_close', 'table', -1);
29
+ }
30
+ function processRow(md, state, tag, columnAlignments, lineBegin, lineEnd, cells) {
31
+ const token = state.push('tr_open', 'tr', 1);
32
+ token.map = [lineBegin, lineEnd];
33
+ for (let i = 0; i < cells.length; i++) {
34
+ const token = state.push(tag + '_open', tag, 1);
35
+ token.map = [lineBegin + 1, lineEnd - 1];
36
+ if (columnAlignments[i] !== ColumnAlignments.None) {
37
+ token.attrSet('style', `text-align: ${columnAlignments[i]};`);
38
+ }
39
+ if (cells[i].length === 0) {
40
+ // empty cell
41
+ }
42
+ else if (cells[i].length === 1) {
43
+ // single line cell -> emit as inline markdown
44
+ const token = state.push('inline', '', 0);
45
+ token.content = cells[i][0].trim();
46
+ token.children = [];
47
+ }
48
+ else {
49
+ // multi line cell -> render and emit as html
50
+ let cell = md.render(cells[i].join('\r\n')).trim();
51
+ // remove single p tag because we're in a table cell
52
+ if (cell.slice(0, 3) === '<p>' &&
53
+ cell.slice(-4) === '</p>' &&
54
+ cell.indexOf('<p>', 3) === -1) {
55
+ cell = cell.slice(3, cell.length - 4);
56
+ }
57
+ const token = state.push('html_block', '', 0);
58
+ token.content = cell;
59
+ token.children = [];
60
+ }
61
+ state.push(tag + '_close', tag, -1);
62
+ }
63
+ state.push('tr_close', 'tr', -1);
64
+ }
@@ -0,0 +1,8 @@
1
+ import IState from '../../interfaces/markdown-it/IState';
2
+ /**
3
+ * Returns the char code of the character at the start of the current line,
4
+ * or -1 if this is not available (e.g. on an empty line).
5
+ *
6
+ * @param state The Markdown It state.
7
+ */
8
+ export default function getCharCodeAtStartOfLine(state: IState, line: number): number;
@@ -0,0 +1,17 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * Returns the char code of the character at the start of the current line,
7
+ * or -1 if this is not available (e.g. on an empty line).
8
+ *
9
+ * @param state The Markdown It state.
10
+ */
11
+ export default function getCharCodeAtStartOfLine(state, line) {
12
+ const pos = state.bMarks[line] + state.tShift[line];
13
+ if (pos >= state.eMarks[line]) {
14
+ return -1;
15
+ }
16
+ return state.src.charCodeAt(pos);
17
+ }
@@ -0,0 +1,2 @@
1
+ import IState from '../../interfaces/markdown-it/IState';
2
+ export default function getLine(state: IState, line: number): string;
@@ -0,0 +1,9 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export default function getLine(state, line) {
6
+ const start = state.bMarks[line] + state.blkIndent;
7
+ const end = state.eMarks[line];
8
+ return state.src.substr(start, end - start);
9
+ }
@@ -0,0 +1,3 @@
1
+ import IState from '../../interfaces/markdown-it/IState';
2
+ import ParseTableResult from './ParseTableResult';
3
+ export default function parseTable(state: IState, startLine: number, endLine: number): ParseTableResult;
@@ -0,0 +1,152 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import wcwidth from 'wcwidth';
6
+ import getColumnWidths from '../gridtables/GetColumnWidths';
7
+ import ColumnAlignments from './ColumnAlignments';
8
+ import getLine from './GetLine';
9
+ import ParseTableResult from './ParseTableResult';
10
+ export default function parseTable(state, startLine, endLine) {
11
+ const result = new ParseTableResult();
12
+ let rowLine = getLine(state, startLine);
13
+ if (rowLine.charAt(0) !== '+') {
14
+ // line does not start with a '+'
15
+ return result;
16
+ }
17
+ result.ColumnWidths = getColumnWidths(rowLine);
18
+ if (result.ColumnWidths.length === 0) {
19
+ // no columns found
20
+ return result;
21
+ }
22
+ // initialize column alignments
23
+ result.ColumnAlignments = result.ColumnWidths.map(() => ColumnAlignments.None);
24
+ if (rowLine.indexOf(':') >= 0) {
25
+ // column alignment specifiers present in first row line
26
+ result.HeaderLess = true;
27
+ // set column alignments
28
+ result.ColumnAlignments = getColumnAlignments(rowLine, result.ColumnWidths);
29
+ // remove alignment specifiers for further matching
30
+ rowLine = rowLine.replace(/[:]/g, '-');
31
+ }
32
+ // create header line matcher
33
+ const headerLineMatcher = new RegExp('^\\+' +
34
+ result.ColumnWidths.map(w => `[=:][=]{${w - 3}}[=:]\\+`).join('') +
35
+ '$');
36
+ // build column offsets
37
+ result.ColumnOffsets = [0];
38
+ for (let i = 0; i < result.ColumnWidths.length - 1; i++) {
39
+ result.ColumnOffsets.push(result.ColumnOffsets[i] + result.ColumnWidths[i]);
40
+ }
41
+ // create cell line matcher
42
+ const cellLineMatcher = new RegExp('^\\|' +
43
+ result.ColumnWidths.map(w => `([^|]{${Math.ceil((w - 1) / 2)},${w - 1}})\\|`).join('') +
44
+ '$');
45
+ // save first separator line offset
46
+ result.SeparatorLineOffsets.push(startLine);
47
+ // continue to scan until a complete table is found, or an invalid line is encountered
48
+ let currentRow = [];
49
+ let currentLine = startLine + 1;
50
+ for (; currentLine <= endLine; currentLine++) {
51
+ const line = getLine(state, currentLine);
52
+ if (line.charCodeAt(0) === 0x2b) {
53
+ // '+'
54
+ // separator line
55
+ if (currentRow.length === 0) {
56
+ // no row lines since last separator -> invalid table
57
+ return result;
58
+ }
59
+ // save separator line offset
60
+ result.SeparatorLineOffsets.push(currentLine);
61
+ if (line === rowLine) {
62
+ // new regular row
63
+ result.RowLines.push(currentRow);
64
+ if (result.HeaderLines.length === 0) {
65
+ result.HeaderLess = true;
66
+ }
67
+ }
68
+ else if (!result.HeaderLess && line.match(headerLineMatcher)) {
69
+ // found header line
70
+ if (result.HeaderLines.length > 0 || result.RowLines.length > 0) {
71
+ // header already found, or not the first row -> invalid table
72
+ return result;
73
+ }
74
+ // header row
75
+ result.HeaderLines = currentRow;
76
+ if (line.indexOf(':') >= 0) {
77
+ // set column alignments
78
+ result.ColumnAlignments = getColumnAlignments(line, result.ColumnWidths);
79
+ }
80
+ }
81
+ else {
82
+ // not a header or regular row -> invalid table
83
+ return result;
84
+ }
85
+ // reset current row
86
+ currentRow = [];
87
+ }
88
+ else if (line.charCodeAt(0) === 0x7c) {
89
+ // '|'
90
+ // cell line
91
+ const matches = line.match(cellLineMatcher);
92
+ if (matches === null) {
93
+ // cell line does not match -> invalid table
94
+ return result;
95
+ }
96
+ const cells = validateColumnWidths(matches, result.ColumnWidths);
97
+ if (cells === null) {
98
+ // cell line does not match -> invalid table
99
+ return result;
100
+ }
101
+ // add the line to the current row
102
+ currentRow.push(cells);
103
+ }
104
+ else {
105
+ // not a separator or cell line, check if we have a complete table
106
+ if (currentRow.length === 0 &&
107
+ (result.HeaderLines.length > 0 || result.RowLines.length > 0)) {
108
+ // found a complete table
109
+ break;
110
+ }
111
+ return result;
112
+ }
113
+ }
114
+ result.CurrentLine = currentLine;
115
+ result.Success = true;
116
+ return result;
117
+ }
118
+ function getColumnAlignments(line, columnWidths) {
119
+ const alignments = [];
120
+ let left = 1;
121
+ let right = -1;
122
+ for (let i = 0; i < columnWidths.length; i++) {
123
+ right += columnWidths[i];
124
+ let alignment = ColumnAlignments.None;
125
+ if (line.charAt(right) === ':') {
126
+ if (line.charAt(left) === ':') {
127
+ alignment = ColumnAlignments.Center;
128
+ }
129
+ else {
130
+ alignment = ColumnAlignments.Right;
131
+ }
132
+ }
133
+ else if (line.charAt(left) === ':') {
134
+ alignment = ColumnAlignments.Left;
135
+ }
136
+ alignments.push(alignment);
137
+ left += columnWidths[i];
138
+ }
139
+ return alignments;
140
+ }
141
+ function validateColumnWidths(matches, columnWidths) {
142
+ const cells = [];
143
+ for (let i = 0; i < columnWidths.length; i++) {
144
+ const cell = matches[i + 1];
145
+ const columnWidth = wcwidth(cell) + 1; // add 1 for separator
146
+ if (columnWidth !== columnWidths[i]) {
147
+ return null;
148
+ }
149
+ cells.push(cell);
150
+ }
151
+ return cells;
152
+ }
@@ -0,0 +1,12 @@
1
+ import ColumnAlignments from './ColumnAlignments';
2
+ export default class ParseTableResult {
3
+ Success: boolean;
4
+ ColumnWidths: number[];
5
+ ColumnOffsets: number[];
6
+ ColumnAlignments: ColumnAlignments[];
7
+ HeaderLess: boolean;
8
+ HeaderLines: string[][];
9
+ RowLines: string[][][];
10
+ SeparatorLineOffsets: number[];
11
+ CurrentLine: number;
12
+ }
@@ -0,0 +1,17 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export default class ParseTableResult {
6
+ constructor() {
7
+ this.Success = false;
8
+ this.ColumnWidths = [];
9
+ this.ColumnOffsets = [];
10
+ this.ColumnAlignments = [];
11
+ this.HeaderLess = false;
12
+ this.HeaderLines = [];
13
+ this.RowLines = [];
14
+ this.SeparatorLineOffsets = [];
15
+ this.CurrentLine = 0;
16
+ }
17
+ }
@@ -0,0 +1 @@
1
+ export default function gridTableRulePlugin(md: any): void;
@@ -0,0 +1,10 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import gridTableRule from './rules/gridtable';
6
+ export default function gridTableRulePlugin(
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ md) {
9
+ md.block.ruler.before('table', 'gridtable', gridTableRule(md));
10
+ }
@@ -0,0 +1,10 @@
1
+ import IToken from './IToken';
2
+ export default interface IState {
3
+ src: string;
4
+ bMarks: number[];
5
+ eMarks: number[];
6
+ blkIndent: number;
7
+ tShift: number[];
8
+ line: number;
9
+ push(action: string, tag: string, level: number): IToken;
10
+ }
@@ -0,0 +1,5 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export {};
@@ -0,0 +1,6 @@
1
+ export default interface IToken {
2
+ children: IToken[];
3
+ content: string;
4
+ map: number[];
5
+ attrSet(name: string, value: string): void;
6
+ }
@@ -0,0 +1,5 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export {};
@@ -0,0 +1,3 @@
1
+ import IState from './IState';
2
+ type TRuleFunction = (state: IState, startLine: number, endLine: number, silent: boolean) => boolean;
3
+ export default TRuleFunction;
@@ -0,0 +1,5 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export {};
@@ -0,0 +1,3 @@
1
+ import * as MarkdownIt from 'markdown-it';
2
+ import TRuleFunction from '../interfaces/markdown-it/TRuleFunction';
3
+ export default function gridTableRule(md: MarkdownIt): TRuleFunction;
@@ -0,0 +1,25 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bas Verweij. All rights reserved.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import emitTable from '../common/markdown-it/EmitTable';
6
+ import getCharCodeAtStartOfLine from '../common/markdown-it/GetCharCodeAtStartOfLine';
7
+ import parseTable from '../common/markdown-it/ParseTable';
8
+ export default function gridTableRule(md) {
9
+ return function (state, startLine, endLine, silent) {
10
+ if (getCharCodeAtStartOfLine(state, startLine) !== 0x2b) {
11
+ // line does not start with a '+'
12
+ return false;
13
+ }
14
+ const parseResult = parseTable(state, startLine, endLine);
15
+ if (!parseResult.Success) {
16
+ return false;
17
+ }
18
+ if (silent) {
19
+ return true;
20
+ }
21
+ emitTable(md, state, parseResult);
22
+ state.line = parseResult.CurrentLine;
23
+ return true;
24
+ };
25
+ }
@@ -0,0 +1,15 @@
1
+ import gridTableRulePlugin from './gridtables';
2
+ export { gridTableRulePlugin };
3
+ import mermaidPlugin from './mermaid';
4
+ export { mermaidPlugin };
5
+ export * from './callouts';
6
+ export * from './cites';
7
+ export * from './decorator';
8
+ export * from './divs';
9
+ export * from './figure-divs';
10
+ export * from './figures';
11
+ export * from './math';
12
+ export * from './shortcodes';
13
+ export * from './spans';
14
+ export * from './table-captions';
15
+ export * from './yaml';
@@ -0,0 +1,21 @@
1
+ /*
2
+ * index.ts
3
+ *
4
+ * Copyright (C) 2020-2023 Posit Software, PBC
5
+ *
6
+ */
7
+ import gridTableRulePlugin from './gridtables';
8
+ export { gridTableRulePlugin };
9
+ import mermaidPlugin from './mermaid';
10
+ export { mermaidPlugin };
11
+ export * from './callouts';
12
+ export * from './cites';
13
+ export * from './decorator';
14
+ export * from './divs';
15
+ export * from './figure-divs';
16
+ export * from './figures';
17
+ export * from './math';
18
+ export * from './shortcodes';
19
+ export * from './spans';
20
+ export * from './table-captions';
21
+ export * from './yaml';
@@ -0,0 +1,6 @@
1
+ import type MarkdownIt from 'markdown-it';
2
+ export declare const kTokMathBlock = "math_block";
3
+ export declare const kTokMathInline = "math_inline";
4
+ export declare function mathjaxPlugin(md: MarkdownIt, options?: {
5
+ enableInlines?: boolean;
6
+ }): void;