Newcommand 中的数字

Newcommand 中的数字

我有数千条经过特别编号的特殊文本行。

001001=aaaaaaaa
001002=bbbbbbbb
001003=cccccccc

002001=dddddddd
002002=mmmmmmmm
002003=jjjjjjjj

003001=uuuuuuuu
003002=iiiiiiii
003003=vvvvvvvv

ETC。

在我的 Latex 文件中,我想插入带有简单数字条目(例如001001或 )的特定指定文本\001001,这些文本将在编译后显示aaaaaaaa。我该怎么做?

请注意,我已经研究了以下问答,但仍然无法得出好的结果,我不能使用\catcode。我使用xetexpolyglossia如果这有区别的话。

答案1

不使用外部包的方法如下:

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.dat}
001001=aaaaaaaa
001002=bbbbbbbb
001002=cccccccc

002001=dddddddd
002002=mmmmmmmm
002003=jjjjjjjj

003001=uuuuuuuu
003002=iiiiiiii
003003=vvvvvvvv
\end{filecontents*}

\makeatletter
\newread\nina@read
\newcommand{\grabdata}[1]{%
  \begingroup\endlinechar=\m@ne
  \openin\nina@read=#1\relax
  \loop\ifeof\nina@read\else
    \read\nina@read to \@tempa
    \nina@convert
  \repeat
  \closein\nina@read
  \endgroup}
\def\nina@convert{%
  \if\relax\detokenize\expandafter{\@tempa}\relax\else
    \expandafter\nina@convert@i\@tempa\relax
  \fi}
\def\nina@convert@i#1=#2\relax{%
  \global\@namedef{nina@data@#1}{#2}}
\newcommand{\numentry}[1]{\@nameuse{nina@data@#1}}
\makeatother

\grabdata{\jobname.dat}


\begin{document}

\numentry{001001}

\numentry{001002}

\numentry{001003}

\numentry{002001}

\numentry{002002}

\numentry{002003}

\numentry{003001}

\numentry{003002}

\numentry{003003}

\end{document}

我使用它\jobname.dat作为文件名只是为了不破坏我现有的文件。

如果数据文件被命名,foo.xyz你将使用

\grabdata{foo.xyz}

然后数据将以以下形式提供

\numentry{001001}

数据文件逐行读取,每行在=token 处拆分以获取键和值。因此,如果该行是

001001=aaaaaaaa

我们本质上

\@namedef{nina@data@001001}{aaaaaaaa}

(全局而言,我们用它\endlinechar=-1来避免虚假空格并删除空行)。

答案2

一种方法是使用包裹datatool。尝试打印002003001002和的值,999999结果如下:

在此处输入图片描述

笔记:

  • 我用的\IfStrEq包裹xstring包,我更喜欢它的语法,但是如果需要的话,可能不用那个包也可以做到这一点。
  • 包裹filecontents仅用于创建 MWE 来生成数据文件foo.dat。否则就不需要了。

代码:

\documentclass{article}
\usepackage{datatool}
\usepackage{xstring}

\usepackage{filecontents}
\begin{filecontents*}{foo.dat}
001001=aaaaaaaa
001002=bbbbbbbb
001002=cccccccc

002001=dddddddd
002002=mmmmmmmm
002003=jjjjjjjj

003001=uuuuuuuu
003002=iiiiiiii
003003=vvvvvvvv
\end{filecontents*}

\newcommand{\LocateDataRow}[3]{%
    % #1 = csname in which to store the required data
    % #2 = database to search
    % #3 = word to search for
    %
    \global\expandafter\def\csname#1\endcsname{UNDEFINED}% Default in case it is not found
    %
    \DTLforeach{#2}{%
        \NumValue=NumValue,%
        \DataValue=DataValue%
        }{%
        \IfStrEq{#3}{\NumValue}{% 
            % Found an exact match!! Yeah
            \global\expandafter\def\csname#1\endcsname{\DataValue}%
            \dtlbreak% Break out of for loop 
        }{%
            % Did not find match -- continue searching
        }%
    }%
}%

\begin{document}
\DTLsetseparator{=}% Define separator of the data
\DTLloaddb[noheader,keys={NumValue,DataValue}]{myDB}{foo.dat}

\LocateDataRow{RequiredData}{myDB}{002003}\RequiredData

\LocateDataRow{RequiredData}{myDB}{001002}\RequiredData

\LocateDataRow{RequiredData}{myDB}{999999}\RequiredData
\end{document}

答案3

这是一个用于expl3解析数据文件的解决方案。它使用属性列表将数据保存在内存中。用法意味着在此属性列表中查找键并显示其存储的值。

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{foo.dat}
001001=aaaaaaaa
001002=bbbbbbbb
001002=cccccccc

002001=dddddddd
002002=mmmmmmmm
002003=jjjjjjjj
foo bar
003001=uuuuuuuu
003002=iiiiiiii
003003=vvvvvvvv
\end{filecontents*}

\usepackage{expl3,xparse}

\ExplSyntaxOn

\tl_new:N \l_ndata_line_tl
\tl_new:N \l_ndata_key_tl
\tl_new:N \l_ndata_value_tl

\prop_new:N \g_ndata_prop

% loading and parsing the data file

\cs_new:Npn \ndata_load_file:n #1 {
% opening a read stream
   \ior_open:Nn \l_ndata_ior {#1}
% loop until we see "eof"
   \bool_until_do:nn { \ior_if_eof_p:N \l_ndata_ior }
      {
% read one line of data into a variable
        \ior_to:NN  \l_ndata_ior \l_ndata_line_tl
% if the line has no "=" we skip it
        \tl_if_in:NnTF \l_ndata_line_tl {=}
            {
% if it has we parse (low-level, strange input is usually strange
               \exp_after:wN \ndata_parse:w \l_ndata_line_tl \q_stop 
               \typeout {line~ processed~ (\l_ndata_line_tl)}
            }
           {  \typeout {line~ without~ =~ ignored~ (\l_ndata_line_tl)}  }
      }
% close the stream as it is no longer needed
  \ior_close:N \l_ndata_ior
% showing the resulting property list (comment out in real use)
   \prop_show:N \g_ndata_prop
}

\cs_new:Npn \ndata_parse:w #1=#2\q_stop {
   \tl_set:Nn \l_ndata_key_tl {#1}
   \tl_set:Nn \l_ndata_value_tl {#2}
% remove any space to the left and right of key and value
   \tl_trim_spaces:N \l_ndata_key_tl
   \tl_trim_spaces:N \l_ndata_value_tl
% put the data into the property list
   \prop_gput:Noo \g_ndata_prop  \l_ndata_key_tl \l_ndata_value_tl
}

% using the data (instead of error handling for nonexistent keys I just used typeout)
\cs_new:Npn \ndata_use:n #1 {
   \prop_get:NnNTF \g_ndata_prop {#1} \l_ndata_value_tl
            { \l_ndata_value_tl }
            { ??? 
               \typeout{Warning:~ key~`#1`~ not~ known}
            }
}

% document level commands:

\DeclareDocumentCommand \ndataload {m} { \ndata_load_file:n {#1} }
\DeclareDocumentCommand \ndata     {m} { \ndata_use:n {#1} }

\ExplSyntaxOff

\begin{document}

\ndataload{foo.dat}

\ndata{002003}
\ndata{001002}
\ndata{999999}

\end{document}

相关内容