@chayns-components/format 5.0.0-beta.650

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/lib/cjs/index.js +13 -0
  4. package/lib/cjs/index.js.map +1 -0
  5. package/lib/cjs/utils/escape.js +13 -0
  6. package/lib/cjs/utils/escape.js.map +1 -0
  7. package/lib/cjs/utils/formatString/bb-code/findBBCode.js +41 -0
  8. package/lib/cjs/utils/formatString/bb-code/findBBCode.js.map +1 -0
  9. package/lib/cjs/utils/formatString/bb-code/formatBBCode.js +94 -0
  10. package/lib/cjs/utils/formatString/bb-code/formatBBCode.js.map +1 -0
  11. package/lib/cjs/utils/formatString/formatString.js +95 -0
  12. package/lib/cjs/utils/formatString/formatString.js.map +1 -0
  13. package/lib/cjs/utils/formatString/markdown/formatMarkdown.js +41 -0
  14. package/lib/cjs/utils/formatString/markdown/formatMarkdown.js.map +1 -0
  15. package/lib/cjs/utils/formatString/markdown/formatMarkdownTable.js +86 -0
  16. package/lib/cjs/utils/formatString/markdown/formatMarkdownTable.js.map +1 -0
  17. package/lib/esm/index.js +2 -0
  18. package/lib/esm/index.js.map +1 -0
  19. package/lib/esm/utils/escape.js +5 -0
  20. package/lib/esm/utils/escape.js.map +1 -0
  21. package/lib/esm/utils/formatString/bb-code/findBBCode.js +35 -0
  22. package/lib/esm/utils/formatString/bb-code/findBBCode.js.map +1 -0
  23. package/lib/esm/utils/formatString/bb-code/formatBBCode.js +90 -0
  24. package/lib/esm/utils/formatString/bb-code/formatBBCode.js.map +1 -0
  25. package/lib/esm/utils/formatString/formatString.js +88 -0
  26. package/lib/esm/utils/formatString/formatString.js.map +1 -0
  27. package/lib/esm/utils/formatString/markdown/formatMarkdown.js +32 -0
  28. package/lib/esm/utils/formatString/markdown/formatMarkdown.js.map +1 -0
  29. package/lib/esm/utils/formatString/markdown/formatMarkdownTable.js +78 -0
  30. package/lib/esm/utils/formatString/markdown/formatMarkdownTable.js.map +1 -0
  31. package/lib/types/index.d.ts +1 -0
  32. package/lib/types/utils/escape.d.ts +4 -0
  33. package/lib/types/utils/formatString/bb-code/findBBCode.d.ts +8 -0
  34. package/lib/types/utils/formatString/bb-code/formatBBCode.d.ts +9 -0
  35. package/lib/types/utils/formatString/formatString.d.ts +14 -0
  36. package/lib/types/utils/formatString/markdown/formatMarkdown.d.ts +1 -0
  37. package/lib/types/utils/formatString/markdown/formatMarkdownTable.d.ts +9 -0
  38. package/package.json +73 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Tobit Laboratories AG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # `format`
