Python にて tex → dvi → svg に変換する際のフォントエラー

Python にて tex → dvi → svg に変換する際のフォントエラー

- 環耀 望月 の投稿
返信数: 7
実行環境:
Windows 10 Home 64bit

TeX環境:
TeX Live 2019 を texlive2019.iso 内の install-tl-windows.bat でインストールしました.

問題点:
以下の tex ファイルを C:\Users\(ユーザー名)\Desktop\Python\textest_0 に template.tex という名前で保存しました.
===== template.tex =====
\documentclass[uplatex]{standalone}
\begin{document}
YourTextHere
\end{document}
======================
エンコーディングは UTF-8 です.

この tex ファイルの "YourTextHere" という部分を自分の指定した TeX テキスト (例として "あいうえお") に書き換え,
それを uplatex で dvi に変換後,
さらに dvisvgm で dvi を svg に変換する以下の Python プログラム (mktexsvg.py) を実行しました.
===== mktexsvg.py =====
import os
import subprocess

THIS_DIR = "C:\Users\(ユーザー名)\Desktop\Python\textest_0"
TEX_DIR = os.path.join(THIS_DIR, "tex") # 作成した tex ファイルの出力先.
TEMPLATE_TEX_PATH = os.path.join(THIS_DIR, "template.tex") # テンプレート (template.tex) へのファイルパス.
TEX_TEXT_TO_REPLACE = "YourTextHere" # テンプレート (template.tex) 内の書き換え用 TeX テキスト.

def mktex(expr):
# C:\Users\(ユーザー名)\Desktop\Python\textest_0 (=THIS_DIR) にある
# テンプレート (template.tex) の書き換え用 TeX テキスト (TEX_TEXT_TO_REPLACE)
# を expr に書き換え.
# 書き換えた tex ファイルを expr から mkname() にて作成した
# ファイル名 (name) で name.tex として UTF-8 で
# C:\Users\(ユーザー名)\Desktop\Python\textest_0\tex (=TEX_DIR) に保存.
name = mkname(expr)
tex_path = os.path.join(
TEX_DIR,
name
) + ".tex"
if os.path.exists(tex_path):
return tex_path
with open(TEMPLATE_TEX_PATH, 'r', encoding='utf-8') as template_tex:
body = template_tex.read()
body = body.replace(TEX_TEXT_TO_REPLACE, expr)
with open(tex_path, 'w', encoding='utf-8') as tex:
tex.write(body)
return tex_path

def mkname(expr):
# expr (TeX テキスト) からファイル名 (name) を作成.
name = expr
to_delete = ['/', '\\', '{', '}', ' ', '~', '\'', '\"', '^']
to_replace = {<br /> '<': 'lessthan',<br /> '>': 'greaterthan',<br /> '?': 'questionmark',<br /> '.': 'point',<br /> ':': 'colon',<br /> '%': 'percent',<br /> '|': 'vbar'<br /> }
for char in name:
if char in to_delete:
name = name.replace(char, "")
for char in name:
if char in to_replace.keys():
name = name.replace(char, to_replace[char])
return name

def texdvi(tex_path):
# tex_path にある tex ファイルを uplatex にて dvi に変換.
dvi_path = tex_path.replace(".tex", ".dvi")
if os.path.exists(dvi_path):
return dvi_path
commands = [
"uplatex",
"-kanji=utf8",
"-no-guess-input-enc",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=" + TEX_DIR,
tex_path
]
subprocess.run(commands)
return dvi_path

def dvisvg(dvi_path):
# dvi_path にある dvi ファイルを dvisvgm にて svg に変換.
svg_path = dvi_path.replace(".dvi", ".svg")
if os.path.exists(svg_path):
return svg_path
commands = [
"dvisvgm",
dvi_path,
"-n",
"-v",
"3",
"-o",
svg_path
]
subprocess.run(commands)
return svg_path

def mktexsvg(expr):
tex_path = mktex(expr)
dvi_path = texdvi(tex_path)
svg_path = dvisvg(dvi_path)
return svg_path

if __name__ == "__main__":
expr = "あいうえお"
mktexsvg(expr=expr)
========================

すると以下のような警告が発生し, svg に文字が表示されません.
========================
This is e-upTeX, Version 3.14159265-p3.8.2-u1.24-190131-2.6 (utf8.uptex) (TeX Live 2019/W32TeX) (preloaded format=uplatex)
restricted \write18 enabled.
entering extended mode
WARNING: font file 'uprml-h.mf' not found
The command name is C:\texlive\2019\bin\win32\mktexmf
WARNING: font file 'uprml-hq.mf' not found
WARNING: can't embed font 'uprml-h'
========================
これはどのようにして解決すればよいでしょうか?

