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}
  • 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
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);
  • 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}
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.

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.