2

For my actual project I am breaking down my Lua/LaTeX/TikZ problems into several smaller ones. So here is one of the many.

First, I'm trying to write a macro for the color of a node. Argument for the command is a variable from the foreach loop. This should make the colors consistent over several figures (so it will be in a separate style/class later).

\documentclass[border=2mm]{standalone}
\usepackage{tikz,fontspec}

% https://tug.org/FontCatalogue/typewriterfonts.html
\setmonofont{Noto Sans Mono} % how to use this font inside selected tikzpicture only?

\usetikzlibrary{chains, scopes, patterns,
                decorations.pathreplacing}

\begin{document}

\newcommand{\RegColor}[1]{%
    \pgfmathparse{%
        ifthenelse(#1 < 7, "blue!10",                 % lower
            ifthenelse(#1 < 12, "blue!20",            % upper
                ifthenelse(#1 == 13, "yellow!30",     % 1st special case
                    ifthenelse(#1 == 14, "green!10",  % 2nd special case
                        "green!20"                    % 3rd special case
                    )%
                )%
            )%
        )%
    }\pgfmathresult%
}

\newcommand{\texthex}[1]{\texttt{#1}}

\begin{tikzpicture}[
    %font=\sffamily,
    node distance = 0mm and 20mm,
    start chain = R going below,
    N/.style = {draw, fill=#1,                                      % style for drawing nodes
                minimum height=5mm,
                outer sep=0pt, text opacity=1, align=center},
    N/.default = red!70,
  ]
  \begin{scope}[nodes=on chain=R]
    \tikzset{
        minimum width={width("0xAA BB CC DD")+2pt}
    }
    \foreach\r in {0, 1,...,15}{
        \ifnum\r<7
            \node[on chain=R, N=\RegColor{\r}] {\texthex{0xAA BB CC DD}};
        \else
            \ifnum\r=9 % extra care for readers
                \node[on chain=R, N=\RegColor{\r}, text=blue] {\texthex{0xAA FF FF EE}};
            \else
                \node[on chain=R, N=\RegColor{\r}] {\texthex{0x00 11 22 33}};
            \fi
        \fi
    }
  \end{scope}
  \node[above] at (R-1.north west) {MSB};
  \node[above] at (R-1.north east) {LSB};
\end{tikzpicture}

\end{document}

Unfortunately (Lua)LaTex does not accept this, gives errors:

$ lualatex test_RegColor.tex
! Undefined control sequence.
\pgfmath@catcodes ...`\|=12 \catcode `\&=12 \let "
                                                  \pgfmath@char@quote 
l.51     }
        

Edit: In the meantime I fixed the wrong \newcommand[\texthex][1]{\texttt{#1}} to \newcommand{\texthex}[1]{\texttt{#1}}- I simply overlooked it, thanks cfr.

Secondly, I want to write the text of the nodes in sans-serif 'Noto Sans Mono' (the whole document will later be sans-serif) - these are hex numbers, which are usually written in typewriter. I have written a command for this, is this also possible directly via \tikzset, inside a scope separately? \setmonofont sets this for the complete document, if I have understood it correctly, which I do not (yet) want.

3
  • It does not accept this how? Do you get an error? Please try to stick to the one question-per question format, even if it means linking related questions for context. \setmonofont is what you want. It will only change the monowidth font for the document. It won't change the serif or sans families. So unless you want some other monowidth font for the rest of the document, just set it in the preamble. \setmainfont will setup the main font for the document. \setsansfont will set the sans.
    – cfr
    Commented May 20 at 15:11
  • I can't see the width issue you mention. If you only saw it by forcing compilation after an error, it doesn't count. Output following an error is not reliable and can be used only for debugging. Do you see the same issue if you compile my code?
    – cfr
    Commented May 20 at 16:09
  • Thanks for editing!
    – cfr
    Commented May 20 at 16:16

1 Answer 1

4

I think the problem is that the command \RegColor is defined under one cat code regime, but used under another. I am probably wrong about this.

There are various ways you might address this. One would be to change the cat codes before and after you define the command. However, there are more straightforward options. One is to use pgfkeys to set a suitable .code key and to use that instead of \RegColor. Another would be to use an indexed sequence of colours (e.g. with expl3 or another implementation). But the simplest, given this is in the context of a tikzpicture, is probably the pgfkeys.

There remain several options, even within pgfkeys, including alternatives to using a .code key and different ways of setting this up. Here's an example,

\documentclass[border=2mm]{standalone}
\usepackage{tikz,fontspec}

% ateb: https://tex.stackexchange.com/a/718376/  addaswyd o gwestiwn olStckEx: https://tex.stackexchange.com/q/718371/

% https://tug.org/FontCatalogue/typewriterfonts.html
\setmonofont{Noto Sans Mono} % will only change typewriter/monowidth
% \setsansfont{}
% \setmainfont{}

\usetikzlibrary{chains, scopes, patterns,
  decorations.pathreplacing}
\colorlet{regcolor}{black}
\tikzset{%
  reg color/.code={%
    \pgfmathparse{%
      ifthenelse(#1<7,"blue!10",%                 % lower
      ifthenelse(#1<12,"blue!20",%            % upper
      ifthenelse(#1==13,"yellow!30",%     % 1st special case
      ifthenelse(#1==14,"green!10",%  % 2nd special case
      "green!20"%                    % 3rd special case
      )%
      )%
      )%
      )%
    }\colorlet{regcolor}{\pgfmathresult}%
  },
}  

\newcommand\texthex[1]{\texttt{#1}}
\begin{document}        

\begin{tikzpicture}[
    %font=\sffamily,
    node distance=0mm and 20mm,
    start chain=R going below,
    N/.style={draw, reg color=#1, fill=regcolor,                                     % style for drawing nodes
      minimum height=5mm,
      outer sep=0pt, text opacity=1, align=center,
    },
    N/.default = red!70,
  ]
  \begin{scope}[nodes=on chain=R]
    \tikzset{
        minimum width={width("0xAA BB CC DD")+2pt}
    }
    \foreach\r in {0,1,...,15}{
        \ifnum\r<7
          \node[on chain=R, N=\r] {\texthex{0xAA BB CC DD}};
        \else
          \ifnum\r=9 % extra care for readers
            \node[on chain=R, N={\r}, text=blue] {\texthex{0xAA FF FF EE}};
          \else
            \node[on chain=R, N={\r}] {\texthex{0x00 11 22 33}};
          \fi
        \fi
    };
  \end{scope}
  \node[above] at (R-1.north west) {MSB};
  \node[above] at (R-1.north east) {LSB};
\end{tikzpicture}

\end{document}

Another option would be to define a custom handler to facilitate colour setting or to feed the colour into fill directly without using an intermediate colour name.

I'm afraid my images are not great right now, but it does work:

proof of concept in colour setting

5
  • Thanks, your source is a good basis for my project and invites me to do more :)
    – olStckEx
    Commented May 20 at 17:39
  • I am now trying to integrate your solution into my specific use case. Here is my current status: cocalc.com/share/public_paths/… .
    – olStckEx
    Commented May 21 at 17:33
  • I have several scopes in which the nodes should have different colors. Accordingly, I have placed the reg color local in the scopes. However, the whole thing does not work like this. I get error Package PGF Math Error: Unknown operator =' or =7' (in 'ifthenelse(<=7,.... How can I fix this error? Also, having to write register color=13, fill=RegColor every time is inconvenient. I have not yet fully grasped the concept of macros, and in line 96 Node simply does not turn red as intended.
    – olStckEx
    Commented May 21 at 17:33
  • @olStckEx But you're only doing it in a definition and then looping over it. If you want a particular colour, just say fill=<colour>. The only reason to do it this way is because you want to cycle through and select the colour programmatically. It's not an interface designed for application to particular nodes where you know the colour you want?
    – cfr
    Commented May 21 at 19:39
  • @olStckEx <= isn't a recognised operator: ifthen doesn't support it. You'd get the same error with your original use of ifthenelse. Use <8 instead.
    – cfr
    Commented May 21 at 19:42

You must log in to answer this question.

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