aarkue / tiptap-math-extension

Math Extension for the TipTap Editor
https://aarkue.github.io/tiptap-math-extension/
MIT License
42 stars 7 forks source link

Pasting rich HTML content mixed with LaTeX #7

Open rajatkulkarni95 opened 3 months ago

rajatkulkarni95 commented 3 months ago

Requires deleting the trailing $ and re-adding it for it to work.

https://github.com/aarkue/tiptap-math-extension/assets/57321156/d751e640-cf73-4c9f-bfcb-388e39a913ce

rajatkulkarni95 commented 3 months ago

Is evaluate: 'no' the reason?

https://github.com/aarkue/tiptap-math-extension/blob/main/packages/tiptap-math-extension/src/inline-math-node.ts#L131

aarkue commented 3 months ago

I think this might be an issue with the pasting rules regex, but not sure yet.

Could you include the latex string you are having the issue with and your browser version?

I tried pasting $\left\{\begin{matrix}x&\text{ if }x>0\\0&\text{otherwise}\end{matrix}\right.$ on Firefox mobile and could not reproduce the problem.

Screenshot_20240608-082546_Firefox.png

rajatkulkarni95 commented 3 months ago

Ah I think my version had an extra \ at the beginning?

Anyway, is there a way to allow editing without requiring a backspace? Like it the equation was focused? Tiptap's Mathematics one does it, any reason why this doesn't?

rajatkulkarni95 commented 3 months ago

@aarkue Can you try pasting stuff from https://tiptap.dev/docs/editor/api/extensions/mathematics#katex-options example and see if it renders automatically?

I tried and it doesn't.

https://github.com/aarkue/tiptap-math-extension/assets/57321156/34fd5d0a-1165-4d5f-9356-8ab76eed1276

aarkue commented 3 months ago

Ah I think my version had an extra \ at the beginning?

Anyway, is there a way to allow editing without requiring a backspace? Like it the equation was focused? Tiptap's Mathematics one does it, any reason why this doesn't?

To be honest, I am not really a fan of the jump from rendered LaTeX to the source LaTeX expression when the cursor navigates to the rendered LaTeX. Additionally, the implementation of this plugin right now is fairly simple and only uses the exposed TipTap extensions API (without reaching in addProseMirrorPlugins etc.).

However, I think adding some functionality to optionally enable this (or even just allowing users to edit the expression after clicking on it) might be on the roadmap in the future. :+1:

aarkue commented 3 months ago

@aarkue Can you try pasting stuff from https://tiptap.dev/docs/editor/api/extensions/mathematics#katex-options example and see if it renders automatically?

I tried and it doesn't. Screen.Recording.2024-06-08.at.14.25.01.mov

Thanks for the reproduction example! I believe the issue you are experiencing is because the content (from the TipTap example) is copied as HTML. When pasting the content again, it probably triggers the TipTap HTML -> Content conversion, without triggering the paste rules.

I will investigate how we could handle converting LaTeX pasted inside HTML. For now, you can try using paste-as-plain-text (with Ctrl+Shift+v), which seems to convert the LaTeX expressions correctly, but of course looses the other markup (e.g., Headings).

aarkue commented 3 months ago

Some progress: The TipTap APIs (PasteRules and InputRules) do not trigger when pasting rich HTML content mixes with (plain text) LaTeX.

Using parseHTML is also not applicable, as the example copied HTML (i.e., from the official TipTap mathematics extension) does not wrap the LaTeX in any special HTML tags.

Overall, this means that handling LaTeX inside pasted HTML is not possible without reaching for the ProseMirror API surface. This might be addressable in the future, but for now, it seems like not worth pursuing further. Pasting as plain text (Cmd/Ctrl+Shift+v) seems like a good enough workaround for the moment.

rajatkulkarni95 commented 3 months ago

Fair, for now I've gone ahead with the package from Tiptap, but it suffers from re-painting and re-rendering causing the app to slow down when there's a lot, while your package didn't.

Would you be okay keeping this issue open, till you either find a fix or deem it not worth fixing?

aarkue commented 3 months ago

Yes definitively, we can keep this issue open for tracking!

Cheers

xiangshu233 commented 3 months ago

@aarkue @rajatkulkarni95 hi guys,I also encountered the same problem. I had to delete the ending $ and re-enter it to render the math correctly.Moreover, directly inserting the latex formula into the document will not render $\tan {\theta }=\frac {\sin {\theta }} {\cos {\theta }}$ correctly. Is there any good solution? The reason I don't want to use the official math library is that I don't need to click on the formula to edit latex. Unfortunately, the official does not provide this option, so I found this library, 🙏

https://github.com/aarkue/tiptap-math-extension/assets/49575330/73e68366-9a46-4ba9-8c82-5d2b58c945cb

aarkue commented 3 months ago

@xiangshu233 hi, I tried pasting the formula manually in the demo page, and it worked without problems. However, my theory is that you are automatically inserting the math content (e.g., with editor.commands.insertContent see https://tiptap.dev/docs/editor/api/commands/insert-content). In this case, the automatic conversion will likely not trigger.

Instead, try inserting the latex formula as content element (either JSON or HTML) using editor.commands.insertContent):

Let me know if that works for you! Cheers.

xiangshu233 commented 3 months ago

@aarkue Many thanks for the prompt reply. However, I seem to try to paste $\tan {\theta }=\frac {\sin {\theta }} {\cos {\theta }}$ latex formula in the demo page. It does not render automatically. I still have to delete $ and enter $ again to render correctly. I use the editor.commands.insertContent($\tan {\theta }=\frac {\sin {\theta }} {\cos {\theta }}$) command to insert the formula. This writing method is recognized in the official math extension. At present, I have inserted the content in this way as you said, and it works for me.

click: (latex) => {
  editor?.chain()
    .insertContent(`<span data-type="inlineMath" data-latex="${latex}"></span>`)
    .focus()
    .run()
},

But I am still curious about what causes the deletion The problem is that the formula can only be rendered correctly if $ is entered again after $. Is it a regular expression problem of PasteRule?

https://github.com/aarkue/tiptap-math-extension/assets/49575330/47aeb46f-b4bb-49ce-b959-56f69e56964a

aarkue commented 3 months ago

@xiangshu233 No problem! I would actually recommend inserting via JSON instead of HTML to be more robust for future updates, but both should work fine for now.

Regarding the pasting issue: Pasting $\tan {\theta }=\frac {\sin {\theta }} {\cos {\theta }}$ works fine for me in both Chrome and Firefox. Could you try the following:

Cheers :)

