Attributes now have YAML values

This commit is contained in:
Zef Hemel
2023-07-26 17:12:56 +02:00
parent 5481e49393
commit 7b8d8af2c1
12 changed files with 139 additions and 54 deletions
+8 -6
View File
@@ -1,3 +1,4 @@
import "$sb/lib/syscall_mock.ts";
import { parse } from "../../common/markdown_parser/parse_tree.ts";
import buildMarkdown from "../../common/markdown_parser/parser.ts";
import { extractAttributes } from "$sb/lib/attribute.ts";
@@ -6,7 +7,7 @@ import { renderToText } from "$sb/lib/tree.ts";
const inlineAttributeSample = `
# My document
Top level attributes: [name:: sup] [age:: 42]
Top level attributes: [name:: sup] [age:: 42] [children: [pete, "john", mary]]
* [ ] Attribute in a task [tag:: foo]
* Regular item [tag:: bar]
@@ -16,7 +17,7 @@ Top level attributes: [name:: sup] [age:: 42]
const cleanedInlineAttributeSample = `
# My document
Top level attributes:
Top level attributes:
* [ ] Attribute in a task [tag:: foo]
* Regular item [tag:: bar]
@@ -24,16 +25,17 @@ Top level attributes:
1. Itemized list [tag:: baz]
`;
Deno.test("Test attribute extraction", () => {
Deno.test("Test attribute extraction", async () => {
const lang = buildMarkdown([]);
const tree = parse(lang, inlineAttributeSample);
const toplevelAttributes = extractAttributes(tree, false);
assertEquals(Object.keys(toplevelAttributes).length, 2);
const toplevelAttributes = await extractAttributes(tree, false);
// console.log("All attributes", toplevelAttributes);
assertEquals(toplevelAttributes.name, "sup");
assertEquals(toplevelAttributes.age, 42);
assertEquals(toplevelAttributes.children, ["pete", "john", "mary"]);
// Check if the attributes are still there
assertEquals(renderToText(tree), inlineAttributeSample);
// Now once again with cleaning
extractAttributes(tree, true);
await extractAttributes(tree, true);
assertEquals(renderToText(tree), cleanedInlineAttributeSample);
});
+12 -10
View File
@@ -1,28 +1,28 @@
import {
findNodeOfType,
ParseTree,
replaceNodesMatching,
replaceNodesMatchingAsync,
} from "$sb/lib/tree.ts";
import { YAML } from "$sb/plugos-syscall/mod.ts";
export type Attribute = {
name: string;
value: string;
};
const numberRegex = /^-?\d+(\.\d+)?$/;
/**
* Extracts attributes from a tree, optionally cleaning them out of the tree.
* @param tree tree to extract attributes from
* @param clean whether or not to clean out the attributes from the tree
* @returns mapping from attribute name to attribute value
*/
export function extractAttributes(
export async function extractAttributes(
tree: ParseTree,
clean: boolean,
): Record<string, any> {
): Promise<Record<string, any>> {
const attributes: Record<string, any> = {};
replaceNodesMatching(tree, (n) => {
await replaceNodesMatchingAsync(tree, async (n) => {
if (n.type === "ListItem") {
// Find top-level only, no nested lists
return n;
@@ -31,11 +31,13 @@ export function extractAttributes(
const nameNode = findNodeOfType(n, "AttributeName");
const valueNode = findNodeOfType(n, "AttributeValue");
if (nameNode && valueNode) {
let val: any = valueNode.children![0].text!;
if (numberRegex.test(val)) {
val = +val;
const name = nameNode.children![0].text!;
const val = valueNode.children![0].text!;
try {
attributes[name] = await YAML.parse(val);
} catch (e: any) {
console.error("Error parsing attribute value as YAML", val, e);
}
attributes[nameNode.children![0].text!] = val;
}
// Remove from tree
if (clean) {
+10
View File
@@ -0,0 +1,10 @@
import { YAML } from "../../common/deps.ts";
globalThis.syscall = (name: string, ...args: readonly any[]) => {
switch (name) {
case "yaml.parse":
return Promise.resolve(YAML.parse(args[0]));
default:
throw Error(`Not implemented in tests: ${name}`);
}
};
+1 -1
View File
@@ -129,7 +129,7 @@ export async function replaceNodesMatchingAsync(
tree.children.splice(pos, 1);
}
} else {
replaceNodesMatchingAsync(child, substituteFn);
await replaceNodesMatchingAsync(child, substituteFn);
}
}
}