LoginSignup
1
1

MathJaxのLaTeXから画像ファイルを錬成する

Posted at

MathJaxのLaTeXから画像ファイルを錬成する

この記事はアドカレに参加しています。

LaTeXってなに?

平方根や、行列式などを綺麗に表示したいときがあります。そんなときに役に立つのが、LaTeXという記法です。例えば、Qiitaで$a = \sqrt{10}$と表示するには以下のように書きます。

a = \sqrt{10}

LaTeXで表わせる数式記号はたくさんあります。
Qiitaでの様々な数式の書き方 ~ TeX記法を使ったサンプルコード付き
よく忘れるので数学のTeX記法をまとめ
場合分けをきれいに書く
27.7 数式の書き方(1)

MathJax

web上のLaTeXで書かれたコードを実際の数式に変換してくれるライブラリにMathJaxがあります。MathJaxはQiitaでも採用されていて、Qiitaの多くの記事ではMathJaxによって数式が描かれています。

LaTeXから任意の画像ファイルへ

LaTeXから画像ファイルを作成するには、
LaTeX→SVG→DataURL(svg)→Image→canvas→DataURL(任意の画像形式)
のようにする必要があります。

1. LaTeXからSVG

MathJaxのMathJax.tex2svgPromiseを用いることで、LaTeXコードからsvg要素を作成することができます。

let str = "\\frac{1}{2}"
MathJax.tex2svgPromise(str, {display: true}).then((obj) => {
  let svg_ele = obj.childNodes[0]
})

objはsvg文字列ではなく、nodeであることに注意する必要があります。obj.childNodes[0]svg要素が、obj.childNodes[1]の方にはMathML要素があります。

2. SVGをURL化

svg要素をXMLSerializer().serializeToStringでXML形式の文字列にします。さらに、その文字列からDataURLを作成します。encodeURIComponent関数で文字列をエスケープする必要があります。

let svg = new XMLSerializer().serializeToString(obj.childNodes[0])
let svg_url = "data:image/svg+xml;charset=utf-8;," + encodeURIComponent(svg)

DataURLはdata:(MIMEタイプ);(文字コード);,(データ)のようにします。

3. URLからcanvasに描画

Image()コンストラクタでDataURLを読み込み、canvas要素にsvgを描画します。

let cvs = document.createElement("canvas")
let img = new Image()
img.src = svg_url
img.onload = () => {
  cvs.width = img.width
  cvs.height = img.height
  cvs.getContext("2d").drawImage(img, 0, 0)
  let url = cvs.toDataURL("image/png")
}

canvasのtoDataURLメソッドでcanvasの内容を画像データを表すDataURLに変換することができます。ユーザーがこのDataURLを踏むことで、画像ファイルをダウンロードすることができます。

toDataURLの引数ではMIMEタイプで画像形式を指定しますが、ブラウザが必ずしも指定した画像形式のエンコードに対応している訳ではありません。もしもブラウザがエンコードをサポートしていないMIMEタイプであった場合は、戻り値のDataURLがpng形式になります。(戻り値の最初がdata:image/pngで始まっていれば、引数で指定されたMIMEタイプをブラウザはサポートしていません。)

4. URLから自動ダウンロード処理

URLからファイルを自動ダウンロードするような処理を書くには、aタグを使用します。downloadプロパティにファイル名、hrefプロパティにファイル先を示すURLがある状態でaタグがクリックされると、ファイルがダウンロードされます。

let ele = document.createElement("a")
ele.download = "filename.png"
ele.href = url
ele.click()

プログラム例

downloadをクリックすると、指定されたファイル名でファイルをダウンロードします。

<span>file output: </span>
<input type="text" value="sample.png" placeholder="filename.filetype" spellcheck="false" id="text"/>
<input type="button" value="download" id="button" />

<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
<script>
  let str = "\\frac{1}{2}"
  let text = document.getElementById("text")
  let button = document.getElementById("button")
  button.addEventListener("click", () => {
    let ele = document.createElement("a")
    ele.download = text.value
    let type = ele.download.replace(/[^\.]*\.(.*)/gu, "$1")
    if (type === "txt") {
      ele.href = "data:text/plain;charset=utf-8;," + encodeURIComponent(str)
      ele.click()
    }
    else {
      MathJax.tex2svgPromise(str, {display: true}).then((obj) => {
        let svg = new XMLSerializer().serializeToString(obj.childNodes[0])
        let svg_url = "data:image/svg+xml;charset=utf-8;," + encodeURIComponent(svg)
        if(type === "svg") {
          ele.href = svg_url
          ele.click()
        }
        else {
          let cvs = document.createElement("canvas")
          let img = new Image()
          img.src = svg_url
          img.onload = () => {
            cvs.width = img.width
            cvs.height = img.height
            cvs.getContext("2d").drawImage(img, 0, 0)
            ele.href = cvs.toDataURL("image/" + type)
            ele.click()
          }
        }
      })
    }
  })
</script>

参考文献

MathJaxでLaTeXをsvgに変換する
JavaScriptで動的に作成したテキストファイルをダウンロード
SVG イメージを JavaScript から保存する方法
[HTML/js] SVGファイルをPNGに変換するツール
Rendering MathJax output on

むすび

LaTeXコードからファイルを錬成する話でした。

宣伝((小声
こんなかんじのエディタを作っていたりするので、よければ。
 
 
bsky
 
 

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1