0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LaTeX→MathJax変換器(Qiita用)

Last updated at Posted at 2020-05-03

LaTeX→Qiita用MathJax変換マクロ@EmEditorEmEditorでしか動かないのでブラウザで動くようにした.
変換結果は上記の記事とほぼ同じで,簡単な$\mathrm{\LaTeX}$文書しか変換できないが,
\label付の式に連番を自動割当するので作業が大幅に軽減されるはず.
Qiita用MathJaxマクロ集も含めた.

入力例
…Cauchyの積分定理より,
\begin{align}
\oint\D z f(z) = 2\pi\I\sum_{a}\Res_{z=a} f(z),\label{Cauchy}
\end{align}
である.ここで$f(z)$\begin{align}
f(z):=\cdots,\label{f}
\end{align}
%
%
で定義されている.\Ref{f}\Ref{Cauchy}に代入すると…

LaTeX2MathJax.html (ヘッダなし変換)


…Cauchyの積分定理より,

```math
\begin{align}
\oint\D z f(z) = 2\pi\I\sum_{a}\Res_{z = a} f(z), \tag{1}\label{Cauchy}
\end{align}
```

である.ここで$f(z)$は

```math
\begin{align}
f(z): = \cdots, \tag{2}\label{f}
\end{align}
```

で定義されている.__($\ref{f}$)__を__($\ref{Cauchy}$)__に代入すると…

↓Qiita記事に貼り付け

…Cauchyの積分定理より,

\begin{align}
\oint\D z f(z) = 2\pi\I\sum_{a}\Res_{z = a} f(z), \tag{1}\label{Cauchy}
\end{align}

である.ここで$f(z)$は

\begin{align}
f(z): = \cdots, \tag{2}\label{f}
\end{align}

で定義されている.__($\ref{f}$)($\ref{Cauchy}$)__に代入すると…

一部エラーが起きているが,ヘッダをつけて変換すれば完全に表示される.

#変換器本体

以下をUTF-8でHTMLファイルとして保存してブラウザで開けばOK.

LaTeX2MathJax.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>LaTeX2MathJax</title>
</head>
<body>
  <form>
    <div>
    <font size=10>
    LaTeX→MathJax変換器(Qiita用)<br>
    </font>
    <div>
    <input type="button" onclick="paste()" value="ペースト">
    </div>
    <textarea placeholder="ここにLaTeXコマンドをペーストする"
    id="LaTeX" rows="20" cols="100" wrap="off"></textarea>
    </div>
    <div><input type="button" onclick="convert()" value="変換">
    数式環境:<input type="text" id="mathenv" value="equation align">
    <input type="checkbox" id ="header" checked> headerを付加する
    <input type="checkbox" id ="copy" checked> 変換結果をクリップボードにコピーする
    </div>
    <div>
    <textarea id="MathJax" rows="20" cols="100" wrap="off"></textarea>
    </div>
    <div>
    ヘッダ:
    </div>
    <div>
    <textarea id="headerbody" rows="20" cols="100" wrap="off">
