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

customHTMLElementModels not working with 'math' tags #635

Open
7 of 15 tasks
arnabbit opened this issue Jun 20, 2023 · 11 comments
Open
7 of 15 tasks

customHTMLElementModels not working with 'math' tags #635

arnabbit opened this issue Jun 20, 2023 · 11 comments
Labels
is:waiting for feedback Waiting for OP input.

Comments

@arnabbit
Copy link

Decision Table

  • My issue does not look like “The HTML attribute 'xxx' is ignored” (unless we claim support for it)
  • My issue does not look like “The HTML element <yyy> is not rendered”

Good Faith Declaration

Description

I wish to render my html content which contains 'math' tags along with a bunch of other tags.
My html content for example looks like
<p> <p>This is outta the park</p> <math xmlns="http://www.w3.org/1998/Math/MathML"><msqrt><mn>2</mn><mfrac bevelled="true"><mn>4</mn><mn>7</mn></mfrac></msqrt><mo>+</mo><mfrac><mn>5</mn><mn>8</mn></mfrac></math> <- this is just a math string <span>Please look above the problem is with the above math tags!</span> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. </p> </p>

and i have defined my customHTMLElementModels as follows

const customHTMLElementModels = { math: defaultHTMLElementModels.math.extend({ contentModel: HTMLContentModel.block }) };

and my component's render function looks like the following:
<HTML width = { width} source={{html :customSource}} tagsStyles={SoltagsStyles} customHTMLElementModels={customHTMLElementModels} />

for which the output comes as such
image

As you can see, the math equation doesn't render.

I also tried using Custom Rendering using components.
using MathJax from react-native-mathjax
but same output

React Native Information

System:
    OS: Windows 10 10.0.22621
    CPU: (8) x64 Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
    Memory: 9.06 GB / 23.77 GB
  Binaries:
    Node: 18.16.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
    Windows SDK: Not Found
  IDEs:
    Android Studio: Version     2020.3.0.0 AI-203.7717.56.2031.7678000
    Visual Studio: Not Found
  Languages:
    Java: 20.0.1
  npmPackages:
    @react-native-community/cli: Not Found
    react: >=16.8.0 => 17.0.2
    react-native: 0.68.2 => 0.68.2
    react-native-windows: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

RNRH Version

6.3.4

Tested Platforms

  • Android
  • iOS
  • Web
  • MacOS
  • Windows

Reproduction Platforms

  • Android
  • iOS
  • Web
  • MacOS
  • Windows

Minimal, Reproducible Example

https://snack.expo.dev/@arnab_bit/mathtagparsing

Additional Notes

No response

@arnabbit arnabbit added the bug Crush'em all. label Jun 20, 2023
@jsamr
Copy link
Collaborator

jsamr commented Jun 20, 2023

@BenzterBit It is actually working but since you're extending the default model, the opaque flag is set:
https://github.com/native-html/core/blob/4c37d2915feb8c071d060b08d54f5ef5fd9c9afc/packages/transient-render-engine/src/model/defaultHTMLElementModels.ts#L614C1-L619

Instead, extend the div model if you want something similar to div. On the other hand, the opaque flag means it won't render inner nodes (so tnode.children will be empty), but you still have access to the dom node. To do this, use the tnode.domNode prop and you'll be able to use a recursive renderer to render all descendants.

@jsamr jsamr added is:waiting for feedback Waiting for OP input. and removed bug Crush'em all. labels Jun 20, 2023
@arnabbit
Copy link
Author

@jsamr From what i am able to understand of what you are saying is that since the opaque flag is set, i won't be able to render the children and say using the other approach of custom rendering using renderers, I have to recursively render all the tags inside of mathml using MathJax individually?
Also its too much to ask, but if you could provide a snack, which renders the html content above, that would make my doubts much clearer

@jsamr
Copy link
Collaborator

jsamr commented Jun 21, 2023

@BenzterBit Yes, clearly there are two approaches:

  1. Define non-opaque custom models and renderers for each MathML tag.
  2. Define an opaque custom model for the math tag, and provide a custom renderer. This custom renderer can either use tnode.domNode; which is an object from htmlparser2 library (refer to this lib documentation to walk the tree); or transform the domNode to an HTML string with domNodeToHTMLString and use a third-party library to render it.

I'm sorry as I don't have much time to provide a snack.

@arnabbit
Copy link
Author

@jsamr I tried the second approach. I did what you said, and now atleast i can see the mathjax or some of it, that i am wiritng. But still it can't render the tags like say . For eg. for equation n/100 *x it will print n100 *x.

It could've been due to me not specifying isOpaque: false, so i did it for each tag supported by mathml and rendered it through MathJax but even that didn't help, it gave the same 'n100 * x'

Can you tell me how to proceed from here? So that i can render the entire equation

@jsamr
Copy link
Collaborator

jsamr commented Jun 24, 2023

@BenzterBit If you could provide snacks with the two approaches I'd be happy to help.

@arnabbit
Copy link
Author

@jsamr sure, please check the following 2 snacks

  1. where i have defined a custom model to render all the supported math tags via mathjax https://snack.expo.dev/@arnab_bit/allmathmltagsrenderers

  2. where i have only defined a custom model for the 'math' tag specifically and tried to render it via mathjax
    https://snack.expo.dev/@arnab_bit/singlemathtagcustommodelrenderer

@arnabbit
Copy link
Author

@jsamr also the rendered elements above are in a new line, can you tell me how to make them inline with the rest of the content

@jsamr
Copy link
Collaborator

jsamr commented Jul 3, 2023

@BenzterBit Inlining may or may not work because it basically relies on embedding View into Text, which support has been inconsistent and ill-specified in RN, but this may have changed recently with Fabric which I haven't worked with yet.

To force inlining, you can use HTMLContentModel.textual or HTMLContentModel.mixed in your models. I suggest to first try to see if you can achieve the desired outcome with vanilla React Native + MathJax, and if you manage it, try to tweak these models.

@arnabbit
Copy link
Author

@jsamr couldn't do it through Mathjax, i converted the mathml incoming which is used a custom renderer using rnrh and converted it to latex using a library mathml-to-latex npm library. I used HTMLContentModel.textual and it did inline though, the styling is a bit off, which i am still figuring, if you do have any ideas on that. I will let you know after a few more tries

@ihojmanb
Copy link

@BenzterBit hi! could you share your changes with the rest of us? I think what you are trying to solve is in my usecase, it would be helpul to see a bit of code. We may have a common ground in what we are trying to do :)

@tranminhnhat1005
Copy link

Thank @BenzterBit for the snack example, I also found a solution seems good for you @ihojmanb, I hope it is useful:

https://medium.com/@nutanbhogendrasharma/how-to-implement-latex-in-react-native-mobile-app-6433a7726954

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
is:waiting for feedback Waiting for OP input.
Projects
None yet
Development

No branches or pull requests

4 participants