dviの時点で句読点を置き換える
LaTeX で論文とかレポートとか書きたいときに句読点を、。ではなく,.にしたいことがあります。IME から句読点を変えればいいじゃんとなりますが、メールとかそういうのでは、。のままにしたいから IME からは変えたくない。あとtexファイルの中の文字は、。のままにしておきたいという願望もあります。
このような場合 usepackage とかしてLaTeX のシステムの中で「、。」を「,.」に置き換えるのが理想ですが、やはり自分のような素人には限界があるようです(【LaTeX】upLaTeXの句読点を置き換えるパッケージ を参照)。そこで外部コマンド、すなわちlatexmkの中で句読点を変換してしまえば確実なのではないかと考えました。それでもソースのtexファイル中の文字を置き換えることはできません。texファイルでは「、」「。」にしたままpdfでは「,」「.」にするというのが自分の目的なのです。真っ先に思いついたのは
(ソースファイル名).tex → コピー → (ソースファイル名)_copied.tex → 句読点置き換え・(u)platex → (ソースファイル名).dvi → dvipdfmx → (ソースファイル名).pdf
なのですが、そのためにlatexmkを使おうとするとコンパイルエラーが出てしまいました。どうやら、インプットファイル名と異なるアウトプットファイル名で出力するという操作は想定されていないようです。
方針を変えて、そもそもu(p)latexで置き換えられればよいのだからdviの段階で書き換えればよいのではないかと考えました。
dvispc
そうはいっても生のdviはバイナリなので書き換えできません。そこでdviを(人間が読める)テキストに変換でき、かつテキストをdviに変換できるdvispcを使います(dvispcはtexlive2022に含まれているようです)。
方法としては
(ソースファイル名).tex → (複数回)(u)platex → (ソースファイル名).dvi → dvispc → (ソースファイル名).txt → 句読点置換 → dvispc → (ソースファイル名).dvi → dvipdfmx → (ソースファイル名).pdf
とします。下はplatexを使う場合の.latexmkrc
の一例です(uplatexの場合はplatex,pbibtexをuplatex,upbibtexに置き換えてください)。「、」「。」を「,」「.」に置換するものです。なおdviをテキスト化したファイルの中で、「、」「。」「,」「.」はそれぞれ0x3001
0x3002
0xff0c
0xff0e
に対応します。
sed
は以下のように使います。
sed -i (入力ファイルの末尾に追加して出力ファイルとする文字列) -e s/(置換前の文字列)/(置換後の文字列)/ (入力ファイル)
なぜ入力ファイルの末尾に文字を追加して出力する仕様になっているのかは自分にはわかりませんが、これを""
として何もつけない扱いにすると元のファイルが上書きされます。
あとlatexmkではプレースホルダー(日本語にすると変数?)が使えます。%O
はオプション、%S
は入力ファイル、%D
は出力ファイル、%R
はファイル名から拡張子を抜いた文字列を表します。dviを変換したファイル名を%R.txt
にしています。VSCode で最高の LaTeX 環境を作る の記事のものからdvipdf
の部分を改造してみました。
#!/usr/bin/env perl
# LaTeX
$latex = 'platex -synctex=1 -interaction=nonstopmode -halt-on-error %O %S';
$max_repeat = 5;
# BibTeX
$bibtex = 'pbibtex %O %S';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S';
$makeindex = 'mendex %O -o %D %S';
# DVIからPDFにする、ここで句読点を置換する
$dvipdf = 'dvispc %O -a %R.dvi %R.txt && sed -i "" -e s/0x3001/0xff0c/ -e s/0x3002/0xff0e/ %R.txt && dvispc %O -x %O %R.txt %R.dvi && dvipdfmx %O -o %D %S';
$pdf_mode = 3;
# preview
$pvc_view_file_via_temporary = 0;
if ($^O eq 'linux') {
$dvi_previewer = "xdg-open %S";
$pdf_previewer = "xdg-open %S";
} elsif ($^O eq 'darwin') {
$dvi_previewer = "open %S";
$pdf_previewer = "open %S";
} else {
$dvi_previewer = "start %S";
$pdf_previewer = "start %S";
}
# 下の方まで探してくれる
$ENV{'TEXINPUTS'}='.//:' . $ENV{'TEXINPUTS'};
# clean up
$clean_full_ext = "%R.synctex.gz"
このlatexmkrc
を文書ごとに準備してやれば文書単位で句読点を副作用なく指定して使うことができます。もしローカル環境をお使いの方であれば、ホームディレクトリ直下にこのファイルを入れておけばソースのフォルダにlatexmkrc
を入れていなくてもlatexmk
コマンドをそのまま使えば句読点が置換されるようになります。
また、逆に「このファイルでは句読点を置換したくない!」となった場合はそのソースのフォルダに
$dvipdf = 'dvipdfmx %O -o %D %S';
だけ書いたlatexmkrc
を入れておけば変数dvipdf
の内容が上書きされてそのフォルダ内では句読点が置換されません。
なお Overleaf を使っている場合はこの方法は使えません。どうやらdviの名前が元ファイルの名前によらずoutput.dviになるためのようです。%R
の部分をうまくかえるとできるかもしれません。
settings.jsonから使う場合(VSCode)
ほとんど同じですが一応書いておきます。
{
"latex-workshop.latex.tools": [
{
"name": "platexmkkutoten",
"command": "latexmk",
"args": [
"-e",
"$latex=q/platex -synctex=1 -interaction=nonstopmode -halt-on-error/",
"-e",
"$bibtex=q/pbibtex/",
"-e",
"$biber=q/biber --bblencoding=utf8 -u -U --output_safechars/",
"-e",
"$pdf_mode=3",
"-e",
"$dvipdf=q/dvispc %O -a %R.dvi %R.txt && sed -i '' -e s\\/0x3001\\/0xff0c\\/ -e s\\/0x3002\\/0x3002\\/ %R.txt && dvispc %O -x %O %R.txt %R.dvi && dvipdfmx %O -o %D %S/",
"-e",
"$makeindex=q/mendex %O -o %D %S/",
"%DOCFILE%.tex",
"-e",
"$ENV{'TEXINPUTS'}='.//:' . $ENV{'TEXINPUTS'}"
]
},
],
"latex-workshop.latex.recipes": [
{
"name": "latexmk",
"tools": ["latexmk"]
}
]
}
快適な句読点ライフを!
(2022/09/08追記)Overleafでの方法
Overleaf で使う場合はファイル名の都合から上の方法は使えません。latexmk による LaTeX ワークフロー内で句読点を自動で置換するの記事を参考にこちらの.latexmkrc
を作ってみました。この方法を使うと自分のパソコンでは「ソースでは[、。]のまま pdf では[,.]にする」が達成できました。
#!/usr/bin/env perl
# LaTeX
$latex = "perl -pi -e 's/、/,/g' ./*.tex && perl -pi -e 's/。/./g' ./*.tex && platex -synctex=1 -halt-on-error -file-line-error";
# BibTeX
$bibtex = 'upbibtex %O %S';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S';
# index
$makeindex = 'mendex %O -o %D %S';
# DVI / PDF句読点の変更
$dvipdf = 'dvipdfmx %O -o %D %S';
$pdf_mode = 3;
# preview
$pvc_view_file_via_temporary = 0;
if ($^O eq 'linux') {
$dvi_previewer = "xdg-open %S";
$pdf_previewer = "xdg-open %S";
} elsif ($^O eq 'darwin') {
$dvi_previewer = "open %S";
$pdf_previewer = "open %S";
} else {
$dvi_previewer = "start %S";
$pdf_previewer = "start %S";
}
#下の方まで探してくれる
$ENV{'TEXINPUTS'}='.//:' . $ENV{'TEXINPUTS'};
# clean up
$clean_full_ext = "%R.synctex.gz"
参考文献
latexmk による LaTeX ワークフロー内で句読点を自動で置換する
VSCode で最高の LaTeX 環境を作る