문제: 내부 링크를 사용한 문자열 조작

문제: 내부 링크를 사용한 문자열 조작

\openintro나는 내 작업의 모든 장에서 부르는 새로운 명령을 정의했습니다 . 이 명령은 기본적으로 아래 이미지와 같은 lettrine 문장을 구성합니다(텍스트 스타일은 신경쓰지 마세요).

\openintro{This is a working test}

여기에 이미지 설명을 입력하세요

나는 xstring패키지의 일부 명령을 사용하여 텍스트를 잘라내거나 분할하여 원하는 효과를 lettrine과 일치시킵니다. 그러나 \ref{label}명령 내부에서 사용할 때 일부 오류가 발생합니다.

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

문제는 hyperref링크가 활성화된 패키지와 관련되어 있습니다. 이 명령은 \StrBefore문자열의 링크에 직면할 때 몇 가지 오류를 표시합니다. 을 비활성화하면 hyperref사용에 문제가 없습니다 \ref. 하지만 hyperref. 이 문제를 해결하기 위한 제안 사항이 있습니까? 감사해요.

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

제가 보기에는 너무 복잡해 보입니다. 왜 등의 처리가 있습니까 \StrBefore? 왜 패키지가 필요합니까 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에게 감사 인사를 전하고 싶습니다.

관련 정보