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