spac-par.mkiv /size: 8994 b    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=spac-par,
3%D        version=2009.10.16, % 1997.03.31, was core-spa.tex
4%D          title=\CONTEXT\ Spacing Macros,
5%D       subtitle=Paragraphs,
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 / Paragraphs}
15
16\unprotect
17
18%D The dreadful sequence \type {\bgroup} \unknown\ \type {\carryoverpar} \unknown\
19%D \type {\egroup} is needed when for instance sidefloats are used in combination
20%D with something that starts with a group. This is because otherwise the
21%D indentation as set (by the output routine) inside the group are forgotten
22%D afterwards. (I must not forget its existence).
23
24% Todo (maybe):
25%
26% \parshape             \getparshape\relax
27% \interlinepenalties   \getinterlinepenalties\relax
28% \clubpenalties        \getclubpenalties\relax
29% \widowpenalties       \getwidowpenalties\relax
30% \displaywidowpenalties\getdisplaywidowpenalties\relax
31
32\def\carryoverpar#1% #1 can be \endgroup or \egroup or ... expandable !
33  {\normalexpanded
34     {\noexpand#1%
35      \hangindent\the\hangindent
36      \hangafter \the\hangafter
37      \parskip   \the\parskip
38      \leftskip  \the\leftskip
39      \rightskip \the\rightskip
40      \relax}}
41
42\unexpanded\def\pushparagraphproperties
43  {\edef\currentparagraphproperties{\carryoverpar\relax}%
44   \pushmacro\currentparagraphproperties}
45
46\unexpanded\def\popparagraphproperties
47  {\popmacro\currentparagraphproperties
48   \currentparagraphproperties}
49
50\unexpanded\def\flushparagraphproperties
51  {\popmacro\currentparagraphproperties}
52
53%D New experimental stuff, not supported in \MKIV:
54
55\let\freezeparagraphproperties \relax
56\let\defrostparagraphproperties\relax
57\let\setparagraphfreezing      \relax
58\let\forgetparagraphfreezing   \relax
59\let\updateparagraphproperties \relax
60\let\updateparagraphpenalties  \relax
61\let\updateparagraphdemerits   \relax
62\let\updateparagraphshapes     \relax
63
64\let\updateparwrapper  \relax
65\let\forgetparwrapper  \relax
66\let\registerparwrapper\gobblethreearguments
67\let\directparwrapper  \gobbletwoarguments
68
69\let\spac_paragraph_wrap  \relax
70\let\spac_paragraph_freeze\relax
71
72%D Beware, changing this will break some code (like pos/backgrounds) but it has been
73%D changed anyway so let's see where things go wrong.
74
75\installcorenamespace{paragraphintro}
76
77\let\insertparagraphintro\relax % hook into everypar
78
79\newtoks\t_spac_paragraphs_intro_first
80\newtoks\t_spac_paragraphs_intro_next
81\newtoks\t_spac_paragraphs_intro_each
82
83\newconditional\c_spac_paragraphs_intro_first
84\newconditional\c_spac_paragraphs_intro_next
85\newconditional\c_spac_paragraphs_intro_each
86
87\unexpanded\def\setupparagraphintro
88  {\dodoubleempty\spac_paragraphs_intro}
89
90\unexpanded\def\spac_paragraphs_intro[#1][#2]%
91  {\def\spac_paragraphs_intro_step##1%
92     {\csname\??paragraphintro\ifcsname\??paragraphintro##1\endcsname##1\fi\endcsname{#2}}%
93   \processcommacommand[#1]\spac_paragraphs_intro_step}
94
95\letvalue{\??paragraphintro\empty}\gobbleoneargument
96
97\setvalue{\??paragraphintro\v!reset}#1%
98  {\global\setfalse\c_spac_paragraphs_intro_first
99   \global\setfalse\c_spac_paragraphs_intro_next
100   \global\setfalse\c_spac_paragraphs_intro_each
101   \global\t_spac_paragraphs_intro_first\emptytoks
102   \global\t_spac_paragraphs_intro_next \emptytoks
103   \global\t_spac_paragraphs_intro_each \emptytoks
104   \glet\insertparagraphintro\relax}
105
106\setvalue{\??paragraphintro\v!first}#1%
107  {\global\settrue\c_spac_paragraphs_intro_first
108   \gtoksapp\t_spac_paragraphs_intro_first{#1}%
109   \glet\insertparagraphintro\spac_paragraphs_flush_intro}
110
111\setvalue{\??paragraphintro\v!next}#1%
112  {\global\settrue\c_spac_paragraphs_intro_next
113   \gtoksapp\t_spac_paragraphs_intro_next{#1}%
114   \glet\insertparagraphintro\spac_paragraphs_flush_intro}
115
116\setvalue{\??paragraphintro\v!each}#1%
117  {\global\settrue\c_spac_paragraphs_intro_each
118   \gtoksapp\t_spac_paragraphs_intro_each{#1}%
119   \glet\insertparagraphintro\spac_paragraphs_flush_intro}
120
121%D We can say:
122%D
123%D \starttyping
124%D \setupparagraphintro[first][\index{Knuth}]
125%D \stoptyping
126%D
127%D Maybe more convenient is:
128%D
129%D \starttyping
130%D \flushatparagraph{\index{Zapf}}
131%D \stoptyping
132%D
133%D \starttyping
134%D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}]
135%D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}]
136%D \setupparagraphintro[next] [\hbox to 3.5em{\tt NEXT  \hss}]
137%D \setupparagraphintro[next] [\hbox to 3.5em{\tt TXEN  \hss}]
138%D \setupparagraphintro[each] [\hbox to 3.0em{\tt EACH  \hss}]
139%D \setupparagraphintro[each] [\hbox to 3.0em{\tt HCEA  \hss}]
140%D
141%D some paragraph \par
142%D some paragraph \par
143%D some paragraph \par
144%D some paragraph \par
145%D
146%D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}]
147%D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}]
148%D
149%D some paragraph \par
150%D some paragraph \par
151%D
152%D \setupparagraphintro[reset]
153%D
154%D some paragraph \par
155%D \stoptyping
156
157\unexpanded\def\flushatparagraph#1%
158  {\global\c_spac_paragraphs_intro_first\plusone
159   \gtoksapp\t_spac_paragraphs_intro_first{#1}%
160   \glet\insertparagraphintro\spac_paragraphs_flush_intro}
161
162%D Here comes the flusher (we misuse the one level expansion of token registers to
163%D feed a nice stream into the paragraph.)
164
165\unexpanded\def\spac_paragraphs_flush_intro % we make sure that the token lists expand directly
166  {\normalexpanded{%                        % after another so the first code is there twice
167     \ifconditional\c_spac_paragraphs_intro_each
168       \ifconditional\c_spac_paragraphs_intro_next
169         \glet\insertparagraphintro\spac_paragraphs_flush_intro_next
170       \else
171         \glet\insertparagraphintro\spac_paragraphs_flush_intro_each
172       \fi
173       \ifconditional\c_spac_paragraphs_intro_first
174         \global\setfalse\c_spac_paragraphs_intro_first
175         \global\t_spac_paragraphs_intro_first\emptytoks
176         \the\t_spac_paragraphs_intro_first
177       \fi
178       \the\t_spac_paragraphs_intro_each
179     \else
180       \ifconditional\c_spac_paragraphs_intro_next
181         \glet\insertparagraphintro\spac_paragraphs_flush_intro_next
182       \fi
183       \ifconditional\c_spac_paragraphs_intro_first
184         \global\setfalse\c_spac_paragraphs_intro_first
185         \global\t_spac_paragraphs_intro_first\emptytoks
186         \the\t_spac_paragraphs_intro_first
187       \fi
188     \fi}}
189
190\unexpanded\def\spac_paragraphs_flush_intro_next
191  {\normalexpanded{%
192     \global\setfalse\c_spac_paragraphs_intro_next
193     \global\t_spac_paragraphs_intro_next\emptytoks
194     \ifconditional\c_spac_paragraphs_intro_each
195       \glet\insertparagraphintro\spac_paragraphs_flush_intro_each
196       \the\t_spac_paragraphs_intro_next
197       \the\t_spac_paragraphs_intro_each
198     \else
199       \glet\insertparagraphintro\relax
200       \the\t_spac_paragraphs_intro_next
201     \fi}}
202
203\unexpanded\def\spac_paragraphs_flush_intro_each
204  {\the\t_spac_paragraphs_intro_each}
205
206%D \macros
207%D   {flushatnextpar}
208%D
209%D This macro collects data that will be flushed at the next paragraph. By using
210%D this macro you can avoid interfering nodes (writes, etc).
211
212\let\flushpostponednodedata\relax % hook into everypar
213
214\newbox  \b_spac_postponed_data
215%newcount\c_spac_postponed_data
216
217% \installcorenamespace {postponednodesstack}
218%
219% \initializeboxstack\??postponednodesstack
220%
221% \unexpanded\def\pushpostponednodedata
222%   {\global\advance\c_spac_postponed_data\plusone
223%    \savebox\??postponednodesstack{\the\c_spac_postponed_data}{\box\b_spac_postponed_data}}
224%
225% \unexpanded\def\poppostponednodedata
226%   {\global\setbox\b_spac_postponed_data\hbox{\foundbox\??postponednodesstack{\the\c_spac_postponed_data}}%
227%    \global\advance\c_spac_postponed_data\minusone
228%    \ifvoid\b_spac_postponed_data\else
229%      \glet\flushpostponednodedata\spac_postponed_data_flush
230%    \fi}
231
232\newtoks\everyflushatnextpar
233
234\unexpanded\def\pushpostponednodedata
235  {\globalpushbox\b_spac_postponed_data}
236
237\unexpanded\def\poppostponednodedata
238  {\globalpopbox\b_spac_postponed_data
239   \ifvoid\b_spac_postponed_data\else
240     \glet\flushpostponednodedata\spac_postponed_data_flush
241   \fi}
242
243\unexpanded\def\flushatnextpar
244  {\begingroup
245   \the\everyflushatnextpar
246   \glet\flushpostponednodedata\spac_postponed_data_flush
247   \dowithnextboxcs\spac_postponed_data_finish\hpack}
248
249\def\spac_postponed_data_finish
250  {\global\setbox\b_spac_postponed_data\hpack % to\zeropoint
251     {\box\b_spac_postponed_data\box\nextbox}%
252   \endgroup}
253
254\def\spac_postponed_data_flush
255  {%\iftrialtypesetting \else
256     \ifvoid\b_spac_postponed_data\else
257       \hpack{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data
258     \fi
259     \glet\flushpostponednodedata\relax
260   }%\fi}
261
262\unexpanded\def\doflushatpar % might be renamed
263  {\ifvmode
264     \expandafter\flushatnextpar
265   \else
266     \expandafter\firstofoneargument
267   \fi}
268
269\protect \endinput
270