在引用作者的语言实例时,我喜欢使用特殊标签来指定作者的姓名。(我将其括在方括号中,但由于不相关,它不会出现在这里。)
当引用多个示例和子示例时同一作者我希望能够跳过这个特殊的非数字标签并只保留数字。
\StrCut 可以xstring
很好地去除作者姓名和数字之间的不可分割的空格。
但是,当没有分隔符时,通常的解决方案cleveref
\crefstripprefix 不能按预期工作,请参阅 MWE。
此外,使用 \StrCut 剥离到 level2/level3 分隔符可获得作者 1a.i--iiihyperref
可以工作,但如果加载则会产生严重错误。
让我指出的是,我并不特别需要范围,它已经在使用 mwe 中所示的替代“调整”方法了。
我只是希望在引用示例时能够跳过作者姓名,它将为非范围的多个引用提供所需的灵活性,例如“作者 1a.ii, 2b.i”。
所有编码信息均可在此处找到: 交叉引用:更多子级别和预设
\documentclass{article}
\usepackage{philex} % Linguex wrapper. Awesome despite the "non-academic" coding.
\usepackage{xstring} % Provides the \StrCut command.
\usepackage{refcount} % Provides the \getrefbykeydefault command.
\usepackage{cleveref} % For ranges.
\setlength{\parskip}{1em}
\crefname{bpa}{}{} % Main Counter
\crefname{SubExNo}{}{} % Sublevel.
\crefname{SubSubExNo}{}{}
\newcommand{\dotstrip}[2]{\StrCut{#1}{.}{\onea}{\oneb}%
\StrCut{#2}{.}{\twoa}{\twob}%
\IfStrEq{\onea}{\twoa}{\twob}{#2}}
\newcommand{\spacestrip}[2]{\StrCut{#1}{~}{\onea}{\oneb}%
\StrCut{#2}{~}{\twoa}{\twob}%
\IfStrEq{\onea}{\twoa}{\twob}{#2}}
\crefrangelabelformat{bpa}{(#3#1#4--#5\spacestrip{#1}{#2}#6)} % Stripping to the non-brakable space, so that Author is not repeated.
\crefrangelabelformat{SubExNo}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)} % Usually outputs 1a--b but does not work here.
\crefrangelabelformat{SubSubExNo}{(#3#1#4--#5\dotstrip{#1}{#2}#6)} % Used with roman numbering, which confuses crefstripprefix. But you need a separator (a dot in this variant).
\begin{document}
% Philex Formatting
\phildashes{}{.} % Adds a dot between levels 2 and 3 in references.
\subformat{a}{}{.} % Level 2 is of the form “a.”
\subsubformat{i}{(}{)} % Level 3 is of the form “(i)”
\bpaformat{1}{Author~}{}
\lbpa{main1}{Example One.
\lba{sub11}{Subexample One-One.
\lba{subsub111}{Subsubexample One-One-One.}
\lbb{subsub112}{Subsubexample One-One-Two.}
\lbz{subsub113}{Subsubexample One-One-Three}}
\lbz{sub12}{Subexample One-Two.
\lba{subsub121}{Subsubexample One-Two-One.}
\lbz{subsub122}{Subsubexample One-Two-Two.}}}
\lbpa{main2}{Example Two.}
When quoting different examples, I do not want \textit{Author} to be repeated.
Works very nicely with xstring's StrCut for the 1st level...
\crefrange{main1}{main2}
... but the 3rd does not work if hypperref is loaded :
\textbackslash crefrange\{subsub111\}\{subsub113\} yields a critical error.
\vspace{6pt}
... and more importantly, level 2 does not work at all because \textbackslash crefstripprefix fails:
\textbackslash crefrange\{sub11\}\{sub12\} should output “Author 1a--b” but instead I get the following error :
“Improper alphabetic constant.”
\vspace{12pt}
Of course an alternative approach is to refer to “parts” so we can “cheat” and build the refs manually:
Philex already has \textbackslash rfx/rnx command to skip the main level.
Then we may define a new command to skip the first sublevel :
\makeatletter
\@ifdefinable\gobbletodot{\long\def\gobbletodot#1.{}}% refcount package
\newcommand\delbefdot[1]{%
\ifcat$\detokenize\expandafter{\gobbletodot#1.}$%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{#1}{\expandafter\delbefdot\expandafter{\gobbletodot#1}}%
}%
\@ifdefinable\rfxx{%
\DeclareRobustCommand\rfxx[1]{%
\IfRefUndefinedBabel{#1}{\refused{#1}\nfss@text{\reset@font\bfseries??}}%
{%
\@ifundefined{hyperref}{\@firstofone}{\hyperref[{#1}]}%
{%
(\expandafter\expandafter\expandafter\delbefdot
\expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}})%
}%
}%
}%
}%
\@ifdefinable\rnxx{%
\DeclareRobustCommand\rnxx[1]{%
\IfRefUndefinedBabel{#1}{\refused{#1}\nfss@text{\reset@font\bfseries??}}%
{%
\@ifundefined{hyperref}{\@firstofone}{\hyperref[{#1}]}%
{%
\expandafter\expandafter\expandafter\delbefdot
\expandafter\expandafter\expandafter{\getrefbykeydefault{#1}{}{??}}%
}%
}%
}%
}%
\makeatother
\newcommand{\rfstrip}[2]{(\rn{#1}--\rnx{#2})}
\newcommand{\rfdoublestrip}[2]{(\rn{#1}--\rnxx{#2})}
\rfstrip{sub11}{sub12}
\rfdoublestrip{subsub111}{subsub113}
\vspace{6pt}
But we lose systematicity and besides, “Author 1a.i, 2b.” is also something I would like.
\end{document}
答案1
感谢@Ulrike Fischer 的示例这里关于如何使用 brilliant 包zref
,我提出了一个快速说明如何解决原帖中我自己提出的问题的方案。
正如您所见,此后一切都变得容易多了。
(当然, \zlabel 必须在包含后者的任何语言包的所有地方替换 \label,这样我们就不必手动添加它,但这很简单。)
\documentclass{report}
\usepackage{zref-user}
\usepackage{philex}
\setlength{\parskip}{1em}
\makeatletter
\zref@newprop{exno}{\arabic{ExNo}}
\zref@newprop{subexno}{\alph{SubExNo}}
\zref@newprop{subsubexno}{\roman{SubSubExNo}}
\zref@newprop{authorstrip}{\bota{bpa}\alph{SubExNo}{\ifnum\theExDepth=3\roman{SubSubExNo}\fi}} % Here is the key line.
\zref@newprop{refstrip}{\ifnum\theExDepth=3\roman{SubSubExNo}\else\alph{SubExNo}\fi}
\zref@addprops{main}{exno,subexno,subsubexno,authorstrip,refstrip}
\makeatother
\newcommand{\authorstrip}[2]{(\zref{#1},\,\zref[authorstrip]{#2})}
\newcommand{\rfxx}[1]{(\zref[subsubexno]{#1})}
\newcommand{\rfstrip}[2]{(\zref{#1}--\zref[refstrip]{#2})}
\begin{document}
\phildashes{}{.}
\subformat{a}{}{.}
\bpaformat{1}{Author~}{}
\lbpa{main1}{Example One.\zlabel{mainex}
\lba{sub11}{Subexample One-One.\zlabel{sub11}
\lba{subsub111}{Subsubexample One-One-One.}\zlabel{subsub111}
\lbb{subsub112}{Subsubexample One-One-Two.}
\lbz{subsub113}{Subsubexample One-One-Three.\zlabel{subsub113}}}
\lbz{sub12}{Subexample One-Two.\zlabel{sub12}
\lba{subsub121}{Subsubexample One-Two-One.}
\lbz{subsub122}{Subsubexample One-Two-Two.}}}
\lbpa{main2}{Example Two.
\lba{sub21}{Subexample Two-One.}
\lbz{sub22}{Subexample Two-Two.}} \zlabel{sub22}
\vspace{6pt}
Results :
\rfxx{subsub113}
\rfstrip{subsub111}{subsub113}
\rfstrip{sub11}{sub12}
\authorstrip{subsub111}{sub22}
\end{document}
编辑:
要单独提取与命令的参数 3 相对应的作者姓名变量\bpaformat
,只需在后者的定义中添加以下命令:
\gdef\theauthor{#3}
命令\gdef
是一种非常有效的方法,可以从任何命令中提取任何参数。只需确保在定义中使用它,这样就可以通过参数引用代码访问变量#n(在哪里n是参数的等级,从左到右计数)。