fix: catch html to jsx errors (closes #547)
This commit is contained in:
parent
14a5196822
commit
735315a01b
@ -247,7 +247,7 @@ If you are creating an emitter plugin that needs to render components, there are
|
|||||||
|
|
||||||
- Your component should use `getQuartzComponents` to declare a list of `QuartzComponents` that it uses to construct the page. See the page on [[creating components]] for more information.
|
- Your component should use `getQuartzComponents` to declare a list of `QuartzComponents` that it uses to construct the page. See the page on [[creating components]] for more information.
|
||||||
- You can use the `renderPage` function defined in `quartz/components/renderPage.tsx` to render Quartz components into HTML.
|
- You can use the `renderPage` function defined in `quartz/components/renderPage.tsx` to render Quartz components into HTML.
|
||||||
- If you need to render an HTML AST to JSX, you can use the `toJsxRuntime` function from `hast-util-to-jsx-runtime` library. An example of this can be found in `quartz/components/pages/Content.tsx`.
|
- If you need to render an HTML AST to JSX, you can use the `htmlToJsx` function from `quartz/util/jsx.ts`. An example of this can be found in `quartz/components/pages/Content.tsx`.
|
||||||
|
|
||||||
For example, the following is a simplified version of the content page plugin that renders every single page.
|
For example, the following is a simplified version of the content page plugin that renders every single page.
|
||||||
|
|
||||||
|
@ -33,10 +33,13 @@ TagList.css = `
|
|||||||
gap: 0.4rem;
|
gap: 0.4rem;
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: flex-end;
|
|
||||||
justify-self: end;
|
justify-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section-ul .tags {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
.tags > li {
|
.tags > li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
|
import { htmlToJsx } from "../../util/jsx"
|
||||||
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
|
||||||
import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
|
|
||||||
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
|
|
||||||
|
|
||||||
function Content({ tree }: QuartzComponentProps) {
|
function Content({ fileData, tree }: QuartzComponentProps) {
|
||||||
// @ts-ignore (preact makes it angry)
|
const content = htmlToJsx(fileData.filePath!, tree)
|
||||||
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
|
|
||||||
return <article class="popover-hint">{content}</article>
|
return <article class="popover-hint">{content}</article>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
|
||||||
import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
|
|
||||||
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|
||||||
import style from "../styles/listPage.scss"
|
import style from "../styles/listPage.scss"
|
||||||
@ -8,6 +6,7 @@ import { PageList } from "../PageList"
|
|||||||
import { _stripSlashes, simplifySlug } from "../../util/path"
|
import { _stripSlashes, simplifySlug } from "../../util/path"
|
||||||
import { Root } from "hast"
|
import { Root } from "hast"
|
||||||
import { pluralize } from "../../util/lang"
|
import { pluralize } from "../../util/lang"
|
||||||
|
import { htmlToJsx } from "../../util/jsx"
|
||||||
|
|
||||||
function FolderContent(props: QuartzComponentProps) {
|
function FolderContent(props: QuartzComponentProps) {
|
||||||
const { tree, fileData, allFiles } = props
|
const { tree, fileData, allFiles } = props
|
||||||
@ -29,8 +28,7 @@ function FolderContent(props: QuartzComponentProps) {
|
|||||||
const content =
|
const content =
|
||||||
(tree as Root).children.length === 0
|
(tree as Root).children.length === 0
|
||||||
? fileData.description
|
? fileData.description
|
||||||
: // @ts-ignore
|
: htmlToJsx(fileData.filePath!, tree)
|
||||||
toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="popover-hint">
|
<div class="popover-hint">
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
|
||||||
import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
|
|
||||||
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
|
|
||||||
import style from "../styles/listPage.scss"
|
import style from "../styles/listPage.scss"
|
||||||
import { PageList } from "../PageList"
|
import { PageList } from "../PageList"
|
||||||
import { FullSlug, getAllSegmentPrefixes, simplifySlug } from "../../util/path"
|
import { FullSlug, getAllSegmentPrefixes, simplifySlug } from "../../util/path"
|
||||||
import { QuartzPluginData } from "../../plugins/vfile"
|
import { QuartzPluginData } from "../../plugins/vfile"
|
||||||
import { Root } from "hast"
|
import { Root } from "hast"
|
||||||
import { pluralize } from "../../util/lang"
|
import { pluralize } from "../../util/lang"
|
||||||
|
import { htmlToJsx } from "../../util/jsx"
|
||||||
|
|
||||||
const numPages = 10
|
const numPages = 10
|
||||||
function TagContent(props: QuartzComponentProps) {
|
function TagContent(props: QuartzComponentProps) {
|
||||||
@ -26,8 +25,7 @@ function TagContent(props: QuartzComponentProps) {
|
|||||||
const content =
|
const content =
|
||||||
(tree as Root).children.length === 0
|
(tree as Root).children.length === 0
|
||||||
? fileData.description
|
? fileData.description
|
||||||
: // @ts-ignore
|
: htmlToJsx(fileData.filePath!, tree)
|
||||||
toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
|
|
||||||
|
|
||||||
if (tag === "") {
|
if (tag === "") {
|
||||||
const tags = [...new Set(allFiles.flatMap((data) => data.frontmatter?.tags ?? []))]
|
const tags = [...new Set(allFiles.flatMap((data) => data.frontmatter?.tags ?? []))]
|
||||||
|
15
quartz/util/jsx.ts
Normal file
15
quartz/util/jsx.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
|
||||||
|
import { QuartzPluginData } from "../plugins/vfile"
|
||||||
|
import { Node, Root } from "hast"
|
||||||
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
|
||||||
|
import { trace } from "./trace"
|
||||||
|
import { type FilePath } from "./path"
|
||||||
|
|
||||||
|
export function htmlToJsx(fp: FilePath, tree: Node<QuartzPluginData>) {
|
||||||
|
try {
|
||||||
|
// @ts-ignore (preact makes it angry)
|
||||||
|
return toJsxRuntime(tree as Root, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
|
||||||
|
} catch (e) {
|
||||||
|
trace(`Failed to parse Markdown in \`${fp}\` into JSX`, e as Error)
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { isMainThread } from "workerpool"
|
|||||||
|
|
||||||
const rootFile = /.*at file:/
|
const rootFile = /.*at file:/
|
||||||
export function trace(msg: string, err: Error) {
|
export function trace(msg: string, err: Error) {
|
||||||
const stack = err.stack
|
let stack = err.stack ?? ""
|
||||||
|
|
||||||
const lines: string[] = []
|
const lines: string[] = []
|
||||||
|
|
||||||
@ -12,15 +12,11 @@ export function trace(msg: string, err: Error) {
|
|||||||
lines.push(
|
lines.push(
|
||||||
"\n" +
|
"\n" +
|
||||||
chalk.bgRed.black.bold(" ERROR ") +
|
chalk.bgRed.black.bold(" ERROR ") +
|
||||||
"\n" +
|
"\n\n" +
|
||||||
chalk.red(` ${msg}`) +
|
chalk.red(` ${msg}`) +
|
||||||
(err.message.length > 0 ? `: ${err.message}` : ""),
|
(err.message.length > 0 ? `: ${err.message}` : ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!stack) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let reachedEndOfLegibleTrace = false
|
let reachedEndOfLegibleTrace = false
|
||||||
for (const line of stack.split("\n").slice(1)) {
|
for (const line of stack.split("\n").slice(1)) {
|
||||||
if (reachedEndOfLegibleTrace) {
|
if (reachedEndOfLegibleTrace) {
|
||||||
|
Loading…
Reference in New Issue
Block a user