前言
以下问题是一个相当复杂的类文件的一部分。因此,我试图使其尽可能简单,以显示实际问题(MWE)。我用、等做了很多实验\expandafter
,\noexpand
但\unexpanded
不得不意识到,我自己无法解决这个问题。
动机
我reledmac
定义了两个宏以便能够使用连续的引理。
\footnoteAnmerkung*
保存引理的开头和注释文本,而\footnoteAnmerkung
保存引理的结尾(以及一个空的注释文本)。连接是通过两个宏的可选参数完成的。如果没有可选参数,非星号版本也可用于“普通”单个脚注。
此外,\truncatelemma
如果词元长度超过六个单词,宏会自动截断词元(使用来自的宏xstring
)。
问题
当使用\gpreto
来组合词根的起始和结束的时候,完整的起始部分被算作一个单词\truncatelemma
(原样参见示例结果)。
使用时,\xpreto
只要我不在引理中使用任何宏,一切都会正常。结果,第二句出现了很多错误。
那么,获得有效且稳定的解决方案的正确方法是什么?
\documentclass{book}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage[]{reledmac}
\usepackage{xstring}
%%% A dummy macro
\newcommand{\mymacroA}[1]{\textbf{#1}}
\newcommand{\morenoexpands}{%
\let\mymacroA\relax
}%
\makeatletter
\newcommand{\truncatelemma}[1]{%
\begingroup%
\morenoexpands%
\normalexpandarg%
\StrCount{#1}{ }[\@numspaces]%
\ifnum\@numspaces>5%
\noindent\ignorespaces%
\StrBefore[3]{#1}{ }%
\ \ldots{}\ %
\StrBehind[\numexpr\@numspaces-2\relax]{#1}{ }%
\else%
\noindent\ignorespaces%
#1%
\fi%
\endgroup%
}%
\Xwraplemma[A]{\truncatelemma}
\def\footnoteAnmerkung{\@ifstar\@footnoteAnmerkung\@@footnoteAnmerkung}
\newcommand{\@@footnoteAnmerkung}[3][]{%
\ifcsdef{lemmastart#1}%
{\xdef\@tempA{#2}%
%%% \xpreto vs. \gpreto
\gpreto{\@tempA}{\csuse{lemmastart#1} }%
#2%
\edtext{}{%
\expandafter\lemma\expandafter{\@tempA}%
\Afootnote{\noindent\ignorespaces\csuse{anmtext#1}}%
}%
}%
{\edtext{#2}{%
\Afootnote{\noindent\ignorespaces#3}%
}%
}%
}%
\newcommand{\@footnoteAnmerkung}[3][]{%
\ifstrempty{#1}%
{% ERROR
}%
{%
#2%
\csgdef{lemmastart#1}{#2}%
\csgdef{anmtext#1}{#3}%
}%
}%
\makeatother
\begin{document}
\beginnumbering
\autopar
This is \footnoteAnmerkung*[N1]{almost the same text}{now we have a
split note} with some text in between and \footnoteAnmerkung[N1]{to show the
problem with expansion}{}. That's it.
%% Not working with \xpreto above
This is \footnoteAnmerkung*[N1]{almost \mymacroA{the same} text}{now we have a
split note} with some text in between and \footnoteAnmerkung[N1]{to show the
problem with expansion}{}. That's it.
\endnumbering
\end{document}
答案1
好的。
你的问题(第二个例子)
- 您
lemmastart#1
定义的调用\@@footnoteAnmerkung
是用 定义的\csgdef
。因此它被扩展为almost \mymacroA {the same} text.
(正如您所看到的使用 )\csshow
。 \xpreto
在定义宏时,您在某些想要完全扩展它的地方调用它\@tempA
(就像在 of 中调用它\xdef
而\edef
不是在\gdef
or中调用它一样\def
)但最终,这调用了
\bfseries
(通过mymacroA
和\textbf
)。因此\bfseries
不是“在仅扩展的上下文中是安全的“,\xpreto
在第二种情况下你不能工作(\edef\toto#1{\bfseries#1} \toto{A}
不起作用。但它与 一起工作\def
)4. 因此,您的问题是\textbf
在调用 之前将其转换为可以安全使用的内容\xpreto
。5. 因此,您必须\morenoexpands
在 的开头添加\@@footnoteAnmerkung
。6. 我认为您的\morenoexpands
应该定义为
\newcommand{\morenoexpands}{%
\let\textbf\@firstofone
}%
- 但是,在这种情况下,你输掉了比赛(当然)。但正如你所测试的,
\StrCount{\textbf{sncf toto}}{ }
这是不可能的。而且你不能使用 xstring 拆分宏来保留 bf 和其他东西(或者我不知道该怎么做)。也许使用 LuaTeXengines 是可能的。
所以我认为你能做的最好的就是
\documentclass{book}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage[]{reledmac}
\usepackage{xstring}
%%% A dummy macro
\newcommand{\mymacroA}[1]{\textbf{#1}}
\makeatletter
\newcommand{\morenoexpands}{%
\let\textbf\@firstofone
}%
\newcommand{\truncatelemma}[1]{%
\begingroup%
\morenoexpands%
\normalexpandarg%
\StrCount{#1}{ }[\@numspaces]%
\ifnum\@numspaces>5%
\noindent\ignorespaces%
\StrBefore[3]{#1}{ }%
\ \ldots{}\ %
\StrBehind[\numexpr\@numspaces-2\relax]{#1}{ }%
\else%
\noindent\ignorespaces%
#1%
\fi%
\endgroup%
}%
\Xwraplemma[A]{\truncatelemma}
\def\footnoteAnmerkung{\@ifstar\@footnoteAnmerkung\@@footnoteAnmerkung}
\newcommand{\@@footnoteAnmerkung}[3][]{%
\ifcsdef{lemmastart#1}%
{\xdef\@tempA{#2}%
%%% \xpreto vs. \gpreto
\morenoexpands%
%\csshow{lemmastart#1}
\xpreto{\@tempA}{\csuse{lemmastart#1} }%
#2%
\edtext{}{%
\expandafter\lemma\expandafter{\@tempA}%
\Afootnote{\noindent\ignorespaces\csuse{anmtext#1}}%
}%
}%
{\edtext{#2}{%
\Afootnote{\noindent\ignorespaces#3}%
}%
}%
}%
\newcommand{\@footnoteAnmerkung}[3][]{%
\ifstrempty{#1}%
{% ERROR
}%
{%
#2%
\csgdef{lemmastart#1}{#2}%
\csgdef{anmtext#1}{#3}%
}%
}%
\makeatother
\begin{document}
\beginnumbering
\autopar
This is \footnoteAnmerkung*[N1]{almost the same text}{now we have a
split note} with some text in between and \footnoteAnmerkung[N1]{to show the
problem with expansion}{}. That's it.
%% Not working with \xpreto above
This is \footnoteAnmerkung*[N1]{almost \mymacroA{the same} text}{now we have a
split note} with some text in between and \footnoteAnmerkung[N1]{to show the
problem with expansion}{}. That's it.
\endnumbering
\end{document}
关于 reledmac 使用的一些说明
- 您不应该
noindent
在命令中使用Afootnote
。首先,由于您的引理打印在行号之后,这毫无意义。此外,reledmac 不会在关键脚注中添加缩进(除非我们明确要求Xparindent
- 我认为,对于用户来说,使用较长的关键脚注比使用标签将其一分为二更简单。而且代码也会更简洁。
- 无论如何,如果您想要一个开始和结束关键脚注命令,您应该使用
\edlabel
和\xxref
命令来获取正确的行数。