1
0

Fixes #576 supporting markdown in headers and refactoring some stuff

This commit is contained in:
Zef Hemel 2023-11-27 16:29:19 +01:00
parent 1335820abd
commit 259ad5b488
8 changed files with 36 additions and 31 deletions

View File

@ -80,7 +80,7 @@ export function filterBox(
}
export function showPanel(
id: "lhs" | "rhs" | "bhs" | "modal" | "ps" | "preface",
id: "lhs" | "rhs" | "bhs" | "modal" | "bottom" | "top",
mode: number,
html: string,
script = "",
@ -89,7 +89,7 @@ export function showPanel(
}
export function hidePanel(
id: "lhs" | "rhs" | "bhs" | "modal" | "ps" | "preface",
id: "lhs" | "rhs" | "bhs" | "modal" | "bottom" | "top",
): Promise<void> {
return syscall("editor.hidePanel", id);
}

View File

@ -176,13 +176,13 @@ functions:
# TOC
toggleTOC:
path: toc_preface.ts:toggleTOC
path: toc.ts:toggleTOC
command:
name: "Table of Contents: Toggle"
key: ctrl-alt-t
renderTOC:
path: toc_preface.ts:renderTOC
path: toc.ts:renderTOC
env: client
events:
- editor:pageLoaded

View File

@ -12,7 +12,7 @@ export async function toggleMentions() {
if (!hideMentions) {
await renderMentions();
} else {
await editor.hidePanel("ps");
await editor.hidePanel("bottom");
}
}
@ -53,13 +53,13 @@ export async function renderMentions() {
});
if (linksResult.length === 0) {
// Don't show the panel if there are no links here.
await editor.hidePanel("ps");
await editor.hidePanel("bottom");
} else {
const css = await asset.readAsset("asset/style.css");
const js = await asset.readAsset("asset/linked_mentions.js");
await editor.showPanel(
"ps",
"bottom",
1,
` <style>${css}</style>
<div id="sb-main"><div id="sb-editor"><div class="cm-editor">

View File

@ -1,5 +1,10 @@
import { clientStore, editor, markdown } from "$sb/silverbullet-syscall/mod.ts";
import { renderToText, traverseTree } from "$sb/lib/tree.ts";
import {
clientStore,
editor,
markdown,
system,
} from "$sb/silverbullet-syscall/mod.ts";
import { renderToText, traverseTree, traverseTreeAsync } from "$sb/lib/tree.ts";
import { asset } from "$sb/syscalls.ts";
const hideTOCKey = "hideTOC";
@ -21,18 +26,24 @@ export async function toggleTOC() {
await renderTOC(); // This will hide it if needed
}
async function markdownToHtml(text: string): Promise<string> {
return system.invokeFunction("markdown.markdownToHtml", text);
}
export async function renderTOC(reload = false) {
if (await clientStore.get(hideTOCKey)) {
return editor.hidePanel("preface");
return editor.hidePanel("top");
}
const page = await editor.getCurrentPage();
const text = await editor.getText();
const tree = await markdown.parseMarkdown(text);
const headers: Header[] = [];
traverseTree(tree, (n) => {
await traverseTreeAsync(tree, async (n) => {
if (n.type?.startsWith("ATXHeading")) {
headers.push({
name: n.children!.slice(1).map(renderToText).join("").trim(),
name: await markdownToHtml(
n.children!.slice(1).map(renderToText).join("").trim(),
),
pos: n.from!,
level: +n.type[n.type.length - 1],
});
@ -49,20 +60,14 @@ export async function renderTOC(reload = false) {
cachedTOC = JSON.stringify(headers);
if (headers.length < headerThreshold) {
console.log("Not enough headers, not showing TOC", headers.length);
await editor.hidePanel("preface");
await editor.hidePanel("top");
return;
}
let tocMarkdown = "";
for (const header of headers) {
tocMarkdown += `${
" ".repeat(3 * (header.level - 1))
}* [${header.name}](/${page}@${header.pos})\n`;
}
const css = await asset.readAsset("asset/style.css");
const js = await asset.readAsset("asset/toc.js");
await editor.showPanel(
"preface",
"top",
1,
` <style>${css}</style>
<div id="sb-main"><div id="sb-editor"><div class="cm-editor">

View File

@ -42,26 +42,26 @@ class IFrameWidget extends WidgetType {
export function postScriptPrefacePlugin(editor: Client) {
return decoratorStateField((state: EditorState) => {
const widgets: any[] = [];
if (editor.ui.viewState.panels.preface.html) {
if (editor.ui.viewState.panels.top.html) {
widgets.push(
Decoration.widget({
widget: new IFrameWidget(
editor,
editor.ui.viewState.panels.preface,
"sb-preface-iframe",
editor.ui.viewState.panels.top,
"sb-top-iframe",
),
side: -1,
block: true,
}).range(0),
);
}
if (editor.ui.viewState.panels.ps.html) {
if (editor.ui.viewState.panels.bottom.html) {
widgets.push(
Decoration.widget({
widget: new IFrameWidget(
editor,
editor.ui.viewState.panels.ps,
"sb-ps-iframe",
editor.ui.viewState.panels.bottom,
"sb-bottom-iframe",
),
side: 1,
block: true,

View File

@ -40,7 +40,7 @@ import {
pasteLinkExtension,
} from "./cm_plugins/editor_paste.ts";
import { TextChange } from "$sb/lib/change.ts";
import { postScriptPrefacePlugin } from "./cm_plugins/preface_ps.ts";
import { postScriptPrefacePlugin } from "./cm_plugins/top_bottom_panels.ts";
import { languageFor } from "../common/languages.ts";
import { plugLinter } from "./cm_plugins/lint.ts";

View File

@ -147,14 +147,14 @@ body {
flex: 1;
}
.sb-ps-iframe {
.sb-bottom-iframe {
width: 100%;
margin-top: 10px;
border: 1px solid var(--editor-directive-background-color);
border-radius: 5px;
}
.sb-preface-iframe {
.sb-top-iframe {
width: 100%;
margin-top: 10px;
border: 1px solid var(--editor-directive-background-color);

View File

@ -90,8 +90,8 @@ export const initialViewState: AppViewState = {
rhs: {},
bhs: {},
modal: {},
ps: {},
preface: {},
top: {},
bottom: {},
},
allPages: [],
commands: new Map(),