7

Several packages that generate inline text (i.e. glossaries, cleverref) have commands to let the author choose capitalization. In particular, glossaries seems to be able to do parts of this automatically.

However, nameref (of the nameref package) is unable to change the capitalization of the referenced text. As nameref is often used to reference section titles which are capitalized text starts looking wrong, when the capitalization is kept up mid sentence.

While there is one answer on here that solves this problem, it relies on inserting a macro infront of every letter for which the capitalization should be adjusted.

  1. Given that commands for modifying capitalization are available (\MakeUppercase, \MakeLowercase, \makefirstuc), why is it so hard to provide nameref commands that return the name in all lowercase or all but the first letter lowercase?

  2. Would it be possible to protect parts of a heading from capitalization changes? (i.e. \MakeUppercase{so\MakeLowercase{WhAT}} returns SOwhat (see Texbook page 42 for details))

i.e:

\section{This is about \MakeUppercase{PCI}e on Mainboards}

\nameref    -> This is about PCIe on Mainboards    normal
\lcnameref  -> this is about PCIe on mainboards    LowerCase
\ucnameref  -> This Is About PCIe On Mainboards    UpperCase
\fucnameref -> This is about PCIe on mainboards    FirstUpperCase

I tried extending nameref by copying the definition of \nameref and wrapping all occurences of \@thirdoffive{#1} in \MakeLowercase however the result was quite unexpected: for the input This Is a Section I got 11This Is a Sectionsection.1.

I actually had to copy the .sty file, as using \makeatletter/\makeatother in the preamble for the new definition resulted in warnings about undefined macros.

11
+100

hyperref/nameref makes extensive use of the \AtBeginDocument-hook.

In case you wish to redefine some internals of the nameref-package, you need to use the \AtBeginDocument-hook, too.

Otherwise your changes done in the preamble will be overridden when hyperref/nameref's \AtBeginDocument-thingies are carried out.

The example below delivers three macros \fucnameref, \ucnameref and \lcnameref.

For case-changing the macros from Nicola Talbot's mfirstuc-package are used.

Thus within the arguments of sectioning-commands you can use the tricks explained in the manual of that package.

I highly recommend reading that manual as it also explains the many pitfalls with that package.

With that package you can use a preceding empty group {} for preventing evaluation of commands. E.g., you can use {}\MakeUppercase and {}\MakeLowercase for ensuring uppercased-letters/lowercased-letters.

\documentclass{article}
\usepackage{hyperref}[2018/02/06 v6.86b Hypertext links for LaTeX]
\usepackage{mfirstuc}[2017/11/14 v2.06 (NLCT)]

\makeatletter
\AtBeginDocument{%
  \newcommand\My@Macro[1]{#1}%
  \newcommand\My@Thirdoffive[5]{\My@Macro{#3}}%
  \renewcommand*\@namerefstar[1]{%
    \HyRef@StarSetRef{#1}\My@Thirdoffive
  }%
  \renewcommand*\T@nameref[1]{%
    \begingroup
    \let\label\@gobble
    \NR@setref{#1}\My@Thirdoffive{#1}%
    \endgroup
  }%
  \DeclareRobustCommand\fucnameref{%
    \@ifstar\fucnameref@star\fucnameref@nostar
  }%
  \newcommand\callemakefirstuc[1]{%
    \MakeLowercase{\emakefirstuc{#1}}%
  }%
  \newcommand\fucnameref@star[1]{%
    \begingroup
    \let\My@Macro=\callemakefirstuc
    \nameref*{#1}%
    \endgroup
  }%
  \newcommand\fucnameref@nostar[1]{%
    \begingroup
    \let\My@Macro=\callemakefirstuc
    \nameref{#1}%
    \endgroup
  }%
  \DeclareRobustCommand\ucnameref{%
    \@ifstar\ucnameref@star\ucnameref@nostar
  }%
  \newcommand\ucnameref@star[1]{%
    \begingroup
    \MFUhyphentrue
    \let\My@Macro=\ecapitalisefmtwords
    \nameref*{#1}%
    \endgroup
  }%
  \newcommand\ucnameref@nostar[1]{%
    \begingroup
    \MFUhyphentrue
    \let\My@Macro=\ecapitalisefmtwords
    \nameref{#1}%
    \endgroup
  }%
  \DeclareRobustCommand\lcnameref{%
    \@ifstar\lcnameref@star\lcnameref@nostar
  }%
  \newcommand\lcnameref@star[1]{%
    \begingroup
    \let\My@Macro=\MakeLowercase
    \nameref*{#1}%
    \endgroup
  }%
  \newcommand\lcnameref@nostar[1]{%
    \begingroup
    \let\My@Macro=\MakeLowercase
    \nameref{#1}%
    \endgroup
  }%
}%
\makeatother

\newcommand\SomeSectionTitle{%
  Some very Nice section Title with 
  {}\texorpdfstring{{}\MakeUppercase{pci}}{PCI} and
  {}\texorpdfstring{{}\MakeLowercase{PCI}}{{}pci}%
}

\begin{document}

\parindent=0ex
\parskip=\baselineskip

\begin{verbatim}
\newcommand\SomeSectionTitle{%
  Some very Nice section Title with 
  {}\texorpdfstring{{}\MakeUppercase{pci}}{PCI} and
  {}\texorpdfstring{{}\MakeLowercase{PCI}}{{}pci}%
}

\section{\SomeSectionTitle}\label{NiceLabel}
\end{verbatim}

yields:

\section{\SomeSectionTitle}\label{NiceLabel}

\verb|\nameref{NiceLabel}| yields:\\ \nameref{NiceLabel}

\verb|\fucnameref{NiceLabel}| yields:\\ \fucnameref{NiceLabel}

\verb|\ucnameref{NiceLabel}| yields:\\ \ucnameref{NiceLabel}

\verb|\lcnameref{NiceLabel}| yields:\\ \lcnameref{NiceLabel}

\verb|\nameref*{NiceLabel}| yields:\\ \nameref*{NiceLabel}

\verb|\fucnameref*{NiceLabel}| yields:\\ \fucnameref*{NiceLabel}

\verb|\ucnameref*{NiceLabel}| yields:\\ \ucnameref*{NiceLabel}

\verb|\lcnameref*{NiceLabel}| yields:\\ \lcnameref*{NiceLabel}

\end{document}

enter image description here

Edit on Friday, September 7, 2018:

Please don't try to nest calls to \fucnameref or to \ucnameref or to \lcnameref—i.e., don't do try things like

\section{Some Nice Section}\label{NiceSection}
...
\section{annotations to \lcnameref*{NiceSection}}\label{Annotations}
...
\fucnameref{Annotations}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.