LaTeX→Qiita用MathJax変換マクロ@EmEditorはEmEditor
でしか動かないのでブラウザで動くようにした.
変換結果は上記の記事とほぼ同じで,簡単な$\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
というものを初めて使った.とても便利でびっくり.
参考文献
- David Flanagan (著),村上列 (翻訳)「JavaScript 第6版」, オライリージャパン (2012)
- David Flanagan (著),木下哲也 (翻訳)「JavaScriptリファレンス 第6版」,オライリージャパン (2012)
- [JavaScript]クリップボードを使ったコピーとペースト
- JSでクリップボードのコピー&ペーストを実装する2つの方法【execCommand / Clipboard API】
- JavaScript テキストボックスの値を取得/設定する
- JavaScript テキストエリアの値を取得/設定するサンプル
- 正規表現を使ったマッチングに変数を使用する