On 6/9/2021 7:30 PM, Michael Urban wrote:
I am not especially facile with ConTeXt, and it has been years since I did anything complex with TeX, so I am hoping someone could help me with this. The following is probably not great code, but it shows what I am trying to do. The problems are twofold: a benign problem is that I get underfull hbox errors (\dontcomplain notwithstanding). But the other problem is that with text of a certain size, the final line is much shorter than the others. Is there some clever way to repeatedly typeset the text (e.g., put it in an hbox, measure the width, and repeatedly try .5, .333, .25 of the hbox width until it fits in the allocated space)? How to go about this?
\defineblank[EpigraphDistance][3pt]
\definestartstop[EpigraphText][ style=\ssa, before={\blank[EpigraphDistance] \setupnarrower[left=.25\textwidth,right=0pt] \startnarrower[left,right] \setupalign[flushright,nothyphenated,broad] \dontcomplain \noindent}, after={\stopalignment\stopnarrower \blank[EpigraphDistance] \indenting[next]}]
\long\def\epigraph#1#2#3{% \startEpigraphText #1 \par \stopEpigraphText \ifx\hfuzz#3\hfuzz \rightaligned{\ssa\sl --- #2} \else \rightaligned{\ssa\sl --- #2, \tf\ssa\symbol[leftquote]#3\symbol[rightquote]} \fi }
\starttext Testing epigraph
\epigraph{% para \quotation{My birthday-present!} he whispered to himself, as he had often done in the endless dark days. \quotation{That's what we\unknown} }{J.R.R. Tolkien}{The Hobbit}
That was an epigraph.
\stoptext I assume that when you see some trickery that you can do the rest yourself.
\starttext First we typeset the box ad one line and then flush it in a vertical box (paragraph). We can of course also typeset each time. When we're okay with the fit (naturalwidth == less than max width) we quit. We can assume that spaces have enough stretch to deal with the close fit. \protected\def\makeitfit#1#2#3% {\begingroup \hsize#1\relax \setbox\scratchboxone\hbox\bgroup#3\egroup \doloop {% \setbox\scratchboxtwo\vbox\bgroup\unhcopy\scratchboxone\egroup \scratchdimenone\boxlinenw\scratchboxtwo\boxlines\scratchboxtwo \scratchdimentwo\boxlinewd\scratchboxtwo\boxlines\scratchboxtwo \ifdim\scratchdimenone<\scratchdimentwo \advance\hsize-#2\relax \else \unhbox\scratchboxone \exitloop \fi }% \endgroup} This variant is more neat as it returns the to b eused width. It doesn't flush the content. \protected\def\guessbestwidth#1#2#3% no \protected when no \dimexpr {\beginlocalcontrol \begingroup \hsize#1\relax \setbox\scratchboxone\hbox\bgroup#3\egroup \doloop {% \setbox\scratchboxtwo\vbox\bgroup\unhcopy\scratchboxone\egroup \scratchcounter\boxlines\scratchboxtwo % n of lines \scratchdimenone\boxlinenw\scratchboxtwo\scratchcounter \scratchdimentwo\boxlinewd\scratchboxtwo\scratchcounter \ifdim\scratchdimenone<\scratchdimentwo \advance\hsize-#2\relax \else \exitloop \fi }% % \normalexpanded{\endgroup\endlocalcontrol\the\hsize}} \normalexpanded{\endgroup\endlocalcontrol\dimexpr\the\hsize\relax}} Here are some tests: \makeitfit{10cm}{1mm}{\input{ward}} \hsize \guessbestwidth{10cm}{1mm}{\input{ward}} \input{ward} \the\guessbestwidth{10cm}{1mm}{\input{ward}} \stoptext The mechanisms used are relatively simple: - good old tex primitives - few scratch registers - a loop that we quit - the boxlines mechanism discussed in some manual (i admit that i already had forgotten about it) - and in the last example some local processing magic which makes sure that all these calculations are unseen One can then of course try to make it more compact: \protected\def\guessbestwidth#1#2#3% {\beginlocalcontrol \begingroup \hsize#1\relax \setbox\scratchboxone\hbox\bgroup#3\egroup \doloop {% \setbox\scratchboxtwo\vbox\bgroup\unhcopy\scratchboxone\egroup \scratchcounter\boxlines\scratchboxtwo \ifdim\boxlinenw\scratchboxtwo\scratchcounter<\boxlinewd\scratchboxtwo\scratchcounter \advance\hsize-#2\relax \else \exitloop \fi }% \normalexpanded{\endgroup\endlocalcontrol\dimexpr\the\hsize\relax}} And of course you now need to wikify it. Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------