@chayns-components/format 5.0.0-beta.1288 → 5.0.0-beta.1351
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.
- package/lib/cjs/utils/formatString/formatString.js +4 -3
- package/lib/cjs/utils/formatString/formatString.js.map +1 -1
- package/lib/cjs/utils/formatString/markdown/formatMarkdown.js +57 -35
- package/lib/cjs/utils/formatString/markdown/formatMarkdown.js.map +1 -1
- package/lib/esm/utils/formatString/formatString.js +4 -3
- package/lib/esm/utils/formatString/formatString.js.map +1 -1
- package/lib/esm/utils/formatString/markdown/formatMarkdown.js +57 -35
- package/lib/esm/utils/formatString/markdown/formatMarkdown.js.map +1 -1
- package/package.json +7 -7
|
@@ -7,7 +7,7 @@ exports.formatStringToHtml = void 0;
|
|
|
7
7
|
var _escape = require("../escape");
|
|
8
8
|
var _formatBBCode = require("./bb-code/formatBBCode");
|
|
9
9
|
var _formatMarkdown = require("./markdown/formatMarkdown");
|
|
10
|
-
// This function takes a string and returns formatted
|
|
10
|
+
// This function takes a string and returns formatted HTML as a string.
|
|
11
11
|
const formatStringToHtml = (string, options) => {
|
|
12
12
|
if (!string) {
|
|
13
13
|
return {
|
|
@@ -23,7 +23,7 @@ const formatStringToHtml = (string, options) => {
|
|
|
23
23
|
} = options || {};
|
|
24
24
|
let formattedString = string;
|
|
25
25
|
|
|
26
|
-
// Needs to get the tables before escaping
|
|
26
|
+
// Needs to get the tables before escaping HTML and parsing bb-code, so the original content can be extracted.
|
|
27
27
|
const tables = [];
|
|
28
28
|
if (parseMarkdownOption) {
|
|
29
29
|
try {
|
|
@@ -36,7 +36,8 @@ const formatStringToHtml = (string, options) => {
|
|
|
36
36
|
// Escape HTML entities.
|
|
37
37
|
formattedString = (0, _escape.escapeHtmlInText)(formattedString);
|
|
38
38
|
|
|
39
|
-
// Escape BB-Code
|
|
39
|
+
// Escape BB-Code to prevent conflicts between Markdown and BB-code. Specifically [b]test[/b]()
|
|
40
|
+
// would be a problem, since Markdown interprets parts of this as a link.
|
|
40
41
|
|
|
41
42
|
// Parses markdown to HTML.
|
|
42
43
|
if (parseMarkdownOption) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatString.js","names":["_escape","require","_formatBBCode","_formatMarkdown","formatStringToHtml","string","options","html","tables","parseMarkdown","parseMarkdownOption","parseBBCode","parseBBCodeOption","customInlineLevelBBCodeTags","customBlockLevelBBCodeTags","formattedString","push","getMarkdownTables","error","console","warn","escapeHtmlInText","justEscapeSquareBrackets","replace","unescapeBBCodeSquareBrackets","exports"],"sources":["../../../../src/utils/formatString/formatString.ts"],"sourcesContent":["import type { TableObject } from '../../types/format';\nimport { escapeHtmlInText } from '../escape';\nimport {\n parseBBCode,\n ParseBBCodesOptions,\n unescapeBBCodeSquareBrackets,\n} from './bb-code/formatBBCode';\nimport { getMarkdownTables, parseMarkdown } from './markdown/formatMarkdown';\n\ninterface FormatStringOptions extends ParseBBCodesOptions {\n parseMarkdown?: boolean;\n parseBBCode?: boolean;\n}\n\ninterface FormatStringResult {\n html: string;\n tables: TableObject[];\n}\n\n// This function takes a string and returns formatted
|
|
1
|
+
{"version":3,"file":"formatString.js","names":["_escape","require","_formatBBCode","_formatMarkdown","formatStringToHtml","string","options","html","tables","parseMarkdown","parseMarkdownOption","parseBBCode","parseBBCodeOption","customInlineLevelBBCodeTags","customBlockLevelBBCodeTags","formattedString","push","getMarkdownTables","error","console","warn","escapeHtmlInText","justEscapeSquareBrackets","replace","unescapeBBCodeSquareBrackets","exports"],"sources":["../../../../src/utils/formatString/formatString.ts"],"sourcesContent":["import type { TableObject } from '../../types/format';\nimport { escapeHtmlInText } from '../escape';\nimport {\n parseBBCode,\n ParseBBCodesOptions,\n unescapeBBCodeSquareBrackets,\n} from './bb-code/formatBBCode';\nimport { getMarkdownTables, parseMarkdown } from './markdown/formatMarkdown';\n\ninterface FormatStringOptions extends ParseBBCodesOptions {\n parseMarkdown?: boolean;\n parseBBCode?: boolean;\n}\n\ninterface FormatStringResult {\n html: string;\n tables: TableObject[];\n}\n\n// This function takes a string and returns formatted HTML as a string.\nexport const formatStringToHtml = (\n string: string,\n options?: FormatStringOptions,\n): FormatStringResult => {\n if (!string) {\n return {\n html: '',\n tables: [],\n };\n }\n\n const {\n parseMarkdown: parseMarkdownOption = true,\n parseBBCode: parseBBCodeOption = false,\n customInlineLevelBBCodeTags = [],\n customBlockLevelBBCodeTags = [],\n } = options || {};\n\n let formattedString = string;\n\n // Needs to get the tables before escaping HTML and parsing bb-code, so the original content can be extracted.\n const tables: TableObject[] = [];\n\n if (parseMarkdownOption) {\n try {\n tables.push(...getMarkdownTables(formattedString));\n } catch (error) {\n console.warn(\n '[@chayns-components/format] Warning: Failed to get markdown tables',\n error,\n );\n }\n }\n\n // Escape HTML entities.\n formattedString = escapeHtmlInText(formattedString);\n\n // Escape BB-Code to prevent conflicts between Markdown and BB-code. Specifically [b]test[/b]()\n // would be a problem, since Markdown interprets parts of this as a link.\n\n // Parses markdown to HTML.\n if (parseMarkdownOption) {\n try {\n if (parseBBCodeOption) {\n // Escapes BB-Code brackets.\n formattedString = parseBBCode(formattedString, {\n customInlineLevelBBCodeTags,\n customBlockLevelBBCodeTags,\n justEscapeSquareBrackets: true,\n });\n }\n\n formattedString = parseMarkdown(formattedString, parseBBCodeOption);\n\n // Remove trailing \\n\n formattedString = formattedString.replace(/\\n$/, '');\n\n if (parseBBCodeOption) {\n // Unescapes BB-Code brackets.\n formattedString = unescapeBBCodeSquareBrackets(formattedString);\n }\n } catch (error) {\n console.warn('[@chayns-components/format] Warning: Failed to parse markdown', error);\n }\n }\n\n // Parses BB-Code to HTML.\n if (parseBBCodeOption) {\n try {\n formattedString = parseBBCode(formattedString, {\n customInlineLevelBBCodeTags,\n customBlockLevelBBCodeTags,\n });\n formattedString = unescapeBBCodeSquareBrackets(formattedString);\n } catch (error) {\n console.warn('[@chayns-components/format] Warning: Failed to parse bb-code', error);\n }\n }\n\n return {\n html: formattedString,\n tables,\n };\n};\n"],"mappings":";;;;;;AACA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAKA,IAAAE,eAAA,GAAAF,OAAA;AAYA;AACO,MAAMG,kBAAkB,GAAGA,CAC9BC,MAAc,EACdC,OAA6B,KACR;EACrB,IAAI,CAACD,MAAM,EAAE;IACT,OAAO;MACHE,IAAI,EAAE,EAAE;MACRC,MAAM,EAAE;IACZ,CAAC;EACL;EAEA,MAAM;IACFC,aAAa,EAAEC,mBAAmB,GAAG,IAAI;IACzCC,WAAW,EAAEC,iBAAiB,GAAG,KAAK;IACtCC,2BAA2B,GAAG,EAAE;IAChCC,0BAA0B,GAAG;EACjC,CAAC,GAAGR,OAAO,IAAI,CAAC,CAAC;EAEjB,IAAIS,eAAe,GAAGV,MAAM;;EAE5B;EACA,MAAMG,MAAqB,GAAG,EAAE;EAEhC,IAAIE,mBAAmB,EAAE;IACrB,IAAI;MACAF,MAAM,CAACQ,IAAI,CAAC,GAAG,IAAAC,iCAAiB,EAACF,eAAe,CAAC,CAAC;IACtD,CAAC,CAAC,OAAOG,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CACR,oEAAoE,EACpEF,KACJ,CAAC;IACL;EACJ;;EAEA;EACAH,eAAe,GAAG,IAAAM,wBAAgB,EAACN,eAAe,CAAC;;EAEnD;EACA;;EAEA;EACA,IAAIL,mBAAmB,EAAE;IACrB,IAAI;MACA,IAAIE,iBAAiB,EAAE;QACnB;QACAG,eAAe,GAAG,IAAAJ,yBAAW,EAACI,eAAe,EAAE;UAC3CF,2BAA2B;UAC3BC,0BAA0B;UAC1BQ,wBAAwB,EAAE;QAC9B,CAAC,CAAC;MACN;MAEAP,eAAe,GAAG,IAAAN,6BAAa,EAACM,eAAe,EAAEH,iBAAiB,CAAC;;MAEnE;MACAG,eAAe,GAAGA,eAAe,CAACQ,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;MAEpD,IAAIX,iBAAiB,EAAE;QACnB;QACAG,eAAe,GAAG,IAAAS,0CAA4B,EAACT,eAAe,CAAC;MACnE;IACJ,CAAC,CAAC,OAAOG,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,+DAA+D,EAAEF,KAAK,CAAC;IACxF;EACJ;;EAEA;EACA,IAAIN,iBAAiB,EAAE;IACnB,IAAI;MACAG,eAAe,GAAG,IAAAJ,yBAAW,EAACI,eAAe,EAAE;QAC3CF,2BAA2B;QAC3BC;MACJ,CAAC,CAAC;MACFC,eAAe,GAAG,IAAAS,0CAA4B,EAACT,eAAe,CAAC;IACnE,CAAC,CAAC,OAAOG,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,8DAA8D,EAAEF,KAAK,CAAC;IACvF;EACJ;EAEA,OAAO;IACHX,IAAI,EAAEQ,eAAe;IACrBP;EACJ,CAAC;AACL,CAAC;AAACiB,OAAA,CAAArB,kBAAA,GAAAA,kBAAA","ignoreList":[]}
|
|
@@ -4,8 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.parseMarkdown = exports.getMarkdownTables = void 0;
|
|
7
|
-
var _marked = require("marked");
|
|
8
7
|
var _sync = require("csv-stringify/browser/esm/sync");
|
|
8
|
+
var _marked = require("marked");
|
|
9
9
|
var _formatBBCode = require("../bb-code/formatBBCode");
|
|
10
10
|
// eslint-disable-next-line import/extensions,import/no-unresolved
|
|
11
11
|
|
|
@@ -14,13 +14,14 @@ const inlineTextRule = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<![`*_]|\b_|$)
|
|
|
14
14
|
const TABLE_ID_PREFIX = 'formatted-table-';
|
|
15
15
|
|
|
16
16
|
/*
|
|
17
|
-
The marked Pipeline, including tokenizer, renderer and hooks are explained here:
|
|
17
|
+
The marked Pipeline, including tokenizer, renderer and hooks, are explained here:
|
|
18
18
|
https://marked.js.org/using_pro
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
const tokenizer = {
|
|
22
|
-
// Codespan Tokenizer is overwritten to prevent
|
|
23
|
-
// The function is copied from marked.js and slightly modified:
|
|
22
|
+
// Codespan Tokenizer is overwritten to prevent HTML escaping, since HTML has been already
|
|
23
|
+
// escaped. The function is copied from marked.js and slightly modified:
|
|
24
|
+
// https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L749
|
|
24
25
|
codespan(src) {
|
|
25
26
|
const cap = inlineCodeRule.exec(src);
|
|
26
27
|
if (cap) {
|
|
@@ -31,9 +32,9 @@ const tokenizer = {
|
|
|
31
32
|
text = text.substring(1, text.length - 1);
|
|
32
33
|
}
|
|
33
34
|
return {
|
|
34
|
-
type: 'codespan',
|
|
35
35
|
raw: cap[0],
|
|
36
|
-
text
|
|
36
|
+
text,
|
|
37
|
+
type: 'codespan'
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
40
|
return undefined;
|
|
@@ -46,35 +47,39 @@ const tokenizer = {
|
|
|
46
47
|
url() {
|
|
47
48
|
return undefined;
|
|
48
49
|
},
|
|
49
|
-
// Disables converting text with 4 leading spaces to code block.
|
|
50
|
+
// Disables converting text with 4 leading spaces to the code block.
|
|
50
51
|
code() {
|
|
51
52
|
return undefined;
|
|
52
53
|
},
|
|
53
|
-
// inlineText is overwritten to prevent
|
|
54
|
-
//
|
|
54
|
+
// inlineText is overwritten to prevent HTML escaping, specifically since quote characters are
|
|
55
|
+
// escaped, which breaks the attributes of bb-code elements. The function is copied from
|
|
56
|
+
// marked.js and slightly modified:
|
|
57
|
+
// https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L854
|
|
55
58
|
inlineText(src) {
|
|
56
59
|
const cap = inlineTextRule.exec(src);
|
|
57
60
|
if (cap) {
|
|
58
61
|
return {
|
|
59
|
-
type: 'text',
|
|
60
62
|
raw: cap[0],
|
|
61
|
-
text: cap[0]
|
|
63
|
+
text: cap[0],
|
|
64
|
+
type: 'text'
|
|
62
65
|
};
|
|
63
66
|
}
|
|
64
67
|
return undefined;
|
|
65
68
|
},
|
|
66
|
-
// Disables escaping of characters via backslash. This is needed for LaTeX formulas, since
|
|
67
|
-
//
|
|
69
|
+
// Disables escaping of characters via backslash. This is needed for LaTeX formulas, since
|
|
70
|
+
// multiline LaTeX formulas have 2 backslashes at the end of their lines. Without this function,
|
|
71
|
+
// the backslashes would be escaped and the LaTeX formula would be broken.
|
|
68
72
|
escape() {
|
|
69
73
|
return undefined;
|
|
70
74
|
},
|
|
71
|
-
// Disables the conversion of backslash at the end of a line to a line break. This is needed for
|
|
75
|
+
// Disables the conversion of backslash at the end of a line to a line break. This is needed for
|
|
76
|
+
// LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.
|
|
72
77
|
// Without this '\\' would be converted to '\<br>' which breaks LaTeX formulas.
|
|
73
78
|
br() {
|
|
74
79
|
return undefined;
|
|
75
80
|
},
|
|
76
|
-
// Only recognizes ordered lists
|
|
77
|
-
//
|
|
81
|
+
// Only recognizes ordered lists that start with the number 1. Also recognizes ordered lists
|
|
82
|
+
// that contain a list item with the number 1, so those lists are
|
|
78
83
|
list(src) {
|
|
79
84
|
// The regex is copied from marked.js: https://github.com/markedjs/marked/blob/4fc639e053a605b25abf66dccaa70c1bf6562eb7/src/rules.ts#L115
|
|
80
85
|
if (/^( {0,3}[*+-]|1[.)])/.test(src)) {
|
|
@@ -86,9 +91,12 @@ const tokenizer = {
|
|
|
86
91
|
}
|
|
87
92
|
};
|
|
88
93
|
const renderer = {
|
|
89
|
-
// Code Renderer is overwritten to prevent
|
|
94
|
+
// Code Renderer is overwritten to prevent HTML escaping, since HTML has been already escaped.
|
|
90
95
|
// The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Renderer.ts#L24
|
|
91
|
-
code(
|
|
96
|
+
code({
|
|
97
|
+
lang,
|
|
98
|
+
text
|
|
99
|
+
}) {
|
|
92
100
|
var _match;
|
|
93
101
|
const langString = (_match = (lang || '').match(/^\S*/)) === null || _match === void 0 ? void 0 : _match[0];
|
|
94
102
|
const code = `${text.replace(/\n$/, '')}`;
|
|
@@ -97,27 +105,40 @@ const renderer = {
|
|
|
97
105
|
}
|
|
98
106
|
return `<pre><code class="language-${langString}">${code}</code></pre>\n`;
|
|
99
107
|
},
|
|
100
|
-
// Replaces the checkbox input elements with
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
108
|
+
// Replaces the checkbox input elements with Markdown checkboxes. This is the easiest way to
|
|
109
|
+
// prevent the formatting of Markdown checkboxes in lists. This can modify the input string
|
|
110
|
+
// slightly, since the capitalization of the checkbox can be lost. If a user types '- [X]', it
|
|
111
|
+
// will be replaced with '- [x]'.
|
|
104
112
|
checkbox({
|
|
105
113
|
checked
|
|
106
114
|
}) {
|
|
107
115
|
return checked ? '[x]' : '[ ]';
|
|
108
116
|
},
|
|
117
|
+
// Replaces the link renderer to prevent opening links in the same tab. Therefore, the target
|
|
118
|
+
// attribute is set to "_blank".
|
|
119
|
+
link({
|
|
120
|
+
href,
|
|
121
|
+
text,
|
|
122
|
+
title
|
|
123
|
+
}) {
|
|
124
|
+
if (title) {
|
|
125
|
+
return `<a href="${href}" rel="noopener noreferrer" target="_blank" title="${title}">${text}</a>`;
|
|
126
|
+
}
|
|
127
|
+
return `<a href="${href}" rel="noopener noreferrer" target="_blank">${text}</a>`;
|
|
128
|
+
},
|
|
109
129
|
// Ensures that the numbering of ordered lists is preserved.
|
|
110
|
-
listitem
|
|
130
|
+
listitem(item) {
|
|
111
131
|
if (item.task) {
|
|
112
132
|
return false;
|
|
113
133
|
}
|
|
114
134
|
const match = item.raw.trim().match(/^\d{1,9}[.)]/);
|
|
135
|
+
|
|
115
136
|
// Removes the trailing dot or parenthesis from the match.
|
|
116
137
|
const value = match ? match[0].slice(0, match[0].length - 1) : '';
|
|
117
138
|
if (value) {
|
|
118
139
|
let itemBody = '';
|
|
119
|
-
|
|
120
|
-
|
|
140
|
+
itemBody += this.parser.parse(item.tokens);
|
|
141
|
+
|
|
121
142
|
// Sets the value attribute of the list item to the number of the list item.
|
|
122
143
|
return `<li value="${value}">${itemBody}</li>\n`;
|
|
123
144
|
}
|
|
@@ -127,18 +148,16 @@ const renderer = {
|
|
|
127
148
|
}
|
|
128
149
|
};
|
|
129
150
|
const postprocess = html => {
|
|
130
|
-
let tableIndex =
|
|
151
|
+
let tableIndex = -1;
|
|
152
|
+
|
|
131
153
|
// Assigns ids to tables.
|
|
132
|
-
|
|
133
|
-
const result = `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
154
|
+
return html.replace(/(<table>)/g, () => {
|
|
134
155
|
tableIndex++;
|
|
135
|
-
return
|
|
156
|
+
return `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
136
157
|
});
|
|
137
|
-
return modifiedString;
|
|
138
158
|
};
|
|
139
159
|
|
|
140
160
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
141
|
-
// @ts-ignore
|
|
142
161
|
_marked.marked.use({
|
|
143
162
|
tokenizer,
|
|
144
163
|
renderer,
|
|
@@ -147,8 +166,8 @@ _marked.marked.use({
|
|
|
147
166
|
}
|
|
148
167
|
});
|
|
149
168
|
|
|
150
|
-
// Parses markdown following the
|
|
151
|
-
//
|
|
169
|
+
// Parses markdown following the GitHub flavored Markdown specification. The tokenizer and renderer
|
|
170
|
+
// are slightly modified to prevent HTML escaping in code block and inline code.
|
|
152
171
|
const parseMarkdown = (text, parseBBCode) => _marked.marked.parse(text, {
|
|
153
172
|
walkTokens: token => {
|
|
154
173
|
if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {
|
|
@@ -158,12 +177,15 @@ const parseMarkdown = (text, parseBBCode) => _marked.marked.parse(text, {
|
|
|
158
177
|
}
|
|
159
178
|
});
|
|
160
179
|
|
|
161
|
-
// It is important that, & is replaced
|
|
180
|
+
// It is important that, & is replaced last to prevent double escaping.
|
|
162
181
|
exports.parseMarkdown = parseMarkdown;
|
|
163
182
|
const unescapeHtml = text => text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');
|
|
164
183
|
const getMarkdownTables = text => {
|
|
165
184
|
const tableTokens = [];
|
|
166
|
-
|
|
185
|
+
|
|
186
|
+
// Since walkTokens is not called with async functions and parseInline is not used, the result
|
|
187
|
+
// of parse is synchronous. To match the type, it will be voided here.
|
|
188
|
+
void _marked.marked.parse(text, {
|
|
167
189
|
walkTokens: token => {
|
|
168
190
|
if (token.type === 'table') {
|
|
169
191
|
tableTokens.push(token);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatMarkdown.js","names":["_marked","require","_sync","_formatBBCode","inlineCodeRule","inlineTextRule","TABLE_ID_PREFIX","tokenizer","codespan","src","cap","exec","text","replace","hasNonSpaceChars","test","hasSpaceCharsOnBothEnds","substring","length","type","raw","undefined","lheading","url","code","inlineText","escape","br","list","renderer","lang","_match","langString","match","checkbox","checked","listitem","item","task","trim","value","slice","itemBody","parser","parse","tokens","loose","postprocess","html","tableIndex","modifiedString","result","marked","use","hooks","parseMarkdown","parseBBCode","walkTokens","token","escapeBBCodeSquareBrackets","exports","unescapeHtml","replaceAll","getMarkdownTables","tableTokens","push","tables","forEach","tableToken","index","_tableToken$header","_tableToken$rows","tableArray","header","rowArray","rows","row","cell","csv","stringify","id"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdown.ts"],"sourcesContent":["import { marked, Tokens } from 'marked';\nimport type { TableObject } from '../../../types/format';\n// eslint-disable-next-line import/extensions,import/no-unresolved\nimport { stringify } from 'csv-stringify/browser/esm/sync';\nimport { escapeBBCodeSquareBrackets } from '../bb-code/formatBBCode';\n\nconst inlineCodeRule = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst inlineTextRule = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<![`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n\nconst TABLE_ID_PREFIX = 'formatted-table-';\n\n/*\n The marked Pipeline, including tokenizer, renderer and hooks are explained here:\n https://marked.js.org/using_pro\n*/\n\nconst tokenizer = {\n // Codespan Tokenizer is overwritten to prevent html escaping, since html is already escaped.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L749\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = inlineCodeRule.exec(src);\n if (cap) {\n let text = (cap[2] as string).replace(/\\n/g, ' ');\n const hasNonSpaceChars = /[^ ]/.test(text);\n const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n\n return {\n type: 'codespan',\n raw: cap[0],\n text,\n };\n }\n\n return undefined;\n },\n // Disables Markdown formatting for setext headings.\n lheading(): Tokens.Heading | undefined {\n return undefined;\n },\n // Disables converting urls to hyperlinks.\n url() {\n return undefined;\n },\n // Disables converting text with 4 leading spaces to code block.\n code() {\n return undefined;\n },\n // inlineText is overwritten to prevent html escaping, specifically since quote characters are escaped, which breaks the attributes of bb-code elements.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L854\n inlineText(src: string) {\n const cap = inlineTextRule.exec(src);\n if (cap) {\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n };\n }\n return undefined;\n },\n // Disables escaping of characters via backslash. This is needed for LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.\n // Without this function, the backslashes would be escaped and the LaTeX formula would be broken.\n escape() {\n return undefined;\n },\n // Disables the conversion of backslash at the end of a line to a line break. This is needed for LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.\n // Without this '\\\\' would be converted to '\\<br>' which breaks LaTeX formulas.\n br() {\n return undefined;\n },\n // Only recognizes ordered lists, that start with the number 1.\n // Also recognizes ordered lists, that contain a list item with the number 1, so those lists are\n list(src: string) {\n // The regex is copied from marked.js: https://github.com/markedjs/marked/blob/4fc639e053a605b25abf66dccaa70c1bf6562eb7/src/rules.ts#L115\n if (/^( {0,3}[*+-]|1[.)])/.test(src)) {\n return false;\n }\n\n // Prevents the text from being recognized as a list.\n return undefined;\n },\n};\n\nconst renderer = {\n // Code Renderer is overwritten to prevent html escaping, since html is already escaped.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Renderer.ts#L24\n code(text: string, lang: string): string {\n const langString = (lang || '').match(/^\\S*/)?.[0];\n\n const code = `${text.replace(/\\n$/, '')}`;\n\n if (!langString) {\n return `<pre><code>${code}</code></pre>\\n`;\n }\n\n return `<pre><code class=\"language-${langString}\">${code}</code></pre>\\n`;\n },\n // Replaces the checkbox input elements with markdown checkboxes.\n // This is the easiest way to prevent the formatting of markdown checkboxes in lists.\n // This can modify the input string slightly, since the capitalization of the checkbox can be lost.\n // If a user types '- [X]' it will be replaced with '- [x]' => the capitalization is lost.\n checkbox({ checked }: Tokens.Checkbox) {\n return checked ? '[x]' : '[ ]';\n },\n // Ensures that the numbering of ordered lists is preserved.\n listitem: function (item: Tokens.ListItem) {\n if (item.task) {\n return false;\n }\n\n const match = item.raw.trim().match(/^\\d{1,9}[.)]/);\n // Removes the trailing dot or parenthesis from the match.\n const value = match ? match[0].slice(0, match[0].length - 1) : '';\n if (value) {\n let itemBody = '';\n // @ts-ignore\n itemBody += this.parser.parse(item.tokens, !!item.loose);\n // Sets the value attribute of the list item to the number of the list item.\n return `<li value=\"${value}\">${itemBody}</li>\\n`;\n }\n\n // Ensures that the default listitem renderer from marked js is used.\n return false;\n },\n};\n\nconst postprocess = (html: string): string => {\n let tableIndex = 0;\n // Assigns ids to tables.\n const modifiedString = html.replace(/(<table>)/g, () => {\n const result = `<table id=\"${TABLE_ID_PREFIX}${tableIndex}\">`;\n tableIndex++;\n return result;\n });\n\n return modifiedString;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nmarked.use({ tokenizer, renderer, hooks: { postprocess } });\n\n// Parses markdown following the Github Flavored Markdown specification.\n// The tokenizer and renderer are slightly modified to prevent html escaping in code block and inline code.\nexport const parseMarkdown = (text: string, parseBBCode: boolean) =>\n marked.parse(text, {\n walkTokens: (token) => {\n if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {\n // eslint-disable-next-line no-param-reassign\n (token as Tokens.Codespan).text = escapeBBCodeSquareBrackets(\n (token as Tokens.Codespan).text,\n );\n }\n },\n }) as string;\n\n// It is important that, & is replaced lastly to prevent double escaping.\nconst unescapeHtml = (text: string) =>\n text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');\n\nexport const getMarkdownTables = (text: string): TableObject[] => {\n const tableTokens: Tokens.Table[] = [];\n\n marked.parse(text, {\n walkTokens: (token) => {\n if (token.type === 'table') {\n tableTokens.push(token as Tokens.Table);\n }\n },\n }) as string;\n\n const tables: TableObject[] = [];\n\n tableTokens.forEach((tableToken, index) => {\n const tableArray: string[][] = [];\n\n if (tableToken.header?.length > 0) {\n const rowArray: string[] = [];\n\n tableToken.header.forEach((header) => {\n rowArray.push(unescapeHtml(header.text));\n });\n\n tableArray.push(rowArray);\n }\n if (tableToken.rows?.length > 0) {\n tableToken.rows.forEach((row) => {\n const rowArray: string[] = [];\n\n row.forEach((cell) => {\n rowArray.push(unescapeHtml(cell.text));\n });\n\n tableArray.push(rowArray);\n });\n }\n\n const csv = stringify(tableArray || []);\n\n tables.push({\n raw: unescapeHtml(tableToken.raw),\n csv,\n id: `${TABLE_ID_PREFIX}${index}`,\n });\n });\n\n return tables;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"formatMarkdown.js","names":["_sync","require","_marked","_formatBBCode","inlineCodeRule","inlineTextRule","TABLE_ID_PREFIX","tokenizer","codespan","src","cap","exec","text","replace","hasNonSpaceChars","test","hasSpaceCharsOnBothEnds","substring","length","raw","type","undefined","lheading","url","code","inlineText","escape","br","list","renderer","lang","_match","langString","match","checkbox","checked","link","href","title","listitem","item","task","trim","value","slice","itemBody","parser","parse","tokens","postprocess","html","tableIndex","marked","use","hooks","parseMarkdown","parseBBCode","walkTokens","token","escapeBBCodeSquareBrackets","exports","unescapeHtml","replaceAll","getMarkdownTables","tableTokens","push","tables","forEach","tableToken","index","_tableToken$header","_tableToken$rows","tableArray","header","rowArray","rows","row","cell","csv","stringify","id"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdown.ts"],"sourcesContent":["// eslint-disable-next-line import/extensions,import/no-unresolved\nimport { stringify } from 'csv-stringify/browser/esm/sync';\nimport { marked, RendererObject, TokenizerObject, Tokens } from 'marked';\nimport type { TableObject } from '../../../types/format';\nimport { escapeBBCodeSquareBrackets } from '../bb-code/formatBBCode';\n\nconst inlineCodeRule = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst inlineTextRule = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<![`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n\nconst TABLE_ID_PREFIX = 'formatted-table-';\n\n/*\n The marked Pipeline, including tokenizer, renderer and hooks, are explained here:\n https://marked.js.org/using_pro\n*/\n\nconst tokenizer: TokenizerObject = {\n // Codespan Tokenizer is overwritten to prevent HTML escaping, since HTML has been already\n // escaped. The function is copied from marked.js and slightly modified:\n // https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L749\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = inlineCodeRule.exec(src);\n\n if (cap) {\n let text = (cap[2] as string).replace(/\\n/g, ' ');\n\n const hasNonSpaceChars = /[^ ]/.test(text);\n const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n\n return { raw: cap[0], text, type: 'codespan' };\n }\n\n return undefined;\n },\n // Disables Markdown formatting for setext headings.\n lheading(): Tokens.Heading | undefined {\n return undefined;\n },\n // Disables converting urls to hyperlinks.\n url() {\n return undefined;\n },\n // Disables converting text with 4 leading spaces to the code block.\n code() {\n return undefined;\n },\n // inlineText is overwritten to prevent HTML escaping, specifically since quote characters are\n // escaped, which breaks the attributes of bb-code elements. The function is copied from\n // marked.js and slightly modified:\n // https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L854\n inlineText(src: string) {\n const cap = inlineTextRule.exec(src);\n\n if (cap) {\n return { raw: cap[0], text: cap[0], type: 'text' };\n }\n\n return undefined;\n },\n // Disables escaping of characters via backslash. This is needed for LaTeX formulas, since\n // multiline LaTeX formulas have 2 backslashes at the end of their lines. Without this function,\n // the backslashes would be escaped and the LaTeX formula would be broken.\n escape() {\n return undefined;\n },\n // Disables the conversion of backslash at the end of a line to a line break. This is needed for\n // LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.\n // Without this '\\\\' would be converted to '\\<br>' which breaks LaTeX formulas.\n br() {\n return undefined;\n },\n // Only recognizes ordered lists that start with the number 1. Also recognizes ordered lists\n // that contain a list item with the number 1, so those lists are\n list(src: string) {\n // The regex is copied from marked.js: https://github.com/markedjs/marked/blob/4fc639e053a605b25abf66dccaa70c1bf6562eb7/src/rules.ts#L115\n if (/^( {0,3}[*+-]|1[.)])/.test(src)) {\n return false;\n }\n\n // Prevents the text from being recognized as a list.\n return undefined;\n },\n};\n\nconst renderer: RendererObject = {\n // Code Renderer is overwritten to prevent HTML escaping, since HTML has been already escaped.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Renderer.ts#L24\n code({ lang, text }: Tokens.Code): string {\n const langString = (lang || '').match(/^\\S*/)?.[0];\n\n const code = `${text.replace(/\\n$/, '')}`;\n\n if (!langString) {\n return `<pre><code>${code}</code></pre>\\n`;\n }\n\n return `<pre><code class=\"language-${langString}\">${code}</code></pre>\\n`;\n },\n // Replaces the checkbox input elements with Markdown checkboxes. This is the easiest way to\n // prevent the formatting of Markdown checkboxes in lists. This can modify the input string\n // slightly, since the capitalization of the checkbox can be lost. If a user types '- [X]', it\n // will be replaced with '- [x]'.\n checkbox({ checked }: Tokens.Checkbox) {\n return checked ? '[x]' : '[ ]';\n },\n // Replaces the link renderer to prevent opening links in the same tab. Therefore, the target\n // attribute is set to \"_blank\".\n link({ href, text, title }: Tokens.Link): string {\n if (title) {\n return `<a href=\"${href}\" rel=\"noopener noreferrer\" target=\"_blank\" title=\"${title}\">${text}</a>`;\n }\n\n return `<a href=\"${href}\" rel=\"noopener noreferrer\" target=\"_blank\">${text}</a>`;\n },\n // Ensures that the numbering of ordered lists is preserved.\n listitem(item: Tokens.ListItem) {\n if (item.task) {\n return false;\n }\n\n const match = item.raw.trim().match(/^\\d{1,9}[.)]/);\n\n // Removes the trailing dot or parenthesis from the match.\n const value = match ? match[0].slice(0, match[0].length - 1) : '';\n\n if (value) {\n let itemBody = '';\n\n itemBody += this.parser.parse(item.tokens);\n\n // Sets the value attribute of the list item to the number of the list item.\n return `<li value=\"${value}\">${itemBody}</li>\\n`;\n }\n\n // Ensures that the default listitem renderer from marked js is used.\n return false;\n },\n};\n\nconst postprocess = (html: string): string => {\n let tableIndex = -1;\n\n // Assigns ids to tables.\n return html.replace(/(<table>)/g, () => {\n tableIndex++;\n\n return `<table id=\"${TABLE_ID_PREFIX}${tableIndex}\">`;\n });\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\nmarked.use({ tokenizer, renderer, hooks: { postprocess } });\n\n// Parses markdown following the GitHub flavored Markdown specification. The tokenizer and renderer\n// are slightly modified to prevent HTML escaping in code block and inline code.\nexport const parseMarkdown = (text: string, parseBBCode: boolean) =>\n marked.parse(text, {\n walkTokens: (token) => {\n if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {\n // eslint-disable-next-line no-param-reassign\n (token as Tokens.Codespan).text = escapeBBCodeSquareBrackets(\n (token as Tokens.Codespan).text,\n );\n }\n },\n }) as string;\n\n// It is important that, & is replaced last to prevent double escaping.\nconst unescapeHtml = (text: string) =>\n text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');\n\nexport const getMarkdownTables = (text: string): TableObject[] => {\n const tableTokens: Tokens.Table[] = [];\n\n // Since walkTokens is not called with async functions and parseInline is not used, the result\n // of parse is synchronous. To match the type, it will be voided here.\n void marked.parse(text, {\n walkTokens: (token) => {\n if (token.type === 'table') {\n tableTokens.push(token as Tokens.Table);\n }\n },\n });\n\n const tables: TableObject[] = [];\n\n tableTokens.forEach((tableToken, index) => {\n const tableArray: string[][] = [];\n\n if (tableToken.header?.length > 0) {\n const rowArray: string[] = [];\n\n tableToken.header.forEach((header) => {\n rowArray.push(unescapeHtml(header.text));\n });\n\n tableArray.push(rowArray);\n }\n\n if (tableToken.rows?.length > 0) {\n tableToken.rows.forEach((row) => {\n const rowArray: string[] = [];\n\n row.forEach((cell) => {\n rowArray.push(unescapeHtml(cell.text));\n });\n\n tableArray.push(rowArray);\n });\n }\n\n const csv = stringify(tableArray || []);\n\n tables.push({\n raw: unescapeHtml(tableToken.raw),\n csv,\n id: `${TABLE_ID_PREFIX}${index}`,\n });\n });\n\n return tables;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { escapeHtmlInText } from '../escape';
|
|
2
2
|
import { parseBBCode, unescapeBBCodeSquareBrackets } from './bb-code/formatBBCode';
|
|
3
3
|
import { getMarkdownTables, parseMarkdown } from './markdown/formatMarkdown';
|
|
4
|
-
// This function takes a string and returns formatted
|
|
4
|
+
// This function takes a string and returns formatted HTML as a string.
|
|
5
5
|
export const formatStringToHtml = (string, options) => {
|
|
6
6
|
if (!string) {
|
|
7
7
|
return {
|
|
@@ -17,7 +17,7 @@ export const formatStringToHtml = (string, options) => {
|
|
|
17
17
|
} = options || {};
|
|
18
18
|
let formattedString = string;
|
|
19
19
|
|
|
20
|
-
// Needs to get the tables before escaping
|
|
20
|
+
// Needs to get the tables before escaping HTML and parsing bb-code, so the original content can be extracted.
|
|
21
21
|
const tables = [];
|
|
22
22
|
if (parseMarkdownOption) {
|
|
23
23
|
try {
|
|
@@ -30,7 +30,8 @@ export const formatStringToHtml = (string, options) => {
|
|
|
30
30
|
// Escape HTML entities.
|
|
31
31
|
formattedString = escapeHtmlInText(formattedString);
|
|
32
32
|
|
|
33
|
-
// Escape BB-Code
|
|
33
|
+
// Escape BB-Code to prevent conflicts between Markdown and BB-code. Specifically [b]test[/b]()
|
|
34
|
+
// would be a problem, since Markdown interprets parts of this as a link.
|
|
34
35
|
|
|
35
36
|
// Parses markdown to HTML.
|
|
36
37
|
if (parseMarkdownOption) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatString.js","names":["escapeHtmlInText","parseBBCode","unescapeBBCodeSquareBrackets","getMarkdownTables","parseMarkdown","formatStringToHtml","string","options","html","tables","parseMarkdownOption","parseBBCodeOption","customInlineLevelBBCodeTags","customBlockLevelBBCodeTags","formattedString","push","error","console","warn","justEscapeSquareBrackets","replace"],"sources":["../../../../src/utils/formatString/formatString.ts"],"sourcesContent":["import type { TableObject } from '../../types/format';\nimport { escapeHtmlInText } from '../escape';\nimport {\n parseBBCode,\n ParseBBCodesOptions,\n unescapeBBCodeSquareBrackets,\n} from './bb-code/formatBBCode';\nimport { getMarkdownTables, parseMarkdown } from './markdown/formatMarkdown';\n\ninterface FormatStringOptions extends ParseBBCodesOptions {\n parseMarkdown?: boolean;\n parseBBCode?: boolean;\n}\n\ninterface FormatStringResult {\n html: string;\n tables: TableObject[];\n}\n\n// This function takes a string and returns formatted
|
|
1
|
+
{"version":3,"file":"formatString.js","names":["escapeHtmlInText","parseBBCode","unescapeBBCodeSquareBrackets","getMarkdownTables","parseMarkdown","formatStringToHtml","string","options","html","tables","parseMarkdownOption","parseBBCodeOption","customInlineLevelBBCodeTags","customBlockLevelBBCodeTags","formattedString","push","error","console","warn","justEscapeSquareBrackets","replace"],"sources":["../../../../src/utils/formatString/formatString.ts"],"sourcesContent":["import type { TableObject } from '../../types/format';\nimport { escapeHtmlInText } from '../escape';\nimport {\n parseBBCode,\n ParseBBCodesOptions,\n unescapeBBCodeSquareBrackets,\n} from './bb-code/formatBBCode';\nimport { getMarkdownTables, parseMarkdown } from './markdown/formatMarkdown';\n\ninterface FormatStringOptions extends ParseBBCodesOptions {\n parseMarkdown?: boolean;\n parseBBCode?: boolean;\n}\n\ninterface FormatStringResult {\n html: string;\n tables: TableObject[];\n}\n\n// This function takes a string and returns formatted HTML as a string.\nexport const formatStringToHtml = (\n string: string,\n options?: FormatStringOptions,\n): FormatStringResult => {\n if (!string) {\n return {\n html: '',\n tables: [],\n };\n }\n\n const {\n parseMarkdown: parseMarkdownOption = true,\n parseBBCode: parseBBCodeOption = false,\n customInlineLevelBBCodeTags = [],\n customBlockLevelBBCodeTags = [],\n } = options || {};\n\n let formattedString = string;\n\n // Needs to get the tables before escaping HTML and parsing bb-code, so the original content can be extracted.\n const tables: TableObject[] = [];\n\n if (parseMarkdownOption) {\n try {\n tables.push(...getMarkdownTables(formattedString));\n } catch (error) {\n console.warn(\n '[@chayns-components/format] Warning: Failed to get markdown tables',\n error,\n );\n }\n }\n\n // Escape HTML entities.\n formattedString = escapeHtmlInText(formattedString);\n\n // Escape BB-Code to prevent conflicts between Markdown and BB-code. Specifically [b]test[/b]()\n // would be a problem, since Markdown interprets parts of this as a link.\n\n // Parses markdown to HTML.\n if (parseMarkdownOption) {\n try {\n if (parseBBCodeOption) {\n // Escapes BB-Code brackets.\n formattedString = parseBBCode(formattedString, {\n customInlineLevelBBCodeTags,\n customBlockLevelBBCodeTags,\n justEscapeSquareBrackets: true,\n });\n }\n\n formattedString = parseMarkdown(formattedString, parseBBCodeOption);\n\n // Remove trailing \\n\n formattedString = formattedString.replace(/\\n$/, '');\n\n if (parseBBCodeOption) {\n // Unescapes BB-Code brackets.\n formattedString = unescapeBBCodeSquareBrackets(formattedString);\n }\n } catch (error) {\n console.warn('[@chayns-components/format] Warning: Failed to parse markdown', error);\n }\n }\n\n // Parses BB-Code to HTML.\n if (parseBBCodeOption) {\n try {\n formattedString = parseBBCode(formattedString, {\n customInlineLevelBBCodeTags,\n customBlockLevelBBCodeTags,\n });\n formattedString = unescapeBBCodeSquareBrackets(formattedString);\n } catch (error) {\n console.warn('[@chayns-components/format] Warning: Failed to parse bb-code', error);\n }\n }\n\n return {\n html: formattedString,\n tables,\n };\n};\n"],"mappings":"AACA,SAASA,gBAAgB,QAAQ,WAAW;AAC5C,SACIC,WAAW,EAEXC,4BAA4B,QACzB,wBAAwB;AAC/B,SAASC,iBAAiB,EAAEC,aAAa,QAAQ,2BAA2B;AAY5E;AACA,OAAO,MAAMC,kBAAkB,GAAGA,CAC9BC,MAAc,EACdC,OAA6B,KACR;EACrB,IAAI,CAACD,MAAM,EAAE;IACT,OAAO;MACHE,IAAI,EAAE,EAAE;MACRC,MAAM,EAAE;IACZ,CAAC;EACL;EAEA,MAAM;IACFL,aAAa,EAAEM,mBAAmB,GAAG,IAAI;IACzCT,WAAW,EAAEU,iBAAiB,GAAG,KAAK;IACtCC,2BAA2B,GAAG,EAAE;IAChCC,0BAA0B,GAAG;EACjC,CAAC,GAAGN,OAAO,IAAI,CAAC,CAAC;EAEjB,IAAIO,eAAe,GAAGR,MAAM;;EAE5B;EACA,MAAMG,MAAqB,GAAG,EAAE;EAEhC,IAAIC,mBAAmB,EAAE;IACrB,IAAI;MACAD,MAAM,CAACM,IAAI,CAAC,GAAGZ,iBAAiB,CAACW,eAAe,CAAC,CAAC;IACtD,CAAC,CAAC,OAAOE,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CACR,oEAAoE,EACpEF,KACJ,CAAC;IACL;EACJ;;EAEA;EACAF,eAAe,GAAGd,gBAAgB,CAACc,eAAe,CAAC;;EAEnD;EACA;;EAEA;EACA,IAAIJ,mBAAmB,EAAE;IACrB,IAAI;MACA,IAAIC,iBAAiB,EAAE;QACnB;QACAG,eAAe,GAAGb,WAAW,CAACa,eAAe,EAAE;UAC3CF,2BAA2B;UAC3BC,0BAA0B;UAC1BM,wBAAwB,EAAE;QAC9B,CAAC,CAAC;MACN;MAEAL,eAAe,GAAGV,aAAa,CAACU,eAAe,EAAEH,iBAAiB,CAAC;;MAEnE;MACAG,eAAe,GAAGA,eAAe,CAACM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;MAEpD,IAAIT,iBAAiB,EAAE;QACnB;QACAG,eAAe,GAAGZ,4BAA4B,CAACY,eAAe,CAAC;MACnE;IACJ,CAAC,CAAC,OAAOE,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,+DAA+D,EAAEF,KAAK,CAAC;IACxF;EACJ;;EAEA;EACA,IAAIL,iBAAiB,EAAE;IACnB,IAAI;MACAG,eAAe,GAAGb,WAAW,CAACa,eAAe,EAAE;QAC3CF,2BAA2B;QAC3BC;MACJ,CAAC,CAAC;MACFC,eAAe,GAAGZ,4BAA4B,CAACY,eAAe,CAAC;IACnE,CAAC,CAAC,OAAOE,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,8DAA8D,EAAEF,KAAK,CAAC;IACvF;EACJ;EAEA,OAAO;IACHR,IAAI,EAAEM,eAAe;IACrBL;EACJ,CAAC;AACL,CAAC","ignoreList":[]}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { marked } from 'marked';
|
|
2
1
|
// eslint-disable-next-line import/extensions,import/no-unresolved
|
|
3
2
|
import { stringify } from 'csv-stringify/browser/esm/sync';
|
|
3
|
+
import { marked } from 'marked';
|
|
4
4
|
import { escapeBBCodeSquareBrackets } from '../bb-code/formatBBCode';
|
|
5
5
|
const inlineCodeRule = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
|
|
6
6
|
const inlineTextRule = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<![`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
|
|
7
7
|
const TABLE_ID_PREFIX = 'formatted-table-';
|
|
8
8
|
|
|
9
9
|
/*
|
|
10
|
-
The marked Pipeline, including tokenizer, renderer and hooks are explained here:
|
|
10
|
+
The marked Pipeline, including tokenizer, renderer and hooks, are explained here:
|
|
11
11
|
https://marked.js.org/using_pro
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const tokenizer = {
|
|
15
|
-
// Codespan Tokenizer is overwritten to prevent
|
|
16
|
-
// The function is copied from marked.js and slightly modified:
|
|
15
|
+
// Codespan Tokenizer is overwritten to prevent HTML escaping, since HTML has been already
|
|
16
|
+
// escaped. The function is copied from marked.js and slightly modified:
|
|
17
|
+
// https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L749
|
|
17
18
|
codespan(src) {
|
|
18
19
|
const cap = inlineCodeRule.exec(src);
|
|
19
20
|
if (cap) {
|
|
@@ -24,9 +25,9 @@ const tokenizer = {
|
|
|
24
25
|
text = text.substring(1, text.length - 1);
|
|
25
26
|
}
|
|
26
27
|
return {
|
|
27
|
-
type: 'codespan',
|
|
28
28
|
raw: cap[0],
|
|
29
|
-
text
|
|
29
|
+
text,
|
|
30
|
+
type: 'codespan'
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
return undefined;
|
|
@@ -39,35 +40,39 @@ const tokenizer = {
|
|
|
39
40
|
url() {
|
|
40
41
|
return undefined;
|
|
41
42
|
},
|
|
42
|
-
// Disables converting text with 4 leading spaces to code block.
|
|
43
|
+
// Disables converting text with 4 leading spaces to the code block.
|
|
43
44
|
code() {
|
|
44
45
|
return undefined;
|
|
45
46
|
},
|
|
46
|
-
// inlineText is overwritten to prevent
|
|
47
|
-
//
|
|
47
|
+
// inlineText is overwritten to prevent HTML escaping, specifically since quote characters are
|
|
48
|
+
// escaped, which breaks the attributes of bb-code elements. The function is copied from
|
|
49
|
+
// marked.js and slightly modified:
|
|
50
|
+
// https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L854
|
|
48
51
|
inlineText(src) {
|
|
49
52
|
const cap = inlineTextRule.exec(src);
|
|
50
53
|
if (cap) {
|
|
51
54
|
return {
|
|
52
|
-
type: 'text',
|
|
53
55
|
raw: cap[0],
|
|
54
|
-
text: cap[0]
|
|
56
|
+
text: cap[0],
|
|
57
|
+
type: 'text'
|
|
55
58
|
};
|
|
56
59
|
}
|
|
57
60
|
return undefined;
|
|
58
61
|
},
|
|
59
|
-
// Disables escaping of characters via backslash. This is needed for LaTeX formulas, since
|
|
60
|
-
//
|
|
62
|
+
// Disables escaping of characters via backslash. This is needed for LaTeX formulas, since
|
|
63
|
+
// multiline LaTeX formulas have 2 backslashes at the end of their lines. Without this function,
|
|
64
|
+
// the backslashes would be escaped and the LaTeX formula would be broken.
|
|
61
65
|
escape() {
|
|
62
66
|
return undefined;
|
|
63
67
|
},
|
|
64
|
-
// Disables the conversion of backslash at the end of a line to a line break. This is needed for
|
|
68
|
+
// Disables the conversion of backslash at the end of a line to a line break. This is needed for
|
|
69
|
+
// LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.
|
|
65
70
|
// Without this '\\' would be converted to '\<br>' which breaks LaTeX formulas.
|
|
66
71
|
br() {
|
|
67
72
|
return undefined;
|
|
68
73
|
},
|
|
69
|
-
// Only recognizes ordered lists
|
|
70
|
-
//
|
|
74
|
+
// Only recognizes ordered lists that start with the number 1. Also recognizes ordered lists
|
|
75
|
+
// that contain a list item with the number 1, so those lists are
|
|
71
76
|
list(src) {
|
|
72
77
|
// The regex is copied from marked.js: https://github.com/markedjs/marked/blob/4fc639e053a605b25abf66dccaa70c1bf6562eb7/src/rules.ts#L115
|
|
73
78
|
if (/^( {0,3}[*+-]|1[.)])/.test(src)) {
|
|
@@ -79,9 +84,12 @@ const tokenizer = {
|
|
|
79
84
|
}
|
|
80
85
|
};
|
|
81
86
|
const renderer = {
|
|
82
|
-
// Code Renderer is overwritten to prevent
|
|
87
|
+
// Code Renderer is overwritten to prevent HTML escaping, since HTML has been already escaped.
|
|
83
88
|
// The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Renderer.ts#L24
|
|
84
|
-
code(
|
|
89
|
+
code({
|
|
90
|
+
lang,
|
|
91
|
+
text
|
|
92
|
+
}) {
|
|
85
93
|
const langString = (lang || '').match(/^\S*/)?.[0];
|
|
86
94
|
const code = `${text.replace(/\n$/, '')}`;
|
|
87
95
|
if (!langString) {
|
|
@@ -89,27 +97,40 @@ const renderer = {
|
|
|
89
97
|
}
|
|
90
98
|
return `<pre><code class="language-${langString}">${code}</code></pre>\n`;
|
|
91
99
|
},
|
|
92
|
-
// Replaces the checkbox input elements with
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
100
|
+
// Replaces the checkbox input elements with Markdown checkboxes. This is the easiest way to
|
|
101
|
+
// prevent the formatting of Markdown checkboxes in lists. This can modify the input string
|
|
102
|
+
// slightly, since the capitalization of the checkbox can be lost. If a user types '- [X]', it
|
|
103
|
+
// will be replaced with '- [x]'.
|
|
96
104
|
checkbox({
|
|
97
105
|
checked
|
|
98
106
|
}) {
|
|
99
107
|
return checked ? '[x]' : '[ ]';
|
|
100
108
|
},
|
|
109
|
+
// Replaces the link renderer to prevent opening links in the same tab. Therefore, the target
|
|
110
|
+
// attribute is set to "_blank".
|
|
111
|
+
link({
|
|
112
|
+
href,
|
|
113
|
+
text,
|
|
114
|
+
title
|
|
115
|
+
}) {
|
|
116
|
+
if (title) {
|
|
117
|
+
return `<a href="${href}" rel="noopener noreferrer" target="_blank" title="${title}">${text}</a>`;
|
|
118
|
+
}
|
|
119
|
+
return `<a href="${href}" rel="noopener noreferrer" target="_blank">${text}</a>`;
|
|
120
|
+
},
|
|
101
121
|
// Ensures that the numbering of ordered lists is preserved.
|
|
102
|
-
listitem
|
|
122
|
+
listitem(item) {
|
|
103
123
|
if (item.task) {
|
|
104
124
|
return false;
|
|
105
125
|
}
|
|
106
126
|
const match = item.raw.trim().match(/^\d{1,9}[.)]/);
|
|
127
|
+
|
|
107
128
|
// Removes the trailing dot or parenthesis from the match.
|
|
108
129
|
const value = match ? match[0].slice(0, match[0].length - 1) : '';
|
|
109
130
|
if (value) {
|
|
110
131
|
let itemBody = '';
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
itemBody += this.parser.parse(item.tokens);
|
|
133
|
+
|
|
113
134
|
// Sets the value attribute of the list item to the number of the list item.
|
|
114
135
|
return `<li value="${value}">${itemBody}</li>\n`;
|
|
115
136
|
}
|
|
@@ -119,18 +140,16 @@ const renderer = {
|
|
|
119
140
|
}
|
|
120
141
|
};
|
|
121
142
|
const postprocess = html => {
|
|
122
|
-
let tableIndex =
|
|
143
|
+
let tableIndex = -1;
|
|
144
|
+
|
|
123
145
|
// Assigns ids to tables.
|
|
124
|
-
|
|
125
|
-
const result = `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
146
|
+
return html.replace(/(<table>)/g, () => {
|
|
126
147
|
tableIndex++;
|
|
127
|
-
return
|
|
148
|
+
return `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
128
149
|
});
|
|
129
|
-
return modifiedString;
|
|
130
150
|
};
|
|
131
151
|
|
|
132
152
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
133
|
-
// @ts-ignore
|
|
134
153
|
marked.use({
|
|
135
154
|
tokenizer,
|
|
136
155
|
renderer,
|
|
@@ -139,8 +158,8 @@ marked.use({
|
|
|
139
158
|
}
|
|
140
159
|
});
|
|
141
160
|
|
|
142
|
-
// Parses markdown following the
|
|
143
|
-
//
|
|
161
|
+
// Parses markdown following the GitHub flavored Markdown specification. The tokenizer and renderer
|
|
162
|
+
// are slightly modified to prevent HTML escaping in code block and inline code.
|
|
144
163
|
export const parseMarkdown = (text, parseBBCode) => marked.parse(text, {
|
|
145
164
|
walkTokens: token => {
|
|
146
165
|
if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {
|
|
@@ -150,11 +169,14 @@ export const parseMarkdown = (text, parseBBCode) => marked.parse(text, {
|
|
|
150
169
|
}
|
|
151
170
|
});
|
|
152
171
|
|
|
153
|
-
// It is important that, & is replaced
|
|
172
|
+
// It is important that, & is replaced last to prevent double escaping.
|
|
154
173
|
const unescapeHtml = text => text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');
|
|
155
174
|
export const getMarkdownTables = text => {
|
|
156
175
|
const tableTokens = [];
|
|
157
|
-
|
|
176
|
+
|
|
177
|
+
// Since walkTokens is not called with async functions and parseInline is not used, the result
|
|
178
|
+
// of parse is synchronous. To match the type, it will be voided here.
|
|
179
|
+
void marked.parse(text, {
|
|
158
180
|
walkTokens: token => {
|
|
159
181
|
if (token.type === 'table') {
|
|
160
182
|
tableTokens.push(token);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatMarkdown.js","names":["marked","stringify","escapeBBCodeSquareBrackets","inlineCodeRule","inlineTextRule","TABLE_ID_PREFIX","tokenizer","codespan","src","cap","exec","text","replace","hasNonSpaceChars","test","hasSpaceCharsOnBothEnds","substring","length","type","raw","undefined","lheading","url","code","inlineText","escape","br","list","renderer","lang","langString","match","checkbox","checked","listitem","item","task","trim","value","slice","itemBody","parser","parse","tokens","loose","postprocess","html","tableIndex","modifiedString","result","use","hooks","parseMarkdown","parseBBCode","walkTokens","token","unescapeHtml","replaceAll","getMarkdownTables","tableTokens","push","tables","forEach","tableToken","index","tableArray","header","rowArray","rows","row","cell","csv","id"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdown.ts"],"sourcesContent":["import { marked, Tokens } from 'marked';\nimport type { TableObject } from '../../../types/format';\n// eslint-disable-next-line import/extensions,import/no-unresolved\nimport { stringify } from 'csv-stringify/browser/esm/sync';\nimport { escapeBBCodeSquareBrackets } from '../bb-code/formatBBCode';\n\nconst inlineCodeRule = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst inlineTextRule = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<![`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n\nconst TABLE_ID_PREFIX = 'formatted-table-';\n\n/*\n The marked Pipeline, including tokenizer, renderer and hooks are explained here:\n https://marked.js.org/using_pro\n*/\n\nconst tokenizer = {\n // Codespan Tokenizer is overwritten to prevent html escaping, since html is already escaped.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L749\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = inlineCodeRule.exec(src);\n if (cap) {\n let text = (cap[2] as string).replace(/\\n/g, ' ');\n const hasNonSpaceChars = /[^ ]/.test(text);\n const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n\n return {\n type: 'codespan',\n raw: cap[0],\n text,\n };\n }\n\n return undefined;\n },\n // Disables Markdown formatting for setext headings.\n lheading(): Tokens.Heading | undefined {\n return undefined;\n },\n // Disables converting urls to hyperlinks.\n url() {\n return undefined;\n },\n // Disables converting text with 4 leading spaces to code block.\n code() {\n return undefined;\n },\n // inlineText is overwritten to prevent html escaping, specifically since quote characters are escaped, which breaks the attributes of bb-code elements.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L854\n inlineText(src: string) {\n const cap = inlineTextRule.exec(src);\n if (cap) {\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n };\n }\n return undefined;\n },\n // Disables escaping of characters via backslash. This is needed for LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.\n // Without this function, the backslashes would be escaped and the LaTeX formula would be broken.\n escape() {\n return undefined;\n },\n // Disables the conversion of backslash at the end of a line to a line break. This is needed for LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.\n // Without this '\\\\' would be converted to '\\<br>' which breaks LaTeX formulas.\n br() {\n return undefined;\n },\n // Only recognizes ordered lists, that start with the number 1.\n // Also recognizes ordered lists, that contain a list item with the number 1, so those lists are\n list(src: string) {\n // The regex is copied from marked.js: https://github.com/markedjs/marked/blob/4fc639e053a605b25abf66dccaa70c1bf6562eb7/src/rules.ts#L115\n if (/^( {0,3}[*+-]|1[.)])/.test(src)) {\n return false;\n }\n\n // Prevents the text from being recognized as a list.\n return undefined;\n },\n};\n\nconst renderer = {\n // Code Renderer is overwritten to prevent html escaping, since html is already escaped.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Renderer.ts#L24\n code(text: string, lang: string): string {\n const langString = (lang || '').match(/^\\S*/)?.[0];\n\n const code = `${text.replace(/\\n$/, '')}`;\n\n if (!langString) {\n return `<pre><code>${code}</code></pre>\\n`;\n }\n\n return `<pre><code class=\"language-${langString}\">${code}</code></pre>\\n`;\n },\n // Replaces the checkbox input elements with markdown checkboxes.\n // This is the easiest way to prevent the formatting of markdown checkboxes in lists.\n // This can modify the input string slightly, since the capitalization of the checkbox can be lost.\n // If a user types '- [X]' it will be replaced with '- [x]' => the capitalization is lost.\n checkbox({ checked }: Tokens.Checkbox) {\n return checked ? '[x]' : '[ ]';\n },\n // Ensures that the numbering of ordered lists is preserved.\n listitem: function (item: Tokens.ListItem) {\n if (item.task) {\n return false;\n }\n\n const match = item.raw.trim().match(/^\\d{1,9}[.)]/);\n // Removes the trailing dot or parenthesis from the match.\n const value = match ? match[0].slice(0, match[0].length - 1) : '';\n if (value) {\n let itemBody = '';\n // @ts-ignore\n itemBody += this.parser.parse(item.tokens, !!item.loose);\n // Sets the value attribute of the list item to the number of the list item.\n return `<li value=\"${value}\">${itemBody}</li>\\n`;\n }\n\n // Ensures that the default listitem renderer from marked js is used.\n return false;\n },\n};\n\nconst postprocess = (html: string): string => {\n let tableIndex = 0;\n // Assigns ids to tables.\n const modifiedString = html.replace(/(<table>)/g, () => {\n const result = `<table id=\"${TABLE_ID_PREFIX}${tableIndex}\">`;\n tableIndex++;\n return result;\n });\n\n return modifiedString;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nmarked.use({ tokenizer, renderer, hooks: { postprocess } });\n\n// Parses markdown following the Github Flavored Markdown specification.\n// The tokenizer and renderer are slightly modified to prevent html escaping in code block and inline code.\nexport const parseMarkdown = (text: string, parseBBCode: boolean) =>\n marked.parse(text, {\n walkTokens: (token) => {\n if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {\n // eslint-disable-next-line no-param-reassign\n (token as Tokens.Codespan).text = escapeBBCodeSquareBrackets(\n (token as Tokens.Codespan).text,\n );\n }\n },\n }) as string;\n\n// It is important that, & is replaced lastly to prevent double escaping.\nconst unescapeHtml = (text: string) =>\n text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');\n\nexport const getMarkdownTables = (text: string): TableObject[] => {\n const tableTokens: Tokens.Table[] = [];\n\n marked.parse(text, {\n walkTokens: (token) => {\n if (token.type === 'table') {\n tableTokens.push(token as Tokens.Table);\n }\n },\n }) as string;\n\n const tables: TableObject[] = [];\n\n tableTokens.forEach((tableToken, index) => {\n const tableArray: string[][] = [];\n\n if (tableToken.header?.length > 0) {\n const rowArray: string[] = [];\n\n tableToken.header.forEach((header) => {\n rowArray.push(unescapeHtml(header.text));\n });\n\n tableArray.push(rowArray);\n }\n if (tableToken.rows?.length > 0) {\n tableToken.rows.forEach((row) => {\n const rowArray: string[] = [];\n\n row.forEach((cell) => {\n rowArray.push(unescapeHtml(cell.text));\n });\n\n tableArray.push(rowArray);\n });\n }\n\n const csv = stringify(tableArray || []);\n\n tables.push({\n raw: unescapeHtml(tableToken.raw),\n csv,\n id: `${TABLE_ID_PREFIX}${index}`,\n });\n });\n\n return tables;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"formatMarkdown.js","names":["stringify","marked","escapeBBCodeSquareBrackets","inlineCodeRule","inlineTextRule","TABLE_ID_PREFIX","tokenizer","codespan","src","cap","exec","text","replace","hasNonSpaceChars","test","hasSpaceCharsOnBothEnds","substring","length","raw","type","undefined","lheading","url","code","inlineText","escape","br","list","renderer","lang","langString","match","checkbox","checked","link","href","title","listitem","item","task","trim","value","slice","itemBody","parser","parse","tokens","postprocess","html","tableIndex","use","hooks","parseMarkdown","parseBBCode","walkTokens","token","unescapeHtml","replaceAll","getMarkdownTables","tableTokens","push","tables","forEach","tableToken","index","tableArray","header","rowArray","rows","row","cell","csv","id"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdown.ts"],"sourcesContent":["// eslint-disable-next-line import/extensions,import/no-unresolved\nimport { stringify } from 'csv-stringify/browser/esm/sync';\nimport { marked, RendererObject, TokenizerObject, Tokens } from 'marked';\nimport type { TableObject } from '../../../types/format';\nimport { escapeBBCodeSquareBrackets } from '../bb-code/formatBBCode';\n\nconst inlineCodeRule = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst inlineTextRule = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<![`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n\nconst TABLE_ID_PREFIX = 'formatted-table-';\n\n/*\n The marked Pipeline, including tokenizer, renderer and hooks, are explained here:\n https://marked.js.org/using_pro\n*/\n\nconst tokenizer: TokenizerObject = {\n // Codespan Tokenizer is overwritten to prevent HTML escaping, since HTML has been already\n // escaped. The function is copied from marked.js and slightly modified:\n // https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L749\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = inlineCodeRule.exec(src);\n\n if (cap) {\n let text = (cap[2] as string).replace(/\\n/g, ' ');\n\n const hasNonSpaceChars = /[^ ]/.test(text);\n const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n\n return { raw: cap[0], text, type: 'codespan' };\n }\n\n return undefined;\n },\n // Disables Markdown formatting for setext headings.\n lheading(): Tokens.Heading | undefined {\n return undefined;\n },\n // Disables converting urls to hyperlinks.\n url() {\n return undefined;\n },\n // Disables converting text with 4 leading spaces to the code block.\n code() {\n return undefined;\n },\n // inlineText is overwritten to prevent HTML escaping, specifically since quote characters are\n // escaped, which breaks the attributes of bb-code elements. The function is copied from\n // marked.js and slightly modified:\n // https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Tokenizer.ts#L854\n inlineText(src: string) {\n const cap = inlineTextRule.exec(src);\n\n if (cap) {\n return { raw: cap[0], text: cap[0], type: 'text' };\n }\n\n return undefined;\n },\n // Disables escaping of characters via backslash. This is needed for LaTeX formulas, since\n // multiline LaTeX formulas have 2 backslashes at the end of their lines. Without this function,\n // the backslashes would be escaped and the LaTeX formula would be broken.\n escape() {\n return undefined;\n },\n // Disables the conversion of backslash at the end of a line to a line break. This is needed for\n // LaTeX formulas, since multiline LaTeX formulas have 2 backslashes at the end of their lines.\n // Without this '\\\\' would be converted to '\\<br>' which breaks LaTeX formulas.\n br() {\n return undefined;\n },\n // Only recognizes ordered lists that start with the number 1. Also recognizes ordered lists\n // that contain a list item with the number 1, so those lists are\n list(src: string) {\n // The regex is copied from marked.js: https://github.com/markedjs/marked/blob/4fc639e053a605b25abf66dccaa70c1bf6562eb7/src/rules.ts#L115\n if (/^( {0,3}[*+-]|1[.)])/.test(src)) {\n return false;\n }\n\n // Prevents the text from being recognized as a list.\n return undefined;\n },\n};\n\nconst renderer: RendererObject = {\n // Code Renderer is overwritten to prevent HTML escaping, since HTML has been already escaped.\n // The function is copied from marked.js and slightly modified: https://github.com/markedjs/marked/blob/42954aaba960b6f815b24ec0d39da464960e4ec9/src/Renderer.ts#L24\n code({ lang, text }: Tokens.Code): string {\n const langString = (lang || '').match(/^\\S*/)?.[0];\n\n const code = `${text.replace(/\\n$/, '')}`;\n\n if (!langString) {\n return `<pre><code>${code}</code></pre>\\n`;\n }\n\n return `<pre><code class=\"language-${langString}\">${code}</code></pre>\\n`;\n },\n // Replaces the checkbox input elements with Markdown checkboxes. This is the easiest way to\n // prevent the formatting of Markdown checkboxes in lists. This can modify the input string\n // slightly, since the capitalization of the checkbox can be lost. If a user types '- [X]', it\n // will be replaced with '- [x]'.\n checkbox({ checked }: Tokens.Checkbox) {\n return checked ? '[x]' : '[ ]';\n },\n // Replaces the link renderer to prevent opening links in the same tab. Therefore, the target\n // attribute is set to \"_blank\".\n link({ href, text, title }: Tokens.Link): string {\n if (title) {\n return `<a href=\"${href}\" rel=\"noopener noreferrer\" target=\"_blank\" title=\"${title}\">${text}</a>`;\n }\n\n return `<a href=\"${href}\" rel=\"noopener noreferrer\" target=\"_blank\">${text}</a>`;\n },\n // Ensures that the numbering of ordered lists is preserved.\n listitem(item: Tokens.ListItem) {\n if (item.task) {\n return false;\n }\n\n const match = item.raw.trim().match(/^\\d{1,9}[.)]/);\n\n // Removes the trailing dot or parenthesis from the match.\n const value = match ? match[0].slice(0, match[0].length - 1) : '';\n\n if (value) {\n let itemBody = '';\n\n itemBody += this.parser.parse(item.tokens);\n\n // Sets the value attribute of the list item to the number of the list item.\n return `<li value=\"${value}\">${itemBody}</li>\\n`;\n }\n\n // Ensures that the default listitem renderer from marked js is used.\n return false;\n },\n};\n\nconst postprocess = (html: string): string => {\n let tableIndex = -1;\n\n // Assigns ids to tables.\n return html.replace(/(<table>)/g, () => {\n tableIndex++;\n\n return `<table id=\"${TABLE_ID_PREFIX}${tableIndex}\">`;\n });\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\nmarked.use({ tokenizer, renderer, hooks: { postprocess } });\n\n// Parses markdown following the GitHub flavored Markdown specification. The tokenizer and renderer\n// are slightly modified to prevent HTML escaping in code block and inline code.\nexport const parseMarkdown = (text: string, parseBBCode: boolean) =>\n marked.parse(text, {\n walkTokens: (token) => {\n if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {\n // eslint-disable-next-line no-param-reassign\n (token as Tokens.Codespan).text = escapeBBCodeSquareBrackets(\n (token as Tokens.Codespan).text,\n );\n }\n },\n }) as string;\n\n// It is important that, & is replaced last to prevent double escaping.\nconst unescapeHtml = (text: string) =>\n text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');\n\nexport const getMarkdownTables = (text: string): TableObject[] => {\n const tableTokens: Tokens.Table[] = [];\n\n // Since walkTokens is not called with async functions and parseInline is not used, the result\n // of parse is synchronous. To match the type, it will be voided here.\n void marked.parse(text, {\n walkTokens: (token) => {\n if (token.type === 'table') {\n tableTokens.push(token as Tokens.Table);\n }\n },\n });\n\n const tables: TableObject[] = [];\n\n tableTokens.forEach((tableToken, index) => {\n const tableArray: string[][] = [];\n\n if (tableToken.header?.length > 0) {\n const rowArray: string[] = [];\n\n tableToken.header.forEach((header) => {\n rowArray.push(unescapeHtml(header.text));\n });\n\n tableArray.push(rowArray);\n }\n\n if (tableToken.rows?.length > 0) {\n tableToken.rows.forEach((row) => {\n const rowArray: string[] = [];\n\n row.forEach((cell) => {\n rowArray.push(unescapeHtml(cell.text));\n });\n\n tableArray.push(rowArray);\n });\n }\n\n const csv = stringify(tableArray || []);\n\n tables.push({\n raw: unescapeHtml(tableToken.raw),\n csv,\n id: `${TABLE_ID_PREFIX}${index}`,\n });\n });\n\n return tables;\n};\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chayns-components/format",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.1351",
|
|
4
4
|
"description": "A set of beautiful React components for developing your own applications with chayns.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"browserslist": [
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@babel/cli": "^7.28.3",
|
|
57
|
-
"@babel/core": "^7.28.
|
|
58
|
-
"@babel/preset-env": "^7.28.
|
|
59
|
-
"@babel/preset-react": "^7.
|
|
60
|
-
"@babel/preset-typescript": "^7.
|
|
57
|
+
"@babel/core": "^7.28.5",
|
|
58
|
+
"@babel/preset-env": "^7.28.5",
|
|
59
|
+
"@babel/preset-react": "^7.28.5",
|
|
60
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
61
61
|
"@types/commonmark": "^0.27.10",
|
|
62
62
|
"@types/csv-stringify": "^3.1.3",
|
|
63
63
|
"babel-loader": "^9.2.1",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"commonmark": "^0.31.2",
|
|
71
71
|
"csv-stringify": "^6.6.0",
|
|
72
|
-
"marked": "^
|
|
72
|
+
"marked": "^17.0.1"
|
|
73
73
|
},
|
|
74
74
|
"publishConfig": {
|
|
75
75
|
"access": "public"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "85e957e375f78f7830cc1c0c41fda7bc0428b3c6"
|
|
78
78
|
}
|