diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl | 2430 |
1 files changed, 2430 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl b/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl new file mode 100644 index 00000000000..d116113399d --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl @@ -0,0 +1,2430 @@ +%D \module +%D [ file=spac-ver, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Vertical, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Spacing Macros / Vertical} + +\unprotect + +\registerctxluafile{spac-ver}{autosuffix,optimize} + +% todo: use usernodes ? + +% todo: itemize : intro ... only when there is one or two lines preceding and then +% keep these together i.e. \blank[intro] + +% Isn't it about time to get rid of topskip i.e. make it equivalent to +% \openstrutheight so that we can remove delta code. +% +% There might be more namespace protection. + +%D There are two ways to influence the interline spacing. The most general and often +%D most consistent way is using +%D +%D \showsetup{setupinterlinespace} +%D +%D For instance +%D +%D \starttyping +%D \setupinterlinespace[line=2.8ex] +%D \stoptyping +%D +%D This setting adapts itself to the bodyfontsize, while for instance saying +%D +%D \starttyping +%D \setupinterlinespace[line=12pt] +%D \stoptyping +%D +%D sets things fixed for all sizes, which is definitely not what we want. Therefore +%D one can also say: +%D +%D \starttyping +%D \definebodyfontenvironment[9pt][interlinespace=11pt] +%D \stoptyping +%D +%D One can still use \type {\setupinterlinespace} (without arguments) to set the +%D interline space according to the current font, e.g. a \type {\bfa}. + +% will be cleaned up but it will stay messy because we accept so +% many variants + +\newif\iflocalinterlinespace + +\newskip \s_spac_vspacing_temp \s_spac_vspacing_temp\bigskipamount + +\mutable\def\skipfactor {.75} +\mutable\def\skipgluefactor{.25} + +\permanent\def\normalskipamount + {\openlineheight + \ifgridsnapping \orelse \ifconditional\c_spac_whitespace_flexible + \s!plus \skipgluefactor\openlineheight + \s!minus\skipgluefactor\openlineheight + \fi + \relax} + +\ifdefined\bodyfontinterlinespace \else + \let\bodyfontinterlinespace\empty +\fi + +\permanent\protected\def\presetnormallineheight % each bodyfont + {\edef\normallineheight{\interlinespaceparameter\c!line}% + \iflocalinterlinespace \else + \edef\m_spac_normallineheight{\bodyfontinterlinespace}% + \ifempty\m_spac_normallineheight \else + \let\normallineheight\m_spac_normallineheight + \fi + \fi} + +\permanent\protected\def\setupspecifiedinterlinespace[#1]% + {\setupcurrentinterlinespace[#1]% + \spac_linespacing_setup_specified_interline_space} + +\def\spac_linespacing_setup_specified_interline_space + {\edef\strutheightfactor {\interlinespaceparameter\c!height }% + \edef\strutdepthfactor {\interlinespaceparameter\c!depth }% + \edef\minimumstrutheight {\interlinespaceparameter\c!minheight}% + \edef\minimumstrutdepth {\interlinespaceparameter\c!mindepth }% + \edef\minimumlinedistance {\interlinespaceparameter\c!distance }% + \edef\normallineheight {\interlinespaceparameter\c!line }% + \edef\topskipfactor {\interlinespaceparameter\c!top }% + \edef\maxdepthfactor {\interlinespaceparameter\c!bottom }% + \edef\m_spac_vertical_baseline_stretch_factor{\interlinespaceparameter\c!stretch}% + \edef\m_spac_vertical_baseline_shrink_factor {\interlinespaceparameter\c!shrink }% + % often topskip does more bad than good, so: + \ifx\topskipfactor\v!height + \let\topskipfactor\strutheightfactor + \fi + \setfontparameters % redundant, can be \setstrut, test first + \updateraggedskips} % yes indeed + +\installcorenamespace{interlinespacerelative} + +\aliased\let\setrelativeinterlinespace \relax % used elsewhere +\mutable\let\currentrelativeinterlinespace\empty + +\defcsname\??interlinespacerelative\v!on \endcsname{\oninterlineskip} +\defcsname\??interlinespacerelative\v!off \endcsname{\offinterlineskip} +\defcsname\??interlinespacerelative\v!reset\endcsname{\enforced\let\currentrelativeinterlinespace\empty + \enforced\let\setrelativeinterlinespace\relax + \setfontparameters} +\defcsname\??interlinespacerelative\v!auto \endcsname{\enforced\let\setrelativeinterlinespace\spac_linespacing_set_relative_interlinespace} + +\def\spac_linespacing_set_specified_relative_interlinespace#1% fragile? + {\doifelsedimenstring{#1}% + {\setupspecifiedinterlinespace[\c!line=#1]}% + {\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}% + \spacing\currentrelativeinterlinespace}} + +\permanent\protected\def\setuprelativeinterlinespace[#1]% + {\processcommalist[#1]\spac_linespacing_setup_relative_interlinespace} + +\def\spac_linespacing_setup_relative_interlinespace#1% + {\ifcsname\??interlinespacerelative#1\endcsname + \lastnamedcs + \else + \spac_linespacing_set_specified_relative_interlinespace{#1}% + \fi} + +\permanent\protected\def\spac_linespacing_set_relative_interlinespace + {\ifempty\currentrelativeinterlinespace\else + \spacing\currentrelativeinterlinespace + \fi} + +\protected\def\spac_linespacing_setup_use + {\ifcsname\namedinterlinespacehash\m_spac_interlinespace\s!parent\endcsname + \let\currentinterlinespace\m_spac_interlinespace + \spac_linespacing_setup_specified_interline_space + % \else + % we only support named interlinespaces + \fi} + +\permanent\protected\def\useinterlinespaceparameter#1% see footnotes + {\edef\m_spac_interlinespace{#1\c!interlinespace}% + \ifempty\m_spac_interlinespace \else + \spac_linespacing_setup_use + \fi} + +\newtoks\everysetupglobalinterlinespace +\newtoks\everysetuplocalinterlinespace + +\newconditional\interlinespaceisset + +\installcorenamespace{interlinespace} + +\installcommandhandler \??interlinespace {interlinespace} \??interlinespace + +\installmacrostack\currentinterlinespace + +\permanent\overloaded\tolerant\protected\def\setupinterlinespace[#1]% + {\ifarguments + \settrue\interlinespaceisset + \spac_linespacing_synchronize_local + \else + \settrue\interlinespaceisset + \ifcsname\namedinterlinespacehash{#1}\s!parent\endcsname + \edef\currentinterlinespace{#1}% + \spac_linespacing_setup_specified_interline_space + %\dosetupspecifiedinterlinespaceindeed + \else + \spac_linespacing_setup_specified_or_relative[#1]% + \fi + \fi} + +\def\spac_linespacing_setup_specified_or_relative[#1]% + {\doifelseassignment{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]% + \the\iflocalinterlinespace\everysetuplocalinterlinespace\else\everysetupglobalinterlinespace\fi} + +\def\spac_linespacing_synchronize_local % adapts to the font + {\localinterlinespacetrue + \setfontparameters + \updateraggedskips % funny one here + \the\everysetuplocalinterlinespace + \localinterlinespacefalse} + +\permanent\protected\def\dosetupcheckedinterlinespace#1% often a chain + {\edef\p_spac_checked_interlinespace{#1}% + \ifempty\p_spac_checked_interlinespace + \spac_linespacing_synchronize_local + \orelse\ifcsname\namedinterlinespacehash\p_spac_checked_interlinespace\s!parent\endcsname % we could have a \s!check + \push_macro_currentinterlinespace + \let\currentinterlinespace\p_spac_checked_interlinespace + \spac_linespacing_setup_specified_interline_space % \dosetupspecifiedinterlinespaceindeed + \iflocalinterlinespace + \the\everysetuplocalinterlinespace + \else + \localinterlinespacetrue + \the\everysetuplocalinterlinespace + \localinterlinespacefalse + \fi + \pop_macro_currentinterlinespace + \else + \normalexpanded{\noexpand\doifelseassignment{\p_spac_checked_interlinespace}% + \setupspecifiedinterlinespace\setuprelativeinterlinespace[\p_spac_checked_interlinespace]}% + \iflocalinterlinespace + \the\everysetuplocalinterlinespace + \else + \localinterlinespacetrue + \the\everysetuplocalinterlinespace + \localinterlinespacefalse + \fi + \fi} + +\permanent\protected\def\setuplocalinterlinespace[#1]% + {\localinterlinespacetrue + \push_macro_currentinterlinespace + \setupinterlinespace[#1]% + \pop_macro_currentinterlinespace + \localinterlinespacefalse} + +\aliased\let\switchtointerlinespace\setuplocalinterlinespace + +%D Helpers + +\newskip \s_spac_lastskip +\newdimen\d_spac_prevdepth +\newcount\c_spac_spacefactor +\newdimen\d_spac_prevcontent % set by lua + +% \permanent\overloaded\protected\def\removelastskip +% {\ifvmode\ifzeropt\lastskip\else\vskip-\lastskip\fi\fi} + +\permanent\def\doifoutervmode + {\unless\ifvmode + \expandafter\gobbleoneargument + \orelse\ifinner + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\permanent\protected\def\dosomebreak#1% should be replaced by something \blank + {\doifoutervmode + {\s_spac_lastskip\lastskip + \removelastskip + #1\relax + \ifzeropt\s_spac_lastskip + % avoid interference with footnotes + \else + \vskip\s_spac_lastskip + \fi}} + +\permanent\protected\def\packed + {\nointerlineskip} + +\permanent\protected\def\godown[#1]% + {\relax + \ifhmode\endgraf\fi + \ifvmode\nointerlineskip\vskip#1\relax\fi} + +\permanent\protected\def\smallskip{\vskip\smallskipamount} +\permanent\protected\def\medskip {\vskip\medskipamount} +\permanent\protected\def\bigskip {\vskip\bigskipamount} + +\permanent\protected\def\smallbreak + {\par + \ifvmode\ifdim\lastskip<\smallskipamount + \removelastskip + \penalty-\plusfifty + \smallskip + \fi\fi} + +\permanent\protected\def\medbreak + {\par + \ifvmode\ifdim\lastskip<\medskipamount + \removelastskip + \penalty-\plusonehundred + \medskip + \fi\fi} + +\permanent\protected\def\bigbreak + {\par + \ifvmode\ifdim\lastskip<\bigskipamount + \removelastskip + \penalty-\plustwohundred + \bigskip + \fi\fi} + +\permanent\protected\def\break {\penalty-\plustenthousand} % can be hmode or vmode +\permanent\protected\def\nobreak {\penalty \plustenthousand} % can be hmode or vmode +\permanent\protected\def\allowbreak{\penalty \zerocount} % can be hmode or vmode + +\permanent\protected\def\goodbreak {\par\ifvmode\penalty-\plusfivehundred\relax\fi} % forces vmode +\permanent\protected\def\filbreak {\par\ifvmode\vfil\penalty-\plustwohundred\vfilneg\fi} % forces vmode + +%D Made slightly more readable: + +\permanent\protected\def\vglue {\afterassignment\spac_helpers_vglue_indeed\s_spac_lastskip=} +\permanent\protected\def\hglue {\afterassignment\spac_helpers_hglue_indeed\s_spac_lastskip=} +\permanent\protected\def\topglue{\par\ifvmode\nointerlineskip\vglue-\topskip\vglue\fi} + +\def\spac_helpers_vglue_indeed + {\par + \ifvmode + \d_spac_prevdepth\prevdepth + \hrule\s!height\zeropoint + \nobreak + \vskip\s_spac_lastskip + \prevdepth\d_spac_prevdepth + \fi} + +\def\spac_helpers_hglue_indeed + {\dontleavehmode + \c_spac_spacefactor\spacefactor + \vrule\s!width\zeropoint + \nobreak + \hskip\s_spac_lastskip + \spacefactor\c_spac_spacefactor} + +%D We adapt plain's \type {\removelastskip} a bit: + +\pushoverloadmode + +\permanent\overloaded\protected\def\removelastskip % also in supp-box + {\ifvmode\ifzeropt\lastskip\else\vskip-\lastskip\fi\fi} + +\popoverloadmode + +% The whitespace handler. We could cache settings but normally there are not +% that many in a set. + +\installcorenamespace{whitespacemethod} + +\newskip \s_spac_whitespace_parskip \s_spac_whitespace_parskip\zeropoint +\newconditional\c_spac_whitespace_flexible \settrue\c_spac_whitespace_flexible +\newconstant \c_spac_whitespace_grid_mode % option in layout / 1=permit_half_lines + +%def\v_spac_whitespace_current{\zeropoint} +\let\v_spac_whitespace_current\v!none + +\permanent\tolerant\protected\def\setupwhitespace[#1]% + {\ifarguments + \spac_whitespace_setup_nop + \orelse\iftok{#1}\emptytoks + \spac_whitespace_setup_nop + \else + \edef\v_spac_whitespace_current{#1}% + \spac_whitespace_setup + \fi} + +\permanent\protected\def\spac_whitespace_setup_nop + {\ifx\v_spac_whitespace_current\v!none\else + \spac_whitespace_setup + \fi} + +\aliased\let\synchronizewhitespace\spac_whitespace_setup_nop + +\def\spac_whitespace_setup % quick test for no list + {\ifcsname\??whitespacemethod\v_spac_whitespace_current\endcsname + \lastnamedcs + \else + \expandafter\processcommalist\expandafter[\v_spac_whitespace_current]\spac_whitespace_setup_method % can be raw + \fi\relax + \ifgridsnapping + \spac_whitespace_setup_grid + \else + \spac_whitespace_setup_normal + \fi + \parskip\s_spac_whitespace_parskip} + +\def\spac_whitespace_setup_normal + {\ifconditional\c_spac_whitespace_flexible \else + \s_spac_whitespace_parskip\plusone\s_spac_whitespace_parskip + \fi} + +\def\spac_whitespace_setup_grid + {\setfalse\c_spac_whitespace_flexible + \ifdim\s_spac_whitespace_parskip>\zeropoint + \s_spac_whitespace_parskip + \ifcase\c_spac_whitespace_grid_mode + \baselineskip + \or + \ifdim\scratchdimen=\baselineskip % maybe range + \baselineskip + \else + \numexpr\s_spac_whitespace_parskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax + \fi + \else + \baselineskip + \fi + \fi} + +\permanent\protected\def\installwhitespacemethod#1#2% + {\defcsname\??whitespacemethod#1\endcsname{#2}} + +\installwhitespacemethod \v!fix {} +\installwhitespacemethod \v!fixed {\setfalse\c_spac_whitespace_flexible} +\installwhitespacemethod \v!flexible {\settrue \c_spac_whitespace_flexible} + +\installwhitespacemethod \v!line {\s_spac_whitespace_parskip \baselineskip} +\installwhitespacemethod \v!halfline {\s_spac_whitespace_parskip .5\baselineskip} +\installwhitespacemethod \v!quarterline {\s_spac_whitespace_parskip.25\baselineskip} +\installwhitespacemethod \v!none {\s_spac_whitespace_parskip \zeropoint} +\installwhitespacemethod \v!big {\s_spac_whitespace_parskip \bigskipamount} +\installwhitespacemethod \v!medium {\s_spac_whitespace_parskip \medskipamount} +\installwhitespacemethod \v!small {\s_spac_whitespace_parskip \smallskipamount} + +\installwhitespacemethod \s!default {\spac_whitespace_setup_nop} % also covers none + +\def\spac_whitespace_setup_method#1% + {\ifcsname\??whitespacemethod#1\endcsname + \lastnamedcs + \else + \s_spac_whitespace_parskip#1\fi + \relax} + +\permanent\protected\def\forgetparskip + {\s_spac_whitespace_parskip\zeropoint + \parskip\zeropoint + \let\v_spac_whitespace_current\v!none} + +\appendtoks + \forgetparskip +\to \everyforgetall + +% \installwhitespacemethod \s!unknown {\s_spac_whitespace_parskip\commalistelement\relax} +% +% \def\spac_whitespace_setup_method#1% +% {\csname\??whitespacemethod\ifcsname\??whitespacemethod#1\endcsname#1\else\s!unknown\endcsname\relax} + +\permanent\protected\def\nowhitespace{\directcheckedvspacing\v!nowhite} % {\vspacing[\v!nowhite]} +\permanent\protected\def\whitespace {\directcheckedvspacing\v!white} % {\vspacing[\v!white]} + +\setupwhitespace + [\v!none] + +% Packed: + +% todo: when packed blocks blank, we need to enable forced + +\newconditional\c_spac_packed_blank \settrue\c_spac_packed_blank +\newcount \c_spac_packed_level + +\permanent\tolerant\protected\def\startpacked[#1]% + {\global\advance\c_spac_packed_level\plusone + \par + \ifnum\c_spac_packed_level=\plusone \ifvmode + \begingroup + \whitespace % not combined + \directcheckedvspacing\v!disable % \blank[\v!disable]% or \inhibitblank + \doifelse{#1}\v!blank\settrue\setfalse\c_spac_packed_blank + \setupwhitespace[\v!none]% or \forgetparskip + \fi \fi} + +\permanent\protected\def\stoppacked + {\par + \ifnum\c_spac_packed_level=\plusone \ifvmode + \endgroup + \fi \fi + \global\advance\c_spac_packed_level\minusone} + +\permanent\protected\def\startunpacked + {\directdefaultvspacing % \blank + \begingroup} + +\permanent\protected\def\stopunpacked + {\endgroup + \directdefaultvspacing}% \blank} + +% \prevdepth crosses pageboundaries! +% +% todo: a version that works ok inside a box + +% global : outer hsize + keep skips +% local : inner hsize + reset skips + +\installcorenamespace{linesaround} + +\let\spac_lines_vbox\vbox + +\installtextracker + {linecorrection.boxes} + {\letfrozen\let\spac_lines_vbox\ruledvbox} + {\letfrozen\let\spac_lines_vbox\vbox} + +\let\v_spac_lines_around_action_set\relax +\let\m_spac_lines_around \empty + +\newconstant\c_spac_lines_correction_mode + +\setvalue{\??linesaround\v!blank }{\blank} +\letvalue{\??linesaround\empty }\relax +\setvalue{\??linesaround\s!unknown}{\directcheckedvspacing\m_spac_lines_around} % \blank[\m_spac_lines_around]} + +\def\spac_lines_action_around % we used to let this one but it's cleaner this way + {\csname\??linesaround % i.e. do it twice + \ifcsname\??linesaround\m_spac_lines_around\endcsname\m_spac_lines_around\else\s!unknown\fi + \endcsname} + +\permanent\tolerant\protected\def\startlinecorrection [#1]{\spac_lines_start_correction\plusone{#1}} +\permanent\tolerant\protected\def\startlocallinecorrection[#1]{\spac_lines_start_correction\plustwo{#1}} + +\permanent\protected\def\spac_lines_start_correction#1#2% + {\endgraf + \begingroup + \setconstant\c_spac_lines_correction_mode#1% + \edef\m_spac_lines_around{#2}% + \spac_lines_action_around + \d_spac_prevdepth\prevdepth + \spac_lines_initialize_corrections + \offbaselinecorrection % ??? + \setbox\scratchbox\spac_lines_vbox\bgroup + \ifcase\c_spac_lines_correction_mode + % nothing + \or + % global + \or + % local + \setlocalhsize + \hsize\localhsize + \forgetbothskips + \fi + \ignorespaces} + +\permanent\protected\def\spac_lines_stop_correction + {\removeunwantedspaces + \egroup + \ifgridsnapping + \spac_lines_stop_correction_ongrid + \else + \spac_lines_stop_correction_normal + \fi + \endgroup} + +\protected\def\spac_lines_stop_correction_ongrid + {\directcheckedvspacing\v!white % \blank[\v!white]% + \spac_lines_action_around + \snaptogrid\hpack{\box\scratchbox}% + \directcheckedvspacing\v!white + \spac_lines_action_around} + +\protected\def\spac_lines_stop_correction_normal + {\directcheckedvspacing\v!nowhite % \blank[\v!nowhite]% + \ifdim\parskip>\zeropoint + % too fuzzy otherwise + \else + % doesn't like whitespace + \ifdim\d_spac_prevdepth<\maxdimen + \unless\ifdim\d_spac_prevdepth<\zeropoint + \ifdim\d_spac_prevdepth<\strutdp \relax + \pushlastnode + \ifdim\d_spac_prevdepth>\zeropoint + \kern-\d_spac_prevdepth + \fi + \kern\strutdp + \prevdepth\strutdp + \poplastnode + \fi + \fi + \fi + \fi + \ifdim\pagegoal<\maxdimen + % \blank[\v!white,\the\d_spac_lines_correction_before]% \blank[\v!white]\dotopbaselinecorrection + \directcheckedvspacing{\v!white,\the\d_spac_lines_correction_before}% \blank[\v!white]\dotopbaselinecorrection + \fi + \nointerlineskip % new + \noindent % not \dontleavehmode ! + \ifcase\c_spac_lines_correction_mode + % nothing + \or + % global + \hskip-\leftskip % more tricky would be hangindent so we ignore that one + \or + % local + \fi + \box\scratchbox + \endgraf + % + % eventually i'll get it right ... (i also need to check all whitespace code elsewhere) + % + % \blank[\the\d_spac_lines_correction_after]% \dobotbaselinecorrection + % \directcheckedvspacing{\the\d_spac_lines_correction_after}% \dobotbaselinecorrection + \directcheckedvspacing{\v!white,\the\d_spac_lines_correction_after}% \dobotbaselinecorrection + % \allowbreak % new, otherwise problems when many in a row + \prevdepth\strutdp + \spac_lines_action_around} + +\aliased\let\stoplinecorrection \spac_lines_stop_correction +\aliased\let\stoplocallinecorrection\spac_lines_stop_correction + +% todo: + +\permanent\protected\def\correctwhitespace + {\dowithnextboxcs\correctwhitespacefinish\vbox} + +\permanent\protected\def\correctwhitespacefinish + {\startbaselinecorrection + \flushnextbox + \stopbaselinecorrection} + +\permanent\protected\def\verticalstrut {\vpack{\hsize\zeropoint\forgetall\strut}} +\permanent\protected\def\horizontalstrut{\hpack {\strut}} + +%D Here follow some presets related to interline spacing and therefore also struts. +%D The values 2.8, 0.07, 0.72 and 0.28 originate in \INRSTEX, a package that we used +%D a while after we decided that \LATEX\ was not flexible enough. After that +%D \CONTEXT\ evolved, from some wrapper code around (old) \LATEX\ (on a floppy +%D disk), to using modules from \INRSTEX\ (which also fit on a floppy) and finally +%D all written from scratch. I simply didn't understand all that \TEX\ code at that +%D time, and it was easier to figure it out myself. But \unknown\ some settings +%D stayed, as the height|/|depth ratios, and they never proved to be bad ones! The +%D same is true for the font size relations. + +%D \starttabulate +%D \NC \type {\lineheight} \NC the height of a line \NC \NR +%D \NC \type {\spacing{number}} \NC adapting the interline space \NC \NR +%D \NC \type {\normalbaselines} \NC initialize the interline spacing \NC \NR +%D \NC \type {\setstrut} \NC initialize \type {\strut} \NC \NR +%D \NC \type {\setnostrut} \NC disable the \type {\strut}, \type {\endstrut}, \type {\begstrut} \NC \NR +%D \NC \type {\setteststrut} \NC initialize the visual \type {\strut} \NC \NR +%D \NC \type {\resetteststrut} \NC disable the visual \type {\strut} \NC \NR +%D \NC \type {\setfontparameters} \NC synchronize parameters with foints \NC \NR +%D \stoptabulate +%D +%D \unknown\ and many more (this is a decades old list). +%D +%D The lineheight is the sum of the height and depth of \type {strut}, which is +%D an invisible blob that can be used to enforce the proper dimensions. +%D +%D Such a blob, when placed at the beginning of a paragraph can have side effects +%D that can be prevented with \type {\dontleavehmode}. Never use \type +%D {\leavevmode}! + +\newdimen\strutdimen +\newdimen\lineheight +\newdimen\openlineheight +\newdimen\openstrutheight +\newdimen\openstrutdepth +\newdimen\topskipgap + +\newdimen\strutheight +\newdimen\strutdepth +\newdimen\struttotal +\newdimen\strutwidth + +\let\m_spac_vertical_baseline_stretch_factor \zerocount +\let\m_spac_vertical_baseline_shrink_factor \zerocount + +\mutable\def\strutheightfactor {.72} +\mutable\def\strutdepthfactor {.28} +\mutable\def\baselinefactor {2.8} +\mutable\def\topskipfactor {1.0} +\mutable\def\maxdepthfactor {0.5} + +\mutable\def\minimumstrutheight {\zeropoint} +\mutable\def\minimumstrutdepth {\zeropoint} + +\mutable\def\normallineheight {\baselinefactor\exheight} +\mutable\def\minimumlinedistance {\lineskip} + +\mutable\let\spacingfactor \plusone + +\mutable\def\systemtopskipfactor {\topskipfactor} +\mutable\def\systemmaxdepthfactor{\maxdepthfactor} + +\ifdefined\globalbodyfontsize \else + \newdimen\globalbodyfontsize + \globalbodyfontsize=12pt +\fi + +\ifdefined\normalizedbodyfontsize \else + \def\normalizedbodyfontsize{12pt} +\fi + +\permanent\protected\def\topskipcorrection + {\simpletopskipcorrection + \vskip-\struttotal + \verticalstrut} + +\permanent\protected\def\simpletopskipcorrection + {\ifdim\topskip>\openstrutheight + % == \vskip\topskipgap + \vskip\topskip + \vskip-\openstrutheight + \fi} + +\permanent\protected\def\settopskip % the extra test is needed for the lbr family + {\topskip + \ifgridsnapping + \zeropoint + \else + \systemtopskipfactor\globalbodyfontsize + \ifcase\bottomraggednessmode % ragged bottom + \s!plus5\globalbodyfontsize + \fi + \fi + %\relax + \topskipgap\topskip + \advance\topskipgap -\openstrutheight\relax + \ifdim\minimumstrutheight>\zeropoint + \ifdim\topskip<\minimumstrutheight + \topskip\minimumstrutheight\relax + \fi + \else + \ifdim\topskip<\strutheightfactor\openlineheight + \topskip\strutheightfactor\openlineheight\relax + \fi + \fi} + +\permanent\protected\def\setmaxdepth + {\maxdepth\systemmaxdepthfactor\globalbodyfontsize} + +\newskip \usedbaselineskip % These used to be \normal... but that isn't pretty +\newskip \usedlineskip % in the token interface, so thes few now have new +\newdimen\usedlineskiplimit % names. They are public but not really user commands. + +\permanent\protected\def\normalbaselines + {\baselineskip \usedbaselineskip + \lineskip \usedlineskip + \lineskiplimit\usedlineskiplimit} + +\permanent\protected\def\flexiblebaselines + {\baselineskip \usedbaselineskip + \lineskip 1\usedlineskip \s!plus 1\s!fill + \lineskiplimit\usedlineskiplimit} + +\permanent\protected\def\setnormalbaselines % used in overload + {\ifdim\normallineheight>\zeropoint + \lineheight\normallineheight + \fi + \openlineheight\spacingfactor\lineheight + \openstrutheight \ifdim\minimumstrutheight>\zeropoint + \minimumstrutheight % new + \else + \strutheightfactor\openlineheight + \fi + \openstrutdepth \ifdim\minimumstrutdepth>\zeropoint + \minimumstrutdepth % new + \else + \strutdepthfactor \openlineheight + \fi + \ifdim\dimexpr\minimumstrutdepth+\minimumstrutheight\relax>\zeropoint + \openlineheight\dimexpr\openstrutheight+\openstrutdepth\relax % new + \fi + \usedbaselineskip\openlineheight + \ifgridsnapping\else + \s!plus \m_spac_vertical_baseline_stretch_factor\openlineheight + \s!minus\m_spac_vertical_baseline_shrink_factor \openlineheight + \fi + \usedlineskip\minimumlinedistance\relax % \onepoint\relax + \usedlineskiplimit\zeropoint\relax + \normalbaselines} + +\permanent\protected\def\spacing#1% vertical + {\ifgridsnapping + \let\spacingfactor\plusone + \else + \permanent\edef\spacingfactor{#1}% + \fi + \edef\systemtopskipfactor {\thewithoutunit\dimexpr#1\dimexpr\topskipfactor \points}% + \edef\systemmaxdepthfactor{\thewithoutunit\dimexpr#1\dimexpr\maxdepthfactor\points}% + \setnormalbaselines + \setstrut} + +% \protected\def\forgetverticalstretch % \forgetspacing +% {\spacing\plusone} + +\permanent\protected\def\forgetverticalstretch + {\let\spacingfactor \plusone + \let\systemtopskipfactor \topskipfactor + \let\systemmaxdepthfactor\maxdepthfactor + \setnormalbaselines + \setstrut} + +\appendtoks + \forgetverticalstretch +\to \everyforgetall % needed in otr + +%D Sometimes one needs to freeze the interlinespacing +%D +%D \starttyping +%D \rm \saveinterlinespace .... {\ss \restoreinterlinespace .... \endgraf} +%D \stoptyping + +\aliased\let\restoreinterlinespace\relax + +\permanent\protected\def\saveinterlinespace + {\enforced\permanent\protected\edef\restoreinterlinespace + {\lineheight \the\lineheight + \openstrutheight \the\openstrutheight + \openstrutdepth \the\openstrutdepth + \openlineheight \the\openlineheight + \usedbaselineskip \the\usedbaselineskip + \usedlineskip \the\usedlineskip + \usedlineskiplimit \the\usedlineskiplimit + \noexpand\def\noexpand\normallineheight{\the\dimexpr\normallineheight}% + \noexpand\normalbaselines}} + +%D This is the plain definition: +%D +%D \starttyping +%D \def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi} +%D \stoptyping +%D +%D which could be: +%D +%D \starttyping +%D \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox} +%D \stoptyping +%D +%D But we do things differently. + +\newbox\strutbox + +\setbox\strutbox\hpack{\vrule\s!height8.5pt\s!depth3.5pt\s!width\zeropoint} % just a start + +% \permanent\protected\def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox} +% +% \protected\def\strut +% {\relax +% \ifmmode\copy\else\dontleavehmode\unhcopy\fi\strutbox} +% +% \aliased\let\normalstrut\strut + +%D The double \type {\hbox} construction enables us to backtrack boxes. + +\overloaded\let\strutht\undefined \newdimen\strutht +\overloaded\let\strutdp\undefined \newdimen\strutdp + +\permanent\protected\def\setstrut + {\ifgridsnapping + \setstrutgridyes + \else + \setstrutgridnop + \fi} + +\permanent\protected\def\setstrutgridyes + {\strutht\spacingfactor\dimexpr + \ifdim\minimumstrutheight>\zeropoint + \minimumstrutheight + \else + \strutheightfactor\dimexpr\normallineheight + \fi + \relax + \strutdp\dimexpr + \ifdim\minimumstrutdepth>\zeropoint + \minimumstrutdepth + \else + \normallineheight-\strutht + \fi + \relax + \dosetstrut} + +\permanent\protected\def\setstrutgridnop + {\strutht\spacingfactor\dimexpr + \ifdim\minimumstrutheight>\zeropoint + \minimumstrutheight + \else + \strutheightfactor\dimexpr\normallineheight + \fi + \relax + \strutdp\spacingfactor\dimexpr + \ifdim\minimumstrutdepth>\zeropoint + \minimumstrutdepth + \else + \strutdepthfactor\dimexpr\normallineheight + \fi + \relax + \dosetstrut} + +\permanent\protected\def\setcharstrut#1% + {\setbox\strutbox\hbox{#1}% no \hpack, in case we have smallcaps + \strutht\ht\strutbox + \strutdp\dp\strutbox + \dosetstrut} + +\permanent\protected\def\settightstrut + {\setcharstrut{(}} + +\permanent\protected\def\setfontstrut + {\setcharstrut{(gplQT}} + +\permanent\protected\def\setcapstrut% could be M, but Q has descender + {\setcharstrut{Q}} + +%D Handy for math (used in mathml): + +\permanent\protected\def\charhtstrut + {\begingroup + \setcharstrut{GJY}% + \vrule\s!width\zeropoint\s!depth\zeropoint\s!height\strutht + \endgroup} + +\permanent\protected\def\chardpstrut + {\begingroup + \setcharstrut{gjy}% + \vrule\s!width\zeropoint\s!depth\strutdp\s!height\zeropoint + \endgroup} + +%D Because of all the callbacks in mkiv, we avoid unnecessary boxes ... maybe use an +%D attribute so that we can tag boxes that don't need a treatment; tests with using +%D an attribute so far have shown that it's slower because testing the attribute +%D takes time too. + +\permanent\protected\def\dosetstrut + {\enforced\let\strut\normalstrut + \ifabsnum\dimexpr\strutht+\strutdp-\lineheight\relax<\plustwo + % compensate rounding error /- 1sp to avoid too many + % 1sp baselineskips in for instance verbatim + % \strutht\dimexpr\lineheight-\strutdp\relax + % better: + \strutdp\dimexpr\lineheight-\strutht\relax + \struttotal\lineheight + \else + \struttotal\dimexpr\strutht+\strutdp\relax + \fi + \strutheight\strutht + \strutdepth \strutdp + \ifdim\strutwidth=\zeropoint + \spac_struts_set_hide + \else + \spac_struts_set_vide + \fi} + +\def\spac_struts_set_hide + {\setbox\strutbox\hpack + {\vrule + \s!width \zeropoint + \s!height\strutht + \s!depth \strutdp}} + +\newconstant\c_strut_visual_mode + +\def\spac_struts_set_vide + {\setbox\strutbox\hpack % at some time this extra wrapping was needed + {\spac_struts_vide_hbox to \zeropoint + {\ifcase\c_strut_visual_mode + \spac_struts_black + \or + \spac_struts_color + \else + \spac_struts_black + \fi}}} + +\def\spac_struts_black + {\vrule + \s!width \strutwidth + \s!height\strutht + \s!depth \strutdp + \hss} + +\def\spac_struts_color + {\hss % new, will be option + \scratchwidth.1\struthtdp + \begingroup + \directcolor[f:b:t]% + \vrule + \s!width \scratchwidth + \s!height\strutht + \s!depth \strutdp + \kern-\scratchwidth + \vrule + \s!width \scratchwidth + \s!height\zeropoint + \s!depth \strutdp + \endgroup + \kern-.625\scratchwidth + \vrule + \s!width .25\scratchwidth + \s!height\strutht + \s!depth \strutdp + \hss} + +\let\spac_struts_vide_hbox\hbox % overloaded in trac-vis.mkiv + +%D The dimen \type {\struttotal} holds the exact size of the strut; occasionally a +%D one scaled point difference can show up with the lineheight. This is more +%D efficient (less callbacks): + +\newbox\b_spac_struts_empty \setbox\b_spac_struts_empty\emptyhbox + +\def\spac_struts_set_hide + {\setbox\strutbox\copy\b_spac_struts_empty + \ht\strutbox\strutht + \dp\strutbox\strutdp} + +\permanent\protected\def\strut % still callbacks for \hbox{\strut} + {\relax + \dontleavehmode + \copy\strutbox} + +% \protected\def\strut % slightly faster +% {\relax +% \ifmmode\copy\else\dontleavehmode\unhcopy\fi\strutbox} + +\aliased\let\normalstrut\strut + +\permanent\protected\def\halfstrut + {\relax + \dontleavehmode + \begingroup + \setbox\scratchbox\copy\strutbox + \ht\scratchbox\dimexpr\strutht/\plustwo\relax + \dp\scratchbox\dimexpr\strutdp/\plustwo\relax + \box\scratchbox + \endgroup} + +\permanent\protected\def\quarterstrut + {\relax + \dontleavehmode + \begingroup + \setbox\scratchbox\copy\strutbox + \ht\scratchbox\dimexpr\strutht/\plusfour\relax + \dp\scratchbox\dimexpr\strutdp/\plusfour\relax + \box\scratchbox + \endgroup} + +\permanent\protected\def\depthstrut + {\relax + \dontleavehmode + \begingroup + \setbox\scratchbox\copy\strutbox + \ht\scratchbox\dimexpr\strutht-\struthtdp/\plustwo\relax % assumes that ht > lineheight/2 + \box\scratchbox + \endgroup} + +\permanent\protected\def\halflinestrut + {\relax + \dontleavehmode + \begingroup + \setbox\scratchbox\copy\strutbox + \ht\scratchbox\dimexpr\strutht-.5\strutht-.5\strutdp\relax + \box\scratchbox + \endgroup} + +\permanent\protected\def\noheightstrut + {\relax + \dontleavehmode + \begingroup + \setbox\scratchbox\copy\strutbox + \ht\scratchbox\zeropoint + \box\scratchbox + \endgroup} + +%D Sometimes a capstrut comes in handy +%D +%D \starttabulate[|Tl|l|l|] +%D \NC yes \NC normal strut \NC {\showstruts\setupstrut[yes]\strut} \NC \NR +%D \NC no \NC no strut \NC {\showstruts\setupstrut[no]\strut} \NC \NR +%D \NC kap \NC a capital strut (i.e. Q) \NC {\showstruts\setupstrut[cap]\strut} \NC \NR +%D \NC A B \unknown \NC a character strut (e.g. A) \NC {\showstruts\setupstrut[A]\strut} \NC \NR +%D \NC \NC a normal strut \NC {\showstruts\setupstrut\strut} \NC \NR +%D \stoptabulate +%D +%D Beware: using an unknown value results in char struts. + +\installcorenamespace{struts} + +\permanent\tolerant\protected\def\setupstrut[#1]% + {\edef\m_strut{#1}% + \ifcsname\??struts\m_strut\endcsname + \lastnamedcs + \else + \setcharstrut\m_strut + \fi} + +\permanent\protected\def\synchronizestrut#1% no [] parsing, faster for internal + {\edef\m_strut{#1}% + \ifcsname\??struts\m_strut\endcsname + \lastnamedcs + \else + \setcharstrut\m_strut + \fi} + +\permanent\protected\def\dosynchronizestrut#1% no [] parsing, faster for internal + {\ifcsname\??struts#1\endcsname + \lastnamedcs + \else + \setcharstrut{#1}% + \fi} + +\permanent\protected\def\showstruts % adapts .. is wrong + {\c_strut_visual_mode\zerocount + \setteststrut + \settestcrlf} + +\permanent\protected\def\showcolorstruts % adapts .. is wrong + {\c_strut_visual_mode\plusone + \setteststrut + \settestcrlf} + +\permanent\protected\def\setteststrut + {\strutwidth.8\onepoint + \setstrut} + +\permanent\protected\def\dontshowstruts + {\unsetteststrut + \settestcrlf} + +\permanent\protected\def\unsetteststrut + {\strutwidth\zeropoint + \setstrut} + +\mutable\def\autostrutfactor{1.1} + +\permanent\protected\def\setautostrut + {\begingroup + \setbox\scratchbox\copy\strutbox + \setstrut + \ifdim\strutht>\autostrutfactor\ht\scratchbox + \endgroup \setstrut + \orelse\ifdim\strutdp>\autostrutfactor\dp\scratchbox + \endgroup \setstrut + \else + \endgroup + \fi} + +\newbox\nostrutbox \setbox\nostrutbox\emptyhbox + +\newtoks\everysetnostrut + +\permanent\protected\def\setnostrut + {\the\everysetnostrut} + +\appendtoks + \setbox\strutbox\copy\nostrutbox + \enforced\let\strut \empty + \enforced\let\endstrut\empty + \enforced\let\begstrut\empty +\to \everysetnostrut + +%D When enabled, sigstruts will remove themselves if nothing goes inbetween. For +%D practical reasons we define some boundary characters here. + +\permanent\protected\def\leftboundary {\protrusionboundary\plusone} +\permanent\protected\def\rightboundary {\protrusionboundary\plustwo} +\permanent\protected\def\signalcharacter{\boundary\plusone\char\zerocount\boundary\plustwo} % not the same as strut signals + +\newsignal\d_spac_struts_signal \setfalse\sigstruts + +\permanent\protected\def\begstrut + {\relax\ifcase\strutht + % \ignorespaces % maybe + \else + \spac_struts_beg + \fi} + +\def\spac_struts_beg + {\ifconditional\sigstruts + \spac_struts_beg_signal + \else + \spac_struts_beg_normal + \fi + \ignorespaces} + +\def\spac_struts_beg_signal + {\noindent\horizontalstrut + \penalty\plustenthousand + \hskip-\d_spac_struts_signal + \hskip\d_spac_struts_signal} + +\def\spac_struts_beg_normal + {\boundary\plusone + \strut + %\boundary\plusone + \penalty\plustenthousand + %\boundary\plusone + \hskip\zeropoint} + +\permanent\protected\def\endstrut + {\relax\ifhmode + \ifcase\strutht + % \removeunwantedspaces % maybe + \else + \spac_struts_end + \fi + \fi} + +\def\spac_struts_end + {\ifconditional\sigstruts + \spac_struts_end_signal + \else + \spac_struts_end_normal + \fi} + +\def\spac_struts_end_signal + {\ifdim\lastskip=\d_spac_struts_signal + \unskip + \unskip + \unpenalty + \setbox\scratchbox\lastbox + \else + \penalty\plustenthousand + \hskip\zeropoint + \strut + \fi} + +\def\spac_struts_end_normal + {\removeunwantedspaces + \penalty\plustenthousand + %\boundary\plustwo + \hskip\zeropoint + %\boundary\plustwo + \strut + \boundary\plustwo} + +% unsave: +% +% \def\pseudostrut +% {\bgroup +% \setnostrut +% \normalstrut +% \egroup} +% +% try: +% +% \startchemie +% \chemie[ONE,Z0,SB15,MOV1,SB15,Z0][C,C] +% \stopchemie +% +% so: + +\permanent\protected\def\pseudostrut + {\noindent} % better: \dontleavehmode + +\aliased\let\pseudobegstrut\pseudostrut +\aliased\let\pseudoendstrut\removeunwantedspaces + +\permanent\protected\def\resetteststrut + {\strutwidth\zeropoint + \setstrut} + +\ifdefined\setfontparameters \else + \def\setfontparameters{\the\everybodyfont} +\fi + +%D Keyword based strutting: + +\letcsname\??struts\v!yes \endcsname\setstrut +\letcsname\??struts\v!auto \endcsname\setautostrut +\letcsname\??struts\v!no \endcsname\setnostrut +\letcsname\??struts\v!cap \endcsname\setcapstrut +\letcsname\??struts\v!fit \endcsname\setfontstrut +\letcsname\??struts\v!line \endcsname\setstrut +\letcsname\??struts\s!default\endcsname\setstrut +\letcsname\??struts\empty \endcsname\setstrut + +%D Handy: + +\permanent\def\baselinedistance{\the\lineheight} + +%D We need \type {\normaloffinterlineskip} because the new definition contains an +%D assignment, and |<|don't ask me why|>| this assignment gives troubles in for +%D instance the visual debugger. + +\pushoverloadmode + +\overloaded\permanent\protected\def\offinterlineskip + {\baselineskip-\thousandpoint + \lineskip \zeropoint + \lineskiplimit\maxdimen + % We also need this here now; thanks to taco for figuring that out! + \let\minimumlinedistance\zeropoint} + +\overloaded\permanent\protected\def\nointerlineskip + {\prevdepth-\thousandpoint} + +\aliased\let\normaloffinterlineskip\offinterlineskip % knuth's original + +\popoverloadmode + +%D This is tricky. The prevdepth value is still set to the last one even if there is +%D nothing on the page. The same is true for prevgraf, which doesn't resemble the +%D value on the current page. +%D +%D So, here we kick in a checker but it has to happen after the output group and it +%D only has to be done once (output can trigger itself!). +%D +%D However, prevgraf is somehow bound to hangindent so we can get very nasty side +%D effects. So, in tne end we use our own variable! + +\ifdefined\getnofpreviouslines + % defined public at the lua end +\else + \let\getnofpreviouslines\!!zerocount +\fi + +\protected\def\page_otr_synchronize_page_yes + {\aftergroup\page_otr_synchronize_page_indeed + \global\enforced\let\page_otr_synchronize_page\relax} + +% This has to become an otr method: \s!page_otr_command_synchonize_page + +\protected\def\page_otr_synchronize_page_indeed + {\ifx\currentoutputroutine\s!multicolumn\else\clf_synchronizepage\fi + \global\enforced\let\page_otr_synchronize_page\page_otr_synchronize_page_yes} + +\let\page_otr_synchronize_page\page_otr_synchronize_page_yes + +\appendtoks + \page_otr_synchronize_page +\to \everyaftershipout + +%D My own one: + +\protected\def\spac_helpers_push_interlineskip_yes + {\enforced\edef\oninterlineskip + {\baselineskip \the\baselineskip + \lineskip \the\lineskip + \lineskiplimit\the\lineskiplimit + \noexpand\edef\noexpand\minimumlinedistance{\the\dimexpr\minimumlinedistance}% + \enforced\let\noexpand\offinterlineskip\noexpand\normaloffinterlineskip}} % \noexpand not needed + +\protected\def\spac_helpers_push_interlineskip_nop + {\enforced\let\oninterlineskip\setnormalbaselines} + +\pushoverloadmode + +\overloaded\permanent\protected\def\offinterlineskip + {\ifdim\baselineskip>\zeropoint + \spac_helpers_push_interlineskip_yes + \else + \spac_helpers_push_interlineskip_nop + \fi + \normaloffinterlineskip} + +\permanent\let\oninterlineskip\relax + +\popoverloadmode + +\permanent\protected\def\resetpenalties#1% + {\ifdefined#1% + \frozen#1\minusone + \fi} + +\permanent\protected\def\setpenalties#1#2#3% + {\ifdefined#1% space before #3 prevents lookahead problems, needed when #3=text + \frozen#1\numexpr#2+\plusone\relax\space\doexpandedrecurse{\the\numexpr#2\relax}{ #3}\zerocount\relax + \fi} + +%D \macros +%D {keeplinestogether} +%D +%D Dirty hack, needed in margin content that can run of a page. + +% just before margintexts ... will eventually be done differently in mkiv using +% attributes + +\newcount\c_spac_keep_lines_together + +\aliased\let\restoreinterlinepenalty\relax + +\protected\def\spac_penalties_restore + {\global\enforced\let\restoreinterlinepenalty\relax + \overloaded\global\resetpenalties\interlinepenalties + \global\c_spac_keep_lines_together\zerocount} + +\permanent\protected\def\keeplinestogether#1% + {\ifnum#1>\c_spac_keep_lines_together + \global\c_spac_keep_lines_together#1% + \overloaded\global\setpenalties\interlinepenalties\c_spac_keep_lines_together\plustenthousand + \global\enforced\let\restoreinterlinepenalty\spac_penalties_restore + \fi} + +\immutable\integerdef\defaultdisplaywidowpenalty 50 +\immutable\integerdef\defaultwidowpenalty 2000 % was: 1000 +\immutable\integerdef\defaultclubpenalty 2000 % was: 800 +\immutable\integerdef\defaultbrokenpenalty 100 +\immutable\integerdef\defaultdoublehyphendemerits 10000 +\immutable\integerdef\defaultfinalhyphendemerits 5000 +\immutable\integerdef\defaultadjdemerits 10000 + +\immutable\integerdef\defaultgriddisplaywidowpenalty 0 +\immutable\integerdef\defaultgridwidowpenalty 0 +\immutable\integerdef\defaultgridclubpenalty 0 +\immutable\integerdef\defaultgridbrokenpenalty 0 +\immutable\integerdef\defaultgriddoublehyphendemerits 10000 % always was so +\immutable\integerdef\defaultgridfinalhyphendemerits 5000 % always was so +\immutable\integerdef\defaultgridadjdemerits 10000 % always was so + +\permanent\protected\def\nopenalties + {\frozen\widowpenalty \zerocount + \frozen\clubpenalty \zerocount + \frozen\brokenpenalty \zerocount + \frozen\doublehyphendemerits\zerocount + \frozen\finalhyphendemerits \zerocount + \frozen\adjdemerits \zerocount} + +\permanent\protected\def\setdefaultpenalties + {\directsetup{\systemsetupsprefix\s!default}} + +\startsetups [\systemsetupsprefix\s!reset] + \resetpenalties\widowpenalties + \resetpenalties\clubpenalties + \resetpenalties\interlinepenalties +\stopsetups + +%D We use \directsetup because it's faster and we know there is no csl: + +\startsetups [\systemsetupsprefix\s!default] + + \directsetup{\systemsetupsprefix\s!reset} + + \frozen\widowpenalty \defaultwidowpenalty + \frozen\clubpenalty \defaultclubpenalty + \frozen\displaywidowpenalty \defaultdisplaywidowpenalty + \frozen\brokenpenalty \defaultbrokenpenalty + \frozen\doublehyphendemerits\defaultdoublehyphendemerits + \frozen\finalhyphendemerits \defaultfinalhyphendemerits + \frozen\adjdemerits \defaultadjdemerits + +\stopsetups + +\startsetups [\v!grid] [\systemsetupsprefix\s!default] + + \directsetup{\systemsetupsprefix\s!reset} + + \frozen\widowpenalty \defaultgridwidowpenalty + \frozen\clubpenalty \defaultgridclubpenalty + \frozen\displaywidowpenalty \defaultgriddisplaywidowpenalty + \frozen\brokenpenalty \defaultgridbrokenpenalty + \frozen\doublehyphendemerits\defaultgriddoublehyphendemerits + \frozen\finalhyphendemerits \defaultgridfinalhyphendemerits + \frozen\adjdemerits \defaultgridadjdemerits + +\stopsetups + +%D As an illustration: + +\startsetups [\systemsetupsprefix\v!strict] + + \directsetup{\systemsetupsprefix\s!reset} + + \setpenalties \widowpenalties \plustwo \maxdimen + \setpenalties \clubpenalties \plustwo \maxdimen + \frozen \brokenpenalty \maxdimen + \frozen \doublehyphendemerits \defaultdoublehyphendemerits + \frozen \finalhyphendemerits \defaultfinalhyphendemerits + \frozen \adjdemerits \defaultadjdemerits + +\stopsetups + +\setdefaultpenalties % will happen later in \setuplayout + +%D To be checked: + +\newbox\b_spac_struts_saved + +\permanent\protected\def\savestrut {\setbox\b_spac_struts_saved\copy\strutbox} +\permanent\protected\def\savedstrut{\copy \b_spac_struts_saved} + +%D Good old blank redone: + +%definesystemattribute[kernchars] [public] +\definesystemattribute[skipcategory] [public] +\definesystemattribute[skippenalty] [public] +\definesystemattribute[skiporder] [public] +\definesystemattribute[snapmethod] [public] +\definesystemattribute[snapvbox] [public] +%definesystemattribute[snapcategory] [public] + +% TODO: NAMED SNAPPERS + +\installcorenamespace{gridsnappers} +\installcorenamespace{gridsnapperattributes} +\installcorenamespace{gridsnappersets} + +\newskip \bodyfontlineheight +\newdimen \bodyfontstrutheight +\newdimen \bodyfontstrutdepth + +\newskip \globalbodyfontlineheight % why a skip +\newdimen \globalbodyfontstrutheight +\newdimen \globalbodyfontstrutdepth + +\permanent\def\snappedvboxattribute{\ifgridsnapping attr\snapvboxattribute\c_attr_snapmethod\fi} +\permanent\def\setlocalgridsnapping{\ifgridsnapping \c_attr_snapvbox \c_attr_snapmethod\fi} + +\def\spac_grids_set_local_snapping#1% + {\ifgridsnapping + \doifsomething{#1}% + {\spac_grids_snap_value_set{#1}% + \c_attr_snapvbox\c_attr_snapmethod}% + \fi} + +\def\spac_grids_expand_snapper#1% + {\edef\m_spac_snapper + {\ifempty\m_spac_snapper\else\m_spac_snapper,\fi + \ifcsname\??gridsnappersets#1\endcsname\lastnamedcs\else#1\fi}} + +\permanent\protected\def\installsnapvalues#1#2% + {\let\m_spac_snapper\empty + \rawprocesscommacommand[#2]\spac_grids_expand_snapper + \edef\p_spac_snapper{#1:\m_spac_snapper}% + \ifcsname\??gridsnapperattributes\p_spac_snapper\endcsname + \scratchcounter\lastnamedcs % already defined + \else + \scratchcounter\clf_definesnapmethod{#1}{\m_spac_snapper}% + \edefcsname\??gridsnapperattributes\p_spac_snapper\endcsname{\the\scratchcounter}% + \fi + \edefcsname\??gridsnappers#1\endcsname{\c_attr_snapmethod\the\scratchcounter\relax}% + \letcsname\??gridsnappersets#1\endcsname\m_spac_snapper} + +\permanent\def\theexpandedsnapperset#1{\begincsname\??gridsnappersets#1\endcsname} % only for manuals + +\permanent\protected\def\usegridparameter#1% no checking here + {\edef\m_spac_grid_asked{#1\c!grid}% + \ifempty\m_spac_grid_asked + \c_attr_snapvbox\attributeunsetvalue + \else + \spac_grids_snap_value_set\m_spac_grid_asked + \c_attr_snapvbox\c_attr_snapmethod + \fi} + +\permanent\tolerant\protected\def\definegridsnapping[#1]#*[#2]% + {\installsnapvalues{#1}{#2}} + +\edef\spac_grids_snap_value_reset + {%\gridsnappingfalse + \c_attr_snapmethod\attributeunsetvalue} + +\def\spac_grids_snap_value_set#1% + {%\gridsnappingtrue + \begincsname\??gridsnappers#1\endcsname} + +% maybe: +% +% \def\spac_grids_snap_value_set#1% +% {%\gridsnappingtrue +% \ifcsname\??gridsnappers#1\endcsname +% \lastnamedcs +% \else +% \definegridsnapping[#1][#1]% +% \begincsname\??gridsnappers#1\endcsname +% \fi} + +\def\spac_grids_snap_value_auto#1% + {\ifcsname\??gridsnappers#1\endcsname + \lastnamedcs + \else + \installsnapvalues\s!dummy{#1}% + \csname\??gridsnappers\s!dummy\endcsname + \fi} + +% \installsnapvalues{loose} {\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut} +% \installsnapvalues{normal}{\v!maxdepth:1.0,\v!maxheight:1.0,\v!strut} +% \installsnapvalues{tight} {\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut} + +% none don't enlarge +% halfline enlarge by halfline/halfline +% line enlarge by line/line +% strut enlarge by ht/dp (default) +% first align to top line +% last align to bottom line +% mindepth round depth down +% maxdepth round depth up +% minheight round height down +% maxheight round height up +% local use local interline space +% offset:-3tp vertical shift within box +% bottom:lines +% top:lines +% box centers a box rounded upwards (box:.5 -> tolerance) +% min centers a box rounded downwards +% max centers a box rounded upwards + +%D We're not downward compatible with \MKII ! Not yet in interface file: + +\definegridsnapping[\v!normal] [\v!maxheight,\v!maxdepth,\v!strut] +\definegridsnapping[\v!standard] [\v!maxheight,\v!maxdepth,\v!strut] +\definegridsnapping[\v!yes] [\v!maxheight,\v!maxdepth,\v!strut] + +\definegridsnapping[\v!strict] [\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut] +\definegridsnapping[\v!tolerant] [\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut] +\definegridsnapping[\v!verytolerant] [\v!maxdepth:1.4,\v!maxheight:1.4,\v!strut] + +\definegridsnapping[\v!tolerant:10] [\v!maxdepth:1.1,\v!maxheight:1.1,\v!strut] % 10 pct tolerance +\definegridsnapping[\v!tolerant:20] [\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut] % 20 pct tolerance +\definegridsnapping[\v!tolerant:30] [\v!maxdepth:1.3,\v!maxheight:1.3,\v!strut] % 30 pct tolerance +\definegridsnapping[\v!tolerant:40] [\v!maxdepth:1.4,\v!maxheight:1.4,\v!strut] % 40 pct tolerance + +\definegridsnapping[\v!top] [\v!minheight,\v!maxdepth,\v!strut] +\definegridsnapping[\v!bottom] [\v!maxheight,\v!mindepth,\v!strut] +\definegridsnapping[\v!both] [\v!minheight,\v!mindepth,\v!strut] + +\definegridsnapping[\v!broad] [\v!maxheight,\v!maxdepth,\v!strut,0.8] % maybe 0.85 +\definegridsnapping[\v!fit] [\v!maxheight,\v!maxdepth,\v!strut,1.2] % tight 0.15 + +\definegridsnapping[\v!first] [\v!first] +\definegridsnapping[\v!last] [\v!last] +\definegridsnapping[\v!high] [\v!minheight,\v!maxdepth,\v!none] +\definegridsnapping[\v!one] [\v!minheight,\v!mindepth] +\definegridsnapping[\v!low] [\v!maxheight,\v!mindepth,\v!none] +\definegridsnapping[\v!none] [\v!none] +\definegridsnapping[\v!line] [\v!line] +\definegridsnapping[\v!strut] [\v!strut] +\definegridsnapping[\v!box] [\v!box] +\definegridsnapping[\v!min] [\v!min] +\definegridsnapping[\v!max] [\v!max] + +\definegridsnapping[\v!middle] [\v!maxheight,\v!maxdepth] % used in placement + +\definegridsnapping[\v!math] [\v!maxdepth:1.05,\v!maxheight:1.05,\v!strut] % experimental, maybe 1.1 +\definegridsnapping[\v!math:\v!line] [\v!math,\v!line,\v!split] +\definegridsnapping[\v!math:\v!halfline] [\v!math,\v!halfline,\v!split] +\definegridsnapping[\v!math:-\v!line] [\v!math,-\v!line,\v!split] +\definegridsnapping[\v!math:-\v!halfline][\v!math,-\v!halfline,\v!split] + +\permanent\protected\def\synchronizelocallinespecs + {\bodyfontlineheight \normallineheight + \bodyfontstrutheight\strutht + \bodyfontstrutdepth \strutdp} + +\permanent\protected\def\synchronizegloballinespecs + {\global\globalbodyfontlineheight \normallineheight + \global\globalbodyfontstrutheight\strutht + \global\globalbodyfontstrutdepth \strutdp} + +\appendtoks + \synchronizegloballinespecs + \synchronizelocallinespecs +\to \everysetupglobalinterlinespace + +\appendtoks + \synchronizelocallinespecs +\to \everysetuplocalinterlinespace + +%D We still have to synchronize these: + +\permanent\protected\def\synchronizeskipamounts + {\bigskipamount + \skipfactor\baselineskip + \s!plus\skipgluefactor\baselineskip + \s!minus\skipgluefactor\baselineskip + \relax + \medskipamount \bigskipamount \divide\medskipamount \plustwo + \smallskipamount\bigskipamount \divide\smallskipamount\plusfour} + +%D Snapping. + +% \newif\ifgridsnapping % already defined + +\permanent\tolerant\protected\def\startgridsnapping[#1]% + {\snaptogrid[#1]\vbox\bgroup} + +\permanent\protected\def\stopgridsnapping + {\egroup} + +\permanent\tolerant\protected\def\placeongrid[#1]% + {\snaptogrid[#1]\vbox} % mark as done + +\permanent\tolerant\protected\def\snaptogrid[#1]% list or predefined + {\ifgridsnapping + \expandafter\spac_grids_snap_to_indeed % todo: move inline + \else + \expandafter\gobbleoneargument + \fi{#1}} + +\def\spac_grids_snap_to_indeed#1% + {\bgroup + \spac_grids_snap_value_reset + \dowithnextbox{\spac_grids_snap_to_finish{#1}}} + +% eventually there will always be a line snap + +\def\spac_grids_snap_to_finish#1% + {\ifvbox\nextbox % this will go away + \clf_vspacingcollapse\nextbox\relax % isn't that already done? + \fi + \doifelsenothing{#1}{\spac_grids_snap_value_set\v!normal}{\spac_grids_snap_value_set{#1}}% + \clf_vspacingsnap\nextbox\c_attr_snapmethod\relax + \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% no pack (?), we snap + \egroup} + +\def\spac_grids_check_nop + {\gridsnappingfalse + \resetsystemmode\v!grid + \spac_grids_snap_value_reset} + +\def\spac_grids_check_yes + {\gridsnappingtrue + \setsystemmode\v!grid + \spac_grids_snap_value_set\p_grid} + +\permanent\protected\def\synchronizegridsnapping + {\edef\p_grid{\layoutparameter\c!grid}% + \ifx\p_grid\v!no % official + \spac_grids_check_nop + \orelse\ifx\p_grid\v!off % for taco and luigi + \spac_grids_check_nop + \orelse\ifempty\p_grid % to be sure + \spac_grids_check_nop + \else + \spac_grids_check_yes + \fi} + +\permanent\protected\def\setupgridsnapping[#1]% less overhead than setuplayout (needs testing) + {\setlayoutparameter\c!grid{#1}\synchronizegridsnapping} + +\mutable\let\checkedgridmethod\empty % these can become private +\mutable\let\checkedgridscope \v!local % these can become private + +\permanent\protected\def\checkgridmethod#1% + {\edef\p_grid{#1}% + \ifempty\p_grid + \let\checkedgridmethod\empty + \let\checkedgridscope \v!local + \else + \splitatcolon\p_grid\checkedgridscope\checkedgridmethod + \ifempty\checkedgridmethod + \ifx\checkedgridscope\v!local\orelse\ifx\checkedgridscope\v!global\else + \let\checkedgridmethod\checkedgridscope + \let\checkedgridscope \v!local + \fi + \fi + \fi} + +\permanent\protected\def\applygridmethod#1#2#3% content localsettings (used in head rendering) + {\checkgridmethod{#1}% + \ifx\checkedgridscope\v!global + \ifempty\checkedgridmethod \else + % we assume that the call is grouped because grouping here has the side + % effect that the eventually constructed line will get the value outside + % the group + % + % overkill: \setupgridsnapping[\checkedgridmethod]% + % maybe : \spac_grids_snap_value_auto\checkedgridmethod + \spac_grids_snap_value_set\checkedgridmethod + \fi + \hbox{#3}% + \else + % the extra hbox will trigger the global snapper on top of the local and + % we really need that in this case (compatibility etc etc) so here we don't + % het an already done hit (otherwise we would not snap) + \hbox\bgroup + \ifempty\checkedgridmethod\orelse\ifconditional\headisdisplay + #2% + \fi + \snaptogrid[\checkedgridmethod]\hbox{#3}% + \egroup + \fi} + +\protected\gdef\page_layouts_calculate_overshoot + {\ifgridsnapping\ifcase\layoutlines + \getnoflines\textheight + \textovershoot\dimexpr\noflines\globalbodyfontlineheight-\textheight\relax + \fi\fi} + +\protected\def\page_layouts_report_overshoot + {\page_layouts_calculate_overshoot + \ifdim\textovershoot>\zeropoint + \writestatus\m!layouts{gridmode,\space + noflines: \the\noflines,\space + textheight: \the\textheight,\space + textovershoot: \the\textovershoot\space + (maybe set number of lines instead)% + }% + \fi + \glet\page_layouts_report_overshoot\page_layouts_calculate_overshoot} + +\appendtoks + \page_layouts_report_overshoot +\to \everybeforepagebody + +%D Visualization: + +\definepalet + [grid] + [ one=red, + two=green, + three=blue, + four=gray] + +\permanent\protected\def\setgridtracebox#1[#2]% % maybe reverse the order + {\setbox\nextbox#1% + {\hbox + {\hbox to \zeropoint + {\setlayoutcomponentattribute{\v!grid:\v!test}% + \color[grid:#2]{\ruledhbox \layoutcomponentboxattribute {\fakebox\nextbox}}% + \hss}% + \flushnextbox}}} + +\setnewconstant\gridboxlinenomode\plusone % 0:nothing 1:all 2:lines 3:frame 4:l/r +\setnewconstant\gridboxlinemode \plusone + +\permanent\protected\def\gridboxvbox + {\ifcase\gridboxlinemode + \vpack + \or + \ruledvpack + \or + \vpack + \or + \ruledvpack + \else + \ruledvpack + \fi} + +\permanent\def\gridboxwidth{\ifcase\gridboxlinemode0\or.5\or.5\or0\else.5\fi\linewidth} + +\permanent\protected\def\setgridbox#1#2#3% maybe ifgridsnapping at outer level + {\setbox#1\gridboxvbox to #3 % given size + {\forgetall + \resetvisualizers + \resetteststrut + \offinterlineskip + \hsize#2% + \ifcase\gridboxlinenomode\or\or\or + \gridboxlinenomode\doifoddpageelse\plusone\plustwo % 3: outer + \or + \gridboxlinenomode\doifoddpageelse\plustwo\plusone % 4: inner + \fi + \topskipcorrection + \gridboxvbox % calculated size + {\getrawnoflines{#3}% \getnoflines{#3}% + \scratchdimen\dimexpr#2+\lineheight\relax + \dorecurse\noflines + {\strut + \hskip-.5\lineheight\relax + \ifcase\gridboxlinenomode\or + \rlap + {\hskip\dimexpr.2\bodyfontsize+\scratchdimen\relax + \infofont\hbox to \emwidth{\hss\recurselevel}}% + \or + \llap + {\infofont\hbox to \emwidth{\hss\recurselevel}% + \hskip.2\bodyfontsize}% + \fi + \vrule + \s!height \gridboxwidth + \s!depth \gridboxwidth + \s!width \scratchdimen + \par}} + \vfill}} + +%D This has become obsolete: + +% \def\moveboxontogrid#1#2#3% will become obsolete, but it needs checking +% {} + +%D Helper: + +\protected\def\spac_helpers_assign_skip#1#2% ook nog \v!halfline+fuzzysnap + {\doifelse{#2}\v!line + {#1\ifgridsnapping + \bodyfontlineheight + \else + \openlineheight + \fi} + {\ifgridsnapping + \assigndimension{#2}{#1}{.25\bodyfontlineheight}{.5\bodyfontlineheight}\bodyfontlineheight + \else + \assigndimension{#2}{#1}\smallskipamount\medskipamount\bigskipamount + \fi}% + \relax} + +% \start \dosetstretch{.25em} \setuptolerance[tolerant,stretch] \input tufte \endgraf \stop +% \start \dosetstretch{.5em} effe flink doorfietsen \stop + +% experimental code, not yet interfaced: + +% category: +% +% 0 == discard discard +% 1 == only if larger largest +% 2 == force even if smaller force +% 3 == only take penalty component penalty +% 4 == add to existing skip add +% 5 == disable (ignore following) disable +% 6 == kill whitespace nowhite +% 7 == discard previous back +% 10 == no topskip +% +% penalty: larger wins +% order: larger wins +% category:2,order:5,penalty:10000,skip:value|kw +% +% \defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi} + +% todo, in grid mode: builders.vspacing.fixed = false +% +% \ifgridsnapping will go + +\installcorenamespace{vspacing} +\installcorenamespace{vspacingamount} + +\permanent\tolerant\protected\def\definevspacingamount[#1]#*[#2]#*[#3]% can be combined + {\ifarguments + %defcsname\??vspacingamount#1\endcsname{\lineheight}% + \or + \defcsname\??vspacingamount#1\endcsname{\lineheight}% + \or + \defcsname\??vspacingamount#1\endcsname{\ifgridsnapping\lineheight\else#2\fi}% + \or + \defcsname\??vspacingamount#1\endcsname{\ifgridsnapping#3\else#2\fi}% + \fi + \clf_vspacingsetamount{#1}} + +\def\spac_vspacing_no_topskip % use grouped + {\c_attr_skipcategory\pluseleven} + +%permanent\def\vspacingfromscratchtoks {\scratchdimen\dimexpr\csname\??vspacingamount\the\scratchtoks\endcsname\relax} +\permanent\def\vspacingpredefinedvalue#1{\scratchskip\glueexpr\csname\??vspacingamount#1\endcsname\relax} +%permanent\def\vspacingfromtempstring {\scratchdimen\dimexpr\csname\??vspacingamount\tempstring\endcsname\relax} + +% \installcorenamespace{vspacingamountnormal} +% \installcorenamespace{vspacingamountgrid} + +% \def\spac_vspacing_define_amount[#1][#2][#3]% can be combined +% {\ifcsname n>#1\endcsname\else +% \expandafter\newtoks\csname n>#1\endcsname +% \expandafter\newtoks\csname g>#1\endcsname +% \fi +% \csname n>#1\endcsname{#2}% +% \csname g>#1\endcsname{#3}% +% \clf_vspacingsetamount{#1}} + +\permanent\tolerant\protected\def\definevspacing[#1]#*[#2]% + {\clf_vspacingdefine{#1}{#2}} + +%D The injector code (generated at the \LUA\ end). This will go away! + +\newtoks\everybeforeblankhandling +\newtoks\everyafterblankhandling + +\newconditional\c_space_vspacing_done +\newconditional\c_space_vspacing_fixed +\newconditional\c_space_ignore_parskip + +\appendtoks + \s_spac_vspacing_temp\zeropoint + \c_attr_skipcategory\plusone + \c_attr_skippenalty \attributeunsetvalue + \c_attr_skiporder \attributeunsetvalue + \ifgridsnapping + \settrue\c_space_vspacing_fixed + \else + \setfalse\c_space_vspacing_fixed + \fi +\to \everybeforeblankhandling + +\appendtoks + \s_spac_vspacing_temp\plusone\s_spac_vspacing_temp + \ifconditional\c_space_vspacing_fixed \else + \s!plus \skipgluefactor\s_spac_vspacing_temp + \s!minus\skipgluefactor\s_spac_vspacing_temp + \fi + \relax +\to \everyafterblankhandling + +% The main spacer: + +\permanent\tolerant\protected\def\vspacing[#1]% + {\ifarguments + \spac_vspacing_yes[\currentvspacing]% in the new mechanism no [] needed + \else + \spac_vspacing_yes[#1]% in the new mechanism no [] needed + \fi} + +\def\spac_vspacing_yes + {\ifinpagebody % somewhat weird + \expandafter\spac_vspacing_yes_indeed + \orelse\ifconditional\c_spac_packed_blank + \expandafter\spac_vspacing_yes_indeed + \else + \expandafter\spac_vspacing_yes_ignore + \fi} + +\def\spac_vspacing_nop + {\ifinpagebody % somewhat weird + \expandafter\spac_vspacing_nop_indeed + \orelse\ifconditional\c_spac_packed_blank + \expandafter\spac_vspacing_nop_indeed + \else + \expandafter\spac_vspacing_nop_ignore + \fi} + +\def\spac_vspacing_yes_indeed[#1]{\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{#1}\fi\fi} +\def\spac_vspacing_nop_indeed {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{\currentvspacing}\fi\fi} + +\def\spac_vspacing_yes_ignore[#1]{\ifmmode\else\par\fi} +\def\spac_vspacing_nop_ignore {\ifmmode\else\par\fi} + +\permanent\protected\def\directvspacing#1% + {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{\iftok{#1}\emptytoks\currentvspacing\else#1\fi}\fi\fi} + +\permanent\protected\def\directdefaultvspacing + {\ifinpagebody % somewhat weird + \directvspacing\currentvspacing + \orelse\ifconditional\c_spac_packed_blank + \directvspacing\currentvspacing + \fi} + +\permanent\protected\def\directcheckedvspacing + {\ifinpagebody % somewhat weird + \expandafter\directvspacing + \orelse\ifconditional\c_spac_packed_blank + \expandafter\directvspacing + \else + \expandafter\gobbleoneargument + \fi} + +\permanent\protected\def\useblankparameter#1% faster local variant + {\edef\m_spac_blank_asked{#1\c!blank}% + \ifempty\m_spac_blank_asked\else + \directvspacing\m_spac_blank_asked + \fi} + +%D Handy (and faster): + +\permanent\protected\def\directvpenalty#1{\ifmmode\else\par\ifvmode\clf_injectvpenalty#1\relax\fi\fi} +\permanent\protected\def\directvskip #1{\ifmmode\else\par\ifvmode\clf_injectvskip #1\relax\fi\fi} + +%D These depend on bigskipamount cum suis so we'd better sync them: + +\mutable\let\currentvspacing\s!default % hm, default, standard ... + +\permanent\tolerant\protected\def\setupvspacing[#1]% + {\ifarguments\else + \edef\currentvspacing{#1}% + \fi + \synchronizevspacing} + +\permanent\protected\def\synchronizevspacing + {\ifempty\currentvspacing % mistakenly had an \else + \let\currentvspacing\s!default + \fi + \spac_whitespace_setup_nop} + +\permanent\protected\def\restorestandardblank % or default ? + {\let\currentvspacing\v!standard} + +%D The \type {category:4} is default. + +\definevspacingamount[\v!none] [\zeropoint] [\zeropoint] +\definevspacingamount[\v!big] [\bigskipamount] [\bodyfontlineheight] +\definevspacingamount[\v!medium] [\medskipamount] [.5\bodyfontlineheight] +\definevspacingamount[\v!small] [\smallskipamount] [.25\bodyfontlineheight] +\definevspacingamount[\v!line] [\openlineheight] [\bodyfontlineheight] +\definevspacingamount[\v!halfline] [.5\openlineheight] [.5\bodyfontlineheight] +\definevspacingamount[\v!quarterline] [.25\openlineheight] [.25\bodyfontlineheight] +\definevspacingamount[\v!formula] [\medskipamount] [.5\bodyfontlineheight] +\definevspacingamount[\v!white] [\parskip] [\bodyfontwhitespace] +\definevspacingamount[\v!height] [\strutht] [\bodyfontstrutheight] +\definevspacingamount[\v!depth] [\strutdp] [\bodyfontstrutdepth] + +\definevspacingamount[\v!standard] [.75\openlineheight] [.75\openlineheight] % mkii compatible + +\permanent\def\bodyfontwhitespace + {\dimexpr + \ifzeropt\parskip + \zeropoint + \orelse\ifgridsnapping + \bodyfontlineheight + \else + \parskip + \fi + \relax} + +%D used in itemize \unknown\ always test this: + +\newdimen\d_spac_overlay + +\def\spac_overlay_lines + {\directcheckedvspacing{\v!back,\v!overlay}% \blank[\v!back,\v!overlay]% + \nointerlineskip} + +% \startitemize[n] +% \item \input zapf +% \item \startitemize[a] +% \item \input knuth +% \stopitemize +% \stopitemize +% +% \strut \hfill first line \blank[overlay] second line \hfill \strut +% +% \ruledvbox { +% \strut \hfill line 1 \blank[overlay] +% line 2 \hfill \strut \blank[overlay] +% \strut \hfill line 3 \hfill \strut +% } +% +% \dorecurse{50} +% {\startitemize[n] \startitem \startitemize[a] \item #1 \stopitemize \stopitem \stopitemize} + +\definevspacing[\v!preference][penalty:-500] % goodbreak +\definevspacing[\v!samepage] [penalty:10000] % nobreak + +\definevspacing[\v!always] [category:0] % hm, internally it's discard +\definevspacing[\v!max] [category:1] +\definevspacing[\v!force] [category:2] +\definevspacing[\v!disable] [category:5] +\definevspacing[\v!nowhite] [category:6] +\definevspacing[\v!back] [category:7] +\definevspacing[\v!packed] [category:8] % noparskip (kind of special) +\definevspacing[\v!overlay] [category:9] +\definevspacing[\v!enable] [category:10] + +%definevspacing[\v!noparskip] [category:8] +%definevspacing[\v!notopskip] [category:11] + +\definevspacing[\v!weak] [order:0] +\definevspacing[\v!strong] [order:100] + +\definevspacing[\s!default] [\v!white] % was big for a while + +\newcount\c_spac_vspacing_special_base \c_spac_vspacing_special_base = 32250 % 4000 +\newcount\c_spac_vspacing_special_step \c_spac_vspacing_special_step = 10 % 250 +\newcount\c_spac_vspacing_special_done + +% 2019-05-31 : upgraded a bit to more distinctive samepage-[level]-[0|1|2] names + +\protected\def\spac_vspacing_define_same_step#1#2% alternatively we could have samepage-n-m + {\begingroup + \scratchcounterone\numexpr\plusthree*#1+#2\relax + \scratchcountertwo\numexpr\c_spac_vspacing_special_base+\c_spac_vspacing_special_step*\scratchcounterone\relax + %\writestatus{defined}{\v!samepage-\number#1-\number#2\space=>\space penalty:\the\scratchcountertwo}% + \normalexpanded{\definevspacing[\v!samepage-\number#1-\number#2][penalty:\the\scratchcountertwo]}% + \endgroup} + +\protected\def\spac_vspacing_define_same_page#1% + {\dostepwiserecurse\c_spac_vspacing_special_done{#1}\plusone + {\spac_vspacing_define_same_step\recurselevel\zerocount % before + \spac_vspacing_define_same_step\recurselevel\plusone % after + \spac_vspacing_define_same_step\recurselevel\plustwo}% % whatever + \global\c_spac_vspacing_special_done#1\relax} + +\spac_vspacing_define_same_page{12} % 12 levels should be more than enough as a start + +\def\spac_vspacing_same_page#1#2% level offset (starts at 0) + {\ifnum#1>\c_spac_vspacing_special_done + \spac_vspacing_define_same_page{#1}% + \fi + %\writestatus{used}{\v!samepage-\number#1-\number#2}% + \vspacing[\v!samepage-\number#1-\number#2]} + +\definevspacing[\v!default] [\v!big] % todo: needs to adapt to \setupblank +\definevspacing[\v!before] [\v!default] % but we need to avoid circular references +\definevspacing[\v!inbetween][\v!default] % then +\definevspacing[\v!after] [\v!before] + +\setupvspacing + [\v!big] % alternatively [\v!standard] + +%D Maybe at some point we will differ between \type {\vspacing} and \type {\blank} +%D (we needed the first one while playing with the new code). + +% We keep this one as reference +% +% \protected\def\inhibitblank +% {\vspacing[\v!disable]} +% +% but use the following more efficient variant instead: + +\permanent\protected\def\inhibitblank{\ifmmode\else\par\ifvmode\clf_injectdisable\fi\fi} + +\aliased\let\doinhibitblank\inhibitblank % keep this command for a while, used in styles + +%D We use \type {vspacing} because at some point we had the blank mechanism alongside +%D a new experimental variant and I aliased it locally till it all worked out well. So, +%D we're kind of stuck with synonyms now. Some day we will drop the vspacing and use the +%D old aliases instead. + +\aliased\let\defineblank \definevspacing +\aliased\let\setupblank \setupvspacing +\aliased\let\blank \vspacing +\aliased\let\synchronizeblank \synchronizevspacing +\aliased\let\defineblankmethod\definevspacingamount + +%D The following command is for Wolfgang. It has to be used with care as it does +%D {\em not} work in tandem with the other spacing commands. + +\installcorenamespace{vspace} + +\permanent\tolerant\protected\def\definevspace[#1]#*[#2]#*[#3]% + {\ifarguments + \or + \letcsname\??vspace:#1\endcsname\empty + \or + \defcsname\??vspace:#1\endcsname{#2}% + \or + \defcsname\??vspace#1:#2\endcsname{#3}% + \fi} + +\letvalue{\??vspace:\s!unknown}\zeropoint + +\def\spac_vspace_unknown + {\csname\??vspace:\s!unknown\endcsname} + +\permanent\tolerant\protected\def\vspace[#1]#*[#2]% + {\par + \ifvmode + \removelastskip + \vskip + \ifparameter#2\or + \ifcsname\??vspace#1:#2\endcsname + \lastnamedcs + \orelse\ifcsname\??vspace:#2\endcsname + \lastnamedcs + \else + \spac_vspace_unknown + \fi + \orelse\ifparameter#1\or + \ifcsname\??vspace:#1\endcsname + \lastnamedcs + \else + \spac_vspace_unknown + \fi + \else + \ifcsname\??vspace:\s!default\endcsname + \lastnamedcs + \else + \spac_vspace_unknown + \fi + \fi + \relax + \fi} + +%D Some preliminary code: a simple and fast hanger, for usage in macros. + +\installcorenamespace {hanging} + +\installdirectcommandhandler \??hanging {hanging} + +\setuphanging + [\c!distance=.5\emwidth, + \c!location=\v!left, + \c!n=\zerocount] + +\let\m_spac_hanging_location\empty + +\permanent\tolerant\protected\def\starthanging[#1]% + {\dontleavehmode\bgroup + \ifhastok={#1}% + \let\m_spac_hanging_location\empty + \setupcurrenthanging[#1]% + \else + \edef\m_spac_hanging_location{#1}% + \fi + \ifempty\m_spac_hanging_location + \edef\m_spac_hanging_location{\directhangingparameter\c!location}% + \fi + \dowithnextboxcs\spac_hanging_finish\hbox} + +\permanent\protected\def\stophanging + {\endgraf + \egroup} + +\def\spac_hanging_finish + {\scratchdistance\directhangingparameter\c!distance\relax + \ifdim\ht\nextbox>\strutht + \setbox\nextbox\tbox{\box\nextbox}% + \fi + \scratchcounter\directhangingparameter\c!n\relax + \ifnum\scratchcounter>\zerocount + \frozen\hangafter-\scratchcounter + \else + \getboxheight\scratchdimen\of\box\nextbox + \getnoflines\scratchdimen + \frozen\hangafter-\noflines + \fi + \ht\nextbox\strutht + \dp\nextbox\strutdp + \scratchwidth\dimexpr\wd\nextbox+\scratchdistance\relax + \ifx\m_spac_hanging_location\v!right + \frozen\hangindent\ifconditional\displaylefttoright-\fi\scratchwidth + \rlap{\hskip\dimexpr\hsize-\leftskip-\wd\nextbox\relax\box\nextbox}% \leftskip is new + \else + \frozen\hangindent\ifconditional\displaylefttoright\else-\fi\scratchwidth + \llap{\box\nextbox\hskip\scratchdistance}% + \fi + \ignorespaces} + +%D \macros +%D {startfixed} +%D +%D \starttyping +%D \startitemize +%D \startitem \externalfigure[cow][height=1cm] \stopitem +%D \startitem \externalfigure[cow][height=1cm] \stopitem +%D +%D \startitem \startfixed \externalfigure[cow][height=1cm]\stopfixed \stopitem +%D \startitem \startfixed[high]\externalfigure[cow][height=1cm]\stopfixed \stopitem +%D \startitem \startfixed[low] \externalfigure[cow][height=1cm]\stopfixed \stopitem +%D \startitem \startfixed[lohi]\externalfigure[cow][height=1cm]\stopfixed \stopitem +%D +%D \startitem test \par \startfixed \externalfigure[koe][height=1cm]\stopfixed \stopitem +%D \startitem test \par \startfixed[high]\externalfigure[koe][height=1cm]\stopfixed \stopitem +%D \startitem test \par \startfixed[low] \externalfigure[koe][height=1cm]\stopfixed \stopitem +%D \startitem test \par \startfixed[lohi]\externalfigure[koe][height=1cm]\stopfixed \stopitem +%D \stopitemize +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\installcorenamespace{fixedalternatives} + +\aliased\let\stopfixed\relax + +\permanent\protected\def\startfixed + {\bgroup + \ifhmode + \expandafter\typo_fixed_start_h + \else + \expandafter\typo_fixed_start_v + \fi} + +\tolerant\def\typo_fixed_start_h[#1]% + {\enforced\let\stopfixed\typo_fixed_stop_h + \dowithnextbox{\typo_fixed_finish{#1}}% + \vbox\bgroup + %ignorespaces + \setlocalhsize} + +\protected\def\typo_fixed_stop_h + {%removeunwantedspaces + \egroup + \egroup} + +\tolerant\def\typo_fixed_start_v[#1]% + {\enforced\let\stopfixed\typo_fixed_stop_v + \startbaselinecorrection} + +\protected\def\typo_fixed_stop_v + {\stopbaselinecorrection + \egroup} + +\letcsname\??fixedalternatives \v!high\endcsname\bbox +\letcsname\??fixedalternatives \v!low\endcsname\tbox +\letcsname\??fixedalternatives \v!middle\endcsname\vcenter +\letcsname\??fixedalternatives \v!lohi\endcsname\vcenter +\letcsname\??fixedalternatives\s!unknown\endcsname\tbox +\letcsname\??fixedalternatives\s!default\endcsname\tbox + +\protected\def\typo_fixed_finish#1% + {\expandnamespacevalue\??fixedalternatives{#1}\s!default{\box\nextbox}} + +% %D Forgotten already: +% +% \def\shapefill{\vskip\zeropoint\s!plus\lineheight\s!minus\lineheight\relax} + +%D Nasty: + +% \writestatus{1}{\the\prevdepth} \blank[force,5*big] { \writestatus{1}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page +% \writestatus{2}{\the\prevdepth} \blank[force,5*big] { \writestatus{2}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page +% \writestatus{3}{\the\prevdepth} \blank[force,5*big] { \writestatus{3}{\the\prevdepth} \baselineskip5cm xxxxxxxxx \par } \page +% \writestatus{4}{\the\prevdepth} \input tufte \page +% \writestatus{5}{\the\prevdepth} \input tufte \page +% \writestatus{6}{\the\prevdepth} \blank[force,5*big] { \writestatus{6}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page + +% \writestatus{1}{\the\prevdepth} \null\vskip4cm { \writestatus{1}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page +% \writestatus{2}{\the\prevdepth} \null\vskip4cm { \writestatus{2}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page +% \writestatus{3}{\the\prevdepth} \null\vskip4cm { \writestatus{3}{\the\prevdepth} \baselineskip5cm xxxxxxxxx \par } \page +% \writestatus{4}{\the\prevdepth} \input tufte \page +% \writestatus{5}{\the\prevdepth} \input tufte \page +% \writestatus{6}{\the\prevdepth} \null\vskip4cm { \writestatus{6}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page + +\appendtoks + \ifvmode\prevdepth\zeropoint\fi % consistent, else first page -1000pt .. needed for fixed,3*big first/successive pages consistency +\to \everystarttext + +\prevdepth\zeropoint + +%D Helper: + +\permanent\protected\def\checkedblank[#1]% + {\edef\p_blank{#1}% + \ifempty\p_blank + % ignore + \orelse\ifx\p_blank\v!none + % ignore + \else + \blank[\p_blank]% + \fi} + +% \setupwhitespace[line] +% \prerollblank[2*line] \the\prerolledblank +% \prerollblank[-2*line] \the\prerolledblank + +\newskip\prerolledblank + +\permanent\protected\def\prerollblank[#1]% + {\begingroup + \edef\p_blank{#1}% + \ifempty\p_blank + \global\prerolledblank\zeropoint + \orelse\ifx\p_blank\v!none + \global\prerolledblank\zeropoint + \else + % don't mess with \arskip here! + \scratchskip\plusten\lineheight + \setbox\scratchbox\vbox + {\vskip\scratchskip + \kern\zeropoint + \blank[\p_blank]}% + % \dimexpr doesn't work well with skips + \advance\scratchskip-\ht\scratchbox + \global\prerolledblank-\scratchskip + \fi + \endgroup} + +\newcount\c_spac_vspacing_ignore_parskip + +% \setupwhitespace[line] +% \setuphead[subject][after={\blank[packed]},style=\bfb] +% \subject{foo} +% test \par +% test \par +% \blank[packed] % \ignoreparskip +% test \par +% test \par +% \ignoreparskip +% test \par +% test \par +% \setuphead[subject][after={\blank[nowhite]},style=\bfb] +% \subject{foo} +% test \par +% test \par + +\permanent\protected\def\ignoreparskip{\c_spac_vspacing_ignore_parskip\plusone} + +\protect \endinput |