typo-del.mkiv /size: 29 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=typo-del, % moved from core-mis,
3%D        version=20110112,
4%D          title=\CONTEXT\ Typesetting Macros,
5%D       subtitle=Delimited Content,
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% todo: textstyle|color for inline \quotation etc
15
16\writestatus{loading}{ConTeXt Typesetting Macros / Delimited Content}
17
18\unprotect
19
20\ifdefined\dotagsetdelimitedsymbol   \else \let\dotagsetdelimitedsymbol  \gobbleoneargument \fi
21\ifdefined\dotagsetsubsentencesymbol \else \let\dotagsetsubsentencesymbol\gobbleoneargument \fi
22
23% THIS IS OBSOLETE:
24
25\installcorenamespace{hyphenmarksign} % let's not waste a setuphandler (yet)
26
27\unexpanded\def\setuphyphenmark[#1]% sign=normal|wide
28  {\getdummyparameters[#1]%
29   \expandnamespaceparameter\??hyphenmarksign\dummyparameter\c!sign\v!normal}
30
31\setvalue{\??hyphenmarksign\v!normal}%
32  {\let\textmodehyphen\normalhyphen
33   \let\textmodehyphendiscretionary\normalhyphendiscretionary}
34
35\setvalue{\??hyphenmarksign\v!wide}%
36  {\let\textmodehyphen\composedhyphen
37   \let\textmodehyphendiscretionary\composedhyphendiscretionary}
38
39\setuphyphenmark[\c!sign=\v!wide]
40
41\definesymbol[\c!lefthyphen]  [\languageparameter\c!lefthyphen]
42\definesymbol[\c!righthyphen] [\languageparameter\c!righthyphen]
43\definesymbol[\c!hyphen]      [\languageparameter\c!hyphen]
44
45\unexpanded\def\normalhyphen
46  {\hbox{\directsymbol\empty\c!hyphen}}
47
48\unexpanded\def\composedhyphen
49  {\hbox{\directsymbol\empty\c!compoundhyphen}}
50
51\unexpanded\def\normalhyphendiscretionary
52  {\discretionary
53     {\hbox{\directsymbol\empty\c!righthyphen}}
54     {\hbox{\directsymbol\empty\c!lefthyphen}}
55     {\hbox{\directsymbol\empty\c!hyphen}}}
56
57\unexpanded\def\composedhyphendiscretionary
58  {\discretionary
59     {\hbox{\directsymbol\empty\c!rightcompoundhyphen}}
60     {\hbox{\directsymbol\empty\c!leftcompoundhyphen}}
61     {\hbox{\directsymbol\empty\c!compoundhyphen}}}
62
63\let\textmodehyphen             \composedhyphen
64\let\textmodehyphendiscretionary\composedhyphendiscretionary
65
66\definesymbol[\c!leftcompoundhyphen]  [\languageparameter\c!leftcompoundhyphen]
67\definesymbol[\c!rightcompoundhyphen] [\languageparameter\c!rightcompoundhyphen]
68\definesymbol[\c!compoundhyphen]      [\languageparameter\c!compoundhyphen]
69
70% TILL HERE
71
72\setnewconstant\boundarycharactermode\plusone
73
74% old:       skip symbol skip
75% new: bound skip symbol skip bound
76
77\unexpanded\def\midboundarycharacter#1#2%
78  {\ifcase\boundarycharactermode
79   \or
80     \removeunwantedspaces
81     \wordboundary
82     \hskip\hspaceamount\currentusedlanguage{#2}%
83     \usedlanguageparameter#1%
84     \hskip\hspaceamount\currentusedlanguage{#2}%
85     \wordboundary
86     \ignorespaces
87   \or
88     \usedlanguageparameter#1%
89   \fi
90   \boundarycharactermode\plusone}
91
92% old: symbol nobreak skip
93% new: symbol nobreak skip wordboundary
94
95\unexpanded\def\leftboundarycharacter#1#2%
96  {\ifcase\boundarycharactermode
97   \or
98     \usedlanguageparameter#1%
99     \nobreak
100     \hskip\hspaceamount\currentusedlanguage{#2}% why not a kern
101     \wordboundary
102   \or
103     \usedlanguageparameter#1%
104   \fi
105   \boundarycharactermode\plusone}
106
107% old: preword         skip symbol
108% new: bound   nobreak skip symbol
109
110\unexpanded\def\rightboundarycharacter#1#2%
111  {\ifcase\boundarycharactermode
112   \or
113     \wordboundary
114     \nobreak
115     \hskip\hspaceamount\currentusedlanguage{#2}% why not a kern
116     \usedlanguageparameter#1%
117   \or
118     \usedlanguageparameter#1%
119   \fi
120   \boundarycharactermode\plusone}
121
122\definehspace [sentence]      [\zeropoint]
123\definehspace [intersentence] [.250\emwidth]
124
125\definesymbol
126  [\c!midsentence]
127  [\midboundarycharacter\c!midsentence{sentence}]
128
129\definesymbol
130  [\c!leftsentence]
131  [\leftboundarycharacter\c!leftsentence{sentence}]
132
133\definesymbol
134  [\c!rightsentence]
135  [\rightboundarycharacter\c!rightsentence{sentence}]
136
137\definesymbol
138  [\c!leftsubsentence]
139  [\leftboundarycharacter\c!leftsubsentence{sentence}]
140
141\definesymbol
142  [\c!rightsubsentence]
143  [\rightboundarycharacter\c!rightsubsentence{sentence}]
144
145\newsignal\d_typo_subsentence_signal
146\newcount \c_typo_subsentence_nesting
147
148\let\beforesubsentence\donothing
149\let\aftersubsentence \donothing
150
151% todo: make this language option
152%
153% \def\beforesubsentence{\removeunwantedspaces}
154% \def\aftersubsentence {\ignorespaces}
155
156\newconditional\c_typo_subsentence_cleanup  \settrue\c_typo_subsentence_cleanup
157
158\def\typo_subsentence_cleanup_start
159  {\ifconditional\c_typo_subsentence_cleanup
160     \expandafter\ignorespaces
161   \fi}
162
163\def\typo_subsentence_cleanup_stop
164  {\ifconditional\c_typo_subsentence_cleanup
165     \removeunwantedspaces
166   \fi}
167
168\unexpanded\def\midsentence
169  {\dostarttagged\t!subsentencesymbol\empty
170   \dotagsetsubsentencesymbol\s!middle
171   \symbol[\c!midsentence]%
172   \dostoptagged}
173
174\unexpanded\def\beginofsubsentence
175  {\beforesubsentence
176   \ifdim\lastkern=\d_typo_subsentence_signal
177     \unskip
178     \kern\hspaceamount\currentusedlanguage{intersentence}%
179   \fi
180   \global\advance\c_typo_subsentence_nesting\plusone
181   \ifnum\c_typo_subsentence_nesting=\plusone
182     \dontleavehmode
183   \fi
184   \dostarttagged\t!subsentence\empty % no chain
185   \dostarttagged\t!subsentencesymbol\empty
186   \dotagsetsubsentencesymbol\s!left
187   \symbol[\ifodd\c_typo_subsentence_nesting\c!leftsentence\else\c!leftsubsentence\fi]%
188   \dostoptagged
189   \dostarttagged\t!subsentencecontent\empty
190   \typo_subsentence_cleanup_start}
191
192\unexpanded\def\endofsubsentence % relax prevents space gobbling
193  {\typo_subsentence_cleanup_stop
194   \dostoptagged
195   \dostarttagged\t!subsentencesymbol\empty
196   \dotagsetsubsentencesymbol\s!right
197   \symbol[\ifodd\c_typo_subsentence_nesting\c!rightsentence\else\c!rightsubsentence\fi]%
198   \dostoptagged
199   \dostoptagged
200   \global\advance\c_typo_subsentence_nesting\minusone
201   \unskip
202   \kern\d_typo_subsentence_signal\relax
203   \aftersubsentence}
204
205\unexpanded\def\beginofsubsentencespacing % relax prevents space gobbling
206  {\kern\d_typo_subsentence_signal\relax}% \ignorespaces}
207
208\unexpanded\def\endofsubsentencespacing
209  {\ifdim\lastkern=\d_typo_subsentence_signal
210     \unskip
211     \hskip\hspaceamount\currentusedlanguage{intersentence}%
212     % no good, actually language dependent:
213     % \ignorespaces
214   \else
215     \unskip
216   \fi}
217
218%D \startbuffer
219%D test |<|test |<|test|>| test|>| test \par
220%D test|<|test|<|test|>|test|>|test \par
221%D test |<||<|test|>||>| test \par
222%D test \directdiscretionary{<}test\directdiscretionary{>} test \par
223%D \stopbuffer
224%D
225%D \typebuffer
226%D \getbuffer
227
228%unexpanded\def\startsubsentence{\beginofsubsentence\prewordbreak\beginofsubsentencespacing\typo_subsentence_cleanup_start}
229%unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\endofsubsentencespacing\prewordbreak\endofsubsentence}
230%unexpanded\def\subsentence     {\groupedcommandcs\startsubsentence\stopsubsentence}
231%unexpanded\def\midsubsentence  {\typo_subsentence_cleanup_start\prewordbreak\midsentence\prewordbreak\typo_subsentence_cleanup_stop}
232
233\unexpanded\def\startsubsentence{\beginofsubsentence\wordboundary\beginofsubsentencespacing\wordboundary\typo_subsentence_cleanup_start}
234\unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\wordboundary\endofsubsentencespacing\wordboundary\endofsubsentence}
235\unexpanded\def\subsentence     {\groupedcommandcs\startsubsentence\stopsubsentence}
236\unexpanded\def\midsubsentence  {\typo_subsentence_cleanup_start\wordboundary\midsentence\wordboundary\typo_subsentence_cleanup_stop}
237
238\definehspace [quotation]      [\zeropoint]
239\definehspace [interquotation] [.125em]
240
241%definehspace [quote]  [\zeropoint]
242%definehspace [speech] [\zeropoint]
243
244\definehspace [quote]  [\hspaceamount\currentusedlanguage{quotation}]
245\definehspace [speech] [\hspaceamount\currentusedlanguage{quotation}]
246
247\definesymbol
248  [\c!leftquotation]
249  [\leftboundarycharacter\c!leftquotation{quotation}]
250
251\definesymbol
252  [\c!rightquotation]
253  [\rightboundarycharacter\c!rightquotation{quotation}]
254
255\definesymbol
256  [\c!nextleftquotation]
257  [\rightboundarycharacter\c!leftquotation{quotation}]
258
259\definesymbol
260  [\c!nextrightquotation]
261  [\leftboundarycharacter\c!rightquotation{quotation}]
262
263\definesymbol
264  [\c!leftquote]
265  [\leftboundarycharacter\c!leftquote{quote}]
266
267\definesymbol
268  [\c!rightquote]
269  [\rightboundarycharacter\c!rightquote{quote}]
270
271\definesymbol
272  [\c!leftspeech]
273  [\leftboundarycharacter\c!leftspeech{speech}]
274
275\definesymbol
276  [\c!rightspeech]
277  [\rightboundarycharacter\c!rightspeech{speech}]
278
279\definesymbol
280  [\c!middlespeech]
281  [\leftboundarycharacter\c!middlespeech{speech}]
282
283\appendtoks
284    \def\quotation#1{"#1"}%
285    \def\quote    #1{'#1'}%
286\to \everysimplifycommands
287
288%D The next features was so desperately needed by Giuseppe Bilotta that he made a
289%D module for it. Since this is a typical example of core functionality, I decided
290%D to extend the low level quotation macros in such a way that a speech feature
291%D could be build on top of it. The speech opening and closing symbols are defined
292%D per language. Italian is an example of a language that has them set.
293
294\newsignal\d_typo_delimited_signal
295
296\let\currentdelimitedtext\s!unknown
297
298\installglobalmacrostack\currentdelimitedtext
299
300\let\delimitedtextlevel\!!zerocount
301
302\def\c_typo_delimited_nesting{\csname\??delimitedtextlevel\currentparentdelimitedtext\endcsname}
303
304% the \setlanguageparameter macro sets but we are ungrouped .. only used here
305%
306% \currentusedlanguage
307% \usedlanguageparameter
308
309%D The optional argument can be a language, a narrower spec, or a outer:inner language
310%D specification.
311%D
312%D \starttabulate
313%D     \NC [en]    \NC {\tttf en} \quotation[en]   {{\tttf <en=\currentlanguage>} something french} \NC \NR
314%D     \NC [fr]    \NC {\tttf en} \quotation[fr]   {{\tttf <fr=\currentlanguage>} something french} \NC \NR
315%D     \NC [fr:]   \NC {\tttf fr} \quotation[fr:]  {{\tttf <en=\currentlanguage>} something french} \NC \NR
316%D     \NC [:fr]   \NC {\tttf en} \quotation[:fr]  {{\tttf <fr=\currentlanguage>} something french} \NC \NR
317%D     \NC [fr:fr] \NC {\tttf fr} \quotation[fr:fr]{{\tttf <fr=\currentlanguage>} something french} \NC \NR
318%D     \NC [en:fr] \NC {\tttf en} \quotation[en:fr]{{\tttf <fr=\currentlanguage>} something french} \NC \NR
319%D     \NC [fr:en] \NC {\tttf fr} \quotation[fr:en]{{\tttf <en=\currentlanguage>} something french} \NC \NR
320%D \stoptabulate
321
322\let\currentdelimitedlanguage\empty
323
324\installglobalmacrostack\currentdelimitedlanguage
325
326\def\typo_delimited_set_language_nop
327  {\setusedlanguage{\delimitedtextparameter\c!language}}
328
329\def\typo_delimited_set_language_yes
330  {\doiflanguageelse\m_delimited_argument
331     \typo_delimited_set_language_yes_a
332     {\doifelseinstring:\m_delimited_argument
333        \typo_delimited_set_language_yes_b
334        \typo_delimited_set_language_nop}}
335
336\def\typo_delimited_set_language_yes_b
337  {\splitatcolon\m_delimited_argument\outerdelimitedlanguage\innerdelimitedlanguage
338   \ifx\outerdelimitedlanguage\empty
339     \typo_delimited_set_language_nop
340   \else
341     \doiflanguageelse\outerdelimitedlanguage
342       {\setusedlanguage\outerdelimitedlanguage}%
343       \typo_delimited_set_language_nop
344   \fi
345   \ifx\innerdelimitedlanguage\empty
346   \else
347     \doiflanguageelse\innerdelimitedlanguage
348       {\let\currentdelimitedlanguage\innerdelimitedlanguage}%
349       \donothing
350   \fi
351   \let\m_delimited_argument\empty}
352
353\def\typo_delimited_set_language_yes_a
354  {\let\currentdelimitedlanguage\m_delimited_argument
355   \let\m_delimited_argument\empty}
356
357\def\typo_delimited_push#1#2%
358  {\push_macro_currentdelimitedtext     % can we combine these two
359   \push_macro_currentdelimitedlanguage % the language used for hyphenation
360   \edef\currentdelimitedtext{#1}%
361   \edef\m_delimited_argument{#2}%
362   \ifx\m_delimited_argument\empty
363     \typo_delimited_set_language_nop
364   \else
365     \typo_delimited_set_language_yes
366   \fi
367   \let\currentparentdelimitedtext\currentdelimitedtext
368   \global\advance\c_typo_delimited_nesting\plusone
369   \edef\delimitedtextlevel{\number\c_typo_delimited_nesting}%
370   \normalexpanded{\chaintocurrentdelimitedtext{\currentparentdelimitedtext:\delimitedtextlevel}}%
371   \edef\currentdelimitedtext{\currentparentdelimitedtext:\delimitedtextlevel}}
372
373\def\typo_delimited_pop
374  {\global\advance\c_typo_delimited_nesting\minusone
375   \pop_macro_currentdelimitedlanguage
376   \pop_macro_currentdelimitedtext}
377
378\installcorenamespace{delimitedtext}
379\installcorenamespace{delimitedtextlevel}
380
381\installcommandhandler \??delimitedtext {delimitedtext} \??delimitedtext
382
383\appendtoks
384    \expandafter\newcount\csname\??delimitedtextlevel\currentdelimitedtext\endcsname
385    \setuevalue{\currentdelimitedtext        }{\delimitedtext[\currentdelimitedtext]}%
386    \setuevalue{\e!start\currentdelimitedtext}{\startdelimitedtext[\currentdelimitedtext]}%
387    \setuevalue{\e!stop \currentdelimitedtext}{\stopdelimitedtext}%
388\to \everydefinedelimitedtext
389
390\setupdelimitedtext
391  [\c!location=\v!margin, % \v!text \v!paragraph
392   \c!spacebefore=,
393   \c!spaceafter=\delimitedtextparameter\c!spacebefore,
394   \c!style=,
395   \c!color=,
396   \c!leftmargin=\zeropoint,
397   \c!rightmargin=\delimitedtextparameter\c!leftmargin,
398   \c!indentnext=\v!yes,
399   \c!before=,
400   \c!after=,
401   \c!left=,
402   \c!right=,
403  %\c!level=0,
404   \c!method=,
405  %\c!language=\v!local,
406   \c!repeat=\v!no]
407
408\def\typo_delimited_repeat_indeed
409  {\relax\ifcase\delimitedtextlevel\else
410     \typo_delimited_handle_middle\c!middle
411   \fi}
412
413\let\typo_delimited_repeat\relax
414
415\unexpanded\def\startdelimitedtext
416  {\dodoubleempty\typo_delimited_text_start}
417
418\unexpanded\def\typo_delimited_text_start[#1][#2]%
419  {\begingroup
420   \typo_delimited_push{#1}{#2}%
421   \dostarttaggedchained\t!delimitedblock\currentdelimitedtext\??delimitedtext
422   \edef\p_delimited_method{\delimitedtextparameter\c!method}%
423   \ifx\p_delimited_method\v!font
424     \expandafter\typo_delimited_start_font
425   \else
426     \expandafter\typo_delimited_start_other
427   \fi}
428
429\let\typo_delimited_stop\relax % hooks into \everypar
430
431\def\typo_delimited_start_font
432  {\let\typo_delimited_stop\typo_delimitedtexts_finish_font
433   \dostarttagged\t!delimitedsymbol\empty
434   \dotagsetdelimitedsymbol\s!left
435   \delimitedtextparameter\c!left
436   \dostoptagged
437   \ignorespaces}
438
439\newconditional\c_typo_delimited_repeating
440
441\def\typo_delimited_start_other
442  {\edef\p_delimited_repeat{\delimitedtextparameter\c!repeat}%
443   \ifx\p_delimited_repeat\v!yes
444     \let\typo_delimited_repeat\typo_delimited_repeat_indeed
445   \else
446     \let\typo_delimited_repeat\relax
447   \fi
448   \setfalse\c_typo_delimited_repeating
449   \edef\p_delimited_location{\delimitedtextparameter\c!location}%
450   \ifx\p_delimited_location\v!paragraph
451     \singleexpandafter\typo_delimited_start_par
452   \else\ifx\p_delimited_location\v!margin
453     \doubleexpandafter\typo_delimited_start_par
454   \else
455     \doubleexpandafter\typo_delimited_start_txt
456   \fi\fi}
457
458\def\typo_delimitedtexts_finish_font
459  {\removeunwantedspaces % again ?
460   \dostarttagged\t!delimitedsymbol\empty
461   \dotagsetdelimitedsymbol\s!right
462   \delimitedtextparameter\c!right
463   \dostoptagged}
464
465\def\typo_delimited_show_language_indeed#1#2%
466  {\begingroup
467   \infofont
468   \setbox\scratchbox\hpack{\lower\strutht\hbox to \zeropoint{\darkred#1\currentlanguage:\currentdelimitedlanguage#2}}%
469   \vsmashbox\scratchbox
470   \box\scratchbox
471   \endgroup}
472
473\let\typo_delimited_show_language\gobbletwoarguments
474
475\installtextracker{delimited.language}
476  {\let\typo_delimited_show_language\typo_delimited_show_language_indeed}
477  {\let\typo_delimited_show_language\gobbletwoarguments}
478
479\def\typo_delimited_start_content
480  {\dostarttagged\t!delimitedcontent\empty
481   \begingroup
482   \douselanguageparameter\currentdelimitedlanguage
483   \typo_delimited_show_language<\hss
484   \ignorespaces}
485
486\def\typo_delimited_stop_content
487  {\removeunwantedspaces
488   \removelastskip % redundant
489   \typo_delimited_show_language\hss<%
490   \endgroup
491   \dostoptagged}
492
493\def\typo_delimited_start_par
494  {\dosingleempty\typo_delimited_start_par_indeed}
495
496\let\typo_delimited_stop_par_indeed\endgraf
497
498\def\typo_delimited_start_par_indeed[#1]%
499  {\let\typo_delimited_stop\typo_delimited_stop_par
500   \edef\p_delimited_spacebefore{\delimitedtextparameter\c!spacebefore}%
501   \ifx\p_delimited_spacebefore\empty \else
502     \blank[\p_delimited_spacebefore]%
503   \fi
504   \delimitedtextparameter\c!before
505   \iffirstargument
506     \edef\m_delimited_argument{#1}%
507   \fi
508   \ifx\m_delimited_argument\empty
509     \let\m_delimited_argument\m_delimited_argument
510   \fi
511   \ifx\m_delimited_argument\empty
512     \endgraf
513     \doadaptleftskip {\delimitedtextparameter\c!leftmargin}%
514     \doadaptrightskip{\delimitedtextparameter\c!rightmargin}%
515     \let\typo_delimited_stop_par_indeed\endgraf
516   \else % backward compatible direct directive
517     \startnarrower[\m_delimited_argument]%
518     \let\typo_delimited_stop_par_indeed\stopnarrower
519   \fi
520   % so far
521   \push_macro_checkindentation
522   \useindentingparameter\delimitedtextparameter
523   %
524   \begingroup
525   \usedelimitedtextstyleandcolor\c!style\c!color
526   %
527   \begingroup
528   \edef\p_delimited_left     {\delimitedtextparameter{\c!left}}%
529   \edef\p_delimited_right    {\delimitedtextparameter{\c!right}}%
530   \edef\p_delimited_nextleft {\delimitedtextparameter{\c!nextleft}}%
531   \edef\p_delimited_nextright{\delimitedtextparameter{\c!nextright}}%
532   %
533   \leftdelimitedtextmark
534   %
535   \setnextleftdelimitedtextmark
536   \setnextrightdelimitedtextmark
537   %
538   \typo_delimited_start_content}
539
540\def\typo_delimited_stop_par
541  {\typo_delimited_stop_content
542   \rightdelimitedtextmark
543   \rightdelimitedtextmark
544   \carryoverpar\endgroup
545   \endgraf
546   \endgroup
547   \pop_macro_checkindentation
548   \typo_delimited_stop_par_indeed
549   \delimitedtextparameter\c!after
550   \edef\p_delimited_spaceafter{\delimitedtextparameter\c!spaceafter}%
551   \ifx\p_delimited_spaceafter\empty \else
552     \blank[\p_delimited_spaceafter]%
553   \fi
554   \useindentnextparameter\delimitedtextparameter
555   \aftergroup\dorechecknextindentation}% AM: This was missing!
556
557\def\typo_delimited_start_txt
558  {\let\typo_delimited_stop\typo_delimited_stop_txt
559   \begingroup
560   \usedelimitedtextstyleandcolor\c!style\c!color
561   \typo_delimited_handle_left\c!left
562   \typo_delimited_start_content}
563
564\def\typo_delimited_stop_txt
565  {\typo_delimited_stop_content
566   \typo_delimited_handle_right\c!right
567   \endgroup}
568
569\unexpanded\def\stopdelimitedtext
570  {\typo_delimited_stop
571   \dostoptagged
572   \typo_delimited_pop
573   \endgroup}
574
575\unexpanded\def\delimitedtext
576  {\dodoubleempty\typo_delimited_text}
577
578\unexpanded\def\typo_delimited_text[#1][#2]%
579  {\dontleavehmode % following ones can be omited
580   \typo_delimited_push{#1}{#2}%
581   \edef\p_delimited_method{\delimitedtextparameter\c!method}%
582   \ifx\p_delimited_method\v!font
583     \expandafter\typo_delimited_fontdriven
584   \else
585     \expandafter\typo_delimited_other
586   \fi}
587
588\def\typo_delimited_other
589  {\edef\p_delimited_location{\delimitedtextparameter\c!location}%
590   \ifx\p_delimited_location\v!paragraph
591     \singleexpandafter\typo_delimited_par
592   \else\ifx\p_delimited_location\v!margin
593     \doubleexpandafter\typo_delimited_par
594   \else
595     \doubleexpandafter\typo_delimited_txt
596   \fi\fi}
597
598% shortcuts
599
600\unexpanded\def\startdelimited{\startdelimitedtext}
601\unexpanded\def\stopdelimited {\stopdelimitedtext}  % no let, dynamically assigned
602           \def\delimited     {\delimitedtext}
603
604% todo: \dostarttagged\t!nothing\empty % for left/right boxes
605
606%D We have 4 different location and symbol handlers (two pairs):
607%D
608%D \starttyping
609%D \input tufte \startquotation \input tufte \stopquotation
610%D
611%D \setupdelimitedtext
612%D   [quotation]
613%D   [nextleft=right,
614%D    nextright=left]
615%D
616%D \input tufte \startquotation \input tufte \stopquotation
617%D
618%D \setupdelimitedtext
619%D   [quotation]
620%D   [nextleft={\symbol[nextleftquotation]},
621%D    nextright={\symbol[nextrightquotation]}]
622%D
623%D \input tufte \startquotation \input tufte \stopquotation
624%D \stoptyping
625
626\unexpanded\def\setnextleftdelimitedtextmark
627  {\ifx\p_delimited_nextleft\empty
628      % nothing
629   \else\ifx\p_delimited_nextleft\v!left
630     \typo_delimited_nextleft_symbol\p_delimited_left
631   \else\ifx\p_delimited_nextleft\v!right
632     \typo_delimited_nextleft_symbol\p_delimited_right
633   \else
634     \typo_delimited_nextleft_symbol\p_delimited_nextleft
635   \fi\fi\fi}
636
637\unexpanded\def\setnextrightdelimitedtextmark
638  {\ifx\p_delimited_nextright\empty
639      % nothing
640   \else\ifx\p_delimited_nextright\v!right
641     \typo_delimited_nextright_symbol\p_delimited_right
642   \else\ifx\p_delimited_nextright\v!left
643     \typo_delimited_nextright_symbol\p_delimited_left
644   \else
645     \typo_delimited_nextright_symbol\p_delimited_nextright
646   \fi\fi\fi}
647
648\unexpanded\def\leftdelimitedtextmark
649  {\ifx\p_delimited_left\empty
650      % nothing
651   \else
652     \typo_delimited_left_symbol\p_delimited_left
653   \fi}
654
655\unexpanded\def\rightdelimitedtextmark
656  {\ifx\p_delimited_right\empty
657      % nothing
658   \else
659      \typo_delimited_right_symbol\p_delimited_right
660   \fi}
661
662\def\typo_delimited_left_symbol#1%
663  {\dostarttagged\t!delimitedsymbol\empty
664   \dotagsetdelimitedsymbol\s!left
665   \setbox\scratchbox\hbox{\usedelimitedtextstyleandcolor\c!symstyle\c!symcolor#1}%
666   \dontleavehmode
667   \edef\p_delimited_margin{\delimitedtextparameter\c!location}%
668   \ifx\p_delimited_margin\v!margin
669      \hskip-\wd\scratchbox
670   \fi
671   \box\scratchbox
672   \dostoptagged}
673
674\def\typo_delimited_right_symbol#1%
675  {\dostarttagged\t!delimitedsymbol\empty
676   \dotagsetdelimitedsymbol\s!right
677   \hsmash{\usedelimitedtextstyleandcolor\c!symstyle\c!symcolor#1}%
678   \dostoptagged}
679
680\def\typo_delimited_nextleft_symbol#1%
681  {\let\typo_delimited_reset_next_symbol\typo_delimited_reset_next_symbol_indeed
682   \localleftbox\bgroup
683     \swapmacros\leftboundarycharacter\rightboundarycharacter
684     \boundarycharactermode\plusone
685     \typo_delimited_left_symbol#1%
686   \egroup}
687
688\def\typo_delimited_nextright_symbol#1%
689  {\let\typo_delimited_reset_next_symbol\typo_delimited_reset_next_symbol_indeed
690   \localrightbox\bgroup
691     \swapmacros\leftboundarycharacter\rightboundarycharacter
692     \boundarycharactermode\plusone
693     \typo_delimited_right_symbol#1%
694   \egroup}
695
696\unexpanded\def\typo_delimited_reset_next_symbol_indeed
697  {\localleftbox {}%
698   \localrightbox{}}%
699
700\let\typo_delimited_reset_next_symbol\relax
701
702\appendtoks
703    \typo_delimited_reset_next_symbol
704\to \everyforgetall
705
706% \starttext
707%    \hyphenatedword{groepsvrijstellingsverordeningen}\par
708%    \hyphenatedword{\quote{groepsvrijstellingsverordeningen}}\par
709%     \dorecurse{100}{\hskip300pt\hskip\recurselevel pt test \quote{xxx xxxx}.\par}
710%     \page \setuppapersize[A5][A4]
711%     \quotation {overly beautiful pusillanimous sesquipedalian
712%     longwinded} test test test test test test test test test test test
713%     test test test test test test test test test test test test test
714%     test test test test test test test test test test test test test
715%     test test test test test test test test test test test test test
716%     test test test
717% \stoptext
718
719% We have no real test case for this and it's broken already for a while,
720% even in \MKII. Maybe we should to this in \LUA. Only Italian has the
721% middlespeech parameter set.
722
723\def\typo_delimited_handle_middle#1% special case
724  {\ifconditional\c_typo_delimited_repeating
725     \begingroup
726     \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor
727     \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
728     \ifdim\wd\scratchbox>\zeropoint
729       \ifdim\lastkern=\d_typo_delimited_signal
730         \unkern
731         \hskip\hspaceamount\currentusedlanguage{interquotation}%
732       \else % maybe an option:
733        %\edef\p_delimited_margin{\delimitedtextparameter\c!location}%
734        %\ifx\p_delimited_margin\v!margin
735        %   \hskip-\wd\scratchbox
736        %\fi
737       \fi
738       \strut % new, needed below
739       \dostarttagged\t!delimitedsymbol\empty
740       \dotagsetdelimitedsymbol\s!middle
741       \delimitedtextparameter#1% unhbox\scratchbox
742       \dostoptagged
743     % \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods
744       \kern\d_typo_delimited_signal % +- \prewordbreak
745     \fi
746     \endgroup
747   \else
748     \settrue\c_typo_delimited_repeating
749   \fi}
750
751\def\typo_delimited_handle_left#1%
752  {\begingroup
753   \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor
754   \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
755   \ifdim\wd\scratchbox>\zeropoint
756     \ifdim\lastkern=\d_typo_delimited_signal
757       \unkern
758       \hskip\hspaceamount\currentusedlanguage{interquotation}%
759     \else\ifdim\lastskip=\d_typo_delimited_signal
760       \unskip
761       \hskip\hspaceamount\currentusedlanguage{interquotation}%
762     \fi\fi
763   % \strut % new, needed below
764   % \ifhmode % else funny pagebeaks
765   %   \penalty\plustenthousand
766   %   \hskip\zeropoint % == \prewordbreak
767   % \fi
768     \strut % new, needed below
769     \dostarttagged\t!delimitedsymbol\empty
770     \dotagsetdelimitedsymbol\s!left
771     \delimitedtextparameter#1% unhbox\scratchbox
772     \dostoptagged
773     \penalty\plustenthousand % new per 2013-03-09 WS mailing list
774     \hskip\d_typo_delimited_signal % +- \prewordbreak
775   \fi
776   \endgroup}
777
778\def\typo_delimited_handle_right#1%
779  {\begingroup
780   \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor
781   \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
782   \ifdim\wd\scratchbox>\zeropoint
783     \ifdim\lastkern=\d_typo_delimited_signal
784       \unkern
785       \penalty\plustenthousand
786       \hskip\hspaceamount\currentusedlanguage{interquotation}%
787     \else\ifdim\lastskip=\d_typo_delimited_signal
788       \unskip
789       \penalty\plustenthousand
790       \hskip\hspaceamount\currentusedlanguage{interquotation}%
791     \fi\fi
792     \ifhmode % else funny pagebeaks
793       \penalty\plustenthousand
794       \hskip\zeropoint % == \prewordbreak
795     \fi
796     \strut % new, needed below
797     \dostarttagged\t!delimitedsymbol\empty
798     \dotagsetdelimitedsymbol\s!right
799     \delimitedtextparameter#1% unhbox\scratchbox
800     \dostoptagged
801     \kern\d_typo_delimited_signal % +- \prewordbreak
802   \fi
803   \endgroup}
804
805\unexpanded\def\typo_delimited_par
806  {\groupedcommand
807     {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext % block?
808      \usedelimitedtextstyleandcolor\c!style\c!color
809      \typo_delimited_handle_left\c!left
810      \typo_delimited_start_content}
811     {\typo_delimited_stop_content
812      \typo_delimited_handle_right\c!right
813      \removelastskip % hm
814      \dostoptagged
815      \typo_delimited_pop}}
816
817\unexpanded\def\typo_delimited_txt
818  {\edef\p_left_right{\delimitedtextparameter\c!left\delimitedtextparameter\c!right}%
819   \ifx\p_left_right\empty
820     \expandafter\typo_delimited_attributed
821   \else
822     \expandafter\typo_delimited_quoted
823   \fi}
824
825\def\typo_delimited_quoted
826  {\dontleavehmode
827   \begingroup
828   \dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext
829   \typo_delimited_handle_left\c!left
830   \usedelimitedtextstyleandcolor\c!style\c!color
831   \typo_delimited_start_content
832   \bgroup
833   \aftergroup\typo_delimited_quoted_e
834   \let\next=}
835
836\def\typo_delimited_quoted_e
837  {\typo_delimited_stop_content
838   \typo_delimited_handle_right\c!right
839   \removelastskip % ?
840   \dostoptagged
841   \typo_delimited_pop
842   \endgroup}
843
844\def\typo_delimited_attributed
845  {\dontleavehmode
846   \begingroup
847   \dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext
848   \usedelimitedtextstyleandcolor\c!style\c!color
849   \typo_delimited_start_content
850   \bgroup
851   \aftergroup\typo_delimited_attributed_e
852   \let\next=}
853
854\def\typo_delimited_attributed_e
855  {\typo_delimited_stop_content
856   \dostoptagged
857   \typo_delimited_pop
858   \endgroup}
859
860\def\typo_delimited_fontdriven
861  {\dontleavehmode
862   \begingroup
863   \dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext
864   \usedlanguageparameter{\c!left\currentparentdelimitedtext}% was: \currentdelimitedtext
865   \usedelimitedtextstyleandcolor\c!style\c!color
866   \typo_delimited_start_content
867   \bgroup
868   \aftergroup\typo_delimited_fontdriven_e
869   \let\next=}
870
871\def\typo_delimited_fontdriven_e
872  {\typo_delimited_stop_content
873   \usedlanguageparameter{\c!right\currentparentdelimitedtext}% was: \currentdelimitedtext
874   \dostoptagged
875   \typo_delimited_pop
876   \endgroup}
877
878% testcase for nesting:
879%
880% \quotation{... \quotation{...} ...}
881% \startquotation ... \startquotation... \quotation{...} \stopquotation\space ...\stopquotation
882% \setupdelimitedtext[quotation][1][left=(,right=)]
883% \setupdelimitedtext[quotation][2][left={[},right={]}]
884% \setupdelimitedtext[quotation][3][left=\{,right=\}]
885% \quotation{... \quotation{...} ...}
886% \startquotation ... \startquotation... \quotation{...} \stopquotation\space ...\stopquotation
887
888\definedelimitedtext
889  [\v!quotation]
890  [\c!left={\symbol[\c!leftquotation]},
891   \c!right={\symbol[\c!rightquotation]},
892   \c!leftmargin=\v!standard]
893
894\definedelimitedtext
895  [\v!quote][\v!quotation]
896
897\setupdelimitedtext
898  [\v!quote]
899  [\c!location=\v!text,
900   \c!left={\symbol[\c!leftquote]},
901   \c!right={\symbol[\c!rightquote]}]
902
903\definedelimitedtext
904   [\v!blockquote][\v!quotation]
905
906\setupdelimitedtext
907  [\v!blockquote]
908  [\c!left=,
909   \c!right=]
910
911\definedelimitedtext
912  [\v!speech][\v!quotation]
913
914\setupdelimitedtext
915  [\v!speech]
916  [\c!repeat=\v!yes,
917   \c!left={\symbol[\c!leftspeech]},
918   \c!middle={\symbol[\c!middlespeech]},
919   \c!right={\symbol[\c!rightspeech]}]
920
921\definedelimitedtext
922  [\v!aside]
923  [\c!left={\symbol[\c!leftsentence]},
924   \c!right={\symbol[\c!rightsentence]}]
925
926% how do we call an tight quote
927%
928% \definedelimitedtext
929%    [\v!quotation][\v!quotation]
930%
931% \setupdelimitedtext
932%   [\v!quotation]
933%   [\c!indentnext=\v!no,
934%    \c!spacebefore=\v!nowhite]
935
936\unexpanded\def\setupquotation{\setupdelimitedtext[\v!quotation]}
937\unexpanded\def\setupquote    {\setupdelimitedtext[\v!quote]}
938
939\protect \endinput
940