mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-30 16:24:06 -06:00
Rewrite parser application
This commit is contained in:
parent
c1c8e26722
commit
8f96809bf3
@ -65,7 +65,7 @@ const config: QuartzConfig = {
|
|||||||
},
|
},
|
||||||
keepBackground: false,
|
keepBackground: false,
|
||||||
}),
|
}),
|
||||||
Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
|
//Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
|
||||||
Plugin.GitHubFlavoredMarkdown(),
|
Plugin.GitHubFlavoredMarkdown(),
|
||||||
Plugin.TableOfContents(),
|
Plugin.TableOfContents(),
|
||||||
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
|
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
|
||||||
@ -77,8 +77,8 @@ const config: QuartzConfig = {
|
|||||||
Plugin.AliasRedirects(),
|
Plugin.AliasRedirects(),
|
||||||
Plugin.ComponentResources(),
|
Plugin.ComponentResources(),
|
||||||
Plugin.ContentPage(),
|
Plugin.ContentPage(),
|
||||||
//Plugin.FolderPage(),
|
Plugin.FolderPage(),
|
||||||
//Plugin.TagPage(),
|
Plugin.TagPage(),
|
||||||
Plugin.ContentIndex({
|
Plugin.ContentIndex({
|
||||||
enableSiteMap: true,
|
enableSiteMap: true,
|
||||||
enableRSS: true,
|
enableRSS: true,
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-
|
|||||||
import { JSResource } from "../../../util/resources"
|
import { JSResource } from "../../../util/resources"
|
||||||
import { Root } from "mdast"
|
import { Root } from "mdast"
|
||||||
import { Pluggable } from "unified"
|
import { Pluggable } from "unified"
|
||||||
|
import { visit } from "unist-util-visit"
|
||||||
|
import { Element, Literal, Root as HtmlRoot } from "hast"
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
@ -22,16 +24,16 @@ export const CustomDefault: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(tree, file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
|
||||||
mdastFindReplace(tree, replacements)
|
|
||||||
}
|
|
||||||
return replacements
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins(tree, file) {
|
||||||
const plug: Pluggable = () => {}
|
if (opts.enabled) {
|
||||||
return plug
|
return () => {
|
||||||
|
visit(tree!, "element", (node) => {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {} as Pluggable
|
||||||
},
|
},
|
||||||
externalResources() {
|
externalResources() {
|
||||||
const js = {} as JSResource
|
const js = {} as JSResource
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { QuartzParser } from "../../types"
|
import { QuartzParser } from "../../types"
|
||||||
import { JSResource } from "../../../util/resources"
|
import { JSResource } from "../../../util/resources"
|
||||||
|
import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace"
|
||||||
import { Pluggable } from "unified"
|
import { Pluggable } from "unified"
|
||||||
import rehypeSlug from "rehype-slug"
|
import rehypeSlug from "rehype-slug"
|
||||||
import rehypeAutolinkHeadings from "rehype-autolink-headings"
|
import rehypeAutolinkHeadings from "rehype-autolink-headings"
|
||||||
@ -22,9 +23,8 @@ export const GitHubLinkheadings: QuartzParser<Partial<Options>> = (userOpts) =>
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(tree, file) {
|
||||||
const plug: Pluggable = () => {}
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
return plug
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
if (opts.enabled) {
|
if (opts.enabled) {
|
||||||
@ -74,10 +74,9 @@ export const GitHubLinkheadings: QuartzParser<Partial<Options>> = (userOpts) =>
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
] as Pluggable[]
|
] as Pluggable
|
||||||
} else {
|
|
||||||
return [] as Pluggable[]
|
|
||||||
}
|
}
|
||||||
|
return [] as Pluggable
|
||||||
},
|
},
|
||||||
externalResources() {
|
externalResources() {
|
||||||
const js = {} as JSResource
|
const js = {} as JSResource
|
||||||
|
|||||||
@ -22,11 +22,11 @@ export const GitHubSmartypants: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins() {
|
||||||
if (opts.enabled) {
|
if (opts.enabled) {
|
||||||
return [remarkGfm, smartypants]
|
return smartypants as Pluggable
|
||||||
}
|
}
|
||||||
return [remarkGfm]
|
return {} as Pluggable
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -8,12 +8,10 @@ import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
|||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
inHtml: Boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: Options = {
|
const defaultOptions: Options = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
inHtml: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrowMapping: Record<string, string> = {
|
const arrowMapping: Record<string, string> = {
|
||||||
@ -41,24 +39,21 @@ export const ObsidianArrow: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins() {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
if (opts.enabled) {
|
||||||
const plug: Pluggable = (tree: Root, _path) => {
|
return [
|
||||||
if (opts.enabled) {
|
arrowRegex,
|
||||||
replacements.push([
|
(value: string, ..._capture: string[]) => {
|
||||||
arrowRegex,
|
const maybeArrow = arrowMapping[value]
|
||||||
(value: string, ..._capture: string[]) => {
|
if (maybeArrow === undefined) return SKIP
|
||||||
const maybeArrow = arrowMapping[value]
|
return {
|
||||||
if (maybeArrow === undefined) return SKIP
|
type: "html",
|
||||||
return {
|
value: `<span>${maybeArrow}</span>`,
|
||||||
type: "html",
|
}
|
||||||
value: `<span>${maybeArrow}</span>`,
|
},
|
||||||
}
|
] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return replacements
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -26,18 +26,14 @@ export const ObsidianBlockReference: QuartzParser<Partial<Options>> = (userOpts)
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_tree, _file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
|
||||||
mdastFindReplace(tree, replacements)
|
|
||||||
}
|
|
||||||
return replacements
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins(tree, file) {
|
||||||
const inlineTagTypes = new Set(["p", "li"])
|
const inlineTagTypes = new Set(["p", "li"])
|
||||||
const blockTagTypes = new Set(["blockquote"])
|
const blockTagTypes = new Set(["blockquote"])
|
||||||
if (opts.enabled) {
|
if (opts.enabled) {
|
||||||
const plug: Pluggable = (tree: HtmlRoot, file) => {
|
return () => {
|
||||||
file.data.blocks = {}
|
file.data.blocks = {}
|
||||||
|
|
||||||
visit(tree, "element", (node, index, parent) => {
|
visit(tree, "element", (node, index, parent) => {
|
||||||
@ -106,7 +102,6 @@ export const ObsidianBlockReference: QuartzParser<Partial<Options>> = (userOpts)
|
|||||||
|
|
||||||
file.data.htmlAst = tree
|
file.data.htmlAst = tree
|
||||||
}
|
}
|
||||||
return plug
|
|
||||||
}
|
}
|
||||||
return {} as Pluggable
|
return {} as Pluggable
|
||||||
},
|
},
|
||||||
|
|||||||
@ -77,113 +77,110 @@ export const ObsidianCallouts: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
|
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(tree, _file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
if (opts.enabled && tree !== undefined) {
|
||||||
const plug: Pluggable = (tree: Root, _path) => {
|
visit(tree, "blockquote", (node) => {
|
||||||
if (opts.enabled) {
|
if (node.children.length === 0) {
|
||||||
visit(tree, "blockquote", (node) => {
|
return
|
||||||
if (node.children.length === 0) {
|
}
|
||||||
return
|
|
||||||
|
// find first line and callout content
|
||||||
|
const [firstChild, ...calloutContent] = node.children
|
||||||
|
if (firstChild.type !== "paragraph" || firstChild.children[0]?.type !== "text") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = firstChild.children[0].value
|
||||||
|
const restOfTitle = firstChild.children.slice(1)
|
||||||
|
const [firstLine, ...remainingLines] = text.split("\n")
|
||||||
|
const remainingText = remainingLines.join("\n")
|
||||||
|
|
||||||
|
const match = firstLine.match(calloutRegex)
|
||||||
|
if (match && match.input) {
|
||||||
|
const [calloutDirective, typeString, calloutMetaData, collapseChar] = match
|
||||||
|
const calloutType = canonicalizeCallout(typeString.toLowerCase())
|
||||||
|
const collapse = collapseChar === "+" || collapseChar === "-"
|
||||||
|
const defaultState = collapseChar === "-" ? "collapsed" : "expanded"
|
||||||
|
const titleContent = match.input.slice(calloutDirective.length).trim()
|
||||||
|
const useDefaultTitle = titleContent === "" && restOfTitle.length === 0
|
||||||
|
const titleNode: Paragraph = {
|
||||||
|
type: "paragraph",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
value: useDefaultTitle ? capitalize(typeString) : titleContent + " ",
|
||||||
|
},
|
||||||
|
...restOfTitle,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
const title = mdastToHtml(titleNode)
|
||||||
|
|
||||||
// find first line and callout content
|
const toggleIcon = `<div class="fold-callout-icon"></div>`
|
||||||
const [firstChild, ...calloutContent] = node.children
|
|
||||||
if (firstChild.type !== "paragraph" || firstChild.children[0]?.type !== "text") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const text = firstChild.children[0].value
|
const titleHtml: Html = {
|
||||||
const restOfTitle = firstChild.children.slice(1)
|
type: "html",
|
||||||
const [firstLine, ...remainingLines] = text.split("\n")
|
value: `<div
|
||||||
const remainingText = remainingLines.join("\n")
|
|
||||||
|
|
||||||
const match = firstLine.match(calloutRegex)
|
|
||||||
if (match && match.input) {
|
|
||||||
const [calloutDirective, typeString, calloutMetaData, collapseChar] = match
|
|
||||||
const calloutType = canonicalizeCallout(typeString.toLowerCase())
|
|
||||||
const collapse = collapseChar === "+" || collapseChar === "-"
|
|
||||||
const defaultState = collapseChar === "-" ? "collapsed" : "expanded"
|
|
||||||
const titleContent = match.input.slice(calloutDirective.length).trim()
|
|
||||||
const useDefaultTitle = titleContent === "" && restOfTitle.length === 0
|
|
||||||
const titleNode: Paragraph = {
|
|
||||||
type: "paragraph",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
value: useDefaultTitle ? capitalize(typeString) : titleContent + " ",
|
|
||||||
},
|
|
||||||
...restOfTitle,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
const title = mdastToHtml(titleNode)
|
|
||||||
|
|
||||||
const toggleIcon = `<div class="fold-callout-icon"></div>`
|
|
||||||
|
|
||||||
const titleHtml: Html = {
|
|
||||||
type: "html",
|
|
||||||
value: `<div
|
|
||||||
class="callout-title"
|
class="callout-title"
|
||||||
>
|
>
|
||||||
<div class="callout-icon"></div>
|
<div class="callout-icon"></div>
|
||||||
<div class="callout-title-inner">${title}</div>
|
<div class="callout-title-inner">${title}</div>
|
||||||
${collapse ? toggleIcon : ""}
|
${collapse ? toggleIcon : ""}
|
||||||
</div>`,
|
</div>`,
|
||||||
}
|
|
||||||
|
|
||||||
const blockquoteContent: (BlockContent | DefinitionContent)[] = [titleHtml]
|
|
||||||
if (remainingText.length > 0) {
|
|
||||||
blockquoteContent.push({
|
|
||||||
type: "paragraph",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
value: remainingText,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace first line of blockquote with title and rest of the paragraph text
|
|
||||||
node.children.splice(0, 1, ...blockquoteContent)
|
|
||||||
|
|
||||||
const classNames = ["callout", calloutType]
|
|
||||||
if (collapse) {
|
|
||||||
classNames.push("is-collapsible")
|
|
||||||
}
|
|
||||||
if (defaultState === "collapsed") {
|
|
||||||
classNames.push("is-collapsed")
|
|
||||||
}
|
|
||||||
|
|
||||||
// add properties to base blockquote
|
|
||||||
node.data = {
|
|
||||||
hProperties: {
|
|
||||||
...(node.data?.hProperties ?? {}),
|
|
||||||
className: classNames.join(" "),
|
|
||||||
"data-callout": calloutType,
|
|
||||||
"data-callout-fold": collapse,
|
|
||||||
"data-callout-metadata": calloutMetaData,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add callout-content class to callout body if it has one.
|
|
||||||
if (calloutContent.length > 0) {
|
|
||||||
const contentData: BlockContent | DefinitionContent = {
|
|
||||||
data: {
|
|
||||||
hProperties: {
|
|
||||||
className: "callout-content",
|
|
||||||
},
|
|
||||||
hName: "div",
|
|
||||||
},
|
|
||||||
type: "blockquote",
|
|
||||||
children: [...calloutContent],
|
|
||||||
}
|
|
||||||
node.children = [node.children[0], contentData]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
const blockquoteContent: (BlockContent | DefinitionContent)[] = [titleHtml]
|
||||||
|
if (remainingText.length > 0) {
|
||||||
|
blockquoteContent.push({
|
||||||
|
type: "paragraph",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
value: remainingText,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace first line of blockquote with title and rest of the paragraph text
|
||||||
|
node.children.splice(0, 1, ...blockquoteContent)
|
||||||
|
|
||||||
|
const classNames = ["callout", calloutType]
|
||||||
|
if (collapse) {
|
||||||
|
classNames.push("is-collapsible")
|
||||||
|
}
|
||||||
|
if (defaultState === "collapsed") {
|
||||||
|
classNames.push("is-collapsed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// add properties to base blockquote
|
||||||
|
node.data = {
|
||||||
|
hProperties: {
|
||||||
|
...(node.data?.hProperties ?? {}),
|
||||||
|
className: classNames.join(" "),
|
||||||
|
"data-callout": calloutType,
|
||||||
|
"data-callout-fold": collapse,
|
||||||
|
"data-callout-metadata": calloutMetaData,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add callout-content class to callout body if it has one.
|
||||||
|
if (calloutContent.length > 0) {
|
||||||
|
const contentData: BlockContent | DefinitionContent = {
|
||||||
|
data: {
|
||||||
|
hProperties: {
|
||||||
|
className: "callout-content",
|
||||||
|
},
|
||||||
|
hName: "div",
|
||||||
|
},
|
||||||
|
type: "blockquote",
|
||||||
|
children: [...calloutContent],
|
||||||
|
}
|
||||||
|
node.children = [node.children[0], contentData]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return replacements
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -29,12 +29,8 @@ export const ObsidianCheckboxes: QuartzParser<Partial<Options>> = (userOpts) =>
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_tree, _file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
|
||||||
mdastFindReplaceInHtml(tree, replacements, opts.inHtml)
|
|
||||||
}
|
|
||||||
return replacements
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
if (opts.enabled) {
|
if (opts.enabled) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-
|
|||||||
import { JSResource } from "../../../util/resources"
|
import { JSResource } from "../../../util/resources"
|
||||||
import { Root } from "mdast"
|
import { Root } from "mdast"
|
||||||
import { Pluggable } from "unified"
|
import { Pluggable } from "unified"
|
||||||
|
import { visit } from "unist-util-visit"
|
||||||
import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
@ -32,14 +33,16 @@ export const ObsidianComments: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
|
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(tree, file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
const plug: Pluggable = (tree: Root, _file) => {}
|
|
||||||
return replacements
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins(tree, file) {
|
||||||
const plug: Pluggable = () => {}
|
if (opts.enabled) {
|
||||||
return plug
|
return () => {
|
||||||
|
visit(tree, "element", (node) => {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {} as Pluggable
|
||||||
},
|
},
|
||||||
externalResources() {
|
externalResources() {
|
||||||
const js = {} as JSResource
|
const js = {} as JSResource
|
||||||
|
|||||||
@ -7,12 +7,10 @@ import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
|||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
inHtml: Boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: Options = {
|
const defaultOptions: Options = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
inHtml: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlightRegex = new RegExp(/==([^=]+)==/g)
|
const highlightRegex = new RegExp(/==([^=]+)==/g)
|
||||||
@ -29,23 +27,20 @@ export const ObsidianHighlights: QuartzParser<Partial<Options>> = (userOpts) =>
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins() {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
if (opts.enabled) {
|
||||||
const plug: Pluggable = (tree: Root, _path) => {
|
return [
|
||||||
if (opts.enabled) {
|
highlightRegex,
|
||||||
replacements.push([
|
(_value: string, ...capture: string[]) => {
|
||||||
highlightRegex,
|
const [inner] = capture
|
||||||
(_value: string, ...capture: string[]) => {
|
return {
|
||||||
const [inner] = capture
|
type: "html",
|
||||||
return {
|
value: `<span class="text-highlight">${inner}</span>`,
|
||||||
type: "html",
|
}
|
||||||
value: `<span class="text-highlight">${inner}</span>`,
|
},
|
||||||
}
|
] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return replacements
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
71
quartz/plugins/parsers/obsidian/html.ts
Normal file
71
quartz/plugins/parsers/obsidian/html.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { QuartzParser } from "../../types"
|
||||||
|
import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace"
|
||||||
|
import { JSResource } from "../../../util/resources"
|
||||||
|
import { Root, Html, Paragraph } from "mdast"
|
||||||
|
import { Pluggable } from "unified"
|
||||||
|
import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
||||||
|
import { SKIP, visit } from "unist-util-visit"
|
||||||
|
import { toHast } from "mdast-util-to-hast"
|
||||||
|
import { toHtml } from "hast-util-to-html"
|
||||||
|
import { PhrasingContent } from "mdast-util-find-and-replace/lib"
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
enabled: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultOptions: Options = {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const mdastToHtml = (ast: PhrasingContent | Paragraph) => {
|
||||||
|
const hast = toHast(ast, { allowDangerousHtml: true })!
|
||||||
|
return toHtml(hast, { allowDangerousHtml: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ObsidianHtml: QuartzParser<Partial<Options>> = (userOpts) => {
|
||||||
|
const opts: Options = { ...defaultOptions, ...userOpts }
|
||||||
|
return {
|
||||||
|
name: "ObsidianHtml",
|
||||||
|
textTransform(_ctx, src: string | Buffer) {
|
||||||
|
if (opts.enabled) {
|
||||||
|
if (src instanceof Buffer) {
|
||||||
|
src = src.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
},
|
||||||
|
markdownPlugins(tree, _file, replacements) {
|
||||||
|
if (opts.enabled && tree !== undefined && replacements !== undefined) {
|
||||||
|
return visit(tree, "html", (node: Html) => {
|
||||||
|
for (const [regex, replace] of replacements) {
|
||||||
|
if (typeof replace === "string") {
|
||||||
|
node.value = node.value.replace(regex, replace)
|
||||||
|
} else {
|
||||||
|
node.value = node.value.replace(regex, (substring: string, ...args) => {
|
||||||
|
const replaceValue = replace(substring, ...args)
|
||||||
|
if (typeof replaceValue === "string") {
|
||||||
|
return replaceValue
|
||||||
|
} else if (Array.isArray(replaceValue)) {
|
||||||
|
return replaceValue.map(mdastToHtml).join("")
|
||||||
|
} else if (typeof replaceValue === "object" && replaceValue !== null) {
|
||||||
|
return mdastToHtml(replaceValue)
|
||||||
|
} else {
|
||||||
|
return substring
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
|
},
|
||||||
|
htmlPlugins() {
|
||||||
|
const plug: Pluggable = () => {}
|
||||||
|
return plug
|
||||||
|
},
|
||||||
|
externalResources() {
|
||||||
|
const js = {} as JSResource
|
||||||
|
return js
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ export { ObsidianCallouts } from "./callouts"
|
|||||||
export { ObsidianCheckboxes } from "./checkboxes"
|
export { ObsidianCheckboxes } from "./checkboxes"
|
||||||
export { ObsidianComments } from "./comments"
|
export { ObsidianComments } from "./comments"
|
||||||
export { ObsidianHighlights } from "./highlights"
|
export { ObsidianHighlights } from "./highlights"
|
||||||
|
export { ObsidianHtml } from "./html"
|
||||||
export { ObsidianMermaid } from "./mermaid"
|
export { ObsidianMermaid } from "./mermaid"
|
||||||
export { ObsidianTags } from "./tags"
|
export { ObsidianTags } from "./tags"
|
||||||
export { ObsidianWikilinks } from "./wikilinks"
|
export { ObsidianWikilinks } from "./wikilinks"
|
||||||
|
|||||||
@ -25,22 +25,18 @@ export const ObsidianMermaid: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins() {
|
markdownPlugins(tree, _file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
if (opts.enabled && tree !== undefined) {
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
visit(tree, "code", (node: Code) => {
|
||||||
if (opts.enabled) {
|
if (node.lang === "mermaid") {
|
||||||
visit(tree, "code", (node: Code) => {
|
node.data = {
|
||||||
if (node.lang === "mermaid") {
|
hProperties: {
|
||||||
node.data = {
|
className: ["mermaid"],
|
||||||
hProperties: {
|
},
|
||||||
className: ["mermaid"],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
return replacements
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -8,13 +8,11 @@ import { Pluggable } from "unified"
|
|||||||
import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
import { mdastFindReplaceInHtml } from "../../transformers/markdown"
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
enabled: Boolean
|
enabled: ConstrainBoolean
|
||||||
inHtml: Boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: Options = {
|
const defaultOptions: Options = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
inHtml: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// (?:^| ) -> non-capturing group, tag should start be separated by a space or be the start of the line
|
// (?:^| ) -> non-capturing group, tag should start be separated by a space or be the start of the line
|
||||||
@ -35,45 +33,43 @@ export const ObsidianTags: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_tree, file) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
console.log(file)
|
||||||
const plug: Pluggable = (tree: Root, file) => {
|
if (opts.enabled && file !== undefined) {
|
||||||
if (opts.enabled) {
|
const base = pathToRoot(file.data.slug!)
|
||||||
const base = pathToRoot(file.data.slug!)
|
return [
|
||||||
replacements.push([
|
tagRegex,
|
||||||
tagRegex,
|
(_value: string, tag: string) => {
|
||||||
(_value: string, tag: string) => {
|
// Check if the tag only includes numbers and slashes
|
||||||
// Check if the tag only includes numbers and slashes
|
if (/^[\/\d]+$/.test(tag)) {
|
||||||
if (/^[\/\d]+$/.test(tag)) {
|
return false
|
||||||
return false
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tag = slugTag(tag)
|
tag = slugTag(tag)
|
||||||
if (file.data.frontmatter) {
|
if (file.data.frontmatter) {
|
||||||
const noteTags = file.data.frontmatter.tags ?? []
|
const noteTags = file.data.frontmatter.tags ?? []
|
||||||
file.data.frontmatter.tags = [...new Set([...noteTags, tag])]
|
file.data.frontmatter.tags = [...new Set([...noteTags, tag])]
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "link",
|
type: "link",
|
||||||
url: base + `/tags/${tag}`,
|
url: base + `/tags/${tag}`,
|
||||||
data: {
|
data: {
|
||||||
hProperties: {
|
hProperties: {
|
||||||
className: ["tag-link"],
|
className: ["tag-link"],
|
||||||
},
|
|
||||||
},
|
},
|
||||||
children: [
|
},
|
||||||
{
|
children: [
|
||||||
type: "text",
|
{
|
||||||
value: tag,
|
type: "text",
|
||||||
},
|
value: tag,
|
||||||
],
|
},
|
||||||
}
|
],
|
||||||
},
|
}
|
||||||
])
|
},
|
||||||
}
|
] as [RegExp, string | ReplaceFunction]
|
||||||
}
|
}
|
||||||
return replacements
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -24,23 +24,20 @@ export const ObsidianVideo: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(tree, _file) {
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
if (opts.enabled && tree !== undefined) {
|
||||||
if (opts.enabled) {
|
visit(tree, "image", (node, index, parent) => {
|
||||||
visit(tree, "image", (node, index, parent) => {
|
if (parent && index != undefined && videoExtensionRegex.test(node.url)) {
|
||||||
if (parent && index != undefined && videoExtensionRegex.test(node.url)) {
|
const newNode: Html = {
|
||||||
const newNode: Html = {
|
type: "html",
|
||||||
type: "html",
|
value: `<video controls src="${node.url}"></video>`,
|
||||||
value: `<video controls src="${node.url}"></video>`,
|
|
||||||
}
|
|
||||||
|
|
||||||
parent.children.splice(index, 1, newNode)
|
|
||||||
return SKIP
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
parent.children.splice(index, 1, newNode)
|
||||||
|
return SKIP
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return plug
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -9,12 +9,10 @@ import path from "path"
|
|||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
inHtml: Boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: Options = {
|
const defaultOptions: Options = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
inHtml: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const externalLinkRegex = /^https?:\/\//i
|
const externalLinkRegex = /^https?:\/\//i
|
||||||
@ -82,86 +80,81 @@ export const ObsidianWikilinks: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
|
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins() {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
if (opts.enabled) {
|
||||||
const plug: Pluggable = (tree: Root, file) => {
|
return [
|
||||||
if (opts.enabled) {
|
wikilinkRegex,
|
||||||
replacements.push([
|
(value: string, ...capture: string[]) => {
|
||||||
wikilinkRegex,
|
let [rawFp, rawHeader, rawAlias] = capture
|
||||||
(value: string, ...capture: string[]) => {
|
const fp = rawFp?.trim() ?? ""
|
||||||
let [rawFp, rawHeader, rawAlias] = capture
|
const anchor = rawHeader?.trim() ?? ""
|
||||||
const fp = rawFp?.trim() ?? ""
|
const alias = rawAlias?.slice(1).trim()
|
||||||
const anchor = rawHeader?.trim() ?? ""
|
|
||||||
const alias = rawAlias?.slice(1).trim()
|
|
||||||
|
|
||||||
// embed cases
|
// embed cases
|
||||||
if (value.startsWith("!")) {
|
if (value.startsWith("!")) {
|
||||||
const ext: string = path.extname(fp).toLowerCase()
|
const ext: string = path.extname(fp).toLowerCase()
|
||||||
const url = slugifyFilePath(fp as FilePath)
|
const url = slugifyFilePath(fp as FilePath)
|
||||||
if ([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp"].includes(ext)) {
|
if ([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp"].includes(ext)) {
|
||||||
const match = wikilinkImageEmbedRegex.exec(alias ?? "")
|
const match = wikilinkImageEmbedRegex.exec(alias ?? "")
|
||||||
const alt = match?.groups?.alt ?? ""
|
const alt = match?.groups?.alt ?? ""
|
||||||
const width = match?.groups?.width ?? "auto"
|
const width = match?.groups?.width ?? "auto"
|
||||||
const height = match?.groups?.height ?? "auto"
|
const height = match?.groups?.height ?? "auto"
|
||||||
return {
|
return {
|
||||||
type: "image",
|
type: "image",
|
||||||
url,
|
url,
|
||||||
data: {
|
data: {
|
||||||
hProperties: {
|
hProperties: {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
alt,
|
alt,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
|
||||||
} else if ([".mp4", ".webm", ".ogv", ".mov", ".mkv"].includes(ext)) {
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
value: `<video src="${url}" controls></video>`,
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
[".mp3", ".webm", ".wav", ".m4a", ".ogg", ".3gp", ".flac"].includes(ext)
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
value: `<audio src="${url}" controls></audio>`,
|
|
||||||
}
|
|
||||||
} else if ([".pdf"].includes(ext)) {
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
value: `<iframe src="${url}" class="pdf"></iframe>`,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const block = anchor
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
data: { hProperties: { transclude: true } },
|
|
||||||
value: `<blockquote class="transclude" data-url="${url}" data-block="${block}" data-embed-alias="${alias}"><a href="${
|
|
||||||
url + anchor
|
|
||||||
}" class="transclude-inner">Transclude of ${url}${block}</a></blockquote>`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, fall through to regular link
|
|
||||||
}
|
|
||||||
|
|
||||||
// internal link
|
|
||||||
const url = fp + anchor
|
|
||||||
return {
|
|
||||||
type: "link",
|
|
||||||
url,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
value: alias ?? fp,
|
|
||||||
},
|
},
|
||||||
],
|
}
|
||||||
|
} else if ([".mp4", ".webm", ".ogv", ".mov", ".mkv"].includes(ext)) {
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
value: `<video src="${url}" controls></video>`,
|
||||||
|
}
|
||||||
|
} else if ([".mp3", ".webm", ".wav", ".m4a", ".ogg", ".3gp", ".flac"].includes(ext)) {
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
value: `<audio src="${url}" controls></audio>`,
|
||||||
|
}
|
||||||
|
} else if ([".pdf"].includes(ext)) {
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
value: `<iframe src="${url}" class="pdf"></iframe>`,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const block = anchor
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
data: { hProperties: { transclude: true } },
|
||||||
|
value: `<blockquote class="transclude" data-url="${url}" data-block="${block}" data-embed-alias="${alias}"><a href="${
|
||||||
|
url + anchor
|
||||||
|
}" class="transclude-inner">Transclude of ${url}${block}</a></blockquote>`,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
])
|
// otherwise, fall through to regular link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internal link
|
||||||
|
const url = fp + anchor
|
||||||
|
return {
|
||||||
|
type: "link",
|
||||||
|
url,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
value: alias ?? fp,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
] as [RegExp, string | ReplaceFunction]
|
||||||
}
|
}
|
||||||
return replacements
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
|
|||||||
@ -27,16 +27,12 @@ export const ObsidianYouTube: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_file, _tree) {
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
return [new RegExp(""), ""] as [RegExp, string | ReplaceFunction]
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
|
||||||
mdastFindReplace(tree, replacements)
|
|
||||||
}
|
|
||||||
return replacements
|
|
||||||
},
|
},
|
||||||
htmlPlugins() {
|
htmlPlugins(tree, _file) {
|
||||||
if (opts.enabled) {
|
if (opts.enabled) {
|
||||||
const plug: Pluggable = (tree: HtmlRoot, _file) => {
|
return () => {
|
||||||
visit(tree, "element", (node) => {
|
visit(tree, "element", (node) => {
|
||||||
if (node.tagName === "img" && typeof node.properties.src === "string") {
|
if (node.tagName === "img" && typeof node.properties.src === "string") {
|
||||||
const match = node.properties.src.match(ytLinkRegex)
|
const match = node.properties.src.match(ytLinkRegex)
|
||||||
@ -68,7 +64,6 @@ export const ObsidianYouTube: QuartzParser<Partial<Options>> = (userOpts) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return plug
|
|
||||||
}
|
}
|
||||||
return {} as Pluggable
|
return {} as Pluggable
|
||||||
},
|
},
|
||||||
|
|||||||
@ -44,6 +44,7 @@ import {
|
|||||||
ObsidianCheckboxes,
|
ObsidianCheckboxes,
|
||||||
ObsidianComments,
|
ObsidianComments,
|
||||||
ObsidianHighlights,
|
ObsidianHighlights,
|
||||||
|
ObsidianHtml,
|
||||||
ObsidianMermaid,
|
ObsidianMermaid,
|
||||||
ObsidianTags,
|
ObsidianTags,
|
||||||
ObsidianVideo,
|
ObsidianVideo,
|
||||||
@ -249,14 +250,14 @@ export const GitHubFlavoredMarkdown: QuartzTransformerPlugin<Partial<GitHubOptio
|
|||||||
const opts = { ...defaultGitHubOptions, ...userOpts }
|
const opts = { ...defaultGitHubOptions, ...userOpts }
|
||||||
return {
|
return {
|
||||||
name: "GitHubFlavoredMarkdown",
|
name: "GitHubFlavoredMarkdown",
|
||||||
textTransform(ctx, src) {
|
/*textTransform(ctx, src) {
|
||||||
return src
|
return src
|
||||||
},
|
},*/
|
||||||
markdownPlugins(ctx) {
|
markdownPlugins() {
|
||||||
const plugins: PluggableList = []
|
const plugins: PluggableList = [remarkGfm]
|
||||||
|
|
||||||
plugins.push(
|
plugins.push(
|
||||||
GitHubSmartypants({ enabled: opts.enableSmartyPants }).markdownPlugins(ctx) as Pluggable,
|
GitHubSmartypants({ enabled: opts.enableSmartyPants }).markdownPlugins() as Pluggable,
|
||||||
)
|
)
|
||||||
|
|
||||||
return plugins
|
return plugins
|
||||||
@ -264,15 +265,15 @@ export const GitHubFlavoredMarkdown: QuartzTransformerPlugin<Partial<GitHubOptio
|
|||||||
htmlPlugins() {
|
htmlPlugins() {
|
||||||
const plugins: PluggableList = []
|
const plugins: PluggableList = []
|
||||||
|
|
||||||
plugins.push.apply(GitHubLinkheadings({ enabled: opts.linkHeadings }).htmlPlugins())
|
plugins.push(GitHubLinkheadings({ enabled: opts.linkHeadings }).htmlPlugins())
|
||||||
|
|
||||||
return plugins
|
return plugins
|
||||||
},
|
},
|
||||||
externalResources() {
|
/*externalResources() {
|
||||||
const js: JSResource[] = []
|
const js: JSResource[] = []
|
||||||
|
|
||||||
return { js }
|
return { js }
|
||||||
},
|
},*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,67 +290,61 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<ObsidianO
|
|||||||
|
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(ctx) {
|
markdownPlugins(_ctx) {
|
||||||
const plugins: PluggableList = []
|
const plugins: PluggableList = []
|
||||||
|
|
||||||
const inHtml = opts.enableInHtmlEmbed
|
plugins.push((tree: Root, file) => {
|
||||||
|
const replacements: [RegExp, string | ReplaceFunction][] = []
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
if (file !== undefined && file.data !== undefined) {
|
||||||
|
const base = pathToRoot(file.data.slug!)
|
||||||
replacements.push.apply(
|
|
||||||
ObsidianWikilinks({ enabled: opts.wikilinks, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
replacements.push.apply(
|
|
||||||
ObsidianHighlights({ enabled: opts.highlight, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
replacements.push.apply(
|
|
||||||
ObsidianArrow({ enabled: opts.parseArrows, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
replacements.push.apply(
|
|
||||||
ObsidianTags({ enabled: opts.parseTags, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
|
|
||||||
plugins.push(() => {
|
|
||||||
return (tree: Root, file) => {
|
|
||||||
mdastFindReplaceInHtml(tree, replacements, inHtml)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replacements.push(
|
||||||
|
ObsidianWikilinks({ enabled: opts.wikilinks }).markdownPlugins() as [
|
||||||
|
RegExp,
|
||||||
|
string | ReplaceFunction,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
replacements.push(
|
||||||
|
ObsidianHighlights({ enabled: opts.highlight }).markdownPlugins() as [
|
||||||
|
RegExp,
|
||||||
|
string | ReplaceFunction,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
replacements.push(
|
||||||
|
ObsidianArrow({ enabled: opts.parseArrows }).markdownPlugins() as [
|
||||||
|
RegExp,
|
||||||
|
string | ReplaceFunction,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
replacements.push(
|
||||||
|
ObsidianTags({ enabled: opts.parseTags }).markdownPlugins() as [
|
||||||
|
RegExp,
|
||||||
|
string | ReplaceFunction,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
/*ObsidianHtml({ enabled: opts.enableInHtmlEmbed }).markdownPlugins(
|
||||||
|
tree,
|
||||||
|
undefined,
|
||||||
|
replacements,
|
||||||
|
)*/
|
||||||
|
|
||||||
|
mdastFindReplace(tree, replacements)
|
||||||
})
|
})
|
||||||
|
|
||||||
/*plugins.push(() => {
|
/*plugins.push(() => {
|
||||||
return (tree: Root, file) => {
|
return (tree: Root, file) =>
|
||||||
//const replacements: [RegExp, string | ReplaceFunction][] = []
|
ObsidianVideo({ enabled: opts.enableVideoEmbed }).markdownPlugins(tree)
|
||||||
//const base = pathToRoot(file.data.slug!)
|
})
|
||||||
|
plugins.push(() => {
|
||||||
ObsidianWikilinks({ enabled: opts.wikilinks }).markdownPlugins(ctx)
|
return (tree: Root, file) =>
|
||||||
|
ObsidianCallouts({ enabled: opts.callouts }).markdownPlugins(tree)
|
||||||
ObsidianHighlights({ enabled: opts.highlight }).markdownPlugins(ctx)
|
})
|
||||||
|
plugins.push(() => {
|
||||||
ObsidianArrow({ enabled: opts.parseArrows }).markdownPlugins(ctx)
|
return (tree: Root, file) =>
|
||||||
|
ObsidianMermaid({ enabled: opts.mermaid }).markdownPlugins(tree)
|
||||||
//mdastFindReplace(tree, replacements)
|
|
||||||
}
|
|
||||||
})*/
|
})*/
|
||||||
/*plugins.push(
|
|
||||||
ObsidianWikilinks({ enabled: opts.wikilinks, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
plugins.push(
|
|
||||||
ObsidianHighlights({ enabled: opts.highlight, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
plugins.push(
|
|
||||||
ObsidianArrow({ enabled: opts.parseArrows, inHtml: inHtml }).markdownPlugins(ctx),
|
|
||||||
)
|
|
||||||
plugins.push(ObsidianTags({ enabled: opts.parseTags, inHtml: inHtml }).markdownPlugins(ctx))*/
|
|
||||||
plugins.push(() => {
|
|
||||||
return (tree: Root, file) =>
|
|
||||||
ObsidianVideo({ enabled: opts.enableVideoEmbed }).markdownPlugins(ctx)
|
|
||||||
})
|
|
||||||
plugins.push(() => {
|
|
||||||
return (tree: Root, file) =>
|
|
||||||
ObsidianCallouts({ enabled: opts.callouts }).markdownPlugins(ctx)
|
|
||||||
})
|
|
||||||
plugins.push(() => {
|
|
||||||
return (tree: Root, file) => ObsidianMermaid({ enabled: opts.mermaid }).markdownPlugins(ctx)
|
|
||||||
})
|
|
||||||
|
|
||||||
return plugins
|
return plugins
|
||||||
},
|
},
|
||||||
@ -357,12 +352,12 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<ObsidianO
|
|||||||
const plugins: PluggableList = [rehypeRaw]
|
const plugins: PluggableList = [rehypeRaw]
|
||||||
|
|
||||||
plugins.push(() => {
|
plugins.push(() => {
|
||||||
return (tree: Root, file) =>
|
return (tree: HtmlRoot, file) =>
|
||||||
ObsidianBlockReference({ enabled: opts.parseBlockReferences }).htmlPlugins() as Pluggable
|
ObsidianBlockReference({ enabled: opts.parseBlockReferences }).htmlPlugins(tree, file)
|
||||||
})
|
})
|
||||||
plugins.push(() => {
|
plugins.push(() => {
|
||||||
return (tree: Root, file) =>
|
return (tree: HtmlRoot, file) =>
|
||||||
ObsidianYouTube({ enabled: opts.enableYouTubeEmbed }).htmlPlugins() as Pluggable
|
ObsidianYouTube({ enabled: opts.enableYouTubeEmbed }).htmlPlugins(tree, file)
|
||||||
})
|
})
|
||||||
/*plugins.push(() => {
|
/*plugins.push(() => {
|
||||||
return (tree: HtmlRoot, file) => ObsidianCheckboxes({ enabled: opts.enableCheckbox }).htmlPlugins() as Pluggable}
|
return (tree: HtmlRoot, file) => ObsidianCheckboxes({ enabled: opts.enableCheckbox }).htmlPlugins() as Pluggable}
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import { QuartzComponent } from "../components/types"
|
|||||||
import { FilePath } from "../util/path"
|
import { FilePath } from "../util/path"
|
||||||
import { BuildCtx } from "../util/ctx"
|
import { BuildCtx } from "../util/ctx"
|
||||||
import DepGraph from "../depgraph"
|
import DepGraph from "../depgraph"
|
||||||
|
import { Root } from "mdast-util-find-and-replace/lib"
|
||||||
|
import { Element, Literal, Root as HtmlRoot } from "hast"
|
||||||
|
|
||||||
export interface PluginTypes {
|
export interface PluginTypes {
|
||||||
transformers: QuartzTransformerPluginInstance[]
|
transformers: QuartzTransformerPluginInstance[]
|
||||||
@ -57,7 +59,11 @@ export type QuartzParser<Options extends OptionType = undefined> = (
|
|||||||
export type QuartzParserInstance = {
|
export type QuartzParserInstance = {
|
||||||
name: string
|
name: string
|
||||||
textTransform: (ctx: BuildCtx, src: string | Buffer) => string | Buffer
|
textTransform: (ctx: BuildCtx, src: string | Buffer) => string | Buffer
|
||||||
markdownPlugins: (ctx: BuildCtx) => [RegExp, string | ReplaceFunction][]
|
markdownPlugins: (
|
||||||
htmlPlugins: () => Pluggable | Pluggable[]
|
tree?: Root,
|
||||||
|
file?: any,
|
||||||
|
replacements?: [RegExp, string | ReplaceFunction][],
|
||||||
|
) => [RegExp, string | ReplaceFunction] | Pluggable | void
|
||||||
|
htmlPlugins: (tree?: HtmlRoot, file?: any) => Pluggable
|
||||||
externalResources: () => JSResource | string
|
externalResources: () => JSResource | string
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user