Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rehype-katex does not catch non-parse errors #82

Closed
4 tasks done
FindDefinition opened this issue Apr 23, 2023 · 7 comments
Closed
4 tasks done

rehype-katex does not catch non-parse errors #82

FindDefinition opened this issue Apr 23, 2023 · 7 comments
Labels
💪 phase/solved Post is done

Comments

@FindDefinition
Copy link

FindDefinition commented Apr 23, 2023

Initial checklist

Affected packages and versions

5.1.1

Link to runnable example

https://codesandbox.io/s/markdown-editor-with-katex-forked-x63zo4

Steps to reproduce

use invalid latex code with rehypeKatex and react-markdown:

\begin{split}
A & = \frac{\pi r^2}{2} \\
 & = \frac{1}{2} \pi r^2
\end{{split}}

Expected behavior

invalid latex code is displayed with red color
here is a fixed version of rehypeKatex that has expected behavior:

/**
 * @typedef {import('hast').Root} Root
 * @typedef {import('katex').KatexOptions} Options
 */

import katex from 'katex'
import {visit} from 'unist-util-visit'
import {removePosition} from 'unist-util-remove-position'
import {toText} from 'hast-util-to-text'
import {unified} from 'unified'
import rehypeParse from 'rehype-parse'

const assign = Object.assign

const parseHtml = unified().use(rehypeParse, {fragment: true})

const source = 'rehype-katex'

/**
 * Plugin to transform `<span class=math-inline>` and `<div class=math-display>`
 * with KaTeX.
 *
 * @type {import('unified').Plugin<[Options?]|void[], Root>}
 */
export default function rehypeKatex(options) {
  const settings = options || {}
  const throwOnError = settings.throwOnError || false

  return (tree, file) => {
    visit(tree, 'element', (element) => {
      const classes =
        element.properties && Array.isArray(element.properties.className)
          ? element.properties.className
          : []
      const inline = classes.includes('math-inline')
      const displayMode = classes.includes('math-display')

      if (!inline && !displayMode) {
        return
      }
      const value = toText(element, {whitespace: 'pre'})

      /** @type {string | null} */
      let result = null

      try {
        result = katex.renderToString(
          value,
          assign({}, settings, {displayMode, throwOnError: true})
        )
      } catch (error_) {
        const error = /** @type {Error} */ (error_)
        if (error instanceof katex.ParseError) {
            const fn = throwOnError ? 'fail' : 'message'
            const origin = [source, error.name.toLowerCase()].join(':')
    
            file[fn](error.message, element.position, origin)
            result = katex.renderToString(
              value,
              assign({}, settings, {
                displayMode,
                throwOnError: false,
                strict: 'ignore'
              })
            )    
        }else{
          result = `<div style="color: red">${value}</div>`
        }
      }
      // @ts-expect-error: assume no `doctypes` in KaTeX result.
      element.children = removePosition(parseHtml.parse(result), true).children
    })
  }
}

Actual behavior

element crash.

Runtime

No response

Package manager

No response

OS

No response

Build and bundle tools

No response

@github-actions github-actions bot added 👋 phase/new Post is being triaged automatically 🤞 phase/open Post is being triaged manually and removed 👋 phase/new Post is being triaged automatically labels Apr 23, 2023
@wooorm
Copy link
Member

wooorm commented Apr 23, 2023

Errors happen. You can handle errors: https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary

@wooorm wooorm closed this as not planned Won't fix, can't repro, duplicate, stale Apr 23, 2023
@wooorm wooorm added the 🙅 no/wontfix This is not (enough of) an issue for this project label Apr 23, 2023
@github-actions

This comment has been minimized.

@github-actions github-actions bot added 👎 phase/no Post cannot or will not be acted on and removed 🤞 phase/open Post is being triaged manually labels Apr 23, 2023
@FindDefinition
Copy link
Author

FindDefinition commented Apr 23, 2023

@wooorm ?????? I know the error boundry, if I use rehype-mathjax, the syntax error is handled inside mathjax to tell users that math block is wrong WITHOUT breaking render of legal markdown code, but it's impossible to implement this in rehype-katex via error boundry. this error will break whole react-markdown renderer.

@wooorm
Copy link
Member

wooorm commented Apr 23, 2023

I don’t know what you want.
Your codesandbox is broken.
Your code sandbox does not use react-markdown or rehype-katex.
If there is an error, show a stack trace.
Your issue title, “invalid latex code breaks whole react-markdown”, is incorrect: set throwOnError: false

@FindDefinition
Copy link
Author

FindDefinition commented Apr 23, 2023

@wooorm thanks for reply. This bug should be a katex bug, not rehype-katex. I will open a issue in katex.
Here is error image. the codesandbox is my mistake, should be fixed now.
image

@wooorm wooorm reopened this Apr 23, 2023
@wooorm wooorm added the 👍 phase/yes Post is accepted and can be worked on label Apr 23, 2023
@github-actions github-actions bot removed 👎 phase/no Post cannot or will not be acted on 🙅 no/wontfix This is not (enough of) an issue for this project labels Apr 23, 2023
@github-actions

This comment has been minimized.

@wooorm wooorm changed the title invalid latex code breaks whole react-markdown when use rehypeKatex rehype-katex does not catch non-parse errors Apr 23, 2023
@wooorm wooorm closed this as completed in e28098a Apr 23, 2023
@wooorm wooorm added the 💪 phase/solved Post is done label Apr 23, 2023
@github-actions github-actions bot removed the 👍 phase/yes Post is accepted and can be worked on label Apr 23, 2023
@wooorm
Copy link
Member

wooorm commented Apr 23, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💪 phase/solved Post is done
Development

No branches or pull requests

2 participants