環耀 望月 への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- Akira Kakuto の投稿
dvisvgm のデフォルトでは,現在の場合必要な
font map file が読めません。 dvisvgm のコマンドライン


dvisvgm --fontmap=+kanjix.map dvifilename

となるようにすると,成功するでしょう。
Akira Kakuto への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- 環耀 望月 の投稿
Akira Kakuto 様

ありがとうございます、大変助かりました。
もう一点お聞きしたいことがあります.

以下のようなドキュメント部が平仮名 (例として "あいうえお") のみでできている tex ファイルを uplatex で dvi に変換し、それをさらに dvisvgm により svg に変換することはできました.
====================
\documentclass[uplatex]{standalone}
\begin{document}
あいうえお
\end{document}
====================

しかし以下のようにドキュメント部に漢字が含まれていると、同じ手順を踏んでもうまく svg に変換できませんでした(文字化けのようなことが起きてしまいました).
====================
\documentclass[uplatex]{standalone}
\begin{document}
漢字
\end{document}
====================
これはどのような原因によるものなのでしょうか?初心者の質問で申し訳ありませんが, よろしくお願いいたします.
添付 dvisvgm_kanji_error.png
環耀 望月 への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- Akira Kakuto の投稿
> しかし以下のようにドキュメント部に漢字が含まれていると、
> 同じ手順を踏んでもうまく svg に変換できませんでした
> (文字化けのようなことが起きてしまいました)

まさかと思いましたが本当ですね。おそらく dvisvgm が encoding
を取り扱う際に何かの不完全性があるのだと思われます。
uplatex ではなくて,platex を使用すると大丈夫のようです。
なお,dvisvgm のコマンドラインは

dvisvgm --fontmap==kanjix.map dvifilename

のほうが良いでしょう。= が二つあることに注意して下さい。
Akira Kakuto への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- Akira Kakuto の投稿
> まさかと思いましたが本当ですね。おそらく dvisvgm が encoding
> を取り扱う際に何かの不完全性があるのだと思われます。
> uplatex ではなくて,platex を使用すると大丈夫のようです。

uplatex を使う場合,

%%uprml-h UniJIS-UTF16-H ipaexm.ttf %!PS IPAexMincho
uprml-h UniJIS-UCS2-H ipaexm.ttf %!PS IPAexMincho

なる2行だけのファイル test.map をカレントディレクトリに置き,

dvisvgm --fontmap==kanjix.map,=test.map dvifilename

とすると,OK になります。

test.map は,kanjix.map に置ける encoding UniJIS-UTF16-H
を UniJIS-UCS2-H に変更するものです。

よく理解していませんが,dvisvgm の場合,UniJIS-UTF16-H では
うまく行かないが,UniJIS-UCS2-H ではうまく行くようです。
Akira Kakuto への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- 環耀 望月 の投稿
Akira Kakuto 様

uplatex の場合の解決法まで調べてくださり, 本当にありがとうございました.
私が抱える問題が解決され, 大変助かりました.

後学のために少しお聞きしたいのですが, たとえばここで uprml-h 以外の日本語フォントを uplatex で用いようとするとどうなるでしょうか?
初心者の私だと欧文フォントや数式フォントの変更等による影響も dvisvgm にはありえるのかな, と心配になってしまいます.
その時にはおそらく test.map も変更が必要になると思うので, この機会にぜひお聞きしたいです.

お手数のかからない範囲で良いので, 教えていただけると幸いです. よろしくお願いいたします.
環耀 望月 への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- Akira Kakuto の投稿
dvisvgm はデフォルトで ps2pk.map, pdftex.map, dvipdfm.map, psfonts.map
を読みます。欧文フォントについては,おそらく問題が起きることは
殆ど無いのではないかと思います。
日本語フォントについては,--fontmap==kanjix.map で失敗する部分
は test.map で UniJIS-UTF16  --> UniJIS-UCS2,
--fontmap==kanjix.map,=test.map
などでテストして見て下さい。なお kanjix.map は TeX Live の場合
$TEXMFDIST/fonts/map/dvipdfmx/updmap
にあると思います。
Akira Kakuto への返信

Re: Python にて tex → dvi → svg に変換する際のフォントエラー

- Akira Kakuto の投稿
> よく理解していませんが,dvisvgm の場合,UniJIS-UTF16-H では
> うまく行かないが,UniJIS-UCS2-H ではうまく行くようです。

調べてみると,原因は dvisvgm の CMap reader が "begincidchar"
を知らないからのようです。自己流で "begincidchar" も解釈できる
ようにしてみると,UniJIS-UTF16-H でも OK になりました。
次期バージョンでは,"begincidchar" もサポートするようにお願い
しておきました。