lang-hyp.mkxl /size: 10 Kb    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=lang-ini,
3%D        version=2014.08.10,
4%D          title=\CONTEXT\ Language Macros,
5%D       subtitle=Experimental Patterns,
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%D This is an experimental module. We often have to deal with titles that have
15%D conflicting demands:
16%D
17%D \startitemize
18%D \startitem They go into a dedicated space (often a graphic). \stopitem
19%D \startitem The words cannot be hyphenated. \stopitem
20%D \startitem But as an escape they can get hyphenated. \stopitem
21%D \startitem In that case we want at least an extra word on the last line. \stopitem
22%D \stopitemize
23%D
24%D These and maybe more cases can be dealt with using dedicated hyphenation
25%D mechanisms. At he same time we want to experiment with more extensive patterns
26%D as discussed in {\em TUGboat, Volume 27 (2006), No. 2—Proceedings of EuroTEX2006}.
27
28% lua: 5.341 5.354
29% tex: 5.174 5.262
30
31\writestatus{loading}{ConTeXt Language Macros / Initialization}
32
33\registerctxluafile{lang-dis}{autosuffix}
34\registerctxluafile{lang-hyp}{autosuffix}
35
36\unprotect
37
38\definesystemattribute[hyphenation][public]
39
40%D After a decade of playing with these things in \LUATEX|/|\MKIV\ it's time to
41%D finish the way we deal with discretionaries. Apart from the fact that they play a
42%D role in hyphenation they also need to be dealt with in fonts. Flattening, cleanup
43%D and such are now more or less default in \CONTEXT\ so we can simplify some of the
44%D code. We also use the new penalty mechanism.
45
46\newinteger\compoundhyphenpenalty
47
48% \ifcase\contextlmtxmode
49%     \hyphenpenaltymode\plusfour
50%     \automatichyphenmode\plusone
51% \fi
52
53\hyphenpenalty            50 % hyphenator
54\automatichyphenpenalty   50 % -
55\explicithyphenpenalty    50 % \-
56\compoundhyphenpenalty    50
57\exceptionpenalty       1000
58
59%D This command can change! At some point we will keep the setting with the
60%D paragraph and then the \type {\par} can go.
61
62\installcorenamespace{hyphenation}
63\installcorenamespace{hyphenationfeatures}
64
65\installparameterhandler     \??hyphenation {hyphenation}
66\installrootparameterhandler \??hyphenation {hyphenation}
67\installsetuphandler         \??hyphenation {hyphenation}
68
69% \installbasicsetuphandler  \??hyphenation {hyphenation}
70
71\setuphyphenation
72  [\c!method=\s!default,
73   \c!hyphens=\v!yes,
74   \s!righthyphenchar=0, % number tzt g: etc
75   \s!lefthyphenchar=0]  % number
76
77\appendtoks
78   \ifcstok{\hyphenationparameter\c!hyphens}\v!no
79     \nohyphencollapsing
80   \else
81     \dohyphencollapsing
82   \fi
83\to \everysetuphyphenation
84
85\appendtoks
86    \clf_sethyphenationmethod{\hyphenationparameter\c!method}%
87\to \everysetuphyphenation
88
89%D These are mostly meant for manuals:
90
91\permanent\protected\def\starthyphenation[#1]%
92  {\begingroup
93   \clf_pushhyphenation{#1}}
94
95\permanent\protected\def\stophyphenation
96  {\ifhmode\par\fi
97   \clf_pophyphenation
98   \endgroup}
99
100% This is a global setting, so we need to disable it when needed. However, as
101% we are (hopefully) compatible and attribute driven one can also just keep it
102% enabled.
103%
104% \setuphyphenation
105%   [\c!method=\s!traditional] % no translations
106
107\permanent\tolerant\protected\def\definehyphenationfeatures[#1]#*[#S#2]%
108  {\begingroup % maybe simple handler
109   \resetdummyparameter\c!characters                % maybe \s!characters
110   \resetdummyparameter\c!hyphens                   % maybe \s!hyphens
111   \resetdummyparameter\c!joiners                   % maybe \s!joiners
112   \letdummyparameter  \c!rightwords     \zerocount % maybe \s!rightwords
113   \letdummyparameter  \s!lefthyphenmin  \zerocount
114   \letdummyparameter  \s!righthyphenmin \zerocount
115   \letdummyparameter  \s!hyphenmin      \zerocount
116   \letdummyparameter  \s!lefthyphenchar \zerocount
117   \letdummyparameter  \s!righthyphenchar\zerocount
118   \resetdummyparameter\c!alternative
119   \resetdummyparameter\c!rightedge
120   \resetdummyparameter\c!rightchars
121   \getdummyparameters[#2]%
122   \clf_definehyphenationfeatures
123      {#1}%
124      {
125        characters   {\dummyparameter\c!characters}%
126        hyphens      {\dummyparameter\c!hyphens}%
127        joiners      {\dummyparameter\c!joiners}%
128        rightwordmin \numexpr\dummyparameter\c!rightwords\relax
129        rightchars   {\dummyparameter\c!rightchars}%
130        charmin      \numexpr\dummyparameter\s!hyphenmin\relax
131        leftcharmin  \numexpr\dummyparameter\s!lefthyphenmin\relax
132        rightcharmin \numexpr\dummyparameter\s!righthyphenmin\relax
133        leftchar     \numexpr\dummyparameter\s!lefthyphenchar\relax
134        rightchar    \numexpr\dummyparameter\s!righthyphenchar\relax
135        alternative  {\dummyparameter\c!alternative}%
136        rightedge    {\dummyparameter\c!rightedge}%
137      % autohyphen   {\dummyparameter\c!autohyphen}
138      % hyphenonly   {\dummyparameter\c!hyphenonly}
139      }%
140   \relax
141   \endgroup}
142
143\permanent\protected\def\sethyphenationfeatures[#1]%
144  {\clf_sethyphenationfeatures{#1}}
145
146\permanent\protected\def\resethyphenationfeatures
147  {\attribute\hyphenationattribute\attributeunsetvalue}
148
149\resethyphenationfeatures
150
151% todo: \start ... \stop too
152
153\permanent\tolerant\protected\def\registerhyphenationpattern[#S#1]#*[#S#2]%
154  {\clf_registerhyphenationpattern\ifparameter#2\or{#1}{#2}\else{\currentlanguage}{#1}\fi\s!true\relax}
155
156\permanent\tolerant\protected\def\unregisterhyphenationpattern[#S#1]#*[#S#2]%
157  {\clf_registerhyphenationpattern\ifparameter#2\or{#1}{#2}\else{\currentlanguage}{#1}\fi\s!false\relax}
158
159\permanent\tolerant\protected\def\registerhyphenationexception[#S#1]#*[#S#2]%
160  {\clf_registerhyphenationexception\ifparameter#2\or{#1}{#2}\else{\currentlanguage}{#1}\fi\relax}
161
162\permanent\tolerant\protected\def\showhyphenationtrace[#S#1]#*[#S#2]%
163  {\begingroup
164   \tt
165   \clf_showhyphenationtrace\ifparameter#2\or{#1}{#2}\else{\currentlanguage}{#1}\fi\relax
166   \endgroup}
167
168% For old times sake:
169
170\permanent\protected\def\atleastoneword#1%
171  {\begingroup
172   \starthyphenation[traditional]% this might become default or a faster switch
173   \sethyphenationfeatures[words]%
174   #1\par
175   \stophyphenation
176   \endgroup}
177
178%D For me:
179
180\permanent\protected\def\showdiscretionaries
181  {\clf_showdiscretionaries}
182
183%D These are (at least now) not cummulative:
184
185\definehyphenationfeatures % just an example
186  [fences]
187  [\c!characters={[]()}]
188
189\definehyphenationfeatures
190  [words]
191  [\c!rightwords=1,
192   \s!lefthyphenmin=4,
193   \s!righthyphenmin=4]
194
195\definehyphenationfeatures
196  [default]
197  [%c!rightedge=\v!tex,
198   \c!hyphens=\v!yes,
199   \c!joiners=\v!yes]
200
201\definehyphenationfeatures
202  [strict]
203  [\c!rightedge=\s!tex]
204
205% \sethyphenationfeatures
206%   [fences]
207
208% \sethyphenationfeatures
209%   [default,fences]
210
211%D When we have \OPENTYPE\ fonts with many replacements we can end up with collapsed
212%D discretionaries with relative long snippets. When investigating a buglet in the
213%D font handler (a final discretionary with no trailing glyph got no ligatures) I
214%D got an empty line due to an empty post.
215%D
216%D \startbuffer
217%D \showmakeup[line]
218%D \discretionaryoptions\zerocount
219%D % We need to force an end of line situation:
220%D \hsize\widthofstring{sciencefiction}
221%D % We had no ligatures in the replacement (fixed):
222%D science\discretionary{\red fict-}{\green ion}{\blue fiction}\par
223%D % We got an empty line in the par builder:
224%D science\discretionary{\red f\kern0ptiction}{}{\blue fiction}\par
225%D % Regular cases (with a simple hyphen only pre):
226%D science\-fiction\par
227%D % Just a (par builder criterium) test case:
228%D science\discretionary{-}{}{\blue fiction}\par
229%D \hyphenation{science-fiction}
230%D % Nothing special:
231%D sciencefiction\par
232%D \stopbuffer
233%D
234%D \typebuffer % \startpacked \getbuffer \stoppacked
235%D
236%D Changes are slim that this will happen in real documents (the buglet was more
237%D likely to show up). Anyhow, we now catch the border case in the linebreak
238%D routine:
239
240\discretionaryoptions\prefernobreakdiscoptioncode
241
242%D Here is an example with optional content (at least, the original idea as
243%D we now do it differently:
244%D
245%D \start
246%D     \tttf
247%D     \hsize\widthofstring{short}
248%D     --:\par
249%D     \discretionaryoptions\zerocount
250%D     \discretionary{before}{after}{short}\par
251%D     \discretionary{before}{}{short}\blank
252%D     nb:\par
253%D     \discretionaryoptions\prefernobreakdiscoptioncode
254%D     \discretionary{before}{after}{short}\par
255%D     \discretionary{before}{}{short}\blank
256%D     br:\par
257%D     \discretionaryoptions\preferbreakdiscoptioncode
258%D     \discretionary{before}{after}{short}\par
259%D     \discretionary{before}{}{short}\blank
260%D \stop
261%D
262%D Todo: examples with break and nobreak keywords.
263
264\protect \endinput
265
266% \starttext
267%
268% \enabledirectives[hyphenators.method=traditional]
269%
270% % \dorecurse{1000}{\input tufte \par}
271%
272% \setupalign[verytolerant,flushleft]
273% \setuplayout[width=140pt] \showframe
274%
275% longword longword long word longword longwordword \blank
276%
277% \enabledirectives[hyphenators.rightwordsmin=1]
278%
279% longword longword long word longword longwordword\blank
280%
281% \disabledirectives[hyphenators.rightwordsmin]
282%
283% longword longword long word longword longwordword\blank
284%
285% \atleastoneword{longword longword long word longword longwordword}
286%
287% \enabledirectives[hyphenators.method=traditional]
288%
289% \stoptext
290
291% \startluacode
292%     -- e1ë/e=e             reëel      re-eel
293%     -- a1atje./a=t,1,3     omaatje    oma-tje
294%     -- schif1f/ff=f,5,2    Schiffahrt Schiff-fahrt
295%
296%     languages.hyphenators.traditional.registerpattern("en","a1b",      { start = 1, length = 2, before = "CD", after = "EF"  } )
297%     languages.hyphenators.traditional.registerpattern("en","e1ë",      { start = 1, length = 2, before = "e",  after = "e"  } )
298%     languages.hyphenators.traditional.registerpattern("en","oo1ë",     { start = 2, length = 2, before = "o",  after = "e"  } )
299%     languages.hyphenators.traditional.registerpattern("en","qqxc9xkqq",{ start = 3, length = 4, before = "ab", after = "cd" } ) -- replacement start length
300%
301%     --  print("reëel",       injecthyphens(dictionaries.nl,"reëel",       2,2))
302%     --  print("reeëel",      injecthyphens(dictionaries.nl,"reeëel",      2,2))
303%     --  print("rooëel",      injecthyphens(dictionaries.nl,"rooëel",      2,2))
304%     --  print(   "QXcXkQ",   injecthyphens(dictionaries.de,   "QXcXkQ",   2,2))
305%     --  print(  "QQXcXkQQ",  injecthyphens(dictionaries.de,  "QQXcXkQQ",  2,2))
306%     --  print( "QQQXcXkQQQ", injecthyphens(dictionaries.de, "QQQXcXkQQQ", 2,2))
307%     --  print("QQQQXcXkQQQQ",injecthyphens(dictionaries.de,"QQQQXcXkQQQQ",2,2))
308%     --
309%     --  print(  "QQXcXkQQ QQXcXkQQ",  injecthyphens(dictionaries.de,  "QQXcXkQQ QQXcXkQQ",  2,2))
310% \stopluacode
311%
312% \starttext
313%
314% \blank
315%
316% xreëel rooëel \par xxabxx xxxabxxx \par
317%
318% \hsize1mm \lefthyphenmin2 \righthyphenmin2
319%
320% \blank Capacity \blank capacity \blank xyabxy \blank xreëel \blank rooëel \blank
321%
322% xy\discretionary{CD}{EF}{ab}xy % xxacceedxxx
323%
324% \stoptext
325