如果“i”出现在对列表中,则将样式应用于第“i”个节点

如果“i”出现在对列表中,则将样式应用于第“i”个节点

我编写了一个命令来使用 TikZ 制作以下图像:

在此处输入图片描述

调用创建该图像的命令如下:

    \drawmatching{%
        G,A,T,T,A,C,A}{%
        G,C,A,T,T,G,C,A%
    }{
        0/0,
        1/2,
        2/3,
        3/4,
        5/6,
        6/7%
    }

这表示将第一幅图像中的位置 0 与第二幅图像中的位置 0 链接起来,将第一幅图像中的位置 1 与第二幅图像中的位置 2 链接起来,等等。

现在我想要做的是给边缘末端的每个字母添加样式,例如,使其变为粗体(或红色,或其他颜色)。也就是说,在顶部字符串中,我希望索引 0、1、2、3、5 和 6 处的字母为粗体,在底部字符串中,我希望索引 0、2、3、4、6 和 7 处的字母为粗体。这就是我陷入困境的地方。

以下是完整的 MWE:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{xparse}

\begin{document}


\newcommand{\letterspacing}{.5}


\NewDocumentCommand{\drawmatching}{m m m O{0} O{0}}{
    \pgfmathsetmacro{\xstart}{#4}
    \pgfmathsetmacro{\ystart}{#5}

    \foreach [count=\i] \letter in {#1}{
        \pgfmathtruncatemacro{\index}{\i-1}

        % check if \index in the list of pairs?
        \tikzset{letter/.style={}}

        \node[anchor=base, letter] at (\xstart+\letterspacing*\i,\ystart) (a\index) {\texttt \letter};
        \node[above=.45cm, anchor=base] at (\xstart+\letterspacing*\i,\ystart) {\tiny \index};

    }


    \foreach [count=\i] \letter in {#2}{
        \pgfmathtruncatemacro{\index}{\i-1}
        \node[anchor=base] at (\xstart+\letterspacing*\i,\ystart-2) (b\index) {\texttt \letter};
        \node[anchor=north] at (\xstart+\letterspacing*\i,\ystart-2) {\tiny \index};
    }

    \foreach \i/\j in {#3}{
        \draw (a\i) -- (b\j);
    }
}


\begin{tikzpicture}
    \drawmatching{%
        G,A,T,T,A,C,A}{%
        G,C,A,T,T,G,C,A%
    }{
        0/0,
        1/2,
        2/3,
        3/4,
        5/6,
        6/7%
    }
\end{tikzpicture}

\end{document}

我的第一个想法是检查上面注释的行是否\index出现在有序对列表中的一对中的第一个数字,但我掉进了 xparse 兔子洞。有没有简单的方法可以做到这一点?

答案1

一种使用 LaTeX 条件和样式命令的方法。其思想是#3每次需要打印字母时都进行嵌套循环,并在该嵌套循环中检查#3(第一个数字代表顶部,第二个数字代表底部)中提到的任何数字是否与当前索引匹配。

如果找到匹配项(使用\ifnum[index from inner loop]=[index from outer loop]),则可以定义一个命令(\letterstyle在下面的代码中调用)来更改字体,例如使用颜色或斜体等。应该在循环之前为此命令分配一个默认值,如果在循环中未找到任何元素的匹配项,则将使用该默认值。

请注意,我在您的代码中切换\texttt到的是一个接受参数的命令,而是一个更改当前范围内所有剩余文本的字体的开关(或直到与另一个字体开关一起使用新的字体系列)。\ttfamily\texttt\ttfamily

梅威瑟:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{xparse}

\begin{document}


\newcommand{\letterspacing}{.5}


\NewDocumentCommand{\drawmatching}{m m m O{0} O{0}}{
    \pgfmathsetmacro{\xstart}{#4}
    \pgfmathsetmacro{\ystart}{#5}

    \foreach [count=\i] \letter in {#1}{
        \pgfmathtruncatemacro{\index}{\i-1}

        % default style if no match is found: black
        \gdef\letterstyle{\color{black}}
        \foreach \lfirst/\lsecond in {#3}{
            \ifnum\lfirst=\index\gdef\letterstyle{\color{red}}\fi
        }
        \node[anchor=base] at (\xstart+\letterspacing*\i,\ystart) (a\index) {\ttfamily\letterstyle\letter};
        \node[above=.45cm, anchor=base] at (\xstart+\letterspacing*\i,\ystart) {\tiny \index};

    }


    \foreach [count=\i] \letter in {#2}{
        \pgfmathtruncatemacro{\index}{\i-1}
        % default style if no match is found: italics  
        \gdef\letterstyle{\itshape}
        \foreach \lfirst/\lsecond in {#3}{
           \ifnum\lsecond=\index\gdef\letterstyle{\upshape}\fi
        }
        \node[anchor=base] at (\xstart+\letterspacing*\i,\ystart-2) (b\index) {\ttfamily\letterstyle\letter};
        \node[anchor=north] at (\xstart+\letterspacing*\i,\ystart-2) {\tiny \index};
    }

    \foreach \i/\j in {#3}{
        \draw (a\i) -- (b\j);
    }
}

\begin{tikzpicture}
    \drawmatching{%
        G,A,T,T,A,C,A}{%
        G,C,A,T,T,G,C,A%
    }{
        0/0,
        1/2,
        2/3,
        3/4,
        5/6,
        6/7%
    }
\end{tikzpicture}

\end{document}

结果:

在此处输入图片描述

相关内容