vbox의 긴 단어에 맞게 글꼴 크기를 조정하세요.

vbox의 긴 단어에 맞게 글꼴 크기를 조정하세요.

목표:
ConTeXt에서 미니멀한 책 표지를 조판하고 제목은 상자에 남아 있는 동안 가능한 가장 큰 글꼴 크기로 표시합니다.

문제:
긴 단어나 줄은 상자 오른쪽을 따르지 않고 페이지 밖으로 계속됩니다.

최소한의 예:
나는 찾았다Wolfgang의 이 코드메일링 리스트에 있어요, 덕분에이 답변@aditya에서. (바보 같은 제목이라 죄송합니다. 하지만 페이지 밖으로 계속 이어질 것이라는 단어를 원했습니다!)

\newbox\cover
\newdimen\coverheight \coverheight= 4in
\newdimen\coverwidth  \coverwidth = 7in
\newdimen\coverfont   \coverfont  = 12pt
\newdimen\fontstep    \fontstep   = 1pt

\def\startcover
  {\dostartbuffer[cover][startcover][stopcover]}

\def\stopcover
  {\setups[cover:place]}

\def\boxsize
  {\setbox\cover\vbox
     {\hsize\coverwidth
      \definedfont[Serif at \the\coverfont]\setupinterlinespace
      \setupalign[nothyphenated]
      \emergencystretch\maxdimen
      \getbuffer[cover]}}

\def\covertext
  {\boxsize\doloop
     {\boxsize
      \ifdim\ht\cover>\coverheight
        \global\advance\coverfont-\fontstep
        \exitloop
      \else
        \global\advance\coverfont\fontstep
      \fi}}

\startsetups[cover:place]
  \covertext
  \boxsize
  \vbox to\coverheight{\box\cover}
\stopsetups

\starttext

\startcover
\strut Mary Poppins Sings Supercalifragilisticexpialidocious
\stopcover

\stoptext

다음으로 컴파일:
여기에 이미지 설명을 입력하세요 노트:
맥락에서(말장난 의도는 없습니다!)책 표지의 경우 세로 공간을 채우는 것보다 가로로 최대 텍스트 크기를 얻는 것이 더 중요합니다. 이상적인 것은 텍스트의 최대 높이와 ​​절대 너비를 설정하고 텍스트를 내부에 맞추고 위쪽에 정렬하는 것입니다. 텍스트가 최대 수직 공간을 차지하지 않는다면 괜찮습니다.

답변1

이 경우에는 완전히 새로운 알고리즘을 생각해 내야 하기 때문에 설정이 조금 더 복잡합니다. 당신이 게시한 것은 상자에 물건을 조판하고 특정 높이에 도달할 때까지 글꼴 크기를 반복합니다(증가). 여기서는 상자 안에 있는 내용을 조판하고, 상자가 너무 넓은지 검사하고,감소하다글꼴 크기. 이는 터무니없이 큰 글꼴 크기(저는 100pt를 선택했습니다)부터 시작한다는 의미입니다.

이제 문제는 vbox에 고정된 너비로 항목을 설정한다는 것입니다( \textwidth단순화를 위해). 선이 너무 넓은지 어떻게 알 수 있나요? Victor Eijkhout는 그의 책에서 이에 대한 방법을 제시했습니다.주제별 TeX그가 전화한 것 \eatlines. 이를 조정하여 선 너비를 측정하고 너비 충족 여부에 따라 부울 값을 설정했습니다. 남은 유일한 일은 글꼴 크기를 반복하는 것입니다(여기서는 1pt 단위로 감소). 또한 글꼴 크기가 0pt 미만으로 감소하는 경우도 처리합니다. 이 경우 콘텐츠가 상자에 들어갈 수 없지만(이런 일이 발생해서는 안 됨) 이 경우를 생략하면 무한 루프가 발생합니다.

\newdimen\coverwidth  \coverwidth = \textwidth
\newdimen\coverfont   \coverfont  = 100pt
\newdimen\fontstep    \fontstep   = 1pt
\newconditional\widthmet

\def\startcover
  {\dostartbuffer[cover][startcover][stopcover]}

\def\stopcover
  {\setups[cover:place]}

\def\eatlines{%
  \global\settrue\widthmet
  \setbox\scratchboxone=\lastbox
  \ifvoid\scratchboxone\else
    \unskip\unpenalty
    {\eatlines}%
    \copy\scratchboxone
    \setbox\scratchboxtwo=\hbox{\unhbox\scratchboxone}%
    \ifdim\wd\scratchboxtwo>\coverwidth
      \global\setfalse\widthmet
    \fi
  \fi
}

