7

I need help with these macros. What I'm trying to achieve is to loop over all the letters in the title of a custom environment. Then colorize the first three letters of that title with a different color each. The colors used should be stored in a list.

So for every call of the environment, I'm increasing a counter that counts the number of environments, I then call a function that fetches (or rather should fetch) the correct color.

That function should now iterate through the list of colors and return the color that has the same key as the environment: For the first environment, the first color should be used, for the second environment, the second one and so on...

A feature that is not implemented yet in my (not working) code is to restart with the first color of the list if there are more environments than colors.

There are also some bugs in this:

  • The color is only returned for the first environment
  • The letter loop deletes my spaces

If you have any idea how to solve one of these problems, I'll be very glad for your answer. This also applies if you think this should be handled in a different way.

M(N)WE

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox, xcolor, environ, parskip}

% Title Color List
\listadd{\titleColors}{red}
\listadd{\titleColors}{green}
\listadd{\titleColors}{blue}
\listadd{\titleColors}{yellow}



% Colorize the first three letters
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcounter{letterCounter}%
\makeatletter
    \newcommand{\titleColorize}[2]{%
        \setcounter{letterCounter}{1}%
        \@tfor\next:=#1\do{%
            \ifnumcomp{\the\value{letterCounter}}{<}{4}%
            {\textcolor{#2}{\next}}%
            {\next}%
            \refstepcounter{letterCounter}%
        }%
    }%
\makeatother



% Get the corresponding color
% %%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcounter{colourCounter}
\setcounter{colourCounter}{1}
\newcommand{\getTitleColor}[1]%
{%
    \renewcommand*{\do}[1]%
    {%
        \ifnumcomp{\thecolourCounter}{=}{#1}%
        {%
            ##1%
        }{}%
        \refstepcounter{colourCounter}%
    }%
    \dolistloop{\titleColors}%
}



% Define the environment
% %%%%%%%%%%%%%%%%%%%%%%
\newcounter{titleCounter}
\setcounter{titleCounter}{1}

\NewEnviron{entrylist}[1]{
    \vskip 1em
    {%
        \LARGE\bfseries\lowercase{%
            \titleColorize{#1}{red}
            \getTitleColor{\thetitleCounter} % Returns the correct color
            % \titleColorize{#1}{\getTitleColor{\thetitleCounter}}
        }%
    }\par
    \refstepcounter{titleCounter}
    \BODY
}



\begin{document}

    \begin{entrylist}{Test 1}
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    \end{entrylist}

    \begin{entrylist}{Test 2}
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    \end{entrylist}

    \begin{entrylist}{Test 3}
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    \end{entrylist}

    \begin{entrylist}{Test 4}
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    \end{entrylist}

    \begin{entrylist}{Test 5}
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    \end{entrylist}

\end{document}

Edit

The answers provided by Werner and egreg are both fully functional, however, due to the very complex syntax of the expl3 "language", I prefer Werners approach.

After implementing the code provided by the latter into my project, I realized the need of translations in my project. So I imported the translations package and defined translations for all the strings in the document. Also for the titles of my custom entrylist environment which were subject of this question. After replacing the strings by a \GetTranslation{} command, I recompiled the document and noticed that the output does not show the correct result, even if LaTeX does not throw an error message. As this issue is clearly caused by the code, looping through the string passed and setting a color to the first three items, I think that it is better to keep this in the same thread instead of opening a new one. If anyone knows what causes the false output and how this could be fixed, feel free to answer. At best this should work with the more comprehensible code provided by Werner.

Here is what LaTeX outputs: Babel on ngerman and \GetTranslation{interests} results in the output

terestsngerman

If selecting english as language, it changes to

terestsenglish

So apparently the \GetTranslation command is not executed at all as terests is clearly the key of the translatable string (except the two first letters).

MWE by Werner with added translations

\documentclass[ngerman]{article}



% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%

\usepackage{%
    xcolor,%
    environ,%
    babel,%
    translations,%
}



% %%%%%%%%%%%%%%%
% Define Commands
% %%%%%%%%%%%%%%%

% Define the listcolor list
\newcounter{listcolor}
\makeatletter
    \newcommand{\addlistcolor}[1]{%
        \stepcounter{listcolor}%
        \@namedef{titlecolor@\thelistcolor}{#1}%
    }
\makeatother

% Choose the title color
\newcounter{titlecolor}
\newcommand{\colortitle}[3]{%
    \expandafter\textcolor\expandafter{\csname titlecolor@\thetitlecolor\endcsname}{#1#2#3}%
}



% %%%%%%%%%%%%%%%%%%%
% Define environments
% %%%%%%%%%%%%%%%%%%%

% Define the entrylist environment
\NewEnviron{entrylist}[1]{%
    \stepcounter{titlecolor}%
    \ifnum\value{titlecolor}>\value{listcolor}
        \setcounter{titlecolor}{1}%
    \fi
    \par\addvspace{1em}
    \begingroup
        \LARGE\bfseries\MakeLowercase{\expandafter\colortitle #1\relax}
        \par\nobreak
    \endgroup
    \BODY
}



% %%%%%%%%%%%%%%%%%
% Declare Variables
% %%%%%%%%%%%%%%%%%

% List colors
\addlistcolor{red}
\addlistcolor{green}
\addlistcolor{blue}
\addlistcolor{yellow}

% Translations
\DeclareTranslationFallback{test}{Test}
\DeclareTranslation{English}{test}{Test}
\DeclareTranslation{German}{test}{Test}



\begin{document}

\begin{entrylist}{\GetTranslation{} 1}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{\GetTranslation{test} 2}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{\GetTranslation{test} 3}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{\GetTranslation{test} 4}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{\GetTranslation{test} 5}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\end{document}
6

Depending on your preference, you can cycle through the colours per entrylist:

enter image description here

\documentclass{article}

\usepackage{xcolor,environ}

\newcounter{listcolor}
\makeatletter
\newcommand{\addlistcolor}[1]{%
  \stepcounter{listcolor}%
  \@namedef{titlecolor@\thelistcolor}{#1}%
}
\addlistcolor{red}
\addlistcolor{green}
\addlistcolor{blue}
\addlistcolor{yellow}

\newcounter{titlecolor}
\newcommand{\colortitle}[3]{%
  \expandafter\textcolor\expandafter{\csname titlecolor@\thetitlecolor\endcsname}{#1#2#3}%
}
\NewEnviron{entrylist}[1]{%
  \stepcounter{titlecolor}%
  \ifnum\value{titlecolor}>\value{listcolor}
    \setcounter{titlecolor}{1}%
  \fi
  \par\addvspace{1em}
  \begingroup
  \LARGE\bfseries\MakeLowercase{\expandafter\colortitle #1\relax}
  \par\nobreak
  \endgroup
  \BODY
}

\begin{document}

\begin{entrylist}{Test 1}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 2}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 3}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 4}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 5}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\end{document}

...or you can cycle through each colour for each title:

enter image description here

\documentclass{article}

\usepackage{xcolor,environ}

\newcounter{listcolor}
\newcounter{curlistcolor}
\makeatletter
\newcommand{\addlistcolor}[1]{%
  \stepcounter{listcolor}%
  \@namedef{titlecolor@\thelistcolor}{#1}%
}
\makeatother
\addlistcolor{red}
\addlistcolor{green}
\addlistcolor{blue}
\addlistcolor{yellow}

\newcounter{titlecolor}
\newcommand{\colortitle}[3]{{%
  \edef\x{\noexpand\textcolor{\csname titlecolor@\thecurlistcolor\endcsname}}\x{#1}%
  \stepcounter{curlistcolor}%
  \ifnum\value{curlistcolor}>\value{listcolor}\relax
    \setcounter{curlistcolor}{1}%
  \fi
  \edef\x{\noexpand\textcolor{\csname titlecolor@\thecurlistcolor\endcsname}}\x{#2}%
  \stepcounter{curlistcolor}%
  \ifnum\value{curlistcolor}>\value{listcolor}\relax
    \setcounter{curlistcolor}{1}%
  \fi
  \edef\x{\noexpand\textcolor{\csname titlecolor@\thecurlistcolor\endcsname}}\x{#3}%
}}
\NewEnviron{entrylist}[1]{%
  \stepcounter{titlecolor}%
  \ifnum\value{titlecolor}>\value{listcolor}
    \setcounter{titlecolor}{1}%
  \fi
  \setcounter{curlistcolor}{\value{titlecolor}}%
  \par\addvspace{1em}
  \begingroup
  \LARGE\bfseries\lowercase{\colortitle #1\relax\relax\relax}%
  \par\endgroup\nobreak
  \BODY
}

\begin{document}

\begin{entrylist}{Test 1}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 2}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 3}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 4}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 5}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\end{document}
  • Thank you, Werner for this awesome Rewrite. As I find the expl3 syntax very difficult to understand I like this method more. Unfortunately, I have a small issue with your code and I was unable to find out the reason. If the title is, say My hobbies are: the space between my and hobbies is removed in the output while the one between hobbies and are stays. The ideal behaviour would be to let the space there and only colourize the first word. So maybe I should re-ask the question to: How to colourize the first 3 letters of the first word?. Thanks again for your help. – Sam Nov 18 '17 at 12:04
  • @sam: An quick fix for this would be to use My~hobbies are:. And if you only have one letter for the first word, you can use I~\relax am hungy:. – Werner Nov 19 '17 at 16:08
  • As this code was meant for my resume, I now included the translations package to be able to translate my resume. The problem is, that the use of \GetTranslation{} kills nice output of your code. Any idea why and how to solve it? – Sam Nov 20 '17 at 21:47
  • I included some more information as well as an MWE to my question. Feel free to have a look at it whenever you have the time. :-) – Sam Nov 21 '17 at 18:07
4

An implementation with expl3:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse,xcolor}

\ExplSyntaxOn

% entry list
\NewDocumentEnvironment{entrylist}{m}
 {
  \par\addvspace{\topsep}
  \group_begin:
  \LARGE\bfseries\noindent
  \sam_entries_color_argument:n { #1 }
  \par\nobreak
  \group_end:
  \noindent\ignorespaces
 }
 {
  \par\addvspace{\topsep}
  % increment the counter
  \int_gincr:N \g_sam_entries_color_int
 }

\int_new:N \g_sam_entries_color_int
\tl_new:N \l__sam_entries_title_tl

\cs_new_protected:Nn \sam_entries_color_argument:n
 {
  % lowercase the argument
  \tl_set:Nf \l__sam_entries_title_tl { \tl_lower_case:n { #1 } }
  % replace spaces with a macro for counting right
  \tl_replace_all:Nnn \l__sam_entries_title_tl { ~ } { \c_space_tl }
  \textcolor
   {% pick the color from the sequence, dividing modulo the number of colors
    \seq_item:Nn \g_sam_entries_colors_seq
     {
      \int_mod:nn { \g_sam_entries_color_int } { \__sam_entries_colors: } + 1
     }
   }
   {% just the first three items are colored
    \tl_range:Vnn \l__sam_entries_title_tl { 1 } { 3 }
   }
   % the rest of the argument
   \tl_range:Vnn \l__sam_entries_title_tl { 4 } { \tl_count:V \l__sam_entries_title_tl }
 }
\cs_generate_variant:Nn \tl_range:nnn { V }

% color list
\NewDocumentCommand{\addtocolorlist}{m}
 {
  \clist_map_inline:nn { #1 } { \seq_gput_right:Nn \g_sam_entries_colors_seq { ##1 } }
 }
\seq_new:N \g_sam_entries_colors_seq
\cs_new:Nn \__sam_entries_colors:
 {
  \seq_count:N \g_sam_entries_colors_seq
 }

\ExplSyntaxOff

\addtocolorlist{red,green,blue}
\addtocolorlist{yellow}

\begin{document}

\begin{entrylist}{Test 1}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 2}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Test 3}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{T{é}st 4}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Te}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\begin{entrylist}{Te s}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{entrylist}

\end{document}

Note that accented characters should be braced, because to the eyes of pdflatex they aren't a single token. With XeLaTeX or LuaLatex this is not required.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.