用变音符号重新写出表格

用变音符号重新写出表格

我有一个后续问题https://tex.stackexchange.com/a/598981/46023

MWE 中的一切都正常,但是在我的原始示例中使用时它不再起作用(注意:originaltable.csv 是原始版本的大大缩短版本,其中包含比较、计算等)。

originaltable.csv 中所写的“Molybdän”一词中的变音符号“ä”是有问题的。

\begin{filecontents}[overwrite]{originaltable.csv}
Z; Symbol; Name
2; He; Helium
41; Mo; Molybdän
\end{filecontents}
    
\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep=semicolon, header=true]{originaltable.csv} {\psetable}

% Methode % https://tex.stackexchange.com/a/598981/46023
\makeatletter
\long\def\protected@iwrite#1#2#3{\begingroup%
#2%
\let\protect\@unexpandable@protect%
\edef\reserved@a{\immediate\write#1{#3}}%
\reserved@a%
\endgroup%
\if@nobreak\ifvmode\nobreak\fi\fi}
\newcommand{\mywrite}[2]{\protected@iwrite#1{}{#2}}%
\makeatother
   
\begin{document}
\newwrite\out
\immediate\openout\out=out.csv

\foreach[count=\n from 0] \row in {0,1}{%%
% In:
\pgfplotstablegetelem{\row}{Z}\of{\psetable}
\xdef\Z{\pgfplotsretval}%
\pgfplotstablegetelem{\row}{Symbol}\of{\psetable}%
\xdef\Symbol{\pgfplotsretval}%
\pgfplotstablegetelem{\row}{Name}\of{\psetable}%
\xdef\Name{\pgfplotsretval}%
% Out:
\mywrite\out{\Z; \Symbol; \Name}% does not work :(
}%%
\immediate\closeout\out

%\input{out.csv}
% Target in: 
\pgfplotstableread[col sep=semicolon, header=false]{out.csv}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}
\end{document}

答案1

问题在于 pdfLaTeX 如何处理 ä(和其他重音字符)。快速简单的解决方案:使用 XeLaTeX 或 LuaLaTeX。

你遇到麻烦的地方是当\xdef\pgfplotsretval您会绕过任何可能存在的扩展保护。最简单的解决方法是不是使用\xdef,而是使用\let。我在这个答案中谈到了\let与定义宏https://tex.stackexchange.com/a/598902/202780昨天。这是一个\let完全适合这项工作的工具的案例。

如果您想这样做\edef,LaTeX 提供的选项要求超出用户级命令的范围,使用私有命令\protected@edef或 expl3 等效命令,这是我目前无法找到的,我在粗略浏览 interface3.pdf 时找不到,但我相信大卫卡莱尔会跳出来提供它,即使在这种情况下\let是最好的解决方案。

答案2

没有理由使用\xdef(这会破坏重音字符)。

由于写入操作发生在循环周期内\immediate,因此也不需要全局定义。您只需\pgfplotsretval以不同的(本地)名称保存即可。

\begin{filecontents}[overwrite]{\jobname-original.csv}
Z; Symbol; Name
2; He; Helium
41; Mo; Molybdän
\end{filecontents}
    
\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep=semicolon, header=true]{\jobname-original.csv} {\psetable}

% Methode % https://tex.stackexchange.com/a/598981/46023
\makeatletter
\providecommand\protected@iwrite[3]{%
  \begingroup
  #2%
  \let\protect\@unexpandable@protect
  \edef\reserved@a{\immediate\write#1{#3}}%
  \reserved@a
  \endgroup
  \if@nobreak\ifvmode\nobreak\fi\fi
}
\newcommand{\mywrite}[2]{\protected@iwrite#1{}{#2}}%
\makeatother
   
\begin{document}
\newwrite\out
\immediate\openout\out=\jobname.csv

\foreach[count=\n from 0] \row in {0,1}{%%
  % In:
  \pgfplotstablegetelem{\row}{Z}\of{\psetable}%
  \let\Z\pgfplotsretval
  \pgfplotstablegetelem{\row}{Symbol}\of{\psetable}%
  \let\Symbol\pgfplotsretval
  \pgfplotstablegetelem{\row}{Name}\of{\psetable}%
  \let\Name\pgfplotsretval
  % Out:
  \mywrite\out{\Z; \Symbol; \Name}% works!
}
\immediate\closeout\out

%\input{out.csv}
% Target in: 
\pgfplotstableread[col sep=semicolon, header=false]{\jobname.csv}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}

\end{document}

(文件名已更改以避免破坏我的文件。)

写入文件的内容是

2; He; Helium
41; Mo; Molybdän

正如预期的那样。

一个expl3版本。

\begin{filecontents}[overwrite]{\jobname-original.csv}
Z; Symbol; Name
2; He; Helium
41; Mo; Molybdän
\end{filecontents}
    
\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep=semicolon, header=true]{\jobname-original.csv} {\psetable}

\ExplSyntaxOn

\NewDocumentCommand{\startwritingfile}{mm}
 {% #1 = output stream, #2 = file name
  \iow_new:N #1
  \iow_open:Nn #1 { #2 }
 }
\NewDocumentCommand{\finishwritingfile}{m}
 {% #1 = output stream
  \iow_close:N #1
 }
\NewDocumentCommand{\mywrite}{mm}
 {% #1 = output stream, #2 = tokens to write
  \iow_now:Nx #1 { \text_expand:n { #2 } }
 }

\ExplSyntaxOff

\begin{document}
\startwritingfile{\out}{\jobname.csv}

\foreach[count=\n from 0] \row in {0,1}{%%
  % In:
  \pgfplotstablegetelem{\row}{Z}\of{\psetable}%
  \let\Z\pgfplotsretval
  \pgfplotstablegetelem{\row}{Symbol}\of{\psetable}%
  \let\Symbol\pgfplotsretval
  \pgfplotstablegetelem{\row}{Name}\of{\psetable}%
  \let\Name\pgfplotsretval
  % Out:
  \mywrite\out{\Z; \Symbol; \Name}% works!
}
\finishwritingfile{\out}

%\input{out.csv}
% Target in: 
\pgfplotstableread[col sep=semicolon, header=false]{\jobname.csv}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}

\end{document}

答案3

正如一些评论所指出的那样: LuaLaTeX无需任何特殊方法即可让它发挥作用。

在此处输入图片描述

% arara: lualatex

\begin{filecontents}[overwrite]{originaltable.csv}
Z; Symbol; Name
2; He; Helium
41; Mo; Molybdän
\end{filecontents}

\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep=semicolon, header=true]{originaltable.csv} {\psetable}
\begin{document}
\newwrite\out
\immediate\openout\out=out.csv

\foreach[count=\n from 0] \row in {0,1}{%%
% In:
\pgfplotstablegetelem{\row}{Z}\of{\psetable}
\xdef\Z{\pgfplotsretval}%
\pgfplotstablegetelem{\row}{Symbol}\of{\psetable}%
\xdef\Symbol{\pgfplotsretval}%
\pgfplotstablegetelem{\row}{Name}\of{\psetable}%
\xdef\Name{\pgfplotsretval}%
% Out:
\immediate\write\out{\Z; \Symbol; \Name}% does not work :(
}%%
\immediate\closeout\out

%\input{out.csv}
% Target out: 
\pgfplotstableread[col sep=semicolon, header=false]{out.csv}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}
\end{document}

相关内容