매크로에 포함된 다음 텍스트 덩어리(지정된 크기) 가져오기

매크로에 포함된 다음 텍스트 덩어리(지정된 크기) 가져오기

단일 매크로에 조판할 텍스트가 많이 포함되어 있다고 가정해 보겠습니다.\myverylongtext

\newcommand{\myverylongtext}{
    This is some really long text: \blindtext[4].

    And it continues even more: \blindtext[1].
}

단순화를 위해 에는 sectioning/newpage 명령이 없지만 \myverylongtext줄바꿈 명령과 여러 단락(단락바꿈 명령?)이 있을 수 있다고 가정해 보겠습니다. 또한 다른 모든 LaTeX 조판 명령(\textbf 등)이 텍스트 내에서 허용되고 적용되더라도 글꼴 크기와 행간은 전체적으로 일정하게 유지된다고 가정합니다.

(만났을 때) 지정된 차원의 다음 텍스트 덩어리를 가져오는 효율적인* 매크로를 정의하는 것이 가능합니까? 예를 들어:

\newcommand{\getnextchunk}[4]{
    % #1 is name of macro (in our case \myverylongtext) 
    % #2 width of text box
    % #3 height of text box in lines
    % #4 draftmode: optional boolean argument that, when set, instead of typesetting contents returns the actual height (in lines), and width (in length units) of the chunk. (useful in making dynamic layout decisions)
    % returns/typesets a box of shape width * height
}

이 매크로에 대한 새로운 호출은 마치 \getnextchunk에 포함된 텍스트가 \myverylongtext이전 청크에서 이 청크로 리플로우된 것처럼 다음 텍스트 청크를 가져와야 합니다.

* 내용이 \myverylongtext매우 길고 덩어리가 많을 수 있으므로 효율성이 필요합니다. 나머지 부분을 \myverylongtext여러 번 조판할 수 없습니다. 이러한 문제에 대한 해결책 중 하나는 크기가 0인 상자가 너비(길이 치수), 높이(라인) 및 필요한 정렬과 같은 지정된 측정항목으로 커질 때까지 반복적으로 채워지는 것입니다. 비록 제가 직접 작성하기에는 저수준 tex/luatex/expl3에 대한 이해가 부족합니다.

또한 지정된 raggedright/raggedleft/full-justified와 같은 정렬 명령이 \myverylongtext마법처럼 적용되거나 &에 그러한 명령이 없도록 제한을 설정할 수 있습니다. \myverylongtext대신에 4번째 인수로 전달할 수 있습니다 \getnextchunk(후자는 다음과 같습니다). 바람직하며 코드/사용이 더 쉽고 깨끗해집니다.)

문제를 시각화하는 또 다른 방법은 문서에서 만날 때마다 순차적으로 서로 흐르는 여러 개의 직사각형 텍스트 상자(너비와 높이가 다름)가 있다고 상상하는 것입니다(이 텍스트 상자의 배치에 대해 걱정하지 마십시오. *tex는 이미 이에 대한 여러 가지 우아한 솔루션이 있습니다). 또한 문서에서 이러한 텍스트 상자가 언제, 얼마나 많이 나타날지 알 수 없습니다. 내 생각에는 수년간 *tex를 사용해 본 결과 이 ​​문제 하나만 해결하면 수많은 가능성이 열리고 디자인 중심 레이아웃을 위한 타이포그래피 도구로서 가치 면에서 InDesign 등에 비해 tex가 최고가 될 것입니다. InDesign 및 Affinity Publisher와 같은 도구를 사용하면 결국 스트림으로 서로 연결되는 텍스트 상자를 연결할 수 있으며 현대적인 표현 타이포그래피와 다양한 디자인을 수용하려는 타이포그래피 시스템에 없어서는 안될 요소입니다. 이는 *tex를 훨씬 더 광범위한 조판/디자인 커뮤니티의 조판자로 열어줄 수 있습니다.

답변1

내 솔루션은 정확히 원하는 것이 아니지만 모든 정보가 한 곳에서 관리됩니다. 매개변수를 세 번 통과하는 것이 문제가 되지 않기를 바랍니다.

데이터는 다음과 같아야 합니다.

%          lines  width
\declchunk    5     10cm ;
\declchunk    6     12cm ;
\declchunk   12     13cm ;
\declchunk    9     10cm ;
\declchunk    9     10cm ;
\declchunk    9     10cm ;
\declchunk    7      8cm ;
\declchunk    5     10cm ;

\formatchunks \myverylongtext