2
+
3
+ > TODO: description
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ const format = require('format');
9
+
10
+ // TODO: DEMONSTRATE API
11
+ ```
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "formatStringToHtml", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _formatString.formatStringToHtml;
10
+ }
11
+ });
12
+ var _formatString = require("./utils/formatString/formatString");
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_formatString","require"],"sources":["../../src/index.ts"],"sourcesContent":["export { formatStringToHtml } from './utils/formatString/formatString';\n"],"mappings":";;;;;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.unescapeSquareBrackets = exports.escapeHtmlInText = exports.MESSAGE_CONVERSION_LINE_BREAK_ESCAPED = exports.MESSAGE_CONVERSION_LINE_BREAK = void 0;
7
+ const escapeHtmlInText = text => text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
8
+ exports.escapeHtmlInText = escapeHtmlInText;
9
+ const unescapeSquareBrackets = text => text.replaceAll('&#91;', '[').replaceAll('&#93;', ']');
10
+ exports.unescapeSquareBrackets = unescapeSquareBrackets;
11
+ const MESSAGE_CONVERSION_LINE_BREAK = exports.MESSAGE_CONVERSION_LINE_BREAK = '<br is-replaced-linebreak>';
12
+ const MESSAGE_CONVERSION_LINE_BREAK_ESCAPED = exports.MESSAGE_CONVERSION_LINE_BREAK_ESCAPED = escapeHtmlInText(MESSAGE_CONVERSION_LINE_BREAK);
13
+ //# sourceMappingURL=escape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.js","names":["escapeHtmlInText","text","replace","exports","unescapeSquareBrackets","replaceAll","MESSAGE_CONVERSION_LINE_BREAK","MESSAGE_CONVERSION_LINE_BREAK_ESCAPED"],"sources":["../../../src/utils/escape.ts"],"sourcesContent":["export const escapeHtmlInText = (text: string): string =>\n text.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\nexport const unescapeSquareBrackets = (text: string): string =>\n text.replaceAll('&#91;', '[').replaceAll('&#93;', ']');\n\nexport const MESSAGE_CONVERSION_LINE_BREAK = '<br is-replaced-linebreak>';\nexport const MESSAGE_CONVERSION_LINE_BREAK_ESCAPED = escapeHtmlInText(\n MESSAGE_CONVERSION_LINE_BREAK,\n);\n"],"mappings":";;;;;;AAAO,MAAMA,gBAAgB,GAAIC,IAAY,IACzCA,IAAI,CAACC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;AAACC,OAAA,CAAAH,gBAAA,GAAAA,gBAAA;AAE9C,MAAMI,sBAAsB,GAAIH,IAAY,IAC/CA,IAAI,CAACI,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAACA,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;AAACF,OAAA,CAAAC,sBAAA,GAAAA,sBAAA;AAEpD,MAAME,6BAA6B,GAAAH,OAAA,CAAAG,6BAAA,GAAG,4BAA4B;AAClE,MAAMC,qCAAqC,GAAAJ,OAAA,CAAAI,qCAAA,GAAGP,gBAAgB,CACjEM,6BACJ,CAAC","ignoreList":[]}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.findFirstBBCode = findFirstBBCode;
7
+ const BB_REGEX = /\[([a-zA-Z0-9_]*)(.*?)\](.*?)\[\/\1\]/s;
8
+ // Also matches "\" before quote to fix button for voucher messages
9
+ const PARAMETER_REGEX = /([\w]*?)=\\?["„](.*?)["“]/g;
10
+ // TODO Use external package instead of RegExp to parse BBCode.
11
+ // It is not recommended to use RegExp to parse markup languages like BBCode, because it is not possible to parse nested tags with it.
12
+
13
+ // Finds and returns the first BBCode tag in the input string.
14
+ function findFirstBBCode(inputString) {
15
+ const matches = BB_REGEX.exec(inputString);
16
+ if (matches !== null) {
17
+ const [fullMatch, tag, params, content] = matches;
18
+ const {
19
+ index
20
+ } = matches;
21
+ if (fullMatch === undefined || tag === undefined || params === undefined || content === undefined) return null;
22
+ const parameters = {};
23
+ let match = null;
24
+ // eslint-disable-next-line no-cond-assign
25
+ while (match = PARAMETER_REGEX.exec(params)) {
26
+ const [, key, value] = match;
27
+ if (value) {
28
+ parameters[key || 'url'] = value;
29
+ }
30
+ }
31
+ return {
32
+ fullMatch,
33
+ tag,
34
+ parameters,
35
+ content,
36
+ index
37
+ };
38
+ }
39
+ return null;
40
+ }
41
+ //# sourceMappingURL=findBBCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findBBCode.js","names":["BB_REGEX","PARAMETER_REGEX","findFirstBBCode","inputString","matches","exec","fullMatch","tag","params","content","index","undefined","parameters","match","key","value"],"sources":["../../../../../src/utils/formatString/bb-code/findBBCode.ts"],"sourcesContent":["const BB_REGEX = /\\[([a-zA-Z0-9_]*)(.*?)\\](.*?)\\[\\/\\1\\]/s;\n// Also matches \"\\\" before quote to fix button for voucher messages\nconst PARAMETER_REGEX = /([\\w]*?)=\\\\?[\"„](.*?)[\"“]/g;\n\nexport interface BBCodeMatch {\n fullMatch: string;\n tag: string;\n parameters: Record<string, string>;\n content: string;\n index: number;\n}\n\n// TODO Use external package instead of RegExp to parse BBCode.\n// It is not recommended to use RegExp to parse markup languages like BBCode, because it is not possible to parse nested tags with it.\n\n// Finds and returns the first BBCode tag in the input string.\nexport function findFirstBBCode(inputString: string): BBCodeMatch | null {\n const matches = BB_REGEX.exec(inputString);\n\n if (matches !== null) {\n const [fullMatch, tag, params, content] = matches;\n const { index } = matches;\n\n if (\n fullMatch === undefined ||\n tag === undefined ||\n params === undefined ||\n content === undefined\n )\n return null;\n\n const parameters: Record<string, string> = {};\n\n let match: RegExpExecArray | null = null;\n // eslint-disable-next-line no-cond-assign\n while ((match = PARAMETER_REGEX.exec(params))) {\n const [, key, value] = match;\n\n if (value) {\n parameters[key || 'url'] = value;\n }\n }\n\n return {\n fullMatch,\n tag,\n parameters,\n content,\n index,\n };\n }\n\n return null;\n}\n"],"mappings":";;;;;;AAAA,MAAMA,QAAQ,GAAG,wCAAwC;AACzD;AACA,MAAMC,eAAe,GAAG,4BAA4B;AAUpD;AACA;;AAEA;AACO,SAASC,eAAeA,CAACC,WAAmB,EAAsB;EACrE,MAAMC,OAAO,GAAGJ,QAAQ,CAACK,IAAI,CAACF,WAAW,CAAC;EAE1C,IAAIC,OAAO,KAAK,IAAI,EAAE;IAClB,MAAM,CAACE,SAAS,EAAEC,GAAG,EAAEC,MAAM,EAAEC,OAAO,CAAC,GAAGL,OAAO;IACjD,MAAM;MAAEM;IAAM,CAAC,GAAGN,OAAO;IAEzB,IACIE,SAAS,KAAKK,SAAS,IACvBJ,GAAG,KAAKI,SAAS,IACjBH,MAAM,KAAKG,SAAS,IACpBF,OAAO,KAAKE,SAAS,EAErB,OAAO,IAAI;IAEf,MAAMC,UAAkC,GAAG,CAAC,CAAC;IAE7C,IAAIC,KAA6B,GAAG,IAAI;IACxC;IACA,OAAQA,KAAK,GAAGZ,eAAe,CAACI,IAAI,CAACG,MAAM,CAAC,EAAG;MAC3C,MAAM,GAAGM,GAAG,EAAEC,KAAK,CAAC,GAAGF,KAAK;MAE5B,IAAIE,KAAK,EAAE;QACPH,UAAU,CAACE,GAAG,IAAI,KAAK,CAAC,GAAGC,KAAK;MACpC;IACJ;IAEA,OAAO;MACHT,SAAS;MACTC,GAAG;MACHK,UAAU;MACVH,OAAO;MACPC;IACJ,CAAC;EACL;EAEA,OAAO,IAAI;AACf","ignoreList":[]}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseBBCode = void 0;
7
+ var _findBBCode = require("./findBBCode");
8
+ const BB_CODE_HTML_TAG_PREFIX = 'bb-code-';
9
+ const BLOCK_LEVEL_TAGS = ['center', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'];
10
+ const INLINE_LEVEL_TAGS = ['b', 'strong', 'i', 'em', 'u', 's', 'span', 'img'];
11
+ const HTML_CODE_PATTERN = /(?:<code>|<code class="inline-code">)[\s\S]*?<\/code>/;
12
+ // Parses BB-Code to HTML recursively.
13
+ // When justEscapeSquareBrackets is true, square brackets are escaped to prevent conflicts between markdown and BB Code.
14
+ // In that case the function only escapes square brackets and doesn't remove line breaks.
15
+ const parseBBCode = (text, options) => {
16
+ const {
17
+ justEscapeSquareBrackets = false,
18
+ customBlockLevelBBCodeTags: customBlockLevelTags = [],
19
+ customInlineLevelBBCodeTags: customInlineLevelTags = []
20
+ } = options || {};
21
+ let html = text;
22
+
23
+ // This index is used to keep track of the position in the html string that is being parsed.
24
+ let parseBehindIndex = 0;
25
+ while (parseBehindIndex < html.length) {
26
+ const htmlToParse = html.slice(parseBehindIndex);
27
+ const firstCodeElementMatch = HTML_CODE_PATTERN.exec(htmlToParse);
28
+ const firstBBCodeMatch = (0, _findBBCode.findFirstBBCode)(htmlToParse);
29
+
30
+ // Stops parsing if no BB-Code is found.
31
+ if (!firstBBCodeMatch) {
32
+ return html;
33
+ }
34
+
35
+ // Prevents bb-code parsing within code block.
36
+ if (firstCodeElementMatch && firstBBCodeMatch && firstCodeElementMatch.index < firstBBCodeMatch.index) {
37
+ // If a code block is found before a BB-Code tag, BB-Code parsing continues behind the code block.
38
+ parseBehindIndex += firstCodeElementMatch.index + firstCodeElementMatch[0].length;
39
+ // eslint-disable-next-line no-continue
40
+ continue;
41
+ }
42
+ const {
43
+ content,
44
+ fullMatch,
45
+ parameters,
46
+ index
47
+ } = firstBBCodeMatch;
48
+ const Tag = firstBBCodeMatch.tag.toLowerCase();
49
+ const isValidTag = [...BLOCK_LEVEL_TAGS, ...customBlockLevelTags, ...INLINE_LEVEL_TAGS, ...customInlineLevelTags].includes(Tag);
50
+ const isBlockLevelTag = [...BLOCK_LEVEL_TAGS, ...customBlockLevelTags].includes(Tag);
51
+
52
+ // Ignores tags that are not supported.
53
+ if (!isValidTag) {
54
+ // The parsing continues behind the first square bracket of the BB-Code tag.
55
+ parseBehindIndex += index + 1;
56
+ // eslint-disable-next-line no-continue
57
+ continue;
58
+ }
59
+
60
+ // Converts BB-Code tag's content before converting itself, because it may contain other BB-Codes.
61
+ let parsedContent = parseBBCode(content);
62
+
63
+ // Removes leading and trailing line-breaks from within bb code elements, to prevent unwanted spacing.
64
+ if (!justEscapeSquareBrackets) {
65
+ parsedContent = parsedContent.replace(/^\n+|\n+$/g, '');
66
+ }
67
+ const indexOfFullMatch = html.indexOf(fullMatch);
68
+ let htmlAfterTag = html.slice(indexOfFullMatch + fullMatch.length);
69
+
70
+ // Removes leading line-break (ONE, NOT ALL) after block level elements, to prevent unwanted spacing.
71
+ if (!justEscapeSquareBrackets && isBlockLevelTag) {
72
+ htmlAfterTag = htmlAfterTag.replace(/^\n/, '');
73
+ }
74
+
75
+ // Use escaped square brackets to prevent conflicts between markdown and BB Code.
76
+ const openTag = justEscapeSquareBrackets ? '&#91;' : '<';
77
+ const closeTag = justEscapeSquareBrackets ? '&#93;' : '>';
78
+
79
+ // TODO Don't alter content of bb-code tags when justEscapeSquareBrackets is true.
80
+ // This is necessary to preserve whitespaces in bb-code tags within code blocks.
81
+
82
+ const isCustomTag = [...customBlockLevelTags, ...customInlineLevelTags].includes(Tag);
83
+ const htmlTag = !justEscapeSquareBrackets && isCustomTag ? `${BB_CODE_HTML_TAG_PREFIX}${Tag}` : Tag;
84
+ const openingTag = `${openTag}${htmlTag}${Object.entries(parameters).length > 0 ? ' ' : ''}${Object.entries(parameters).map(([key, value]) => `${key}="${value}"`).join(' ')}${closeTag}`;
85
+ const closingTag = `${openTag}/${htmlTag}${closeTag}`;
86
+ html = html.slice(0, indexOfFullMatch) + openingTag + parsedContent + closingTag + htmlAfterTag;
87
+
88
+ // Continues parsing behind the parsed bb-code.
89
+ parseBehindIndex = indexOfFullMatch + openingTag.length + parsedContent.length + closingTag.length;
90
+ }
91
+ return html;
92
+ };
93
+ exports.parseBBCode = parseBBCode;
94
+ //# sourceMappingURL=formatBBCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatBBCode.js","names":["_findBBCode","require","BB_CODE_HTML_TAG_PREFIX","BLOCK_LEVEL_TAGS","INLINE_LEVEL_TAGS","HTML_CODE_PATTERN","parseBBCode","text","options","justEscapeSquareBrackets","customBlockLevelBBCodeTags","customBlockLevelTags","customInlineLevelBBCodeTags","customInlineLevelTags","html","parseBehindIndex","length","htmlToParse","slice","firstCodeElementMatch","exec","firstBBCodeMatch","findFirstBBCode","index","content","fullMatch","parameters","Tag","tag","toLowerCase","isValidTag","includes","isBlockLevelTag","parsedContent","replace","indexOfFullMatch","indexOf","htmlAfterTag","openTag","closeTag","isCustomTag","htmlTag","openingTag","Object","entries","map","key","value","join","closingTag","exports"],"sources":["../../../../../src/utils/formatString/bb-code/formatBBCode.ts"],"sourcesContent":["import { findFirstBBCode } from './findBBCode';\n\nconst BB_CODE_HTML_TAG_PREFIX = 'bb-code-';\n\nconst BLOCK_LEVEL_TAGS = ['center', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'];\nconst INLINE_LEVEL_TAGS = ['b', 'strong', 'i', 'em', 'u', 's', 'span', 'img'];\n\nconst HTML_CODE_PATTERN = /(?:<code>|<code class=\"inline-code\">)[\\s\\S]*?<\\/code>/;\n\nexport interface ParseBBCodesOptions {\n customBlockLevelBBCodeTags?: string[];\n customInlineLevelBBCodeTags?: string[];\n}\n\ninterface PrivateParseBBCodesOptions extends ParseBBCodesOptions {\n // When justEscapeSquareBrackets is true, this function is simply used to escape square brackets of bb-code tags and nothing else!\n justEscapeSquareBrackets?: boolean;\n}\n\n// Parses BB-Code to HTML recursively.\n// When justEscapeSquareBrackets is true, square brackets are escaped to prevent conflicts between markdown and BB Code.\n// In that case the function only escapes square brackets and doesn't remove line breaks.\nexport const parseBBCode = (text: string, options?: PrivateParseBBCodesOptions) => {\n const {\n justEscapeSquareBrackets = false,\n customBlockLevelBBCodeTags: customBlockLevelTags = [],\n customInlineLevelBBCodeTags: customInlineLevelTags = [],\n } = options || {};\n\n let html = text;\n\n // This index is used to keep track of the position in the html string that is being parsed.\n let parseBehindIndex = 0;\n\n while (parseBehindIndex < html.length) {\n const htmlToParse = html.slice(parseBehindIndex);\n\n const firstCodeElementMatch = HTML_CODE_PATTERN.exec(htmlToParse);\n const firstBBCodeMatch = findFirstBBCode(htmlToParse);\n\n // Stops parsing if no BB-Code is found.\n if (!firstBBCodeMatch) {\n return html;\n }\n\n // Prevents bb-code parsing within code block.\n if (\n firstCodeElementMatch &&\n firstBBCodeMatch &&\n firstCodeElementMatch.index < firstBBCodeMatch.index\n ) {\n // If a code block is found before a BB-Code tag, BB-Code parsing continues behind the code block.\n parseBehindIndex += firstCodeElementMatch.index + firstCodeElementMatch[0].length;\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const { content, fullMatch, parameters, index } = firstBBCodeMatch;\n\n const Tag = firstBBCodeMatch.tag.toLowerCase();\n const isValidTag = [\n ...BLOCK_LEVEL_TAGS,\n ...customBlockLevelTags,\n ...INLINE_LEVEL_TAGS,\n ...customInlineLevelTags,\n ].includes(Tag);\n const isBlockLevelTag = [...BLOCK_LEVEL_TAGS, ...customBlockLevelTags].includes(Tag);\n\n // Ignores tags that are not supported.\n if (!isValidTag) {\n // The parsing continues behind the first square bracket of the BB-Code tag.\n parseBehindIndex += index + 1;\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // Converts BB-Code tag's content before converting itself, because it may contain other BB-Codes.\n let parsedContent = parseBBCode(content);\n\n // Removes leading and trailing line-breaks from within bb code elements, to prevent unwanted spacing.\n if (!justEscapeSquareBrackets) {\n parsedContent = parsedContent.replace(/^\\n+|\\n+$/g, '');\n }\n\n const indexOfFullMatch = html.indexOf(fullMatch);\n\n let htmlAfterTag = html.slice(indexOfFullMatch + fullMatch.length);\n\n // Removes leading line-break (ONE, NOT ALL) after block level elements, to prevent unwanted spacing.\n if (!justEscapeSquareBrackets && isBlockLevelTag) {\n htmlAfterTag = htmlAfterTag.replace(/^\\n/, '');\n }\n\n // Use escaped square brackets to prevent conflicts between markdown and BB Code.\n const openTag = justEscapeSquareBrackets ? '&#91;' : '<';\n const closeTag = justEscapeSquareBrackets ? '&#93;' : '>';\n\n // TODO Don't alter content of bb-code tags when justEscapeSquareBrackets is true.\n // This is necessary to preserve whitespaces in bb-code tags within code blocks.\n\n const isCustomTag = [...customBlockLevelTags, ...customInlineLevelTags].includes(Tag);\n const htmlTag =\n !justEscapeSquareBrackets && isCustomTag ? `${BB_CODE_HTML_TAG_PREFIX}${Tag}` : Tag;\n const openingTag = `${openTag}${htmlTag}${Object.entries(parameters).length > 0 ? ' ' : ''}${Object.entries(\n parameters,\n )\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join(' ')}${closeTag}`;\n const closingTag = `${openTag}/${htmlTag}${closeTag}`;\n html =\n html.slice(0, indexOfFullMatch) +\n openingTag +\n parsedContent +\n closingTag +\n htmlAfterTag;\n\n // Continues parsing behind the parsed bb-code.\n parseBehindIndex =\n indexOfFullMatch + openingTag.length + parsedContent.length + closingTag.length;\n }\n\n return html;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.formatStringToHtml = void 0;
7
+ var _escape = require("../escape");
8
+ var _formatBBCode = require("./bb-code/formatBBCode");
9
+ var _formatMarkdown = require("./markdown/formatMarkdown");
10
+ var _formatMarkdownTable = require("./markdown/formatMarkdownTable");
11
+ // This function takes a string and returns formatted html as a string.
12
+ const formatStringToHtml = (string, options) => {
13
+ if (!string) {
14
+ return {
15
+ html: '',
16
+ tables: []
17
+ };
18
+ }
19
+ const {
20
+ escapeHtml: escapeHtmlOption = false,
21
+ parseMarkdown: parseMarkdownOption = true,
22
+ parseMarkdownTables: parseMarkdownTablesOption = false,
23
+ parseBBCode: parseBBCodeOption = false,
24
+ customInlineLevelBBCodeTags = [],
25
+ customBlockLevelBBCodeTags = []
26
+ } = options || {};
27
+ let formattedString = string;
28
+
29
+ // Escapes HTML.
30
+ if (escapeHtmlOption) {
31
+ formattedString = (0, _escape.escapeHtmlInText)(formattedString);
32
+ }
33
+
34
+ // Escape BB-Code square brackets, to prevent conflicts between markdown and BB Code.
35
+ /* Conflict example:
36
+ When Sidekick detects a function call as an entity through NER, then the following text is returned.
37
+ '[nerReplace <params>]function[/nerReplace](<params>)'
38
+ Because '[/nerReplace](<params>)' is a valid Markdown link, the Markdown parser would interpret it as a link
39
+ and thus prevent the BB-Code parser from recognizing the BB-Code. Parsing the BB-Code first would prevent this
40
+ issue. Unfortunately the Markdown parser doesn't support this.
41
+ */
42
+ const shouldTemporarilyEscapeBBCodeBrackets = parseMarkdownOption && parseBBCodeOption;
43
+ if (shouldTemporarilyEscapeBBCodeBrackets) {
44
+ try {
45
+ formattedString = (0, _formatBBCode.parseBBCode)(formattedString, {
46
+ justEscapeSquareBrackets: true
47
+ });
48
+ } catch (error) {
49
+ console.warn('[@chayns-components/format] Warning: Failed to escape bb-code brackets', error);
50
+ }
51
+ }
52
+
53
+ // Parses markdown to HTML. Markdown tables are parsed separately.
54
+ if (parseMarkdownOption) {
55
+ try {
56
+ formattedString = (0, _formatMarkdown.parseMarkdown)(formattedString);
57
+ } catch (error) {
58
+ console.warn('[@chayns-components/format] Warning: Failed to parse markdown', error);
59
+ }
60
+ }
61
+ const tables = [];
62
+
63
+ // Parses markdown tables to HTML. Also returns the tables content as an array, to allow further processing.
64
+ if (parseMarkdownTablesOption) {
65
+ try {
66
+ const result = (0, _formatMarkdownTable.parseMarkdownTables)(formattedString);
67
+ formattedString = result.html;
68
+ tables.push(...result.tables);
69
+ } catch (error) {
70
+ console.warn('[@chayns-components/format] Warning: Failed to parse markdown tables', error);
71
+ }
72
+ }
73
+
74
+ // Unescapes BB-Code square brackets, to allow parsing of BB-Code.
75
+ if (shouldTemporarilyEscapeBBCodeBrackets) {
76
+ formattedString = (0, _escape.unescapeSquareBrackets)(formattedString);
77
+ }
78
+ if (parseBBCodeOption) {
79
+ try {
80
+ formattedString = (0, _formatBBCode.parseBBCode)(formattedString, {
81
+ customInlineLevelBBCodeTags,
82
+ customBlockLevelBBCodeTags,
83
+ justEscapeSquareBrackets: false
84
+ });
85
+ } catch (error) {
86
+ console.warn('[@chayns-components/format] Warning: Failed to parse bb-code', error);
87
+ }
88
+ }
89
+ return {
90
+ html: formattedString,
91
+ tables
92
+ };
93
+ };
94
+ exports.formatStringToHtml = formatStringToHtml;
95
+ //# sourceMappingURL=formatString.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatString.js","names":["_escape","require","_formatBBCode","_formatMarkdown","_formatMarkdownTable","formatStringToHtml","string","options","html","tables","escapeHtml","escapeHtmlOption","parseMarkdown","parseMarkdownOption","parseMarkdownTables","parseMarkdownTablesOption","parseBBCode","parseBBCodeOption","customInlineLevelBBCodeTags","customBlockLevelBBCodeTags","formattedString","escapeHtmlInText","shouldTemporarilyEscapeBBCodeBrackets","justEscapeSquareBrackets","error","console","warn","result","push","unescapeSquareBrackets","exports"],"sources":["../../../../src/utils/formatString/formatString.ts"],"sourcesContent":["import { escapeHtmlInText, unescapeSquareBrackets } from '../escape';\nimport { parseBBCode, ParseBBCodesOptions } from './bb-code/formatBBCode';\nimport { parseMarkdown } from './markdown/formatMarkdown';\nimport { parseMarkdownTables, TableObject } from './markdown/formatMarkdownTable';\n\ninterface FormatStringOptions extends ParseBBCodesOptions {\n escapeHtml?: boolean;\n parseMarkdown?: boolean;\n parseMarkdownTables?: 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 escapeHtml: escapeHtmlOption = false,\n parseMarkdown: parseMarkdownOption = true,\n parseMarkdownTables: parseMarkdownTablesOption = false,\n parseBBCode: parseBBCodeOption = false,\n customInlineLevelBBCodeTags = [],\n customBlockLevelBBCodeTags = [],\n } = options || {};\n\n let formattedString = string;\n\n // Escapes HTML.\n if (escapeHtmlOption) {\n formattedString = escapeHtmlInText(formattedString);\n }\n\n // Escape BB-Code square brackets, to prevent conflicts between markdown and BB Code.\n /* Conflict example:\n When Sidekick detects a function call as an entity through NER, then the following text is returned.\n '[nerReplace <params>]function[/nerReplace](<params>)'\n Because '[/nerReplace](<params>)' is a valid Markdown link, the Markdown parser would interpret it as a link\n and thus prevent the BB-Code parser from recognizing the BB-Code. Parsing the BB-Code first would prevent this\n issue. Unfortunately the Markdown parser doesn't support this.\n */\n const shouldTemporarilyEscapeBBCodeBrackets = parseMarkdownOption && parseBBCodeOption;\n if (shouldTemporarilyEscapeBBCodeBrackets) {\n try {\n formattedString = parseBBCode(formattedString, {\n justEscapeSquareBrackets: true,\n });\n } catch (error) {\n console.warn(\n '[@chayns-components/format] Warning: Failed to escape bb-code brackets',\n error,\n );\n }\n }\n\n // Parses markdown to HTML. Markdown tables are parsed separately.\n if (parseMarkdownOption) {\n try {\n formattedString = parseMarkdown(formattedString);\n } catch (error) {\n console.warn('[@chayns-components/format] Warning: Failed to parse markdown', error);\n }\n }\n\n const tables: TableObject[] = [];\n\n // Parses markdown tables to HTML. Also returns the tables content as an array, to allow further processing.\n if (parseMarkdownTablesOption) {\n try {\n const result = parseMarkdownTables(formattedString);\n formattedString = result.html;\n tables.push(...result.tables);\n } catch (error) {\n console.warn(\n '[@chayns-components/format] Warning: Failed to parse markdown tables',\n error,\n );\n }\n }\n\n // Unescapes BB-Code square brackets, to allow parsing of BB-Code.\n if (shouldTemporarilyEscapeBBCodeBrackets) {\n formattedString = unescapeSquareBrackets(formattedString);\n }\n\n if (parseBBCodeOption) {\n try {\n formattedString = parseBBCode(formattedString, {\n customInlineLevelBBCodeTags,\n customBlockLevelBBCodeTags,\n justEscapeSquareBrackets: false,\n });\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":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AACA,IAAAE,eAAA,GAAAF,OAAA;AACA,IAAAG,oBAAA,GAAAH,OAAA;AAcA;AACO,MAAMI,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,UAAU,EAAEC,gBAAgB,GAAG,KAAK;IACpCC,aAAa,EAAEC,mBAAmB,GAAG,IAAI;IACzCC,mBAAmB,EAAEC,yBAAyB,GAAG,KAAK;IACtDC,WAAW,EAAEC,iBAAiB,GAAG,KAAK;IACtCC,2BAA2B,GAAG,EAAE;IAChCC,0BAA0B,GAAG;EACjC,CAAC,GAAGZ,OAAO,IAAI,CAAC,CAAC;EAEjB,IAAIa,eAAe,GAAGd,MAAM;;EAE5B;EACA,IAAIK,gBAAgB,EAAE;IAClBS,eAAe,GAAG,IAAAC,wBAAgB,EAACD,eAAe,CAAC;EACvD;;EAEA;EACA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,MAAME,qCAAqC,GAAGT,mBAAmB,IAAII,iBAAiB;EACtF,IAAIK,qCAAqC,EAAE;IACvC,IAAI;MACAF,eAAe,GAAG,IAAAJ,yBAAW,EAACI,eAAe,EAAE;QAC3CG,wBAAwB,EAAE;MAC9B,CAAC,CAAC;IACN,CAAC,CAAC,OAAOC,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CACR,wEAAwE,EACxEF,KACJ,CAAC;IACL;EACJ;;EAEA;EACA,IAAIX,mBAAmB,EAAE;IACrB,IAAI;MACAO,eAAe,GAAG,IAAAR,6BAAa,EAACQ,eAAe,CAAC;IACpD,CAAC,CAAC,OAAOI,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,+DAA+D,EAAEF,KAAK,CAAC;IACxF;EACJ;EAEA,MAAMf,MAAqB,GAAG,EAAE;;EAEhC;EACA,IAAIM,yBAAyB,EAAE;IAC3B,IAAI;MACA,MAAMY,MAAM,GAAG,IAAAb,wCAAmB,EAACM,eAAe,CAAC;MACnDA,eAAe,GAAGO,MAAM,CAACnB,IAAI;MAC7BC,MAAM,CAACmB,IAAI,CAAC,GAAGD,MAAM,CAAClB,MAAM,CAAC;IACjC,CAAC,CAAC,OAAOe,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CACR,sEAAsE,EACtEF,KACJ,CAAC;IACL;EACJ;;EAEA;EACA,IAAIF,qCAAqC,EAAE;IACvCF,eAAe,GAAG,IAAAS,8BAAsB,EAACT,eAAe,CAAC;EAC7D;EAEA,IAAIH,iBAAiB,EAAE;IACnB,IAAI;MACAG,eAAe,GAAG,IAAAJ,yBAAW,EAACI,eAAe,EAAE;QAC3CF,2BAA2B;QAC3BC,0BAA0B;QAC1BI,wBAAwB,EAAE;MAC9B,CAAC,CAAC;IACN,CAAC,CAAC,OAAOC,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,8DAA8D,EAAEF,KAAK,CAAC;IACvF;EACJ;EAEA,OAAO;IACHhB,IAAI,EAAEY,eAAe;IACrBX;EACJ,CAAC;AACL,CAAC;AAACqB,OAAA,CAAAzB,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseMarkdown = void 0;
7
+ var _commonmark = require("commonmark");
8
+ var _escape = require("../../escape");
9
+ var _InternalHTMLRenderer = _interopRequireDefault(require("./InternalHTMLRenderer.js"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
+ // @ts-ignore
13
+
14
+ const parseMarkdown = text => {
15
+ let newText = text;
16
+
17
+ // Markdown has its own line break handling. For that reason, we need to replace line breaks with a custom element.
18
+ // In this case I chose a custom <br> Tag.
19
+ // Since commonmark doesn't parse markdown in lines with html, the custom <br> Tag needs to be in its own line.
20
+ // Since there are issues, when the <br> Tag + \n is followed by text, there needs to be a second line break.
21
+ // Thus, we replace \n with \n<br>\n\n.
22
+ newText = newText.replaceAll(/\n/gm, `\n${_escape.MESSAGE_CONVERSION_LINE_BREAK}\n\n`);
23
+ const commonmarkParser = new _commonmark.Parser();
24
+ // TODO Check if esc needs to be passed to InternalHTMLRenderer.
25
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
26
+ const internalHTMLRenderer = new _InternalHTMLRenderer.default({
27
+ esc: _escape.escapeHtmlInText
28
+ });
29
+
30
+ // Converts markdown to HTML.
31
+ const parsedText = commonmarkParser.parse(newText);
32
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
33
+ newText = internalHTMLRenderer.render(parsedText);
34
+
35
+ // The Linebreak handling of markdown is ignored, by removing \n. Then the custom <br> Tags are converted back to \n.
36
+ newText = newText.replaceAll(/\n/gm, '');
37
+ newText = newText.replaceAll(_escape.MESSAGE_CONVERSION_LINE_BREAK, '\n').replaceAll(_escape.MESSAGE_CONVERSION_LINE_BREAK_ESCAPED, '\n');
38
+ return newText;
39
+ };
40
+ exports.parseMarkdown = parseMarkdown;
41
+ //# sourceMappingURL=formatMarkdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatMarkdown.js","names":["_commonmark","require","_escape","_InternalHTMLRenderer","_interopRequireDefault","e","__esModule","default","parseMarkdown","text","newText","replaceAll","MESSAGE_CONVERSION_LINE_BREAK","commonmarkParser","Parser","internalHTMLRenderer","InternalHTMLRenderer","esc","escapeHtmlInText","parsedText","parse","render","MESSAGE_CONVERSION_LINE_BREAK_ESCAPED","exports"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdown.ts"],"sourcesContent":["import { Parser } from 'commonmark';\nimport {\n escapeHtmlInText,\n MESSAGE_CONVERSION_LINE_BREAK,\n MESSAGE_CONVERSION_LINE_BREAK_ESCAPED,\n} from '../../escape';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport InternalHTMLRenderer from './InternalHTMLRenderer.js';\n\nexport const parseMarkdown = (text: string) => {\n let newText = text;\n\n // Markdown has its own line break handling. For that reason, we need to replace line breaks with a custom element.\n // In this case I chose a custom <br> Tag.\n // Since commonmark doesn't parse markdown in lines with html, the custom <br> Tag needs to be in its own line.\n // Since there are issues, when the <br> Tag + \\n is followed by text, there needs to be a second line break.\n // Thus, we replace \\n with \\n<br>\\n\\n.\n newText = newText.replaceAll(/\\n/gm, `\\n${MESSAGE_CONVERSION_LINE_BREAK}\\n\\n`);\n\n const commonmarkParser = new Parser();\n // TODO Check if esc needs to be passed to InternalHTMLRenderer.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call\n const internalHTMLRenderer = new InternalHTMLRenderer({ esc: escapeHtmlInText });\n\n // Converts markdown to HTML.\n const parsedText = commonmarkParser.parse(newText);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access\n newText = internalHTMLRenderer.render(parsedText) as string;\n\n // The Linebreak handling of markdown is ignored, by removing \\n. Then the custom <br> Tags are converted back to \\n.\n newText = newText.replaceAll(/\\n/gm, '');\n newText = newText\n .replaceAll(MESSAGE_CONVERSION_LINE_BREAK, '\\n')\n .replaceAll(MESSAGE_CONVERSION_LINE_BREAK_ESCAPED, '\\n');\n\n return newText;\n};\n"],"mappings":";;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAOA,IAAAE,qBAAA,GAAAC,sBAAA,CAAAH,OAAA;AAA6D,SAAAG,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAF7D;AACA;;AAGO,MAAMG,aAAa,GAAIC,IAAY,IAAK;EAC3C,IAAIC,OAAO,GAAGD,IAAI;;EAElB;EACA;EACA;EACA;EACA;EACAC,OAAO,GAAGA,OAAO,CAACC,UAAU,CAAC,MAAM,EAAE,KAAKC,qCAA6B,MAAM,CAAC;EAE9E,MAAMC,gBAAgB,GAAG,IAAIC,kBAAM,CAAC,CAAC;EACrC;EACA;EACA,MAAMC,oBAAoB,GAAG,IAAIC,6BAAoB,CAAC;IAAEC,GAAG,EAAEC;EAAiB,CAAC,CAAC;;EAEhF;EACA,MAAMC,UAAU,GAAGN,gBAAgB,CAACO,KAAK,CAACV,OAAO,CAAC;EAClD;EACAA,OAAO,GAAGK,oBAAoB,CAACM,MAAM,CAACF,UAAU,CAAW;;EAE3D;EACAT,OAAO,GAAGA,OAAO,CAACC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;EACxCD,OAAO,GAAGA,OAAO,CACZC,UAAU,CAACC,qCAA6B,EAAE,IAAI,CAAC,CAC/CD,UAAU,CAACW,6CAAqC,EAAE,IAAI,CAAC;EAE5D,OAAOZ,OAAO;AAClB,CAAC;AAACa,OAAA,CAAAf,aAAA,GAAAA,aAAA","ignoreList":[]}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseMarkdownTables = void 0;
7
+ var _sync = require("csv-stringify/browser/esm/sync");
8
+ var _marked = require("marked");
9
+ // TODO Implement all markdown parsing this way.
10
+ // This parses tables, that follow the Github-Flavored-Markdown specification.
11
+ const parseMarkdownTables = text => {
12
+ let newText = text;
13
+ const tableTokens = [];
14
+
15
+ // marked.parse parses all markdown in the provided text and returns the result.
16
+ // The parsed result isn't needed. Instead, the parsed table tokens are collected.
17
+ _marked.marked.parse(newText, {
18
+ walkTokens: token => {
19
+ if (token.type === 'table') {
20
+ tableTokens.push(token);
21
+ }
22
+ }
23
+ });
24
+ const tables = [];
25
+
26
+ // The collected table tokens are used to replace the raw Markdown table with the corresponding bb-code table.
27
+ // If the table was directly parsed to html, other markdown replacements within the table wouldn't work.
28
+ tableTokens.forEach((tableToken, index) => {
29
+ var _tableToken$header, _tableToken$rows;
30
+ let tableHtml = '';
31
+ const tableArray = [];
32
+ const id = `message-table-${index}`;
33
+ tableHtml += `<table id="${id}">`;
34
+ if (((_tableToken$header = tableToken.header) === null || _tableToken$header === void 0 ? void 0 : _tableToken$header.length) > 0) {
35
+ const rowArray = [];
36
+ tableHtml += '<thead>';
37
+ tableToken.header.forEach(header => {
38
+ rowArray.push(header.text);
39
+ tableHtml += '<th>';
40
+ tableHtml += header.text;
41
+ tableHtml += '</th>';
42
+ });
43
+ tableHtml += '</thead>';
44
+ tableArray.push(rowArray);
45
+ }
46
+ if (((_tableToken$rows = tableToken.rows) === null || _tableToken$rows === void 0 ? void 0 : _tableToken$rows.length) > 0) {
47
+ tableHtml += '<tbody>';
48
+ tableToken.rows.forEach(row => {
49
+ const rowArray = [];
50
+ tableHtml += '<tr>';
51
+ row.forEach(cell => {
52
+ rowArray.push(cell.text);
53
+ tableHtml += '<td>';
54
+ tableHtml += cell.text;
55
+ tableHtml += '</td>';
56
+ });
57
+ tableHtml += '</tr>';
58
+ tableArray.push(rowArray);
59
+ });
60
+ tableHtml += '</tbody>';
61
+ }
62
+ tableHtml += '</table>';
63
+ const csv = (0, _sync.stringify)(tableArray || []);
64
+ tables.push({
65
+ id,
66
+ raw: tableToken.raw,
67
+ csv
68
+ });
69
+
70
+ // This removes all trailing line breaks from the raw table Markdown, except for one.
71
+ // This is done to ensure that the table HTML is followed by the correct number of line breaks.
72
+ const trailingLineBreaksIndex = tableToken.raw.search(/\n+$/);
73
+ const rawTableMarkdown = trailingLineBreaksIndex === -1 ? tableToken.raw : tableToken.raw.slice(0, trailingLineBreaksIndex + 1);
74
+
75
+ // Replaces the raw table + a leading line break with the table HTML.
76
+ // The line break is removed to ensure, that the table context menu is displayed in the same line as the text before the table.
77
+ const hasLeadingLineBreak = newText.includes(`\n${rawTableMarkdown}`);
78
+ newText = newText.replace(`${hasLeadingLineBreak ? '\n' : ''}${rawTableMarkdown}`, tableHtml);
79
+ });
80
+ return {
81
+ html: newText,
82
+ tables
83
+ };
84
+ };
85
+ exports.parseMarkdownTables = parseMarkdownTables;
86
+ //# sourceMappingURL=formatMarkdownTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatMarkdownTable.js","names":["_sync","require","_marked","parseMarkdownTables","text","newText","tableTokens","marked","parse","walkTokens","token","type","push","tables","forEach","tableToken","index","_tableToken$header","_tableToken$rows","tableHtml","tableArray","id","header","length","rowArray","rows","row","cell","csv","stringify","raw","trailingLineBreaksIndex","search","rawTableMarkdown","slice","hasLeadingLineBreak","includes","replace","html","exports"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdownTable.ts"],"sourcesContent":["import { stringify } from 'csv-stringify/browser/esm/sync';\nimport { marked, Tokens } from 'marked';\n\nexport type TableObject = {\n id: string;\n raw: string;\n csv: string;\n};\n\n// TODO Implement all markdown parsing this way.\n// This parses tables, that follow the Github-Flavored-Markdown specification.\nexport const parseMarkdownTables = (text: string) => {\n let newText = text;\n const tableTokens: Tokens.Table[] = [];\n\n // marked.parse parses all markdown in the provided text and returns the result.\n // The parsed result isn't needed. Instead, the parsed table tokens are collected.\n marked.parse(newText, {\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 // The collected table tokens are used to replace the raw Markdown table with the corresponding bb-code table.\n // If the table was directly parsed to html, other markdown replacements within the table wouldn't work.\n tableTokens.forEach((tableToken, index) => {\n let tableHtml = '';\n const tableArray: string[][] = [];\n\n const id = `message-table-${index}`;\n\n tableHtml += `<table id=\"${id}\">`;\n if (tableToken.header?.length > 0) {\n const rowArray: string[] = [];\n\n tableHtml += '<thead>';\n tableToken.header.forEach((header) => {\n rowArray.push(header.text);\n\n tableHtml += '<th>';\n tableHtml += header.text;\n tableHtml += '</th>';\n });\n tableHtml += '</thead>';\n\n tableArray.push(rowArray);\n }\n if (tableToken.rows?.length > 0) {\n tableHtml += '<tbody>';\n tableToken.rows.forEach((row) => {\n const rowArray: string[] = [];\n\n tableHtml += '<tr>';\n row.forEach((cell) => {\n rowArray.push(cell.text);\n\n tableHtml += '<td>';\n tableHtml += cell.text;\n tableHtml += '</td>';\n });\n tableHtml += '</tr>';\n\n tableArray.push(rowArray);\n });\n tableHtml += '</tbody>';\n }\n tableHtml += '</table>';\n\n const csv = stringify(tableArray || []);\n\n tables.push({\n id,\n raw: tableToken.raw,\n csv,\n });\n\n // This removes all trailing line breaks from the raw table Markdown, except for one.\n // This is done to ensure that the table HTML is followed by the correct number of line breaks.\n const trailingLineBreaksIndex = tableToken.raw.search(/\\n+$/);\n const rawTableMarkdown =\n trailingLineBreaksIndex === -1\n ? tableToken.raw\n : tableToken.raw.slice(0, trailingLineBreaksIndex + 1);\n\n // Replaces the raw table + a leading line break with the table HTML.\n // The line break is removed to ensure, that the table context menu is displayed in the same line as the text before the table.\n const hasLeadingLineBreak = newText.includes(`\\n${rawTableMarkdown}`);\n newText = newText.replace(\n `${hasLeadingLineBreak ? '\\n' : ''}${rawTableMarkdown}`,\n tableHtml,\n );\n });\n\n return {\n html: newText,\n tables,\n };\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export { formatStringToHtml } from './utils/formatString/formatString';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["formatStringToHtml"],"sources":["../../src/index.ts"],"sourcesContent":["export { formatStringToHtml } from './utils/formatString/formatString';\n"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,mCAAmC","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ export const escapeHtmlInText = text => text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
2
+ export const unescapeSquareBrackets = text => text.replaceAll('&#91;', '[').replaceAll('&#93;', ']');
3
+ export const MESSAGE_CONVERSION_LINE_BREAK = '<br is-replaced-linebreak>';
4
+ export const MESSAGE_CONVERSION_LINE_BREAK_ESCAPED = escapeHtmlInText(MESSAGE_CONVERSION_LINE_BREAK);
5
+ //# sourceMappingURL=escape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.js","names":["escapeHtmlInText","text","replace","unescapeSquareBrackets","replaceAll","MESSAGE_CONVERSION_LINE_BREAK","MESSAGE_CONVERSION_LINE_BREAK_ESCAPED"],"sources":["../../../src/utils/escape.ts"],"sourcesContent":["export const escapeHtmlInText = (text: string): string =>\n text.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\nexport const unescapeSquareBrackets = (text: string): string =>\n text.replaceAll('&#91;', '[').replaceAll('&#93;', ']');\n\nexport const MESSAGE_CONVERSION_LINE_BREAK = '<br is-replaced-linebreak>';\nexport const MESSAGE_CONVERSION_LINE_BREAK_ESCAPED = escapeHtmlInText(\n MESSAGE_CONVERSION_LINE_BREAK,\n);\n"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,GAAIC,IAAY,IACzCA,IAAI,CAACC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;AAEpD,OAAO,MAAMC,sBAAsB,GAAIF,IAAY,IAC/CA,IAAI,CAACG,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAACA,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;AAE1D,OAAO,MAAMC,6BAA6B,GAAG,4BAA4B;AACzE,OAAO,MAAMC,qCAAqC,GAAGN,gBAAgB,CACjEK,6BACJ,CAAC","ignoreList":[]}
@@ -0,0 +1,35 @@
1
+ const BB_REGEX = /\[([a-zA-Z0-9_]*)(.*?)\](.*?)\[\/\1\]/s;
2
+ // Also matches "\" before quote to fix button for voucher messages
3
+ const PARAMETER_REGEX = /([\w]*?)=\\?["„](.*?)["“]/g;
4
+ // TODO Use external package instead of RegExp to parse BBCode.
5
+ // It is not recommended to use RegExp to parse markup languages like BBCode, because it is not possible to parse nested tags with it.
6
+
7
+ // Finds and returns the first BBCode tag in the input string.
8
+ export function findFirstBBCode(inputString) {
9
+ const matches = BB_REGEX.exec(inputString);
10
+ if (matches !== null) {
11
+ const [fullMatch, tag, params, content] = matches;
12
+ const {
13
+ index
14
+ } = matches;
15
+ if (fullMatch === undefined || tag === undefined || params === undefined || content === undefined) return null;
16
+ const parameters = {};
17
+ let match = null;
18
+ // eslint-disable-next-line no-cond-assign
19
+ while (match = PARAMETER_REGEX.exec(params)) {
20
+ const [, key, value] = match;
21
+ if (value) {
22
+ parameters[key || 'url'] = value;
23
+ }
24
+ }
25
+ return {
26
+ fullMatch,
27
+ tag,
28
+ parameters,
29
+ content,
30
+ index
31
+ };
32
+ }
33
+ return null;
34
+ }
35
+ //# sourceMappingURL=findBBCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findBBCode.js","names":["BB_REGEX","PARAMETER_REGEX","findFirstBBCode","inputString","matches","exec","fullMatch","tag","params","content","index","undefined","parameters","match","key","value"],"sources":["../../../../../src/utils/formatString/bb-code/findBBCode.ts"],"sourcesContent":["const BB_REGEX = /\\[([a-zA-Z0-9_]*)(.*?)\\](.*?)\\[\\/\\1\\]/s;\n// Also matches \"\\\" before quote to fix button for voucher messages\nconst PARAMETER_REGEX = /([\\w]*?)=\\\\?[\"„](.*?)[\"“]/g;\n\nexport interface BBCodeMatch {\n fullMatch: string;\n tag: string;\n parameters: Record<string, string>;\n content: string;\n index: number;\n}\n\n// TODO Use external package instead of RegExp to parse BBCode.\n// It is not recommended to use RegExp to parse markup languages like BBCode, because it is not possible to parse nested tags with it.\n\n// Finds and returns the first BBCode tag in the input string.\nexport function findFirstBBCode(inputString: string): BBCodeMatch | null {\n const matches = BB_REGEX.exec(inputString);\n\n if (matches !== null) {\n const [fullMatch, tag, params, content] = matches;\n const { index } = matches;\n\n if (\n fullMatch === undefined ||\n tag === undefined ||\n params === undefined ||\n content === undefined\n )\n return null;\n\n const parameters: Record<string, string> = {};\n\n let match: RegExpExecArray | null = null;\n // eslint-disable-next-line no-cond-assign\n while ((match = PARAMETER_REGEX.exec(params))) {\n const [, key, value] = match;\n\n if (value) {\n parameters[key || 'url'] = value;\n }\n }\n\n return {\n fullMatch,\n tag,\n parameters,\n content,\n index,\n };\n }\n\n return null;\n}\n"],"mappings":"AAAA,MAAMA,QAAQ,GAAG,wCAAwC;AACzD;AACA,MAAMC,eAAe,GAAG,4BAA4B;AAUpD;AACA;;AAEA;AACA,OAAO,SAASC,eAAeA,CAACC,WAAmB,EAAsB;EACrE,MAAMC,OAAO,GAAGJ,QAAQ,CAACK,IAAI,CAACF,WAAW,CAAC;EAE1C,IAAIC,OAAO,KAAK,IAAI,EAAE;IAClB,MAAM,CAACE,SAAS,EAAEC,GAAG,EAAEC,MAAM,EAAEC,OAAO,CAAC,GAAGL,OAAO;IACjD,MAAM;MAAEM;IAAM,CAAC,GAAGN,OAAO;IAEzB,IACIE,SAAS,KAAKK,SAAS,IACvBJ,GAAG,KAAKI,SAAS,IACjBH,MAAM,KAAKG,SAAS,IACpBF,OAAO,KAAKE,SAAS,EAErB,OAAO,IAAI;IAEf,MAAMC,UAAkC,GAAG,CAAC,CAAC;IAE7C,IAAIC,KAA6B,GAAG,IAAI;IACxC;IACA,OAAQA,KAAK,GAAGZ,eAAe,CAACI,IAAI,CAACG,MAAM,CAAC,EAAG;MAC3C,MAAM,GAAGM,GAAG,EAAEC,KAAK,CAAC,GAAGF,KAAK;MAE5B,IAAIE,KAAK,EAAE;QACPH,UAAU,CAACE,GAAG,IAAI,KAAK,CAAC,GAAGC,KAAK;MACpC;IACJ;IAEA,OAAO;MACHT,SAAS;MACTC,GAAG;MACHK,UAAU;MACVH,OAAO;MACPC;IACJ,CAAC;EACL;EAEA,OAAO,IAAI;AACf","ignoreList":[]}
@@ -0,0 +1,90 @@
1
+ import { findFirstBBCode } from './findBBCode';
2
+ const BB_CODE_HTML_TAG_PREFIX = 'bb-code-';
3
+ const BLOCK_LEVEL_TAGS = ['center', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'];
4
+ const INLINE_LEVEL_TAGS = ['b', 'strong', 'i', 'em', 'u', 's', 'span', 'img'];
5
+ const HTML_CODE_PATTERN = /(?:<code>|<code class="inline-code">)[\s\S]*?<\/code>/;
6
+ // Parses BB-Code to HTML recursively.
7
+ // When justEscapeSquareBrackets is true, square brackets are escaped to prevent conflicts between markdown and BB Code.
8
+ // In that case the function only escapes square brackets and doesn't remove line breaks.
9
+ export const parseBBCode = (text, options) => {
10
+ const {
11
+ justEscapeSquareBrackets = false,
12
+ customBlockLevelBBCodeTags: customBlockLevelTags = [],
13
+ customInlineLevelBBCodeTags: customInlineLevelTags = []
14
+ } = options || {};
15
+ let html = text;
16
+
17
+ // This index is used to keep track of the position in the html string that is being parsed.
18
+ let parseBehindIndex = 0;
19
+ while (parseBehindIndex < html.length) {
20
+ const htmlToParse = html.slice(parseBehindIndex);
21
+ const firstCodeElementMatch = HTML_CODE_PATTERN.exec(htmlToParse);
22
+ const firstBBCodeMatch = findFirstBBCode(htmlToParse);
23
+
24
+ // Stops parsing if no BB-Code is found.
25
+ if (!firstBBCodeMatch) {
26
+ return html;
27
+ }
28
+
29
+ // Prevents bb-code parsing within code block.
30
+ if (firstCodeElementMatch && firstBBCodeMatch && firstCodeElementMatch.index < firstBBCodeMatch.index) {
31
+ // If a code block is found before a BB-Code tag, BB-Code parsing continues behind the code block.
32
+ parseBehindIndex += firstCodeElementMatch.index + firstCodeElementMatch[0].length;
33
+ // eslint-disable-next-line no-continue
34
+ continue;
35
+ }
36
+ const {
37
+ content,
38
+ fullMatch,
39
+ parameters,
40
+ index
41
+ } = firstBBCodeMatch;
42
+ const Tag = firstBBCodeMatch.tag.toLowerCase();
43
+ const isValidTag = [...BLOCK_LEVEL_TAGS, ...customBlockLevelTags, ...INLINE_LEVEL_TAGS, ...customInlineLevelTags].includes(Tag);
44
+ const isBlockLevelTag = [...BLOCK_LEVEL_TAGS, ...customBlockLevelTags].includes(Tag);
45
+
46
+ // Ignores tags that are not supported.
47
+ if (!isValidTag) {
48
+ // The parsing continues behind the first square bracket of the BB-Code tag.
49
+ parseBehindIndex += index + 1;
50
+ // eslint-disable-next-line no-continue
51
+ continue;
52
+ }
53
+
54
+ // Converts BB-Code tag's content before converting itself, because it may contain other BB-Codes.
55
+ let parsedContent = parseBBCode(content);
56
+
57
+ // Removes leading and trailing line-breaks from within bb code elements, to prevent unwanted spacing.
58
+ if (!justEscapeSquareBrackets) {
59
+ parsedContent = parsedContent.replace(/^\n+|\n+$/g, '');
60
+ }
61
+ const indexOfFullMatch = html.indexOf(fullMatch);
62
+ let htmlAfterTag = html.slice(indexOfFullMatch + fullMatch.length);
63
+
64
+ // Removes leading line-break (ONE, NOT ALL) after block level elements, to prevent unwanted spacing.
65
+ if (!justEscapeSquareBrackets && isBlockLevelTag) {
66
+ htmlAfterTag = htmlAfterTag.replace(/^\n/, '');
67
+ }
68
+
69
+ // Use escaped square brackets to prevent conflicts between markdown and BB Code.
70
+ const openTag = justEscapeSquareBrackets ? '&#91;' : '<';
71
+ const closeTag = justEscapeSquareBrackets ? '&#93;' : '>';
72
+
73
+ // TODO Don't alter content of bb-code tags when justEscapeSquareBrackets is true.
74
+ // This is necessary to preserve whitespaces in bb-code tags within code blocks.
75
+
76
+ const isCustomTag = [...customBlockLevelTags, ...customInlineLevelTags].includes(Tag);
77
+ const htmlTag = !justEscapeSquareBrackets && isCustomTag ? `${BB_CODE_HTML_TAG_PREFIX}${Tag}` : Tag;
78
+ const openingTag = `${openTag}${htmlTag}${Object.entries(parameters).length > 0 ? ' ' : ''}${Object.entries(parameters).map(_ref => {
79
+ let [key, value] = _ref;
80
+ return `${key}="${value}"`;
81
+ }).join(' ')}${closeTag}`;
82
+ const closingTag = `${openTag}/${htmlTag}${closeTag}`;
83
+ html = html.slice(0, indexOfFullMatch) + openingTag + parsedContent + closingTag + htmlAfterTag;
84
+
85
+ // Continues parsing behind the parsed bb-code.
86
+ parseBehindIndex = indexOfFullMatch + openingTag.length + parsedContent.length + closingTag.length;
87
+ }
88
+ return html;
89
+ };
90
+ //# sourceMappingURL=formatBBCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatBBCode.js","names":["findFirstBBCode","BB_CODE_HTML_TAG_PREFIX","BLOCK_LEVEL_TAGS","INLINE_LEVEL_TAGS","HTML_CODE_PATTERN","parseBBCode","text","options","justEscapeSquareBrackets","customBlockLevelBBCodeTags","customBlockLevelTags","customInlineLevelBBCodeTags","customInlineLevelTags","html","parseBehindIndex","length","htmlToParse","slice","firstCodeElementMatch","exec","firstBBCodeMatch","index","content","fullMatch","parameters","Tag","tag","toLowerCase","isValidTag","includes","isBlockLevelTag","parsedContent","replace","indexOfFullMatch","indexOf","htmlAfterTag","openTag","closeTag","isCustomTag","htmlTag","openingTag","Object","entries","map","_ref","key","value","join","closingTag"],"sources":["../../../../../src/utils/formatString/bb-code/formatBBCode.ts"],"sourcesContent":["import { findFirstBBCode } from './findBBCode';\n\nconst BB_CODE_HTML_TAG_PREFIX = 'bb-code-';\n\nconst BLOCK_LEVEL_TAGS = ['center', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'];\nconst INLINE_LEVEL_TAGS = ['b', 'strong', 'i', 'em', 'u', 's', 'span', 'img'];\n\nconst HTML_CODE_PATTERN = /(?:<code>|<code class=\"inline-code\">)[\\s\\S]*?<\\/code>/;\n\nexport interface ParseBBCodesOptions {\n customBlockLevelBBCodeTags?: string[];\n customInlineLevelBBCodeTags?: string[];\n}\n\ninterface PrivateParseBBCodesOptions extends ParseBBCodesOptions {\n // When justEscapeSquareBrackets is true, this function is simply used to escape square brackets of bb-code tags and nothing else!\n justEscapeSquareBrackets?: boolean;\n}\n\n// Parses BB-Code to HTML recursively.\n// When justEscapeSquareBrackets is true, square brackets are escaped to prevent conflicts between markdown and BB Code.\n// In that case the function only escapes square brackets and doesn't remove line breaks.\nexport const parseBBCode = (text: string, options?: PrivateParseBBCodesOptions) => {\n const {\n justEscapeSquareBrackets = false,\n customBlockLevelBBCodeTags: customBlockLevelTags = [],\n customInlineLevelBBCodeTags: customInlineLevelTags = [],\n } = options || {};\n\n let html = text;\n\n // This index is used to keep track of the position in the html string that is being parsed.\n let parseBehindIndex = 0;\n\n while (parseBehindIndex < html.length) {\n const htmlToParse = html.slice(parseBehindIndex);\n\n const firstCodeElementMatch = HTML_CODE_PATTERN.exec(htmlToParse);\n const firstBBCodeMatch = findFirstBBCode(htmlToParse);\n\n // Stops parsing if no BB-Code is found.\n if (!firstBBCodeMatch) {\n return html;\n }\n\n // Prevents bb-code parsing within code block.\n if (\n firstCodeElementMatch &&\n firstBBCodeMatch &&\n firstCodeElementMatch.index < firstBBCodeMatch.index\n ) {\n // If a code block is found before a BB-Code tag, BB-Code parsing continues behind the code block.\n parseBehindIndex += firstCodeElementMatch.index + firstCodeElementMatch[0].length;\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const { content, fullMatch, parameters, index } = firstBBCodeMatch;\n\n const Tag = firstBBCodeMatch.tag.toLowerCase();\n const isValidTag = [\n ...BLOCK_LEVEL_TAGS,\n ...customBlockLevelTags,\n ...INLINE_LEVEL_TAGS,\n ...customInlineLevelTags,\n ].includes(Tag);\n const isBlockLevelTag = [...BLOCK_LEVEL_TAGS, ...customBlockLevelTags].includes(Tag);\n\n // Ignores tags that are not supported.\n if (!isValidTag) {\n // The parsing continues behind the first square bracket of the BB-Code tag.\n parseBehindIndex += index + 1;\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // Converts BB-Code tag's content before converting itself, because it may contain other BB-Codes.\n let parsedContent = parseBBCode(content);\n\n // Removes leading and trailing line-breaks from within bb code elements, to prevent unwanted spacing.\n if (!justEscapeSquareBrackets) {\n parsedContent = parsedContent.replace(/^\\n+|\\n+$/g, '');\n }\n\n const indexOfFullMatch = html.indexOf(fullMatch);\n\n let htmlAfterTag = html.slice(indexOfFullMatch + fullMatch.length);\n\n // Removes leading line-break (ONE, NOT ALL) after block level elements, to prevent unwanted spacing.\n if (!justEscapeSquareBrackets && isBlockLevelTag) {\n htmlAfterTag = htmlAfterTag.replace(/^\\n/, '');\n }\n\n // Use escaped square brackets to prevent conflicts between markdown and BB Code.\n const openTag = justEscapeSquareBrackets ? '&#91;' : '<';\n const closeTag = justEscapeSquareBrackets ? '&#93;' : '>';\n\n // TODO Don't alter content of bb-code tags when justEscapeSquareBrackets is true.\n // This is necessary to preserve whitespaces in bb-code tags within code blocks.\n\n const isCustomTag = [...customBlockLevelTags, ...customInlineLevelTags].includes(Tag);\n const htmlTag =\n !justEscapeSquareBrackets && isCustomTag ? `${BB_CODE_HTML_TAG_PREFIX}${Tag}` : Tag;\n const openingTag = `${openTag}${htmlTag}${Object.entries(parameters).length > 0 ? ' ' : ''}${Object.entries(\n parameters,\n )\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join(' ')}${closeTag}`;\n const closingTag = `${openTag}/${htmlTag}${closeTag}`;\n html =\n html.slice(0, indexOfFullMatch) +\n openingTag +\n parsedContent +\n closingTag +\n htmlAfterTag;\n\n // Continues parsing behind the parsed bb-code.\n parseBehindIndex =\n indexOfFullMatch + openingTag.length + parsedContent.length + closingTag.length;\n }\n\n return html;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,88 @@
1
+ import { escapeHtmlInText, unescapeSquareBrackets } from '../escape';
2
+ import { parseBBCode } from './bb-code/formatBBCode';
3
+ import { parseMarkdown } from './markdown/formatMarkdown';
4
+ import { parseMarkdownTables } from './markdown/formatMarkdownTable';
5
+ // This function takes a string and returns formatted html as a string.
6
+ export const formatStringToHtml = (string, options) => {
7
+ if (!string) {
8
+ return {
9
+ html: '',
10
+ tables: []
11
+ };
12
+ }
13
+ const {
14
+ escapeHtml: escapeHtmlOption = false,
15
+ parseMarkdown: parseMarkdownOption = true,
16
+ parseMarkdownTables: parseMarkdownTablesOption = false,
17
+ parseBBCode: parseBBCodeOption = false,
18
+ customInlineLevelBBCodeTags = [],
19
+ customBlockLevelBBCodeTags = []
20
+ } = options || {};
21
+ let formattedString = string;
22
+
23
+ // Escapes HTML.
24
+ if (escapeHtmlOption) {
25
+ formattedString = escapeHtmlInText(formattedString);
26
+ }
27
+
28
+ // Escape BB-Code square brackets, to prevent conflicts between markdown and BB Code.
29
+ /* Conflict example:
30
+ When Sidekick detects a function call as an entity through NER, then the following text is returned.
31
+ '[nerReplace <params>]function[/nerReplace](<params>)'
32
+ Because '[/nerReplace](<params>)' is a valid Markdown link, the Markdown parser would interpret it as a link
33
+ and thus prevent the BB-Code parser from recognizing the BB-Code. Parsing the BB-Code first would prevent this
34
+ issue. Unfortunately the Markdown parser doesn't support this.
35
+ */
36
+ const shouldTemporarilyEscapeBBCodeBrackets = parseMarkdownOption && parseBBCodeOption;
37
+ if (shouldTemporarilyEscapeBBCodeBrackets) {
38
+ try {
39
+ formattedString = parseBBCode(formattedString, {
40
+ justEscapeSquareBrackets: true
41
+ });
42
+ } catch (error) {
43
+ console.warn('[@chayns-components/format] Warning: Failed to escape bb-code brackets', error);
44
+ }
45
+ }
46
+
47
+ // Parses markdown to HTML. Markdown tables are parsed separately.
48
+ if (parseMarkdownOption) {
49
+ try {
50
+ formattedString = parseMarkdown(formattedString);
51
+ } catch (error) {
52
+ console.warn('[@chayns-components/format] Warning: Failed to parse markdown', error);
53
+ }
54
+ }
55
+ const tables = [];
56
+
57
+ // Parses markdown tables to HTML. Also returns the tables content as an array, to allow further processing.
58
+ if (parseMarkdownTablesOption) {
59
+ try {
60
+ const result = parseMarkdownTables(formattedString);
61
+ formattedString = result.html;
62
+ tables.push(...result.tables);
63
+ } catch (error) {
64
+ console.warn('[@chayns-components/format] Warning: Failed to parse markdown tables', error);
65
+ }
66
+ }
67
+
68
+ // Unescapes BB-Code square brackets, to allow parsing of BB-Code.
69
+ if (shouldTemporarilyEscapeBBCodeBrackets) {
70
+ formattedString = unescapeSquareBrackets(formattedString);
71
+ }
72
+ if (parseBBCodeOption) {
73
+ try {
74
+ formattedString = parseBBCode(formattedString, {
75
+ customInlineLevelBBCodeTags,
76
+ customBlockLevelBBCodeTags,
77
+ justEscapeSquareBrackets: false
78
+ });
79
+ } catch (error) {
80
+ console.warn('[@chayns-components/format] Warning: Failed to parse bb-code', error);
81
+ }
82
+ }
83
+ return {
84
+ html: formattedString,
85
+ tables
86
+ };
87
+ };
88
+ //# sourceMappingURL=formatString.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatString.js","names":["escapeHtmlInText","unescapeSquareBrackets","parseBBCode","parseMarkdown","parseMarkdownTables","formatStringToHtml","string","options","html","tables","escapeHtml","escapeHtmlOption","parseMarkdownOption","parseMarkdownTablesOption","parseBBCodeOption","customInlineLevelBBCodeTags","customBlockLevelBBCodeTags","formattedString","shouldTemporarilyEscapeBBCodeBrackets","justEscapeSquareBrackets","error","console","warn","result","push"],"sources":["../../../../src/utils/formatString/formatString.ts"],"sourcesContent":["import { escapeHtmlInText, unescapeSquareBrackets } from '../escape';\nimport { parseBBCode, ParseBBCodesOptions } from './bb-code/formatBBCode';\nimport { parseMarkdown } from './markdown/formatMarkdown';\nimport { parseMarkdownTables, TableObject } from './markdown/formatMarkdownTable';\n\ninterface FormatStringOptions extends ParseBBCodesOptions {\n escapeHtml?: boolean;\n parseMarkdown?: boolean;\n parseMarkdownTables?: 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 escapeHtml: escapeHtmlOption = false,\n parseMarkdown: parseMarkdownOption = true,\n parseMarkdownTables: parseMarkdownTablesOption = false,\n parseBBCode: parseBBCodeOption = false,\n customInlineLevelBBCodeTags = [],\n customBlockLevelBBCodeTags = [],\n } = options || {};\n\n let formattedString = string;\n\n // Escapes HTML.\n if (escapeHtmlOption) {\n formattedString = escapeHtmlInText(formattedString);\n }\n\n // Escape BB-Code square brackets, to prevent conflicts between markdown and BB Code.\n /* Conflict example:\n When Sidekick detects a function call as an entity through NER, then the following text is returned.\n '[nerReplace <params>]function[/nerReplace](<params>)'\n Because '[/nerReplace](<params>)' is a valid Markdown link, the Markdown parser would interpret it as a link\n and thus prevent the BB-Code parser from recognizing the BB-Code. Parsing the BB-Code first would prevent this\n issue. Unfortunately the Markdown parser doesn't support this.\n */\n const shouldTemporarilyEscapeBBCodeBrackets = parseMarkdownOption && parseBBCodeOption;\n if (shouldTemporarilyEscapeBBCodeBrackets) {\n try {\n formattedString = parseBBCode(formattedString, {\n justEscapeSquareBrackets: true,\n });\n } catch (error) {\n console.warn(\n '[@chayns-components/format] Warning: Failed to escape bb-code brackets',\n error,\n );\n }\n }\n\n // Parses markdown to HTML. Markdown tables are parsed separately.\n if (parseMarkdownOption) {\n try {\n formattedString = parseMarkdown(formattedString);\n } catch (error) {\n console.warn('[@chayns-components/format] Warning: Failed to parse markdown', error);\n }\n }\n\n const tables: TableObject[] = [];\n\n // Parses markdown tables to HTML. Also returns the tables content as an array, to allow further processing.\n if (parseMarkdownTablesOption) {\n try {\n const result = parseMarkdownTables(formattedString);\n formattedString = result.html;\n tables.push(...result.tables);\n } catch (error) {\n console.warn(\n '[@chayns-components/format] Warning: Failed to parse markdown tables',\n error,\n );\n }\n }\n\n // Unescapes BB-Code square brackets, to allow parsing of BB-Code.\n if (shouldTemporarilyEscapeBBCodeBrackets) {\n formattedString = unescapeSquareBrackets(formattedString);\n }\n\n if (parseBBCodeOption) {\n try {\n formattedString = parseBBCode(formattedString, {\n customInlineLevelBBCodeTags,\n customBlockLevelBBCodeTags,\n justEscapeSquareBrackets: false,\n });\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":"AAAA,SAASA,gBAAgB,EAAEC,sBAAsB,QAAQ,WAAW;AACpE,SAASC,WAAW,QAA6B,wBAAwB;AACzE,SAASC,aAAa,QAAQ,2BAA2B;AACzD,SAASC,mBAAmB,QAAqB,gCAAgC;AAcjF;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;IACFC,UAAU,EAAEC,gBAAgB,GAAG,KAAK;IACpCR,aAAa,EAAES,mBAAmB,GAAG,IAAI;IACzCR,mBAAmB,EAAES,yBAAyB,GAAG,KAAK;IACtDX,WAAW,EAAEY,iBAAiB,GAAG,KAAK;IACtCC,2BAA2B,GAAG,EAAE;IAChCC,0BAA0B,GAAG;EACjC,CAAC,GAAGT,OAAO,IAAI,CAAC,CAAC;EAEjB,IAAIU,eAAe,GAAGX,MAAM;;EAE5B;EACA,IAAIK,gBAAgB,EAAE;IAClBM,eAAe,GAAGjB,gBAAgB,CAACiB,eAAe,CAAC;EACvD;;EAEA;EACA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,MAAMC,qCAAqC,GAAGN,mBAAmB,IAAIE,iBAAiB;EACtF,IAAII,qCAAqC,EAAE;IACvC,IAAI;MACAD,eAAe,GAAGf,WAAW,CAACe,eAAe,EAAE;QAC3CE,wBAAwB,EAAE;MAC9B,CAAC,CAAC;IACN,CAAC,CAAC,OAAOC,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CACR,wEAAwE,EACxEF,KACJ,CAAC;IACL;EACJ;;EAEA;EACA,IAAIR,mBAAmB,EAAE;IACrB,IAAI;MACAK,eAAe,GAAGd,aAAa,CAACc,eAAe,CAAC;IACpD,CAAC,CAAC,OAAOG,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,+DAA+D,EAAEF,KAAK,CAAC;IACxF;EACJ;EAEA,MAAMX,MAAqB,GAAG,EAAE;;EAEhC;EACA,IAAII,yBAAyB,EAAE;IAC3B,IAAI;MACA,MAAMU,MAAM,GAAGnB,mBAAmB,CAACa,eAAe,CAAC;MACnDA,eAAe,GAAGM,MAAM,CAACf,IAAI;MAC7BC,MAAM,CAACe,IAAI,CAAC,GAAGD,MAAM,CAACd,MAAM,CAAC;IACjC,CAAC,CAAC,OAAOW,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CACR,sEAAsE,EACtEF,KACJ,CAAC;IACL;EACJ;;EAEA;EACA,IAAIF,qCAAqC,EAAE;IACvCD,eAAe,GAAGhB,sBAAsB,CAACgB,eAAe,CAAC;EAC7D;EAEA,IAAIH,iBAAiB,EAAE;IACnB,IAAI;MACAG,eAAe,GAAGf,WAAW,CAACe,eAAe,EAAE;QAC3CF,2BAA2B;QAC3BC,0BAA0B;QAC1BG,wBAAwB,EAAE;MAC9B,CAAC,CAAC;IACN,CAAC,CAAC,OAAOC,KAAK,EAAE;MACZC,OAAO,CAACC,IAAI,CAAC,8DAA8D,EAAEF,KAAK,CAAC;IACvF;EACJ;EAEA,OAAO;IACHZ,IAAI,EAAES,eAAe;IACrBR;EACJ,CAAC;AACL,CAAC","ignoreList":[]}
@@ -0,0 +1,32 @@
1
+ import { Parser } from 'commonmark';
2
+ import { escapeHtmlInText, MESSAGE_CONVERSION_LINE_BREAK, MESSAGE_CONVERSION_LINE_BREAK_ESCAPED } from '../../escape';
3
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
+ // @ts-ignore
5
+ import InternalHTMLRenderer from './InternalHTMLRenderer.js';
6
+ export const parseMarkdown = text => {
7
+ let newText = text;
8
+
9
+ // Markdown has its own line break handling. For that reason, we need to replace line breaks with a custom element.
10
+ // In this case I chose a custom <br> Tag.
11
+ // Since commonmark doesn't parse markdown in lines with html, the custom <br> Tag needs to be in its own line.
12
+ // Since there are issues, when the <br> Tag + \n is followed by text, there needs to be a second line break.
13
+ // Thus, we replace \n with \n<br>\n\n.
14
+ newText = newText.replaceAll(/\n/gm, `\n${MESSAGE_CONVERSION_LINE_BREAK}\n\n`);
15
+ const commonmarkParser = new Parser();
16
+ // TODO Check if esc needs to be passed to InternalHTMLRenderer.
17
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
18
+ const internalHTMLRenderer = new InternalHTMLRenderer({
19
+ esc: escapeHtmlInText
20
+ });
21
+
22
+ // Converts markdown to HTML.
23
+ const parsedText = commonmarkParser.parse(newText);
24
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
25
+ newText = internalHTMLRenderer.render(parsedText);
26
+
27
+ // The Linebreak handling of markdown is ignored, by removing \n. Then the custom <br> Tags are converted back to \n.
28
+ newText = newText.replaceAll(/\n/gm, '');
29
+ newText = newText.replaceAll(MESSAGE_CONVERSION_LINE_BREAK, '\n').replaceAll(MESSAGE_CONVERSION_LINE_BREAK_ESCAPED, '\n');
30
+ return newText;
31
+ };
32
+ //# sourceMappingURL=formatMarkdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatMarkdown.js","names":["Parser","escapeHtmlInText","MESSAGE_CONVERSION_LINE_BREAK","MESSAGE_CONVERSION_LINE_BREAK_ESCAPED","InternalHTMLRenderer","parseMarkdown","text","newText","replaceAll","commonmarkParser","internalHTMLRenderer","esc","parsedText","parse","render"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdown.ts"],"sourcesContent":["import { Parser } from 'commonmark';\nimport {\n escapeHtmlInText,\n MESSAGE_CONVERSION_LINE_BREAK,\n MESSAGE_CONVERSION_LINE_BREAK_ESCAPED,\n} from '../../escape';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport InternalHTMLRenderer from './InternalHTMLRenderer.js';\n\nexport const parseMarkdown = (text: string) => {\n let newText = text;\n\n // Markdown has its own line break handling. For that reason, we need to replace line breaks with a custom element.\n // In this case I chose a custom <br> Tag.\n // Since commonmark doesn't parse markdown in lines with html, the custom <br> Tag needs to be in its own line.\n // Since there are issues, when the <br> Tag + \\n is followed by text, there needs to be a second line break.\n // Thus, we replace \\n with \\n<br>\\n\\n.\n newText = newText.replaceAll(/\\n/gm, `\\n${MESSAGE_CONVERSION_LINE_BREAK}\\n\\n`);\n\n const commonmarkParser = new Parser();\n // TODO Check if esc needs to be passed to InternalHTMLRenderer.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call\n const internalHTMLRenderer = new InternalHTMLRenderer({ esc: escapeHtmlInText });\n\n // Converts markdown to HTML.\n const parsedText = commonmarkParser.parse(newText);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access\n newText = internalHTMLRenderer.render(parsedText) as string;\n\n // The Linebreak handling of markdown is ignored, by removing \\n. Then the custom <br> Tags are converted back to \\n.\n newText = newText.replaceAll(/\\n/gm, '');\n newText = newText\n .replaceAll(MESSAGE_CONVERSION_LINE_BREAK, '\\n')\n .replaceAll(MESSAGE_CONVERSION_LINE_BREAK_ESCAPED, '\\n');\n\n return newText;\n};\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,YAAY;AACnC,SACIC,gBAAgB,EAChBC,6BAA6B,EAC7BC,qCAAqC,QAClC,cAAc;AACrB;AACA;AACA,OAAOC,oBAAoB,MAAM,2BAA2B;AAE5D,OAAO,MAAMC,aAAa,GAAIC,IAAY,IAAK;EAC3C,IAAIC,OAAO,GAAGD,IAAI;;EAElB;EACA;EACA;EACA;EACA;EACAC,OAAO,GAAGA,OAAO,CAACC,UAAU,CAAC,MAAM,EAAE,KAAKN,6BAA6B,MAAM,CAAC;EAE9E,MAAMO,gBAAgB,GAAG,IAAIT,MAAM,CAAC,CAAC;EACrC;EACA;EACA,MAAMU,oBAAoB,GAAG,IAAIN,oBAAoB,CAAC;IAAEO,GAAG,EAAEV;EAAiB,CAAC,CAAC;;EAEhF;EACA,MAAMW,UAAU,GAAGH,gBAAgB,CAACI,KAAK,CAACN,OAAO,CAAC;EAClD;EACAA,OAAO,GAAGG,oBAAoB,CAACI,MAAM,CAACF,UAAU,CAAW;;EAE3D;EACAL,OAAO,GAAGA,OAAO,CAACC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;EACxCD,OAAO,GAAGA,OAAO,CACZC,UAAU,CAACN,6BAA6B,EAAE,IAAI,CAAC,CAC/CM,UAAU,CAACL,qCAAqC,EAAE,IAAI,CAAC;EAE5D,OAAOI,OAAO;AAClB,CAAC","ignoreList":[]}
@@ -0,0 +1,78 @@
1
+ import { stringify } from 'csv-stringify/browser/esm/sync';
2
+ import { marked } from 'marked';
3
+ // TODO Implement all markdown parsing this way.
4
+ // This parses tables, that follow the Github-Flavored-Markdown specification.
5
+ export const parseMarkdownTables = text => {
6
+ let newText = text;
7
+ const tableTokens = [];
8
+
9
+ // marked.parse parses all markdown in the provided text and returns the result.
10
+ // The parsed result isn't needed. Instead, the parsed table tokens are collected.
11
+ marked.parse(newText, {
12
+ walkTokens: token => {
13
+ if (token.type === 'table') {
14
+ tableTokens.push(token);
15
+ }
16
+ }
17
+ });
18
+ const tables = [];
19
+
20
+ // The collected table tokens are used to replace the raw Markdown table with the corresponding bb-code table.
21
+ // If the table was directly parsed to html, other markdown replacements within the table wouldn't work.
22
+ tableTokens.forEach((tableToken, index) => {
23
+ let tableHtml = '';
24
+ const tableArray = [];
25
+ const id = `message-table-${index}`;
26
+ tableHtml += `<table id="${id}">`;
27
+ if (tableToken.header?.length > 0) {
28
+ const rowArray = [];
29
+ tableHtml += '<thead>';
30
+ tableToken.header.forEach(header => {
31
+ rowArray.push(header.text);
32
+ tableHtml += '<th>';
33
+ tableHtml += header.text;
34
+ tableHtml += '</th>';
35
+ });
36
+ tableHtml += '</thead>';
37
+ tableArray.push(rowArray);
38
+ }
39
+ if (tableToken.rows?.length > 0) {
40
+ tableHtml += '<tbody>';
41
+ tableToken.rows.forEach(row => {
42
+ const rowArray = [];
43
+ tableHtml += '<tr>';
44
+ row.forEach(cell => {
45
+ rowArray.push(cell.text);
46
+ tableHtml += '<td>';
47
+ tableHtml += cell.text;
48
+ tableHtml += '</td>';
49
+ });
50
+ tableHtml += '</tr>';
51
+ tableArray.push(rowArray);
52
+ });
53
+ tableHtml += '</tbody>';
54
+ }
55
+ tableHtml += '</table>';
56
+ const csv = stringify(tableArray || []);
57
+ tables.push({
58
+ id,
59
+ raw: tableToken.raw,
60
+ csv
61
+ });
62
+
63
+ // This removes all trailing line breaks from the raw table Markdown, except for one.
64
+ // This is done to ensure that the table HTML is followed by the correct number of line breaks.
65
+ const trailingLineBreaksIndex = tableToken.raw.search(/\n+$/);
66
+ const rawTableMarkdown = trailingLineBreaksIndex === -1 ? tableToken.raw : tableToken.raw.slice(0, trailingLineBreaksIndex + 1);
67
+
68
+ // Replaces the raw table + a leading line break with the table HTML.
69
+ // The line break is removed to ensure, that the table context menu is displayed in the same line as the text before the table.
70
+ const hasLeadingLineBreak = newText.includes(`\n${rawTableMarkdown}`);
71
+ newText = newText.replace(`${hasLeadingLineBreak ? '\n' : ''}${rawTableMarkdown}`, tableHtml);
72
+ });
73
+ return {
74
+ html: newText,
75
+ tables
76
+ };
77
+ };
78
+ //# sourceMappingURL=formatMarkdownTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatMarkdownTable.js","names":["stringify","marked","parseMarkdownTables","text","newText","tableTokens","parse","walkTokens","token","type","push","tables","forEach","tableToken","index","tableHtml","tableArray","id","header","length","rowArray","rows","row","cell","csv","raw","trailingLineBreaksIndex","search","rawTableMarkdown","slice","hasLeadingLineBreak","includes","replace","html"],"sources":["../../../../../src/utils/formatString/markdown/formatMarkdownTable.ts"],"sourcesContent":["import { stringify } from 'csv-stringify/browser/esm/sync';\nimport { marked, Tokens } from 'marked';\n\nexport type TableObject = {\n id: string;\n raw: string;\n csv: string;\n};\n\n// TODO Implement all markdown parsing this way.\n// This parses tables, that follow the Github-Flavored-Markdown specification.\nexport const parseMarkdownTables = (text: string) => {\n let newText = text;\n const tableTokens: Tokens.Table[] = [];\n\n // marked.parse parses all markdown in the provided text and returns the result.\n // The parsed result isn't needed. Instead, the parsed table tokens are collected.\n marked.parse(newText, {\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 // The collected table tokens are used to replace the raw Markdown table with the corresponding bb-code table.\n // If the table was directly parsed to html, other markdown replacements within the table wouldn't work.\n tableTokens.forEach((tableToken, index) => {\n let tableHtml = '';\n const tableArray: string[][] = [];\n\n const id = `message-table-${index}`;\n\n tableHtml += `<table id=\"${id}\">`;\n if (tableToken.header?.length > 0) {\n const rowArray: string[] = [];\n\n tableHtml += '<thead>';\n tableToken.header.forEach((header) => {\n rowArray.push(header.text);\n\n tableHtml += '<th>';\n tableHtml += header.text;\n tableHtml += '</th>';\n });\n tableHtml += '</thead>';\n\n tableArray.push(rowArray);\n }\n if (tableToken.rows?.length > 0) {\n tableHtml += '<tbody>';\n tableToken.rows.forEach((row) => {\n const rowArray: string[] = [];\n\n tableHtml += '<tr>';\n row.forEach((cell) => {\n rowArray.push(cell.text);\n\n tableHtml += '<td>';\n tableHtml += cell.text;\n tableHtml += '</td>';\n });\n tableHtml += '</tr>';\n\n tableArray.push(rowArray);\n });\n tableHtml += '</tbody>';\n }\n tableHtml += '</table>';\n\n const csv = stringify(tableArray || []);\n\n tables.push({\n id,\n raw: tableToken.raw,\n csv,\n });\n\n // This removes all trailing line breaks from the raw table Markdown, except for one.\n // This is done to ensure that the table HTML is followed by the correct number of line breaks.\n const trailingLineBreaksIndex = tableToken.raw.search(/\\n+$/);\n const rawTableMarkdown =\n trailingLineBreaksIndex === -1\n ? tableToken.raw\n : tableToken.raw.slice(0, trailingLineBreaksIndex + 1);\n\n // Replaces the raw table + a leading line break with the table HTML.\n // The line break is removed to ensure, that the table context menu is displayed in the same line as the text before the table.\n const hasLeadingLineBreak = newText.includes(`\\n${rawTableMarkdown}`);\n newText = newText.replace(\n `${hasLeadingLineBreak ? '\\n' : ''}${rawTableMarkdown}`,\n tableHtml,\n );\n });\n\n return {\n html: newText,\n tables,\n };\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export { formatStringToHtml } from './utils/formatString/formatString';
@@ -0,0 +1,4 @@
1
+ export declare const escapeHtmlInText: (text: string) => string;
2
+ export declare const unescapeSquareBrackets: (text: string) => string;
3
+ export declare const MESSAGE_CONVERSION_LINE_BREAK = "<br is-replaced-linebreak>";
4
+ export declare const MESSAGE_CONVERSION_LINE_BREAK_ESCAPED: string;
@@ -0,0 +1,8 @@
1
+ export interface BBCodeMatch {
2
+ fullMatch: string;
3
+ tag: string;
4
+ parameters: Record<string, string>;
5
+ content: string;
6
+ index: number;
7
+ }
8
+ export declare function findFirstBBCode(inputString: string): BBCodeMatch | null;
@@ -0,0 +1,9 @@
1
+ export interface ParseBBCodesOptions {
2
+ customBlockLevelBBCodeTags?: string[];
3
+ customInlineLevelBBCodeTags?: string[];
4
+ }
5
+ interface PrivateParseBBCodesOptions extends ParseBBCodesOptions {
6
+ justEscapeSquareBrackets?: boolean;
7
+ }
8
+ export declare const parseBBCode: (text: string, options?: PrivateParseBBCodesOptions) => string;
9
+ export {};
@@ -0,0 +1,14 @@
1
+ import { ParseBBCodesOptions } from './bb-code/formatBBCode';
2
+ import { TableObject } from './markdown/formatMarkdownTable';
3
+ interface FormatStringOptions extends ParseBBCodesOptions {
4
+ escapeHtml?: boolean;
5
+ parseMarkdown?: boolean;
6
+ parseMarkdownTables?: boolean;
7
+ parseBBCode?: boolean;
8
+ }
9
+ interface FormatStringResult {
10
+ html: string;
11
+ tables: TableObject[];
12
+ }
13
+ export declare const formatStringToHtml: (string: string, options?: FormatStringOptions) => FormatStringResult;
14
+ export {};
@@ -0,0 +1 @@
1
+ export declare const parseMarkdown: (text: string) => string;
@@ -0,0 +1,9 @@
1
+ export type TableObject = {
2
+ id: string;
3
+ raw: string;
4
+ csv: string;
5
+ };
6
+ export declare const parseMarkdownTables: (text: string) => {
7
+ html: string;
8
+ tables: TableObject[];
9
+ };
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@chayns-components/format",
3
+ "version": "5.0.0-beta.650",
4
+ "description": "A set of beautiful React components for developing your own applications with chayns.",
5
+ "sideEffects": false,
6
+ "browserslist": [
7
+ ">0.5%",
8
+ "not dead",
9
+ "not op_mini all",
10
+ "not IE 11"
11
+ ],
12
+ "keywords": [
13
+ "chayns",
14
+ "react",
15
+ "components"
16
+ ],
17
+ "author": "Tobit.Software",
18
+ "homepage": "https://github.com/TobitSoftware/chayns-components/tree/main/packages/format#readme",
19
+ "license": "MIT",
20
+ "main": "lib/cjs/index.js",
21
+ "module": "lib/esm/index.js",
22
+ "types": "lib/types/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "require": "./lib/cjs/index.js",
26
+ "import": "./lib/esm/index.js",
27
+ "types": "./lib/types/index.d.ts"
28
+ }
29
+ },
30
+ "directories": {
31
+ "lib": "lib",
32
+ "test": "__tests__"
33
+ },
34
+ "files": [
35
+ "lib"
36
+ ],
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/TobitSoftware/chayns-components.git"
40
+ },
41
+ "scripts": {
42
+ "build": "npm run build:cjs && npm run build:esm && npm run build:types",
43
+ "build:types": "tsc",
44
+ "build:cjs": "cross-env NODE_ENV=cjs babel src --out-dir lib/cjs --extensions=.ts,.tsx --source-maps --ignore=src/stories",
45
+ "build:esm": "cross-env NODE_ENV=esm babel src --out-dir lib/esm --extensions=.ts,.tsx --source-maps --ignore=src/stories",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/TobitSoftware/chayns-components/issues"
50
+ },
51
+ "devDependencies": {
52
+ "@babel/cli": "^7.24.6",
53
+ "@babel/core": "^7.24.6",
54
+ "@babel/preset-env": "^7.24.6",
55
+ "@babel/preset-react": "^7.24.6",
56
+ "@babel/preset-typescript": "^7.24.6",
57
+ "@types/commonmark": "^0.27.9",
58
+ "@types/csv-stringify": "^3.1.0",
59
+ "babel-loader": "^9.1.3",
60
+ "cross-env": "^7.0.3",
61
+ "lerna": "^8.1.3",
62
+ "typescript": "^5.4.5"
63
+ },
64
+ "dependencies": {
65
+ "commonmark": "^0.31.0",
66
+ "csv-stringify": "^6.5.0",
67
+ "marked": "^13.0.0"
68
+ },
69
+ "publishConfig": {
70
+ "access": "public"
71
+ },
72
+ "gitHead": "6b8696766d576ca51d075c40dff0441f35089c84"
73
+ }