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
+21 -3
View File
@@ -91,14 +91,32 @@ Deno.test("Test directive parser", () => {
});
const inlineAttributeSample = `
Hello there [a link](http://zef.plus) and [age:: 100]
Hello there [a link](http://zef.plus)
[age: 100]
[age:: 200]
Here's a more [ambiguous: case](http://zef.plus)
And one with nested brackets: [array: [1, 2, 3]]
`;
Deno.test("Test inline attribute syntax", () => {
const lang = buildMarkdown([]);
const tree = parse(lang, inlineAttributeSample);
const nameNode = findNodeOfType(tree, "AttributeName");
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");
const valueNode = findNodeOfType(tree, "AttributeValue");
let valueNode = findNodeOfType(attributes[0], "AttributeValue");
assertEquals(valueNode?.children![0].text, "100");
nameNode = findNodeOfType(attributes[1], "AttributeName");
assertEquals(nameNode?.children![0].text, "age");
valueNode = findNodeOfType(attributes[1], "AttributeValue");
assertEquals(valueNode?.children![0].text, "200");
nameNode = findNodeOfType(attributes[2], "AttributeName");
assertEquals(nameNode?.children![0].text, "array");
valueNode = findNodeOfType(attributes[2], "AttributeValue");
assertEquals(valueNode?.children![0].text, "[1, 2, 3]");
});
+35 -8
View File
@@ -142,7 +142,7 @@ export const Highlight: MarkdownConfig = {
],
};
export const attributeRegex = /^\[(\w+)(::\s*)([^\]]+)\]/;
export const attributeStartRegex = /^\[(\w+)(::?\s*)/;
export const Attribute: MarkdownConfig = {
defineNodes: [
@@ -157,19 +157,46 @@ export const Attribute: MarkdownConfig = {
name: "Attribute",
parse(cx, next, pos) {
let match: RegExpMatchArray | null;
const textFromPos = cx.slice(pos, cx.end);
if (
next != 91 /* '[' */ ||
// and match the whole thing
!(match = attributeRegex.exec(cx.slice(pos, cx.end)))
!(match = attributeStartRegex.exec(textFromPos))
) {
return -1;
}
const [fullMatch, attributeName, attributeColon, _attributeValue] =
match;
const endPos = pos + fullMatch.length;
const [fullMatch, attributeName, attributeColon] = match;
const attributeValueStart = pos + fullMatch.length;
let bracketNestingDepth = 1;
let valueLength = fullMatch.length;
loopLabel:
for (; valueLength < textFromPos.length; valueLength++) {
switch (textFromPos[valueLength]) {
case "[":
bracketNestingDepth++;
break;
case "]":
bracketNestingDepth--;
if (bracketNestingDepth === 0) {
// Done!
break loopLabel;
}
break;
}
}
if (bracketNestingDepth !== 0) {
console.log("Failed to parse attribute", fullMatch, textFromPos);
return -1;
}
if (textFromPos[valueLength + 1] === "(") {
console.log("Link", fullMatch, textFromPos);
// This turns out to be a link, back out!
return -1;
}
return cx.addElement(
cx.elt("Attribute", pos, endPos, [
cx.elt("Attribute", pos, pos + valueLength + 1, [
cx.elt("AttributeMark", pos, pos + 1), // [
cx.elt("AttributeName", pos + 1, pos + 1 + attributeName.length),
cx.elt(
@@ -180,9 +207,9 @@ export const Attribute: MarkdownConfig = {
cx.elt(
"AttributeValue",
pos + 1 + attributeName.length + attributeColon.length,
endPos - 1,
pos + valueLength,
),
cx.elt("AttributeMark", endPos - 1, endPos), // [
cx.elt("AttributeMark", pos + valueLength, pos + valueLength + 1), // [
]),
);
},