TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I need to measure a number of characters in string, that I returned from label through \nameref command.

Here is my MWE:

\documentclass{article}

\usepackage{hyperref}
\usepackage{xstring}

\begin{document}

\protected\def\testStr{\nameref{testLabel}}
String content = \testStr
\par

\newlength\testStrWidth
\settowidth{\testStrWidth}{\testStr}
String width = \the\testStrWidth
\par

\StrLen{\testStr}[\testStrNumOfChars]
Number of characters in string = \testStrNumOfChars

\clearpage

\makeatletter
\edef\@currentlabelname{This is a somewhat long string}
\label{testLabel}
\makeatother

Here we have some text to make another page.

\end{document}

Here is the result:

MWE result

MWE doesn't give any errors. I'm using XeTeX, but it doesn't work in pdfLaTeX too. I've tried \edef, \def, \let instead of \protected\def, but nothing seems to work.

Of course, if I set tested string explicitly inside \StrLen command, everything will work as it should.

Any help would be much appreciated.

share|improve this question
up vote 2 down vote accepted

The \nameref command needs to be fully expanded into its textual form. To that end, you need to remove the hyperlinking that surrounds it, as that is what's causing the problems.

The following is marginally different from egreg's answer and uses e-TeX for conditioning on the existence of the reference - \r@<label>. All we're interested in is extracting the name/title. Nothing more...

enter image description here

\documentclass{article}

\usepackage{hyperref,xstring}
\newcommand{\thirdoffive}[5]{#3}% Similar to \@thirdoffive
% \assignnameref{<ref>}{<macro>}
\newcommand{\assignnameref}[2]{%
  \gdef#2{}% Assign macro to be blank
  \ifcsname r@#1\endcsname % If the reference exists...
    \xdef#2{\expandafter\expandafter\expandafter\thirdoffive\csname r@#1\endcsname}% ...grab the third argument - the name/title
  \fi
}
\begin{document}

\assignnameref{testLabel}{\testStr}%
String content = \testStr
\par

\newlength\testStrWidth
\settowidth{\testStrWidth}{\testStr}%
String width = \the\testStrWidth
\par

\StrLen{\testStr}[\testStrNumOfChars]%
Number of characters in string = \testStrNumOfChars

\clearpage

\makeatletter
\edef\@currentlabelname{This is a somewhat long string}
\label{testLabel}
\makeatother

Here we have some text to make another page.

\end{document}

Yes, \labels exist in the .aux file as macros in the form \r@<label> (via \newlabel). See Understanding how references and labels work.

share|improve this answer
    
Thanks for replay! So I can extract even another label attributes through this method. It will be really useful. – Andrew Bohr Mar 1 at 1:31
    
@AndrewBohr: Yup. Based on hyperref, the first attribute is the reference number, the second attribute is the page number, the third attribute is the title, the fourth attribute is the hyperlink anchor, while the fifth attribute is left blank. – Werner Mar 1 at 1:46

You need an expandable version of \nameref:

\documentclass{article}

\usepackage{xstring}
\usepackage{hyperref}

\makeatletter
\newcommand{\getnamereftext}[1]{%
  \@ifundefined{r@#1}{}{%
    \unexpanded\expandafter\expandafter\expandafter{%
      \expandafter\expandafter\expandafter\@thirdoffive\csname r@#1\endcsname
    }%
  }%
}

\begin{document}

\StrLen{\getnamereftext{testLabel}}[\testStrNumOfChars]
Number of characters in string = \testStrNumOfChars

\makeatletter
\edef\@currentlabelname{This is a somewhat long string}
\label{testLabel}
\makeatother

\end{document}

This will return 0 when the label is not yet defined.

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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