6

I'm getting better at creating \newcommand instances but I've just reached a part where my knowledge is just not enough for it and also reading this site or the manual doesn't help.

Basically I'd like to create a newcommand that sets a vertical rectangle split in 3 parts, so far so good, but where I can control whether each part gets filled with a boolean. The command would look like (as I've envisioned it but I'm not sure it's feasible):

\command{1, 0, 1}; Here the first and third part would be filled with a color (black or whatever), the second would stay white. Alternatively, it could be \command{1}{0}{1}; for the same result. This would use three arguments but I don't know how to separate arguments with the comma as shown above.

The result would be something like this:

enter image description here

Note that I'd like this to be dynamic, i.e. if I say 0,1,1, the filled parts would be the second and third, and so on. I didn't manage to reach any level so I don't have a code to provide but here is a starting example so you don't need to rewrite all the code (ignore the settings the seem to be unnecessary here, they're used in other parts of the document):

\documentclass[10pt]{article}
\usepackage[a4paper, margin=3mm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage{rotating}
\usepackage{amsmath}
\usepackage{pgfplots}
\usepackage{tikz}

\usetikzlibrary{fit, arrows,backgrounds,patterns,shapes,shapes.multipart,positioning,calc,decorations.markings}

\begin{document}

    \begin{tikzpicture}
            \centering


    \end{tikzpicture}

\end{document}
Alenanno
  • 37,338
  • 2
    Can you add at least the code for getting three filled rectangles? – egreg Apr 14 '13 at 11:12
  • @egreg Sorry, I've seen your comment now, what do you mean by that? Do you mean like \node[rectangle, fill=black] at (0,0) {};? – Alenanno Apr 14 '13 at 13:01
  • @Alenanno: I answered your question with a simple TikZ-Code? At the moment we don't know your intention and so we can't provide a good tikz-part. – Marco Daniel Apr 14 '13 at 13:33
  • @MarcoDaniel I've seen it thanks, I'm playing with it at the moment. I don't get your comment though. My intention is exactly what I've explained and I think you've answered fine! Now that we're here, why can't I apply minimum width/height or inner sep to the rectangles in your code? It complains when I try to typeset. – Alenanno Apr 14 '13 at 13:49
  • @Alenanno: Options like inner sep or width etc. haven't been required. Maybe you can update your question and as egreg mentioned please show us your tikz-code. – Marco Daniel Apr 14 '13 at 14:03
  • @MarcoDaniel I didn't request them because I know those options, I was just wondering why they didn't work as usual in your code, I can tweak around though. But as I have said in my question, there is no code. I was starting to try to do it by myself but I realized I didn't know enough about this and your answer proves me right: I didn't even know about the existence of xparse and l3prop. The rest of my Tikz code is totally unrelated to this part so I don't see the benefit of including it. – Alenanno Apr 14 '13 at 14:19
  • @Alenanno: I edited my answer. – Marco Daniel Apr 14 '13 at 14:34

3 Answers3

6

Here a way using xparse and l3prop. The usage of l3prop allows more modifications.

Maybe the tikz-part can be improved ;-)

\documentclass[10pt]{article}
\usepackage{tikz}
\usepackage{xparse,expl3}

\ExplSyntaxOn
\prop_new:N \l_alenanno_color_prop
\prop_put:Nnn \l_alenanno_color_prop {0} {white}
\prop_put:Nnn \l_alenanno_color_prop {1} {black}

\NewDocumentCommand {\command} { > { \SplitArgument { 2 } { , } } m }
 {
  \alenanno_command_aux:nnn #1 
 }

\cs_new:Npn \alenanno_command_aux:nnn #1 #2 #3
 {
  \begin{tikzpicture}
   \draw[fill=\prop_get:Nn \l_alenanno_color_prop { #1 }] (0,0) rectangle (1,1);
   \draw[fill=\prop_get:Nn \l_alenanno_color_prop { #2 }] (0,1) rectangle (1,2);
   \draw[fill=\prop_get:Nn \l_alenanno_color_prop { #3 }] (0,2) rectangle (1,3);
  \end{tikzpicture}
 }

\ExplSyntaxOff


\begin{document}
\command{1,0,1} \command{0,0,1} \command{0,1,1}
\end{document}

enter image description here


Here a solution using \node:

\documentclass[10pt]{article}
\usepackage{tikz}
\tikzset{mynodestyle/.style={minimum height=1cm,minimum width=1cm,outer sep=0pt,rectangle,draw=black}}
\usepackage{xparse,expl3}

\ExplSyntaxOn
\prop_new:N \l_alenanno_color_prop
\prop_put:Nnn \l_alenanno_color_prop {0} {white}
\prop_put:Nnn \l_alenanno_color_prop {1} {black}

\NewDocumentCommand {\command} { > { \SplitArgument { 2 } { , } } m }
 {
  \alenanno_command_aux:nnn #1 
 }

\cs_new:Npn \alenanno_command_aux:nnn #1 #2 #3
 {
  \begin{tikzpicture}
   \node[mynodestyle, fill=\prop_get:Nn \l_alenanno_color_prop { #2 }] (P) {};
   \node[mynodestyle, fill=\prop_get:Nn \l_alenanno_color_prop { #1 },anchor=south] at (P.north) {};
   \node[mynodestyle, fill=\prop_get:Nn \l_alenanno_color_prop { #3 },anchor=north] at (P.south) {};
  \end{tikzpicture}
 }
\ExplSyntaxOff


\begin{document}
\command{1,0,1} \command{0,0,1} \command{0,1,1} \command{0,0,0}
\end{document}

It's important to know that inside \ExplSyntaxOn ... \ExplSyntaxOff all spaces are ignored. This is explained here: What do ExplSyntaxOn and ExplSyntaxOff do?. So you can't use TikZ options like minimum with You can temporally disable this behaviour as described her: Text within ExplSyntaxOn/Off or do the setting outside.

As mentioned by egreg: If you want to use some TikZ options which require a space you can use the symbol ~. That means:

\draw[fill=\prop_get:Nn \l_alenanno_color_prop { #3 },rounded~corners] (0,2) rectangle (1,3);
Marco Daniel
  • 95,681
  • 1
    You can use ~ in the special environment when a space is required by the syntax rules of TikZ. – egreg Apr 14 '13 at 15:06
  • @egreg: really? I thought this symbol would be passed as a token and so you get an unknown option. I will try it. – Marco Daniel Apr 14 '13 at 15:07
  • @MarcoDaniel Thanks, the second solution you provided worked very nicely. :) I'll be accepting yours, thanks again! – Alenanno Apr 14 '13 at 15:16
5

I'd have needed more help in the MWE to make that with Tikz, but here's the testing part:-)

enter image description here

\documentclass[10pt]{article}


\def\command#1{\xcommand#1\relax}
\def\xcommand#1,#2,#3\relax{%
\begin{tabular}{|l|}
\relax\ifnum#1>0 \leaders\vline\fi\hskip 1em\mbox{}\\
\relax\ifnum#2>0 \leaders\vrule\fi\hskip 1em\mbox{}\\
\relax\ifnum#3>0 \leaders\vrule\fi\hskip 1em\mbox{}%
\end{tabular}}

\begin{document}

\command{1,0,1}

\bigskip

\command{0,1,0}


\end{document}
David Carlisle
  • 757,742
4

Why waste electrons and use a comma list? 010 conveys the same information. Here is a short solution. If you insist on commas, change @tfor to @for. Solution is extensible, use as many 0s or 1s you wish.

\documentclass{article}
\usepackage{xcolor}
\fboxsep0pt
\makeatletter
\def\roll#1{%
\def\boxblack{\rule{1cm}{1cm}}%
\def\boxwhite{{\color{white}\rule{1cm}{1cm}}}%
\fbox{\parbox{1cm}{%
\@tfor\next:=#1\do{%
   \ifnum\next=0\boxblack\else\boxwhite\fi%
\par
}}}}
\makeatother
\begin{document}
\roll{01010}
\end{document}

enter image description here

Posted a solution to illustrate that it is always best to generalize the problem. It is also best IMHO to avoid heavyweight libraries when simpler solutions exist.

yannisl
  • 117,160