UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

142 lines 3.4 kB
import React, { Fragment } from 'react'; import InlineLink from "./internal/InlineLink.js"; import CodeEl from "../elements/Code.js"; import { jsx as _jsx } from "react/jsx-runtime"; const Strong = c => _jsx("strong", { children: c }); const Em = c => _jsx("em", { children: c }); const Code = c => _jsx(CodeEl, { children: c }); const Link = (c, href) => _jsx(InlineLink, { href: href, rel: "noopener noreferrer", children: c }); export default function renderWithFormatting(text, { br = '{br}', strong = Strong, em = Em, link = Link, code = Code } = {}) { if (typeof text === 'string') { const HAS_MARKERS_RE = /(`[^`]+`|\[[^\]]+\]\([^)\s]+\)|\bhttps?:\/\/[^\s<>()]+|\*\*[^*]+\*\*|_[^_]+_)/; const hasFormatting = br && text.includes(br) || HAS_MARKERS_RE.test(text); if (!hasFormatting) { return text; } } return withFormatting(text, { strong, em, br, link, code }); } function withFormatting(text, { br, strong, em, link, code }) { let nodes = Array.isArray(text) ? text : [text]; nodes = splitToken(nodes, br, ({ k }) => _jsx("br", {}, k())); const codeRe = /(`[^`]+`)/g; nodes = replaceInStrings(nodes, codeRe, (m, { k }) => [_jsx(Fragment, { children: code(m[0].slice(1, -1)) }, `c-${k()}`)]); const linkRe = /\[([^\]]+)\]\(([^)\s]+)\)/g; nodes = replaceInStrings(nodes, linkRe, (m, { k }) => { const [, label, href] = m; const children = withFormatting(label, { br, strong, em, link, code }); return [_jsx(Fragment, { children: link(children, href) }, `a-${k()}`)]; }); const bareUrlRe = /\b((?:https?:\/\/)[^\s<>()]+)\b/g; nodes = replaceInStrings(nodes, bareUrlRe, (m, { k }) => { const href = m[1]; return [_jsx(Fragment, { children: link(href, href) }, `l-${k()}`)]; }); const boldRe = /\*\*([^*]+)\*\*/g; nodes = replaceInStrings(nodes, boldRe, (m, { k }) => [_jsx(Fragment, { children: strong(m[1]) }, `b-${k()}`)]); const italicRe = /_([^_]+)_/g; nodes = replaceInStrings(nodes, italicRe, (m, { k }) => [_jsx(Fragment, { children: em(m[1]) }, `i-${k()}`)]); return _jsx(Fragment, { children: nodes }, "renderWithFormatting"); } function replaceInStrings(nodes, re, replacer) { let key = 0; const k = () => String(key++); return nodes.flatMap((n, i) => { if (typeof n !== 'string') return [n]; const out = []; let last = 0; let m; while ((m = re.exec(n)) !== null) { const before = n.slice(last, m.index); if (before) out.push(before); out.push(...replacer(m, { i, k })); last = m.index + m[0].length; if (re.lastIndex === m.index) re.lastIndex++; } const tail = n.slice(last); if (tail) out.push(tail); return out; }); } function splitToken(nodes, token, make) { let key = 0; const k = () => String(key++); return nodes.flatMap((n, i) => { if (typeof n !== 'string') return [n]; const parts = n.split(token); const out = []; parts.forEach((chunk, idx) => { if (chunk) out.push(chunk); if (idx < parts.length - 1) out.push(_jsx(Fragment, { children: make({ i, idx, k }) }, k())); }); return out; }); } //# sourceMappingURL=renderWithFormatting.js.map