
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}
Ich verwende einige Paketbefehle, um den Text auszuschneiden/aufzuteilen, damit er mit Lettrine den gewünschten Effekt erzielt. Bei der Verwendung innerhalb des Befehls xstring
treten jedoch einige Fehler auf .\ref{label}
\openintro{This is a NOT working test due to~\ref{mylabel}}
Das Problem hängt mit dem hyperref
Paket zusammen, bei dem Links aktiviert sind. Der Befehl \StrBefore
zeigt 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. xstring
Das Makro kennt das jedoch \noexpandarg
und verhindert die Erweiterung des Arguments des Haupteingabestrings zu xstring
Makros, 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}
Antwort2
Es scheint mir zu kompliziert. Warum gibt es diese \StrBefore
Verarbeitung usw.? Warum braucht man letrine
ein 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 \openitroA
Definition 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.