我正在尝试做一些非常基本的编程任务(但像往常一样,TeX 使这项工作极其耗时且困难(当然对我来说);/)
问题是我似乎无法让 LaTeX 扩展宏。
我有一个序列,\defaultList
它只是一个逗号分隔的标记序列,例如,{a,b,c},{e,f,g}
是一个 2 元素序列。我只是试图从序列中提取子元素(例如,a、b 和 c 作为要使用的单独实体)。我遇到的最大问题之一是,我似乎无法“插入”我认为的表达式的等价物(ala 通用标准编程逻辑),因为 latex 似乎认为它是其他东西(我曾尝试让事情正确扩展,但从未奏效,而且 latex 的错误消息非常复杂且没有信息量,几乎毫无用处)。
\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.
}
从编程上来说,我所尝试做的就是获取一系列“序列”,并将其中的元素提取到“变量”(或任何文本所称的变量)中。
我更感兴趣的是解决真正的无知问题,而不是这里的具体问题。为什么\typeout{\vvv}
在我输入宏时显示宏内容,而不是“扩展/评估”它?
我确实意识到可扩展性存在很大问题。我只是想知道为什么有些东西似乎按预期工作,而其他东西却没有,但当我尝试各种“解决方案”时,它们却什么也没做(大多数时候)。(\the
,,\expandafter
等等……)
例如,为什么\typeout{\vvv}
显示宏代码并\typeout{\s}
显示预期结果?在我看来,两者的定义基本相同(从概念上讲,我不明白为什么一个有效,而另一个不期望\vvv
有一个额外的“重定向”级别,因为它使用了\s
)。
谢谢
- - 代码...
\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}
答案1
您似乎想要映射变量主逗号列表(而非序列)内的子列表。为此,我会使用
\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
我刚刚展示了结果。
我认为你的困惑在于\typeout
执行扩展但\def
没有执行扩展。因此在你的代码中
\def\s{\seq_item:Nn \defaultList \n}
结果\s
是确切地 \seq_item:Nn \defaultList \n
(试着\show\s
看一看)。当你这样做的时候
\typeout{\s}
TeX 扩展\s
,并且由于内容可扩展,您可以看到结果。