Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 19x 6x 1x 38x 31x 31x 31x 31x 31x 31x 31x 31x 28x 14x 14x 31x 14x 26x 31x 25x 25x 25x 25x | import type {JsonMlNode} from './types'; const escapeText = (str: string): string => str.replace(/[\u00A0-\u9999<>\&]/gim, (i) => '&#' + i.charCodeAt(0) + ';'); const escapeAttr = (str: string): string => str.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<'); export const toHtml = (node: JsonMlNode, tab: string = '', ident: string = ''): string => { if (typeof node === 'string') return ident + escapeText(node); const [tag, attrs, ...children] = node; const childrenLength = children.length; const isFragment = !tag; const childrenIdent = ident + (isFragment ? '' : tab); const doIdent = !!tab; let childrenStr = ''; let textOnlyChildren = true; for (let i = 0; i < childrenLength; i++) if (typeof children[i] !== 'string') { textOnlyChildren = false; break; } if (textOnlyChildren) for (let i = 0; i < childrenLength; i++) childrenStr += escapeText(children[i] as string); else for (let i = 0; i < childrenLength; i++) childrenStr += (doIdent ? (!isFragment || i ? '\n' : '') : '') + toHtml(children[i], tab, childrenIdent); if (isFragment) return childrenStr; let attrStr = ''; if (attrs) for (const key in attrs) attrStr += ' ' + key + '="' + escapeAttr(attrs[key] + '') + '"'; const htmlHead = '<' + tag + attrStr; return ( ident + (childrenStr ? htmlHead + '>' + childrenStr + (doIdent && !textOnlyChildren ? '\n' + ident : '') + '</' + tag + '>' : htmlHead + ' />') ); }; |