\setbox101 = \getnextchunk
\setbox102 = \getnextchunk  \rebox 102:{\raggedright}
\setbox103 = \getnextchunk
\setbox104 = \getnextchunk  \rebox 104:{\raggedleft} 
\setbox105 = \getnextchunk

% you can place these boxes everywhere. the following code is only for testing:

box 101: \par \box101 \bigskip
box 102: \par \box102 \bigskip
box 103: \par \box103 \bigskip
box 104: \par \box104 \bigskip
box 105: \par \box105 \bigskip

\bye

먼저 모든 청크의 크기를 선언합니다(높이는 줄 수로, 너비는 크기로). 둘째, 주어진 텍스트의 형식을 지정합니다. 마지막으로 데이터 조각을 가져와서 상자에 저장할 수 있습니다. 기본적으로 블록에 맞춰져 있습니다. 다른 설정이 필요한 경우 이러한 상자를 다시 포장할 수 있습니다. 우리의 예에서는 두 번째 상자가 오른쪽으로 비정형이고 네 번째 상자가 왼쪽으로 비정형임을 보여줍니다. 게다가, 당신은 할 수 있습니다

\vbox to<dimension>{\unvbox103} \vtop to12mm{\unvbox105} etc. 

예를 들어 선 사이에 신축성과 수축성이 있기 때문입니다.

\parshape구현: s 목록으로 모든 매개변수를 가져온 \declchunk다음 이러한 매개변수를 사용하여(한 번만) 텍스트 형식을 지정 하고 가 호출될 때 \vbox\allchunks수행합니다 . 마지막으로 사용자가 다소 다른 형식의 블록 정당화가 필요한 경우 약간의 리박싱을 수행할 수 있습니다.\vsplit\getnextcunk

내 구현은 일반 TeX 및 클래식 TeX에서만 작동합니다. TeX 확장도 필요하지 않으며 (물론) LaTeX도 필요하지 않습니다.)

\newcount\tmpnum
\newcount\shapenum
\newcount\globpar
\newbox\allchunks
\newif\ifrepeat

\splittopskip=\baselineskip

\def\formatchunks#1{\setbox\allchunks=\vbox{%
   \def\par{\ifhmode\shapepar\fi}
   \def\shapepar{\prevgraf=\globpar 
      \parshape\shapenum\shapelist \endgraf
      \globpar=\prevgraf
      \ifnum\prevgraf>\shapenum \let\par=\endgraf \fi}
   \dimen0=\baselineskip \baselineskip=\dimen0 plus2pt minus2pt
   \widowpenalty=0 \clubpenalty=0 \brokenpenalty=0
   \penalty0 #1\vfil}
   \setbox0=\vsplit\allchunks to0pt % \splittopskip added
   \expandafter \renewsize \sizelist \relax
}

\def\shapelist{} \def\sizelist{}
\splittopskip=\baselineskip

\def\shapelist{} \def\sizelist{}

\def\declchunk #1 #2;{\edef\sizelist{\sizelist#1\space}
   \tmpnum=0
   \loop  \advance\tmpnum by1 \advance\shapenum by1
          \edef\shapelist{\shapelist 0pt#2}%
          \ifnum\tmpnum<#1 \repeat
}
\def\getnextchunk{\vsplit\allchunks to\size
   \ifx\sizelist\empty \def\size{\baselineskip}%
   \else \expandafter \renewsize \sizelist \relax \fi 
}
\def\renewsize #1 #2\relax{%
   \def\size{#1\baselineskip}\def\sizelist{#2}%
}

\def\rebox#1:#2{\setbox#1=\vbox{%
   \setbox0=\hbox{}%
   \repeattrue
   \def\raggedright{\rightskip=0pt plus1fill minus1em \relax}%
   \def\raggedleft{\leftskip=0pt plus1fill minus1em \relax}%
   \hsize=\wd#1 
   \unvbox#1
   \loop
      \setbox2=\lastbox
      \ifvoid2 \repeatfalse
      \else \setbox0=\hbox{\hbox{\unhbox2}\penalty-10000 \unhbox0 }
            \unskip\unskip\unpenalty
      \fi
      \ifrepeat \repeat
   \null
   #2\noindent \hfil \unhbox0 \par
}}

\def\myverylongtext{%
  Lorem ipsum dolor sit amet, consectetuer
  ...
  purus eget enim. Nunc vitae tortor. Proin tempus nibh sit amet nisl.
  Vivamus quis tortor vitae risus porta vehicula.
}

관련 정보