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 0 % MS dislikes 1000, zero == \hyphenpenalty * factor 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 {\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 {#1}} 94 95\permanent\protected\def\stophyphenation 96 {\ifhmode\par\fi 97 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 123 {#1}% 124 { 125 characters {\dummyparameter\c!characters}% 126 hyphens {\dummyparameter\c!hyphens}% 127 joiners {\dummyparameter\c!joiners}% 128 rightwordmin {\dummyparameter\c!rightwords}% 129 rightchars {\dummyparameter\c!rightchars}% 130 charmin {\dummyparameter\s!hyphenmin}% 131 leftcharmin {\dummyparameter\s!lefthyphenmin}% 132 rightcharmin {\dummyparameter\s!righthyphenmin}% 133 leftchar {\dummyparameter\s!lefthyphenchar}% 134 rightchar {\dummyparameter\s!righthyphenchar}% 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 {{#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 {\ifparameter#2\or{#1}{#2}\else{\currentlanguage}{#1}\fi\s!true\relax} 155 156\permanent\tolerant\protected\def\unregisterhyphenationpattern[#S#1]#*[#S#2]% 157 {\ifparameter#2\or{#1}{#2}\else{\currentlanguage}{#1}\fi\s!false\relax} 158 159\permanent\tolerant\protected\def\registerhyphenationexception[#S#1]#*[#S#2]% 160 {\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 \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 {} 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 |