# What I want to do

I want to create a command \planfigur{<edges>}{<angles>} which draws a triangle using TikZ. \planfigur should have 2 mandatory arguments, which let me specify edges and/or angles (where a = alpha, b = beta and c = gamma) of the triangle, which are drawn in red instead of black color.

E. g. \planfigur{ab}{bc} draws a black triangle, where the edges a and b and the angles beta and gamma are red.

I use expl3 and xparse. I already have read (Is it reasonable to expect an expl3-compatible release of TikZ/PGF in the future?), that there are problems in using expl3 and tikz together (which makes sense).

So I played around and tried to outsmart TikZ. I had the following idea, which unfortunately doesn't work (1:0 for TikZ :-)). The approach is to move all expl3 code into a new command, where I can use \tl_if_in:nnT to check the arguments.

# Code

\documentclass{article}

\usepackage{expl3, xparse}

\usepackage{tikz}
\usetikzlibrary{calc}

\ExplSyntaxOn

\tl_new:N \__edu_planfigur_temp

\DeclareDocumentCommand \planfigurLines { m } {

\tl_clear:N \__edu_planfigur_temp

\tl_if_in:nnT {#1} {a} {
\tl_put_right:Nn \__edu_planfigur_temp {\draw (b) -- (c);}
}

\tl_if_in:nnT {#1} {b} {
\tl_put_right:Nn \__edu_planfigur_temp {\draw (a) -- (c);}
}

\tl_if_in:nnT {#1} {c} {
\tl_put_right:Nn \__edu_planfigur_temp {\draw (a) -- (b);}
}

\tl_use:N \__edu_planfigur_temp
}

\DeclareExpandableDocumentCommand \planfigurAngles { m } {
\tl_if_in:nnT {#1} {a} {
\tl_put_right:Nn \__edu_planfigur_temp {\draw ($(a) + (0:1)$) arc (0:40:1) ($(a) + (20:0.7)$) node {$\alpha$};}
}
\tl_if_in:nnT {#1} {b} {
\tl_put_right:Nn \__edu_planfigur_temp {\draw ($(b) + (120:1)$) arc (120:180:1) ($(b) + (150:0.7)$) node {$\beta$};}
}
\tl_if_in:nnT {#1} {c} {
\tl_put_right:Nn \__edu_planfigur_temp {\draw ($(c) + (220:1)$) arc (220:300:1) ($(c) + (260:0.65)$) node {$\gamma$};}
}

\tl_use:N \__edu_planfigur_temp
}

\ExplSyntaxOff

\DeclareExpandableDocumentCommand \planfigur { m m } {
\begin{tikzpicture}[scale=0.65, line join=round, thick]

\coordinate (a) at (0,0);
\coordinate (b) at (5,0);
\coordinate (c) at (3.37, 2.83);

\draw (a) -- node[below] {$c$} (b) -- node[above right] {$a$} (c) -- node[above left] {$b$} (a) -- cycle;

\draw (a) node[left] {$A$};
\draw (b) node[right] {$B$};
\draw (c) node[above] {$C$};

\begin{scope}[color=red, fill=red!25, very thick]
\planfigurLines{#1}
\planfigurAngles{#2}
\end{scope}

\end{tikzpicture}
}

\begin{document}

\planfigur{ac}{a}

\end{document}


# Error

! Package pgf Error: No shape named 0:1 is known.

See the pgf package documentation for explanation. Type H for immediate help. ...
l.70 \planfigur{ac}{a}

-
I strongly suspect that the problem is due to the fact that in expl3 then : has the catcode of a letter but TikZ expects it to be other. One way around this is to define a token list containing a colon with catcode "other" and use that in place of the bare : in your code. –  Loop Space Aug 19 '14 at 20:18
@LoopSpace: Yeah, that makes sense. I forgot the problem with :. This would also explain, why the lines (which don't contain a :) work without any problem. Your approach sounds promising, but I don't know how to do this. :-( –  dawu Aug 19 '14 at 20:23
You can do \tl_const:Nx \c_edu_colon_tl { \token_to_str:N : } and then use \c_edu_colon_tl instead of : in coordinates. \c_edu_colon_tl then contains a : with catcode 12 (other) instead of 11 (letter). –  clemens Aug 19 '14 at 20:24
@cgnieder: Yes, this did it! You are my hero of the day. :-) What to do with the answer? Do you want to answes the question or should I answer it with the full working code? –  dawu Aug 19 '14 at 20:26
@dawu Your \planfigur... commands are not expandable, so they should be declared with \NewDocumentCommand. –  egreg Aug 19 '14 at 20:49

One of the things \ExplSyntaxOn does is giving the colon category code 11 (letter) so it can be used as part of macro names. In coordinates TikZ however expects a colon with category code 12 (other). One solution that works is defining a token list that contains only a : with category code 12

\tl_const:Nx \c_edu_colon_tl { \token_to_str:N : }


and then use said token list \c_edu_colon_tl instead of : in TikZ' coordinates.

BTW: your token list \__edu_planfigur_temp misses the recommended ending for a token list: _tl. It also misses the recommended start \l or \g which denotes if it is local or global. I'd rename it into \l__edu_planfigur_temp_tl.

In expl3 variables generally should start either with \l (local), \g (global) or \c (constant) and end with the type of variable (_tl for a token list, _int for an integer and so on).

-
Thanks for the explanation. I know about the naming conventions of expl3, but this example was very quick and dirty. But you are right, of course! –  dawu Aug 19 '14 at 20:38
@dawu well, the answer is for you but also for others with a similar problem and they might not be aware of the naming convention. So it's better to repeat it. :) I'd also say it's better to follow the convention in MWEs, too: otherwise one might be tempted to get sloppy also in “real” code... :) –  clemens Aug 19 '14 at 20:45
You are right. Should I correct it in my MWE? As you said, it would be better. –  dawu Aug 19 '14 at 20:48
@dawu I don't think it's necessary: since I explained the convention in my answer we should be fine, I think. –  clemens Aug 19 '14 at 20:50

Two more possibilities

\newcommand*\tikzangle[2]{#1:#2}
…
\ExplSyntaxOn
\draw (0,0) -- (\tikzangle{20}{2cm});
\ExplSyntaxOff


and a more practical one

\begingroup
\lccode\X=\:
\lowercase{\endgroup
\gdef\tikzangle(#1X#2){#1:#2}}
\ExplSyntaxOn
\draw (0,0) -- \tikzangle(20:2cm);
\ExplSyntaxOff


To add the more general one, “easier to see” than cgnieder's

\def\othercolon{:}
\ExplSyntaxOn
\draw (0,0) -- (20\othercolon2cm);
\ExplSyntaxOff

-
Also very nice, thank you! It's always interesting to find new ways how to play a trick on the syntax. :o) But I think the first one is a bit "cleaner". –  dawu Aug 21 '14 at 22:06
Nice. This must be adapted for arc (220:300:1) as well but that should not be a problem :) –  clemens Aug 21 '14 at 22:49
@dawu The cool thing about the second one is that you just need to add \tikzangle (or whatever name you choose) before the angle you would write in TikZ (20:2cm). –  Manuel Aug 22 '14 at 2:24
@cgnieder May be defining something like \tikzarc similar to this one. –  Manuel Aug 22 '14 at 2:25
The expl3 version also will always have a : with catcode 12 while \def\othercolon{:} saves : with whatever catcode it has (possibly 13 with \usepackage[french]{babel} for example). The equivalent would rather be \newcommand\othercolon{}\edef\othercolon{\string:} –  clemens Aug 23 '14 at 18:52