Changes
9 changed files (+270/-10)
-
-
@@ -22,6 +22,7 @@export { macanaReplaceAssetTokens } from "./obsidian_markdown/mdast_util_macana_replace_asset_tokens.ts"; export { macanaReplaceDocumentToken } from "./obsidian_markdown/mdast_util_macana_replace_document_tokens.ts"; export { ofmToHastHandlers } from "./obsidian_markdown/mdast_util_ofm.ts"; export { ofmHtml } from "./obsidian_markdown/hast_util_ofm_html.ts"; export type { CalloutType } from "./obsidian_markdown/mdast_util_ofm_callout.ts"; function getFrontMatterValue(
-
-
-
@@ -0,0 +1,157 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 import { assertObjectMatch } from "../../deps/deno.land/std/assert/mod.ts"; import { ofmHtml } from "./hast_util_ofm_html.ts"; Deno.test("Should strip <style>", () => { assertObjectMatch( ofmHtml({ type: "root", children: [ { type: "element", tagName: "style", properties: {}, children: [ { type: "text", value: "body{display:none;}", }, ], }, { type: "text", value: "Foo", }, ], }), { type: "root", children: [ { type: "text", value: "Foo", }, ], }, ); }); Deno.test("Should strip <script>", () => { assertObjectMatch( ofmHtml({ type: "root", children: [ { type: "element", tagName: "script", properties: {}, children: [ { type: "text", value: "alert('yay')", }, ], }, { type: "text", value: "Foo", }, ], }), { type: "root", children: [ { type: "text", value: "Foo", }, ], }, ); }); Deno.test("Should strip <title>", () => { assertObjectMatch( ofmHtml({ type: "root", children: [ { type: "element", tagName: "title", properties: {}, children: [ { type: "text", value: "404", }, ], }, { type: "text", value: "Foo", }, ], }), { type: "root", children: [ { type: "text", value: "Foo", }, ], }, ); }); Deno.test("Should strip hidden inside another tag", () => { assertObjectMatch( ofmHtml({ type: "root", children: [ { type: "element", tagName: "div", properties: {}, children: [ { type: "element", tagName: "script", properties: {}, children: [ { type: "text", value: "alert('yay')", }, ], }, { type: "text", value: "Foo", }, ], }, ], }), { type: "root", children: [ { type: "element", tagName: "div", properties: {}, children: [ { type: "text", value: "Foo", }, ], }, ], }, ); });
-
-
-
@@ -0,0 +1,30 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 import type * as Hast from "../../deps/esm.sh/hast/types.ts"; import { raw } from "../../deps/esm.sh/hast-util-raw/mod.ts"; import { remove } from "../../deps/esm.sh/unist-util-remove/mod.ts"; const stripTags = ["script", "style", "title"]; function isElement(node: Hast.Node): node is Hast.Element { return node.type === "element"; } /** * This function mutates Hast tree to somewhat align to Obsidian's HTML handling * inside Markdown document. This function does not guarantee or aim to 100% compatible * as Obsidian does not publish formal spec of their Markdown. Also their implementation * is quite buggy to the degree it's almost impossible to write compatible processor. */ export function ofmHtml(tree: Hast.Nodes): Hast.Nodes { const converted = raw(tree); // Using bare unist utility, as hast-util-sanitize cannot blacklist elements remove(converted, (node) => { return isElement(node) && stripTags.includes(node.tagName); }); return converted; }
-
-
-
@@ -231,17 +231,26 @@ "https://esm.sh/v135/character-reference-invalid@2.0.1/denonext/character-reference-invalid.mjs": "41034e591247fb2bc6a12dd190e776b84cfe1da74e984fef3efbff2a97814d53","https://esm.sh/v135/comma-separated-tokens@2.0.3/denonext/comma-separated-tokens.mjs": "ad5df8a36487e0a63d15bbbb6bab8b153e08583d0d5eb6d0058cd0fc619252e0", "https://esm.sh/v135/decode-named-character-reference@1.0.2/denonext/decode-named-character-reference.mjs": "1a5a8f9cbe302be478e964ab701be8644dbdfd4d8ce9f14de186cf84ee2a4bc1", "https://esm.sh/v135/devlop@1.1.0/denonext/devlop.mjs": "05fffa5a5168daec45963b784734dbc468758e130a340af874adfe0d457e394a", "https://esm.sh/v135/entities@4.5.0/denonext/lib/decode.js": "7fea6d8bd725edbbf7ea05031d2ea1bbbc1166dc11e3345d541198dd2dc16f1e", "https://esm.sh/v135/entities@4.5.0/denonext/lib/escape.js": "7ebdc622bf3618bab25db40da4a49e2b9d03f044745f125f0bc3359f2d060def", "https://esm.sh/v135/escape-string-regexp@5.0.0/denonext/escape-string-regexp.mjs": "6080dd39c43a11f999a41172a27b8c58572d747d8276c039d93d4be8b21747a5", "https://esm.sh/v135/estree-util-is-identifier-name@3.0.0/denonext/estree-util-is-identifier-name.mjs": "2d1080530be602e98e40807bbb760a08a017b315be59fe869b57afca5d667dca", "https://esm.sh/v135/hast-util-from-parse5@8.0.1/denonext/hast-util-from-parse5.mjs": "1c3f8a5b4fab57bb4edfd4dd5646c6857c1fb0bd9aab82b10720035e10a26505", "https://esm.sh/v135/hast-util-is-element@3.0.0": "d5b1ded368a5fbbcb79687bebcf33d94a37020bd82116c1bec69a012f17e5cf2", "https://esm.sh/v135/hast-util-is-element@3.0.0/denonext/hast-util-is-element.mjs": "d6abf8aaf1da9775a8731295649387cf59ceb0b50eae25953bee6ea9af8043af", "https://esm.sh/v135/hast-util-parse-selector@3.1.1/denonext/hast-util-parse-selector.mjs": "df576c8298a048d9aad89506f5884db91bc249bb6e221b9fd3b228eb40980a62", "https://esm.sh/v135/hast-util-parse-selector@4.0.0/denonext/hast-util-parse-selector.mjs": "bd794c65760a29b2ba20eef4de4f94d4b480a45ae01d2047957143a37e4adbb5", "https://esm.sh/v135/hast-util-raw@9.0.2": "0ec383b32ef4ecbcbfa35f1107befae9038743edcadba6eb8c2c485f7e609101", "https://esm.sh/v135/hast-util-raw@9.0.2/denonext/hast-util-raw.mjs": "47b434e3ac191454283f7077edb75508d53ef5b52e5a025df0121941867f0624", "https://esm.sh/v135/hast-util-to-jsx-runtime@2.3.0": "d70b72b8ff9932e3953de3fbcf7690ca6174a30c9a48bd236b4aa743229c2cfb", "https://esm.sh/v135/hast-util-to-jsx-runtime@2.3.0/denonext/hast-util-to-jsx-runtime.mjs": "c94c36c11225b1d6f36dc7e3f13597a223058510eceb11fa97b844a3bd176fc4", "https://esm.sh/v135/hast-util-to-parse5@8.0.0/denonext/hast-util-to-parse5.mjs": "b3ce8667b168b69115ada0ca9fe4ec2cd750fcee5a87c594fe1e50b516fa167a", "https://esm.sh/v135/hast-util-to-string@3.0.0": "efe413bc8cc4a67ac6b84b46e2fc2b0a79e4d7e4a31707cc8e60fab683b71080", "https://esm.sh/v135/hast-util-to-string@3.0.0/denonext/hast-util-to-string.mjs": "4f7c061733fa8e99e3055e443c09a8d4e7f6e95ccd7a06b61d38682989bf6ba8", "https://esm.sh/v135/hast-util-whitespace@3.0.0/denonext/hast-util-whitespace.mjs": "b2988a87d03b42636bca6ebee778326993a23953ba6638973be17ce03100a357", "https://esm.sh/v135/hastscript@7.2.0/denonext/hastscript.mjs": "21c0292f187622f364e3b3b91db0cdea352b3e5cb61b6557583a2c74b9d8d76e", "https://esm.sh/v135/hastscript@8.0.0/denonext/hastscript.mjs": "55a8079d45899d20a70c6968c3a46b15d247d223b02b1804b79f49bae5dc9a06", "https://esm.sh/v135/html-void-elements@3.0.0/denonext/html-void-elements.mjs": "331b966249908a14e21bcbd584cc9f88d8df7d78a4bed94f002c9fd297d17459", "https://esm.sh/v135/inline-style-parser@0.2.2/denonext/inline-style-parser.mjs": "6b516634a2a716b57fa335bdaf9910c568a01330bfb7686ca534228aff59149e", "https://esm.sh/v135/is-alphabetical@2.0.1/denonext/is-alphabetical.mjs": "d0feb3b8b248c1c89544825a12db253946e94532c3ba2df47c5ce9ed06a10242", "https://esm.sh/v135/is-alphanumerical@2.0.1/denonext/is-alphanumerical.mjs": "978a2d980f37c9b42b82e6dc915455d43a9ba5f7d11c6f314d5ef5694ed9427e",
-
@@ -305,6 +314,7 @@ "https://esm.sh/v135/micromark-util-types@2.0.0/denonext/micromark-util-types.mjs": "e9ed9735f978ab0109a89d83c2c230281cbf881341a60c027344b987c4acb3cd","https://esm.sh/v135/micromark@4.0.0": "caad3cf8d257301f26f48d2cc53267370f2f7108e98e1e75e93f411a9ec766eb", "https://esm.sh/v135/micromark@4.0.0/denonext/micromark.mjs": "dc73ed793c5bbc49ad7201a326fc724d08bc94372a291c184167b22c4edc320d", "https://esm.sh/v135/parse-entities@4.0.1/denonext/parse-entities.mjs": "d850db8f1291c1f42a880afb290f6c0774871651092c3fed6f9dedfee8f971c4", "https://esm.sh/v135/parse5@7.1.2/denonext/parse5.mjs": "35bb04ec36a1c25c8cd8137296d64d16fd523a8ad1c2b63c41ba867fcd455c36", "https://esm.sh/v135/property-information@6.4.0/denonext/property-information.mjs": "8a61ad4cc589e3a30c752bd2eea7703cf286139c919f55f4fd289b90a7ac65a9", "https://esm.sh/v135/refractor@4.8.1/denonext/lang/abap.js": "d172cd4efeb8a73131e075ac5b1a598da105375b75e6d11c7eccd79b667e1758", "https://esm.sh/v135/refractor@4.8.1/denonext/lang/abnf.js": "1a600d9650e59f20dffbc0a01b177596f11e5bea31b7494912e1e0a195b7a2a3",
-
@@ -610,12 +620,16 @@ "https://esm.sh/v135/style-to-object@1.0.5/denonext/style-to-object.mjs": "fa46c0fbe36f636aec3f7a3f5af231c37b9265a444c343cd3067ec2d214c18d0","https://esm.sh/v135/trim-lines@3.0.1/denonext/trim-lines.mjs": "f01a20253341eb2554f307ab05bc9cd93d6f33bcbb24fde2fc9fcd857564283e", "https://esm.sh/v135/unist-util-is@6.0.0/denonext/unist-util-is.mjs": "d92da46b3a1084450f150cc06c02f3bf85b93ab4c4b43a960d72a4f5678e95cc", "https://esm.sh/v135/unist-util-position@5.0.0/denonext/unist-util-position.mjs": "aaef05774a54f2b84400e98325219e2ba6cf966e318173bcd895647c56bb8871", "https://esm.sh/v135/unist-util-remove@4.0.0": "b4e11a095e2758fea44136dca7ecd2cf45814e715a1a1d99187119361d7408d4", "https://esm.sh/v135/unist-util-remove@4.0.0/denonext/unist-util-remove.mjs": "f998d12fa69e64e8c1f1f6a896094013b5c162d96f3bbf25d92caabd060a8572", "https://esm.sh/v135/unist-util-stringify-position@4.0.0/denonext/unist-util-stringify-position.mjs": "dabd32cb2b590bbb077fc6f6591a2e065cffd6c55646ba383455926a27ea64d7", "https://esm.sh/v135/unist-util-visit-parents@6.0.1/denonext/do-not-use-color.js": "a1c0a6b93471dd4ed996804dd8a2b9f753c83c4a2da98373253e6b312c8492e2", "https://esm.sh/v135/unist-util-visit-parents@6.0.1/denonext/unist-util-visit-parents.mjs": "5f7ececae47bea6d87b7e323153a7415ad8f299dc42e61aefda6d28eaf264c64", "https://esm.sh/v135/unist-util-visit@5.0.0": "39c6a28445ca31c6ad1e97c663c9d6f86d8820a2b5893c77e2d363cb630c8dc5", "https://esm.sh/v135/unist-util-visit@5.0.0/denonext/unist-util-visit.mjs": "6c1b5b3d517cc6dbc88406b2dbab1735d503a797e994dbd4a89f3764098318f7", "https://esm.sh/v135/vfile-location@5.0.2/denonext/vfile-location.mjs": "9a7912bc394ed9af26d91b97db831926b0e8ce965ae20f000f25ab17c2658d03", "https://esm.sh/v135/vfile-message@4.0.2/denonext/vfile-message.mjs": "efc85b18bedda337fb1c20cdc452fac3addac32ee55948cebf2845396ae641ac", "https://esm.sh/v135/web-namespaces@2.0.1/denonext/web-namespaces.mjs": "bc6ee363bbe40abddca68678e849584981176d9bde3728b4c5d47a5241dac7bf", "https://esm.sh/v135/zwitch@2.0.4/denonext/zwitch.mjs": "c0e8c246a1f38b425335ea78cc366a7801d3ef89701229a35f85a51310e6e49f" } }
-
-
-
@@ -0,0 +1,5 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 export * from "https://esm.sh/v135/hast-util-raw@9.0.2";
-
-
-
@@ -0,0 +1,5 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 export * from "https://esm.sh/v135/unist-util-remove@4.0.0";
-
-
-
@@ -0,0 +1,47 @@From https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown: > Obsidian supports [CommonMark](https://commonmark.org/), [GitHub Flavored Markdown](https://github.github.com/gfm/), and [LaTeX](https://www.latex-project.org/). **Obsidian does not support using Markdown formatting or blank lines inside of HTML tags**. Emphasis by me. Now, let's see... ```markdown <div> <p> A. Plain **Bold** _Italic_ B. Plain ==Highlight== [[Roadmap]] </p> <p>C. Plain **Bold**</p> </div> ``` <div> <p> Foo </p> <p>Bar **Baz**</p> </div> <div> <p> A. Plain **Bold** _Italic_ B. Plain ==Highlight== [[Roadmap]] </p> <p>C. Plain **Bold**</p> </div> ```markdown <span>D. Plain **Bold** ==Highlight==</span> ``` <span>D. Plain **Bold** ==Highlight==</span> --- Obsidian renders every inner text as un-styled plain text in editing view. However, in reading view, it renders A and C as plain text but B and D as normal styled Markdown content. They seems to use customized parser for the editing view and existing CommonMark (or GFM) parser for the reading view.
-
-
-
@@ -1,6 +1,6 @@--- createdAt: 2024-04-15T23:00:00+09:00 updatedAt: 2024-04-20T01:00:00+09:00 updatedAt: 2024-04-23T23:00:00+09:00 --- - [x] Using Vault as a site structure
-
@@ -37,13 +37,12 @@ - [ ] Search results- [x] ==Highlight== - [x] Callouts - [x] Comments %% You can check this item once I'm no longer visible %% - [ ] Strip Raw HTML (only `<title>` is troublesome, but align behavior to Obsidian's) - [ ] `<script>` <script>console.log("This tag should be eliminated: escaping is not suffice")</script> - [ ] `<title>` <title>Foo</title> - [ ] `<style>` <style>* { display: none; }</style> - [ ] Keep Raw HTML (Unified libraries tends to ignore spec by default, needs to opt-out) - [ ] <span style="color: red; background-color: yellow;">Colored text</span> - [ ] Strip attributes not exist in whitelist - [x] Strip Raw HTML (only `<title>` is troublesome, but align behavior to Obsidian's) - [x] `<script>` <script>console.log("This tag should be eliminated: escaping is not suffice")</script> - [x] `<title>` <title>Foo</title> - [x] `<style>` <style>* { display: none; }</style> - [x] Keep Raw HTML (Unified libraries tends to ignore spec by default, needs to opt-out) - [x] <span style="color: red; background-color: yellow;">Colored text</span> - [ ] JSONCanvas - [ ] Node rendering - [x] Basic shapes
-
-
-
@@ -20,6 +20,7 @@ } from "../../../types.ts";import { type CalloutType, type ObsidianMarkdownDocument, ofmHtml, ofmToHastHandlers, } from "../../../content_parser/obsidian_markdown.ts"; import type { JSONCanvasDocument } from "../../../content_parser/json_canvas.ts";
-
@@ -175,7 +176,7 @@ );} function mdastToHast(input: Mdast.Nodes) { return toHast(input, { return ofmHtml(toHast(input, { // @ts-expect-error: unist-related libraries heavily relies on ambient module declarations, // which Deno does not support. APIs also don't accept type parameters. handlers: {
-
@@ -195,7 +196,8 @@ },}), ...syntaxHighlightingHandlers(), }, }); allowDangerousHtml: true, })); } interface ObsidianMarkdownBodyProps extends ViewProps {
-