再次,我遇到了宏问题。它几乎可以正常工作。我花了很多时间在 Google 上搜索\expandafter
、\noexpand
和\unexpanded
其他。我使用了其中一些,但没有一个能产生预期的结果。
如果你找到了更好的标题来解决这个问题,那就改一下吧。我用的是我能想到的最好的标题。
以下是我的代码:
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{graphicx}
\usepackage{environ}
\makeatletter
%%%Liederbuch. This works!!!
\NewEnviron{Liederbuch}[1]{
\xdef\LB@my@temp{
\noexpand\newcommand{\csname LH#1\endcsname}[2]{
\unexpanded\expandafter{\BODY}
}
}
\aftergroup\LB@my@temp
}
%%%%%%%%%%%%%%%%%
%The problem starts in the following Environ:
%If I replace `##1` and `##2` with constants, it works, but therefore it fails the basic intention of this effort.
%To see, what should happen, have a look at `\begin{document}`
%%%%%%%%%%%%%%%%%
%%%Lied. This doesn't work!!!
\NewEnviron{Lied}[2]{%
\ifnum\numexpr#2=\numexpr##2 % ##2 doesn't work; i.e. "1" instead of ##2 works
\ifnum\pdfstrcmp{#1}{##1}=0 % ##1 doesn't work; same as above
\BODY
\fi
\fi
}
\makeatother %residual of some tries with xdef and \aftergroup
%%%%%%%%%%%%%%%%%
%Apparently, the following code is super clean. That is the basic idea.
%%%%%%%%%%%%%%%%%
% This is a Liederbuch
\begin{Liederbuch}{songbook}
\begin{Lied}{t}{1}
Song 1 par t
\end{Lied}
\begin{Lied}{n}{2}
Song 2 par n
\end{Lied}
\end{Liederbuch}
% LHsong calls "the environment" This works!!!
\newcommand{\LHsong}[3][n]{
\csname LH#2\endcsname[#1]{#3}
}
\begin{document}
%This should produce Song 1 par t
\LHsong[t]{songbook}{1}
%This shouldn't produce anything
\LHsong[n]{songbook}{1}
%This should produce Song 2 par n
\LHsong{songbook}{2}
%This shouldn't produce anything
\LHsong[t]{songbook}{2}
%This should also produce Song 1 par t
\LHsongbook{t}{1}
\end{document}
Liederbuch 扩展为以下代码,但不属于我的代码
% it expands to: %not part of the code
%Liederbuch
\newcommand{\csname LHsongbook\endcsname}[2]{
%Lied 1
\ifnum1=\numexpr##2 %\numexpr#2 expanded to 1; ##2 should be par2 of newcommand
\ifnum\pdfstrcmp{t}{##1}=0 %#1 expanded to t
Song 1 par t
\fi
\fi
%Lied 2 - same here different values
\ifnum2=\numexpr##2
\ifnum\pdfstrcmp{n}{##1}=0
Song 2 par n
\fi
\fi
}
我从我的另一个问题中偷来了 Liederbuch-Environ。通过将 ##x 更改为常数,可以看到此方法有效的证明。我想 Lied 应该看起来类似,但我不知道如何。
目的是让环境 Liederbuch 创建一个 [可能一系列] 自定义 Lied 环境,其中如果参数符合某些规范,则 \LHsong 的调用将产生来自 Lied 的输出。
答案1
我不知道这是否正是您想要的,但这似乎确实有效。我etoolbox
为了方便而加载了(\csgdef
,\csxdef
,\csuse
)。
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}
\usepackage{environ}
\newenvironment{Liederbuch}[1]
{\def\liederbuchtmp{#1}\csgdef{LH#1}##1##2{\csuse{lied;#1;##1;##2}}}
{}
\NewEnviron{Lied}[2]{\csxdef{lied;\liederbuchtmp;#1;#2}{\expandonce\BODY}} % perhaps trimming spaces would be important
\newcommand*\LHsong[3][n]{\csuse{lied;#2;#1;#3}}
\begin{Liederbuch}{songbook}
\begin{Lied}{t}{1}
Song 1 par t
\end{Lied}
\begin{Lied}{n}{2}
Song 2 par n
\end{Lied}
\end{Liederbuch}
\begin{document}
% This should produce Song 1 par t
\LHsong[t]{songbook}{1}
% This shouldnt produce anything
\LHsong[n]{songbook}{1}
% This should produce Song 2 par n
\LHsong{songbook}{2}
% This shouldnt produce anything
\LHsong[t]{songbook}{2}
% This should also produce Song 1 par t
\LHsongbook{t}{1}
\end{document}