われがわログ

最適化アルゴリズムとかプログラミングについて書きたい

PowerShell上におけるlatexdiffの出力結果の文字化けへの対処

latexdiffは、2つのTeXファイルの差分を、PDFにコンパイル可能な形で出力するプログラムであり文書校正に有用である。 この記事では、ネット情報を基にlatexdiffをPowerShell上で実行した際、出力結果が文字化けしたことへの対処をメモする。

まとめ

  • PowerShell上でlatexdiffをlatexdiff -e utf-8 -t CFONT input1.tex input2.tex > output.texと実行すると文字化けする。
  • PowerShell 5.x(2019/6時点でWindows10のデフォルト)なら、[Console]::OutputEncoding = [Text.Encoding]::UTF8と入力してlatexdiffの出力文字コードUTF-8」をPowerShell上で指定した後に
latexdiff -e utf-8 -t CFONT input1.tex input2.tex | Out-String | % { [Text.Encoding]::UTF8.GetBytes($_) } | Set-Content -Path "output.tex" -Encoding Byte

とすると文字化けしていない「BOMなしUTF-8」なoutput.texを出力できる。

  • PowerShell Core 6.xなら以下のコマンドでよい。
[Console]::OutputEncoding = [Text.Encoding]::UTF8
latexdiff -e utf-8 -t CFONT input1.tex input2.tex > output.tex
  • コマンドプロンプトなら最初に挙げたコマンドlatexdiff -e utf-8 -t CFONT input1.tex input2.tex > output.tex を使えばよい。

文字化けの再現

以下、日本語を含むTeXファイルtemplate.tex*1に対して、 それ自身との差分をlatexdiffで取りoutput.texを出力してみる。 これに対応する、ネットでよく紹介されているコマンドは以下の通り。

latexdiff -e utf-8 -t CFONT template.tex template.tex > output.tex

このコマンドをPowerShell 5.x 上で実行したとき、output.texは以下のように文字化けする。 加えて、その文字コードは「BOMありUTF-16 LE」になってしまう。

%\documentclass[a4paper,uplatex,dvipdfmx,ja=standard,11pt,draft]{bxjsarticle}
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL template.tex   Wed Jun 19 17:40:52 2019
%DIF ADD template.tex   Wed Jun 19 17:40:52 2019
\documentclass[a4paper,uplatex,dvipdfmx,ja=standard,11pt,draft]{bxjsarticle}

\setpagelayout{ignorehead}
\usepackage[dynamics]{PrettyLatexReport} % for dynamics seminar
%\usepackage{PrettyLatexReport} % for research seminar

