@longform/longform 0.0.2 → 0.0.4

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.
@@ -8,14 +8,9 @@ declare module "types" {
8
8
  attrs: Record<string, string | null>;
9
9
  text?: string;
10
10
  html: string;
11
+ mount?: string;
11
12
  };
12
- export type ChunkType = 'parsed' | 'ref' | 'scope';
13
- export type WorkingChunk = {
14
- type: ChunkType;
15
- html: string;
16
- els: WorkingElement[];
17
- };
18
- export type WorkingFragmentType = 'root' | 'embed' | 'bare' | 'range' | 'text' | 'template';
13
+ export type WorkingFragmentType = 'root' | 'embed' | 'bare' | 'range' | 'text' | 'mount' | 'template';
19
14
  export type FragmentType = 'embed' | 'bare' | 'range' | 'text';
20
15
  export type FragmentRef = {
21
16
  id: string;
@@ -25,11 +20,12 @@ declare module "types" {
25
20
  export type WorkingFragment = {
26
21
  id?: string;
27
22
  template: boolean;
23
+ mountable: boolean;
28
24
  type: WorkingFragmentType;
29
25
  html: string;
30
26
  refs: FragmentRef[];
31
- chunks: WorkingChunk[];
32
27
  els: WorkingElement[];
28
+ mountPoints: MountPoint[];
33
29
  };
34
30
  export type Fragment = {
35
31
  id: string;
@@ -37,9 +33,16 @@ declare module "types" {
37
33
  type: FragmentType;
38
34
  html: string;
39
35
  };
36
+ export type MountPoint = {
37
+ id: string;
38
+ part: string;
39
+ };
40
40
  export type ParsedResult = {
41
+ mountable?: boolean;
41
42
  root: string | null;
42
43
  selector: string | null;
44
+ mountPoints: MountPoint[];
45
+ tail?: string;
43
46
  fragments: Record<string, Fragment>;
44
47
  templates: Record<string, string>;
45
48
  };
package/dist/longform.js CHANGED
@@ -25,27 +25,21 @@ function makeElement(indent = 0) {
25
25
  attrs: {}
26
26
  };
27
27
  }
28
- function makeChunk(type = "parsed") {
29
- return {
30
- type,
31
- html: "",
32
- els: []
33
- };
34
- }
35
28
  function makeFragment(type = "bare") {
36
29
  return {
37
30
  type,
38
31
  html: "",
39
32
  template: false,
33
+ mountable: false,
40
34
  els: [],
41
- chunks: [],
42
- refs: []
35
+ refs: [],
36
+ mountPoints: []
43
37
  };
44
38
  }
45
39
  export function longform(doc, debug = () => {
46
40
  }) {
47
41
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
48
- let skipping = false, textIndent = null, verbatimSerialize = true, verbatimIndent = null, verbatimFirst = false, element = makeElement(), chunk = makeChunk(), fragment = makeFragment(), root = null;
42
+ let skipping = false, textIndent = null, verbatimSerialize = true, verbatimIndent = null, verbatimFirst = false, element = makeElement(), fragment = makeFragment(), root = null;
49
43
  const claimed = /* @__PURE__ */ new Set(), parsed = /* @__PURE__ */ new Map(), output = /* @__PURE__ */ Object.create(null);
50
44
  output.fragments = /* @__PURE__ */ Object.create(null);
51
45
  output.templates = /* @__PURE__ */ Object.create(null);
@@ -60,6 +54,9 @@ export function longform(doc, debug = () => {
60
54
  fragment.html += ` data-lf="${fragment.id}"`;
61
55
  }
62
56
  }
57
+ if (element.mount != null) {
58
+ fragment.html += ` data-lf-mount="${element.mount}"`;
59
+ }
63
60
  if (element.id != null) {
64
61
  fragment.html += ' id="' + element.id + '"';
65
62
  }
@@ -224,6 +221,17 @@ export function longform(doc, debug = () => {
224
221
  }
225
222
  }
226
223
  }
224
+ if (element.mount != null) {
225
+ const id = element.mount;
226
+ applyIndent(indent + 1);
227
+ fragment.mountPoints.push({
228
+ id,
229
+ part: fragment.html
230
+ });
231
+ fragment.html = "";
232
+ applyIndent(indent);
233
+ break;
234
+ }
227
235
  if (!pr && tx != null) {
228
236
  element.text = tx;
229
237
  } else if (pr) {
@@ -290,6 +298,17 @@ export function longform(doc, debug = () => {
290
298
  }
291
299
  }
292
300
  applyIndent(0);
301
+ break;
302
+ }
303
+ case "mount": {
304
+ if (m2[3] == null) {
305
+ throw new Error("Mount points must have a name");
306
+ } else if (fragment.type !== "root") {
307
+ throw new Error("Mounting is only allowed on a root element");
308
+ }
309
+ fragment.mountable = true;
310
+ element.mount = m2[3].trim();
311
+ break;
293
312
  }
294
313
  }
295
314
  break;
@@ -342,6 +361,12 @@ export function longform(doc, debug = () => {
342
361
  fragment2.refs = [];
343
362
  return fragment2;
344
363
  }
364
+ if (root == null ? void 0 : root.mountable) {
365
+ output.mountable = true;
366
+ output.tail = root.html;
367
+ output.mountPoints = root.mountPoints;
368
+ return output;
369
+ }
345
370
  for (let i = 0; i < parsed.size + 1; i++) {
346
371
  let fragment2;
347
372
  if (i === 0 && root == null) {
Binary file
@@ -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 '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&apos;',\n// '#': '&num;',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '&rbrace;',\n// '}': '&lbrace;',\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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",
4
+ "sourcesContent": ["import type { FragmentType, ParsedResult, 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 '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&apos;',\n// '#': '&num;',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '&rbrace;',\n// '}': '&lbrace;',\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 makeFragment(type: FragmentType = 'bare'): WorkingFragment {\n return {\n type,\n html: '',\n template: false,\n mountable: false,\n els: [],\n refs: [],\n mountPoints: [],\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 , 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.mount != null) {\n fragment.html += ` data-lf-mount=\"${element.mount}\"`;\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 // this is a hack to get temp support of mounting\n // working. In the future it will be moved to a \n // server specific process.\n if (element.mount != null) {\n const id = element.mount;\n applyIndent(indent + 1);\n fragment.mountPoints.push({\n id,\n part: fragment.html,\n });\n fragment.html = '';\n applyIndent(indent);\n break;\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 break;\n }\n case 'mount': {\n if (m2[3] == null) {\n throw new Error('Mount points must have a name');\n } else if (fragment.type !== 'root') {\n throw new Error('Mounting is only allowed on a root element');\n }\n\n fragment.mountable = true;\n element.mount = m2[3].trim();\n break;\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 if (root?.mountable) {\n output.mountable = true;\n output.tail = root.html;\n output.mountPoints = root.mountPoints;\n\n return output;\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,aAAa,OAAqB,QAAyB;AAClE,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,IACX,KAAK,CAAC;AAAA,IACN,MAAM,CAAC;AAAA,IACP,aAAa,CAAC;AAAA,EAChB;AACF;AASO,gBAAS,SAAS,KAAa,QAAmC,MAAM;AAAC,GAAiB;AAxEjG;AAyEE,MAAI,WAAoB,OACpB,aAA4B,MAC5B,oBAA6B,MAC7B,iBAAgC,MAChC,gBAAyB,OACzB,UAA0B,YAAY,GACtC,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,SAAS,MAAM;AACzB,iBAAS,QAAQ,mBAAmB,QAAQ,KAAK;AAAA,MACnD;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;AAKA,cAAI,QAAQ,SAAS,MAAM;AACzB,kBAAM,KAAK,QAAQ;AACnB,wBAAY,SAAS,CAAC;AACtB,qBAAS,YAAY,KAAK;AAAA,cACxB;AAAA,cACA,MAAM,SAAS;AAAA,YACjB,CAAC;AACD,qBAAS,OAAO;AAChB,wBAAY,MAAM;AAClB;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;AACb;AAAA,YACF;AAAA,YACA,KAAK,SAAS;AACZ,kBAAI,GAAG,CAAC,KAAK,MAAM;AACjB,sBAAM,IAAI,MAAM,+BAA+B;AAAA,cACjD,WAAW,SAAS,SAAS,QAAQ;AACnC,sBAAM,IAAI,MAAM,4CAA4C;AAAA,cAC9D;AAEA,uBAAS,YAAY;AACrB,sBAAQ,QAAQ,GAAG,CAAC,EAAE,KAAK;AAC3B;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,MAAI,6BAAM,WAAW;AACnB,WAAO,YAAY;AACnB,WAAO,OAAO,KAAK;AACnB,WAAO,cAAc,KAAK;AAE1B,WAAO;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;AAzlBtB;AA0lBE,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
  }
@@ -1,5 +1,5 @@
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={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&apos;"};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
- `,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((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}
1
+ const R=/^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi,C=/((?:\ \ )+)? ?([\w\-]+(?::[\w\-]+)?)([#\.\[][^\n]*)?::(?: ({{?|[^\n]+))?/gmi,L=/((?:\ \ )+)? ?@([\w][\w\-]+)(?::: ?([^\n]+)?)?/gmi,U=/((?:\ \ )+)\[(\w[\w-]*(?::\w[\w-]*)?)(?:=([^\n]+))?\]/,K=/[ \t]*}}?[ \t]*/,w=/((?:\ \ )+)?#(#)?([\w\-]+)(?: ([\["]))?/gmi,B=/^(\ \ )+/,N=/^((?:\ \ )+)([^ \n][^\n]*)$/i,Q=/(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g,V=/#\[([\w\-]+)\]/g,X=/([&<>"'#\[\]{}])/g,E=/^(\ \ )?([^\n]+)$/gmi,D=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wrb"]);let r,e,$;const Y={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&apos;"};function G(o){return o.replace(X,u=>{var g;return(g=Y[u])!=null?g:u})}function W(o=0){return{indent:o,html:"",attrs:{}}}function H(o="bare"){return{type:o,html:"",template:!1,mountable:!1,els:[],refs:[],mountPoints:[]}}export function longform(o,u=()=>{}){var P,I,j,T,A,O,S,M,_,z,q;let g=!1,c=null,p=!0,d=null,x=!1,n=W(),t=H(),a=null;const y=new Set,b=new Map,m=Object.create(null);m.fragments=Object.create(null),m.templates=Object.create(null);function f(l){if(n.tag!=null){const i=t.type==="range"?l<2:t.html==="";t.html+=`<${n.tag}`,i&&(t.type==="root"?t.html+=" data-lf-root":(t.type==="bare"||t.type==="range")&&(t.html+=` data-lf="${t.id}"`)),n.mount!=null&&(t.html+=` data-lf-mount="${n.mount}"`),n.id!=null&&(t.html+=' id="'+n.id+'"'),n.class!=null&&(t.html+=' class="'+n.class+'"');for(const s of Object.entries(n.attrs))s[1]==null?t.html+=" "+s[0]:t.html+=` ${s[0]}="${s[1]}"`;t.html+=">",!D.has(n.tag)&&n.text!=null&&(t.html+=n.text),D.has(n.tag)||t.els.push(n)}if(l<=n.indent){for(n=W(l);t.els.length!==0&&(l==null||t.els[t.els.length-1].indent!==l-1);){const i=t.els.pop();t.html+=`</${i==null?void 0:i.tag}>`}l===0&&(u(0,"<",t.type,t.id),t.template?m.templates[t.id]=t.html:t.type==="root"?a=t:b.set(t.id,t),t=H())}else n=W(l)}for(;r=R.exec(o);)if(r[1]!=="--"){if(t.template&&(t.html+=r[0]),d!=null){B.lastIndex=0,e=B.exec(r[0]);const l=e==null?null:e[0].length/2;if(e==null||l<=d){if(t.html+=`
2
+ `,u(l,"}",e==null?void 0:e[0]),f(l),d=null,x=!1,c=l,K.test(r[0]))continue}else{const i=r[0].replace(" ".repeat(d+1),"");u(l,"{",i),n.tag!=null&&f(l),x?x=!1:t.html+=`
3
+ `,p?t.html+=G(i):t.html+=i;continue}}if(r[0].trim()!=="")switch((I=(P=r[2])!=null?P:r[3])!=null?I:r[4]){case"#":if(w.lastIndex=0,e=w.exec(r[0]),e!=null){const l=((T=(j=e[1])==null?void 0:j.length)!=null?T:0)/2;(n.tag!=null||c!=null)&&(f(l),c=null),u(l,"id",e[2],e[3],e[4]),t.id=e[3],l===0&&(e[4]=="["?t.type="range":e[4]==='"'?t.type="text":e[2]!=null?t.type="bare":(t.type="embed",n.id=t.id));break}case"@":case"[":case"::":{if(C.lastIndex=0,e=((A=r[2])!=null?A:r[4]!=null)?null:C.exec(r[0]),e!=null){const l=((S=(O=e[1])==null?void 0:O.length)!=null?S:0)/2,i=e[2],s=e[3],h=e[4]==="{"||e[4]==="{{",F=h?null:e[4];if(u(l,"e",i,h,F),(n.tag!=null||n.indent>l)&&f(l),n.indent=l,n.tag=i,c=null,l===0&&t.id==null&&(a!=null?g=!0:(t.type="root",a=t)),s!=null)for(u(l,"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];if(n.mount!=null){const J=n.mount;f(l+1),t.mountPoints.push({id:J,part:t.html}),t.html="",f(l);break}!h&&F!=null?n.text=F:h&&(x=!0,d=l,p=e[4]==="{");break}if(U.lastIndex=0,e=r[2]!=null?null:U.exec(r[0]),e!=null&&n.tag!=null){u("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(L.lastIndex=0,e=r[3]!=null?null:L.exec(r[0]),e!=null){const l=((_=(M=e[1])==null?void 0:M.length)!=null?_:0)/2;switch((n.tag!=null||c!=null)&&f(l),u(l,"d",e[2],e[3]),e[2]){case"doctype":{t.html+=`<!doctype ${(z=e[3])!=null?z:"html"}>`;break}case"xml":{t.html+=`<?xml ${(q=e[3])!=null?q:'version="1.0" encoding="UTF-8"'}?>`;break}case"template":{let i=!1;for(t.template=l===0,E.lastIndex=R.lastIndex;e=E.exec(o);)if(e[1]==null&&!i&&t.id==null)w.lastIndex=0,$=w.exec(e[0]),$!=null&&(t.id=$[3]),t.html+=e[0];else if(e[1]==null&&i){R.lastIndex=E.lastIndex-e[0].length;break}else t.html+=`
4
+ `+e[0],e[1]!=null&&(i=!0);f(0);break}case"mount":{if(e[3]==null)throw new Error("Mount points must have a name");if(t.type!=="root")throw new Error("Mounting is only allowed on a root element");t.mountable=!0,n.mount=e[3].trim();break}}break}}default:{if(e=N.exec(r[0]),e==null)break;const l=e[1].length/2,i=e[2].trim();for(u(l,"t",e[2]),n.tag!=null?(f(l),t.html+=i):t.type==="text"&&t.html===""?t.html+=i:t.html+=" "+i,c=l;e=V.exec(i);){const s=t.html.length+e.index-i.length;t.refs.push({id:e[1],start:s,end:s+e[0].length})}break}}}f(0);const k=Array.from(b.values());function v(l){for(let i=l.refs.length-1;i>=0;i--){const s=l.refs[i];if(y.has(s.id)||!b.has(s.id))l.html=l.html.slice(0,s.start)+l.html.slice(s.end);else{const h=v(b.get(s.id));l.html=l.html.slice(0,s.start)+h.html+l.html.slice(s.end),h.type==="embed"&&y.add(h.id)}}return l.refs=[],l}if(a!=null&&a.mountable)return m.mountable=!0,m.tail=a.html,m.mountPoints=a.mountPoints,m;for(let l=0;l<b.size+1;l++){let i;l===0&&a==null||(l===0?i=a:i=k[l-1],i.refs.length!==0&&v(i))}(a==null?void 0:a.html)!=null&&(m.root=a.html,m.selector="[data-lf-root]");for(let l=0;l<k.length;l++){let i;const s=k[l];s==null||y.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}]`),m.fragments[s.id]={id:s.id,selector:i,type:s.type,html:s.html})}return m}const Z=/(?:#{([\w][\w\-_]*)})|(?:#\[([\w][\w\-_]+)\])/g;export function processTemplate(o,u,g){var p,d;const c=o.replace(Z,(x,n,t)=>{if(t!=null){const a=g(t);return a==null?"":a}return u[n]!=null?G(u[n].toString()):""});return(d=(p=Object.values(longform(c).fragments)[0])==null?void 0:p.html)!=null?d:null}
5
5
  //# sourceMappingURL=longform.min.js.map
Binary file
@@ -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 '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&apos;',\n// '#': '&num;',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '&rbrace;',\n// '}': '&lbrace;',\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
- "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"]
4
+ "sourcesContent": ["import type { FragmentType, ParsedResult, 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 '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&apos;',\n// '#': '&num;',\n// '[': '&lbrak;',\n// ']': '&rbrak;',\n// '{': '&rbrace;',\n// '}': '&lbrace;',\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 makeFragment(type: FragmentType = 'bare'): WorkingFragment {\n return {\n type,\n html: '',\n template: false,\n mountable: false,\n els: [],\n refs: [],\n mountPoints: [],\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 , 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.mount != null) {\n fragment.html += ` data-lf-mount=\"${element.mount}\"`;\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 // this is a hack to get temp support of mounting\n // working. In the future it will be moved to a \n // server specific process.\n if (element.mount != null) {\n const id = element.mount;\n applyIndent(indent + 1);\n fragment.mountPoints.push({\n id,\n part: fragment.html,\n });\n fragment.html = '';\n applyIndent(indent);\n break;\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 break;\n }\n case 'mount': {\n if (m2[3] == null) {\n throw new Error('Mount points must have a name');\n } else if (fragment.type !== 'root') {\n throw new Error('Mounting is only allowed on a root element');\n }\n\n fragment.mountable = true;\n element.mount = m2[3].trim();\n break;\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 if (root?.mountable) {\n output.mountable = true;\n output.tail = root.html;\n output.mountPoints = root.mountPoints;\n\n return output;\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
+ "names": ["sniffTestRe", "element1", "directive1", "attribute1", "preformattedClose", "id1", "idnt1", "text1", "paramsRe", "refRe", "escapeRe", "templateLinesRe", "voids", "m1", "m2", "m3", "entities", "escape", "value", "match", "_a", "makeElement", "indent", "makeFragment", "type", "doc", "debug", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "skipping", "textIndent", "verbatimSerialize", "verbatimIndent", "verbatimFirst", "element", "fragment", "root", "claimed", "parsed", "output", "applyIndent", "targetIndent", "attr", "line", "tg", "ar", "pr", "tx", "id", "indented", "start", "arr", "flatten", "j", "ref", "child", "i", "selector", "templateRe", "template", "args", "getFragment", "lf", "_match", "param"]
7
7
  }
@@ -9,6 +9,7 @@ import { parse, resolve } from "node:path";
9
9
  import { randomUUID } from "node:crypto";
10
10
  import { writeFile, unlink } from "node:fs/promises";
11
11
  import * as prettier from 'prettier';
12
+ import {execPath} from 'node:process';
12
13
 
13
14
  async function validate(html: string, type: 'html' | 'xml' = 'html'): Promise<boolean> {
14
15
  return true;
@@ -301,7 +302,7 @@ const html9 = `\
301
302
  const template9 = `\
302
303
  <div id="my-template" aria-label="Something something 4">Hello world!</div>\
303
304
  `;
304
- test('It renders templated element fragments', () => {
305
+ test('It renders templated element fragments', { only: true }, () => {
305
306
  const parsed = longform(lf9);
306
307
  console.log(parsed)
307
308
  const res = processTemplate(parsed.templates['my-template'], { position: 4 }, x => {
@@ -312,4 +313,35 @@ test('It renders templated element fragments', () => {
312
313
  assert.equal(res, template9);
313
314
  });
314
315
 
316
+ const lf10 = `
317
+ @root
318
+ @doctype:: html
319
+ html::
320
+ @mount:: head
321
+ head::
322
+ body::
323
+ @mount:: header
324
+ header::
325
+ @mount:: main
326
+ main::
327
+ @mount:: footer
328
+ `;
329
+ test('It breaks mount points up into individual dom slices', () => {
330
+ const parsed = longform(lf10, console.log);
331
+
332
+ console.log(parsed);
333
+
334
+ assert(parsed.mountable);
335
+ assert.equal(parsed.mountPoints[0].id, 'head');
336
+ assert.equal(parsed.mountPoints[0].part, '<!doctype html><html><head data-lf-mount="head">');
337
+ assert.equal(parsed.mountPoints[1].id, 'header');
338
+ assert.equal(parsed.mountPoints[1].part, '</head><body><header data-lf-mount="header">');
339
+ assert.equal(parsed.mountPoints[2].id, 'main');
340
+ assert.equal(parsed.mountPoints[2].part, '</header><main data-lf-mount="main">');
341
+ assert.equal(parsed.tail, '</main></body></html>');
342
+ });
343
+
344
+
345
+
346
+
315
347
 
package/lib/longform.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ChunkType, FragmentType, ParsedResult, WorkingChunk, WorkingElement, WorkingFragment, Fragment } from "./types.ts";
1
+ import type { FragmentType, ParsedResult, WorkingElement, WorkingFragment, Fragment } from "./types.ts";
2
2
 
3
3
  export type {
4
4
  FragmentType,
@@ -51,22 +51,15 @@ function makeElement(indent: number = 0): WorkingElement {
51
51
  };
52
52
  }
53
53
 
54
- function makeChunk(type: ChunkType = 'parsed'): WorkingChunk {
55
- return {
56
- type,
57
- html: '',
58
- els: [],
59
- };
60
- }
61
-
62
54
  function makeFragment(type: FragmentType = 'bare'): WorkingFragment {
63
55
  return {
64
56
  type,
65
57
  html: '',
66
58
  template: false,
59
+ mountable: false,
67
60
  els: [],
68
- chunks: [],
69
61
  refs: [],
62
+ mountPoints: [],
70
63
  };
71
64
  }
72
65
 
@@ -84,7 +77,6 @@ export function longform(doc: string, debug: (...d: unknown[]) => void = () => {
84
77
  , verbatimIndent: number | null = null
85
78
  , verbatimFirst: boolean = false
86
79
  , element: WorkingElement = makeElement()
87
- , chunk: WorkingChunk | null = makeChunk()
88
80
  , fragment: WorkingFragment = makeFragment()
89
81
  // the root fragment
90
82
  , root: WorkingFragment | null = null
@@ -119,6 +111,10 @@ export function longform(doc: string, debug: (...d: unknown[]) => void = () => {
119
111
  }
120
112
  }
121
113
 
114
+ if (element.mount != null) {
115
+ fragment.html += ` data-lf-mount="${element.mount}"`;
116
+ }
117
+
122
118
  if (element.id != null) {
123
119
  fragment.html += ' id="' + element.id + '"';
124
120
  }
@@ -343,6 +339,21 @@ export function longform(doc: string, debug: (...d: unknown[]) => void = () => {
343
339
  }
344
340
  }
345
341
 
342
+ // this is a hack to get temp support of mounting
343
+ // working. In the future it will be moved to a
344
+ // server specific process.
345
+ if (element.mount != null) {
346
+ const id = element.mount;
347
+ applyIndent(indent + 1);
348
+ fragment.mountPoints.push({
349
+ id,
350
+ part: fragment.html,
351
+ });
352
+ fragment.html = '';
353
+ applyIndent(indent);
354
+ break;
355
+ }
356
+
346
357
  if (!pr && tx != null) {
347
358
  element.text = tx;
348
359
  } else if (pr) {
@@ -427,6 +438,18 @@ export function longform(doc: string, debug: (...d: unknown[]) => void = () => {
427
438
  }
428
439
 
429
440
  applyIndent(0);
441
+ break;
442
+ }
443
+ case 'mount': {
444
+ if (m2[3] == null) {
445
+ throw new Error('Mount points must have a name');
446
+ } else if (fragment.type !== 'root') {
447
+ throw new Error('Mounting is only allowed on a root element');
448
+ }
449
+
450
+ fragment.mountable = true;
451
+ element.mount = m2[3].trim();
452
+ break;
430
453
  }
431
454
  }
432
455
 
@@ -503,6 +526,14 @@ export function longform(doc: string, debug: (...d: unknown[]) => void = () => {
503
526
  return fragment;
504
527
  }
505
528
 
529
+ if (root?.mountable) {
530
+ output.mountable = true;
531
+ output.tail = root.html;
532
+ output.mountPoints = root.mountPoints;
533
+
534
+ return output;
535
+ }
536
+
506
537
  for (let i = 0; i < parsed.size + 1; i++) {
507
538
  let fragment: WorkingFragment;
508
539
 
package/lib/types.ts CHANGED
@@ -8,18 +8,7 @@ export type WorkingElement = {
8
8
  attrs: Record<string, string | null>;
9
9
  text?: string;
10
10
  html: string;
11
- };
12
-
13
- export type ChunkType =
14
- | 'parsed'
15
- | 'ref'
16
- | 'scope'
17
- ;
18
-
19
- export type WorkingChunk = {
20
- type: ChunkType;
21
- html: string;
22
- els: WorkingElement[];
11
+ mount?: string;
23
12
  };
24
13
 
25
14
  export type WorkingFragmentType =
@@ -28,6 +17,7 @@ export type WorkingFragmentType =
28
17
  | 'bare'
29
18
  | 'range'
30
19
  | 'text'
20
+ | 'mount'
31
21
  | 'template'
32
22
  ;
33
23
 
@@ -47,11 +37,12 @@ export type FragmentRef = {
47
37
  export type WorkingFragment = {
48
38
  id?: string;
49
39
  template: boolean;
40
+ mountable: boolean;
50
41
  type: WorkingFragmentType;
51
42
  html: string;
52
43
  refs: FragmentRef[];
53
- chunks: WorkingChunk[];
54
44
  els: WorkingElement[];
45
+ mountPoints: MountPoint[];
55
46
  };
56
47
 
57
48
  export type Fragment = {
@@ -61,9 +52,17 @@ export type Fragment = {
61
52
  html: string;
62
53
  };
63
54
 
55
+ export type MountPoint = {
56
+ id: string;
57
+ part: string;
58
+ };
59
+
64
60
  export type ParsedResult = {
61
+ mountable?: boolean;
65
62
  root: string | null;
66
63
  selector: string | null;
64
+ mountPoints: MountPoint[];
65
+ tail?: string;
67
66
  fragments: Record<string, Fragment>;
68
67
  templates: Record<string, string>;
69
68
  };
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "author": "Matthew Quinn",
5
5
  "homepage": "https://github.com/occultist-dev/longform",
6
6
  "license": "MIT",
7
- "version": "0.0.2",
7
+ "version": "0.0.4",
8
8
  "type": "module",
9
9
  "main": "dist/longform.js",
10
10
  "types": "dist/longform.d.ts",