请向下滚动查看编辑内容和最新版本
这不是一个好标题,但我没有想出更好的标题。
我有一个应该像这样使用的环境(看起来必须是这样的):
\begin{Lied}{A}{1}
\setAuthor{Author1}
Content A1
\end{Lied}
\begin{Lied}{A}{2}
\setAuthor{Author2}
Conten A2
\end{Lied}
\begin{Lied}{B}{1}
\setAuthor{Author3}
Content B1
\end{Lied}
我想通过命令调用环境的内容,以便将它们放入文本中。存储作者、来源和作曲家等内容。这些内容应根据样式围绕内容放置。因此,我可以使用命令调用环境的内容,它们的外观取决于定义的样式。
内容应该这样调用\csuse{lied;A;1}
:例如,应该插入作者,然后插入 Lied-A-1 的内容。
因此我可以用命令调用预定义数据库的内容。
这是一个运行良好的例子:
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{environ}
\usepackage{etoolbox}
\begin{document}
\NewEnviron{Lied}[2]{{
%to save a string
\def\Author{leer}
%to change the string
\def\setAuthor##1{##1}
\long\def\temp{}
\long\def\test{{\Author \temp}}
\let\temp\BODY
%"write" the content of setAuthor to Author
\let\Author\setAuthor
%make output
\test
}}
\begin{Lied}{A}{1}
\setAuthor{Maestro}
Hallo
Absatz1
\end{Lied}
\csuse{lied;A;1}
Absatz2\\
Zeile
Absatz3
\end{document}
它给出以下输出:
如果我\cslet
这样使用,就会出现错误:
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{environ}
\usepackage{etoolbox}
\begin{document}
\NewEnviron{Lied}[2]{{
\def\Author{leer}
\def\setAuthor##1{##1}
\long\def\temp{}
\long\def\test{{\Author \temp}}
\let\temp\BODY
\let\Author\setAuthor
\global\cslet{lied;#1;#2}\test
}}
\begin{Lied}{A}{1}
\setAuthor{Maestro}
Hallo
Absatz1
\end{Lied}
\csuse{lied;A;1}
Absatz2\\
Zeile
Absatz3
\end{document}
如果我只使用
\NewEnviron{Lied}[2]{\global\cslet{lied;#1;#2}\BODY}
它工作正常,但没有\Author
-part
编辑:
以下代码已简化,以更清楚地显示目的。一般来说,它应该在稍后发布的包中使用。如果它有效,可以以非常简单的方式生成歌本。从这些歌本中,可以通过一个简单的命令将歌曲插入现有文档中。样式应描述它们在导入时的外观。
以下代码可以正常工作,并且 100% 按照应有的方式工作,但如果我\\
在环境中使用,它就会中断:
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{environ}
\usepackage{etoolbox}
%%%The following code defines my default style. Right now, it only contains only the author
\def\stylehead{\Author}
\def\stylefoot{}
%%%This would redefine the commands stylehead and stylefoot. Casual would be some external .sty-file
%\usestyle{casual}
%This code maybe changed.
\NewEnviron{Lied}[2]{{
\def\Author{leer}
\def\setAuthor##1{##1}
\long\def\temp{}
\long\def\test{{\stylehead \BODY \stylefoot}}
\let\Author\setAuthor %This applies setAuthor (defined in \BODY) to Author (used in \stylehead)
\global\csedef{lied;#1;#2}{\test}
}}
%%%This code may not be changed. That is a contraint of the project
\begin{Lied}{A}{1}
\setAuthor{Maestro}
%uncommenting the next line breaks the code
Hallo%\\ this is in a new line
Absatz1
\end{Lied}
%%%document for testing
\begin{document}
\csuse{lied;A;1}
Absatz2\\
Zeile
Absatz3
\end{document}
答案1
如果你添加
\global\cslet{lied;#1;#2}\test
\show\test
你会看到,\test
所以lied;..;..
定义为
> \test=\long macro:
->{\Author \temp }.
但是\Author
和\temp
仅在本地定义,因此在您尝试使用它的组之外没有定义。
我无法弄清楚预期的行为,但这没有错误。
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{environ}
\usepackage{etoolbox}
\begin{document}
\NewEnviron{Lied}[2]{{%
\def\Author{leer}%%%
\def\setAuthor##1{##1}%%%
\let\Author\setAuthor
\csxdef{lied;#1;#2}%
{{%
\expandafter\unexpanded\expandafter{\Author{??}} % space intended here?
\expandafter\unexpanded\expandafter{\BODY}}}%%%
}}
\begin{Lied}{A}{1}
Hallo
Absatz1
\end{Lied}
\csuse{lied;A;1}
Absatz2\\
Zeile
Absatz3
\end{document}
原文的注释版本
\def\stylehead{\Author}
这定义了\stylehead
(\Author
取决于您何时进行评估)固定字符串leer
或具有定义的宏,\def\Author#1{#1}
在这种情况下它将抓取并复制下一个标记\stylehead
(\BODY
此处的示例)。
\def\stylefoot{}
这定义\stylefoot
为空
%%%This would redefine the commands stylehead and stylefoot. Casual would be some external .sty-file
%\usestyle{casual}
好的
%This code maybe changed.
\NewEnviron{Lied}[2]{{
这将在环境组之外启动一个附加组,并由于%
在行尾之前缺少空格标记而添加一个空格标记。
\def\Author{leer}
这定义\Author
为leer
然后插入一个空格标记
\def\setAuthor##1{##1}
this(可能超出定义范围)定义\SetAuthor
为与\@firstofone
so\SetAuthor{anything}
扩展为相同anything
,因此该命令不会执行任何非常有用的操作。然后插入一个空格标记。
\long\def\temp{}
定义\temp
为空(\long
没有做太多事情)然后插入一个空格标记。
\long\def\test{{\stylehead \BODY \stylefoot}}
定义\temp
为\stylehead \BODY \stylefoot
在一个组内。(\long
没做什么)。然后插入一个空格标记。
\let\Author\setAuthor %This applies setAuthor (defined in \BODY) to Author (used in \stylehead)
该评论似乎是错误的,这只是使其\Author
具有相同的定义,因此\SetAuthor
就像\newcommand\Author[1]{#1}
\global\csedef{lied;#1;#2}{\test}
这全局定义了 \lied'..;.. 但不支持将 edef 应用于任意乳胶标记,您将破坏大多数命令(\\
仅仅是一个例子)再次由于缺少而插入空格标记%
。
您需要使用\unexpanded
原始或\expandonce
etoolbox 或 控制扩展\expandafter\protected@xdef\csname lied;#1;#2\endcsname{\test}%
}}
这样就结束了内部组和定义。
\begin{Lied}{A}{1}
\setAuthor{Maestro}
这与
\begin{Lied}{A}{1}
Maestro
就像\SetAuthor
只是复制它的参数。
答案2
您无法实现这一点;诸如必须在扩展\setAuthor
之前评估之类的设置才能将其存储在宏中。您可以在进行设置时添加第三个参数。但您可能使用了错误的方法:键值方法会更好。\BODY
lied
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{environ}
\usepackage{etoolbox}
\newcommand{\setAuthor}[1]{\def\Author{#1}}
\setAuthor{leer} % default
\NewEnviron{Lied}[3]{%
\par#3
\csxdef{lied;#1;#2}{\expandonce{\Author} \expandonce{\BODY}}%
}
\begin{document}
\begin{Lied}{A}{1}{
\setAuthor{Maestro}
}
Hallo
Absatz1
\end{Lied}
\csuse{lied;A;1}
\end{document}
我相信这样的语法
\begin{Lied}{
class=A,
number=1,
author=Author,
title=Title,
publisher=Publisher,
}
Text of the lied\\
with line breaks
\end{Lied}
将会更加容易管理。