spac-hor.mkxl /size: 45 Kb    last modification: 2024-01-16 09:03
1%D \module
2%D   [       file=spac-hor,
3%D        version=2009.10.16, % 1997.03.31, was core-spa.tex
4%D          title=\CONTEXT\ Spacing Macros,
5%D       subtitle=Horizontal,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Spacing Macros / Horizontal}
15
16% document: \enabledirectives[backends.spaces]
17
18\unprotect
19
20\registerctxluafile{spac-hor}{autosuffix}
21
22\ifdefined\parfillrightskip\else \aliased\let\parfillrightskip\parfillskip \fi
23
24\bitwiseflip \normalizelinemode \normalizelinenormalizecode
25\bitwiseflip \normalizelinemode \parindentskipnormalizecode
26\bitwiseflip \normalizelinemode \clipwidthnormalizecode
27\bitwiseflip \normalizelinemode \flattendiscretionariesnormalizecode
28\bitwiseflip \normalizelinemode \flattenhleadersnormalizecode
29%bitwiseflip \normalizelinemode \discardzerotabskipsnormalizecode
30
31\bitwiseflip \normalizeparmode \normalizeparnormalizeparcode
32\bitwiseflip \normalizeparmode \flattenvleadersnormalizeparcode
33
34\lettonothing\v_spac_indentation_current % amount/keyword
35
36\newdimension\d_spac_indentation_par
37\parindent   \d_spac_indentation_par % for the show
38
39\newconditional\c_spac_indentation_indent_first \c_spac_indentation_indent_first\conditionaltrue
40\newconstant   \c_spac_indentation_toggle_state
41
42%D After a blank or comparable situation (left side floats) we
43%D need to check if the next paragraph has to be indented.
44
45\permanent\protected\def\presetindentation
46  {\doifoutervmode{\ifconditional\c_spac_indentation_indent_first\else\spac_indentation_variant_no\fi}}
47
48\permanent\protected\def\setupindenting
49  {\doifelsenextoptionalcs\spac_indentation_setup_options\spac_indentation_setup_size}
50
51\permanent\protected\def\spac_indentation_setup_size
52  {\assigndimension\v_spac_indentation_current\d_spac_indentation_par{1\emwidth}{1.5\emwidth}{2\emwidth}%
53   \ifzeropt\parindent\else
54     \parindent\d_spac_indentation_par\relax % new per 2019-04-12 : just in case it has been set beforehand
55   \fi}
56
57\aliased\let\synchronizeindenting\spac_indentation_setup_size
58
59\lettonothing\m_spac_indentation_options
60
61\def\spac_indentation_setup_options[#1]%
62  {\edef\m_spac_indentation_options{#1}% comma separated list
63   \ifempty\m_spac_indentation_options \else
64     \spac_indentation_setup_indeed
65   \fi}
66
67\def\spac_indentation_setup_indeed
68  {% not here: \c_spac_indentation_indent_first\conditionaltrue
69   % not here: \parindent\d_spac_indentation_par
70   % not here: \c_spac_indentation_toggle_state\zerocount
71   \processcommacommand[\m_spac_indentation_options]\spac_indentation_apply_step_one % catch small, medium, etc
72   \processcommacommand[\m_spac_indentation_options]\spac_indentation_apply_step_two % catch rest
73   \ifzeropt\parindent\else
74     \doifemptytoks\everypar\spac_indentation_set_everypar
75   \fi
76   \ifconditional\c_spac_indentation_indent_first
77     \spac_indentation_variant_yes % better than: \let\checkindentation\relax
78   \else
79     \spac_indentation_variant_no
80   \fi
81   \spac_indentation_check_toggle}
82
83\def\spac_indentation_set_everypar
84  {\everypar{\checkindentation}}
85
86\permanent\protected\def\useindentingparameter#1% faster local variant
87  {\edef\m_spac_indentation_options{#1\c!indenting}%
88   \ifempty\m_spac_indentation_options \else
89     \spac_indentation_setup_indeed
90   \fi}
91
92% \defineindenting[whatever][yes,2cm]
93% %defineindenting[whatever][yes,-2cm]
94%
95% \setupindenting[yes,-2em] \input ward \par
96% \setupindenting[yes,2em]  \input ward \par
97% \setupindenting[whatever] \input ward \par
98
99\installcorenamespace {indentingpreset}
100
101\permanent\tolerant\protected\def\defineindenting[#1]#*[#2]% todo: mixes
102  {\ifarguments\else\edefcsname\??indentingpreset#1\endcsname{#2}\fi}
103
104\def\spac_indentation_apply_step_one_nested
105  {\expandafter\processcommacommand\expandafter[\lastnamedcs]\spac_indentation_apply_step_one}
106
107\def\spac_indentation_apply_step_two_nested
108  {\expandafter\processcommacommand\expandafter[\lastnamedcs]\spac_indentation_apply_step_two}
109
110\def\spac_indentation_apply_step_one#1%
111  {\ifcsname\??indentingpreset#1\endcsname
112     \spac_indentation_apply_step_one_nested
113   \orelse\ifcsname\??indentingmethod#1\endcsname
114     % case two
115   \else
116     \edef\v_spac_indentation_current{#1}% single entry in list
117     \let\v_spac_indentation_normal\v_spac_indentation_current
118     \spac_indentation_setup_size
119   \fi}
120
121\def\spac_indentation_apply_step_two#1%
122  {\ifcsname\??indentingpreset#1\endcsname
123     \spac_indentation_apply_step_two_nested
124   \orelse\ifcsname\??indentingmethod#1\endcsname
125     \lastnamedcs
126   \else
127     % case one
128   \fi}
129
130\permanent\protected\def\indenting % kind of obsolete
131  {\doifelsenextoptionalcs\spac_indentation_setup_options\relax}
132
133% use \noindentation to suppress next indentation
134
135\installcorenamespace{indentingmethod}
136
137\permanent\protected\def\installindentingmethod#1#2%
138  {\defcsname\??indentingmethod#1\endcsname{#2}}
139
140\installindentingmethod \v!no    {\parindent\zeropoint}
141\installindentingmethod \v!not   {\parindent\zeropoint}
142
143\installindentingmethod \v!first {\c_spac_indentation_indent_first\conditionaltrue}
144\installindentingmethod \v!next  {\c_spac_indentation_indent_first\conditionalfalse}
145
146\installindentingmethod \v!yes   {\parindent\d_spac_indentation_par\relax} % not \indent !
147\installindentingmethod \v!always{\parindent\d_spac_indentation_par\relax} % not \indent !
148
149\installindentingmethod \v!never {\parindent\zeropoint\relax     % no \indent !
150                                  \c_spac_indentation_toggle_state\zerocount}
151
152\installindentingmethod \v!odd   {\c_spac_indentation_toggle_state\plusone}
153\installindentingmethod \v!even  {\c_spac_indentation_toggle_state\plustwo}
154
155\installindentingmethod \v!normal{\ifempty\v_spac_indentation_normal\else
156                                    \let\v_spac_indentation_current\v_spac_indentation_normal
157                                    \spac_indentation_setup_size
158                                  \fi}
159
160\installindentingmethod \v!reset {\c_spac_indentation_indent_first\conditionaltrue
161                                  \parindent\zeropoint
162                                  \c_spac_indentation_toggle_state\zerocount}
163
164\installindentingmethod \v!toggle{\parindent\ifzeropt\parindent
165                                    \d_spac_indentation_par
166                                  \else
167                                    \zeropoint
168                                  \fi\relax}
169
170\permanent\protected\def\noindenting{\indenting[\v!no, \v!next ]}
171\permanent\protected\def\doindenting{\indenting[\v!yes,\v!first]}
172
173%D Here come the handlers (still rather messy ... we need states).
174
175%newif\ifindentation \indentationtrue  % will become a mode
176
177\aliased\let\checkindentation\relax
178
179\installmacrostack\checkindentation % used?
180
181%D Actually we can forget about indent and let everypar insert a kern or so,
182%D but on the other hand it's kind of consistent to keep it and make the
183%D width zero. We can do it in \LUA\ or do it natively (which actually makes
184%D sense.
185
186% \permanent\protected\def\undent
187%   {\begingroup
188%      % todo: check subtype too
189%      \ifnum\lastnodetype=\gluenodecode
190%        \unskip % we also need to check for the subtype
191%      \orelse\ifnum\lastnodetype=\hlistnodecode
192%        \setbox\scratchbox\lastbox % we also need to check for the subtype
193%      \else
194%        % forget about it
195%      \fi
196%    \endgroup}
197
198\def\spac_indentation_remove
199  {\ifzeropt\parindent \else
200     \undent
201   \fi}
202
203\def\spac_indentation_kill_indeed
204  {%\global\indentationfalse
205   \spac_indentation_remove}
206
207\permanent\protected\def\spac_indentation_do_toggle_indeed
208  {%\global\indentationfalse
209   \enforced\glet\checkindentation\spac_indentation_no_toggle_indeed
210   \spac_indentation_remove}
211
212\permanent\protected\def\spac_indentation_no_toggle_indeed
213  {%\global\indentationtrue
214   \enforced\glet\checkindentation\spac_indentation_do_toggle_indeed}
215
216\permanent\protected\def\spac_indentation_do_indeed
217  {}%\global\indentationtrue}
218
219\permanent\protected\def\spac_indentation_do_toggle
220  {\enforced\glet\checkindentation\spac_indentation_do_toggle_indeed}
221
222\permanent\protected\def\spac_indentation_no_toggle
223  {\enforced\glet\checkindentation\spac_indentation_no_toggle_indeed}
224
225\permanent\protected\def\spac_indentation_check_toggle
226  {\ifcase\c_spac_indentation_toggle_state
227     % nothing
228   \or
229     \spac_indentation_no_toggle
230   \or
231     \spac_indentation_do_toggle
232   \fi}
233
234\permanent\protected\def\spac_indentation_variant_yes
235  {\enforced\glet\checkindentation\spac_indentation_do_indeed}
236
237\permanent\protected\def\spac_indentation_no_next_check
238  {\spac_indentation_remove
239   \enforced\glet\checkindentation\spac_indentation_do_indeed}
240
241\permanent\protected\def\spac_indentation_variant_no % made global
242  {\ifinpagebody \else
243     %\global\indentationfalse
244     \enforced\glet\checkindentation\spac_indentation_no_next_check
245   \fi}
246
247\permanent\protected\def\nonoindentation % bv bij floats
248  {\ifinpagebody \else
249     %\global\indentationtrue
250     \enforced\glet\checkindentation\spac_indentation_do_indeed
251   \fi}
252
253\permanent\protected\def\spac_indentation_variant_force
254  {\ifvmode \ifzeropt\parindent \else
255     % was : \hskip\parindent
256     % can be: \indent
257     % but we test:
258     \noindent\hskip\parindent % hm, we cannot undent this one
259   \fi \fi}
260
261% public:
262
263\aliased\let\indentation  \spac_indentation_variant_force
264\aliased\let\noindentation\spac_indentation_variant_no    % public
265\aliased\let\doindentation\spac_indentation_variant_yes   % public
266
267\permanent\protected\def\dontrechecknextindentation  % public (in macros)
268  {\global\enforced\let\dorechecknextindentation\relax}
269
270\aliased\let\dorechecknextindentation\relax % public (in macros)
271
272% \permanent\protected\def\spac_indentation_check_next_indentation
273%   {\global\enforced\let\dorechecknextindentation\relax
274%    \doifelsenextchar\par\donothing\spac_indentation_variant_no} % messy check as next is seldom \par
275
276\permanent\protected\def\spac_indentation_check_next_indentation
277  {\global\enforced\let\dorechecknextindentation\relax
278   \begingroup
279   \autoparagraphmode\zerocount
280   \doifelsenextchar\par\endgroup{\endgroup\spac_indentation_variant_no}} % messy check as next is seldom \par
281
282\def\spac_indentation_variant_auto
283  {\global\enforced\let\dorechecknextindentation\spac_indentation_check_next_indentation}
284
285%D This one sets up the local indentation behaviour (i.e. either or not
286%D a next paragraph will be indented).
287
288\installcorenamespace{indentnext}
289
290\permanent\protected\def\checknextindentation[#1]%
291  {\begincsname\??indentnext#1\endcsname}
292
293\permanent\protected\def\useindentnextparameter#1% new, the more efficient variant
294  {\edef\p_indentnext{#1\c!indentnext}%
295   \ifempty\p_indentnext\else
296     \begincsname\??indentnext\p_indentnext\endcsname
297   \fi}
298
299\letcsname\??indentnext       \endcsname\donothing
300\letcsname\??indentnext\v!yes \endcsname\spac_indentation_variant_yes
301\letcsname\??indentnext\v!no  \endcsname\spac_indentation_variant_no
302\letcsname\??indentnext\v!auto\endcsname\spac_indentation_variant_auto
303
304%D An example of usage:
305%D
306%D \starttyping
307%D \setupindenting[small,yes]
308%D
309%D \setupitemize [indentnext=auto]
310%D \setuptyping  [indentnext=auto]
311%D \setupformulas[indentnext=auto]
312%D
313%D \input tufte \startitemize \item itemize \stopitemize
314%D \input tufte \startitemize \item itemize \stopitemize
315%D \input tufte \startitemize \item itemize \stopitemize
316%D
317%D \page
318%D
319%D \input tufte
320%D \starttyping
321%D verbatim
322%D \stoptyping
323%D
324%D \input tufte
325%D \starttyping
326%D verbatim
327%D \stoptyping
328%D
329%D \input tufte
330%D \starttyping
331%D verbatim
332%D \stoptyping
333%D
334%D \page
335%D
336%D \input tufte \startformula a = b \stopformula
337%D \input tufte \startformula a = b \stopformula
338%D \input tufte \startformula a = b \stopformula
339%D \stoptyping
340
341% maybe an everyforgetparindent
342
343\permanent\protected\def\forgetparindent
344  {\c_spac_indentation_indent_first\conditionaltrue % recently added
345   \d_spac_indentation_par\zeropoint
346   \parindent\zeropoint
347   \let\v_spac_indentation_current\v!none}
348
349\appendtoks
350    \forgetparindent
351\to \everyforgetall
352
353\permanent\protected\def\forgethorizontalstretch
354  {\emergencystretch\zeropoint}
355
356\appendtoks
357    \forgethorizontalstretch
358\to \everyforgetall % needed in pagebody
359
360%D Helper:
361
362\permanent\protected\def\softbreak
363  {\relax\ifhmode\hskip\parfillskip\break\fi}
364
365%D \macros
366%D   {frenchspacing,nonfrenchspacing}
367%D
368%D Somehow \type{\frenchspacing} can lead to hyphenation between dashes so we now
369%D have \type {\newfrenchspacing} (moved from \type {syst-chr}). Maybe it's not
370%D needed any more.
371
372%D Hm ... todo:
373
374\installcorenamespace{spacecodemethod}
375
376\sfcode`\)=\zerocount
377\sfcode`\'=\zerocount
378\sfcode`\]=\zerocount
379
380\def\spac_spacecodes_set_fixed#1%
381  {\sfcode`\.#1\relax \sfcode`\,#1\relax
382   \sfcode`\?#1\relax \sfcode`\!#1\relax
383   \sfcode`\:#1\relax \sfcode`\;#1\relax}
384
385\def\spac_spacecodes_set_stretch
386  {\sfcode`\.3000 \sfcode`\,1250
387   \sfcode`\?3000 \sfcode`\!3000
388   \sfcode`\:2000 \sfcode`\;1500 }
389
390\permanent\protected\def\frenchspacing   {\spac_spacecodes_set_fixed\plusthousand}
391\permanent\protected\def\newfrenchspacing{\spac_spacecodes_set_fixed{1050}}
392\permanent\protected\def\nonfrenchspacing{\spac_spacecodes_set_stretch}
393
394\permanent\protected\def\installspacingmethod#1#2{\defcsname\??spacecodemethod#1\endcsname{#2}}
395
396\installspacingmethod \empty    {}                  % keep values
397\installspacingmethod \v!fixed  {\frenchspacing   } % equal spaces everywhere
398\installspacingmethod \v!packed {\newfrenchspacing} % slighly more after punctuation
399\installspacingmethod \v!broad  {\nonfrenchspacing} % more depending on what punctuation
400
401\permanent\tolerant\protected\def\setupspacing[#1]%
402  {\ifarguments\or
403     \begincsname\??spacecodemethod#1\endcsname
404   \fi
405   \updateraggedskips}
406
407% test test\fsp. test % beats frenchspacing
408
409\permanent\protected\def\fsp#1% fixed space puncuation
410  {#1%
411   \ifchknum`#1\or
412    \spacefactor\plusthousand
413   \fi}
414
415%D Here's a tweak .. if needed one can configure it in the configuration
416%D so that initialization happens more efficient.
417%D
418%D \starttyping
419%D \startoverlay
420%D     {
421%D         \green
422%D         \enabledirectives[characters.spaceafteruppercase=normal]%
423%D         \vbox{\hsize 5em x. X\par x.\ X\par X. X\par X.\ X\par}
424%D     } {
425%D         \blue
426%D         \enabledirectives[characters.spaceafteruppercase=traditional]%
427%D         \vbox{\hsize 5em x. X\par x.\ X\par X. X\par X.\ X\par}
428%D     }
429%D \stopoverlay
430%D \stoptyping
431
432% This is not needed, as \updateraggedskips is taking care of it:
433
434\permanent\protected\def\synchronizespacecodes{\updateraggedskips}
435
436% \dorecurse{100}{\recurselevel\spacefactor 800 \space} \par
437% \dorecurse{100}{\recurselevel\spacefactor1200 \space} \par
438% \dorecurse{100}{\recurselevel\spacefactor 800 \normalspaceprimitive} \par
439% \dorecurse{100}{\recurselevel\spacefactor1200 \normalspaceprimitive} \par
440
441% When we don't add the % here, we effectively get \<endlinechar> and
442% since we have by default \def\^^M{\ } we get into a loop.
443
444\aliased\let\normalspaceprimitive=\ % space-comment is really needed
445
446%D As the \type{\ } is convenient in:
447%D
448%D \starttyping
449%D \TEX\space x\crlf
450%D \TEX\      x\crlf
451%D \TEX{}     x\crlf
452%D \stoptyping
453%D
454%D from now on we treat it as a normal space and not as a space with \type
455%D {sfcode} 1000.
456
457% \permanent\protected\def\specialspaceprimitive
458%   {\begingroup
459%    % so, no fancy extra spacing after: foo i.e.\ bar
460%    \nonfrenchspacing\normalspaceprimitive
461%    \endgroup}
462
463\permanent\protected\def\specialspaceprimitive
464  {% is a current state, set explicitly or when a character is appended
465   \ifhmode
466     \spacefactor\plusthousand
467   \else
468     \dontleavehmode
469   \fi
470   \normalspaceprimitive}
471
472% \permanent\protected\def\normalnotobeyedspace
473%   {\mathortext\normalspaceprimitive\specialspaceprimitive} % no \dontleavehmode\space (else no frenchspacing)
474
475\permanent\protected\def\normalnotobeyedspace
476  {\ifmmode\normalspaceprimitive\else\specialspaceprimitive\fi} % no \dontleavehmode\space (else no frenchspacing)
477
478\pushoverloadmode
479
480\overloaded\let\ =\normalnotobeyedspace % so we redefine the primitive!
481
482\popoverloadmode
483
484% Because I strip spaces at the end of lines (in the editor) we need a bit of
485% a trick to define slash+newline, so \space and \<newline> are the same
486
487% We need to be careful with \ and \space and the definition of ~ which uses \ as
488% we need to associate unicode spacing with it. There is some messy aspect that
489% I forgot to note down so I will revision the \ once I ran into it again.
490
491% \ruledhbox spread 10pt {\frenchspacing    xx xx\ X}
492% \ruledhbox spread 10pt {\nonfrenchspacing xx xx\ X}
493% \ruledhbox spread 10pt {\frenchspacing    xx xx X}
494% \ruledhbox spread 10pt {\nonfrenchspacing xx xx X}
495% \ruledhbox spread 10pt {\frenchspacing    xx xx~X}
496% \ruledhbox spread 10pt {\nonfrenchspacing xx xx~X}
497
498% \ruledhbox spread 10pt {\frenchspacing    xx dr.\ X}
499% \ruledhbox spread 10pt {\nonfrenchspacing xx dr.\ X}
500% \ruledhbox spread 10pt {\frenchspacing    xx dr. X}
501% \ruledhbox spread 10pt {\nonfrenchspacing xx dr. X}
502% \ruledhbox spread 10pt {\frenchspacing    xx dr.~X}
503% \ruledhbox spread 10pt {\nonfrenchspacing xx dr.~X}
504
505\permanent\protected\def\nonbreakablespace{\penalty\plustenthousand\normalspaceprimitive} % no space in math
506
507\letcatcodecommand \ctxcatcodes \tildeasciicode \nonbreakablespace % overloaded later
508
509%                   \def\space          { }
510\permanent\protected\def\removelastspace{\ifhmode\unskip\fi}
511\permanent\protected\def\nospace        {\removelastspace\ignorespaces}
512
513\ifdefined\nospaces
514    \permanent\protected\def\nospacing{\normalnospaces\plusone}
515    \permanent\protected\def\dospacing{\normalnospaces\zerocount}
516\else
517    \permanent\protected\def\nospacing{\spaceskip\scaledpoint     \xspaceskip\zeroskip}
518    \permanent\protected\def\dospacing{\spaceskip\currentspaceskip\xspaceskip\zeroskip} % what
519\fi
520
521\ifdefined\softhyphen \else
522    \let\softhyphen\explicitdiscretionary
523\fi
524
525% todo:
526
527\cldcontext{"\string\\protected\string\\def\string\\\string\n{\string\\space}"}
528%cldcontext{"\string\\let\string\\\string\n=\string\\space"}
529
530% in tables we need:
531%
532% \def\fixedspace   {\hskip.5em\relax}
533%
534% but, since not all fonts have .5em digits:
535
536\permanent\protected\def\fixedspace
537  {\setbox\scratchbox\hpack{\mathortext{0}{0}}% was \hbox
538   \hskip\wd\scratchbox\relax}
539
540\permanent\protected\def\fixedspaces
541  {\letcatcodecommand \ctxcatcodes \tildeasciicode\fixedspace
542  %\enforced\let~\fixedspace} % we need to renew it
543   \enforced\letcharcode\tildeasciicode\fixedspace} % why this
544
545\appendtoks
546   %\enforced\let~\space
547    \enforced\letcharcode\tildeasciicode\space
548    \enforced\let\ \space
549\to \everysimplifycommands
550
551% \newsignal\d_spac_keep_unwanted_space_signal
552%
553% % \parindentmode\plusone
554%
555% \permanent\protected\def\keepunwantedspaces
556%   {\ifhmode
557%      \ifdim\lastskip=\d_spac_keep_unwanted_space_signal\else
558%         \hskip\d_spac_keep_unwanted_space_signal\relax
559%      \fi
560%    \fi}
561%
562% \permanent\protected\def\removeunwantedspaces
563%   {\ifhmode
564%      \expandafter \spac_helpers_remove_unwantedspace
565%    \fi}
566%
567% \def\spac_helpers_remove_unwantedspace
568%   {\ifnum\lastnodetype=\gluenodecode\relax
569%      \ifnum\lastnodesubtype=\indentskipsubtypecode\relax
570%        % keep parindent
571%      \orelse\ifdim\lastskip=\d_spac_keep_unwanted_space_signal\relax
572%         \unskip
573%      \else
574%         \unskip
575%         \doubleexpandafter\spac_helpers_remove_unwantedspace
576%      \fi
577%    \fi}
578
579\newboundary\c_spac_keepspaces_boundary
580
581\permanent\protected\def\keepunwantedspaces
582  {\ifhmode\ifnum\lastboundary=\c_spac_keepspaces_boundary\else
583     \boundary\c_spac_keepspaces_boundary
584   \fi\fi}
585
586\permanent\protected\def\removeunwantedspaces
587  {\ifhmode
588     \expandafter \spac_helpers_remove_unwantedspace
589   \fi}
590
591\def\spac_helpers_remove_unwantedspace
592  {\ifnum\lastboundary=\c_spac_keepspaces_boundary
593     \expandafter\unboundary
594   \orunless\ifnum\lastnodetype=\gluenodecode
595     % no skip
596   \orelse\ifnum\lastnodesubtype=\indentskipsubtypecode
597     % keep parindent
598   \else
599      \unskip
600      \expandafter\spac_helpers_remove_unwantedspace
601   \fi}
602
603\permanent\protected\def\onlynonbreakablespace
604  {\ifdim\lastskip=\interwordspace
605     \unskip
606     \nonbreakablespace
607   \fi
608   \ignorespaces}
609
610% \startbuffer
611% \startlines \tt \fixedspaces
612%  0~1~~2~~~3~~~~4~~~~~5
613%  0~~~~~~~~~~~~~~~~~~~5
614% $0~1~~2~~~3~~~~4~~~~~5$
615% $0~~~~~~~~~~~~~~~~~~~5$
616% \stoplines
617%
618% \starttabulate[|~|]
619% \NC  0~1~~2~~~3~~~~4~~~~~5  \NC \NR \NC  0~~~~~~~~~~~~~~~~~~~5  \NC \NR
620% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \NR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \NR
621% \stoptabulate
622%
623% \starttable[||]
624% \NC  0~1~~2~~~3~~~~4~~~~~5  \NC \AR \NC  0~~~~~~~~~~~~~~~~~~~5  \NC \AR
625% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \AR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \AR
626% \stoptable
627% \stopbuffer
628%
629% \setupbodyfont[cmr] \getbuffer
630% \setupbodyfont[lbr] \getbuffer
631
632%D A couple of plain macros:
633
634\ifdefined\enspace \else \permanent\protected\def\enspace{\kern .5\emwidth}       \fi
635\ifdefined\emspace \else \permanent\protected\def\emspace{\kern   \emwidth}       \fi
636
637\ifdefined\quad    \else \permanent\protected\def\quad   {\hskip  \emwidth\relax} \fi
638\ifdefined\enskip  \else \permanent\protected\def\enskip {\hskip.5\emwidth\relax} \fi
639\ifdefined\qquad   \else \permanent\protected\def\qquad  {\hskip 2\emwidth\relax} \fi
640
641\permanent\protected\def\negenspace{\kern-.5\emwidth}
642\permanent\protected\def\negemspace{\kern-  \emwidth}
643
644% \aliased\let\emspace\quad
645
646\permanent\protected\def\charspace{ } % the unexpandable \space (as space can also be delimiter for numbers)
647
648\permanent\tolerant\protected\def\quads[#1]% we do robust checking
649  {\dontleavehmode
650   \begingroup
651  %\scratchcounter\ifparameter#1\or#1\else\plusthree\fi
652   \scratchcounter\ifchknumber#1\or\lastchknumber\else\plusthree\fi
653   \zwj\dorecurse\scratchcounter{\hskip\emwidth\zwj}%
654   \endgroup}
655
656% Suggested by GB (not the name) so we keep it for sentimental reasons:
657
658\permanent\protected\def\rapfillskip{.5\hsize plus .092\hsize minus .5\hsize} % D.A.'s value
659
660% Bovendien definieren we enkele extra \fill's:
661
662\newgluespec\s_spac_fi         \s_spac_fi        \zeropoint \s!plus 1\s!fi   \relax
663\newgluespec\s_spac_fil        \s_spac_fil       \zeropoint \s!plus 1\s!fil  \relax
664\newgluespec\s_spac_fill       \s_spac_fill      \zeropoint \s!plus 1\s!fill \relax
665\newgluespec\s_spac_filll      \s_spac_filll     \zeropoint \s!plus 1\s!filll\relax
666
667\newgluespec\s_spac_neg_fi     \s_spac_neg_fi    \zeropoint \s!plus-1\s!fi  \relax
668\newgluespec\s_spac_neg_fil    \s_spac_neg_fil   \zeropoint \s!plus-1\s!fil  \relax
669\newgluespec\s_spac_neg_fill   \s_spac_neg_fill  \zeropoint \s!plus-1\s!fill \relax
670\newgluespec\s_spac_neg_filll  \s_spac_neg_filll \zeropoint \s!plus-1\s!filll\relax
671
672\permanent\protected\untraced\def\hfilll   {\hskip\s_spac_filll\relax}
673\permanent\protected\untraced\def\vfilll   {\vskip\s_spac_filll\relax}
674
675\permanent\protected\untraced\def\hfillneg {\hskip\s_spac_neg_fill \relax}
676\permanent\protected\untraced\def\hfilllneg{\hskip\s_spac_neg_filll\relax}
677\permanent\protected\untraced\def\vfillneg {\vskip\s_spac_neg_fill \relax}
678\permanent\protected\untraced\def\vfilllneg{\vskip\s_spac_neg_filll\relax}
679
680\permanent\protected\def\tfskip    {\begingroup\tf\hskip\emwidth\endgroup}
681\permanent\protected\def\dotfskip#1{\begingroup\tf\hskip      #1\endgroup} % used elsewhere
682
683% maybe we should hash the analysis
684
685\installcorenamespace{narrower}
686\installcorenamespace{narrowermethod}
687
688\newgluespec\s_spac_narrower_left
689\newgluespec\s_spac_narrower_right
690\newgluespec\s_spac_narrower_middle
691
692\installcommandhandler \??narrower {narrower} \??narrower
693
694\setupnarrower
695  [\c!before=\endgraf,
696   \c!after=\endgraf,
697   \c!left=1.5\emwidth,
698   \c!right=1.5\emwidth,
699   \c!middle=1.5\emwidth,
700   \c!default=\v!middle]
701
702\appendtoks
703   \frozen\instance\protected\edefcsname\e!start\currentnarrower\endcsname{\spac_narrower_start[\currentnarrower]}%
704   \frozen\instance\protected\edefcsname\e!stop \currentnarrower\endcsname{\spac_narrower_stop}%
705\to \everydefinenarrower
706
707\permanent\protected\def\installnarrowermethod#1#2%
708  {\defcsname\??narrowermethod#1\endcsname{#2}}
709
710\protected\def\spac_narrower_method_analyze#1%
711  {\ifcsname\??narrowermethod#1\endcsname
712     \lastnamedcs
713   \else
714     \global\advanceby\s_spac_narrower_middle#1\relax
715   \fi}
716
717\def\spac_narrower_initialize[#1]% hm, can be dorepeat directly
718  {\dorepeatwithcommand[#1]\spac_narrower_method_analyze}
719
720\installnarrowermethod  \v!left   {\global\advanceby\s_spac_narrower_left   \narrowerparameter\c!left  \relax}
721\installnarrowermethod  \v!middle {\global\advanceby\s_spac_narrower_middle \narrowerparameter\c!middle\relax}
722\installnarrowermethod  \v!right  {\global\advanceby\s_spac_narrower_right  \narrowerparameter\c!right \relax}
723\installnarrowermethod{-\v!left  }{\global\advanceby\s_spac_narrower_left  -\narrowerparameter\c!left  \relax}
724\installnarrowermethod{-\v!middle}{\global\advanceby\s_spac_narrower_middle-\narrowerparameter\c!middle\relax}
725\installnarrowermethod{-\v!right }{\global\advanceby\s_spac_narrower_right -\narrowerparameter\c!right \relax}
726\installnarrowermethod  \v!reset  {\global          \s_spac_narrower_left   \zeroskip
727                                   \global          \s_spac_narrower_middle \zeroskip
728                                   \global          \s_spac_narrower_right  \zeroskip\relax}
729\installnarrowermethod \v!none    {}
730\installnarrowermethod \v!reverse {} % never seen
731
732\permanent\overloaded\tolerant\protected\def\spac_narrower_start[#1]#*[#2]%
733  {\begingroup
734   \cdef\currentnarrower{#1}%
735   \ifparameter#2\or
736     \spac_narrower_start_apply{#2}%
737   \else
738     \spac_narrower_start_apply{\narrowerparameter\v!default}%
739   \fi}
740
741\newgluespec   \s_spac_narrower_left_last
742\newgluespec   \s_spac_narrower_right_last
743\newconditional\s_spac_narrower_last_swap
744
745\def\spac_narrower_start_apply#1%
746  {\narrowerparameter\c!before
747   \global\s_spac_narrower_left  \zeroskip
748   \global\s_spac_narrower_right \zeroskip
749   \global\s_spac_narrower_middle\zeroskip
750   \edef\scratchstringone{#1}%
751   \ifx\scratchstringone\v!reverse
752     \ifconditional\s_spac_narrower_last_swap
753       \frozen\leftskip \s_spac_narrower_right_last
754       \frozen\rightskip\s_spac_narrower_left_last
755       \s_spac_narrower_last_swap\conditionalfalse
756     \else
757       \frozen\leftskip \s_spac_narrower_left_last
758       \frozen\rightskip\s_spac_narrower_right_last
759       \s_spac_narrower_last_swap\conditionaltrue
760     \fi
761   \else
762     \normalexpanded{\processcommalistwithparameters[\scratchstringone]}\spac_narrower_initialize
763     \frozen\advanceby\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax
764     \frozen\advanceby\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax
765   \fi
766   \seteffectivehsize}
767
768\permanent\protected\def\spac_narrower_stop
769  {\narrowerparameter\c!after
770   \normalexpanded{%
771      \endgroup
772      \s_spac_narrower_left_last \the\leftskip \relax
773      \s_spac_narrower_right_last\the\rightskip\relax
774      \ifconditional\s_spac_narrower_last_swap
775        \s_spac_narrower_last_swap\conditionalfalse
776      \else
777        \s_spac_narrower_last_swap\conditionaltrue
778      \fi
779   }}
780
781\permanent\tolerant\protected\def\startnarrower[#1]%
782  {\begingroup
783   \lettonothing\currentnarrower
784   \ifparameter#1\or
785     \spac_narrower_start_apply{#1}%
786   \else
787     \spac_narrower_start_apply{\narrowerparameter\v!default}%
788   \fi}
789
790\aliased\let\stopnarrower\spac_narrower_stop
791
792\permanent\tolerant\protected\def\startnarrow[#S#1]#*[#S#2]% current how
793  {\begingroup
794   \ifnum\lastarguments=\plustwo
795      \expandafter\spac_narrower_start_named_two
796   \else
797      \expandafter\spac_narrower_start_named_one
798   \fi[#1][#2]}
799
800% we can combine these:
801
802\def\spac_narrower_start_named_one[#S#1]%
803  {\doifelseassignment{#1}\spac_narrower_start_named_one_yes\spac_narrower_start_named_one_nop[#1]}
804
805\def\spac_narrower_start_named_one_yes[#S#1][#2]% [settings] []
806  {\setupcurrentnarrower[#1]%
807   \spac_narrower_start_apply{\narrowerparameter\v!default}}
808
809\def\spac_narrower_start_named_one_nop[#1][#2]% [tag] []
810  {\cdef\currentnarrower{#1}%
811   \spac_narrower_start_apply{\narrowerparameter\v!default}}
812
813\def\spac_narrower_start_named_two[#S#1]%
814  {\doifelseassignment{#1}\spac_narrower_start_named_settings_how\spac_narrower_start_named_tag_unknown[#1]}
815
816\def\spac_narrower_start_named_settings_how[#S#1][#2]% [settings] [how]
817  {\setupcurrentnarrower[#1]%
818   \spac_narrower_start_apply{#2}}
819
820\def\spac_narrower_start_named_tag_unknown[#1][#S#2]% [tag] [...]
821  {\doifelseassignment{#2}\spac_narrower_start_named_tag_settings\spac_narrower_start_named_tag_how[#1][#2]}
822
823\def\spac_narrower_start_named_tag_settings[#1][#S#2]% [tag] [settings]
824  {\cdef\currentnarrower{#1}%
825   \setupcurrentnarrower[#2]%
826   \spac_narrower_start_apply{\narrowerparameter\v!default}}
827
828\def\spac_narrower_start_named_tag_how[#1][#2]% [tag] [how]
829  {\cdef\currentnarrower{#1}%
830   \spac_narrower_start_apply{#2}}
831
832\aliased\let\stopnarrow\spac_narrower_stop
833
834\newdimension\d_spac_effective_hsize     \permanent\protected\def\effectivehsize    {\hsize}
835\newdimension\d_spac_effective_leftskip  \permanent\protected\def\effectiveleftskip {\dimexpr\leftskip \relax}
836\newdimension\d_spac_effective_rightskip \permanent\protected\def\effectiverightskip{\dimexpr\rightskip\relax}
837
838\permanent\protected\def\seteffectivehsize
839  {\setlocalhsize
840   \d_spac_effective_hsize     \localhsize
841   \d_spac_effective_leftskip 1\leftskip
842   \d_spac_effective_rightskip1\rightskip
843   \enforced\let\effectivehsize    \d_spac_effective_hsize
844   \enforced\let\effectiveleftskip \d_spac_effective_leftskip
845   \enforced\let\effectiverightskip\d_spac_effective_rightskip}
846
847\installcorenamespace{skipadaptionleft}
848\installcorenamespace{skipadaptionright}
849
850\newgluespec\leftskipadaption
851\newgluespec\rightskipadaption
852
853\defcsname\??skipadaptionleft \v!yes\endcsname{\ifzeropt\d_spac_indentation_par\narrowerparameter\c!left\else\d_spac_indentation_par\fi}
854\letcsname\??skipadaptionleft \v!no \endcsname\zeropoint % \zeroskip
855\letcsname\??skipadaptionleft \empty\endcsname\zeropoint % \zeroskip
856\defcsname\??skipadaptionright\v!yes\endcsname{\narrowerparameter\c!right}
857\letcsname\??skipadaptionright\v!no \endcsname\zeropoint % \zeroskip
858\letcsname\??skipadaptionright\empty\endcsname\zeropoint % \zeroskip
859
860\letcsname\??skipadaptionleft \v!standard\expandafter\endcsname\csname\??skipadaptionleft \v!yes\endcsname
861\letcsname\??skipadaptionright\v!standard\expandafter\endcsname\csname\??skipadaptionright\v!yes\endcsname
862
863\permanent\protected\def\dosetleftskipadaption #1{\leftskipadaption \ifcsname\??skipadaptionleft #1\endcsname\lastnamedcs\else#1\fi\relax}
864\permanent\protected\def\dosetrightskipadaption#1{\rightskipadaption\ifcsname\??skipadaptionright#1\endcsname\lastnamedcs\else#1\fi\relax}
865
866\permanent\protected\def\doadaptleftskip #1{\normalexpanded{\dosetleftskipadaption {#1}}\frozen\advanceby\leftskip \leftskipadaption }
867\permanent\protected\def\doadaptrightskip#1{\normalexpanded{\dosetrightskipadaption{#1}}\frozen\advanceby\rightskip\rightskipadaption}
868
869\permanent\protected\def\forgetbothskips
870  {\leftskip \zeroskip
871   \rightskip\zeroskip
872   \relax}
873
874\appendtoks
875    \forgetbothskips
876\to \everyforgetall
877
878% in spac-ver.mkiv
879%
880% \protected\def\forgetparskip
881%   {\s_spac_whitespace_parskip\zeroskip
882%    \parskip\zeroskip
883%    \let\v_spac_whitespace_current\v!none}
884%
885% \appendtoks
886%     \forgetparskip
887% \to \everyforgetall
888
889%D Tolerance (can also be set with align):
890
891\installcorenamespace{tolerancemethods}
892
893\mutable\lettonothing\bottomtolerance % why not zero (not used annyway, but for now we keep it)
894
895\permanent\protected\def\installtolerancemethod#1#2#3%
896  {\defcsname\??tolerancemethods#1:#2\endcsname{#3}}
897
898\installtolerancemethod \v!vertical   \v!verystrict   {\lettonothing\bottomtolerance} % why not zero
899\installtolerancemethod \v!vertical   \v!strict       {\def\bottomtolerance{.050}}
900\installtolerancemethod \v!vertical   \v!tolerant     {\def\bottomtolerance{.075}}
901\installtolerancemethod \v!vertical   \v!verytolerant {\def\bottomtolerance{.100}}
902
903\installtolerancemethod \v!horizontal \v!stretch      {\emergencystretch\bodyfontsize\relax}
904\installtolerancemethod \v!horizontal \v!space        {\spaceskip.5em\s!plus.25em\s!minus.25em\relax}
905\installtolerancemethod \v!horizontal \v!verystrict   {\tolerance\plustwohundred}
906\installtolerancemethod \v!horizontal \v!strict       {\tolerance1500 }
907\installtolerancemethod \v!horizontal \v!tolerant     {\tolerance3000 }
908\installtolerancemethod \v!horizontal \v!verytolerant {\tolerance4500 }
909
910\appendetoks
911     \pretolerance\plushundred
912     \tolerance   \plustwohundred
913\to\everyforgetall
914
915\def\spac_tolerances_step_vertical  #1{\csname\??tolerancemethods\v!vertical  :#1\endcsname}
916\def\spac_tolerances_step_horizontal#1{\csname\??tolerancemethods\v!horizontal:#1\endcsname}
917
918\permanent\tolerant\protected\def\setuptolerance[#1]%
919  {\ifarguments\or
920     \ifinset\v!vertical{#1}%
921       \processcommacommand[#1]\spac_tolerances_step_vertical
922     \else
923       \processcommacommand[#1]\spac_tolerances_step_horizontal
924     \fi
925   \fi}
926
927% %D \macros
928% %D   {pushindentation,popindentation}
929% %D
930% %D The pushing and popping is done by:
931%
932% \newbox\b_spac_indentations_a
933% \newbox\b_spac_indentations_b
934%
935% \permanent\protected\def\pushindentation
936%   {\begingroup
937%    \ifhmode
938%      \unskip
939%      \setbox\b_spac_indentations_a\lastbox       % get \strut if present
940%      \unskip
941%      \setbox\b_spac_indentations_b\lastbox       % get \indent generated box
942%      \unskip
943%    \else
944%      \dontleavehmode % was \hskip\zeroskip       % switch to horizontal mode
945%      \unskip
946%      \setbox\b_spac_indentations_a\lastbox       % get \indent generated box
947%      \setbox\b_spac_indentations_b\emptybox
948%    \fi}
949%
950% \permanent\protected\def\popindentation
951%   {\box\b_spac_indentations_b
952%    \box\b_spac_indentations_a
953%    \endgroup}
954
955%D Struts are done differently now.
956%D
957%D The only complication lays in \type{\strut}. In \PLAIN\ \TEX\ a \type{\strut} is
958%D defined as:
959%D
960%D \starttyping
961%D \def\strut%
962%D   {\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
963%D \stoptyping
964%D
965%D But what is a \type {\strut}? Normally it's a rule of width zero, but when made
966%D visual, it's a rule and a negative skip. The mechanism for putting things in the
967%D margins described here cannot handle this situation very well. One characteristic
968%D of \type {\strut} is that the \type {\unhcopy} results in entering horizontal
969%D mode, which in return leads to some indentation.
970%D
971%D To serve our purpose a bit better, the macro \type {\strut} can be redefined as:
972%D \starttyping
973%D \def\strut
974%D   {\relax\ifmmode\else\hskip\zeroskip\fi\copy\strutbox}
975%D \stoptyping
976%D
977%D Or more compatible:
978%D
979%D \starttyping
980%D \def\strut
981%D   {\relax\ifmmode
982%D      \copy\strutbox
983%D    \else
984%D      \bgroup\setbox\strutbox=\hbox{\box\strutbox}\unhcopy\strutbox\egroup
985%D    \fi}
986%D \stoptyping
987%D
988%D In \CONTEXT\ however we save some processing time by putting an extra \type
989%D {\hbox} around the \type {\strutbox}.
990%D
991%D \starttyping
992%D % \setuplayout[gridgrid=yes] \showgrid
993%D
994%D \startbuffer
995%D test 1\crlf
996%D test 2\crlf
997%D
998%D \crlf test 3
999%D
1000%D test 4\crlf
1001%D test 5
1002%D
1003%D \crlf
1004%D \crlf
1005%D \crlf
1006%D test 6
1007%D \stopbuffer
1008%D
1009%D \hbox
1010%D   {\hsize5em
1011%D    \ruledvtop{\getbuffer}\enspace
1012%D    \ruledvtop{\showstruts\getbuffer}\enspace
1013%D    \hsize15em \setuptyping[before=,after=]%
1014%D    \ruledvtop{\typebuffer}}
1015%D \stoptyping
1016
1017\permanent\protected\def\justonespace{\removeunwantedspaces\space}
1018%permanent\protected\def\justaperiod {\removeunwantedspaces.}
1019%permanent\protected\def\justacomma  {\removeunwantedspaces,}
1020
1021\installcorenamespace{hspace}
1022
1023\permanent\protected\def\ignorecrlf
1024  {\enforced\let\crlf\justonespace
1025   \enforced\let\\\crlf}
1026
1027\permanent\tolerant\protected\def\definehspace[#1]#*[#2]#*[#3]% #1 = optional namespace
1028  {\ifparameter#3\or
1029     \defcsname\??hspace#1:#2\endcsname{#3}%
1030   \else
1031     \defcsname\??hspace  :#1\endcsname{#2}%
1032   \fi}
1033
1034\permanent\tolerant\protected\def\hspace[#1]#*[#2]%
1035  {\ifhmode
1036     \removeunwantedspaces
1037     \hskip % always a skip even when 0pt
1038       \ifparameter#2\or
1039         \hspaceamount{#1}{#2}%
1040       \orelse\ifparameter#1\or
1041         \hspaceamount\empty{#1}%
1042       \else
1043         \hspaceamount\empty\s!default
1044       \fi
1045     \relax
1046     \expandafter\ignorespaces
1047   \fi}
1048
1049\permanent\overloaded\def\hspaceamount      #1#2{\dimexpr\ifcsname\??hspace#1:#2\endcsname\lastnamedcs\else\zeropoint\fi\relax}
1050\permanent\overloaded\def\directhspaceamount  #1{\dimexpr\ifcsname\??hspace  :#1\endcsname\lastnamedcs\else\zeropoint\fi\relax}
1051
1052% no installhspace here (this is already an old command)
1053
1054\definehspace [\v!small]   [.25\emspaceamount]
1055\definehspace [\v!medium]  [.5\emspaceamount]
1056\definehspace [\v!big]     [1\emspaceamount]
1057\definehspace [\v!normal]  [1\spaceamount]
1058\definehspace [\v!default] [\spaceamount]
1059\definehspace [\v!none]    [\zeropoint] % \zeroskip
1060
1061%D Taken from Taco's math module (cq. \AMS\ macros), but %D adapted to \type
1062%D {\hspace}:
1063
1064\permanent\protected\def\textormathspace         #1#2#3{\ifmmode\mskip#1#2\else\kern #1\hspaceamount\empty{#3}\fi\relax}
1065\permanent\protected\def\textormathspacecommand  #1#2#3{\ifmmode\mskip#1#2\else#3\fi\relax}
1066\permanent\protected\def\breakabletextormathspace#1#2#3{\ifmmode\mskip#1#2\else\hskip#1\hspaceamount\empty{#3}\fi\relax}
1067
1068\overloaded\permanent\protected \def\hairspace    {\textormathspace+\hairmuskip{.5}}
1069\overloaded\permanent\protected \def\thinspace    {\textormathspace+\thinmuskip 1}
1070%overloaded\permanent\protected \def\medspace     {\textormathspace+\medmuskip  2}      % 4/18 em
1071\overloaded\permanent\protected \def\thickspace   {\textormathspace+\thickmuskip3}
1072\overloaded\permanent\protected \def\neghairspace {\textormathspace-\thinmuskip{.5}}
1073\overloaded\permanent\protected \def\negthinspace {\textormathspace-\thinmuskip 1}
1074\overloaded\permanent\protected \def\negmedspace  {\textormathspace-\medmuskip  2}
1075\overloaded\permanent\protected \def\negthickspace{\textormathspace-\thickmuskip3}
1076\overloaded\permanent\protected\edef\medspace     {\textormathspacecommand+\medmuskip{\tocharacter"205F}}
1077
1078% maybe
1079
1080% \protected\def\breakablethinskip      {\breakabletextormathspace+\thinmuskip1}
1081% \protected\def\twoperemskip           {\hskip\dimexpr\emwidth/2\relax} % == \enspace
1082% \protected\def\threeperemskip         {\hskip\dimexpr\emwidth/3\relax}
1083% \protected\def\fourperemskip          {\hskip\dimexpr\emwidth/4\relax}
1084% \protected\def\fiveperemskip          {\hskip\dimexpr\emwidth/5\relax} % goodie
1085% \protected\def\sixperemskip           {\hskip\dimexpr\emwidth/6\relax}
1086% \protected\def\figureskip             {\begingroup\setbox\scratchbox\hbox{0}\hskip\wd\scratchbox\endgroup} % there is a command for this
1087% \protected\def\punctuationskip        {\begingroup\setbox\scratchbox\hbox{.}\hskip\wd\scratchbox\endgroup}
1088% \protected\def\ideographicskip        {\hskip\dimexpr\emwidth/1\relax}
1089% \protected\def\ideographichalffillskip{\hskip\dimexpr\emwidth/2\relax}
1090% \protected\def\nobreakskip            {\penalty\plustenthousand\kern\interwordspace}
1091% \protected\def\narrownobreakskip      {\penalty\plustenthousand\thinspace}
1092% \protected\def\zerowidthnobreakskip   {\penalty\plustenthousand\kern\zeropoint}
1093% \protected\def\zerowidthskip          {\hskip\zeroskip}
1094
1095\definehspace[.5][.1250\emwidth] % hair
1096\definehspace[1] [.1667\emwidth] % thin
1097\definehspace[2] [.2222\emwidth] % med
1098\definehspace[3] [.2777\emwidth] % thick
1099
1100% These will be redefined anyway in math-ini:
1101
1102\suggestedalias \, \thinspace
1103\suggestedalias \: \medspace
1104\suggestedalias \; \thickspace
1105\suggestedalias \! \negthinspace
1106
1107% plain ...
1108%
1109% \ifdefined\> \else \protected\def\>{\mskip \medmuskip  }                                \fi
1110% \ifdefined\* \else \protected\def\*{\discretionary{\thinspace\the\textfont2\char2}{}{}} \fi
1111
1112\permanent\def\flexiblespaceamount#1#2#3%
1113         {#1\interwordspace
1114   \s!plus#2\interwordstretch
1115  \s!minus#3\interwordshrink}
1116
1117\permanent\def\fixedspaceamount#1%
1118  {#1\interwordspace}
1119
1120% moved from page-lin
1121%
1122% the following code is used in startlines\stoplines
1123%
1124% do we need \normalspaceprimitive here?
1125
1126\installcorenamespace{spacemethods}
1127
1128\permanent\protected\def\installspacemethod#1#2% needs to set \obeyedspace
1129  {\defcsname\??spacemethods#1\endcsname{#2}}
1130
1131\permanent\def\activatespacehandler#1%
1132  {\csname\??spacemethods\ifcsname\??spacemethods#1\endcsname#1\else\v!off\fi\endcsname}
1133
1134\permanent\protected\def\spac_spaces_checked_control{\mathortext\normalspace{\dontleavehmode{\tt\controlspace}}}%
1135\permanent\protected\def\spac_spaces_checked_normal {\mathortext\normalspace{\dontleavehmode\normalspace}}%
1136\permanent\protected\def\spac_spaces_checked_fixed  {\mathortext\normalspace{\dontleavehmode\fixedspace}}%
1137
1138% hm, order matters when we \let in \obeyspaces
1139
1140\installspacemethod \v!on
1141  {\obeyspaces
1142   \enforced\let\obeyedspace\spac_spaces_checked_control
1143   \enforced\let\ =\obeyedspace}
1144
1145\installspacemethod \v!yes
1146  {\obeyspaces
1147   \enforced\let\obeyedspace\spac_spaces_checked_normal
1148   \enforced\let\ =\obeyedspace}
1149
1150\installspacemethod \v!off % == default
1151  {\normalspaces
1152   \enforced\let\obeyedspace\normalspace
1153   \enforced\let\ =\normalspaceprimitive} % was \normalspace
1154
1155\installspacemethod \v!fixed
1156  {\obeyspaces
1157   \enforced\let\obeyedspace\spac_spaces_checked_fixed
1158   \enforced\let\ =\obeyedspace}
1159
1160\appendtoks
1161   \normalspaces % to be sure
1162\to \everybeforeoutput
1163
1164%D A more robust variant of the \MKII\ one:
1165%D
1166%D \startbuffer
1167%D bla \TEX\autoinsertnextspace bla
1168%D bla \TEX\autoinsertnextspace (bla)
1169%D bla (\TEX\autoinsertnextspace) bla
1170%D bla \TEX\autoinsertnextspace\ bla
1171%D \stopbuffer
1172%D
1173%D \typebuffer \getbuffer
1174
1175% \autoinsertnextspace % defined at the lua end
1176
1177%D Moved from bib module:
1178
1179\permanent\protected\def\outdented#1%
1180  {\hskip-\hangindent#1\relax}
1181
1182%D Beware: due to char-def this becomes an active character but that might change
1183%D sometime when we will replace all these specials to node insertions. We might
1184%D even expand it to utf then as it then can be used in string comparison (not that
1185%D much needed anyway).
1186
1187% \chardef\zwnj="200C
1188% \chardef\zwj ="200D
1189
1190% TODO (but used in languages):
1191
1192\def\spac_glues_text_or_math#1#2%
1193  {\begingroup
1194   \ifmmode
1195     \mskip#1%
1196   \else
1197     \scratchdimen#1\hspaceamount\empty{#2}%
1198     \scratchskip\scratchdimen\s!plus.5\scratchdimen\s!minus.3\scratchdimen
1199     \hskip\scratchskip
1200   \fi
1201   \endgroup}
1202
1203\permanent\protected\def\thinglue {\spac_glues_text_or_math\thinmuskip \v!small}
1204\permanent\protected\def\medglue  {\spac_glues_text_or_math\medmuskip  \v!medium}
1205\permanent\protected\def\thickglue{\spac_glues_text_or_math\thickmuskip\v!big}
1206
1207%D A rather unknown one:
1208
1209\permanent\protected\def\widened % moved from cont-new
1210  {\doifelsenextoptionalcs\spac_widened_yes\spac_widened_nop}
1211
1212\def\spac_widened_yes[#1]#2{\hbox \s!spread       #1{\hss#2\hss}}
1213\def\spac_widened_nop    #1{\hbox \s!spread \emwidth{\hss#1\hss}}
1214
1215%D For the moment here (used in page-txt):
1216
1217\permanent\protected\def\ignoredlinebreak{\unskip\space\ignorespaces}
1218
1219%D \macros
1220%D   {startignorespaces}
1221%D
1222%D I'll probably forget that this one exists:
1223%D
1224%D \starttyping
1225%D \ruledhbox
1226%D   {\startignorespaces
1227%D      \def\oeps{a}
1228%D      \startignorespaces
1229%D        \def\oeps{a}
1230%D      \stopignorespaces
1231%D      \def\oeps{a}
1232%D    \stopignorespaces
1233%D    \oeps}
1234%D \stoptyping
1235
1236% \newsignal \d_spac_ignore_spaces_signal
1237% \newinteger\c_spac_ignore_spaces
1238%
1239% \permanent\protected\def\startignorespaces
1240%   {\advanceby\c_spac_ignore_spaces\plusone
1241%    \ifcase\c_spac_ignore_spaces\or \ifhmode
1242%      \hskip\d_spac_ignore_spaces_signal
1243%    \fi \fi
1244%    \ignorespaces}
1245%
1246% \permanent\protected\def\stopignorespaces
1247%   {\ifcase\c_spac_ignore_spaces \or
1248%      \ifhmode
1249%        \doloop\spac_ignore_spaces_body
1250%      \fi
1251%    \fi
1252%    \advanceby\c_spac_ignore_spaces\minusone}
1253%
1254% \def\spac_ignore_spaces_body
1255%   {\ifzeropt\lastskip
1256%      \exitloop
1257%    \orelse\ifdim\lastskip=\d_spac_ignore_spaces_signal
1258%      \unskip
1259%      \exitloop
1260%    \else
1261%      \unskip
1262%    \fi}
1263
1264\permanent\protected\def\startignorespaces
1265  {\pushmacro\nospaces
1266   \nospaces\plusone}
1267
1268\permanent\protected\def\stopignorespaces
1269  {\popmacro\nospaces}
1270
1271%D \macros
1272%D   {obeyfollowingtoken}
1273
1274\permanent\def\obeyfollowingtoken{{}}  % end \cs scanning
1275
1276%D Something new:
1277
1278\permanent\protected\def\interwordspacebefore{\wordboundary\zwnj\hskip\interwordspace\relax}
1279\permanent\protected\def\interwordspaceafter {\hskip\interwordspace\relax\zwnj\wordboundary}
1280
1281\permanent\protected\def\interwordspacesbefore#1{\dofastloopcs{#1}\interwordspacebefore}
1282\permanent\protected\def\interwordspacesafter #1{\dofastloopcs{#1}\interwordspaceafter}
1283\permanent\protected\def\interwordspaces      #1{\wordboundary\zwnj\dofastloopcs{\numexpr#1+\minusone}\interwordspaceafter}
1284
1285%D For mp:
1286
1287\installcorenamespace{mplocation}
1288
1289\defcsname\??mplocation\v!left \endcsname{1}
1290\defcsname\??mplocation\v!right\endcsname{2}
1291\defcsname\??mplocation\v!inner\endcsname{3}
1292\defcsname\??mplocation\v!outer\endcsname{4}
1293
1294\permanent\def\mplocation#1{\ifcsname\??mplocation#1\endcsname\lastnamedcs\else0\fi}
1295%permanent\def\mplocation#1{\csname\??mplocation\ifcsname\??mplocation#1\endcsname#1\else\v!left\fi\endcsname}
1296
1297% new: \lateindent \lateundent
1298
1299% \parinitleftskip1cm \parindent 1cm \indent test \par
1300% \parinitleftskip1cm \parindent 1cm \undent test \par
1301% \parinitleftskip1cm \parindent 1cm \indent \undent test \par
1302% \parinitleftskip1cm \parindent 1cm \indent \strut \undent test \par
1303% \parinitleftskip1cm \parindent 1cm \strut \lateindent 2cm test \par
1304% \parinitleftskip1cm \parindent 1cm \strut \lateindent 2cm test \lateundent \par
1305
1306\protect \endinput
1307