
Lo que quiero hacer
Quiero crear un comando \planfigur{<edges>}{<angles>}
que dibuje un triángulo usando TikZ
. \planfigur
debería tener 2 argumentos obligatorios, que me permiten especificar los bordes y/o ángulos (donde a = alfa, b = beta y c = gamma) del triángulo, que están dibujados en rojo en lugar de negro.
P.ej. \planfigur{ab}{bc}
Dibuja un triángulo negro, donde los bordes a y b y los ángulos beta y gamma son rojos.
Yo uso expl3
y xparse
. Ya he leído (¿Es razonable esperar una versión de TikZ/PGF compatible con expl3 en el futuro?), que existen problemas al usar expl3
y tikz
juntos (lo cual tiene sentido).
Así que jugué y traté de ser más astuto TikZ
. Tuve la siguiente idea, que lamentablemente no funciona (1:0 para TikZ
:-)). El enfoque es mover todo expl3
el código a un nuevo comando, donde puedo usarlo \tl_if_in:nnT
para verificar los argumentos.
Código
\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
! Error de pgf del paquete: no se conoce ninguna forma denominada 0:1.
Consulte la documentación del paquete pgf para obtener una explicación. Escriba H para obtener ayuda inmediata. ...
l.70 \planfigurar{ac}{a}
Respuesta1
Una de las cosas \ExplSyntaxOn
que hace es darle al código de categoría de dos puntos 11 (letra) para que pueda usarse como parte de los nombres de macro. Sin embargo, en las coordenadas TikZ espera dos puntos con el código de categoría 12 (otro).
La forma más sencilla: puedes utilizar las coordenadas predefinidas \c_colon_str
en lugar de :
las de TikZ.
La solución original antes \c_colon_str
estaba disponible:
Una solución que funciona es definir una lista de tokens que contenga solo un :
código de categoría 12.
\tl_const:Nx \c_edu_colon_tl { \token_to_str:N : }
y luego use dicha lista de tokens \c_edu_colon_tl
en lugar de :
en las coordenadas de TikZ.
Por cierto: a su lista de tokens \__edu_planfigur_temp
le falta el final recomendado para una lista de tokens: _tl
. También omite el inicio recomendado \l
o \g
que indica si es local o global. Le cambiaría el nombre a \l__edu_planfigur_temp_tl
.
En expl3, las variables generalmente deben comenzar con \l
(local), \g
(global) o \c
(constante) y terminar con el tipo de variable ( _tl
para una lista de tokens, _int
para un número entero, etc.).
Respuesta2
Dos posibilidades más
\newcommand*\tikzangle[2]{#1:#2}
…
\ExplSyntaxOn
\draw (0,0) -- (\tikzangle{20}{2cm});
\ExplSyntaxOff
y uno mas practico
\begingroup
\lccode`\X=`\:
\lowercase{\endgroup
\gdef\tikzangle(#1X#2){#1:#2}}
\ExplSyntaxOn
\draw (0,0) -- \tikzangle(20:2cm);
\ExplSyntaxOff
Para añadir el más general, “más fácil de ver” que el de cgnieder
\def\othercolon{:}
\ExplSyntaxOn
\draw (0,0) -- (20\othercolon2cm);
\ExplSyntaxOff