xiangshu233 commented 3 months ago

@aarkue Thank you, I know why copying from rich text doesn't work

When you copy text from a rich text editor (such as Microsoft Word or Google Docs) or a web page, in addition to the plain text content, some formatting information is also copied. This formatting information is usually stored as HTML so that the original formatting is preserved when pasted.

This is the result I got

Copying from rich text: image

Ctrl+Shift+v: image

in addition, the official math extension can directly identify HTML tags such as p or h1. Does it perform filtering operations internally? Is it possible to do some filtering in "addPasteRules"? Unfortunately, the official math extension is not open source.

aarkue commented 3 months ago

@xiangshu233 Ahh okay, thanks for confirming! This is exactly the thing this original issue is about.

Fixing this will probably require using the ProseMirror API to handle such paste event scenarios (i.e. pasting HTML content with LaTeX inside $...$).

I will keep you updated once I get further to fixing this, but right now it is not really a priority.

Cheers!

xiangshu233 commented 3 months ago

@aarkue Hello, sorry to bother you. I am currently using this plugin. But I encountered a strange problem: Whether using JSON or HTML to insert, the formula converted by latex is much smaller than the one manually entered by $$

editor?.chain().insertContent(`<span data-type="inlineMath" data-latex="\\tan {\\theta }=\\frac {\\sin {\\theta }} {\\cos {\\theta }}"></span>`).focus().run()

I have been troubleshooting for a long time but can't find the problem😂. Can you help me?

https://github.com/aarkue/tiptap-math-extension/assets/49575330/5973357b-e3a1-43a3-bf03-1989cacc7fed

Thanks

aarkue commented 2 months ago

@aarkue Hello, sorry to bother you. I am currently using this plugin. But I encountered a strange problem: Whether using JSON or HTML to insert, the formula converted by latex is much smaller than the one manually entered by $$

editor?.chain().insertContent(`<span data-type="inlineMath" data-latex="\\tan {\\theta }=\\frac {\\sin {\\theta }} {\\cos {\\theta }}"></span>`).focus().run()

I have been troubleshooting for a long time but can't find the problem😂. Can you help me? QQ202475-145225.mp4

Thanks

Hi, no problem :) I suspect the difference might lay in whether the math is rendered in "display" or "inline" style.

When inserting the content using JSON (e.g., editor.commands.insertContent({type: "inlineMath", attrs: {latex: "\\tan {\\theta }=\\frac {\\sin {\\theta }} {\\cos {\\theta }}", display: "no"}})) you can switch between both using the display key (with value "no" vs "yes").

Similar, using HTML you can use data-display (e.g.,editor.commands.insertContent(<span data-type="inlineMath" data-display="yes" data-latex="\\sum_{i=0}^n i^2"></span>)`).

The inline style is good when working with math expressions inside text, e.g., $x$ or $n$. However, for larger equations, e.g., with fractions or sums, the larger display math is easier to read.

When using the auto-conversion of the editor $ vs $$ as delimiters trigger inline vs. display styles.

Let me know if this fixes your issue!

xiangshu233 commented 2 months ago

@aarkue Thanks, this is useful for me, thanks for your serious reply