$\phantom{}$$
\newcommand\nr{\notag\\\\}%タグなし改行用
\newcommand\ret{\notag\\\\&\qquad}%数式改行用
\newcommand\I{\mathrm{i}}
\newcommand\D{\mathrm{d}}
\newcommand\E{\mathrm{e}}
\newcommand\hc{\mathrm{h.c.}}
\newcommand\cc{\mathrm{c.c.}}
\newcommand\O[1]{\mathscr{O}\left(#1\right)}
\newcommand\abs[1]{{\left\rvert #1 \right\lvert}}
\newcommand\Res{\mathop{\mathrm{Res}}}
\newcommand\bra[1]{\mathinner{\langle{#1}|}}
\newcommand\ket[1]{\mathinner{|{#1}\rangle}}
\newcommand\braket[1]{\mathinner{\langle{#1}\rangle}}
\newcommand\Bra[1]{\left\langle#1\right|}
\newcommand\Ket[1]{\left|#1\right\rangle}
\newcommand\Braket[1]{\left\langle #1 \right\rangle}
\newcommand\|{\middle|}%\Braket用
\DeclareMathOperator{\Log}{Log}
\DeclareMathOperator{\Arg}{Arg}
\DeclareMathOperator{\sgn}{sgn}
\DeclareMathOperator{\Tr}{Tr}
\newcommand\dashint{\mathchoice
  {\int\kern-10pt-}
  {\int\kern-8.5pt-}
  {\int\kern-6.1pt-}
  {\int\kern-4.58pt-}}
\newcommand\set[1]{\left\\{#1\right\\}}
\newcommand\for[1]{\quad\mathrm{for}\quad #1}
\newcommand\LHS{\mathrm{(LHS)}}
\newcommand\RHS{\mathrm{(RHS)}}
$</textarea>
    </div>
  </form>
 
  <script language="javascript" type="text/javascript">
  
  function paste(){
	var pasteArea=document.getElementById("LaTeX");
	if(navigator.clipboard){
    	navigator.clipboard.readText()
    	.then(function(text){
        	pasteArea.textContent = text;
		});
	}
  }
  
  function convert() {
  	var env = document.getElementById("mathenv").value;
  	env = env.replace(/\s+/g,"|");
  	beginmath = new RegExp('\\\\begin\{('+env+')\}','g');
  	endmath = new RegExp('\\\\end\{('+env+')\}','g');
  	
  	var headerbody=document.getElementById("headerbody").value;
  	
    var str = document.getElementById("LaTeX").value;
    str = str.replace(/\%.*\n/g,"");
    str = str.replace(/\n{3,}/g,"\n\n");
    //
    str = str.replace(beginmath,"\n\n```math\n\\begin{$1}");
    str = str.replace(endmath,"\\end{$1}\n```\n\n");
    //
    str = str.replace(/\ *(<|>|=)\ */g,"\ $1\ ");
    //
    str = str.replace(/\\section\{(.*?)\}/g,"\n\n# $1\n\n");
    str = str.replace(/\\subsection\{(.*?)\}/g,"\n\n## $1\n\n");
    str = str.replace(/\\subsubsection\{(.*?)\}/g,"\n\n### $1\n\n");
    //
    str = str.replace(/\\tag\{.*?\}/g,"\ ");
    str = str.replace(/\\label/g,"\ \\tag\{\}\\label");
    str = str.replace(/\\ref\{(.*?)\}/gi,"__(\$\\ref\{$1\}\$)__");
    var n=(str.match(/\\tag\{\}/g)||[]).length;
    for (var i=1; i<=n ;++i){
    	str=str.replace( /\\tag\{\}/, "\\tag\{"+i+"\}");
    }
    //
    str = str.replace(/\n{3,}/g,"\n\n");
	str = str.replace(/\ {2,}/g,"\ ");
	if(document.getElementById("header").checked){
		str = headerbody+"\n\n"+str;
	}
    document.getElementById("MathJax").innerHTML = str;
    
    if(document.getElementById("copy").checked){
    	target = document.getElementById("MathJax")
        target.select();
    	document.execCommand("copy");
    	document.getSelection().empty(target);
	}
  }
  </script>
</body>
</html>

JavaScriptというものを初めて使った.とても便利でびっくり.

参考文献

  1. David Flanagan (著),村上列 (翻訳)「JavaScript 第6版」, オライリージャパン (2012)
  2. David Flanagan (著),木下哲也 (翻訳)「JavaScriptリファレンス 第6版」,オライリージャパン (2012)
  3. [JavaScript]クリップボードを使ったコピーとペースト
  4. JSでクリップボードのコピー&ペーストを実装する2つの方法【execCommand / Clipboard API】
  5. JavaScript テキストボックスの値を取得/設定する
  6. JavaScript テキストエリアの値を取得/設定するサンプル
  7. 正規表現を使ったマッチングに変数を使用する
0
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?