Fixes #360
This commit is contained in:
parent
495012f796
commit
c1528eff08
20
mobile/android/app/release/output-metadata.json
Executable file
20
mobile/android/app/release/output-metadata.json
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "md.silverbullet",
|
||||||
|
"variantName": "release",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"attributes": [],
|
||||||
|
"versionCode": 1,
|
||||||
|
"versionName": "1.0",
|
||||||
|
"outputFile": "app-release.apk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"elementType": "File"
|
||||||
|
}
|
@ -30,12 +30,12 @@ Deno.test("Markdown render", async () => {
|
|||||||
// console.log("HTML", html);
|
// console.log("HTML", html);
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("Smart hard break test", () => {
|
Deno.test("Smart hard break test", async () => {
|
||||||
const example = `**Hello**
|
const example = `**Hello**
|
||||||
*world!*`;
|
*world!*`;
|
||||||
const lang = buildMarkdown([]);
|
const lang = buildMarkdown([]);
|
||||||
const tree = parse(lang, example);
|
const tree = parse(lang, example);
|
||||||
const html = renderMarkdownToHtml(tree, {
|
const html = await renderMarkdownToHtml(tree, {
|
||||||
failOnUnknown: true,
|
failOnUnknown: true,
|
||||||
smartHardBreak: true,
|
smartHardBreak: true,
|
||||||
});
|
});
|
||||||
|
@ -13,6 +13,8 @@ type MarkdownRenderOptions = {
|
|||||||
annotationPositions?: true;
|
annotationPositions?: true;
|
||||||
renderFrontMatter?: true;
|
renderFrontMatter?: true;
|
||||||
attachmentUrlPrefix?: string;
|
attachmentUrlPrefix?: string;
|
||||||
|
// When defined, use to inline images as data: urls
|
||||||
|
inlineAttachments?: (url: string) => Promise<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
function cleanTags(values: (Tag | null)[]): Tag[] {
|
function cleanTags(values: (Tag | null)[]): Tag[] {
|
||||||
@ -390,11 +392,36 @@ function render(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderMarkdownToHtml(
|
async function traverseTag(
|
||||||
|
t: Tag,
|
||||||
|
fn: (t: Tag) => Promise<void>,
|
||||||
|
): Promise<void> {
|
||||||
|
await fn(t);
|
||||||
|
if (typeof t === "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (t.body) {
|
||||||
|
for (const child of t.body) {
|
||||||
|
await traverseTag(child, fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function renderMarkdownToHtml(
|
||||||
t: ParseTree,
|
t: ParseTree,
|
||||||
options: MarkdownRenderOptions = {},
|
options: MarkdownRenderOptions = {},
|
||||||
) {
|
) {
|
||||||
preprocess(t, options);
|
preprocess(t, options);
|
||||||
const htmlTree = posPreservingRender(t, options);
|
const htmlTree = posPreservingRender(t, options);
|
||||||
|
if (htmlTree && options.inlineAttachments) {
|
||||||
|
await traverseTag(htmlTree, async (t) => {
|
||||||
|
if (typeof t === "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (t.name === "img") {
|
||||||
|
t.attrs!.src = await options.inlineAttachments!(t.attrs!.src!);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return renderHtml(htmlTree);
|
return renderHtml(htmlTree);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
import { clientStore, editor, system } from "$sb/silverbullet-syscall/mod.ts";
|
import {
|
||||||
|
clientStore,
|
||||||
|
editor,
|
||||||
|
space,
|
||||||
|
system,
|
||||||
|
} from "$sb/silverbullet-syscall/mod.ts";
|
||||||
import { asset } from "$sb/plugos-syscall/mod.ts";
|
import { asset } from "$sb/plugos-syscall/mod.ts";
|
||||||
import { parseMarkdown } from "../../plug-api/silverbullet-syscall/markdown.ts";
|
import { parseMarkdown } from "../../plug-api/silverbullet-syscall/markdown.ts";
|
||||||
import { renderMarkdownToHtml } from "./markdown_render.ts";
|
import { renderMarkdownToHtml } from "./markdown_render.ts";
|
||||||
@ -12,11 +17,21 @@ export async function updateMarkdownPreview() {
|
|||||||
// const cleanMd = await cleanMarkdown(text);
|
// const cleanMd = await cleanMarkdown(text);
|
||||||
const css = await asset.readAsset("assets/styles.css");
|
const css = await asset.readAsset("assets/styles.css");
|
||||||
const js = await asset.readAsset("assets/handler.js");
|
const js = await asset.readAsset("assets/handler.js");
|
||||||
const html = renderMarkdownToHtml(mdTree, {
|
const html = await renderMarkdownToHtml(mdTree, {
|
||||||
smartHardBreak: true,
|
smartHardBreak: true,
|
||||||
annotationPositions: true,
|
annotationPositions: true,
|
||||||
renderFrontMatter: true,
|
renderFrontMatter: true,
|
||||||
attachmentUrlPrefix: "fs/",
|
inlineAttachments: async (url): Promise<string> => {
|
||||||
|
if (!url.includes("://")) {
|
||||||
|
try {
|
||||||
|
return await space.readAttachment(url);
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error(e);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await editor.showPanel(
|
await editor.showPanel(
|
||||||
"rhs",
|
"rhs",
|
||||||
|
@ -7,7 +7,7 @@ export async function markdownWidget(
|
|||||||
): Promise<WidgetContent> {
|
): Promise<WidgetContent> {
|
||||||
const mdTree = await parseMarkdown(bodyText);
|
const mdTree = await parseMarkdown(bodyText);
|
||||||
|
|
||||||
const html = renderMarkdownToHtml(mdTree, {
|
const html = await renderMarkdownToHtml(mdTree, {
|
||||||
smartHardBreak: true,
|
smartHardBreak: true,
|
||||||
});
|
});
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -15,11 +15,12 @@ import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts";
|
|||||||
import { ParseTree } from "$sb/lib/tree.ts";
|
import { ParseTree } from "$sb/lib/tree.ts";
|
||||||
import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts";
|
import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.tsx";
|
||||||
|
import { urlToPathname } from "../../plugos/util.ts";
|
||||||
|
|
||||||
class TableViewWidget extends WidgetType {
|
class TableViewWidget extends WidgetType {
|
||||||
constructor(
|
constructor(
|
||||||
readonly pos: number,
|
readonly pos: number,
|
||||||
readonly editorView: EditorView,
|
readonly editor: Editor,
|
||||||
readonly t: ParseTree,
|
readonly t: ParseTree,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
@ -32,17 +33,31 @@ class TableViewWidget extends WidgetType {
|
|||||||
// Pulling data-pos to put the cursor in the right place, falling back
|
// Pulling data-pos to put the cursor in the right place, falling back
|
||||||
// to the start of the table.
|
// to the start of the table.
|
||||||
const dataAttributes = (e.target as any).dataset;
|
const dataAttributes = (e.target as any).dataset;
|
||||||
this.editorView.dispatch({
|
this.editor.editorView!.dispatch({
|
||||||
selection: {
|
selection: {
|
||||||
anchor: dataAttributes.pos ? +dataAttributes.pos : this.pos,
|
anchor: dataAttributes.pos ? +dataAttributes.pos : this.pos,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
dom.innerHTML = renderMarkdownToHtml(this.t, {
|
renderMarkdownToHtml(this.t, {
|
||||||
// Annotate every element with its position so we can use it to put
|
// Annotate every element with its position so we can use it to put
|
||||||
// the cursor there when the user clicks on the table.
|
// the cursor there when the user clicks on the table.
|
||||||
annotationPositions: true,
|
annotationPositions: true,
|
||||||
|
inlineAttachments: async (url): Promise<string> => {
|
||||||
|
if (!url.includes("://")) {
|
||||||
|
try {
|
||||||
|
const d = await this.editor.space.readAttachment(url, "dataurl");
|
||||||
|
return d.data as string;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error(e);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
}).then((html) => {
|
||||||
|
dom.innerHTML = html;
|
||||||
});
|
});
|
||||||
return dom;
|
return dom;
|
||||||
}
|
}
|
||||||
@ -90,7 +105,7 @@ export function tablePlugin(editor: Editor) {
|
|||||||
Decoration.widget({
|
Decoration.widget({
|
||||||
widget: new TableViewWidget(
|
widget: new TableViewWidget(
|
||||||
from,
|
from,
|
||||||
editor.editorView!,
|
editor,
|
||||||
lezerToParseTree(text, node.node),
|
lezerToParseTree(text, node.node),
|
||||||
),
|
),
|
||||||
}).range(from),
|
}).range(from),
|
||||||
|
Loading…
Reference in New Issue
Block a user