我正在使用 readarray 读取包含 key=value 对的文件,如下所示这里。我还想允许读取文件中的评论,可以实现吗(不借助 lualatex,我想使用普通的 pdftex)?
代码(带有示例文件内容):
\begin{filecontents*}[overwrite]{setup.txt}
% comment
distance = 60 % test
% another comment
gridRows = 29
markerSide = 4
\end{filecontents*}
\usepackage{readarray}
\readarraysepchar{=}
\readdef{setup.txt}{\fileData}
\readarray\fileData\setupInfo[-,2]
% turn each key into its own command
\newcounter{keyCount}
\setcounter{keyCount}{0}%
\whiledo{\value{keyCount} < \setupInfoROWS}{%
\stepcounter{keyCount}%
\typeout{\arabic{keyCount}: \setupInfo[\arabic{keyCount},1] -> \setupInfo[\arabic{keyCount},2]}
\expandafter\xdef\csname \setupInfo[\arabic{keyCount},1]\endcsname{%
\setupInfo[\arabic{keyCount},2]}%
}
经过与下面的 Steven 讨论,我发现如果注释位于自己的行上(文件的第一行除外)或者位于键值对之后,那么注释已经是可能的。删除第一行的注释后,上述代码输出:
1: distance -> 60
2: gridRows -> 29
3: markerSide -> 4
答案1
该readarray
软件包确实已经尊重了评论。
这里的问题不是注释存在,而是文件的第一条记录完全是空白的(通过注释)。包使用第一条记录来分析每条记录找到多少个字段(这是消化未来数组的有用信息)。这就是它挂起的地方。如果您删除文件第一条记录上的注释,事情就会按预期进行。
但是,我可能应该让包预见这种情况。所以我会给你两个选择:尊重空白记录,但如果初始记录为空白,则不要挂断,或者忽略空白记录。
我正在编辑我最初的答案,以便在一个 MWE 中提供这两个选项。在这里,我引入了一个新的\ifignoreblankreadarrayrecords
,它可以被设置为真或假。MWE 显示正在使用的两个选项。重新定义的\@readdef
宏使用注释来突出显示对原始宏定义所做的更改。
%dbA
\begin{filecontents*}[overwrite]{databaseA.csv}
% comment
distance = 60 % in cm
markerSide = 4 % in deg
\end{filecontents*}
\documentclass{article}
\usepackage{readarray}[2021-08-08]
\makeatletter
\newif\ifignoreblankreadarrayrecords
\def\@readdef#1#2#3{%
\clear@array{#3}%
\edef\former@recordcount{\csname #3CELLS\endcsname}%
\def\first@row{T}%
\def\first@plane{T}%
\catcode\endlinechar=\readarrayendlinechar\relax %
\def#2{}%
\setcounter{@record}{0}%
\openin\rdar@file=#1%
\ifignoreblankreadarrayrecords\def\rdar@iftest{\rdar@fileline\empty}\else
\def\rdar@iftest{01}\fi
\loop\unless\ifeof\rdar@file%
\read\rdar@file to\rdar@fileline % Reads file line into \rdar@fileline%
\expandafter\ifx\rdar@iftest\else% PERFORM \ifignoreblankreadarrayrecords TEST
\addtocounter{@record}{1}%
\expandafter\g@addto@macro\expandafter#2\expandafter{\rdar@fileline}%
\ifx\rdar@fileline\empty\else\expandafter\g@addto@macro%
\expandafter#2\expandafter{\read@array@sepchar}%\fi% <---DON'T \fi HERE
\if T\first@row\read@array{#2}\setcounter{@col}{\numexpr(\Arg@listlen-1)}%
\edef\ncols{\arabic{@col}}\def\first@row{F}\setcounter{@row}{1}%
\else%
\if T\first@plane%
\ifx\rdar@fileline\empty
\edef\nrows{\arabic{@row}}\def\first@plane{F}%
\else
\addtocounter{@row}{1}%
\fi
\fi%
\fi%
\fi% <---EXTEND \fi TO HERE TO NOT ANALYZE INITIAL BLANK LINE
\def\record@name{\csname #3[\the@record]\endcsname}%
\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter%
\expandafter\def\expandafter\record@name\expandafter{\rdar@fileline}%
\fi% FINISH \ifignoreblankreadarrayrecords TEST
\repeat%
\edef\nrecords{\arabic{@record}}%
\expandafter\edef\csname #3PLANES\endcsname{0}%
\expandafter\edef\csname #3ROWS\endcsname{\nrecords}%
\expandafter\edef\csname #3COLS\endcsname{0}%
\expandafter\edef\csname #3CELLS\endcsname{\nrecords}%
\closein\rdar@file%
\catcode\endlinechar=5 %
\define@rootmacro{#3}%
}
\makeatother
\renewcommand\typesetrowsepchar{\\}
\renewcommand\typesetcolsepchar{&}
\begin{document}
\readarraysepchar{=}
Ignore blank records: TRUE
\ignoreblankreadarrayrecordstrue
\readdef{databaseA.csv}\dbA
1st array record is ``\ArrayRecord[1]''
2nd array record is ``\ArrayRecord[2]''
\readarray\dbA\arrayA[-,\ncols]
\begin{tabular}{cc}
\hline
\typesetarray\arrayA\\
\hline
\end{tabular}
\bigskip
Ignore blank records: FALSE
\ignoreblankreadarrayrecordsfalse
\readdef{databaseA.csv}\dbA
2nd array record is ``\ArrayRecord[2]''
4th array record is ``\ArrayRecord[4]''
\readarray\dbA\arrayA[-,\ncols]
\begin{tabular}{cc}
\hline
\typesetarray\arrayA\\
\hline
\end{tabular}
\end{document}