5

I have control_array.tex and 10 templateA.tex, templateB.tex, ... TeX files. In control_array.tex:

  • ArrayName = [Name1,Name2,...Name10]
  • ArrayColor = [Color1,Color2,...Color10]

With Array in control_array.tex I can change all variable only one time in all templates: templateA.tex, templateB.tex, ...

Here's my MWE:

\documentclass[a4paper,twoside,12pt]{article}
\usepackage{xcolor}
\begin{document}
%Call Name1, Nam10...Color 1, Color2...Color10
\begin{enumerate}
\item \textcolor{color1}{Name1}
\item \textcolor{color2}{Name2}
\item \textcolor{color3}{Name3}
\end{enumerate}
\textcolor{color4}{Name9} \\
\textcolor{color5}{Name8}
\end{document}

How can I do it with LaTeX? Any ideas are welcome.

1
  • Constant arrays are easy, variable arrays use things like \csname name\theindex\endcsname. Commented Feb 14, 2019 at 4:51

4 Answers 4

5

You could use pgffor for that.

\documentclass[a4paper,twoside,12pt]{article}
\usepackage{pgffor}
\usepackage{xcolor}
\begin{document}
\def\ArrayNames{{"koala","duck","marmot","penguin","bear"}}
\def\ArrayColors{{"gray","yellow","blue","red","brown"}}
\begin{enumerate}
\foreach \X in {0,...,4}
{\pgfmathsetmacro{\myname}{\ArrayNames[\X]}
\pgfmathsetmacro{\mycolor}{\ArrayColors[\X]}
\item \textcolor{\mycolor}{\myname}}
\end{enumerate}
\end{document}

enter image description here

Or with an external file (which I create here for the convenience of others in the MWE, but you may drop the filecontents stuff as long you have a data file).

\documentclass[a4paper,twoside,12pt]{article}
\usepackage{filecontents}
\begin{filecontents*}{myarrays.tex}
\def\ArrayNames{{"koala","duck","marmot","penguin","bear"}}
\def\ArrayColors{{"gray","yellow","blue","red","brown"}}
\end{filecontents*}
\usepackage{pgffor}
\usepackage{xcolor}
\begin{document}
\input{myarrays.tex}
\begin{enumerate}
\foreach \X in \ArrayNames
{\foreach \Y [count=\Z starting from 0]in \X 
{\pgfmathsetmacro{\mycolor}{\ArrayColors[\Z]}
\pgfmathsetmacro{\myname}{\ArrayNames[\Z]}
\item \textcolor{\mycolor}{\myname}}}
\end{enumerate}
\end{document}

And of course you can install any mapping. Here is an example (in which I assume you already have created myarrays.tex, if not uncomment the corresponding lines).

\documentclass[a4paper,twoside,12pt]{article}
% \usepackage{filecontents}
% \begin{filecontents*}{myarrays.tex}
% \def\ArrayNames{{"koala","duck","marmot","penguin","bear"}}
% \def\ArrayColors{{"gray","yellow","blue","red","brown"}}
% \end{filecontents*}
\usepackage{pgffor}
\usepackage{xcolor}
\begin{document}
\input{myarrays.tex}
\pgfkeys{/pgf/declare function={mymap(\x)=int(mod(1+\x*\x,4));}}
\begin{enumerate}
\foreach \X in \ArrayNames
{\foreach \Y [count=\Z starting from 0]in \X 
{\pgfmathsetmacro{\mycolor}{\ArrayColors[mymap(\Z)]}
\pgfmathsetmacro{\myname}{\ArrayNames[\Z]}
\item \textcolor{\mycolor}{\myname}}}
\end{enumerate}
\end{document}

enter image description here

As you can see, this function is chosen such that it distinguishes between birds on the one hand and mammals and beings on the other hand.

16
  • thank for your quick reply. I know that pgffor in same file.tex can do it. Can you solution/idea set variable array in control file, not in template file? \def\ArrayNames{{"koala","duck","marmot","penguin","bear"}} \def\ArrayColors{{"gray","yellow","blue","red","brown"}} Thanks
    – latexforti
    Commented Feb 14, 2019 at 2:25
  • 1
    @tisaigon myarrays.tex needs only to have \def\ArrayNames{{"koala","duck","marmot","penguin","bear"}} \def\ArrayColors{{"gray","yellow","blue","red","brown"}} in it.
    – user121799
    Commented Feb 14, 2019 at 4:52
  • 1
    @tisaigon I added a mapping function (the flexibility of adding this very easily may be an advantage of this approach), which you can adjust to your needs.
    – user121799
    Commented Feb 14, 2019 at 6:36
  • 1
    @tisaigon What does \documentclass[a4paper,twoside,12pt]{article} \usepackage{pgffor} \usepackage{xcolor} \begin{document} \input{myarrays.tex} \pgfmathsetmacro{\myname}{\ArrayNames[3]} \myname \end{document} give you?
    – user121799
    Commented Feb 14, 2019 at 7:12
  • 1
    @tisaigon Could you please ask a new question for that. I am just about to go to bed and others will help you more quickly. If you are lucky, Christian Hupfer sees your question, then you will get an excellent answer.
    – user121799
    Commented Feb 14, 2019 at 7:47
