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
-
___
If your question is of interest to others as well, please add an entry to the
Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage : http://www.pragma-ade.nl / http://context.aanh