
Cuando cito ejemplos lingüísticos de autores dentro de una cita, me gusta utilizar una etiqueta especial que especifique el nombre del autor. (Lo incluyo entre corchetes pero no aparecerá aquí porque es irrelevante).
Al hacer referencia a múltiples ejemplos y subejemplosdel mismo autorQuiero poder omitir esta etiqueta especial no numérica y conservar solo el número.
\StrCut from xstring
funciona muy bien para eliminar el espacio irrompible que se encuentra entre el nombre del autor y el número.
Sin embargo, cuando no hay un delimitador, la solución habitual con cleveref
\crefstripprefix no funciona según lo previsto; consulte MWE.
Además, eliminando el delimitador de nivel2/nivel3 con \StrCut para obtenerAutor 1a.i--iiifunciona, pero produce un error crítico si hyperref
se carga.
Permítanme señalar que no necesito específicamente rangos, que ya funcionan utilizando un enfoque alternativo de "ajuste" como se muestra en mwe.
Solo quiero poder omitir el nombre del autor al hacer referencia al ejemplo, ya que permitiría la flexibilidad requerida para múltiples referencias que no son rangos, como "Autor 1a.ii, 2b.i".
Todos los créditos por la codificación se pueden encontrar aquí: Referencias cruzadas: más subniveles y ajustes preestablecidos
\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}
Respuesta1
Gracias al ejemplo de @Ulrike FischeraquíSobre cómo usar el paquete brillante zref
, presenté una ilustración rápida de cómo resolver el problema que planteé yo mismo en la publicación original.
Después todo es mucho más fácil, como verás.
(Por supuesto, \zlabel tendrá que reemplazar \label en todas partes de cualquier paquete lingüístico que incluya este último, de modo que no tengamos que agregarlo manualmente, pero esto es trivial).
\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}
Editar:
Para extraer solo la variable Nombre del autor, que corresponde al Argumento 3 del comando \bpaformat
, basta con agregar dentro de la definición de este último el siguiente comando:
\gdef\theauthor{#3}
El comando \gdef
es una forma muy eficaz de extraer cualquier argumento de cualquier comando. Solo asegúrese de usarlo dentro de la definición, para que se pueda acceder a la variable, mediante el código de referencia de argumento #norte(dóndenortees el rango del argumento, contando de izquierda a derecha).