2

I'm trying to do some very basic programming tasks(but as usual TeX makes this extremely time consuming and difficult (for me, of course) ;/)

The problem is that I can't seem to get LaTeX to expand the macros.

I have a sequence which, \defaultList, which is simply a sequence of comma separated tokens, e.g., {a,b,c},{e,f,g} is a 2 element sequence. I am simply trying to extract the sub elements from the sequence(e.g., a, b and c as separate entities to be used). One of the biggest problems I have is that I can't seem to "plug" in what I think(ala common standard programming logic) the equivalent of an expression because latex seems to think it is something else(I've tried to get things to expand properly but it never works and latex's error messages are so convoluted and uninformative as to be nearly useless).

\ExplSyntaxOn
\pgfmathtruncatemacro{\N}{\seq_count:N \defaultList} % this is done because I can't seem to use the count directly(even if I wrap it in a common macro
\ExplSyntaxOff
\foreach \n [evaluate=\n] in {1,...,\N}
{       
    \ExplSyntaxOn
    \def\s{\seq_item:Nn \defaultList \n} % gets the nth item and 
    \typeout{\s} % prints out the correct {a,b,c} then next iteration {e,f,g}
    \seq_set_split:Nnn \qqqd {,} {\seq_item:Nn \defaultList \n} % suppose to turn the elements into sequences themselves so I can get at the sub-elements. e.g., first time through the loop \qqqd = a,b,c

    \def\vvv{\seq_item:Nn \qqqd 1} % \vvv should be a, the first element extract from \qqqd(and \qqqd was extract from \s)
    \ExplSyntaxOff

    \typeout{\vvv} % this simply prints '\seq_item:Nn \defaultList \n' and not a, which is what I want. (or b if we use 2 instead of 1 in the definition of \qqqd.

}

Programmatically all I am trying to do is take a sequence of "sequences" and extract the elements into "variables"(or whatever text calls them).

I'm more interesting in solving the real problem of ignorance then the specific issue here. Why does \typeout{\vvv}display the macro contents as I typed it instead of "expanding/evaluating" it?

I do realize there is a big issue with expandability. I just want some way to know why something seem to work as expected and others don't, and yet when I try various "solutions" they do nothing(most of the time). (\the, \expandafter, etc...)

e.g., why does \typeout{\vvv} display the macro code and \typeout{\s} display the expected results? In my eyes both are basically defined the same way(conceptually I can't see why one works and one doesn't expect \vvv is an extra level of "redirection" since it uses \s).

Thanks

--- Code...

\documentclass[11pt]{article} % use larger type; default would be 10pt

\usepackage{geometry} % See geometry.pdf to learn the layout options. There are lots.
\geometry{a4paper} % or letterpaper (US) or a5paper or....
%\usepackage[parfill]{parskip} % Activate to begin paragraphs with an empty line rather than an indent

\usepackage{graphicx} % support the \includegraphics command and options
\usepackage{xspace, xparse, tikz, etoolbox, subfig, expl3, pgffor}
\usetikzlibrary{calc,trees,hobby}

\pgfdeclarelayer{bgLayer3}
\pgfdeclarelayer{bgLayer2}
\pgfdeclarelayer{bgLayer1}
\pgfdeclarelayer{bgNotes}
\pgfsetlayers{bgLayer3,bgLayer2,bgLayer1,bgNotes,main}  % set the order of the layers (main is the standard layer)

\ExplSyntaxOn
\let\tl_length:n\tl_count:n
\ExplSyntaxOff

\newcounter{chords-string}
\newcounter{chords-fret}


% Variables
\newcommand{\chordreset}{
  \def\chordtuning{E,A,D,G,B,E}
  \def\chordfretstart{1}
  \def\chordfretend{4}
  \def\chordgroupingstart{1}
  \def\chordgroupingend{10}
}
\chordreset



\ExplSyntaxOn
\NewDocumentCommand \clearSeq {O{\defaultList}} { \seq_clear_new:N #1 }%
\NewDocumentCommand \clearNewSeq {O{\defaultList}} { \seq_clear_new:N #1 }%
\NewDocumentCommand \litSeqToSeq {m O{\defaultList}} { \seq_set_from_clist:NN #2 #1 }%
\DeclareExpandableDocumentCommand \addToSeqEnd {m} { \seq_put_right:Nn \defaultList #1 }%
\NewDocumentCommand \addToSeqStart {m O{\defaultList}} { \seq_put_left:Nn #2 #1 }%

\NewDocumentCommand \popSeqEnd {m O{\defaultList}} { \seq_pop_right:NN #2 #1 }%
\NewDocumentCommand \popSeqStart {m O{\defaultList}} {\seq_pop_left:NN #2 #1 }%
\NewDocumentCommand \peekSeqEnd {m O{\defaultList}} { \seq_get_right:NN #2 #1 }%
\NewDocumentCommand \peekSeqStart {m O{\defaultList}} { \seq_get_left:NN #2 #1 }%
\NewDocumentCommand \mapSeqInline {m O{\defaultList}} { \seq_map_inline:Nn #2 #1 }%

\NewDocumentCommand \showSeq {O{\defaultList}} { \seq_show:N #1 }%
\NewDocumentCommand \useSeq {O{,} O{\defaultList}} { \seq_use:Nn #2 #1 }%

\NewDocumentCommand \seqLength {O{\defaultList}} { \seq_count:N #1 }%
\NewDocumentCommand \seqItem {m O{\defaultList}} { \seq_item:Nn #2 #1 }%
\ExplSyntaxOff




% A single note
% \single <string> <fret> <finger> <other>
\NewDocumentCommand \single {m m m}
{
    \typeout{---------------------single}%
    \begin{pgfonlayer}{bgNotes}    
        \draw node[single](#1) at (#1,#2) {#3};
    \end{pgfonlayer}{bgNotes}    
    \addToSeqStart{{#1,#2,#3}}
}

% A bar
% \bar <startstring> <fret> <finger>
\DeclareDocumentCommand \bar {m m m}
{
    \typeout{---------------------bar}%
    \draw[bar] (#1,#2) -- node[midway] {#3} (1,#2);
}

% No strike
% \nostrike <string>
\NewDocumentCommand \nostrike {m m m}
{
    \typeout{---------------------nostrike}%
    \draw[nostrike] (#1,\chordfretstart-.5) +(-135:.2cm) -- +(45:.2cm);
    \draw[nostrike] (#1,\chordfretstart-.5) +(135:.2cm) -- +(-45:.2cm);
}



\ExplSyntaxOn
\newcommand{\cgrouploop}
{
    %----------- This is where I need to deal with all the arguments passed 
    %\showSeq
    \ExplSyntaxOn
    \pgfmathtruncatemacro{\N}{\seq_count:N \defaultList}

    \foreach \n [evaluate=\n] in {1,...,\N}
    {       

        \def\s{\seq_item:Nn \defaultList \n}        
        %\typeout{\s}
        \seq_set_split:Nnn \qqqd {,} {\seq_item:Nn \defaultList \n}
        \def\fret{\seq_item:Nn \qqqd 1}                


    }

    % Here I need to take the different elements (string, fret, finger, etc) and use them in some way. I'll, at some point need to form a new list such as {string1, string2, string3, ....} and pass that to another command for more processing.

    \ExplSyntaxOff


}


\ExplSyntaxOff
\NewDocumentEnvironment{cgroup} {o}
{
    \clearNewSeq
}
{
    \begin{pgfonlayer}{bgLayer1}
        %\draw[thick,blue] \convexpath{\useSeq}{1.2cm};
        \cgrouploop        
    \end{pgfonlayer}{bgLayer1}
}


% The chord environmant
% \begin{chord}
% \begin{chord}[D,G,D,G,H,E]
\NewDocumentEnvironment{chord} {o}
{
    \typeout{--------------chord}%

    \typeout{---------------------chord:FB}%
    % Fretboard BG Code
    \begin{tikzpicture}
    [
        single/.style={draw,circle,fill=white},
        bar/.style={cap=round,double,double distance=18pt},
        nostrike/.style={line width=.8mm},
        cm={0,-0.8,1,0,(0,0)}
    ]
        % draw grid/fretboard
        \begin{pgfonlayer}{bgLayer3}
            \draw[yshift=-0.5cm] (1,\chordfretstart) grid (6,\chordfretend+1);
        \end{pgfonlayer}{bgLayer3}

        % draw Notes
        \begin{pgfonlayer}{bgNotes}
            \setcounter{chords-string}{6}
            \foreach \tuning in \chordtuning
            {
                %\node at (\value{chords-string},\chordfretstart-1) {\tuning};
                \addtocounter{chords-string}{-1}
            }
        \end{pgfonlayer}{bgNotes}
}
{
    \end{tikzpicture}
}




\begin{document}

\begin{figure}
\subfloat[F major]{
\begin{chord}
    \begin{cgroup}
      \bar    6 1 1    % bar from 6th string down with index finger on 1st fret
      \single 1 2 a  % ringfinger on 5th string 3rd fret
      \single 3 4 b  % pinky on 4th string 3rd fret
      \single 5 6 d  % index on 3rd string 2nd fret
  \end{cgroup}
\end{chord}
\chordreset}
\end{figure}

\break
\vspace{1cm}




\end{document} 
  • The commands \ExplSyntaxOn and \ExplSyntaxOff should go outside the \foreach cycle. But sequences are the wrong data type. – egreg May 3 '15 at 19:09
  • Your example doesn't compile as-is or with a short header added (as @egreg notes), so it's hard to say why you see what you say you see with \typeout{\vvv}. – Joseph Wright May 3 '15 at 19:22
  • Also, the reason for the wrapping of latex3e is because it seems that it doesn't work in the environmental blocks. (simply wrapping them allows it to work) – user4780446 May 3 '15 at 20:07
  • It's difficult to understand what the \cgrouploop macro should do. If you do that cycle, only the last value will be loaded in \fret. So if the sequence contains the items {5,6,d}, {3,4,b} and {1,2,a}, you'll end up with \fret expanding to 1. I mean, with a different loop, because with foreach you'll end up with \fret being undefined or having the same value it had before the \foreach (which does everything in groups). – egreg May 3 '15 at 20:24
  • @egreg: I might be totally approaching it wrong since I'm thinking as a "normal" programmer. (I probably should have used lualatex but I was trying to avoid any heavy dependencies) Basically all I want to do is draw a convexhull around the nodes given in the cgroup environment. To do this, I have to pass the node list to the convexhull macro, which, of course, means I first have to collect the "nodes"(which is done in the single command), then reformat them and pass them appropriately to the convex hull macro... this is what the cgrouploop does. – user4780446 May 3 '15 at 20:41
1

You seem to be aiming to map over the sublists inside the main comma list (not a sequence) of your variable. To do that, I'd use

\RequirePackage{expl3}
\ExplSyntaxOn
\clist_set:Nn \l_tmpa_clist { { a , b , c } , { d , e , f } }
\clist_map_inline:Nn \l_tmpa_clist
  {
    \clist_map_inline:nn {#1}
      { \tl_show:n {##1} }
  }
\ExplSyntaxOff

where I've just shown the results.

I think your confusion arises as \typeout carries out expansion but \def does not. Thus in your code

\def\s{\seq_item:Nn \defaultList \n}

results in \s being exactly \seq_item:Nn \defaultList \n (try \show\s to see it). When you do

\typeout{\s}

TeX expands \s, and as the content is expandable you see the result.

  • I've tried edef and all that but nothing works. I can't use map because I have to construct something to pass it to later. I am simply trying to modify the code @ http://www.texample.net/tikz/examples/guitar-chords/ so that I can take the arguments(after \single in the chord environment) and add more stuff(not just string fret and finger)... but I have to store the arguments of all the \single calls so I have one large list that I can then do stuff with. I have the list but I can't see to extract the sub elements. – user4780446 May 3 '15 at 19:53
  • @user4780446 You'll need to edit the question to include more detail, then. For example, I don't see what is wrong with a simple mapping if you want to store stuff (for example, I could add all of the elements to a single new comma list instead of using \tl_show:n). – Joseph Wright May 3 '15 at 19:54
  • I have no idea if I'm going about it right though. In any case, my new single command simply has the following inserted at the end \addToSeqStart{{#1,#2,#3}} (here I have use xparse to rewrite single outside of the chord enviornment as given in the link because I can't seem to use latex3e stuff). \addToSeqStart is just a wrapper '\NewDocumentCommand \addToSeqStart {m O{\defaultList}} { \seq_put_left:Nn #2 #1 }%' – user4780446 May 3 '15 at 19:55
  • the exmaple is given in the link. As I said, I simply need some way, to extract the elements from the master argument list(again, I already have that in a sequence from using \addToSeqStart. I can also extra the elements easily enough. But why can't I extract the sub-elements? It should be exactly identical logically except In one case I have a sequence and the other a "clist"(I guess, at least a literal clist). – user4780446 May 3 '15 at 19:57
  • Also, s is not the problem. It IS the element I'm after. The problem is with extract the sub element(say, the 3rd) from it. – user4780446 May 3 '15 at 20:08

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.