summaryrefslogtreecommitdiff
path: root/packages/astro-parser/src/parse/state/codefence.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/astro-parser/src/parse/state/codefence.ts')
-rw-r--r--packages/astro-parser/src/parse/state/codefence.ts38
1 files changed, 38 insertions, 0 deletions
diff --git a/packages/astro-parser/src/parse/state/codefence.ts b/packages/astro-parser/src/parse/state/codefence.ts
new file mode 100644
index 000000000..d5b498a0f
--- /dev/null
+++ b/packages/astro-parser/src/parse/state/codefence.ts
@@ -0,0 +1,38 @@
+// @ts-nocheck
+import { Parser } from '../index.js';
+
+export default function codefence(parser: Parser) {
+ const start = parser.index;
+ const open = parser.match_regex(/[`~]{3,}/);
+ parser.index += open!.length;
+
+ let raw = open + '';
+
+ while (parser.index < parser.template.length && !parser.match(open)) {
+ raw += parser.template[parser.index++];
+ }
+
+ parser.eat(open, true);
+ raw += open;
+ const trailingWhitespace = parser.read_until(/\S/);
+ const { metadata, data } = extractCodeFence(raw);
+
+ const node = {
+ start,
+ end: parser.index,
+ type: 'CodeFence',
+ raw: `${raw}` + trailingWhitespace,
+ metadata,
+ data
+ };
+
+ parser.current().children.push(node);
+}
+
+/** Extract attributes on first line */
+function extractCodeFence(str: string) {
+ const [_, leadingLine] = str.match(/(^[^\n]*\r?\n)/m) ?? ['', ''];
+ const metadata = leadingLine.trim();
+ const data = str.slice(leadingLine.length);
+ return { metadata, data };
+}