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