TeX - LaTeX Asked on July 22, 2021
MWE:
documentclass[border = 10pt]{standalone}
usepackage{ifthen}
usepackage{tikz}
usetikzlibrary{calc}
begin{document}
begin{tikzpicture}[every node/.style = {align = center}]
newcounter {lfpnode}
coordinate (LFP) at (0,0);
newcommand {drawaline} [3] {
ifthenelse{equal{#2}{}}
{deftdsdabovespec{}}
{deftdsdabovespec{node[above] unexpanded{{#2}}}}
coordinate (LFPS) at ($(LFP) - (0,{#1})$);
ifthenelse{equal{#3}{}} {
deftdsdnewLFP{LFPS}
deftdsdbelowspec{}
}{
edeftdsdlfpnode{LFPNarabic{lfpnode}}
deftdsdnewLFP{0,0 |- tdsdlfpnode.south}
deftdsdbelowspec{node[below] (tdsdlfpnode) unexpanded{{#3}}}
}
% this doesn't work
deftdsddataflowspec{[blue] (0,0 |- LFPS) -> tdsdabovespec tdsdbelowspec (5,0 |- LFPS)}
expandafterdrawtdsddataflowspec;
% neither does this, although I didn't expect it to
draw [blue] (0,0 |- LFPS) -> tdsdabovespec tdsdbelowspec (5,0 |- LFPS);
coordinate (LFP) at (tdsdnewLFP);
stepcounter{lfpnode}
}
newcommand {drawalineone} [1] {
deftdsdnewLFP{LFPS}
coordinate (LFPS) at ($(LFP) - (0,{#1})$);
draw [blue] (0,0 |- LFPS) -> node[above] {ABOVE1-1ABOVE1-2} (5,0 |- LFPS);
coordinate (LFP) at (tdsdnewLFP);
stepcounter{lfpnode}
}
newcommand {drawalinetwo} [1] {
coordinate (LFPS) at ($(LFP) - (0,{#1})$);
edeftdsdlfpnode{LFPNarabic{lfpnode}}
deftdsdnewLFP{0,0 |- tdsdlfpnode.south}
draw [blue] (0,0 |- LFPS) -> node[above] {ABOVE2-1} node[below]
(tdsdlfpnode) {BELOW2-1} (5,0 |- LFPS);
coordinate (LFP) at (tdsdnewLFP);
stepcounter{lfpnode}
}
newcommand {drawalinethree} [1] {
coordinate (LFPS) at ($(LFP) - (0,{#1})$);
edeftdsdlfpnode{LFPNarabic{lfpnode}}
deftdsdnewLFP{0,0 |- tdsdlfpnode.south}
draw [blue] (0,0 |- LFPS) -> node[below] (tdsdlfpnode) {BELOW3-1BELOW3-2} (5,0 |- LFPS);
coordinate (LFP) at (tdsdnewLFP);
stepcounter{lfpnode}
}
% The following causes errors aplenty:
% "Cannot parse this coordinate."
% "A node must have a (possibly empty) label text."
% "Giving up on this path. Did you forget a semicolon?"
% drawaline{0} {ABOVE1-1ABOVE1-2} {}
% drawaline{1.3cm} {ABOVE2-1} {BELOW2-1}
% drawaline{1cm} {} {BELOW3-1BELOW3-2}
% Works!
drawalineone{0}
drawalinetwo{1.3cm}
drawalinethree{1cm}
end{tikzpicture}
end{document}
The general idea is simple: drawaline
draws a line and accepts three arguments. If the second argument is nonempty, a label appears above the line. If the third argument is nonempty, a label appears below the line.
The vertical spacing of the lines is such that a space defined by the first argument appears between the line currently being rendered and the lowest point (including label, if present) of the previously-rendered line. This isn’t crucial for the MWE, but I’ve included it since it’s how the code is used in the original context, and it might conceivably affect which fixes are possible.
The drawalineone
, drawalinetwo
, and drawalinethree
macros are hard-coded versions of drawaline
. They function as expected. The actual drawaline
macro does not. Note that neither of the approaches used in drawaline
works when unexpanded{{#2}}
(and likewise for #3
) are replaced by simply {#2}
, or by begingroup #2endgroup
. In short, I don’t know how to get TikZ to recognize the content following draw
as a parseable TikZ path spec.
Finally, please note that the drawaline
macro must accept multi-line labels.
Any help would be appreciated.
I am not sure to understand your objective --- but if I understood correctly your description, I tried to simplify it.
documentclass[border=10pt]{standalone}
usepackage{tikz}
usepackage{ifthen}
newcommanddrawline[3]{
% the position of the line is #1 below the previous line
% it is not accounting for the (not typeset yet) above box
path (lastline) ++(0,{-(#1)}) coordinate(thisline);
% draw the line and mark midway
draw (thisline) -- ++(5,0) coordinate[pos=0.5](midline);
% if we have the box above, draw it
ifthenelse{equal{#2}{}}{}{node[above, align=center] at (midline) {#2};}
% if we have the box below, type it. Either case, re-set
% the (lastline) position accordingly
ifthenelse{equal{#3}{}}
{coordinate(lastline) at (thisline);}
{node[below, align=center](tmp) at (midline) {#3};
coordinate(lastline) at (thisline|-tmp.south);}
}
begin{document}
begin{tikzpicture}[]
coordinate (lastline) at (0,0);
drawline{0}{Only above}{}
drawline{2}{Either above}{Or below}
drawline{1}{}{Only below}
end{tikzpicture}
end{document}
Taking into account the size of the text block above, in order to specify the distance between the texts instead of the lines, will be a bit more complex, but not impossible...
Correct answer by Rmano on July 22, 2021
Maybe not the complete solution, but perhaps a direction to go. I tried to use one of your code examples and enhanced it a bit:
newcommand {drawalinetwo} [3] {
coordinate (LFPS) at ($(LFP) - (0,{#1})$);
edeftdsdlfpnode{LFPNarabic{lfpnode}}
deftdsdnewLFP{0,0 |- tdsdlfpnode.south}
draw [blue] (0,0 |- LFPS) -- node[above] {#2} node[below]
(tdsdlfpnode) {#3} (5,0 |- LFPS);
coordinate (LFP) at (tdsdnewLFP);
stepcounter{lfpnode}
}
With the commands
drawalinetwo{1cm}{}{BELOW2-1}
drawalinetwo{1cm}{ABOVE2-1}{}
drawalinetwo{1cm}{ABOVE2-1}{BELOW2-1}
I get this:
Answered by Harald Lichtenstein on July 22, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP