More ways to define tags in frontmatter

This commit is contained in:
Zef Hemel
2023-12-22 13:59:16 +01:00
parent df83c62dec
commit c709f4e4be
7 changed files with 53 additions and 40 deletions
+16
View File
@@ -0,0 +1,16 @@
import { assertEquals } from "../../test_deps.ts";
import { determineTags } from "./cheap_yaml.ts";
Deno.test("cheap yaml", () => {
assertEquals([], determineTags(""));
assertEquals([], determineTags("hank: bla"));
assertEquals(["template"], determineTags("tags: template"));
assertEquals(["bla", "template"], determineTags("tags: bla,template"));
assertEquals(["bla", "template"], determineTags("tags:\n- bla\n- template"));
assertEquals(["bla", "template"], determineTags(`tags: "#bla,#template"`));
assertEquals(["bla", "template"], determineTags(`tags: '#bla, #template'`));
assertEquals(
["bla", "template"],
determineTags(`tags:\n- "#bla"\n- template`),
);
});
+36
View File
@@ -0,0 +1,36 @@
const yamlKvRegex = /^\s*(\w+):\s*["']?([^'"]*)["']?$/;
const yamlListItemRegex = /^\s*-\s+["']?([^'"]+)["']?$/;
/**
* Cheap YAML parser to determine tags (ugly, regex based but fast)
* @param yamlText
* @returns
*/
export function determineTags(yamlText: string): string[] {
const lines = yamlText.split("\n");
let inTagsSection = false;
const tags: string[] = [];
for (const line of lines) {
const yamlKv = yamlKvRegex.exec(line);
if (yamlKv) {
const [key, value] = yamlKv.slice(1);
// Looking for a 'tags' key
if (key === "tags") {
inTagsSection = true;
// 'template' there? Yay!
if (value) {
tags.push(
...value.split(/,\s*|\s+/).map((t) => t.replace(/^#/, "")),
);
}
} else {
inTagsSection = false;
}
}
const yamlListem = yamlListItemRegex.exec(line);
if (yamlListem && inTagsSection) {
tags.push(yamlListem[1].replace(/^#/, ""));
}
}
return tags;
}
+6 -2
View File
@@ -62,10 +62,14 @@ export async function extractFrontmatter(
if (!data.tags) {
data.tags = [];
}
// Normalize tags to an array and support a "tag1, tag2" notation
// Normalize tags to an array
// support "tag1, tag2" as well as "tag1 tag2" as well as "#tag1 #tag2" notations
if (typeof data.tags === "string") {
data.tags = (data.tags as string).split(/,\s*/);
data.tags = (data.tags as string).split(/,\s*|\s+/);
}
// Strip # from tags
data.tags = data.tags.map((t) => t.replace(/^#/, ""));
if (options.removeKeys && options.removeKeys.length > 0) {
let removedOne = false;