Skip to content

Lightweight package using MathJax to allow inline rendering of latex as svg elements

License

Notifications You must be signed in to change notification settings

jpribyl/react-hook-mathjax

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

React Hook MathJax

npm version

Lightweight, strongly typed package with almost no dependencies. It uses MathJax v3 and React Hooks to allow inline conversion of a LaTeX string into an svg. For more details, take a look at the example project (which parses user input and handles error states) or the live demo of the example project.

Example of usage

Install

yarn add react-hook-mathjax

Usage

Basic inline display

import React from "react";
import Tex2SVG from "react-hook-mathjax";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <Tex2SVG display="inline" latex="e^{i \pi} + 1 = 0" />
      </header>
    </div>
  );
}

export default App;

Customizing MathJax options

import React from "react";
import Tex2SVG, { MathJaxProvider } from "react-hook-mathjax";

// This object contains the default options, more info at:
// https://docs.mathjax.org/en/latest/options/output/svg.html 
const mathJaxOptions = {
  svg: {
    scale: 1,                      // global scaling factor for all expressions
    minScale: .5,                  // smallest scaling factor to use
    mtextInheritFont: false,       // true to make mtext elements use surrounding font
    merrorInheritFont: true,       // true to make merror text use surrounding font
    mathmlSpacing: false,          // true for MathML spacing rules, false for TeX rules
    skipAttributes: {},            // RFDa and other attributes NOT to copy to the output
    exFactor: .5,                  // default size of ex in em units
    displayAlign: 'center',        // default for indentalign when set to 'auto'
    displayIndent: '0',            // default for indentshift when set to 'auto'
    fontCache: 'local',            // or 'global' or 'none'
    localID: null,                 // ID to use for local font cache (for single equation processing)
    internalSpeechTitles: true,    // insert <title> tags with speech content
    titleID: 0                     // initial id number to use for aria-labeledby titles
  }
}

function App() {
  return (
    <div>
      <MathJaxProvider options={mathJaxOptions} />
      <div className="App">
        <header className="App-header">
          <Tex2SVG display="inline" latex="e^{i \pi} + 1 = 0" />
        </header>
      </div>
    </div>
  );
}

export default App;

Parsing user input

import React from "react";
import Tex2SVG from "react-hook-mathjax";

function App() {
  const [inputValue, setInputValue] = React.useState(
    "G_{\\mu\\nu} + \\Lambda g_{\\mu\\nu} = \\kappa T_{\\mu\\nu}",
  );

  return (
    <div className="App">
      <header className="App-header">
        <h3>React Hook MathJax</h3>
        <input
          type="text"
          defaultValue={inputValue}
          onChange={e => setInputValue(e.target.value)}
        />

        <div className="tex-container">
          <Tex2SVG class="tex" tabindex={-1} latex={inputValue} />
        </div>
      </header>
    </div>
  );
}

export default App;

Handling error states

import React from "react";
import Tex2SVG from "react-hook-mathjax";

const getErrorFromHTML = (html) =>
  html.children[1].firstChild.firstChild.attributes["data-mjx-error"].value;

function App() {
  const [inputValue, setInputValue] = React.useState(
    "G_{\\mu\\nu} + \\Lambda g_{\\mu\\nu} = \\kappa T_{\\mu\\nu}",
  );
  const [lastValidInput, setLastValidInput] = React.useState("");
  const [error, setError] = React.useState(null);
  const hasError = error !== null;

  return (
    <div className="App">
      <header className="App-header">
        <h3>React Hook MathJax</h3>
        <input
          className={`${hasError ? "error" : ""}`}
          type="text"
          defaultValue={inputValue}
          onChange={e => {
            setInputValue(e.target.value);
            setError(null);
          }}
        />

        <div className="tex-container">
          <Tex2SVG
            class="tex"
            tabindex={-1}
            latex={hasError ? lastValidInput : inputValue}
            onSuccess={() =>
              setLastValidInput(hasError ? lastValidInput : inputValue)
            }
            onError={html => setError(getErrorFromHTML(html))}
          />
        </div>
	{hasError && <div>hint: {error}</div>}
      </header>
    </div>
  );
}

export default App;

API

MathJaxProvider props:

options Object, optional

Tex2SVG props:

latex string, required

onSuccess (HTMLElement) => void, optional

  • Triggered after a successful conversion of LaTeX string into an svg - it receives the html object generated by MathJax
  • Default: (html: HTMLElement) => {}

onError (HTMLElement) => void, optional

  • Triggered after a failed conversion of LaTeX string into an svg - it receives the html object generated by MathJax
  • Default: (html: HTMLElement) => {}

Other html attributes {[key: string]: any} optional

  • All other props passed into this component will be directly translated onto the DOM node
  • This allows you to add css classes or other handlers, see usage examples above
  • NOTE: this does not attach to the virtual DOM, so pass class - not className etc

Acknowledgements

  • Big high five to Wing-Hong Andrew Ko (@wko27) for his work on the original react-mathjax package.

About

Lightweight package using MathJax to allow inline rendering of latex as svg elements

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published