Major directive refactor (#195)
Fixes #188 #144 #76: major refactor of directive parsing, rendering, styling
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { commandLinkRegex } from "../../common/parser.ts";
|
||||
import { commandLinkRegex } from "../../common/markdown_parser/parser.ts";
|
||||
import { ClickEvent } from "$sb/app_event.ts";
|
||||
import { Decoration, syntaxTree } from "../deps.ts";
|
||||
import { Editor } from "../editor.tsx";
|
||||
|
||||
+48
-33
@@ -10,49 +10,64 @@ import {
|
||||
export function directivePlugin() {
|
||||
return decoratorStateField((state: EditorState) => {
|
||||
const widgets: any[] = [];
|
||||
const cursorPos = state.selection.main.head;
|
||||
|
||||
// TODO: This doesn't handle nested directives properly
|
||||
let posOfLastOpen = { from: 0, to: 0 };
|
||||
|
||||
syntaxTree(state).iterate({
|
||||
enter: ({ type, from, to }) => {
|
||||
if (type.name !== "CommentBlock") {
|
||||
enter: ({ type, from, to, node }) => {
|
||||
const parent = node.parent;
|
||||
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
const text = state.sliceDoc(from, to);
|
||||
if (/<!--\s*#/.exec(text)) {
|
||||
// Open directive
|
||||
posOfLastOpen = { from, to };
|
||||
} else if (/<!--\s*\//.exec(text)) {
|
||||
// Close directive
|
||||
if (
|
||||
(cursorPos > to || cursorPos < posOfLastOpen.from) &&
|
||||
!isCursorInRange(state, [posOfLastOpen.from, to])
|
||||
) {
|
||||
|
||||
const cursorInRange = isCursorInRange(state, [parent.from, parent.to]);
|
||||
|
||||
if (type.name === "DirectiveStart") {
|
||||
if (cursorInRange) {
|
||||
// Cursor outside this directive
|
||||
widgets.push(
|
||||
invisibleDecoration.range(
|
||||
posOfLastOpen.from,
|
||||
posOfLastOpen.to + 1,
|
||||
),
|
||||
);
|
||||
widgets.push(
|
||||
invisibleDecoration.range(from - 1, to),
|
||||
Decoration.line({ class: "sb-directive-start" }).range(from),
|
||||
);
|
||||
} else {
|
||||
widgets.push(invisibleDecoration.range(from, to));
|
||||
widgets.push(
|
||||
Decoration.line({
|
||||
class: "sb-directive-start",
|
||||
}).range(posOfLastOpen.from),
|
||||
);
|
||||
widgets.push(
|
||||
Decoration.line({
|
||||
class: "sb-directive-end",
|
||||
}).range(from),
|
||||
Decoration.line({ class: "sb-directive-start-outside" }).range(
|
||||
state.doc.lineAt(to).from,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.name === "DirectiveEnd") {
|
||||
// Cursor outside this directive
|
||||
if (cursorInRange) {
|
||||
widgets.push(
|
||||
Decoration.line({ class: "sb-directive-end" }).range(from),
|
||||
);
|
||||
} else {
|
||||
widgets.push(invisibleDecoration.range(from, to));
|
||||
widgets.push(
|
||||
Decoration.line({ class: "sb-directive-end-outside" }).range(
|
||||
state.doc.lineAt(from - 1).from,
|
||||
),
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.name === "DirectiveBody") {
|
||||
const lines = state.sliceDoc(from, to).split("\n");
|
||||
let pos = from;
|
||||
for (const line of lines) {
|
||||
if (pos !== to) {
|
||||
widgets.push(
|
||||
Decoration.line({
|
||||
class: "sb-directive-body",
|
||||
}).range(pos),
|
||||
);
|
||||
}
|
||||
pos += line.length + 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ const straightQuoteContexts = [
|
||||
"FencedCode",
|
||||
"InlineCode",
|
||||
"FrontMatterCode",
|
||||
"DirectiveStart",
|
||||
];
|
||||
|
||||
// TODO: Add support for selection (put quotes around or create blockquote block?)
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
|
||||
import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts";
|
||||
import { ParseTree } from "$sb/lib/tree.ts";
|
||||
import { lezerToParseTree } from "../../common/parse_tree.ts";
|
||||
import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts";
|
||||
import type { Editor } from "../editor.tsx";
|
||||
|
||||
class TableViewWidget extends WidgetType {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { pageLinkRegex } from "../../common/parser.ts";
|
||||
import { pageLinkRegex } from "../../common/markdown_parser/parser.ts";
|
||||
import { ClickEvent } from "../../plug-api/app_event.ts";
|
||||
import { Decoration, syntaxTree } from "../deps.ts";
|
||||
import { Editor } from "../editor.tsx";
|
||||
|
||||
Reference in New Issue
Block a user