\title{2016/12/02 繧シ繝毳
\author{Wernher Magnus Maximilian Freiherr von Braun}
\date{\today}
% 霈ェ隰幢シ亥鴨蟄ヲ繧シ繝滂シ画球蠖鍋ッ・峇
\contents{100}{110} % required only for dynamics seminar

% 遶逡ェ蜿キ・悟シ冗分蜿キ縺ェ縺ゥ縺ョ螟画峩
%\setcounter{section}{3}
%\setcounter{subsection}{13}
%\setcounter{subsubsection}{4} 
%\setcounter{equation}{141}  
%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF
%DIF CFONT PREAMBLE %DIF PREAMBLE
\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} %DIF PREAMBLE
\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} %DIF PREAMBLE
\providecommand{\DIFadd}[1]{{\protect\color{blue} \sf #1}} %DIF PREAMBLE
\providecommand{\DIFdel}[1]{{\protect\color{red} \scriptsize #1}} %DIF PREAMBLE
%DIF SAFE PREAMBLE %DIF PREAMBLE
\providecommand{\DIFaddbegin}{} %DIF PREAMBLE
\providecommand{\DIFaddend}{} %DIF PREAMBLE
\providecommand{\DIFdelbegin}{} %DIF PREAMBLE
\providecommand{\DIFdelend}{} %DIF PREAMBLE
\providecommand{\DIFmodbegin}{} %DIF PREAMBLE
\providecommand{\DIFmodend}{} %DIF PREAMBLE
%DIF FLOATSAFE PREAMBLE %DIF PREAMBLE
\providecommand{\DIFaddFL}[1]{\DIFadd{#1}} %DIF PREAMBLE
\providecommand{\DIFdelFL}[1]{\DIFdel{#1}} %DIF PREAMBLE
\providecommand{\DIFaddbeginFL}{} %DIF PREAMBLE
\providecommand{\DIFaddendFL}{} %DIF PREAMBLE
\providecommand{\DIFdelbeginFL}{} %DIF PREAMBLE
\providecommand{\DIFdelendFL}{} %DIF PREAMBLE
%DIF LISTINGS PREAMBLE %DIF PREAMBLE
\RequirePackage{listings} %DIF PREAMBLE
\RequirePackage{color} %DIF PREAMBLE
\lstdefinelanguage{DIFcode}{ %DIF PREAMBLE
%DIF DIFCODE_CFONT %DIF PREAMBLE
  moredelim=[il][\color{red}\scriptsize]{\%DIF\ <\ }, %DIF PREAMBLE
  moredelim=[il][\color{blue}\sffamily]{\%DIF\ >\ } %DIF PREAMBLE
} %DIF PREAMBLE
\lstdefinestyle{DIFverbatimstyle}{ %DIF PREAMBLE
    language=DIFcode, %DIF PREAMBLE
    basicstyle=\ttfamily, %DIF PREAMBLE
    columns=fullflexible, %DIF PREAMBLE
    keepspaces=true %DIF PREAMBLE
} %DIF PREAMBLE
\lstnewenvironment{DIFverbatim}{\lstset{style=DIFverbatimstyle}}{} %DIF PREAMBLE
\lstnewenvironment{DIFverbatim*}{\lstset{style=DIFverbatimstyle,showspaces=true}}{} %DIF PREAMBLE
%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF

\begin{document}
    \maketitle

    \section{蠎剰ォ凡
    We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.

    
    縺・m縺ッ縺ォ縺サ縺ク縺ィ縺。繧翫〓繧九r
    繧上°繧医◆繧後◎縺、縺ュ縺ェ繧峨・
    縺・p縺ョ縺翫¥繧・∪縺代・縺薙∴縺ヲ
    縺ゅ&縺阪f繧√∩縺励q縺イ繧ゅ○縺・
    濶イ縺ッ蛹ゅ∈縺ゥ 謨」繧翫〓繧九r
    謌代′荳冶ェー縺・蟶ク縺ェ繧峨・
    譛臥ぜ縺ョ螂・螻ア 縺代・雜翫∴縺ヲ
    豬・″螟「隕九§ 驟斐・繧ゅ○縺・
    \paragraph{蟆剰ヲ句・縺抑\leavevmode\\
    \indent
    蟆剰ヲ句・縺励r蜈・繧後◆縺・エ蜷医・蜃ヲ逅・    \begin{align}
       \hat{J} \cdot \dot{\vec{\omega}} + \vec{\omega}\times \vec{h}  = \vec{T} \label{eq:euler}
   \end{align}
    蠑十eqref{eq:euler}

    \section{蠑慕畑}
    蠑慕畑縺ョ繝・せ繝・cite{Stevenson2012,Tsukahara2016},\cite{konoue2005,Wie2008,Isabelle,book,inbook,inproceeding,URL}
\begin{figure}[h]
    \begin{subfigure}{0.5\linewidth}
        \centering\includegraphics[width=5cm]{fig/fig1.eps}
        \caption{$\vec{f},\vec{g},\vec{h},\vec{u}$縺ョ髢「菫・\label{fig:fig1}    % 繧ュ繝」繝励す繝ァ繝ウ縺悟峙縺ョ荳矩Κ縺ォ蜈・繧・ \end{subfigure}
    \begin{subfigure}{0.5\linewidth}
        \centering\includegraphics[width=5cm]{fig/fig2.eps}
        \caption{$\vec{g},\vec{h},\vec{u}$縺ョ髢「菫・\label{fig:fig2}    % 繧ュ繝」繝励す繝ァ繝ウ縺悟峙縺ョ荳矩Κ縺ォ蜈・繧・   \end{subfigure}
    \caption{蜷・・繧ッ繝医Ν縺ョ蟷セ菴慕噪髢「菫・\label{fig:case4} 
\end{figure}

\bibliography{references}

\end{document} 

上記コマンドの問題点は以下2点である。

  1. latexdiffの出力文字コードは「UTF-8*2であるが、PowerShellのデフォルト値「Shift_JIS」として誤認される。
  2. output.tex文字コードが、PowerShell 5.x系のデフォルト値「BOMありUTF-16 LE」になってしまう。

対処法

問題1への対処

PowerShellのパイプ|はオブジェクトを渡す。 そのため、文字コードPowerShellのデフォルト値「Shift-JIS」でない文字を扱う場合には、正しい文字コードPowerShell上で指定する必要がある。 今回は、latexdiffの出力文字コードである「UTF-8」を以下のように指定する必要がある。

[Console]::OutputEncoding = [Text.Encoding]::UTF8

参考: ladybug.hatenadiary.org

問題2への対処

PowerShell 5.xで「BOMなしUTF-8」を出力するには、次のコマンドを実行する。

latexdiff -e utf-8 -t CFONT input1.tex input2.tex | Out-String | % { [Text.Encoding]::UTF8.GetBytes($_) } | Set-Content -Path "output.tex" -Encoding Byte

PowerShell Core 6.x系ではデフォルト文字コードが「BOMなしUTF-8」に変更されているため、以下のコマンドで良い。

latexdiff -e utf-8 -t CFONT input1.tex input2.tex > "output.tex" 

参考: blog.shibata.tech

blog.shibata.tech

結論

PowerShell 5.x (2019/6時点でWindows10のデフォルト)を使う場合

文字化けしていない「BOMなしUTF-8」なoutput.texは以下のコマンドで出力できる。

[Console]::OutputEncoding = [Text.Encoding]::UTF8
latexdiff -e utf-8 -t CFONT input1.tex input2.tex | Out-String | % { [Text.Encoding]::UTF8.GetBytes($_) } | Set-Content -Path "output.tex" -Encoding Byte

PowerShell Core 6.xを使う場合

[Console]::OutputEncoding = [Text.Encoding]::UTF8
latexdiff -e utf-8 -t CFONT input1.tex input2.tex > output.tex

未確認だが、デフォルト文字コードの変更がなければ PowerShell 7でも使えると思われる。

コマンドプロンプトを使う場合

説明はしなかったが、コマンドプロンプトであれば以下のコマンドでよい。

latexdiff -e utf-8 -t CFONT input1.tex input2.tex > output.tex

コマンドプロンプトではlatexdiffの出力をバイナリのままファイルに書き込んでいると思われるため、追加コマンドが不要であると考えている。

*1:文字コードは「BOMなしUTF-8」。

*2:BOMの有無は調べていない。