My TikZ drawing package has a command that will draw a "simple beam", which is basically a rectangle between two arbitrary points. The code below is the relevant part from the package:
% arara: lualatex
\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{calc}
% Sets various configuration parameters
% \strandlibset[module]{options as pgfkeys}
\NewDocumentCommand{\strandlibset}{o m}{
\IfNoValueTF{#1}{
\pgfqkeys{/strandlib}{#2}
}
{
\pgfqkeys{/strandlib/#1}{#2}
}
}
\makeatletter
\newif\if@beam@start@round
\newif\if@beam@start@butt
\newif\if@beam@start@rect
\newif\if@beam@end@round
\newif\if@beam@end@butt
\newif\if@beam@end@rect
\pgfkeys{
/strandlib/beam/.is family,
/strandlib/beam,
thickness/.initial=1mm,
color/.initial=blue,
@style/.style={/tikz, draw=#1, fill=#1!50!white, thick},
start/.is choice,
start/butt/.is if=@beam@start@butt,
start/rect/.is if=@beam@start@rect,
start/round/.is if=@beam@start@round,
start/butt=false,
start/rect=true,
start/round=false,
start=rect,
end/.is choice,
end/butt/.is if=@beam@end@butt,
end/rect/.is if=@beam@end@rect,
end/round/.is if=@beam@end@round,
end/butt=false,
end/rect=true,
end/round=false,
end=rect,
}
% \simplebeam[*both rounded]{start}{end}[additional options]
\NewDocumentCommand{\simplebeam}{s m m o}{%
\begingroup
\IfValueT{#4}{
\strandlibset[beam]{#4}
}
\IfBooleanT{#1}{
\strandlibset[beam]{start=round, end=round}
}
\if@beam@start@butt
\coordinate (beamCentreA) at (#2);
\else
\coordinate (beamCentreA) at ($(#2)!\pgfkeysvalueof{/strandlib/beam/thickness}!180:(#3)$);
\fi
\if@beam@end@butt
\coordinate (beamCentreB) at (#3);
\else
\coordinate (beamCentreB) at ($ (#3)!\pgfkeysvalueof{/strandlib/beam/thickness}!180:(#2)$);
\fi
\coordinate (beamCornerA1) at ($ (beamCentreA)!\pgfkeysvalueof{/strandlib/beam/thickness}!90:(beamCentreB)$);
\coordinate (beamCornerA2) at ($ (beamCentreA)!\pgfkeysvalueof{/strandlib/beam/thickness}!-90:(beamCentreB)$);
\coordinate (beamCornerB1) at ($ (beamCentreB)!\pgfkeysvalueof{/strandlib/beam/thickness}!-90:(beamCentreA)$);
\coordinate (beamCornerB2) at ($ (beamCentreB)!\pgfkeysvalueof{/strandlib/beam/thickness}!90:(beamCentreA)$);
\if@beam@start@round
\if@beam@end@round
\filldraw[/strandlib/beam/@style=\pgfkeysvalueof{/strandlib/beam/color}, rounded corners=\pgfkeysvalueof{/strandlib/beam/thickness}] (beamCornerA1) -- (beamCornerA2) -- (beamCornerB2) -- (beamCornerB1) -- cycle;
\else
\filldraw[/strandlib/beam/@style=\pgfkeysvalueof{/strandlib/beam/color}, rounded corners=\pgfkeysvalueof{/strandlib/beam/thickness}] (beamCornerA1) -- (beamCornerA2) [sharp corners] -- (beamCornerB2) -- (beamCornerB1) [rounded corners=\pgfkeysvalueof{/strandlib/beam/thickness}] -- cycle;
\fi
\else
\if@beam@end@round
\filldraw[/strandlib/beam/@style=\pgfkeysvalueof{/strandlib/beam/color}] (beamCornerA1) -- (beamCornerA2) [rounded corners=\pgfkeysvalueof{/strandlib/beam/thickness}] -- (beamCornerB2) -- (beamCornerB1) [sharp corners] -- cycle;
\else
\filldraw[/strandlib/beam/@style=\pgfkeysvalueof{/strandlib/beam/color}] (beamCornerA1) -- (beamCornerA2) -- (beamCornerB2) -- (beamCornerB1) -- cycle;
\fi
\fi
\endgroup
}
\makeatother
\begin{document}
Variety of options: some round, some not.
\begin{center}
\begin{tikzpicture}
\strandlibset[beam]{color=red}
\simplebeam{0, 0}{4, 0}
\simplebeam{0, 2}{5, 2}[thickness=2mm, start=round, end=round]
\simplebeam{0, 3}{3, 6}[start=butt, end=round]
\end{tikzpicture}
\end{center}
All round!
\begin{center}
\begin{tikzpicture}
\strandlibset[beam]{color=black!50!white, start=round, end=round}
\simplebeam{0, 0}{4, 0}
\simplebeam{0, 2}{5, 2}[thickness=2mm, start=rect, end=rect]
\simplebeam{0, 5}{2, 3}[start=butt, end=round, thickness=1.5mm]
\end{tikzpicture}
\end{center}
\end{document}
My problem is that if I globally set the beam ends to round (e.g. using \strandlibset[beam]{start=round, end=round}
), then I can't change that for a single instance of a beam (e.g. \simplebeam{A}{B}[end=butt]
), because the @beam@start@round
is true
. Essentially what I need is for the start/.is choice
and end/.is choice
keys to turn off the other booleans: start=butt
should imply that @start@round = false
and @start@rect = false
. What's actually happening is that start=butt
simply sets @start@butt = true
but doesn't change the other two boolean flags.
How can I fix this?
Some alternate method that achieves the same result would also be accepted, as the nested if-statements are somewhat awkward.
/.is choice
key that can take the valuesbutt
,rect
andround
, which determine the line cap on both sides.round
at the start butrect
at the end. The reason I'm posting this question is precisely because of this: I've got a drawing where all the beams except two are round, and those two have abutt
cap at one end.\if@beam@start@butt
, add a\boolfalse{@beam@start@round}
after defining the beam center A coordinate, and likewise for the\if@beam@end@butt
. I'm able to sidestep the PDF specifications because while the beams look like lines, they're actually implemented as (rotated) rectangles.