# Numbers in Newcommand

I have some thousands of special text lines specifically numbered.

001001=aaaaaaaa
001002=bbbbbbbb
001003=cccccccc

002001=dddddddd
002002=mmmmmmmm
002003=jjjjjjjj

003001=uuuuuuuu
003002=iiiiiiii
003003=vvvvvvvv

etc.

In my Latex file I want to insert that specific assigned text with a simple number entry such as 001001 or perhaps \001001 , which in return will show aaaaaaaa once compiled. How can I do this?

Please note that I've already studied following Q&A's but still couldn't come up with a good result, not could I use \catcode. I use xetex and polyglossia if that makes difference.

-
You would not be able to easily use \001001 for a command. Would something like \numentry{001001} (that returns aaaaaaaa) be a possibility? – Werner Jun 15 '12 at 4:01
Yes, that would work. Please provide me with MWE. – Nina Jun 15 '12 at 4:06
– Peter Grill Jun 15 '12 at 7:54
Welcome to TeX.sx! Usually, we don't put a greeting or a "thank you" in our posts. While this might seem strange at first, it is not a sign of lack of politeness, but rather part of our trying to keep everything very concise. Upvoting is the preferred way here to say "thank you" to users who helped you. – Stephen Jun 15 '12 at 9:10

An approach without external packages can be as follows:

\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
\newcommand{\grabdata}[1]{%
\begingroup\endlinechar=\m@ne
\nina@convert
\repeat
\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}

I've used \jobname.dat as the file name just not to clobber my existing files.

If the data file is named foo.xyz you'll use

\grabdata{foo.xyz}

and then the data will be available in the form

\numentry{001001}

The data file is read line by line and each line is split at the = token to get the key and the value. So if the line is

001001=aaaaaaaa

we essentially do

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

(globally, as we use \endlinechar=-1 to avoid spurious spaces and get rid of empty lines).

-
Thank you egreg for your valuable help! – Nina Jun 15 '12 at 20:01

One way is to use the datatool package. An attempt to print the values of 002003, 001002, and 999999 yields:

## Notes:

• I used \IfStrEq from the the xstring package package as I prefer it's syntax, but this can probably be done without that pacakge if desired.
• The filecontents package was used only to create a MWE to generate the data file foo.dat. It is not needed otherwise.

## Code:

\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
%
%
\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

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

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

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

Here is a solution using expl3 for parsing the data file. It uses a property list to keep the data in memory. Usage then means looking up the the key in this property list and displaying its stored value.

\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

\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 \ndata     {m} { \ndata_use:n {#1} }

\ExplSyntaxOff

\begin{document}