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

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}
  • thanks, I'll try it in the morning, the first part worked. – Henry Crun Sep 4 '17 at 12:47

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.