LaTex文章をGoogle翻訳する方法

Google翻訳ですが、ファイルをアップロードして翻訳してくれる機能があって、とても便利です。むかし日本語で書いたLaTex文章があったのですが、手っ取り早く英語に翻訳したくてGoogle翻訳を使うことにしました。

f:id:etopirika5:20180202040948p:plain

Google翻訳、テキストファイルなんでも受け取ってくれるのですが、LaTexのコマンドが認識されずに崩れてしまいます。たとえば\begin{figure}などのコマンドは"\ begin {figure}"となってしまったりバックスラッシュに変なスペースが入ってしまいます。また\begin{document}などのLaTexのコマンドを検出するとエラーがでて翻訳が中断されてしまします。


そこでGoogle翻訳をうまく騙すためには、LaTexのコマンドを別の言葉に変換する必要があります。Latexのコマンドを意味のないアルファベットから成る言葉(zzzsadfgなど)に置き換えれば、そのまま出力されるのでOKです。翻訳が終わればあとはその記号をもういちどLaTexに変換しなおせばOKです。

Pythonを使って簡単な変換プログラムを書きました。

Latex→Text変換プログラム

import random 
import string

# compute nine key character starting from zzz
def getKey(): 
	s = 'zzz'
	for i in xrange(6):
		s = s+random.choice(string.ascii_lowercase)
	return s

# detect starting command 
def beginCode(u0):
	if u0.find("\\begin{equation}")==0: return 0
	if u0.find("\\begin{figure}")==0 : return 1
	if u0.find("\\begin{eqnarray}")==0: return 2
	if u0.find("\\begin{tcolorbox}")==0: return 3
	return -1

# detect ending command 
def endCode(u0):
	if u0.find("\\end{equation}")==0: return 0
	if u0.find("\\end{figure}")==0 : return 1
	if u0.find("\\end{eqnarray}")==0: return 2
	if u0.find("\\end{tcolorbox}")==0: return 3
	return -1

def convert(fname):
	list_line = []
	for l0 in open(fname, 'r'):
		l0 = l0.rstrip()		
		u0 = l0.decode('utf-8')
		list_line.append(u0)
	icode = -1;
	list_Out = []
	list_Tmp = []
	list_Map = []
	for i in xrange(len(list_line)):
		u0 = list_line[i]
		if beginCode(u0) != -1 and icode == -1:
			icode = beginCode(u0)
		if endCode(u0) == icode and icode != -1:
			icode = -1
			list_Tmp.append(u0)
			key = getKey()
			list_Tmp.insert(0,str(len(list_Tmp)))	
			list_Tmp.insert(0,key)
			list_Map.append(list_Tmp)
			list_Tmp = []
			list_Out.append(key)
			continue
		if icode != -1:
			list_Tmp.append(u0)
			continue
		while 1:
			ibeg = u0.find("$")
			if ibeg == -1:
				break;
			else:	
				iend = u0.find("$",ibeg+1)		
				if iend == -1:
					print(u0)
				assert iend != -1
				u1 = u0[0:ibeg]
				u2 = u0[iend+1:]
				eqn = u0[ibeg:iend+1]
				key = getKey()
				list_Map.append([key,"1",eqn])
				u0 = u1+key+u2
		if u0.find("\\usepackage")==0 or \
		 u0.find("\\geometry")==0 or \
		 u0.find("\\newcommand")==0 or \
		 u0.find("\\begin{document}")==0 or\
		 u0.find("\\tableofcontents")==0 or\
		 u0.find("\\maketitle")==0 or\
		 u0.find("\\documentclass")==0 or\
		 u0.find("\\end{document}")==0:
			key = getKey()
			list_Out.append(key)
			list_Map.append([key,"1",u0])
			continue
		list_Out.append(u0)

	f = open('toGoogleTrans.txt', 'w')
	for u0 in list_Out:
		s0 = u0.encode('utf-8')
		f.write(s0+"\n")
	f.close()

	f = open("keyMap.txt", "w")
	for imap in xrange(len(list_Map)):
		list0 = list_Map[imap]
		for l0 in list0:
			print(l0)
			f.write(l0+"\n")

if __name__ == "__main__":
	convert("main_ja.tex")

このプグラムを使うと"main_ja.tex"という日本語のLaTexファイルが、"toGoogleTrans.txt"というLaTexコマンドが全てキーに置き換わったファイルと、"keyMap.txt"というキーの一覧のファイルが生成されます。"toGoogleTrans.txt"をGoogle翻訳して、"fromGoogleTrans.txt"という名前で保存します(APIはないみたいなので、手動でやります)。こんどはkeyMap.txtと"fromGoogleTrans.txt"というファイルから英語のLaTexを生成します。

Text→Latex変換プログラム

def getDict(fname_keyMap):
	list0 = []
	for l0 in open(fname_keyMap,"r"):
		l0 = l0.rstrip()
		list0.append(l0)
	dic0 = {} 
	il = 0
	while(1):
		if il >= len(list0):
			break;
		key = list0[il]
		num = int(list0[il+1])
		print("key:",key,"num:",num)
		list2 = list0[il+2:il+2+num]
		il += num+2
		dic0[key] = list2
	print(dic0)
	return dic0

def convLatex(fname_txt, dic0):
	list0 = []
	for l0 in open(fname_txt,"r"):
		l0 = l0.rstrip()
		if l0.find("\\ section {")==0:
			list0.append("\\section{"+l0[11:])
			continue
		if l0.find("\\ subsection {")==0:
			list0.append("\\subsection{"+l0[14:])
			continue
		if l0.find("\\ subsubsection {")==0:
			list0.append("\\subsubsection{"+l0[17:])
			continue
		if l0.find("\\ title {")==0:
			list0.append("\\title{"+l0[9:])
			continue
		if l0.find("\\ author {")==0:
			list0.append("\\author{"+l0[10:])
			continue
		while(1):			
			is_Cap = False
			ibeg = l0.find("zzz")
			if ibeg == -1:
				ibeg = l0.find("Zzz")
				is_Cap = True
			if ibeg == -1:
				list0.append(l0)
				break;
			key = l0[ibeg:ibeg+9]
			if is_Cap: 
				key = "z" + key[1:9]
			val = dic0[key]
			if len(val)==1 :
				l0 = l0[0:ibeg]+val[0]+l0[ibeg+9:]
			else:
				for lv in val:
					list0.append(lv)
				break

	f = open('main_en.tex', 'w')
	for l0 in list0:
		f.write(l0+"\n")
	f.close()

if __name__ == "__main__":
	dic0 = getDict("keyMap.txt")	
	convLatex("fromGoogleTrans.txt", dic0)


以上で無事に、翻訳されたLaTexドキュメント"main_en.tex"を得ることができます。