@longform/longform 0.0.1 → 0.0.2
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/README.md +11 -8
- package/dist/longform.js +6 -6
- package/dist/longform.js.gz +0 -0
- package/dist/longform.js.map +2 -2
- package/dist/longform.min.js +3 -3
- package/dist/longform.min.js.gz +0 -0
- package/dist/longform.min.js.map +2 -2
- package/lib/longform.test.ts +28 -0
- package/lib/longform.ts +8 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
# Longform
|
|
2
2
|
|
|
3
3
|
<b class=keyword>Longform</b> is an easy to read markup and templating
|
|
4
|
-
language that outputs to <b class=keyword>HTML</b
|
|
4
|
+
language that outputs to <b class=keyword>HTML</b>.
|
|
5
5
|
A longform document can be parsed to a complete document in the output format
|
|
6
6
|
or as fragments to be used by a application as a source of markup when generating a
|
|
7
7
|
document, or when manipulating DOM in a browser environment.
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
This repo contains the Longform language specification and a light weight Longform
|
|
11
|
-
parser implemented for server rendering of HTML
|
|
11
|
+
parser implemented for server rendering of HTML documents and client side
|
|
12
12
|
templating if required. Both the Longform language and parser are a work in progress.
|
|
13
|
-
You can view more on what language features are currently supported in the Github
|
|
14
|
-
milestones.
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
Read more about the Longform language in the <a href="https://occultist-dev.github.io/longform">Longform Markup Language document</a>.
|
|
@@ -21,7 +19,6 @@ Read more about the Longform language in the <a href="https://occultist-dev.gith
|
|
|
21
19
|
|
|
22
20
|
```
|
|
23
21
|
npm install @longform/longform
|
|
24
|
-
deno install jsr:@longform/longform
|
|
25
22
|
```
|
|
26
23
|
|
|
27
24
|
## Usage
|
|
@@ -34,19 +31,25 @@ html::
|
|
|
34
31
|
title:: Example Longform
|
|
35
32
|
body::
|
|
36
33
|
h1:: Example Longform
|
|
34
|
+
#[fragment2]
|
|
37
35
|
|
|
38
36
|
#fragment1
|
|
39
37
|
div::
|
|
40
38
|
p::
|
|
41
39
|
This is a Longform fragment referencable by it's identifier.
|
|
40
|
+
|
|
41
|
+
#fragment2
|
|
42
|
+
div::
|
|
43
|
+
p::
|
|
44
|
+
This fragment will be embedded in the fragment that references it.
|
|
42
45
|
`;
|
|
43
46
|
|
|
44
|
-
const
|
|
47
|
+
const result = longform(markup);
|
|
45
48
|
|
|
46
49
|
// outputs the root fragment as HTML
|
|
47
|
-
console.log(
|
|
50
|
+
console.log(result.root);
|
|
48
51
|
|
|
49
52
|
// outputs fragment1 as HTML
|
|
50
|
-
console.log(fragments.fragment1.
|
|
53
|
+
console.log(result.fragments.fragment1.html);
|
|
51
54
|
```
|
|
52
55
|
|
package/dist/longform.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi, element1 = /((?:\ \ )+)? ?([\w\-]+(?::[\w\-]+)?)([#\.\[][^\n]*)?::(?: ({{?|[^\n]+))?/gmi, directive1 = /((?:\ \ )+)? ?@([\w][\w\-]+)(?::: ?([^\n]+)?)?/gmi, attribute1 = /((?:\ \ )+)\[(\w[\w-]*(?::\w[\w-]*)?)(?:=([^\n]+))?\]/, preformattedClose = /[ \t]*}}?[ \t]*/, id1 = /((?:\ \ )+)?#(#)?([\w\-]+)(?: ([\["]))?/gmi, idnt1 = /^(\ \ )+/, text1 = /^((?:\ \ )+)([^ \n][^\n]*)$/i, paramsRe = /(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g, refRe = /#\[([\w\-]+)\]/g, escapeRe = /([&<>"'#\[\]{}])/g, templateLinesRe = /^(\ \ )?([^\n]
|
|
1
|
+
const sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi, element1 = /((?:\ \ )+)? ?([\w\-]+(?::[\w\-]+)?)([#\.\[][^\n]*)?::(?: ({{?|[^\n]+))?/gmi, directive1 = /((?:\ \ )+)? ?@([\w][\w\-]+)(?::: ?([^\n]+)?)?/gmi, attribute1 = /((?:\ \ )+)\[(\w[\w-]*(?::\w[\w-]*)?)(?:=([^\n]+))?\]/, preformattedClose = /[ \t]*}}?[ \t]*/, id1 = /((?:\ \ )+)?#(#)?([\w\-]+)(?: ([\["]))?/gmi, idnt1 = /^(\ \ )+/, text1 = /^((?:\ \ )+)([^ \n][^\n]*)$/i, paramsRe = /(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g, refRe = /#\[([\w\-]+)\]/g, escapeRe = /([&<>"'#\[\]{}])/g, templateLinesRe = /^(\ \ )?([^\n]+)$/gmi, voids = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wrb"]);
|
|
2
2
|
let m1, m2, m3;
|
|
3
3
|
const entities = {
|
|
4
4
|
"&": "&",
|
|
@@ -276,20 +276,20 @@ export function longform(doc, debug = () => {
|
|
|
276
276
|
fragment.template = indent === 0;
|
|
277
277
|
templateLinesRe.lastIndex = sniffTestRe.lastIndex;
|
|
278
278
|
while (m2 = templateLinesRe.exec(doc)) {
|
|
279
|
-
if (m2[1] == null && !indented) {
|
|
279
|
+
if (m2[1] == null && !indented && fragment.id == null) {
|
|
280
280
|
id1.lastIndex = 0;
|
|
281
281
|
m3 = id1.exec(m2[0]);
|
|
282
|
-
fragment.id = m3[3];
|
|
282
|
+
if (m3 != null) fragment.id = m3[3];
|
|
283
283
|
fragment.html += m2[0];
|
|
284
284
|
} else if (m2[1] == null && indented) {
|
|
285
|
-
sniffTestRe.lastIndex = templateLinesRe.lastIndex -
|
|
286
|
-
applyIndent(0);
|
|
285
|
+
sniffTestRe.lastIndex = templateLinesRe.lastIndex - m2[0].length;
|
|
287
286
|
break;
|
|
288
287
|
} else {
|
|
289
288
|
fragment.html += "\n" + m2[0];
|
|
289
|
+
if (m2[1] != null) indented = true;
|
|
290
290
|
}
|
|
291
|
-
indented = true;
|
|
292
291
|
}
|
|
292
|
+
applyIndent(0);
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
break;
|
package/dist/longform.js.gz
CHANGED
|
Binary file
|
package/dist/longform.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../lib/longform.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ChunkType, FragmentType, ParsedResult, WorkingChunk, WorkingElement, WorkingFragment, Fragment } from \"./types.ts\";\n\nexport type {\n FragmentType,\n Fragment,\n ParsedResult\n};\n\nconst sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\\w\\-]+(?::[\\w\\-]+)?(?:[#.[][^\\n]+)?(::).*)|(?: +([\\[\"]).*)|(\\ \\ .*))$/gmi\n , element1 = /((?:\\ \\ )+)? ?([\\w\\-]+(?::[\\w\\-]+)?)([#\\.\\[][^\\n]*)?::(?: ({{?|[^\\n]+))?/gmi\n , directive1 = /((?:\\ \\ )+)? ?@([\\w][\\w\\-]+)(?::: ?([^\\n]+)?)?/gmi\n , attribute1 = /((?:\\ \\ )+)\\[(\\w[\\w-]*(?::\\w[\\w-]*)?)(?:=([^\\n]+))?\\]/\n , preformattedClose = /[ \\t]*}}?[ \\t]*/\n , id1 = /((?:\\ \\ )+)?#(#)?([\\w\\-]+)(?: ([\\[\"]))?/gmi\n , idnt1 = /^(\\ \\ )+/\n , text1 = /^((?:\\ \\ )+)([^ \\n][^\\n]*)$/i\n , paramsRe = /(?:(#|\\.)([^#.\\[\\n]+)|(?:\\[(\\w[\\w\\-]*(?::\\w[\\w\\-]*)?)(?:=([^\\n\\]]+))?\\]))/g\n , refRe = /#\\[([\\w\\-]+)\\]/g\n , escapeRe = /([&<>\"'#\\[\\]{}])/g\n , templateLinesRe = /^(\\ \\ )?([^\\n]*)$/gmi\n , voids = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wrb']);\n\nlet m1: RegExpExecArray | null\n , m2: RegExpExecArray | null\n , m3: RegExpExecArray | null;\n\nconst entities = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n// '#': '#',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '}',\n// '}': '{',\n};\n\nfunction escape(value: string): string {\n return value.replace(escapeRe, (match) => {\n return entities[match] ?? match;\n });\n}\n\nfunction makeElement(indent: number = 0): WorkingElement {\n return {\n indent,\n html: '',\n attrs: {},\n };\n}\n\nfunction makeChunk(type: ChunkType = 'parsed'): WorkingChunk {\n return {\n type,\n html: '',\n els: [],\n };\n}\n\nfunction makeFragment(type: FragmentType = 'bare'): WorkingFragment {\n return {\n type,\n html: '',\n template: false,\n els: [],\n chunks: [],\n refs: [],\n };\n}\n\n/**\n * Parses a longform document into a object containing the root and fragments\n * in the output format.\n *\n * @param {string} doc - The longform document to parse.\n * @returns {ParsedResult}\n */\nexport function longform(doc: string, debug: (...d: unknown[]) => void = () => {}): ParsedResult {\n let skipping: boolean = false\n , textIndent: number | null = null\n , verbatimSerialize: boolean = true\n , verbatimIndent: number | null = null\n , verbatimFirst: boolean = false\n , element: WorkingElement = makeElement()\n , chunk: WorkingChunk | null = makeChunk()\n , fragment: WorkingFragment = makeFragment()\n // the root fragment\n , root: WorkingFragment | null = null\n // ids of claimed fragments\n const claimed: Set<string> = new Set()\n // parsed fragments\n , parsed: Map<string, WorkingFragment> = new Map()\n , output: ParsedResult = Object.create(null);\n\n output.fragments = Object.create(null);\n output.templates = Object.create(null);\n \n \n /**\n * Closes any current in progress element definition\n * and creates a new working element.\n */\n function applyIndent(targetIndent: number) {\n if (element.tag != null) {\n const root = fragment.type === 'range'\n ? targetIndent < 2\n : fragment.html === ''\n ;\n\n fragment.html += `<${element.tag}`\n\n if (root) {\n if (fragment.type === 'root') {\n fragment.html += ` data-lf-root`;\n } else if (fragment.type === 'bare' || fragment.type === 'range') {\n fragment.html += ` data-lf=\"${fragment.id}\"`;\n }\n }\n\n if (element.id != null) {\n fragment.html += ' id=\"' + element.id + '\"';\n }\n\n if (element.class != null) {\n fragment.html += ' class=\"' + element.class + '\"';\n }\n\n for (const attr of Object.entries(element.attrs)) {\n if (attr[1] == null) {\n fragment.html += ' ' + attr[0]\n } else {\n fragment.html += ` ${attr[0]}=\"${attr[1]}\"`;\n }\n }\n\n fragment.html += '>';\n\n if (!voids.has(element.tag as string) && element.text != null) {\n fragment.html += element.text;\n }\n\n if (\n !voids.has(element.tag as string)\n ) {\n fragment.els.push(element);\n }\n }\n\n if (targetIndent <= element.indent) {\n element = makeElement(targetIndent);\n\n while (\n fragment.els.length !== 0 && (\n targetIndent == null ||\n fragment.els[fragment.els.length - 1].indent !== targetIndent - 1\n )\n ) {\n const element = fragment.els.pop();\n\n fragment.html += `</${element?.tag}>`;\n }\n\n if (targetIndent === 0) {\n debug(0, '<', fragment.type, fragment.id);\n if (fragment.template) {\n output.templates[fragment.id] = fragment.html;\n } else if (fragment.type === 'root') {\n root = fragment;\n } else {\n parsed.set(fragment.id, fragment);\n }\n\n fragment = makeFragment();\n }\n } else {\n element = makeElement(targetIndent)\n }\n }\n\n while ((m1 = sniffTestRe.exec(doc))) {\n if (m1[1] === '--') {\n continue;\n } else if (fragment.template) {\n fragment.html += m1[0];\n }\n\n // If this is a script tag or preformatted block\n // we want to retain the intended formatting less\n // the indent. Preformatting can apply to any element\n // by ending the declaration with `:: {`.\n if (verbatimIndent != null) {\n // inside a script or preformatted block\n idnt1.lastIndex = 0;\n m2 = idnt1.exec(m1[0]);\n const indent = m2 == null\n ? null\n : m2[0].length / 2;\n\n if (m2 == null || indent as number <= verbatimIndent) {\n fragment.html += '\\n';\n debug(indent, '}', m2?.[0]);\n\n applyIndent(indent);\n verbatimIndent = null;\n verbatimFirst = false;\n textIndent = indent;\n\n if (preformattedClose.test(m1[0])) {\n continue;\n }\n } else {\n const line = m1[0].replace(' '.repeat(verbatimIndent + 1), '');\n debug(indent, '{', line);\n\n if (element.tag != null) {\n applyIndent(indent as number);\n }\n\n if (verbatimFirst) {\n verbatimFirst = false;\n } else {\n fragment.html += '\\n';\n }\n \n if (verbatimSerialize) {\n fragment.html += escape(line);\n } else {\n fragment.html += line;\n }\n\n continue;\n }\n }\n\n if (m1[0].trim() === '') {\n continue;\n }\n\n switch (m1[2] ?? m1[3] ?? m1[4]) {\n // deno-lint-ignore no-fallthrough\n case '#': {\n id1.lastIndex = 0;\n m2 = id1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n textIndent = null;\n }\n\n debug(indent, 'id', m2[2], m2[3], m2[4]);\n\n fragment.id = m2[3];\n\n if (indent === 0) {\n if (m2[4] == '[') {\n fragment.type = 'range';\n } else if (m2[4] === '\"') {\n fragment.type = 'text';\n } else if (m2[2] != null) {\n fragment.type = 'bare';\n } else {\n fragment.type = 'embed';\n element.id = fragment.id;\n }\n }\n\n break;\n }\n }\n case '@':\n case '[':\n // deno-lint-ignore no-fallthrough\n case '::': {\n element1.lastIndex = 0;\n // fall through if m1[3] is a # or @\n m2 = m1[2] ?? m1[4] != null\n ? null\n : element1.exec(m1[0]);\n\n // if null then invalid element selector\n // allow the default text case to handle\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2\n , tg = m2[2]\n , ar = m2[3]\n , pr = m2[4] === '{' || m2[4] === '{{'\n const tx = pr ? null : m2[4]\n\n debug(indent, 'e', tg, pr, tx);\n\n if (\n element.tag != null ||\n element.indent > indent\n ) {\n applyIndent(indent);\n }\n\n element.indent = indent;\n element.tag = tg;\n\n textIndent = null;\n \n if (indent === 0 && fragment.id == null) {\n if (root != null) {\n skipping = true;\n } else {\n fragment.type = 'root';\n root = fragment;\n }\n }\n \n if (ar != null) {\n debug(indent, 'a', ar);\n while ((m2 = paramsRe.exec(ar))) {\n if (m2[1] === '#') {\n element.id = m2[2];\n } else if (m2[1] === '.') {\n if (element.class == null) {\n element.class = m2[2];\n } else {\n element.class += ' ' + m2[2];\n }\n } else {\n if (m2[3] === 'id') {\n if (element.id == null) {\n element.id = m2[4];\n }\n } else if (m2[3] === 'class') {\n if (element.class == null) {\n element.class = m2[4]\n } else {\n element.class += ' ' + m2[4]\n }\n } else {\n element.attrs[m2[3]] = m2[4];\n }\n }\n }\n }\n\n if (!pr && tx != null) {\n element.text = tx;\n } else if (pr) {\n verbatimFirst = true;\n verbatimIndent = indent;\n verbatimSerialize = m2[4] === '{';\n }\n\n break;\n }\n\n attribute1.lastIndex = 0;\n m2 = m1[2] != null\n ? null\n : attribute1.exec(m1[0]);\n\n if (m2 != null && element.tag != null) {\n debug('a', m2[2], m2[3]);\n\n if (m2[2] === 'id') {\n if (element.id == null) {\n element.id = m2[3].trim();\n }\n } else if (m2[2] === 'class') {\n if (element.class != null) {\n element.class += ' ' + m2[3].trim();\n } else {\n element.class = m2[3].trim();\n }\n } else if (element.attrs[m2[2]] != null) {\n element.attrs[m2[2]] += m2[3];\n } else {\n element.attrs[m2[2]] = m2[3];\n }\n\n break;\n }\n\n directive1.lastIndex = 0;\n m2 = m1[3] != null\n ? null \n : directive1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n }\n\n debug(indent, 'd', m2[2], m2[3]);\n\n switch (m2[2]) {\n case 'doctype': {\n fragment.html += `<!doctype ${m2[3] ?? 'html'}>`;\n break;\n }\n case 'xml': {\n fragment.html += `<?xml ${m2[3] ?? 'version=\"1.0\" encoding=\"UTF-8\"'}?>`;\n break;\n }\n case 'template': {\n let indented = false;\n fragment.template = indent === 0;\n\n templateLinesRe.lastIndex = sniffTestRe.lastIndex;\n while ((m2 = templateLinesRe.exec(doc))) {\n if (m2[1] == null && !indented) {\n id1.lastIndex = 0;\n m3 = id1.exec(m2[0]);\n\n fragment.id = m3[3];\n fragment.html += m2[0];\n } else if (m2[1] == null && indented) {\n sniffTestRe.lastIndex = templateLinesRe.lastIndex - 1;\n applyIndent(0)\n break;\n } else {\n fragment.html += '\\n' + m2[0];\n }\n indented = true;\n }\n }\n }\n\n break;\n }\n\n }\n default: {\n m2 = text1.exec(m1[0]) as RegExpExecArray;\n\n if (m2 == null) {\n break;\n }\n const indent = m2[1].length / 2;\n const tx = m2[2].trim();\n\n debug(indent, 't', m2[2]);\n\n if (element.tag != null) {\n applyIndent(indent);\n\n fragment.html += tx;\n } else if (fragment.type === 'text' && fragment.html === '') {\n fragment.html += tx;\n } else {\n fragment.html += ' ' + tx;\n }\n\n textIndent = indent;\n\n while ((m2 = refRe.exec(tx))) {\n const start = fragment.html.length + m2.index - tx.length;\n\n fragment.refs.push({\n id: m2[1],\n start,\n end: start + m2[0].length,\n });\n }\n\n break;\n }\n }\n }\n\n applyIndent(0);\n\n const arr = Array.from(parsed.values());\n\n function flatten(fragment: WorkingFragment): WorkingFragment {\n // work backwards so we don't change the html string length\n // for the later replacements\n for (let j = fragment.refs.length - 1; j >= 0; j--) {\n const ref = fragment.refs[j];\n\n if (claimed.has(ref.id) || !parsed.has(ref.id)) {\n fragment.html = fragment.html.slice(0, ref.start)\n + fragment.html.slice(ref.end)\n } else {\n const child = flatten(parsed.get(ref.id));\n\n fragment.html = fragment.html.slice(0, ref.start)\n + child.html\n + fragment.html.slice(ref.end);\n\n if (child.type === 'embed') {\n claimed.add(child.id)\n }\n }\n }\n\n fragment.refs = [];\n\n return fragment;\n }\n\n for (let i = 0; i < parsed.size + 1; i++) {\n let fragment: WorkingFragment;\n \n if (i === 0 && root == null) {\n continue;\n } else if (i === 0) {\n fragment = root;\n } else {\n fragment = arr[i - 1];\n }\n\n if (fragment.refs.length === 0) {\n continue;\n }\n\n flatten(fragment)\n }\n\n if (root?.html != null) {\n output.root = root.html;\n output.selector = `[data-lf-root]`;\n }\n\n for (let i = 0; i < arr.length; i++) {\n let selector: string;\n const fragment = arr[i];\n\n if (fragment == null || claimed.has(fragment.id)) {\n continue;\n }\n\n if (fragment.type === 'embed') {\n selector = `[id=${fragment.id}]`;\n } else if (fragment.type === 'bare') {\n selector = `[data-lf=${fragment.id}]`;\n } else if (fragment.type === 'range') {\n selector = `[data-lf=${fragment.id}]`;\n }\n\n output.fragments[fragment.id] = {\n id: fragment.id,\n selector,\n type: fragment.type as 'embed' | 'bare' | 'range',\n html: fragment.html,\n };\n }\n\n return output;\n}\n\n\nconst templateRe = /(?:#{([\\w][\\w\\-_]*)})|(?:#\\[([\\w][\\w\\-_]+)\\])/g;\n\n/**\n * Processes a client side Longform template to HTML fragment string.\n *\n * @param fragment - The fragment identifier.\n * @param args - A record of template arguments.\n * @param getFragment - A function which returns an already processed fragment's HTML string.\n * @returns The processed template.\n */\nexport function processTemplate(\n template: string,\n args: Record<string, string | number>,\n getFragment: (fragment: string) => string | undefined,\n): string | undefined {\n const lf = template.replace(templateRe, (_match, param, ref) => {\n if (ref != null) {\n const fragment = getFragment(ref);\n\n if (fragment == null) return '';\n\n return fragment;\n }\n \n return args[param] != null ? escape(args[param].toString()) : '';\n });\n\n return Object.values(longform(lf).fragments)[0]?.html ?? null;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import type { ChunkType, FragmentType, ParsedResult, WorkingChunk, WorkingElement, WorkingFragment, Fragment } from \"./types.ts\";\n\nexport type {\n FragmentType,\n Fragment,\n ParsedResult\n};\n\nconst sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\\w\\-]+(?::[\\w\\-]+)?(?:[#.[][^\\n]+)?(::).*)|(?: +([\\[\"]).*)|(\\ \\ .*))$/gmi\n , element1 = /((?:\\ \\ )+)? ?([\\w\\-]+(?::[\\w\\-]+)?)([#\\.\\[][^\\n]*)?::(?: ({{?|[^\\n]+))?/gmi\n , directive1 = /((?:\\ \\ )+)? ?@([\\w][\\w\\-]+)(?::: ?([^\\n]+)?)?/gmi\n , attribute1 = /((?:\\ \\ )+)\\[(\\w[\\w-]*(?::\\w[\\w-]*)?)(?:=([^\\n]+))?\\]/\n , preformattedClose = /[ \\t]*}}?[ \\t]*/\n , id1 = /((?:\\ \\ )+)?#(#)?([\\w\\-]+)(?: ([\\[\"]))?/gmi\n , idnt1 = /^(\\ \\ )+/\n , text1 = /^((?:\\ \\ )+)([^ \\n][^\\n]*)$/i\n , paramsRe = /(?:(#|\\.)([^#.\\[\\n]+)|(?:\\[(\\w[\\w\\-]*(?::\\w[\\w\\-]*)?)(?:=([^\\n\\]]+))?\\]))/g\n , refRe = /#\\[([\\w\\-]+)\\]/g\n , escapeRe = /([&<>\"'#\\[\\]{}])/g\n , templateLinesRe = /^(\\ \\ )?([^\\n]+)$/gmi\n , voids = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wrb']);\n\nlet m1: RegExpExecArray | null\n , m2: RegExpExecArray | null\n , m3: RegExpExecArray | null;\n\nconst entities = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n// '#': '#',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '}',\n// '}': '{',\n};\n\nfunction escape(value: string): string {\n return value.replace(escapeRe, (match) => {\n return entities[match] ?? match;\n });\n}\n\nfunction makeElement(indent: number = 0): WorkingElement {\n return {\n indent,\n html: '',\n attrs: {},\n };\n}\n\nfunction makeChunk(type: ChunkType = 'parsed'): WorkingChunk {\n return {\n type,\n html: '',\n els: [],\n };\n}\n\nfunction makeFragment(type: FragmentType = 'bare'): WorkingFragment {\n return {\n type,\n html: '',\n template: false,\n els: [],\n chunks: [],\n refs: [],\n };\n}\n\n/**\n * Parses a longform document into a object containing the root and fragments\n * in the output format.\n *\n * @param {string} doc - The longform document to parse.\n * @returns {ParsedResult}\n */\nexport function longform(doc: string, debug: (...d: unknown[]) => void = () => {}): ParsedResult {\n let skipping: boolean = false\n , textIndent: number | null = null\n , verbatimSerialize: boolean = true\n , verbatimIndent: number | null = null\n , verbatimFirst: boolean = false\n , element: WorkingElement = makeElement()\n , chunk: WorkingChunk | null = makeChunk()\n , fragment: WorkingFragment = makeFragment()\n // the root fragment\n , root: WorkingFragment | null = null\n // ids of claimed fragments\n const claimed: Set<string> = new Set()\n // parsed fragments\n , parsed: Map<string, WorkingFragment> = new Map()\n , output: ParsedResult = Object.create(null);\n\n output.fragments = Object.create(null);\n output.templates = Object.create(null);\n \n \n /**\n * Closes any current in progress element definition\n * and creates a new working element.\n */\n function applyIndent(targetIndent: number) {\n if (element.tag != null) {\n const root = fragment.type === 'range'\n ? targetIndent < 2\n : fragment.html === ''\n ;\n\n fragment.html += `<${element.tag}`\n\n if (root) {\n if (fragment.type === 'root') {\n fragment.html += ` data-lf-root`;\n } else if (fragment.type === 'bare' || fragment.type === 'range') {\n fragment.html += ` data-lf=\"${fragment.id}\"`;\n }\n }\n\n if (element.id != null) {\n fragment.html += ' id=\"' + element.id + '\"';\n }\n\n if (element.class != null) {\n fragment.html += ' class=\"' + element.class + '\"';\n }\n\n for (const attr of Object.entries(element.attrs)) {\n if (attr[1] == null) {\n fragment.html += ' ' + attr[0]\n } else {\n fragment.html += ` ${attr[0]}=\"${attr[1]}\"`;\n }\n }\n\n fragment.html += '>';\n\n if (!voids.has(element.tag as string) && element.text != null) {\n fragment.html += element.text;\n }\n\n if (\n !voids.has(element.tag as string)\n ) {\n fragment.els.push(element);\n }\n }\n\n if (targetIndent <= element.indent) {\n element = makeElement(targetIndent);\n\n while (\n fragment.els.length !== 0 && (\n targetIndent == null ||\n fragment.els[fragment.els.length - 1].indent !== targetIndent - 1\n )\n ) {\n const element = fragment.els.pop();\n\n fragment.html += `</${element?.tag}>`;\n }\n\n if (targetIndent === 0) {\n debug(0, '<', fragment.type, fragment.id);\n if (fragment.template) {\n output.templates[fragment.id] = fragment.html;\n } else if (fragment.type === 'root') {\n root = fragment;\n } else {\n parsed.set(fragment.id, fragment);\n }\n\n fragment = makeFragment();\n }\n } else {\n element = makeElement(targetIndent)\n }\n }\n\n while ((m1 = sniffTestRe.exec(doc))) {\n if (m1[1] === '--') {\n continue;\n } else if (fragment.template) {\n fragment.html += m1[0];\n }\n\n // If this is a script tag or preformatted block\n // we want to retain the intended formatting less\n // the indent. Preformatting can apply to any element\n // by ending the declaration with `:: {`.\n if (verbatimIndent != null) {\n // inside a script or preformatted block\n idnt1.lastIndex = 0;\n m2 = idnt1.exec(m1[0]);\n const indent = m2 == null\n ? null\n : m2[0].length / 2;\n\n if (m2 == null || indent as number <= verbatimIndent) {\n fragment.html += '\\n';\n debug(indent, '}', m2?.[0]);\n\n applyIndent(indent);\n verbatimIndent = null;\n verbatimFirst = false;\n textIndent = indent;\n\n if (preformattedClose.test(m1[0])) {\n continue;\n }\n } else {\n const line = m1[0].replace(' '.repeat(verbatimIndent + 1), '');\n debug(indent, '{', line);\n\n if (element.tag != null) {\n applyIndent(indent as number);\n }\n\n if (verbatimFirst) {\n verbatimFirst = false;\n } else {\n fragment.html += '\\n';\n }\n \n if (verbatimSerialize) {\n fragment.html += escape(line);\n } else {\n fragment.html += line;\n }\n\n continue;\n }\n }\n\n if (m1[0].trim() === '') {\n continue;\n }\n\n switch (m1[2] ?? m1[3] ?? m1[4]) {\n // deno-lint-ignore no-fallthrough\n case '#': {\n id1.lastIndex = 0;\n m2 = id1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n textIndent = null;\n }\n\n debug(indent, 'id', m2[2], m2[3], m2[4]);\n\n fragment.id = m2[3];\n\n if (indent === 0) {\n if (m2[4] == '[') {\n fragment.type = 'range';\n } else if (m2[4] === '\"') {\n fragment.type = 'text';\n } else if (m2[2] != null) {\n fragment.type = 'bare';\n } else {\n fragment.type = 'embed';\n element.id = fragment.id;\n }\n }\n\n break;\n }\n }\n case '@':\n case '[':\n // deno-lint-ignore no-fallthrough\n case '::': {\n element1.lastIndex = 0;\n // fall through if m1[3] is a # or @\n m2 = m1[2] ?? m1[4] != null\n ? null\n : element1.exec(m1[0]);\n\n // if null then invalid element selector\n // allow the default text case to handle\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2\n , tg = m2[2]\n , ar = m2[3]\n , pr = m2[4] === '{' || m2[4] === '{{'\n const tx = pr ? null : m2[4]\n\n debug(indent, 'e', tg, pr, tx);\n\n if (\n element.tag != null ||\n element.indent > indent\n ) {\n applyIndent(indent);\n }\n\n element.indent = indent;\n element.tag = tg;\n\n textIndent = null;\n \n if (indent === 0 && fragment.id == null) {\n if (root != null) {\n skipping = true;\n } else {\n fragment.type = 'root';\n root = fragment;\n }\n }\n \n if (ar != null) {\n debug(indent, 'a', ar);\n while ((m2 = paramsRe.exec(ar))) {\n if (m2[1] === '#') {\n element.id = m2[2];\n } else if (m2[1] === '.') {\n if (element.class == null) {\n element.class = m2[2];\n } else {\n element.class += ' ' + m2[2];\n }\n } else {\n if (m2[3] === 'id') {\n if (element.id == null) {\n element.id = m2[4];\n }\n } else if (m2[3] === 'class') {\n if (element.class == null) {\n element.class = m2[4]\n } else {\n element.class += ' ' + m2[4]\n }\n } else {\n element.attrs[m2[3]] = m2[4];\n }\n }\n }\n }\n\n if (!pr && tx != null) {\n element.text = tx;\n } else if (pr) {\n verbatimFirst = true;\n verbatimIndent = indent;\n verbatimSerialize = m2[4] === '{';\n }\n\n break;\n }\n\n attribute1.lastIndex = 0;\n m2 = m1[2] != null\n ? null\n : attribute1.exec(m1[0]);\n\n if (m2 != null && element.tag != null) {\n debug('a', m2[2], m2[3]);\n\n if (m2[2] === 'id') {\n if (element.id == null) {\n element.id = m2[3].trim();\n }\n } else if (m2[2] === 'class') {\n if (element.class != null) {\n element.class += ' ' + m2[3].trim();\n } else {\n element.class = m2[3].trim();\n }\n } else if (element.attrs[m2[2]] != null) {\n element.attrs[m2[2]] += m2[3];\n } else {\n element.attrs[m2[2]] = m2[3];\n }\n\n break;\n }\n\n directive1.lastIndex = 0;\n m2 = m1[3] != null\n ? null \n : directive1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n }\n\n debug(indent, 'd', m2[2], m2[3]);\n\n switch (m2[2]) {\n case 'doctype': {\n fragment.html += `<!doctype ${m2[3] ?? 'html'}>`;\n break;\n }\n case 'xml': {\n fragment.html += `<?xml ${m2[3] ?? 'version=\"1.0\" encoding=\"UTF-8\"'}?>`;\n break;\n }\n case 'template': {\n let indented = false;\n fragment.template = indent === 0;\n\n templateLinesRe.lastIndex = sniffTestRe.lastIndex;\n while ((m2 = templateLinesRe.exec(doc))) {\n if (m2[1] == null && !indented && fragment.id == null) {\n id1.lastIndex = 0;\n m3 = id1.exec(m2[0]);\n\n if (m3 != null) fragment.id = m3[3];\n\n fragment.html += m2[0];\n } else if (m2[1] == null && indented) {\n sniffTestRe.lastIndex = templateLinesRe.lastIndex - m2[0].length;\n break;\n } else {\n fragment.html += '\\n' + m2[0];\n if (m2[1] != null) indented = true;\n }\n }\n\n applyIndent(0);\n }\n }\n\n break;\n }\n\n }\n default: {\n m2 = text1.exec(m1[0]) as RegExpExecArray;\n\n if (m2 == null) {\n break;\n }\n const indent = m2[1].length / 2;\n const tx = m2[2].trim();\n\n debug(indent, 't', m2[2]);\n\n if (element.tag != null) {\n applyIndent(indent);\n\n fragment.html += tx;\n } else if (fragment.type === 'text' && fragment.html === '') {\n fragment.html += tx;\n } else {\n fragment.html += ' ' + tx;\n }\n\n textIndent = indent;\n\n while ((m2 = refRe.exec(tx))) {\n const start = fragment.html.length + m2.index - tx.length;\n\n fragment.refs.push({\n id: m2[1],\n start,\n end: start + m2[0].length,\n });\n }\n\n break;\n }\n }\n }\n\n applyIndent(0);\n\n const arr = Array.from(parsed.values());\n\n function flatten(fragment: WorkingFragment): WorkingFragment {\n // work backwards so we don't change the html string length\n // for the later replacements\n for (let j = fragment.refs.length - 1; j >= 0; j--) {\n const ref = fragment.refs[j];\n\n if (claimed.has(ref.id) || !parsed.has(ref.id)) {\n fragment.html = fragment.html.slice(0, ref.start)\n + fragment.html.slice(ref.end)\n } else {\n const child = flatten(parsed.get(ref.id));\n\n fragment.html = fragment.html.slice(0, ref.start)\n + child.html\n + fragment.html.slice(ref.end);\n\n if (child.type === 'embed') {\n claimed.add(child.id)\n }\n }\n }\n\n fragment.refs = [];\n\n return fragment;\n }\n\n for (let i = 0; i < parsed.size + 1; i++) {\n let fragment: WorkingFragment;\n \n if (i === 0 && root == null) {\n continue;\n } else if (i === 0) {\n fragment = root;\n } else {\n fragment = arr[i - 1];\n }\n\n if (fragment.refs.length === 0) {\n continue;\n }\n\n flatten(fragment)\n }\n\n if (root?.html != null) {\n output.root = root.html;\n output.selector = `[data-lf-root]`;\n }\n\n for (let i = 0; i < arr.length; i++) {\n let selector: string;\n const fragment = arr[i];\n\n if (fragment == null || claimed.has(fragment.id)) {\n continue;\n }\n\n if (fragment.type === 'embed') {\n selector = `[id=${fragment.id}]`;\n } else if (fragment.type === 'bare') {\n selector = `[data-lf=${fragment.id}]`;\n } else if (fragment.type === 'range') {\n selector = `[data-lf=${fragment.id}]`;\n }\n\n output.fragments[fragment.id] = {\n id: fragment.id,\n selector,\n type: fragment.type as 'embed' | 'bare' | 'range',\n html: fragment.html,\n };\n }\n\n return output;\n}\n\n\nconst templateRe = /(?:#{([\\w][\\w\\-_]*)})|(?:#\\[([\\w][\\w\\-_]+)\\])/g;\n\n/**\n * Processes a client side Longform template to HTML fragment string.\n *\n * @param fragment - The fragment identifier.\n * @param args - A record of template arguments.\n * @param getFragment - A function which returns an already processed fragment's HTML string.\n * @returns The processed template.\n */\nexport function processTemplate(\n template: string,\n args: Record<string, string | number>,\n getFragment: (fragment: string) => string | undefined,\n): string | undefined {\n const lf = template.replace(templateRe, (_match, param, ref) => {\n if (ref != null) {\n const fragment = getFragment(ref);\n\n if (fragment == null) return '';\n\n return fragment;\n }\n \n return args[param] != null ? escape(args[param].toString()) : '';\n });\n\n return Object.values(longform(lf).fragments)[0]?.html ?? null;\n}\n"],
|
|
5
|
+
"mappings": "AAQA,MAAM,cAAc,gHAChB,WAAW,+EACX,aAAa,qDACb,aAAa,yDACb,oBAAoB,mBACpB,MAAM,8CACN,QAAQ,YACR,QAAQ,gCACR,WAAW,8EACX,QAAQ,mBACR,WAAW,qBACX,kBAAkB,wBAClB,QAAQ,oBAAI,IAAI,CAAC,QAAQ,QAAQ,MAAM,OAAO,SAAS,MAAM,OAAO,SAAS,QAAQ,QAAQ,SAAS,UAAU,SAAS,KAAK,CAAC;AAEnI,IAAI,IACA,IACA;AAEJ,MAAM,WAAW;AAAA,EACf,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAMP;AAEA,SAAS,OAAO,OAAuB;AACrC,SAAO,MAAM,QAAQ,UAAU,CAAC,UAAU;AAxC5C;AAyCI,YAAO,cAAS,KAAK,MAAd,YAAmB;AAAA,EAC5B,CAAC;AACH;AAEA,SAAS,YAAY,SAAiB,GAAmB;AACvD,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,OAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,UAAU,OAAkB,UAAwB;AAC3D,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,KAAK,CAAC;AAAA,EACR;AACF;AAEA,SAAS,aAAa,OAAqB,QAAyB;AAClE,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,KAAK,CAAC;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,MAAM,CAAC;AAAA,EACT;AACF;AASO,gBAAS,SAAS,KAAa,QAAmC,MAAM;AAAC,GAAiB;AA/EjG;AAgFE,MAAI,WAAoB,OACpB,aAA4B,MAC5B,oBAA6B,MAC7B,iBAAgC,MAChC,gBAAyB,OACzB,UAA0B,YAAY,GACtC,QAA6B,UAAU,GACvC,WAA4B,aAAa,GAEzC,OAA+B;AAEnC,QAAM,UAAuB,oBAAI,IAAI,GAEjC,SAAuC,oBAAI,IAAI,GAC/C,SAAuB,uBAAO,OAAO,IAAI;AAE7C,SAAO,YAAY,uBAAO,OAAO,IAAI;AACrC,SAAO,YAAY,uBAAO,OAAO,IAAI;AAOrC,WAAS,YAAY,cAAsB;AACzC,QAAI,QAAQ,OAAO,MAAM;AACvB,YAAMA,QAAO,SAAS,SAAS,UAC3B,eAAe,IACf,SAAS,SAAS;AAGtB,eAAS,QAAQ,IAAI,QAAQ,GAAG;AAEhC,UAAIA,OAAM;AACR,YAAI,SAAS,SAAS,QAAQ;AAC5B,mBAAS,QAAQ;AAAA,QACnB,WAAW,SAAS,SAAS,UAAU,SAAS,SAAS,SAAS;AAChE,mBAAS,QAAQ,aAAa,SAAS,EAAE;AAAA,QAC3C;AAAA,MACF;AAEA,UAAI,QAAQ,MAAM,MAAM;AACtB,iBAAS,QAAQ,UAAU,QAAQ,KAAK;AAAA,MAC1C;AAEA,UAAI,QAAQ,SAAS,MAAM;AACzB,iBAAS,QAAQ,aAAa,QAAQ,QAAQ;AAAA,MAChD;AAEA,iBAAW,QAAQ,OAAO,QAAQ,QAAQ,KAAK,GAAG;AAChD,YAAI,KAAK,CAAC,KAAK,MAAM;AACnB,mBAAS,QAAQ,MAAM,KAAK,CAAC;AAAA,QAC/B,OAAO;AACL,mBAAS,QAAQ,IAAI,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;AAAA,QAC1C;AAAA,MACF;AAEA,eAAS,QAAQ;AAEjB,UAAI,CAAC,MAAM,IAAI,QAAQ,GAAa,KAAK,QAAQ,QAAQ,MAAM;AAC7D,iBAAS,QAAQ,QAAQ;AAAA,MAC3B;AAEA,UACE,CAAC,MAAM,IAAI,QAAQ,GAAa,GAChC;AACA,iBAAS,IAAI,KAAK,OAAO;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,gBAAgB,QAAQ,QAAQ;AAClC,gBAAU,YAAY,YAAY;AAElC,aACE,SAAS,IAAI,WAAW,MACtB,gBAAgB,QAChB,SAAS,IAAI,SAAS,IAAI,SAAS,CAAC,EAAE,WAAW,eAAe,IAElE;AACA,cAAMC,WAAU,SAAS,IAAI,IAAI;AAEjC,iBAAS,QAAQ,KAAKA,YAAA,gBAAAA,SAAS,GAAG;AAAA,MACpC;AAEA,UAAI,iBAAiB,GAAG;AACtB,cAAM,GAAG,KAAK,SAAS,MAAM,SAAS,EAAE;AACxC,YAAI,SAAS,UAAU;AACrB,iBAAO,UAAU,SAAS,EAAE,IAAI,SAAS;AAAA,QAC3C,WAAW,SAAS,SAAS,QAAQ;AACnC,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO,IAAI,SAAS,IAAI,QAAQ;AAAA,QAClC;AAEA,mBAAW,aAAa;AAAA,MAC1B;AAAA,IACF,OAAO;AACL,gBAAU,YAAY,YAAY;AAAA,IACpC;AAAA,EACF;AAEA,SAAQ,KAAK,YAAY,KAAK,GAAG,GAAI;AACnC,QAAI,GAAG,CAAC,MAAM,MAAM;AAClB;AAAA,IACF,WAAW,SAAS,UAAU;AAC5B,eAAS,QAAQ,GAAG,CAAC;AAAA,IACvB;AAMA,QAAI,kBAAkB,MAAM;AAE1B,YAAM,YAAY;AAClB,WAAK,MAAM,KAAK,GAAG,CAAC,CAAC;AACrB,YAAM,SAAS,MAAM,OACjB,OACA,GAAG,CAAC,EAAE,SAAS;AAEnB,UAAI,MAAM,QAAQ,UAAoB,gBAAgB;AACpD,iBAAS,QAAQ;AACjB,cAAM,QAAQ,KAAK,yBAAK,EAAE;AAE1B,oBAAY,MAAM;AAClB,yBAAiB;AACjB,wBAAgB;AAChB,qBAAa;AAEb,YAAI,kBAAkB,KAAK,GAAG,CAAC,CAAC,GAAG;AACjC;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,KAAK,OAAO,iBAAiB,CAAC,GAAG,EAAE;AAC9D,cAAM,QAAQ,KAAK,IAAI;AAEvB,YAAI,QAAQ,OAAO,MAAM;AACvB,sBAAY,MAAgB;AAAA,QAC9B;AAEA,YAAI,eAAe;AACjB,0BAAgB;AAAA,QAClB,OAAO;AACL,mBAAS,QAAQ;AAAA,QACnB;AAEA,YAAI,mBAAmB;AACrB,mBAAS,QAAQ,OAAO,IAAI;AAAA,QAC9B,OAAO;AACL,mBAAS,QAAQ;AAAA,QACnB;AAEA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,GAAG,CAAC,EAAE,KAAK,MAAM,IAAI;AACvB;AAAA,IACF;AAEA,aAAQ,cAAG,CAAC,MAAJ,YAAS,GAAG,CAAC,MAAb,YAAkB,GAAG,CAAC,GAAG;AAAA;AAAA,MAE/B,KAAK,KAAK;AACR,YAAI,YAAY;AAChB,aAAK,IAAI,KAAK,GAAG,CAAC,CAAC;AAEnB,YAAI,MAAM,MAAM;AACd,gBAAM,WAAU,cAAG,CAAC,MAAJ,mBAAO,WAAP,YAAiB,KAAK;AAEtC,cAAI,QAAQ,OAAO,QAAQ,cAAc,MAAM;AAC7C,wBAAY,MAAM;AAClB,yBAAa;AAAA,UACf;AAEA,gBAAM,QAAQ,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAEvC,mBAAS,KAAK,GAAG,CAAC;AAElB,cAAI,WAAW,GAAG;AAChB,gBAAI,GAAG,CAAC,KAAK,KAAK;AAChB,uBAAS,OAAO;AAAA,YAClB,WAAW,GAAG,CAAC,MAAM,KAAK;AACxB,uBAAS,OAAO;AAAA,YAClB,WAAW,GAAG,CAAC,KAAK,MAAM;AACxB,uBAAS,OAAO;AAAA,YAClB,OAAO;AACL,uBAAS,OAAO;AAChB,sBAAQ,KAAK,SAAS;AAAA,YACxB;AAAA,UACF;AAEA;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA;AAAA,MAEL,KAAK,MAAM;AACT,iBAAS,YAAY;AAErB,eAAK,QAAG,CAAC,MAAJ,YAAS,GAAG,CAAC,KAAK,QAClB,OACA,SAAS,KAAK,GAAG,CAAC,CAAC;AAIxB,YAAI,MAAM,MAAM;AACd,gBAAM,WAAU,cAAG,CAAC,MAAJ,mBAAO,WAAP,YAAiB,KAAK,GAChC,KAAK,GAAG,CAAC,GACT,KAAK,GAAG,CAAC,GACT,KAAK,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC,MAAM;AACtC,gBAAM,KAAK,KAAK,OAAO,GAAG,CAAC;AAE3B,gBAAM,QAAQ,KAAK,IAAI,IAAI,EAAE;AAE7B,cACE,QAAQ,OAAO,QACf,QAAQ,SAAS,QACjB;AACA,wBAAY,MAAM;AAAA,UACpB;AAEA,kBAAQ,SAAS;AACjB,kBAAQ,MAAM;AAEd,uBAAa;AAEb,cAAI,WAAW,KAAK,SAAS,MAAM,MAAM;AACvC,gBAAI,QAAQ,MAAM;AAChB,yBAAW;AAAA,YACb,OAAO;AACL,uBAAS,OAAO;AAChB,qBAAO;AAAA,YACT;AAAA,UACF;AAEA,cAAI,MAAM,MAAM;AACd,kBAAM,QAAQ,KAAK,EAAE;AACrB,mBAAQ,KAAK,SAAS,KAAK,EAAE,GAAI;AAC/B,kBAAI,GAAG,CAAC,MAAM,KAAK;AACjB,wBAAQ,KAAK,GAAG,CAAC;AAAA,cACnB,WAAW,GAAG,CAAC,MAAM,KAAK;AACxB,oBAAI,QAAQ,SAAS,MAAM;AACzB,0BAAQ,QAAQ,GAAG,CAAC;AAAA,gBACtB,OAAO;AACL,0BAAQ,SAAS,MAAM,GAAG,CAAC;AAAA,gBAC7B;AAAA,cACF,OAAO;AACL,oBAAI,GAAG,CAAC,MAAM,MAAM;AAClB,sBAAI,QAAQ,MAAM,MAAM;AACtB,4BAAQ,KAAK,GAAG,CAAC;AAAA,kBACnB;AAAA,gBACF,WAAW,GAAG,CAAC,MAAM,SAAS;AAC5B,sBAAI,QAAQ,SAAS,MAAM;AACzB,4BAAQ,QAAQ,GAAG,CAAC;AAAA,kBACtB,OAAO;AACL,4BAAQ,SAAS,MAAM,GAAG,CAAC;AAAA,kBAC7B;AAAA,gBACF,OAAO;AACL,0BAAQ,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;AAAA,gBAC7B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,cAAI,CAAC,MAAM,MAAM,MAAM;AACrB,oBAAQ,OAAO;AAAA,UACjB,WAAW,IAAI;AACb,4BAAgB;AAChB,6BAAiB;AACjB,gCAAoB,GAAG,CAAC,MAAM;AAAA,UAChC;AAEA;AAAA,QACF;AAEA,mBAAW,YAAY;AACvB,aAAK,GAAG,CAAC,KAAK,OACT,OACA,WAAW,KAAK,GAAG,CAAC,CAAC;AAE1B,YAAI,MAAM,QAAQ,QAAQ,OAAO,MAAM;AACrC,gBAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAEvB,cAAI,GAAG,CAAC,MAAM,MAAM;AAClB,gBAAI,QAAQ,MAAM,MAAM;AACtB,sBAAQ,KAAK,GAAG,CAAC,EAAE,KAAK;AAAA,YAC1B;AAAA,UACF,WAAW,GAAG,CAAC,MAAM,SAAS;AAC5B,gBAAI,QAAQ,SAAS,MAAM;AACzB,sBAAQ,SAAS,MAAM,GAAG,CAAC,EAAE,KAAK;AAAA,YACpC,OAAO;AACL,sBAAQ,QAAQ,GAAG,CAAC,EAAE,KAAK;AAAA,YAC7B;AAAA,UACF,WAAW,QAAQ,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM;AACvC,oBAAQ,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;AAAA,UAC9B,OAAO;AACL,oBAAQ,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;AAAA,UAC7B;AAEA;AAAA,QACF;AAEA,mBAAW,YAAY;AACvB,aAAK,GAAG,CAAC,KAAK,OACR,OACA,WAAW,KAAK,GAAG,CAAC,CAAC;AAE3B,YAAI,MAAM,MAAM;AACd,gBAAM,WAAU,cAAG,CAAC,MAAJ,mBAAO,WAAP,YAAiB,KAAK;AAEtC,cAAI,QAAQ,OAAO,QAAQ,cAAc,MAAM;AAC7C,wBAAY,MAAM;AAAA,UACpB;AAEA,gBAAM,QAAQ,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAE/B,kBAAQ,GAAG,CAAC,GAAG;AAAA,YACb,KAAK,WAAW;AACd,uBAAS,QAAQ,cAAa,QAAG,CAAC,MAAJ,YAAS,MAAM;AAC7C;AAAA,YACF;AAAA,YACA,KAAK,OAAO;AACV,uBAAS,QAAQ,UAAS,QAAG,CAAC,MAAJ,YAAS,gCAAgC;AACnE;AAAA,YACF;AAAA,YACA,KAAK,YAAY;AACf,kBAAI,WAAW;AACf,uBAAS,WAAW,WAAW;AAE/B,8BAAgB,YAAY,YAAY;AACxC,qBAAQ,KAAK,gBAAgB,KAAK,GAAG,GAAI;AACvC,oBAAI,GAAG,CAAC,KAAK,QAAQ,CAAC,YAAY,SAAS,MAAM,MAAM;AACrD,sBAAI,YAAY;AAChB,uBAAK,IAAI,KAAK,GAAG,CAAC,CAAC;AAEnB,sBAAI,MAAM,KAAM,UAAS,KAAK,GAAG,CAAC;AAElC,2BAAS,QAAQ,GAAG,CAAC;AAAA,gBACvB,WAAW,GAAG,CAAC,KAAK,QAAQ,UAAU;AACpC,8BAAY,YAAY,gBAAgB,YAAY,GAAG,CAAC,EAAE;AAC1D;AAAA,gBACF,OAAO;AACL,2BAAS,QAAQ,OAAO,GAAG,CAAC;AAC5B,sBAAI,GAAG,CAAC,KAAK,KAAM,YAAW;AAAA,gBAChC;AAAA,cACF;AAEA,0BAAY,CAAC;AAAA,YACf;AAAA,UACF;AAEA;AAAA,QACF;AAAA,MAEF;AAAA,MACA,SAAS;AACP,aAAK,MAAM,KAAK,GAAG,CAAC,CAAC;AAErB,YAAI,MAAM,MAAM;AACd;AAAA,QACF;AACA,cAAM,SAAS,GAAG,CAAC,EAAE,SAAS;AAC9B,cAAM,KAAK,GAAG,CAAC,EAAE,KAAK;AAEtB,cAAM,QAAQ,KAAK,GAAG,CAAC,CAAC;AAExB,YAAI,QAAQ,OAAO,MAAM;AACvB,sBAAY,MAAM;AAElB,mBAAS,QAAQ;AAAA,QACnB,WAAW,SAAS,SAAS,UAAU,SAAS,SAAS,IAAI;AAC3D,mBAAS,QAAQ;AAAA,QACnB,OAAO;AACL,mBAAS,QAAQ,MAAM;AAAA,QACzB;AAEA,qBAAa;AAEb,eAAQ,KAAK,MAAM,KAAK,EAAE,GAAI;AAC5B,gBAAM,QAAQ,SAAS,KAAK,SAAS,GAAG,QAAQ,GAAG;AAEnD,mBAAS,KAAK,KAAK;AAAA,YACjB,IAAI,GAAG,CAAC;AAAA,YACR;AAAA,YACA,KAAK,QAAQ,GAAG,CAAC,EAAE;AAAA,UACrB,CAAC;AAAA,QACH;AAEA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,cAAY,CAAC;AAEb,QAAM,MAAM,MAAM,KAAK,OAAO,OAAO,CAAC;AAEtC,WAAS,QAAQC,WAA4C;AAG3D,aAAS,IAAIA,UAAS,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AAClD,YAAM,MAAMA,UAAS,KAAK,CAAC;AAE3B,UAAI,QAAQ,IAAI,IAAI,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE,GAAG;AAC9C,QAAAA,UAAS,OAAOA,UAAS,KAAK,MAAM,GAAG,IAAI,KAAK,IAC5CA,UAAS,KAAK,MAAM,IAAI,GAAG;AAAA,MACjC,OAAO;AACL,cAAM,QAAQ,QAAQ,OAAO,IAAI,IAAI,EAAE,CAAC;AAExC,QAAAA,UAAS,OAAOA,UAAS,KAAK,MAAM,GAAG,IAAI,KAAK,IAC5C,MAAM,OACNA,UAAS,KAAK,MAAM,IAAI,GAAG;AAE/B,YAAI,MAAM,SAAS,SAAS;AAC1B,kBAAQ,IAAI,MAAM,EAAE;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,IAAAA,UAAS,OAAO,CAAC;AAEjB,WAAOA;AAAA,EACT;AAEA,WAAS,IAAI,GAAG,IAAI,OAAO,OAAO,GAAG,KAAK;AACxC,QAAIA;AAEJ,QAAI,MAAM,KAAK,QAAQ,MAAM;AAC3B;AAAA,IACF,WAAW,MAAM,GAAG;AAClB,MAAAA,YAAW;AAAA,IACb,OAAO;AACL,MAAAA,YAAW,IAAI,IAAI,CAAC;AAAA,IACtB;AAEA,QAAIA,UAAS,KAAK,WAAW,GAAG;AAC9B;AAAA,IACF;AAEA,YAAQA,SAAQ;AAAA,EAClB;AAEA,OAAI,6BAAM,SAAQ,MAAM;AACtB,WAAO,OAAO,KAAK;AACnB,WAAO,WAAW;AAAA,EACpB;AAEA,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,QAAI;AACJ,UAAMA,YAAW,IAAI,CAAC;AAEtB,QAAIA,aAAY,QAAQ,QAAQ,IAAIA,UAAS,EAAE,GAAG;AAChD;AAAA,IACF;AAEA,QAAIA,UAAS,SAAS,SAAS;AAC7B,iBAAW,OAAOA,UAAS,EAAE;AAAA,IAC/B,WAAWA,UAAS,SAAS,QAAQ;AACnC,iBAAW,YAAYA,UAAS,EAAE;AAAA,IACpC,WAAWA,UAAS,SAAS,SAAS;AACpC,iBAAW,YAAYA,UAAS,EAAE;AAAA,IACpC;AAEA,WAAO,UAAUA,UAAS,EAAE,IAAI;AAAA,MAC9B,IAAIA,UAAS;AAAA,MACb;AAAA,MACA,MAAMA,UAAS;AAAA,MACf,MAAMA,UAAS;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AACT;AAGA,MAAM,aAAa;AAUZ,gBAAS,gBACd,UACA,MACA,aACoB;AA1jBtB;AA2jBE,QAAM,KAAK,SAAS,QAAQ,YAAY,CAAC,QAAQ,OAAO,QAAQ;AAC9D,QAAI,OAAO,MAAM;AACf,YAAM,WAAW,YAAY,GAAG;AAEhC,UAAI,YAAY,KAAM,QAAO;AAE7B,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,KAAK,KAAK,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,CAAC,IAAI;AAAA,EAChE,CAAC;AAED,UAAO,kBAAO,OAAO,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC,MAAvC,mBAA0C,SAA1C,YAAkD;AAC3D;",
|
|
6
6
|
"names": ["root", "element", "fragment"]
|
|
7
7
|
}
|
package/dist/longform.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const W=/^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi,
|
|
1
|
+
const W=/^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi,L=/((?:\ \ )+)? ?([\w\-]+(?::[\w\-]+)?)([#\.\[][^\n]*)?::(?: ({{?|[^\n]+))?/gmi,U=/((?:\ \ )+)? ?@([\w][\w\-]+)(?::: ?([^\n]+)?)?/gmi,B=/((?:\ \ )+)\[(\w[\w-]*(?::\w[\w-]*)?)(?:=([^\n]+))?\]/,K=/[ \t]*}}?[ \t]*/,y=/((?:\ \ )+)?#(#)?([\w\-]+)(?: ([\["]))?/gmi,D=/^(\ \ )+/,N=/^((?:\ \ )+)([^ \n][^\n]*)$/i,Q=/(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g,V=/#\[([\w\-]+)\]/g,X=/([&<>"'#\[\]{}])/g,$=/^(\ \ )?([^\n]+)$/gmi,G=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wrb"]);let r,e,E;const Y={"&":"&","<":"<",">":">",'"':""","'":"'"};function H(u){return u.replace(X,a=>{var g;return(g=Y[a])!=null?g:a})}function v(u=0){return{indent:u,html:"",attrs:{}}}function Z(u="parsed"){return{type:u,html:"",els:[]}}function J(u="bare"){return{type:u,html:"",template:!1,els:[],chunks:[],refs:[]}}export function longform(u,a=()=>{}){var C,I,j,A,O,S,P,_,z,M,q;let g=!1,f=null,p=!0,c=null,x=!1,n=v(),b=Z(),l=J(),m=null;const w=new Set,k=new Map,h=Object.create(null);h.fragments=Object.create(null),h.templates=Object.create(null);function o(t){if(n.tag!=null){const i=l.type==="range"?t<2:l.html==="";l.html+=`<${n.tag}`,i&&(l.type==="root"?l.html+=" data-lf-root":(l.type==="bare"||l.type==="range")&&(l.html+=` data-lf="${l.id}"`)),n.id!=null&&(l.html+=' id="'+n.id+'"'),n.class!=null&&(l.html+=' class="'+n.class+'"');for(const s of Object.entries(n.attrs))s[1]==null?l.html+=" "+s[0]:l.html+=` ${s[0]}="${s[1]}"`;l.html+=">",!G.has(n.tag)&&n.text!=null&&(l.html+=n.text),G.has(n.tag)||l.els.push(n)}if(t<=n.indent){for(n=v(t);l.els.length!==0&&(t==null||l.els[l.els.length-1].indent!==t-1);){const i=l.els.pop();l.html+=`</${i==null?void 0:i.tag}>`}t===0&&(a(0,"<",l.type,l.id),l.template?h.templates[l.id]=l.html:l.type==="root"?m=l:k.set(l.id,l),l=J())}else n=v(t)}for(;r=W.exec(u);)if(r[1]!=="--"){if(l.template&&(l.html+=r[0]),c!=null){D.lastIndex=0,e=D.exec(r[0]);const t=e==null?null:e[0].length/2;if(e==null||t<=c){if(l.html+=`
|
|
2
2
|
`,a(t,"}",e==null?void 0:e[0]),o(t),c=null,x=!1,f=t,K.test(r[0]))continue}else{const i=r[0].replace(" ".repeat(c+1),"");a(t,"{",i),n.tag!=null&&o(t),x?x=!1:l.html+=`
|
|
3
|
-
`,p?l.html+=H(i):l.html+=i;continue}}if(r[0].trim()!=="")switch((
|
|
4
|
-
`+e[0]
|
|
3
|
+
`,p?l.html+=H(i):l.html+=i;continue}}if(r[0].trim()!=="")switch((I=(C=r[2])!=null?C:r[3])!=null?I:r[4]){case"#":if(y.lastIndex=0,e=y.exec(r[0]),e!=null){const t=((A=(j=e[1])==null?void 0:j.length)!=null?A:0)/2;(n.tag!=null||f!=null)&&(o(t),f=null),a(t,"id",e[2],e[3],e[4]),l.id=e[3],t===0&&(e[4]=="["?l.type="range":e[4]==='"'?l.type="text":e[2]!=null?l.type="bare":(l.type="embed",n.id=l.id));break}case"@":case"[":case"::":{if(L.lastIndex=0,e=((O=r[2])!=null?O:r[4]!=null)?null:L.exec(r[0]),e!=null){const t=((P=(S=e[1])==null?void 0:S.length)!=null?P:0)/2,i=e[2],s=e[3],d=e[4]==="{"||e[4]==="{{",R=d?null:e[4];if(a(t,"e",i,d,R),(n.tag!=null||n.indent>t)&&o(t),n.indent=t,n.tag=i,f=null,t===0&&l.id==null&&(m!=null?g=!0:(l.type="root",m=l)),s!=null)for(a(t,"a",s);e=Q.exec(s);)e[1]==="#"?n.id=e[2]:e[1]==="."?n.class==null?n.class=e[2]:n.class+=" "+e[2]:e[3]==="id"?n.id==null&&(n.id=e[4]):e[3]==="class"?n.class==null?n.class=e[4]:n.class+=" "+e[4]:n.attrs[e[3]]=e[4];!d&&R!=null?n.text=R:d&&(x=!0,c=t,p=e[4]==="{");break}if(B.lastIndex=0,e=r[2]!=null?null:B.exec(r[0]),e!=null&&n.tag!=null){a("a",e[2],e[3]),e[2]==="id"?n.id==null&&(n.id=e[3].trim()):e[2]==="class"?n.class!=null?n.class+=" "+e[3].trim():n.class=e[3].trim():n.attrs[e[2]]!=null?n.attrs[e[2]]+=e[3]:n.attrs[e[2]]=e[3];break}if(U.lastIndex=0,e=r[3]!=null?null:U.exec(r[0]),e!=null){const t=((z=(_=e[1])==null?void 0:_.length)!=null?z:0)/2;switch((n.tag!=null||f!=null)&&o(t),a(t,"d",e[2],e[3]),e[2]){case"doctype":{l.html+=`<!doctype ${(M=e[3])!=null?M:"html"}>`;break}case"xml":{l.html+=`<?xml ${(q=e[3])!=null?q:'version="1.0" encoding="UTF-8"'}?>`;break}case"template":{let i=!1;for(l.template=t===0,$.lastIndex=W.lastIndex;e=$.exec(u);)if(e[1]==null&&!i&&l.id==null)y.lastIndex=0,E=y.exec(e[0]),E!=null&&(l.id=E[3]),l.html+=e[0];else if(e[1]==null&&i){W.lastIndex=$.lastIndex-e[0].length;break}else l.html+=`
|
|
4
|
+
`+e[0],e[1]!=null&&(i=!0);o(0)}}break}}default:{if(e=N.exec(r[0]),e==null)break;const t=e[1].length/2,i=e[2].trim();for(a(t,"t",e[2]),n.tag!=null?(o(t),l.html+=i):l.type==="text"&&l.html===""?l.html+=i:l.html+=" "+i,f=t;e=V.exec(i);){const s=l.html.length+e.index-i.length;l.refs.push({id:e[1],start:s,end:s+e[0].length})}break}}}o(0);const F=Array.from(k.values());function T(t){for(let i=t.refs.length-1;i>=0;i--){const s=t.refs[i];if(w.has(s.id)||!k.has(s.id))t.html=t.html.slice(0,s.start)+t.html.slice(s.end);else{const d=T(k.get(s.id));t.html=t.html.slice(0,s.start)+d.html+t.html.slice(s.end),d.type==="embed"&&w.add(d.id)}}return t.refs=[],t}for(let t=0;t<k.size+1;t++){let i;t===0&&m==null||(t===0?i=m:i=F[t-1],i.refs.length!==0&&T(i))}(m==null?void 0:m.html)!=null&&(h.root=m.html,h.selector="[data-lf-root]");for(let t=0;t<F.length;t++){let i;const s=F[t];s==null||w.has(s.id)||(s.type==="embed"?i=`[id=${s.id}]`:s.type==="bare"?i=`[data-lf=${s.id}]`:s.type==="range"&&(i=`[data-lf=${s.id}]`),h.fragments[s.id]={id:s.id,selector:i,type:s.type,html:s.html})}return h}const ee=/(?:#{([\w][\w\-_]*)})|(?:#\[([\w][\w\-_]+)\])/g;export function processTemplate(u,a,g){var p,c;const f=u.replace(ee,(x,n,b)=>{if(b!=null){const l=g(b);return l==null?"":l}return a[n]!=null?H(a[n].toString()):""});return(c=(p=Object.values(longform(f).fragments)[0])==null?void 0:p.html)!=null?c:null}
|
|
5
5
|
//# sourceMappingURL=longform.min.js.map
|
package/dist/longform.min.js.gz
CHANGED
|
Binary file
|
package/dist/longform.min.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../lib/longform.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ChunkType, FragmentType, ParsedResult, WorkingChunk, WorkingElement, WorkingFragment, Fragment } from \"./types.ts\";\n\nexport type {\n FragmentType,\n Fragment,\n ParsedResult\n};\n\nconst sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\\w\\-]+(?::[\\w\\-]+)?(?:[#.[][^\\n]+)?(::).*)|(?: +([\\[\"]).*)|(\\ \\ .*))$/gmi\n , element1 = /((?:\\ \\ )+)? ?([\\w\\-]+(?::[\\w\\-]+)?)([#\\.\\[][^\\n]*)?::(?: ({{?|[^\\n]+))?/gmi\n , directive1 = /((?:\\ \\ )+)? ?@([\\w][\\w\\-]+)(?::: ?([^\\n]+)?)?/gmi\n , attribute1 = /((?:\\ \\ )+)\\[(\\w[\\w-]*(?::\\w[\\w-]*)?)(?:=([^\\n]+))?\\]/\n , preformattedClose = /[ \\t]*}}?[ \\t]*/\n , id1 = /((?:\\ \\ )+)?#(#)?([\\w\\-]+)(?: ([\\[\"]))?/gmi\n , idnt1 = /^(\\ \\ )+/\n , text1 = /^((?:\\ \\ )+)([^ \\n][^\\n]*)$/i\n , paramsRe = /(?:(#|\\.)([^#.\\[\\n]+)|(?:\\[(\\w[\\w\\-]*(?::\\w[\\w\\-]*)?)(?:=([^\\n\\]]+))?\\]))/g\n , refRe = /#\\[([\\w\\-]+)\\]/g\n , escapeRe = /([&<>\"'#\\[\\]{}])/g\n , templateLinesRe = /^(\\ \\ )?([^\\n]*)$/gmi\n , voids = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wrb']);\n\nlet m1: RegExpExecArray | null\n , m2: RegExpExecArray | null\n , m3: RegExpExecArray | null;\n\nconst entities = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n// '#': '#',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '}',\n// '}': '{',\n};\n\nfunction escape(value: string): string {\n return value.replace(escapeRe, (match) => {\n return entities[match] ?? match;\n });\n}\n\nfunction makeElement(indent: number = 0): WorkingElement {\n return {\n indent,\n html: '',\n attrs: {},\n };\n}\n\nfunction makeChunk(type: ChunkType = 'parsed'): WorkingChunk {\n return {\n type,\n html: '',\n els: [],\n };\n}\n\nfunction makeFragment(type: FragmentType = 'bare'): WorkingFragment {\n return {\n type,\n html: '',\n template: false,\n els: [],\n chunks: [],\n refs: [],\n };\n}\n\n/**\n * Parses a longform document into a object containing the root and fragments\n * in the output format.\n *\n * @param {string} doc - The longform document to parse.\n * @returns {ParsedResult}\n */\nexport function longform(doc: string, debug: (...d: unknown[]) => void = () => {}): ParsedResult {\n let skipping: boolean = false\n , textIndent: number | null = null\n , verbatimSerialize: boolean = true\n , verbatimIndent: number | null = null\n , verbatimFirst: boolean = false\n , element: WorkingElement = makeElement()\n , chunk: WorkingChunk | null = makeChunk()\n , fragment: WorkingFragment = makeFragment()\n // the root fragment\n , root: WorkingFragment | null = null\n // ids of claimed fragments\n const claimed: Set<string> = new Set()\n // parsed fragments\n , parsed: Map<string, WorkingFragment> = new Map()\n , output: ParsedResult = Object.create(null);\n\n output.fragments = Object.create(null);\n output.templates = Object.create(null);\n \n \n /**\n * Closes any current in progress element definition\n * and creates a new working element.\n */\n function applyIndent(targetIndent: number) {\n if (element.tag != null) {\n const root = fragment.type === 'range'\n ? targetIndent < 2\n : fragment.html === ''\n ;\n\n fragment.html += `<${element.tag}`\n\n if (root) {\n if (fragment.type === 'root') {\n fragment.html += ` data-lf-root`;\n } else if (fragment.type === 'bare' || fragment.type === 'range') {\n fragment.html += ` data-lf=\"${fragment.id}\"`;\n }\n }\n\n if (element.id != null) {\n fragment.html += ' id=\"' + element.id + '\"';\n }\n\n if (element.class != null) {\n fragment.html += ' class=\"' + element.class + '\"';\n }\n\n for (const attr of Object.entries(element.attrs)) {\n if (attr[1] == null) {\n fragment.html += ' ' + attr[0]\n } else {\n fragment.html += ` ${attr[0]}=\"${attr[1]}\"`;\n }\n }\n\n fragment.html += '>';\n\n if (!voids.has(element.tag as string) && element.text != null) {\n fragment.html += element.text;\n }\n\n if (\n !voids.has(element.tag as string)\n ) {\n fragment.els.push(element);\n }\n }\n\n if (targetIndent <= element.indent) {\n element = makeElement(targetIndent);\n\n while (\n fragment.els.length !== 0 && (\n targetIndent == null ||\n fragment.els[fragment.els.length - 1].indent !== targetIndent - 1\n )\n ) {\n const element = fragment.els.pop();\n\n fragment.html += `</${element?.tag}>`;\n }\n\n if (targetIndent === 0) {\n debug(0, '<', fragment.type, fragment.id);\n if (fragment.template) {\n output.templates[fragment.id] = fragment.html;\n } else if (fragment.type === 'root') {\n root = fragment;\n } else {\n parsed.set(fragment.id, fragment);\n }\n\n fragment = makeFragment();\n }\n } else {\n element = makeElement(targetIndent)\n }\n }\n\n while ((m1 = sniffTestRe.exec(doc))) {\n if (m1[1] === '--') {\n continue;\n } else if (fragment.template) {\n fragment.html += m1[0];\n }\n\n // If this is a script tag or preformatted block\n // we want to retain the intended formatting less\n // the indent. Preformatting can apply to any element\n // by ending the declaration with `:: {`.\n if (verbatimIndent != null) {\n // inside a script or preformatted block\n idnt1.lastIndex = 0;\n m2 = idnt1.exec(m1[0]);\n const indent = m2 == null\n ? null\n : m2[0].length / 2;\n\n if (m2 == null || indent as number <= verbatimIndent) {\n fragment.html += '\\n';\n debug(indent, '}', m2?.[0]);\n\n applyIndent(indent);\n verbatimIndent = null;\n verbatimFirst = false;\n textIndent = indent;\n\n if (preformattedClose.test(m1[0])) {\n continue;\n }\n } else {\n const line = m1[0].replace(' '.repeat(verbatimIndent + 1), '');\n debug(indent, '{', line);\n\n if (element.tag != null) {\n applyIndent(indent as number);\n }\n\n if (verbatimFirst) {\n verbatimFirst = false;\n } else {\n fragment.html += '\\n';\n }\n \n if (verbatimSerialize) {\n fragment.html += escape(line);\n } else {\n fragment.html += line;\n }\n\n continue;\n }\n }\n\n if (m1[0].trim() === '') {\n continue;\n }\n\n switch (m1[2] ?? m1[3] ?? m1[4]) {\n // deno-lint-ignore no-fallthrough\n case '#': {\n id1.lastIndex = 0;\n m2 = id1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n textIndent = null;\n }\n\n debug(indent, 'id', m2[2], m2[3], m2[4]);\n\n fragment.id = m2[3];\n\n if (indent === 0) {\n if (m2[4] == '[') {\n fragment.type = 'range';\n } else if (m2[4] === '\"') {\n fragment.type = 'text';\n } else if (m2[2] != null) {\n fragment.type = 'bare';\n } else {\n fragment.type = 'embed';\n element.id = fragment.id;\n }\n }\n\n break;\n }\n }\n case '@':\n case '[':\n // deno-lint-ignore no-fallthrough\n case '::': {\n element1.lastIndex = 0;\n // fall through if m1[3] is a # or @\n m2 = m1[2] ?? m1[4] != null\n ? null\n : element1.exec(m1[0]);\n\n // if null then invalid element selector\n // allow the default text case to handle\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2\n , tg = m2[2]\n , ar = m2[3]\n , pr = m2[4] === '{' || m2[4] === '{{'\n const tx = pr ? null : m2[4]\n\n debug(indent, 'e', tg, pr, tx);\n\n if (\n element.tag != null ||\n element.indent > indent\n ) {\n applyIndent(indent);\n }\n\n element.indent = indent;\n element.tag = tg;\n\n textIndent = null;\n \n if (indent === 0 && fragment.id == null) {\n if (root != null) {\n skipping = true;\n } else {\n fragment.type = 'root';\n root = fragment;\n }\n }\n \n if (ar != null) {\n debug(indent, 'a', ar);\n while ((m2 = paramsRe.exec(ar))) {\n if (m2[1] === '#') {\n element.id = m2[2];\n } else if (m2[1] === '.') {\n if (element.class == null) {\n element.class = m2[2];\n } else {\n element.class += ' ' + m2[2];\n }\n } else {\n if (m2[3] === 'id') {\n if (element.id == null) {\n element.id = m2[4];\n }\n } else if (m2[3] === 'class') {\n if (element.class == null) {\n element.class = m2[4]\n } else {\n element.class += ' ' + m2[4]\n }\n } else {\n element.attrs[m2[3]] = m2[4];\n }\n }\n }\n }\n\n if (!pr && tx != null) {\n element.text = tx;\n } else if (pr) {\n verbatimFirst = true;\n verbatimIndent = indent;\n verbatimSerialize = m2[4] === '{';\n }\n\n break;\n }\n\n attribute1.lastIndex = 0;\n m2 = m1[2] != null\n ? null\n : attribute1.exec(m1[0]);\n\n if (m2 != null && element.tag != null) {\n debug('a', m2[2], m2[3]);\n\n if (m2[2] === 'id') {\n if (element.id == null) {\n element.id = m2[3].trim();\n }\n } else if (m2[2] === 'class') {\n if (element.class != null) {\n element.class += ' ' + m2[3].trim();\n } else {\n element.class = m2[3].trim();\n }\n } else if (element.attrs[m2[2]] != null) {\n element.attrs[m2[2]] += m2[3];\n } else {\n element.attrs[m2[2]] = m2[3];\n }\n\n break;\n }\n\n directive1.lastIndex = 0;\n m2 = m1[3] != null\n ? null \n : directive1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n }\n\n debug(indent, 'd', m2[2], m2[3]);\n\n switch (m2[2]) {\n case 'doctype': {\n fragment.html += `<!doctype ${m2[3] ?? 'html'}>`;\n break;\n }\n case 'xml': {\n fragment.html += `<?xml ${m2[3] ?? 'version=\"1.0\" encoding=\"UTF-8\"'}?>`;\n break;\n }\n case 'template': {\n let indented = false;\n fragment.template = indent === 0;\n\n templateLinesRe.lastIndex = sniffTestRe.lastIndex;\n while ((m2 = templateLinesRe.exec(doc))) {\n if (m2[1] == null && !indented) {\n id1.lastIndex = 0;\n m3 = id1.exec(m2[0]);\n\n fragment.id = m3[3];\n fragment.html += m2[0];\n } else if (m2[1] == null && indented) {\n sniffTestRe.lastIndex = templateLinesRe.lastIndex - 1;\n applyIndent(0)\n break;\n } else {\n fragment.html += '\\n' + m2[0];\n }\n indented = true;\n }\n }\n }\n\n break;\n }\n\n }\n default: {\n m2 = text1.exec(m1[0]) as RegExpExecArray;\n\n if (m2 == null) {\n break;\n }\n const indent = m2[1].length / 2;\n const tx = m2[2].trim();\n\n debug(indent, 't', m2[2]);\n\n if (element.tag != null) {\n applyIndent(indent);\n\n fragment.html += tx;\n } else if (fragment.type === 'text' && fragment.html === '') {\n fragment.html += tx;\n } else {\n fragment.html += ' ' + tx;\n }\n\n textIndent = indent;\n\n while ((m2 = refRe.exec(tx))) {\n const start = fragment.html.length + m2.index - tx.length;\n\n fragment.refs.push({\n id: m2[1],\n start,\n end: start + m2[0].length,\n });\n }\n\n break;\n }\n }\n }\n\n applyIndent(0);\n\n const arr = Array.from(parsed.values());\n\n function flatten(fragment: WorkingFragment): WorkingFragment {\n // work backwards so we don't change the html string length\n // for the later replacements\n for (let j = fragment.refs.length - 1; j >= 0; j--) {\n const ref = fragment.refs[j];\n\n if (claimed.has(ref.id) || !parsed.has(ref.id)) {\n fragment.html = fragment.html.slice(0, ref.start)\n + fragment.html.slice(ref.end)\n } else {\n const child = flatten(parsed.get(ref.id));\n\n fragment.html = fragment.html.slice(0, ref.start)\n + child.html\n + fragment.html.slice(ref.end);\n\n if (child.type === 'embed') {\n claimed.add(child.id)\n }\n }\n }\n\n fragment.refs = [];\n\n return fragment;\n }\n\n for (let i = 0; i < parsed.size + 1; i++) {\n let fragment: WorkingFragment;\n \n if (i === 0 && root == null) {\n continue;\n } else if (i === 0) {\n fragment = root;\n } else {\n fragment = arr[i - 1];\n }\n\n if (fragment.refs.length === 0) {\n continue;\n }\n\n flatten(fragment)\n }\n\n if (root?.html != null) {\n output.root = root.html;\n output.selector = `[data-lf-root]`;\n }\n\n for (let i = 0; i < arr.length; i++) {\n let selector: string;\n const fragment = arr[i];\n\n if (fragment == null || claimed.has(fragment.id)) {\n continue;\n }\n\n if (fragment.type === 'embed') {\n selector = `[id=${fragment.id}]`;\n } else if (fragment.type === 'bare') {\n selector = `[data-lf=${fragment.id}]`;\n } else if (fragment.type === 'range') {\n selector = `[data-lf=${fragment.id}]`;\n }\n\n output.fragments[fragment.id] = {\n id: fragment.id,\n selector,\n type: fragment.type as 'embed' | 'bare' | 'range',\n html: fragment.html,\n };\n }\n\n return output;\n}\n\n\nconst templateRe = /(?:#{([\\w][\\w\\-_]*)})|(?:#\\[([\\w][\\w\\-_]+)\\])/g;\n\n/**\n * Processes a client side Longform template to HTML fragment string.\n *\n * @param fragment - The fragment identifier.\n * @param args - A record of template arguments.\n * @param getFragment - A function which returns an already processed fragment's HTML string.\n * @returns The processed template.\n */\nexport function processTemplate(\n template: string,\n args: Record<string, string | number>,\n getFragment: (fragment: string) => string | undefined,\n): string | undefined {\n const lf = template.replace(templateRe, (_match, param, ref) => {\n if (ref != null) {\n const fragment = getFragment(ref);\n\n if (fragment == null) return '';\n\n return fragment;\n }\n \n return args[param] != null ? escape(args[param].toString()) : '';\n });\n\n return Object.values(longform(lf).fragments)[0]?.html ?? null;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import type { ChunkType, FragmentType, ParsedResult, WorkingChunk, WorkingElement, WorkingFragment, Fragment } from \"./types.ts\";\n\nexport type {\n FragmentType,\n Fragment,\n ParsedResult\n};\n\nconst sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\\w\\-]+(?::[\\w\\-]+)?(?:[#.[][^\\n]+)?(::).*)|(?: +([\\[\"]).*)|(\\ \\ .*))$/gmi\n , element1 = /((?:\\ \\ )+)? ?([\\w\\-]+(?::[\\w\\-]+)?)([#\\.\\[][^\\n]*)?::(?: ({{?|[^\\n]+))?/gmi\n , directive1 = /((?:\\ \\ )+)? ?@([\\w][\\w\\-]+)(?::: ?([^\\n]+)?)?/gmi\n , attribute1 = /((?:\\ \\ )+)\\[(\\w[\\w-]*(?::\\w[\\w-]*)?)(?:=([^\\n]+))?\\]/\n , preformattedClose = /[ \\t]*}}?[ \\t]*/\n , id1 = /((?:\\ \\ )+)?#(#)?([\\w\\-]+)(?: ([\\[\"]))?/gmi\n , idnt1 = /^(\\ \\ )+/\n , text1 = /^((?:\\ \\ )+)([^ \\n][^\\n]*)$/i\n , paramsRe = /(?:(#|\\.)([^#.\\[\\n]+)|(?:\\[(\\w[\\w\\-]*(?::\\w[\\w\\-]*)?)(?:=([^\\n\\]]+))?\\]))/g\n , refRe = /#\\[([\\w\\-]+)\\]/g\n , escapeRe = /([&<>\"'#\\[\\]{}])/g\n , templateLinesRe = /^(\\ \\ )?([^\\n]+)$/gmi\n , voids = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wrb']);\n\nlet m1: RegExpExecArray | null\n , m2: RegExpExecArray | null\n , m3: RegExpExecArray | null;\n\nconst entities = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n// '#': '#',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '}',\n// '}': '{',\n};\n\nfunction escape(value: string): string {\n return value.replace(escapeRe, (match) => {\n return entities[match] ?? match;\n });\n}\n\nfunction makeElement(indent: number = 0): WorkingElement {\n return {\n indent,\n html: '',\n attrs: {},\n };\n}\n\nfunction makeChunk(type: ChunkType = 'parsed'): WorkingChunk {\n return {\n type,\n html: '',\n els: [],\n };\n}\n\nfunction makeFragment(type: FragmentType = 'bare'): WorkingFragment {\n return {\n type,\n html: '',\n template: false,\n els: [],\n chunks: [],\n refs: [],\n };\n}\n\n/**\n * Parses a longform document into a object containing the root and fragments\n * in the output format.\n *\n * @param {string} doc - The longform document to parse.\n * @returns {ParsedResult}\n */\nexport function longform(doc: string, debug: (...d: unknown[]) => void = () => {}): ParsedResult {\n let skipping: boolean = false\n , textIndent: number | null = null\n , verbatimSerialize: boolean = true\n , verbatimIndent: number | null = null\n , verbatimFirst: boolean = false\n , element: WorkingElement = makeElement()\n , chunk: WorkingChunk | null = makeChunk()\n , fragment: WorkingFragment = makeFragment()\n // the root fragment\n , root: WorkingFragment | null = null\n // ids of claimed fragments\n const claimed: Set<string> = new Set()\n // parsed fragments\n , parsed: Map<string, WorkingFragment> = new Map()\n , output: ParsedResult = Object.create(null);\n\n output.fragments = Object.create(null);\n output.templates = Object.create(null);\n \n \n /**\n * Closes any current in progress element definition\n * and creates a new working element.\n */\n function applyIndent(targetIndent: number) {\n if (element.tag != null) {\n const root = fragment.type === 'range'\n ? targetIndent < 2\n : fragment.html === ''\n ;\n\n fragment.html += `<${element.tag}`\n\n if (root) {\n if (fragment.type === 'root') {\n fragment.html += ` data-lf-root`;\n } else if (fragment.type === 'bare' || fragment.type === 'range') {\n fragment.html += ` data-lf=\"${fragment.id}\"`;\n }\n }\n\n if (element.id != null) {\n fragment.html += ' id=\"' + element.id + '\"';\n }\n\n if (element.class != null) {\n fragment.html += ' class=\"' + element.class + '\"';\n }\n\n for (const attr of Object.entries(element.attrs)) {\n if (attr[1] == null) {\n fragment.html += ' ' + attr[0]\n } else {\n fragment.html += ` ${attr[0]}=\"${attr[1]}\"`;\n }\n }\n\n fragment.html += '>';\n\n if (!voids.has(element.tag as string) && element.text != null) {\n fragment.html += element.text;\n }\n\n if (\n !voids.has(element.tag as string)\n ) {\n fragment.els.push(element);\n }\n }\n\n if (targetIndent <= element.indent) {\n element = makeElement(targetIndent);\n\n while (\n fragment.els.length !== 0 && (\n targetIndent == null ||\n fragment.els[fragment.els.length - 1].indent !== targetIndent - 1\n )\n ) {\n const element = fragment.els.pop();\n\n fragment.html += `</${element?.tag}>`;\n }\n\n if (targetIndent === 0) {\n debug(0, '<', fragment.type, fragment.id);\n if (fragment.template) {\n output.templates[fragment.id] = fragment.html;\n } else if (fragment.type === 'root') {\n root = fragment;\n } else {\n parsed.set(fragment.id, fragment);\n }\n\n fragment = makeFragment();\n }\n } else {\n element = makeElement(targetIndent)\n }\n }\n\n while ((m1 = sniffTestRe.exec(doc))) {\n if (m1[1] === '--') {\n continue;\n } else if (fragment.template) {\n fragment.html += m1[0];\n }\n\n // If this is a script tag or preformatted block\n // we want to retain the intended formatting less\n // the indent. Preformatting can apply to any element\n // by ending the declaration with `:: {`.\n if (verbatimIndent != null) {\n // inside a script or preformatted block\n idnt1.lastIndex = 0;\n m2 = idnt1.exec(m1[0]);\n const indent = m2 == null\n ? null\n : m2[0].length / 2;\n\n if (m2 == null || indent as number <= verbatimIndent) {\n fragment.html += '\\n';\n debug(indent, '}', m2?.[0]);\n\n applyIndent(indent);\n verbatimIndent = null;\n verbatimFirst = false;\n textIndent = indent;\n\n if (preformattedClose.test(m1[0])) {\n continue;\n }\n } else {\n const line = m1[0].replace(' '.repeat(verbatimIndent + 1), '');\n debug(indent, '{', line);\n\n if (element.tag != null) {\n applyIndent(indent as number);\n }\n\n if (verbatimFirst) {\n verbatimFirst = false;\n } else {\n fragment.html += '\\n';\n }\n \n if (verbatimSerialize) {\n fragment.html += escape(line);\n } else {\n fragment.html += line;\n }\n\n continue;\n }\n }\n\n if (m1[0].trim() === '') {\n continue;\n }\n\n switch (m1[2] ?? m1[3] ?? m1[4]) {\n // deno-lint-ignore no-fallthrough\n case '#': {\n id1.lastIndex = 0;\n m2 = id1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n textIndent = null;\n }\n\n debug(indent, 'id', m2[2], m2[3], m2[4]);\n\n fragment.id = m2[3];\n\n if (indent === 0) {\n if (m2[4] == '[') {\n fragment.type = 'range';\n } else if (m2[4] === '\"') {\n fragment.type = 'text';\n } else if (m2[2] != null) {\n fragment.type = 'bare';\n } else {\n fragment.type = 'embed';\n element.id = fragment.id;\n }\n }\n\n break;\n }\n }\n case '@':\n case '[':\n // deno-lint-ignore no-fallthrough\n case '::': {\n element1.lastIndex = 0;\n // fall through if m1[3] is a # or @\n m2 = m1[2] ?? m1[4] != null\n ? null\n : element1.exec(m1[0]);\n\n // if null then invalid element selector\n // allow the default text case to handle\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2\n , tg = m2[2]\n , ar = m2[3]\n , pr = m2[4] === '{' || m2[4] === '{{'\n const tx = pr ? null : m2[4]\n\n debug(indent, 'e', tg, pr, tx);\n\n if (\n element.tag != null ||\n element.indent > indent\n ) {\n applyIndent(indent);\n }\n\n element.indent = indent;\n element.tag = tg;\n\n textIndent = null;\n \n if (indent === 0 && fragment.id == null) {\n if (root != null) {\n skipping = true;\n } else {\n fragment.type = 'root';\n root = fragment;\n }\n }\n \n if (ar != null) {\n debug(indent, 'a', ar);\n while ((m2 = paramsRe.exec(ar))) {\n if (m2[1] === '#') {\n element.id = m2[2];\n } else if (m2[1] === '.') {\n if (element.class == null) {\n element.class = m2[2];\n } else {\n element.class += ' ' + m2[2];\n }\n } else {\n if (m2[3] === 'id') {\n if (element.id == null) {\n element.id = m2[4];\n }\n } else if (m2[3] === 'class') {\n if (element.class == null) {\n element.class = m2[4]\n } else {\n element.class += ' ' + m2[4]\n }\n } else {\n element.attrs[m2[3]] = m2[4];\n }\n }\n }\n }\n\n if (!pr && tx != null) {\n element.text = tx;\n } else if (pr) {\n verbatimFirst = true;\n verbatimIndent = indent;\n verbatimSerialize = m2[4] === '{';\n }\n\n break;\n }\n\n attribute1.lastIndex = 0;\n m2 = m1[2] != null\n ? null\n : attribute1.exec(m1[0]);\n\n if (m2 != null && element.tag != null) {\n debug('a', m2[2], m2[3]);\n\n if (m2[2] === 'id') {\n if (element.id == null) {\n element.id = m2[3].trim();\n }\n } else if (m2[2] === 'class') {\n if (element.class != null) {\n element.class += ' ' + m2[3].trim();\n } else {\n element.class = m2[3].trim();\n }\n } else if (element.attrs[m2[2]] != null) {\n element.attrs[m2[2]] += m2[3];\n } else {\n element.attrs[m2[2]] = m2[3];\n }\n\n break;\n }\n\n directive1.lastIndex = 0;\n m2 = m1[3] != null\n ? null \n : directive1.exec(m1[0]);\n\n if (m2 != null) {\n const indent = (m2[1]?.length ?? 0) / 2;\n\n if (element.tag != null || textIndent != null) {\n applyIndent(indent);\n }\n\n debug(indent, 'd', m2[2], m2[3]);\n\n switch (m2[2]) {\n case 'doctype': {\n fragment.html += `<!doctype ${m2[3] ?? 'html'}>`;\n break;\n }\n case 'xml': {\n fragment.html += `<?xml ${m2[3] ?? 'version=\"1.0\" encoding=\"UTF-8\"'}?>`;\n break;\n }\n case 'template': {\n let indented = false;\n fragment.template = indent === 0;\n\n templateLinesRe.lastIndex = sniffTestRe.lastIndex;\n while ((m2 = templateLinesRe.exec(doc))) {\n if (m2[1] == null && !indented && fragment.id == null) {\n id1.lastIndex = 0;\n m3 = id1.exec(m2[0]);\n\n if (m3 != null) fragment.id = m3[3];\n\n fragment.html += m2[0];\n } else if (m2[1] == null && indented) {\n sniffTestRe.lastIndex = templateLinesRe.lastIndex - m2[0].length;\n break;\n } else {\n fragment.html += '\\n' + m2[0];\n if (m2[1] != null) indented = true;\n }\n }\n\n applyIndent(0);\n }\n }\n\n break;\n }\n\n }\n default: {\n m2 = text1.exec(m1[0]) as RegExpExecArray;\n\n if (m2 == null) {\n break;\n }\n const indent = m2[1].length / 2;\n const tx = m2[2].trim();\n\n debug(indent, 't', m2[2]);\n\n if (element.tag != null) {\n applyIndent(indent);\n\n fragment.html += tx;\n } else if (fragment.type === 'text' && fragment.html === '') {\n fragment.html += tx;\n } else {\n fragment.html += ' ' + tx;\n }\n\n textIndent = indent;\n\n while ((m2 = refRe.exec(tx))) {\n const start = fragment.html.length + m2.index - tx.length;\n\n fragment.refs.push({\n id: m2[1],\n start,\n end: start + m2[0].length,\n });\n }\n\n break;\n }\n }\n }\n\n applyIndent(0);\n\n const arr = Array.from(parsed.values());\n\n function flatten(fragment: WorkingFragment): WorkingFragment {\n // work backwards so we don't change the html string length\n // for the later replacements\n for (let j = fragment.refs.length - 1; j >= 0; j--) {\n const ref = fragment.refs[j];\n\n if (claimed.has(ref.id) || !parsed.has(ref.id)) {\n fragment.html = fragment.html.slice(0, ref.start)\n + fragment.html.slice(ref.end)\n } else {\n const child = flatten(parsed.get(ref.id));\n\n fragment.html = fragment.html.slice(0, ref.start)\n + child.html\n + fragment.html.slice(ref.end);\n\n if (child.type === 'embed') {\n claimed.add(child.id)\n }\n }\n }\n\n fragment.refs = [];\n\n return fragment;\n }\n\n for (let i = 0; i < parsed.size + 1; i++) {\n let fragment: WorkingFragment;\n \n if (i === 0 && root == null) {\n continue;\n } else if (i === 0) {\n fragment = root;\n } else {\n fragment = arr[i - 1];\n }\n\n if (fragment.refs.length === 0) {\n continue;\n }\n\n flatten(fragment)\n }\n\n if (root?.html != null) {\n output.root = root.html;\n output.selector = `[data-lf-root]`;\n }\n\n for (let i = 0; i < arr.length; i++) {\n let selector: string;\n const fragment = arr[i];\n\n if (fragment == null || claimed.has(fragment.id)) {\n continue;\n }\n\n if (fragment.type === 'embed') {\n selector = `[id=${fragment.id}]`;\n } else if (fragment.type === 'bare') {\n selector = `[data-lf=${fragment.id}]`;\n } else if (fragment.type === 'range') {\n selector = `[data-lf=${fragment.id}]`;\n }\n\n output.fragments[fragment.id] = {\n id: fragment.id,\n selector,\n type: fragment.type as 'embed' | 'bare' | 'range',\n html: fragment.html,\n };\n }\n\n return output;\n}\n\n\nconst templateRe = /(?:#{([\\w][\\w\\-_]*)})|(?:#\\[([\\w][\\w\\-_]+)\\])/g;\n\n/**\n * Processes a client side Longform template to HTML fragment string.\n *\n * @param fragment - The fragment identifier.\n * @param args - A record of template arguments.\n * @param getFragment - A function which returns an already processed fragment's HTML string.\n * @returns The processed template.\n */\nexport function processTemplate(\n template: string,\n args: Record<string, string | number>,\n getFragment: (fragment: string) => string | undefined,\n): string | undefined {\n const lf = template.replace(templateRe, (_match, param, ref) => {\n if (ref != null) {\n const fragment = getFragment(ref);\n\n if (fragment == null) return '';\n\n return fragment;\n }\n \n return args[param] != null ? escape(args[param].toString()) : '';\n });\n\n return Object.values(longform(lf).fragments)[0]?.html ?? null;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["sniffTestRe", "element1", "directive1", "attribute1", "preformattedClose", "id1", "idnt1", "text1", "paramsRe", "refRe", "escapeRe", "templateLinesRe", "voids", "m1", "m2", "m3", "entities", "escape", "value", "match", "_a", "makeElement", "indent", "makeChunk", "type", "makeFragment", "doc", "debug", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "skipping", "textIndent", "verbatimSerialize", "verbatimIndent", "verbatimFirst", "element", "chunk", "fragment", "root", "claimed", "parsed", "output", "applyIndent", "targetIndent", "attr", "line", "tg", "ar", "pr", "tx", "indented", "start", "arr", "flatten", "j", "ref", "child", "i", "selector", "templateRe", "template", "args", "getFragment", "lf", "_match", "param"]
|
|
7
7
|
}
|
package/lib/longform.test.ts
CHANGED
|
@@ -285,3 +285,31 @@ test('It renders plan text fragments', { skip: true }, () => {
|
|
|
285
285
|
const res = processTemplate('label', { position: 4 }, parsed);
|
|
286
286
|
})
|
|
287
287
|
|
|
288
|
+
const lf9 = `
|
|
289
|
+
@template
|
|
290
|
+
#my-template
|
|
291
|
+
div[aria-label=Something something #{position}]::
|
|
292
|
+
Hello world!
|
|
293
|
+
|
|
294
|
+
#other-fragment
|
|
295
|
+
div::
|
|
296
|
+
p:: Test
|
|
297
|
+
`;
|
|
298
|
+
const html9 = `\
|
|
299
|
+
<div id="other-fragment"><p>Test</p></div>\
|
|
300
|
+
`;
|
|
301
|
+
const template9 = `\
|
|
302
|
+
<div id="my-template" aria-label="Something something 4">Hello world!</div>\
|
|
303
|
+
`;
|
|
304
|
+
test('It renders templated element fragments', () => {
|
|
305
|
+
const parsed = longform(lf9);
|
|
306
|
+
console.log(parsed)
|
|
307
|
+
const res = processTemplate(parsed.templates['my-template'], { position: 4 }, x => {
|
|
308
|
+
return parsed.fragments[x]?.html;
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
assert.equal(parsed.fragments['other-fragment'].html, html9);
|
|
312
|
+
assert.equal(res, template9);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
|
package/lib/longform.ts
CHANGED
|
@@ -17,7 +17,7 @@ const sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#
|
|
|
17
17
|
, paramsRe = /(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g
|
|
18
18
|
, refRe = /#\[([\w\-]+)\]/g
|
|
19
19
|
, escapeRe = /([&<>"'#\[\]{}])/g
|
|
20
|
-
, templateLinesRe = /^(\ \ )?([^\n]
|
|
20
|
+
, templateLinesRe = /^(\ \ )?([^\n]+)$/gmi
|
|
21
21
|
, voids = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wrb']);
|
|
22
22
|
|
|
23
23
|
let m1: RegExpExecArray | null
|
|
@@ -410,21 +410,23 @@ export function longform(doc: string, debug: (...d: unknown[]) => void = () => {
|
|
|
410
410
|
|
|
411
411
|
templateLinesRe.lastIndex = sniffTestRe.lastIndex;
|
|
412
412
|
while ((m2 = templateLinesRe.exec(doc))) {
|
|
413
|
-
if (m2[1] == null && !indented) {
|
|
413
|
+
if (m2[1] == null && !indented && fragment.id == null) {
|
|
414
414
|
id1.lastIndex = 0;
|
|
415
415
|
m3 = id1.exec(m2[0]);
|
|
416
416
|
|
|
417
|
-
fragment.id = m3[3];
|
|
417
|
+
if (m3 != null) fragment.id = m3[3];
|
|
418
|
+
|
|
418
419
|
fragment.html += m2[0];
|
|
419
420
|
} else if (m2[1] == null && indented) {
|
|
420
|
-
sniffTestRe.lastIndex = templateLinesRe.lastIndex -
|
|
421
|
-
applyIndent(0)
|
|
421
|
+
sniffTestRe.lastIndex = templateLinesRe.lastIndex - m2[0].length;
|
|
422
422
|
break;
|
|
423
423
|
} else {
|
|
424
424
|
fragment.html += '\n' + m2[0];
|
|
425
|
+
if (m2[1] != null) indented = true;
|
|
425
426
|
}
|
|
426
|
-
indented = true;
|
|
427
427
|
}
|
|
428
|
+
|
|
429
|
+
applyIndent(0);
|
|
428
430
|
}
|
|
429
431
|
}
|
|
430
432
|
|