Problem: String-Manipulation mit darin enthaltenen Links

Problem: String-Manipulation mit darin enthaltenen Links

Ich habe einen neuen Befehl definiert \openintro, den ich in jedem Kapitel meiner Arbeit aufrufe. Dieser Befehl erstellt im Wesentlichen einen Lettrinensatz, wie im Bild unten (kümmern Sie sich nicht um den Textstil):

\openintro{This is a working test}

Bildbeschreibung hier eingeben

Ich verwende einige Paketbefehle, um den Text auszuschneiden/aufzuteilen, damit er mit Lettrine den gewünschten Effekt erzielt. Bei der Verwendung innerhalb des Befehls xstringtreten jedoch einige Fehler auf .\ref{label}

\openintro{This is a NOT working test due to~\ref{mylabel}}

Das Problem hängt mit dem hyperrefPaket zusammen, bei dem Links aktiviert sind. Der Befehl \StrBeforezeigt einige Fehler an, wenn ein Link in der Zeichenfolge angezeigt wird. Wenn ich deaktiviere hyperref, gibt es bei Verwendung kein Problem \ref. Aber ich muss verwenden hyperref. Haben Sie Vorschläge zur Lösung dieses Problems? Danke.

MWE:

\documentclass[12pt]{book}

\usepackage{xstring,lettrine}

\usepackage[pagebackref]{hyperref}
\hypersetup{
  linktoc=all,
  colorlinks=true,
  allcolors=red
}%

\newcommand{\openintro}[1]{%
  \def\firsttwowords{}%
  \def\firstword{}%
  \def\firstwordsplit{}%
  \def\secondword{}%
  \def\firstletter{}%
  \def\remainingtext{}%
  \def\charcount{}%
  \StrBefore[2]{#1}{ }[\firsttwowords]% get the first two words
  \StrBefore[1]{\firsttwowords}{ }[\firstword]% get the first word
  \StrGobbleLeft{\firstword}{1}[\firstwordsplit]% del the first letter of first word
  \StrBehind[1]{\firsttwowords}{ }[\secondword]% get only the second word
  \StrLeft{#1}{1}[\firstletter]% get the first letter of first word
  \StrLen{\firsttwowords}[\charcount]% count the number of characters of first two words
  \StrGobbleLeft{#1}{\charcount}[\remainingtext]% del the number of characters on the left of the whole sentence
  \lettrine{\firstletter}{\firstwordsplit~\secondword}~\textit{\remainingtext}\\[1PC]%
}%

\begin{document}

\chapter{test}

\openintro{This is a NOT working test due to~\ref{mylabel}}

\section{Hi there}\label{mylabel}

\end{document}

Und der Fehler:

! Use of \@xs@StrBefore@@ doesn't match its definition.
\@ifnextchar ... \reserved@d =#1\def \reserved@a {
                                                  #2}\def \reserved@b {#3}\f...
l.36 ...s a NOT working test due to~\ref{mylabel}}

! Argument of \@firstoftwo has an extra }.
<inserted text> 
                \par 
l.36 ...s a NOT working test due to~\ref{mylabel}}

Runaway argument?
! Paragraph ended before \@firstoftwo was complete.

Antwort1

Die Erweiterung von \ref...führt zum Fehler. xstringDas Makro kennt das jedoch \noexpandargund verhindert die Erweiterung des Arguments des Haupteingabestrings zu xstringMakros, muss aber nach der ersten Operation mit wieder aktiviert werden \expandarg.

\documentclass[12pt]{book}

\usepackage{xstring,lettrine}

\usepackage[pagebackref]{hyperref}
\hypersetup{
  linktoc=all,
  colorlinks=true,
  allcolors=red
}%

\newcommand{\openintro}[1]{%
  \def\firsttwowords{}%
  \def\firstword{}%
  \def\firstwordsplit{}%
  \def\secondword{}%
  \def\firstletter{}%
  \def\remainingtext{}%
  \def\charcount{}%
  \noexpandarg%
  \StrBefore[2]{#1}{ }[\firsttwowords]% get the first two words
  \expandarg% Now expand again
  \StrBefore[1]{\firsttwowords}{ }[\firstword]% get the first word
  \StrGobbleLeft{\firstword}{1}[\firstwordsplit]% del the first letter of first word
  \StrBehind[1]{\firsttwowords}{ }[\secondword]% get only the second word
  \StrLeft{#1}{1}[\firstletter]% get the first letter of first word
  \StrLen{\firsttwowords}[\charcount]% count the number of characters of first two words
  \StrGobbleLeft{#1}{\charcount}[\remainingtext]% del the number of characters on the left of the whole sentence
  \lettrine{\firstletter}{\firstwordsplit~\secondword}~\textit{\remainingtext}\\[1PC]%
}%

\begin{document}

\chapter{test}

\openintro{This is a NOT working test due to~\ref{mylabel}}

\section{Hi there}\label{mylabel}

\end{document}

Bildbeschreibung hier eingeben

Antwort2

Es scheint mir zu kompliziert. Warum gibt es diese \StrBeforeVerarbeitung usw.? Warum braucht man letrineein Paket? Dasselbe kann man so machen:

\documentclass[12pt]{book}
\usepackage[pagebackref]{hyperref}
\hypersetup{
  linktoc=all, 
  colorlinks=true,
  allcolors=red
}%

\def\openintro#1{\openintroA #1 \end}
\def\openintroA#1#2 #3 #4\end{\par
   \setbox0=\hbox{\fontsize{27}{27}\selectfont#1\/}%
   \hangindent=\wd0 \advance\hangindent by0pt \hangafter=-2
   \noindent \hskip-\hangindent\vbox to0pt{\kern-6pt\box0\vss}%
   {\uppercase{#2 #3} \it#4\unskip}%
   \medskip
}

\begin{document}

\chapter{test}

\openintro{This is a working test due to~\ref{mylabel}}

\section{Hi there}\label{mylabel}

\end{document}

Viele Probleme entstehen, weil die Leute nicht wissen, dass es auch einfacher geht.

Bearbeiten: Aufgrund von Davids Kommentar habe ich die \openitroADefinition geändert, sodass das Verhalten der Letrine-Verwendung für Texte mit mehr Zeilen ähnelt.

Antwort3

Ich beantworte meine eigene Frage, indem ich einen Teil des von @wipet und lettrine bereitgestellten Codes verwende (da es einfacher ist, die Textformatierung zu manipulieren). Anstatt die gesamte Zeichenfolgenmanipulation meiner ersten Frage zu verwenden, verwende ich einfach den folgenden Code (der den gesamten ersetzt \newcommand{\openintro}):

\def\openintro#1{\openintroA #1 \end}
\def\openintroA#1#2 #3 #4\end{%
      \lettrine{#1}{#2~#3}~\textit{#4}%
}

Ich möchte mich noch einmal bei @ChristianHupfer, @wipet und @DavidCarlisle für die Hilfe bedanken.

verwandte Informationen