問題: 内部のリンクを含む文字列操作

問題: 内部のリンクを含む文字列操作

私は自分の作品の各章で呼び出す新しいコマンドを定義しました\openintro。このコマンドは基本的に、以下の画像のようなlettrine文を構築します(テキストのスタイルは気にしないでください)。

\openintro{This is a working test}

ここに画像の説明を入力してください

xstring私は、lettrine で目的の効果に一致するようにテキストを切り取り/分割するために、パッケージのいくつかのコマンドを使用しています。ただし、\ref{label}コマンド内で使用するとエラーが発生します。

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

この問題は、リンクが有効になっているパッケージに関連しています。文字列内のリンクに直面すると、hyperrefコマンドがいくつかのエラーを表示します。 を無効にすると、 を使用するときに問題はありません。ただし、 を使用する必要があります。この問題を解決するための提案はありますか? ありがとうございます。\StrBeforehyperref\refhyperref

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}

そしてエラー:

! 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.

答え1

の展開\ref...によりエラーが発生します。ただし、 はマクロxstringを認識しているため\noexpandarg、メイン入力文字列の引数のxstringマクロへの展開は防止されますが、最初の操作の後は、 を使用して、展開を再度有効にする必要があります\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}

ここに画像の説明を入力してください

答え2

複雑すぎるように思えます。なぜ\StrBeforeetc. 処理があるのでしょうか? なぜletrineパッケージが必要なのでしょうか? 次のようにして同じことができます:

\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}

物事をもっと簡単にできることを人々が知らないために、多くの問題が発生します。

編集: David のコメントにより、\openitroA行数の多いテキストでの letrine の使用と同様の動作になるように定義を変更しました。

答え3

私は、@wipet と lettrine によって提供されたコードの一部を使用して、自分の質問に答えています (テキスト スタイルを操作する方が簡単なため)。最初の質問の文字列操作全体を使用する代わりに、次のコードを使用します (全体を置き換えます\newcommand{\openintro})。

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

改めて、@ChristianHupfer、@wipet、@DavidCarlisle の協力に感謝したいと思います。

関連情報