1

Can someone tell me why the text is top-aligned, i.e. for instance the dot on the i letter shifts the text downwards, but the o remains sticked to the top, such causing misalignment between the two nodes?

I want the text centered vertically, both letters, i and o being at the same height.

The code is by @JasperHabicht: https://tex.stackexchange.com/a/711612/262813

I tried to adjust the settings and came up with:

[baseline=(a), >=stealth,every node/.style={minimum height=10ex,text depth=10ex,align=center}]`

but without success.


\documentclass[tikz, border=10pt]{standalone}
\usepackage{tikz}
\usepackage{fontspec}
\setmainfont{Times New Roman}
\usetikzlibrary{decorations.pathreplacing, fit}

\ExplSyntaxOn

\cs_generate_variant:Nn \seq_set_split:Nnn { Nee }
\seq_new:N \l_vincentkrebs_coolsource_deriv_parts_seq
\cs_new:Npn \vincentkrebs_coolsource_format #1 {
    \seq_set_split:Nee \l_vincentkrebs_coolsource_deriv_parts_seq { , } { #1 }
    \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 1 } }
    \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 2 } } 
    \textit{\tl_use:N \l_tmpa_tl} \tl_if_empty:NF \l_tmpb_tl {\textup{\textsubscript{\textsc{\tl_use:N \l_tmpb_tl}}}}
}

\seq_new:N \l_vincentkrebs_coolsource_derivs_seq
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist


\NewDocumentCommand{\coolsource}{ o O{} m }{
    \seq_set_split:Nnn \l_vincentkrebs_coolsource_derivs_seq { ; } { #3 }
    \clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
    \begin{tikzpicture}[baseline=(a), >=stealth,every node/.style={minimum height=10ex,text depth=10ex,align=center}]
        \coordinate (a) at (0,0);
        \IfValueT{#1}{
            \node[anchor=south, #2] (A) at (a) { \vincentkrebs_coolsource_format { #1 } };
            \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
        }
        \coordinate (b) at (-1em,-0.6em);
        \coordinate (c) at (1em,-0.6em);
        \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 1 } }
        \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 2 } }
        \node[anchor=east] (B) at (b) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
        \node[anchor=west] (C) at (c) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
        \draw[<->] (b.west) -- (a.south) -- (c.east);
        \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
        
        \int_compare:nNnT { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 2 } {
            \int_compare:nNnTF { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 3 } {
                \coordinate (d) at (0em,-1.2em);
                \coordinate (e) at (0em,-1.2em);
                \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
                \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 4 } }
                \node[anchor=north ~ east] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
                \node[anchor=north ~ west] (E) at (e) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } }; 
                \draw[->] (a.south) -- ([xshift=-0.5em]d.north);
                \draw[->] (a.south) -- ([xshift=0.5em]e.north);
                \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
            } {
                \coordinate (d) at (0em,-1.2em);
                \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
                \node[anchor=north] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };  
                \draw[->] (a.south) -- (d.north);
                \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
            }
        } 
        
        \node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
        \draw[decorate, decoration={brace, mirror}] (frame.north ~ west) -- (frame.south ~ west);
        \draw[decorate, decoration={brace}] (frame.north ~ east) -- (frame.south ~ east);
    \end{tikzpicture}
}

\ExplSyntaxOff

\begin{document}
    \coolsource{ion,n;ory,n;i,n;i,n}
    
    
    \coolsource{ion,n;ory,n;o,n;o,n}
    
    
    \coolsource{ion,n;ory,n;i,n;o,n}
    
    
    \coolsource{ion,n;ory,n;o,n;i,n}
    
    
\end{document}

enter image description here

EDIT

After @cfr's correction, the optional shape around (A) is anchored to low:

\begin{document}
    
    
    \coolsource[source,v][draw]{ion,n;ory,n;i,n;i,n}
    
    
    
\end{document}

enter image description here

EDIT

The solution is just to keep anchor=south in node (A)'s settings.

4
  • 1
    Try anchor=base rather than anchor=south. (Untested.)
    – cfr
    Mar 3 at 3:28
  • 1
    Please don't use custom fonts in examples unless essential. This may compile for you, but it won't compile for me.
    – cfr
    Mar 3 at 3:30
  • 1
    Exactly. You want the text in one node to align with the text in another, you do it by aligning their anchors. If you don't want to change the position of some the nodes then what do you want? If you align nodes using their north anchors, for example, the dot of your i will be aligned with the top of your o. Either you change the anchors you're aligning or, if you really don't want that, you could add \strut to all of them. But that would still look as if you were moving them.
    – cfr
    Mar 3 at 3:53
  • 1
    Sorry I initially misunderstood your advice, I got it now. Mar 3 at 3:54

1 Answer 1

0

I can't compile your example as is, so I removed the custom font setup. To align nodes on the baseline, use base, base west, base east etc. I'm guessing that's what you want but, if you really do want it centred, use center, west and east instead.

nodes aligned to base

\documentclass[tikz, border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing, fit}

\ExplSyntaxOn

\cs_generate_variant:Nn \seq_set_split:Nnn { Nee }
\seq_new:N \l_vincentkrebs_coolsource_deriv_parts_seq
\cs_new:Npn \vincentkrebs_coolsource_format #1 {
    \seq_set_split:Nee \l_vincentkrebs_coolsource_deriv_parts_seq { , } { #1 }
    \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 1 } }
    \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 2 } } 
    \textit{\tl_use:N \l_tmpa_tl} \tl_if_empty:NF \l_tmpb_tl {\textup{\textsubscript{\textsc{\tl_use:N \l_tmpb_tl}}}}
}

\seq_new:N \l_vincentkrebs_coolsource_derivs_seq
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist


\NewDocumentCommand{\coolsource}{ o O{} m }{
  \seq_set_split:Nnn \l_vincentkrebs_coolsource_derivs_seq { ; } { #3 }
  \clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
  \begin{tikzpicture}[baseline=(a), >=stealth]
    \coordinate (a) at (0,0);
    \IfValueT{#1}{
      \node[anchor=south, #2] (A) at (a) { \vincentkrebs_coolsource_format { #1 } };
      \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
    }
    \coordinate (b) at (-1em,-0.6em);
    \coordinate (c) at (1em,-0.6em);
    \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 1 } }
    \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 2 } }
    \node[anchor=base ~ east] (B) at (b) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
    \node[anchor=base ~ west] (C) at (c) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
    \draw[<->] (b.west) -- (a.south) -- (c.east);
    \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
    
    \int_compare:nNnT { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 2 } {
      \int_compare:nNnTF { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 3 } {
        \coordinate (d) at (0em,-1.2em);
        \coordinate (e) at (0em,-1.2em);
        \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
        \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 4 } }
        \node[anchor=north ~ east] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
        \node[anchor=base ~ west] (E) at (e |- D.base) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } }; 
        \draw[->] (a.south) -- ([xshift=-0.5em]d.north);
        \draw[->] (a.south) -- ([xshift=0.5em]e.north);
        \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
      } {
        \coordinate (d) at (0em,-1.2em);
        \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
        \node[anchor=north] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };  
        \draw[->] (a.south) -- (d.north);
        \clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
      }
    } 
    
    \node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
    \draw[decorate, decoration={brace, mirror}] (frame.north ~ west) -- (frame.south ~ west);
    \draw[decorate, decoration={brace}] (frame.north ~ east) -- (frame.south ~ east);
  \end{tikzpicture}
}

\ExplSyntaxOff

\begin{document}
    \coolsource{ion,n;ory,n;i,n;i,n}
    
    
    \coolsource{ion,n;ory,n;o,n;o,n}
    
    
    \coolsource{ion,n;ory,n;i,n;o,n}
    
    
    \coolsource{ion,n;ory,n;o,n;i,n}
    
    
\end{document}

It's not clear to me that the use of expl3 does a lot for you here. Just be aware that this syntax is not necessarily compatible with pgf/tikz syntax, so it is entirely possible you may run into conflicts. That said, I mix them also - just you need to be a bit wary of the potential pitfalls.

10
  • Yes we ran into problems with line breaks, you're right. Mar 3 at 3:49
  • 1
    @VincentKrebs Note that your every node isn't being applied either because what you've done is define a new style everynode which you never use. You need every ~ node in this context. Similarly, minimum ~ height, text ~ depth and so on.
    – cfr
    Mar 3 at 3:54
  • The font does not matter at all, results are the same here. But I got what you meant, I usually do not include the font but here I did. Mar 3 at 3:55
  • 1
    @VincentKrebs Yes, because I wanted it aligned with D's base only vertically and not horizontally. Otherwise you are just putting the second node on top of the first!
    – cfr
    Mar 3 at 4:06
  • 1
    @VincentKrebs That's because you're aligning B and C on y=0.6em, so it is enough to make sure the base anchor is used. But you don't know what y should be for D and E. Rather, you're aligning the first one by hanging it from north. Then you want to align the second to whatever-y-corresponds-to-y-at-base-of-D.
    – cfr
    Mar 3 at 6:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .