Custom task statuses plus various fixes

This commit is contained in:
Zef Hemel
2023-09-01 16:57:29 +02:00
parent 9b5fa44fb6
commit 2ee20af5c8
24 changed files with 374 additions and 118 deletions
+4 -2
View File
@@ -5,8 +5,6 @@ export const CommandLinkNameTag = Tag.define();
export const WikiLinkTag = Tag.define();
export const WikiLinkPageTag = Tag.define();
export const CodeInfoTag = Tag.define();
export const TaskTag = Tag.define();
export const TaskMarkerTag = Tag.define();
export const CommentTag = Tag.define();
export const CommentMarkerTag = Tag.define();
export const BulletList = Tag.define();
@@ -22,3 +20,7 @@ export const DirectiveProgramTag = Tag.define();
export const AttributeTag = Tag.define();
export const AttributeNameTag = Tag.define();
export const AttributeValueTag = Tag.define();
export const TaskTag = Tag.define();
export const TaskMarkerTag = Tag.define();
export const TaskStateTag = Tag.define();
+60
View File
@@ -0,0 +1,60 @@
import {
BlockContext,
LeafBlock,
LeafBlockParser,
MarkdownConfig,
} from "../deps.ts";
import { tags as t } from "@lezer/highlight";
import { TaskStateTag } from "./customtags.ts";
// Taken from https://github.com/lezer-parser/markdown/blob/main/src/extension.ts and adapted
class MultiStatusTaskParser implements LeafBlockParser {
constructor(private status: string) {
}
nextLine() {
return false;
}
finish(cx: BlockContext, leaf: LeafBlock) {
cx.addLeafElement(
leaf,
cx.elt("Task", leaf.start, leaf.start + leaf.content.length, [
cx.elt("TaskState", leaf.start, leaf.start + 2 + this.status.length, [
cx.elt("TaskMarker", leaf.start, leaf.start + 1),
cx.elt(
"TaskMarker",
leaf.start + 1 + this.status.length,
leaf.start + 2 + this.status.length,
),
]),
...cx.parser.parseInline(
leaf.content.slice(this.status.length + 2),
leaf.start + this.status.length + 2,
),
]),
);
return true;
}
}
export const TaskList: MarkdownConfig = {
defineNodes: [
{ name: "Task", block: true, style: t.list },
{ name: "TaskMarker", style: t.atom },
{ name: "TaskState", style: TaskStateTag },
],
parseBlock: [{
name: "TaskList",
leaf(cx, leaf) {
const match = /^\[([^\]]+)\][ \t]/.exec(leaf.content);
return match &&
cx.parentType().name == "ListItem"
? new MultiStatusTaskParser(match[1])
: null;
},
after: "SetextHeading",
}],
};
+19 -1
View File
@@ -103,7 +103,7 @@ And one with nested brackets: [array: [1, 2, 3]]
Deno.test("Test inline attribute syntax", () => {
const lang = buildMarkdown([]);
const tree = parse(lang, inlineAttributeSample);
console.log("Attribute parsed", JSON.stringify(tree, null, 2));
// console.log("Attribute parsed", JSON.stringify(tree, null, 2));
const attributes = collectNodesOfType(tree, "Attribute");
let nameNode = findNodeOfType(attributes[0], "AttributeName");
assertEquals(nameNode?.children![0].text, "age");
@@ -120,3 +120,21 @@ Deno.test("Test inline attribute syntax", () => {
valueNode = findNodeOfType(attributes[2], "AttributeValue");
assertEquals(valueNode?.children![0].text, "[1, 2, 3]");
});
const multiStatusTaskExample = `
* [ ] Task 1
- [x] Task 2
* [TODO] Task 3
`;
Deno.test("Test multi-status tasks", () => {
const lang = buildMarkdown([]);
const tree = parse(lang, multiStatusTaskExample);
// console.log("Tasks parsed", JSON.stringify(tree, null, 2));
const tasks = collectNodesOfType(tree, "Task");
assertEquals(tasks.length, 3);
// Check " " checkbox state parsing
assertEquals(tasks[0].children![0].children![1].text, " ");
assertEquals(tasks[1].children![0].children![1].text, "x");
assertEquals(tasks[2].children![0].children![1].text, "TODO");
});
+1 -1
View File
@@ -10,10 +10,10 @@ import {
Strikethrough,
styleTags,
tags as t,
TaskList,
yamlLanguage,
} from "../deps.ts";
import * as ct from "./customtags.ts";
import { TaskList } from "./extended_task.ts";
import {
MDExt,
mdExtensionStyleTags,