0

When called in the body the replace function \MakeURLHyperTargetFromSectionName{Replace all spaces with dashes} works, but called as \def\currenthypertarget{\MakeURLHyperTargetFromSectionName{A string with spaces} } it does nothing (i.e. currenthypertarget="A string with spaces"

[BTW, the replace function "marian_replace" is just the simplest I could get to work. Actually I want to use the function \magguu_compactlabel from Automatic Labels with automatically generated keys but any attempt to use mwe's with regex_replace_all throw errors]

MWE

\documentclass[english,headings=optiontotocandhead]{scrartcl}
\makeatletter

\usepackage[colorlinks=true]{hyperref}
\usepackage{pdfcomment}
\usepackage{lipsum}
\usepackage{expl3,xparse}
%----------
\FamilyStringKey[.section]{KOMAarg}{hypertarget}{\currenthypertarget}
\newcommand*{\currenthypertarget}{}
\makeatletter
\renewcommand*{\sectionlinesformat}[4]{%
  \ifx\currenthypertarget\@empty  %hypertarget has not been given
   % \def\currenthypertarget{#1.\csname the#1\endcsname} %use default e.g "section.1
    \def\currenthypertarget{\MakeURLHyperTargetFromSectionName{A string with spaces} } %automatically generate url from heading
  \fi  
  \hypertarget{\currenthypertarget}{}
  \@hangfrom{\hskip #2#3}{\pdftooltip{#4}{\#\currenthypertarget}}%
  \global\let\currenthypertarget\@empty
  \hyperref[toc]{\hphantom{M}} %make an invisible link back to TOC at end of section heading (colorlinks=true)
}
%---------------------
\ExplSyntaxOn
\NewDocumentCommand{\MakeURLHyperTargetFromSectionName}{m}
 {
  \marian_replace:nnn {#1} % {#2} {#3}
 }

\tl_new:N \l_marian_input_text_tl

\cs_new_protected:Npn \marian_replace:nnn #1 % #2 #3
 {
  \tl_set:Nn \l_marian_input_text_tl { #1 }
  \tl_replace_all:Nnn \l_marian_input_text_tl { ~ } { - }
  \tl_use:N \l_marian_input_text_tl
 }
\ExplSyntaxOff

\makeatother

\usepackage{babel}
\begin{document}

\section{Lyx Section1}

\MakeURLHyperTargetFromSectionName{Replace all spaces with dashes}

\subsection{Lyx subSection1}

\section{Lyx Sec Same Name}

\section{Lyx Sec Same Name}

\section[hypertarget={First.Section.Name}]{First Section Name} 
\lipsum[1] 
\section[hypertarget={Example.Section}]{Example Section} 
\lipsum[2] 
\section[hypertarget={anb}]{Final Section} 

See \hyperlink{First.Section.Name}{the first section} or 
\hyperlink{Example.Section}{the second section} or 
\hyperlink{Final.Section}{this final section}.

\newpage{}

\tableofcontents{}\label{toc}
\end{document}

1 Answer 1

1

First of all #4 of \sectionlinesformat is not only the title but the formatted title (see the KOMA-Script manual for information about this). So you would have to replace not only the spaces. An alternative would be to use \@currentlabelname (generated by hyperref resp. nameref resp. scrartcl).

Second, \marian_replace:nnn is wrong, because the name denotes three arguments (of expl3 type n), but have only one. I will not use it in my example, so see the expl3 manual for more information, if you want to know the correct naming scheme.

Last but not least, I think, you want \currenthypertarget be the expanded replacement not the definition of the replacement.

For solving the last issue a simple replacement for the spaces could be done, e.g., by

\documentclass[headings=optiontotocandhead]{scrartcl}
\usepackage{hyperref}
\usepackage[draft]{pdfcomment}
\usepackage{lipsum}
\usepackage{expl3}

\FamilyStringKey[.section]{KOMAarg}{hypertarget}{\currenthypertarget}
\newcommand*{\currenthypertarget}{}
\makeatletter
\ExplSyntaxOn
\renewcommand*{\sectionlinesformat}[4]{%
  \ifx\currenthypertarget\@empty
    \let\currenthypertarget\@currentlabelname
    \tl_replace_all:Nnn\currenthypertarget { ~ } { - }
  \fi  
  \hypertarget{\currenthypertarget}{}\@hangfrom{\hskip
    #2#3}{\pdftooltip{#4}{\#\currenthypertarget}}%
  \global\let\currenthypertarget\@empty
}
\ExplSyntaxOff
\makeatother

\begin{document}
\section{First Section Name}
\lipsum[1]
\section[hypertarget={Example.Section}]{Example Section}
\lipsum[2]
\section[hypertarget={Final.Section}]{Final Section}
See \hyperlink{First-Section-Name}{the first section} or
\hyperlink{Example.Section}{the second section} or
\hyperlink{Final.Section}{this final section}.
\end{document}

To do the full magic, define a \generatehypertarget similar to the label generation commands of the answer to the above linked question:

\documentclass[headings=optiontotocandhead]{scrartcl}
\usepackage{hyperref}
\usepackage[draft]{pdfcomment}
\usepackage{lipsum}
\usepackage{xparse}

\FamilyStringKey[.section]{KOMAarg}{hypertarget}{\currenthypertarget}
\newcommand*{\currenthypertarget}{}
\ExplSyntaxOn
\tl_new:N \l_magguu_compactlabel_tl
\cs_new_protected:Nn \magguu_compactlabel:nn
 {
  \tl_set:Nn \l_magguu_compactlabel_tl { #2 }
  \show \l_magguu_compactlabel_tl
  % remove non alphabetic/space characters
  \regex_replace_all:nnN {[^a-zA-Z\s]} {} \l_magguu_compactlabel_tl
  % remove words less than three letter long
  \regex_replace_all:nnN {\b[a-zA-Z]{1,2}\b} {} \l_magguu_compactlabel_tl
  % remove leading spaces
  \regex_replace_once:nnN {\A\s+} {} \l_magguu_compactlabel_tl
  % remove trailing spaces
  \regex_replace_once:nnN {\s+\Z} {\ } \l_magguu_compactlabel_tl
  % change runs of space into an underscore
  \regex_replace_all:nnN {\s+} {_} \l_magguu_compactlabel_tl
  % truncate to #1 characters
  \regex_replace_all:nnN {(^\w{1,#1})\w*} {\1} \l_magguu_compactlabel_tl
  % remove a possible trailing underscore
  \regex_replace_once:nnN {_\Z} {} \l_magguu_compactlabel_tl
  % lowercase the string
  \tl_set:Nx \l_magguu_compactlabel_tl { \str_lower_case:f { \tl_use:N \l_magguu_compactlabel_tl } }
}
\NewDocumentCommand{\generatehypertarget}{ O{20} m }{%
  \magguu_compactlabel:nn { #1 } { #2 }
  \tl_set_eq:NN\currenthypertarget\l_magguu_compactlabel_tl
}  
\ExplSyntaxOff
\makeatletter
\renewcommand*{\sectionlinesformat}[4]{%
  \ifx\currenthypertarget\@empty
    \expandafter\generatehypertarget\expandafter{\@currentlabelname}%
  \fi  
  \hypertarget{\currenthypertarget}{}\@hangfrom{\hskip
    #2#3}{\pdftooltip{#4}{\#\currenthypertarget}}%
  \global\let\currenthypertarget\@empty
}
\makeatother

\begin{document}
\section{First Section Name}
\lipsum[1]
\section[hypertarget={Example.Section}]{Example Section}
\lipsum[2]
\section[hypertarget={Final.Section}]{Final Section}
See \hyperlink{first_section_name}{the first section} or
\hyperlink{Example.Section}{the second section} or
\hyperlink{Final.Section}{this final section}.
\end{document}
1
  • thanks, I'll try it in the morning, the first part worked.
    – Henry Crun
    Sep 4, 2017 at 12:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .