2

The following TikZ code attempts to make a graph by drawing vertices 1 through 6, then drawing edges from the list. The edges are formatted as 12, 23, etc., so the command StrChar from package xstring is used to extract the first and second characters.

\documentclass{minimal}

\usepackage{tikz}
\usepackage{xstring}

\begin{document}
\begin{tikzpicture}
    \foreach \index in {1, ..., 6}{%
        \node[draw,thick,circle,fill=blue!20,inner sep=1pt,minimum size=7pt] (\index) at (\index*360/6:1) {} ;
    }
    \foreach \edgetodraw in {12,13,14,15,16,34}{%
        \draw[thick] (\StrChar{\edgetodraw}{1}) -- (\StrChar{\edgetodraw}{2}) ;
    }
\end{tikzpicture}
\end{document}

When compiled with pdflatex this gives the unhelpful error

! Undefined control sequence.
\@xs@StrChar@@ ...\@xs@arg@ii {#2}\edef \@xs@call 
                                                  {\noexpand \@testopt {\noe...
l.13     }

An even smaller MWE is below:

\documentclass{minimal}

\usepackage{tikz}
\usepackage{xstring}

\begin{document}
\begin{tikzpicture}
    \draw[thick] (\StrChar{34}{1}) -- (\StrChar{34}{2}) ;
\end{tikzpicture}
\end{document}

giving the same error. How can I get StrChar to work inside tikzpicture?

More Details:

  • StrChar works outside of tikzpicture just fine, even when used inside a \foreach loop.

  • I am writing a macro to be able to draw many graphs very quickly and systematically. I would really like it to be able to work with the format I am using for edges ({12, 13, 14, 15, 16, 23}). So in the interest of my question being as simple and specific as possible, I am asking about how to use StrChar inside tikz. But if it is considered a bad idea to to use such heavily programmed macros in vanilla LaTeX, I'm interested in alternative approaches as well.

  • Maybe this question about xstring and includegraphics is related?

  • 2
    The usual approach is to use Example: \foreach \x / \y in {1/2,a/b} {``\x\ and \y''} yields \1 and 2"\a and b". (from page 911 of the v3.0 manual). – John Kormylo Jul 23 '15 at 23:26
  • @JohnKormylo Thank you for your comment, that is very useful to know! – 6005 Jul 24 '15 at 16:36
2

minimal class is not meant for the end-user --> See Why should the minimal class be avoided?

Regarding your use case, the problem is that xstring provides conditions and tests that are not expandable, in other words, the conditions and tests do not replace stream with the result but rather would like to save the results hidden from the stream. This is also the case for \pgfmathparse macro that you need to use the result \pgfmathresult after you parse the mathematical expression. Here you need to let TikZ know that it has to stop the path parsing and do some TeX stuff (xstring part) and continue parsing.

\documentclass[tikz]{standalone}
\usepackage{xstring}

\begin{document}
\begin{tikzpicture}
    \foreach \index in {1, ..., 6}{%
        \node[draw,thick,circle,fill=blue!20,inner sep=1pt,minimum size=7pt] (\index) at (\index*360/6:1) {} ;
    }
    \foreach \x in {12,13,14,15,16,34}{%
        \draw[thick] \pgfextra{\StrChar{\x}{1}[\tempa]\StrChar{\x}{2}[\tempb]} (\tempa) -- (\tempb) ;
    }
\end{tikzpicture}
\end{document}

enter image description here

You can instead do the macro assignment before the path within the loop and do the path later with well defined quantities. But that's a matter of taste.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.