rehype-pretty / rehype-pretty-code

Beautiful code blocks for Markdown or MDX.

Home Page:https://rehype-pretty.pages.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Katex element is incorrectly identified as inline code and rendered accordingly

ben519 opened this issue · comments

commented

Firstly, this package is amazing - thanks for your hard work on it!

I'm using rehypeKatex along with this package. In rehypeKatex (and most other LaTex-like markdown libraries) you denote block-style equations with opening and closing double dollar signs ($$). For example,

$$
x = 1
$$

This products an AST like this

{
  type: 'root',
  children: [
    {
      type: 'element',
      tagName: 'pre',
      properties: {},
      children: [
        {
          type: 'element',
          tagName: 'code',
          properties: { className: [ 'language-math' ] },
          children: [ { type: 'text', value: 'x = 1' } ]
        }
      ],
      position: {
        start: { line: 6, column: 1, offset: 34 },
        end: { line: 8, column: 3, offset: 45 }
      }
    },
    { type: 'text', value: '\n' }
  ]
}

rehype-pretty-code then incorrectly assumes this is inline code and styles it accordingly. I believe the definition for isInlineCode is to blame.

export function isInlineCode(
  element: Element,
  parent: Element | Root | undefined,
): element is Element {
  return (
    (element.tagName === 'code' &&
      isElement(parent) &&
      parent.tagName !== 'pre') ||
    element.tagName === 'inlineCode'
  );
}

As a temporary hack, I can avoid the issue by placing rehypeKatex before rehypePrettyCode in my processor. But I would rather not do this.

Could you alter the definition for isInlineCode() to be a little more strict, perhaps confirming that the element className does not include 'language-math'?

I don't see why isInlineCode would be the issue since it checks if there's a pre parent, and in your AST there is one?

commented

Oops, my mistake. The culprit must be isBlockCode()

export function isBlockCode(element: Element): element is Element {
  return (
    element.tagName === 'pre' &&
    Array.isArray(element.children) &&
    element.children.length === 1 &&
    isElement(element.children[0]) &&
    element.children[0].tagName === 'code'
  );
}