4

Trivial with listofitems.

\documentclass{article}
\usepackage{listofitems,xcolor}
\newcommand\ArrayNames{Name1,Name2,N3,N4,N5,N6,N7,N8,N9,Name10}
\newcommand\ArrayColors{red,blue,cyan,cyan!50!red,red!50,
  purple,green,yellow,blue!50,magenta}
\readlist*\arrayname{\ArrayNames}
\readlist*\arraycolor{\ArrayColors}
\begin{document}
\begin{enumerate}
\foreachitem\x\in\arrayname{\item \textcolor{\arraycolor[\xcnt]}{\x}}
\end{enumerate}

\textcolor{\arraycolor[4]}{\arrayname[9]}

\textcolor{\arraycolor[5]}{\arrayname[8]}
\end{document}

enter image description here

3

You can have files with the following structure

\colorlist{
  {red}
  {green}
  {blue}
  {green!40!yellow}
  {-green!40!yellow}
  {rgb:-green!40!yellow,3;green!40!yellow,2;red,1}
  {red>wheel,12}
}

It would also be possible to have the simpler structure

red
green
blue
green!40!yellow

- green!40!yellow rgb:-green!40!yellow,3;green!40!yellow,2;red,1 red>wheel,12

if preferred. Then in the document you call

\assigncolors{<filename>}{<list of names for the colors>}

Here's the code, using filecontents for making the example self-contained; the name for the color list file can be whatever you prefer.

\begin{filecontents}{\jobname.colors}
\colorlist{
  {red}
  {green}
  {blue}
  {green!40!yellow}
  {-green!40!yellow}
  {rgb:-green!40!yellow,3;green!40!yellow,2;red,1}
  {red>wheel,12}
}
\end{filecontents}

\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\assigncolors}{mm}
 {% #1 = file name, #2 = list of names
  \clist_set:Nn \l__tisaigon_colornames_clist { #2 }
  \file_input:n { #1 }
 }
\NewDocumentCommand{\colorlist}{m}
 {
  \int_zero:N \l__tisaigon_colornames_int
  \tl_map_inline:nn { #1 }
   {
    \int_incr:N \l__tisaigon_colornames_int
    \colorlet
     {
      \clist_item:Nn \l__tisaigon_colornames_clist { \l__tisaigon_colornames_int }
     }
     {
      ##1
     }
   }
 }
\clist_new:N \l__tisaigon_colornames_clist
\int_new:N \l__tisaigon_colornames_int
\ExplSyntaxOff

\assigncolors{\jobname.colors}{
  color1,
  color2,
  color3,
  header,
  body,
  footer,
  fancy,
}

\begin{document}

\textcolor{color1}{Abc}

\textcolor{color2}{Abc}

\textcolor{color3}{Abc}

\textcolor{header}{Abc}

\textcolor{body}{Abc}

\textcolor{footer}{Abc}

\textcolor{fancy}{Abc}

\end{document}

enter image description here

2

In a very simplistic way you can place a number of color definitions using (say) \colorlet{colorX}{<colour>} inside color_array.tex and load them within the document preamble:

enter image description here

\documentclass{article}

% Just for this example, create control_array.tex that contains all the colour definitions
\usepackage{filecontents}
\begin{filecontents*}{control_array.tex}
\usepackage{xcolor}
\colorlet{color1}{blue}
\colorlet{color2}{green}
\colorlet{color3}{red!30!yellow}
\colorlet{color4}{rgb:black,1;red,2;orange,3}
\colorlet{color5}{black!50}
\end{filecontents*}

\input{control_array}% Input colour definitions

\begin{document}

\begin{enumerate}
  \item \textcolor{color1}{Name1}
  \item \textcolor{color2}{Name2}
  \item \textcolor{color3}{Name3}
\end{enumerate}

\textcolor{color4}{Name9}

\textcolor{color5}{Name8}

\end{document}

Note that \input{color_array} is called within the preamble since color_array.tex includes a call to load xcolor which can only be called within the preamble.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .