@chayns-components/format 5.0.0-beta.1317 → 5.0.0-beta.1352
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 +60 -48
- 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 +60 -48
- package/lib/esm/utils/formatString/markdown/formatMarkdown.js.map +1 -1
- package/package.json +3 -3
|
@@ -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,48 +105,49 @@ 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
|
},
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
// Replaces the link renderer to prevent opening links in the same tab. Therefore, the target
|
|
118
|
+
// attribute is set to "_blank". The function is copied from marked.js and slightly modified:
|
|
119
|
+
// https://github.com/markedjs/marked/blob/15c77deb9e099041d5e70e3b7b17e50ddc35ec2a/src/Renderer.ts#L160
|
|
120
|
+
link({
|
|
121
|
+
href,
|
|
122
|
+
title,
|
|
123
|
+
tokens
|
|
124
|
+
}) {
|
|
125
|
+
const text = this.parser.parseInline(tokens);
|
|
126
|
+
let cleanHref;
|
|
127
|
+
try {
|
|
128
|
+
cleanHref = encodeURI(href).replace(/%25/g, '%');
|
|
129
|
+
} catch {
|
|
130
|
+
return text;
|
|
113
131
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (value) {
|
|
118
|
-
let itemBody = '';
|
|
119
|
-
// @ts-ignore
|
|
120
|
-
itemBody += this.parser.parse(item.tokens, !!item.loose);
|
|
121
|
-
// Sets the value attribute of the list item to the number of the list item.
|
|
122
|
-
return `<li value="${value}">${itemBody}</li>\n`;
|
|
132
|
+
let result = `<a href="${cleanHref}" rel="noopener noreferrer" target="_blank"`;
|
|
133
|
+
if (title) {
|
|
134
|
+
result += ` title="${title}"`;
|
|
123
135
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return false;
|
|
136
|
+
result += `>${text}</a>`;
|
|
137
|
+
return result;
|
|
127
138
|
}
|
|
128
139
|
};
|
|
129
140
|
const postprocess = html => {
|
|
130
|
-
let tableIndex =
|
|
141
|
+
let tableIndex = -1;
|
|
142
|
+
|
|
131
143
|
// Assigns ids to tables.
|
|
132
|
-
|
|
133
|
-
const result = `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
144
|
+
return html.replace(/(<table>)/g, () => {
|
|
134
145
|
tableIndex++;
|
|
135
|
-
return
|
|
146
|
+
return `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
136
147
|
});
|
|
137
|
-
return modifiedString;
|
|
138
148
|
};
|
|
139
149
|
|
|
140
150
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
141
|
-
// @ts-ignore
|
|
142
151
|
_marked.marked.use({
|
|
143
152
|
tokenizer,
|
|
144
153
|
renderer,
|
|
@@ -147,8 +156,8 @@ _marked.marked.use({
|
|
|
147
156
|
}
|
|
148
157
|
});
|
|
149
158
|
|
|
150
|
-
// Parses
|
|
151
|
-
//
|
|
159
|
+
// Parses Markdown following the GitHub flavored Markdown specification. The tokenizer and renderer
|
|
160
|
+
// are slightly modified to prevent HTML escaping in code block and inline code.
|
|
152
161
|
const parseMarkdown = (text, parseBBCode) => _marked.marked.parse(text, {
|
|
153
162
|
walkTokens: token => {
|
|
154
163
|
if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {
|
|
@@ -158,12 +167,15 @@ const parseMarkdown = (text, parseBBCode) => _marked.marked.parse(text, {
|
|
|
158
167
|
}
|
|
159
168
|
});
|
|
160
169
|
|
|
161
|
-
// It is important that, & is replaced
|
|
170
|
+
// It is important that, & is replaced last to prevent double escaping.
|
|
162
171
|
exports.parseMarkdown = parseMarkdown;
|
|
163
172
|
const unescapeHtml = text => text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');
|
|
164
173
|
const getMarkdownTables = text => {
|
|
165
174
|
const tableTokens = [];
|
|
166
|
-
|
|
175
|
+
|
|
176
|
+
// Since walkTokens is not called with async functions and parseInline is not used, the result
|
|
177
|
+
// of parse is synchronous. To match the type, it will be voided here.
|
|
178
|
+
void _marked.marked.parse(text, {
|
|
167
179
|
walkTokens: token => {
|
|
168
180
|
if (token.type === 'table') {
|
|
169
181
|
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","tokens","parser","parseInline","cleanHref","encodeURI","result","postprocess","html","tableIndex","marked","use","hooks","parseMarkdown","parseBBCode","parse","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\". The function is copied from marked.js and slightly modified:\n // https://github.com/markedjs/marked/blob/15c77deb9e099041d5e70e3b7b17e50ddc35ec2a/src/Renderer.ts#L160\n link({ href, title, tokens }: Tokens.Link): string {\n const text = this.parser.parseInline(tokens);\n\n let cleanHref;\n\n try {\n cleanHref = encodeURI(href).replace(/%25/g, '%');\n } catch {\n return text;\n }\n\n let result = `<a href=\"${cleanHref}\" rel=\"noopener noreferrer\" target=\"_blank\"`;\n\n if (title) {\n result += ` title=\"${title}\"`;\n }\n\n result += `>${text}</a>`;\n\n return result;\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,48 +97,49 @@ 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
|
},
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
// Replaces the link renderer to prevent opening links in the same tab. Therefore, the target
|
|
110
|
+
// attribute is set to "_blank". The function is copied from marked.js and slightly modified:
|
|
111
|
+
// https://github.com/markedjs/marked/blob/15c77deb9e099041d5e70e3b7b17e50ddc35ec2a/src/Renderer.ts#L160
|
|
112
|
+
link({
|
|
113
|
+
href,
|
|
114
|
+
title,
|
|
115
|
+
tokens
|
|
116
|
+
}) {
|
|
117
|
+
const text = this.parser.parseInline(tokens);
|
|
118
|
+
let cleanHref;
|
|
119
|
+
try {
|
|
120
|
+
cleanHref = encodeURI(href).replace(/%25/g, '%');
|
|
121
|
+
} catch {
|
|
122
|
+
return text;
|
|
105
123
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (value) {
|
|
110
|
-
let itemBody = '';
|
|
111
|
-
// @ts-ignore
|
|
112
|
-
itemBody += this.parser.parse(item.tokens, !!item.loose);
|
|
113
|
-
// Sets the value attribute of the list item to the number of the list item.
|
|
114
|
-
return `<li value="${value}">${itemBody}</li>\n`;
|
|
124
|
+
let result = `<a href="${cleanHref}" rel="noopener noreferrer" target="_blank"`;
|
|
125
|
+
if (title) {
|
|
126
|
+
result += ` title="${title}"`;
|
|
115
127
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return false;
|
|
128
|
+
result += `>${text}</a>`;
|
|
129
|
+
return result;
|
|
119
130
|
}
|
|
120
131
|
};
|
|
121
132
|
const postprocess = html => {
|
|
122
|
-
let tableIndex =
|
|
133
|
+
let tableIndex = -1;
|
|
134
|
+
|
|
123
135
|
// Assigns ids to tables.
|
|
124
|
-
|
|
125
|
-
const result = `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
136
|
+
return html.replace(/(<table>)/g, () => {
|
|
126
137
|
tableIndex++;
|
|
127
|
-
return
|
|
138
|
+
return `<table id="${TABLE_ID_PREFIX}${tableIndex}">`;
|
|
128
139
|
});
|
|
129
|
-
return modifiedString;
|
|
130
140
|
};
|
|
131
141
|
|
|
132
142
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
133
|
-
// @ts-ignore
|
|
134
143
|
marked.use({
|
|
135
144
|
tokenizer,
|
|
136
145
|
renderer,
|
|
@@ -139,8 +148,8 @@ marked.use({
|
|
|
139
148
|
}
|
|
140
149
|
});
|
|
141
150
|
|
|
142
|
-
// Parses
|
|
143
|
-
//
|
|
151
|
+
// Parses Markdown following the GitHub flavored Markdown specification. The tokenizer and renderer
|
|
152
|
+
// are slightly modified to prevent HTML escaping in code block and inline code.
|
|
144
153
|
export const parseMarkdown = (text, parseBBCode) => marked.parse(text, {
|
|
145
154
|
walkTokens: token => {
|
|
146
155
|
if (parseBBCode && (token.type === 'codespan' || token.type === 'code')) {
|
|
@@ -150,11 +159,14 @@ export const parseMarkdown = (text, parseBBCode) => marked.parse(text, {
|
|
|
150
159
|
}
|
|
151
160
|
});
|
|
152
161
|
|
|
153
|
-
// It is important that, & is replaced
|
|
162
|
+
// It is important that, & is replaced last to prevent double escaping.
|
|
154
163
|
const unescapeHtml = text => text.replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');
|
|
155
164
|
export const getMarkdownTables = text => {
|
|
156
165
|
const tableTokens = [];
|
|
157
|
-
|
|
166
|
+
|
|
167
|
+
// Since walkTokens is not called with async functions and parseInline is not used, the result
|
|
168
|
+
// of parse is synchronous. To match the type, it will be voided here.
|
|
169
|
+
void marked.parse(text, {
|
|
158
170
|
walkTokens: token => {
|
|
159
171
|
if (token.type === 'table') {
|
|
160
172
|
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":"AAAA,SAASA,MAAM,QAAgB,QAAQ;AAEvC;AACA,SAASC,SAAS,QAAQ,gCAAgC;AAC1D,SAASC,0BAA0B,QAAQ,yBAAyB;AAEpE,MAAMC,cAAc,GAAG,qCAAqC;AAC5D,MAAMC,cAAc,GAAG,4EAA4E;AAEnG,MAAMC,eAAe,GAAG,kBAAkB;;AAE1C;AACA;AACA;AACA;;AAEA,MAAMC,SAAS,GAAG;EACd;EACA;EACAC,QAAQA,CAACC,GAAW,EAA+B;IAC/C,MAAMC,GAAG,GAAGN,cAAc,CAACO,IAAI,CAACF,GAAG,CAAC;IACpC,IAAIC,GAAG,EAAE;MACL,IAAIE,IAAI,GAAIF,GAAG,CAAC,CAAC,CAAC,CAAYG,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;MACjD,MAAMC,gBAAgB,GAAG,MAAM,CAACC,IAAI,CAACH,IAAI,CAAC;MAC1C,MAAMI,uBAAuB,GAAG,IAAI,CAACD,IAAI,CAACH,IAAI,CAAC,IAAI,IAAI,CAACG,IAAI,CAACH,IAAI,CAAC;MAClE,IAAIE,gBAAgB,IAAIE,uBAAuB,EAAE;QAC7CJ,IAAI,GAAGA,IAAI,CAACK,SAAS,CAAC,CAAC,EAAEL,IAAI,CAACM,MAAM,GAAG,CAAC,CAAC;MAC7C;MAEA,OAAO;QACHC,IAAI,EAAE,UAAU;QAChBC,GAAG,EAAEV,GAAG,CAAC,CAAC,CAAC;QACXE;MACJ,CAAC;IACL;IAEA,OAAOS,SAAS;EACpB,CAAC;EACD;EACAC,QAAQA,CAAA,EAA+B;IACnC,OAAOD,SAAS;EACpB,CAAC;EACD;EACAE,GAAGA,CAAA,EAAG;IACF,OAAOF,SAAS;EACpB,CAAC;EACD;EACAG,IAAIA,CAAA,EAAG;IACH,OAAOH,SAAS;EACpB,CAAC;EACD;EACA;EACAI,UAAUA,CAAChB,GAAW,EAAE;IACpB,MAAMC,GAAG,GAAGL,cAAc,CAACM,IAAI,CAACF,GAAG,CAAC;IACpC,IAAIC,GAAG,EAAE;MACL,OAAO;QACHS,IAAI,EAAE,MAAM;QACZC,GAAG,EAAEV,GAAG,CAAC,CAAC,CAAC;QACXE,IAAI,EAAEF,GAAG,CAAC,CAAC;MACf,CAAC;IACL;IACA,OAAOW,SAAS;EACpB,CAAC;EACD;EACA;EACAK,MAAMA,CAAA,EAAG;IACL,OAAOL,SAAS;EACpB,CAAC;EACD;EACA;EACAM,EAAEA,CAAA,EAAG;IACD,OAAON,SAAS;EACpB,CAAC;EACD;EACA;EACAO,IAAIA,CAACnB,GAAW,EAAE;IACd;IACA,IAAI,sBAAsB,CAACM,IAAI,CAACN,GAAG,CAAC,EAAE;MAClC,OAAO,KAAK;IAChB;;IAEA;IACA,OAAOY,SAAS;EACpB;AACJ,CAAC;AAED,MAAMQ,QAAQ,GAAG;EACb;EACA;EACAL,IAAIA,CAACZ,IAAY,EAAEkB,IAAY,EAAU;IACrC,MAAMC,UAAU,GAAG,CAACD,IAAI,IAAI,EAAE,EAAEE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAElD,MAAMR,IAAI,GAAG,GAAGZ,IAAI,CAACC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE;IAEzC,IAAI,CAACkB,UAAU,EAAE;MACb,OAAO,cAAcP,IAAI,iBAAiB;IAC9C;IAEA,OAAO,8BAA8BO,UAAU,KAAKP,IAAI,iBAAiB;EAC7E,CAAC;EACD;EACA;EACA;EACA;EACAS,QAAQA,CAAC;IAAEC;EAAyB,CAAC,EAAE;IACnC,OAAOA,OAAO,GAAG,KAAK,GAAG,KAAK;EAClC,CAAC;EACD;EACAC,QAAQ,EAAE,SAAAA,CAAUC,IAAqB,EAAE;IACvC,IAAIA,IAAI,CAACC,IAAI,EAAE;MACX,OAAO,KAAK;IAChB;IAEA,MAAML,KAAK,GAAGI,IAAI,CAAChB,GAAG,CAACkB,IAAI,CAAC,CAAC,CAACN,KAAK,CAAC,cAAc,CAAC;IACnD;IACA,MAAMO,KAAK,GAAGP,KAAK,GAAGA,KAAK,CAAC,CAAC,CAAC,CAACQ,KAAK,CAAC,CAAC,EAAER,KAAK,CAAC,CAAC,CAAC,CAACd,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE;IACjE,IAAIqB,KAAK,EAAE;MACP,IAAIE,QAAQ,GAAG,EAAE;MACjB;MACAA,QAAQ,IAAI,IAAI,CAACC,MAAM,CAACC,KAAK,CAACP,IAAI,CAACQ,MAAM,EAAE,CAAC,CAACR,IAAI,CAACS,KAAK,CAAC;MACxD;MACA,OAAO,cAAcN,KAAK,KAAKE,QAAQ,SAAS;IACpD;;IAEA;IACA,OAAO,KAAK;EAChB;AACJ,CAAC;AAED,MAAMK,WAAW,GAAIC,IAAY,IAAa;EAC1C,IAAIC,UAAU,GAAG,CAAC;EAClB;EACA,MAAMC,cAAc,GAAGF,IAAI,CAAClC,OAAO,CAAC,YAAY,EAAE,MAAM;IACpD,MAAMqC,MAAM,GAAG,cAAc5C,eAAe,GAAG0C,UAAU,IAAI;IAC7DA,UAAU,EAAE;IACZ,OAAOE,MAAM;EACjB,CAAC,CAAC;EAEF,OAAOD,cAAc;AACzB,CAAC;;AAED;AACA;AACAhD,MAAM,CAACkD,GAAG,CAAC;EAAE5C,SAAS;EAAEsB,QAAQ;EAAEuB,KAAK,EAAE;IAAEN;EAAY;AAAE,CAAC,CAAC;;AAE3D;AACA;AACA,OAAO,MAAMO,aAAa,GAAGA,CAACzC,IAAY,EAAE0C,WAAoB,KAC5DrD,MAAM,CAAC0C,KAAK,CAAC/B,IAAI,EAAE;EACf2C,UAAU,EAAGC,KAAK,IAAK;IACnB,IAAIF,WAAW,KAAKE,KAAK,CAACrC,IAAI,KAAK,UAAU,IAAIqC,KAAK,CAACrC,IAAI,KAAK,MAAM,CAAC,EAAE;MACrE;MACCqC,KAAK,CAAqB5C,IAAI,GAAGT,0BAA0B,CACvDqD,KAAK,CAAqB5C,IAC/B,CAAC;IACL;EACJ;AACJ,CAAC,CAAW;;AAEhB;AACA,MAAM6C,YAAY,GAAI7C,IAAY,IAC9BA,IAAI,CAAC8C,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAACA,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAACA,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;AAEjF,OAAO,MAAMC,iBAAiB,GAAI/C,IAAY,IAAoB;EAC9D,MAAMgD,WAA2B,GAAG,EAAE;EAEtC3D,MAAM,CAAC0C,KAAK,CAAC/B,IAAI,EAAE;IACf2C,UAAU,EAAGC,KAAK,IAAK;MACnB,IAAIA,KAAK,CAACrC,IAAI,KAAK,OAAO,EAAE;QACxByC,WAAW,CAACC,IAAI,CAACL,KAAqB,CAAC;MAC3C;IACJ;EACJ,CAAC,CAAC;EAEF,MAAMM,MAAqB,GAAG,EAAE;EAEhCF,WAAW,CAACG,OAAO,CAAC,CAACC,UAAU,EAAEC,KAAK,KAAK;IACvC,MAAMC,UAAsB,GAAG,EAAE;IAEjC,IAAIF,UAAU,CAACG,MAAM,EAAEjD,MAAM,GAAG,CAAC,EAAE;MAC/B,MAAMkD,QAAkB,GAAG,EAAE;MAE7BJ,UAAU,CAACG,MAAM,CAACJ,OAAO,CAAEI,MAAM,IAAK;QAClCC,QAAQ,CAACP,IAAI,CAACJ,YAAY,CAACU,MAAM,CAACvD,IAAI,CAAC,CAAC;MAC5C,CAAC,CAAC;MAEFsD,UAAU,CAACL,IAAI,CAACO,QAAQ,CAAC;IAC7B;IACA,IAAIJ,UAAU,CAACK,IAAI,EAAEnD,MAAM,GAAG,CAAC,EAAE;MAC7B8C,UAAU,CAACK,IAAI,CAACN,OAAO,CAAEO,GAAG,IAAK;QAC7B,MAAMF,QAAkB,GAAG,EAAE;QAE7BE,GAAG,CAACP,OAAO,CAAEQ,IAAI,IAAK;UAClBH,QAAQ,CAACP,IAAI,CAACJ,YAAY,CAACc,IAAI,CAAC3D,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC;QAEFsD,UAAU,CAACL,IAAI,CAACO,QAAQ,CAAC;MAC7B,CAAC,CAAC;IACN;IAEA,MAAMI,GAAG,GAAGtE,SAAS,CAACgE,UAAU,IAAI,EAAE,CAAC;IAEvCJ,MAAM,CAACD,IAAI,CAAC;MACRzC,GAAG,EAAEqC,YAAY,CAACO,UAAU,CAAC5C,GAAG,CAAC;MACjCoD,GAAG;MACHC,EAAE,EAAE,GAAGnE,eAAe,GAAG2D,KAAK;IAClC,CAAC,CAAC;EACN,CAAC,CAAC;EAEF,OAAOH,MAAM;AACjB,CAAC","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","tokens","parser","parseInline","cleanHref","encodeURI","result","postprocess","html","tableIndex","use","hooks","parseMarkdown","parseBBCode","parse","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\". The function is copied from marked.js and slightly modified:\n // https://github.com/markedjs/marked/blob/15c77deb9e099041d5e70e3b7b17e50ddc35ec2a/src/Renderer.ts#L160\n link({ href, title, tokens }: Tokens.Link): string {\n const text = this.parser.parseInline(tokens);\n\n let cleanHref;\n\n try {\n cleanHref = encodeURI(href).replace(/%25/g, '%');\n } catch {\n return text;\n }\n\n let result = `<a href=\"${cleanHref}\" rel=\"noopener noreferrer\" target=\"_blank\"`;\n\n if (title) {\n result += ` title=\"${title}\"`;\n }\n\n result += `>${text}</a>`;\n\n return result;\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.1352",
|
|
4
4
|
"description": "A set of beautiful React components for developing your own applications with chayns.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"browserslist": [
|
|
@@ -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": "d6b366ed6224381b9a2db83fade6b703ad7fdd56"
|
|
78
78
|
}
|