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

fix: Mermaid diagrams fail to render in search results with 'syntax error in text'" #9145

Conversation

reiji-h
Copy link
Contributor

@reiji-h reiji-h commented Sep 20, 2024

Summary

  • 検索結果ページのみで、mermaid が syntax error in text として表示されてしまう問題の修正
  • 原因は検索結果ページの検索文字ハイライターによるハイライトタグの挿入
  • 上記原因を回避するために、 remark の data.hProperties 経由で mermaid の文字列を送ることで回避した

Task

Notes

使用する mermaid のバージョンを更新

Copy link

changeset-bot bot commented Sep 20, 2024

⚠️ No Changeset found

Latest commit: 20f5215

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@@ -21,4 +24,7 @@ export const remarkPlugin: Plugin = function() {

export const sanitizeOption: SanitizeOption = {
tagNames: ['mermaid'],
attributes: {
mermaid: ['value'],
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なぜ attributes として value が必要になるのか説明してください

Copy link
Contributor Author

@reiji-h reiji-h Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回のエラーの原因は、検索結果ページの検索文字のハイライトタグが、mermaid ブロックの中に入ったとき、mermaid の文法エラーを引き起こすものでした。よって mermaid ブロックの中身を文字列として value に入れて MermaidViewer に送っています。

children のみでは出来ない理由は、特定の単語がハイライトされると MermaidViewer は children を文字列ではなく React.Element として受け取るためです。React.Element から文字列を復元することは一応出来ますが、その復元された文字列を使用しての mermaid 図の描画が出来ませんでした。

image

(画像は2つの mermaid 図を描画しようとしています。上はハイライトタグが入っていないので正しく描画され、下は入っているため syntax error。エラーが出ている方は children の type が react.element)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

であれば、もうちょっとやりようがあると思う。このままでは children と value の役割が冗長だし、MermaildViewer で中途半端に使っていたり使っていなかったりするので意図がわからない。

案1

MermaidViewerProps の型を変えるというのはやったのだろうか?
ここで children を string に限定すれば ReactMarkdown がよしなにやってくれるのであれば、children に一本化できる。

とはいえこの案は望み薄。

案2

案1 でうまくいかない場合は hast 時点まで遡る。
rewriteNode 処理 で children を text node にできないのだろうか?

https://github.com/syntax-tree/hast?tab=readme-ov-file#text

これでうまくいけば children に一本化できる。

案3

案1, 2両方共うまくいかない場合、hast では text node でも ReactMarkdown のおせっかいにより React.Element 化されるという診断になるか?
それであれば attribute を使う方が string 型になることが保証されるので、children を使わず attribute に一本化すればいいと思う。

Copy link
Contributor Author

@reiji-h reiji-h Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

結果として案3の採用となりました。

案1

string に制限しても React.Element が流れてきたので断念。

案2

mdast の Code は value: string しか持てず、任意の型の children を持たないので、node を paragraph にし children に text node を入れる形で実験してみましたが、結果は変わリませんでした。
image

そもそも keyword-highlighter は rehype-plugin であり、node のタイプが text のときにキーワードを em で挟む処理でした。これを避けるためには mermaid の中身の node のタイプが text ではなく element な必要がありますが、element 化しつつ中身をテキストとして扱える型や方法がなかったので案2 も断念。

@@ -21,4 +24,7 @@ export const remarkPlugin: Plugin = function() {

export const sanitizeOption: SanitizeOption = {
tagNames: ['mermaid'],
attributes: {
mermaid: ['value'],
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

であれば、もうちょっとやりようがあると思う。このままでは children と value の役割が冗長だし、MermaildViewer で中途半端に使っていたり使っていなかったりするので意図がわからない。

案1

MermaidViewerProps の型を変えるというのはやったのだろうか?
ここで children を string に限定すれば ReactMarkdown がよしなにやってくれるのであれば、children に一本化できる。

とはいえこの案は望み薄。

案2

案1 でうまくいかない場合は hast 時点まで遡る。
rewriteNode 処理 で children を text node にできないのだろうか?

https://github.com/syntax-tree/hast?tab=readme-ov-file#text

これでうまくいけば children に一本化できる。

案3

案1, 2両方共うまくいかない場合、hast では text node でも ReactMarkdown のおせっかいにより React.Element 化されるという診断になるか?
それであれば attribute を使う方が string 型になることが保証されるので、children を使わず attribute に一本化すればいいと思う。

mergify bot added a commit that referenced this pull request Oct 17, 2024
@yuki-takei
Copy link
Member

@mergify requeue

Copy link
Contributor

mergify bot commented Oct 17, 2024

requeue

✅ The queue state of this pull request has been cleaned. It can be re-embarked automatically

mergify bot added a commit that referenced this pull request Oct 17, 2024
@mergify mergify bot merged commit de07e4f into master Oct 17, 2024
21 checks passed
@mergify mergify bot deleted the fix/122548-153821-fix-mermaid-syntax-error-in-text-in-search-result branch October 17, 2024 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants