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