\startsetups cover:place
  \start\dontcomplain
  \doloop{%
    \setbox\scratchbox=\vbox{\hsize=\coverwidth
      \definedfont[Serif at \the\coverfont]\setupinterlinespace
      \setupalign[nothyphenated]\emergencystretch\maxdimen
      \getbuffer[cover]%
      \par\eatlines
    }%
    \ifconditional\widthmet
      \box\scratchbox
      \exitloop
    \else
      \global\advance\coverfont by -\fontstep
    \fi
    \ifdim\coverfont<0pt
      \exitloop
    \fi
  }
  \stop
\stopsetups

\starttext

\startcover
Mary Poppins Sings Supercalifragilisticexpialidocious
\stopcover

\stoptext

출력( 포함 \showboxes):

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

ConTeXt를 사용하면 포괄적인 키-값 인터페이스를 여기에 매우 쉽게 추가할 수 있으므로 다음과 같은 기능을 사용할 수 있습니다.

\startcover[width=2in]
  Mary Poppins Sings Supercalifragilisticexpialidocious
\stopcover

\definecover[whatever][maxsize=200pt]
\setupcover[whatever][stepsize=5pt]
\startwhatever[width=4in]
  Mary Poppins Sings Supercalifragilisticexpialidocious
\stopwhatever

이것은 약간 과장된 것처럼 보일 수 있지만 더 나아가 모듈에 항목을 넣을 수도 있으므로 \usemodule[cover]설정만 하면 됩니다. t-cover.mkiv작업 디렉터리에 다음을 저장합니다 .

\startmodule[cover]
\unprotect

\installcorenamespace{cover}
\installcommandhandler \??cover {cover} \??cover

\startinterface all
  \setinterfaceconstant {maxsize}  {maxsize}
  \setinterfaceconstant {stepsize} {stepsize}
\stopinterface

\appendtoks
  \setuevalue{\e!start\currentcover}{\cover_start[\currentcover]}%
  \setuvalue {\e!stop\currentcover}{\cover_process}%
\to \everydefinecover

\setupcover[
  \c!width=\textwidth,
  \c!maxsize=100pt,
  \c!stepsize=1pt,
]

\unexpanded\def\cover_start
  {\bgroup\obeylines\dodoubleargument\cover_start_indeed}

\starttexdefinition cover_start_indeed [#1][#2]
  \egroup
  \edef\currentcover{#1}
  \setupcover[#1][#2]
  \grabbufferdata[coverbuffer][start#1][stop#1]
\stoptexdefinition

\unexpanded\def\cover_process{%
  \start\dontcomplain
  \scratchdimen=\coverparameter\c!maxsize
  \doloop{%
    \setbox\scratchbox=\vbox{\hsize=\coverparameter\c!width
      \definedfont[Serif at \the\scratchdimen]\setupinterlinespace
      \setupalign[nothyphenated]\emergencystretch\maxdimen
      \getbuffer[coverbuffer]%
      \par\eatlines
    }%
    \ifconditional\scratchcounter
      \box\scratchbox
      \exitloop
    \else
      \global\advance\scratchdimen by -\coverparameter\c!stepsize
    \fi
    \ifdim\scratchdimen<0pt
      \exitloop
    \fi
  }%
  \stop
}

\def\eatlines{%
  \global\settrue\scratchcounter
  \setbox\scratchboxone=\lastbox
  \ifvoid\scratchboxone\else
    \unskip\unpenalty
    {\eatlines}%
    \copy\scratchboxone
    \setbox\scratchboxtwo=\hbox{\unhbox\scratchboxone}%
    \ifdim\wd\scratchboxtwo>\coverparameter\c!width
      \global\setfalse\scratchcounter
    \fi
  \fi
}

\definecover[cover]

\protect
\stopmodule

그러면 기본 파일이 읽혀질 것입니다.

\usemodule[cover]

\starttext

\startcover
  Mary Poppins Sings Supercalifragilisticexpialidocious
\stopcover

\stoptext

답변2

수동으로 줄을 바꾸는 것이 마음에 들지 않고(표지 페이지에서는 큰 문제가 되지 않음) 잘못된 시각적 크기가 사용되는 것에 개의치 않는다면(글꼴 크기에 따라 글리프가 변경되는 글꼴은 거의 없음) 간단히 조판할 수 있습니다. 상자를 선택하고 적절하게 크기를 조정합니다. 예를 들어:

\define[1]\FitBox
    {\scale[width=10cm,height=5cm,factor=max]{\framed[align=normal]{#1}}}


\starttext
\FitBox{Mary \\ Poppins Sings \\ Supercalifragilisticexpialidocious}

\FitBox{A \\ B \\ C \\ D \\ E \\ F \\ G \\ H \\ I \\ J \\ K \\ L \\ M \\ N}

\stoptext

관련 정보