
Что я хочу сделать
Я хочу создать команду \planfigur{<edges>}{<angles>}
, которая рисует треугольник с помощью TikZ
. \planfigur
Она должна иметь 2 обязательных аргумента, которые позволяют мне указывать ребра и/или углы (где a = альфа, b = бета и c = гамма) треугольника, которые рисуются красным, а не черным цветом.
Например, \planfigur{ab}{bc}
рисует черный треугольник, где стороны a и b, а также углы бета и гамма красные.
Я использую expl3
и xparse
. Я уже прочитал (Разумно ли ожидать в будущем релиза TikZ/PGF, совместимого с expl3?), что существуют проблемы при совместном использовании expl3
и tikz
(что имеет смысл).
Поэтому я поигрался и попытался перехитрить TikZ
. У меня возникла следующая идея, которая, к сожалению, не работает (1:0 за TikZ
:-)). Подход заключается в том, чтобы переместить весь expl3
код в новую команду, где я могу использовать \tl_if_in:nnT
для проверки аргументов.
Код
\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}
Ошибка
! Ошибка пакета pgf: неизвестна форма с именем 0:1.
См. документацию пакета pgf для получения объяснений. Введите H для немедленной помощи. ...
l.70 \planfigur{ac}{a}
решение1
Одна из вещей, \ExplSyntaxOn
которые делает, это присваивает двоеточию код категории 11 (буква), чтобы его можно было использовать как часть имен макросов. Однако в координатах TikZ ожидает двоеточие с кодом категории 12 (другое).
Самый простой способ: можно использовать предопределенные \c_colon_str
вместо :
координат TikZ.
Первоначальное решение \c_colon_str
было доступно ранее:
Одним из работающих решений является определение списка токенов, содержащего только токен :
с кодом категории 12.
\tl_const:Nx \c_edu_colon_tl { \token_to_str:N : }
а затем использовать указанный список токенов \c_edu_colon_tl
вместо :
координат TikZ.
Кстати: в вашем списке токенов \__edu_planfigur_temp
отсутствует рекомендуемое окончание для списка токенов: _tl
. Также отсутствует рекомендуемое начало \l
или \g
, которое обозначает, является ли он локальным или глобальным. Я бы переименовал его в \l__edu_planfigur_temp_tl
.
В expl3 переменные обычно должны начинаться с \l
(локальный), \g
(глобальный) или \c
(константа) и заканчиваться типом переменной ( _tl
для списка токенов, _int
для целого числа и т. д.).
решение2
Еще две возможности
\newcommand*\tikzangle[2]{#1:#2}
…
\ExplSyntaxOn
\draw (0,0) -- (\tikzangle{20}{2cm});
\ExplSyntaxOff
и более практичный
\begingroup
\lccode`\X=`\:
\lowercase{\endgroup
\gdef\tikzangle(#1X#2){#1:#2}}
\ExplSyntaxOn
\draw (0,0) -- \tikzangle(20:2cm);
\ExplSyntaxOff
Чтобы добавить более общее, «легче увидеть», чем у cgnieder
\def\othercolon{:}
\ExplSyntaxOn
\draw (0,0) -- (20\othercolon2cm);
\ExplSyntaxOff