diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-22 22:20:48 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-22 22:20:48 +0000 |
commit | 1f8a99f91f89d808a685fb90434693017786a8a6 (patch) | |
tree | c0adb02e7b8fd39fc9335d04d8dcd020fb37b570 /Master/texmf-dist/tex/generic/babel/luababel.def | |
parent | 4220324e99226b427519e0380034f951f67a011f (diff) | |
parent | d9e54ef03db8d244f5386fc89efffccb3d483a5e (diff) |
sync with trunk 57841 to continue testing
git-svn-id: svn://tug.org/texlive/branches/branch2020@57848 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/babel/luababel.def')
-rw-r--r-- | Master/texmf-dist/tex/generic/babel/luababel.def | 519 |
1 files changed, 367 insertions, 152 deletions
diff --git a/Master/texmf-dist/tex/generic/babel/luababel.def b/Master/texmf-dist/tex/generic/babel/luababel.def index 1ee7214a546..5f489e8062d 100644 --- a/Master/texmf-dist/tex/generic/babel/luababel.def +++ b/Master/texmf-dist/tex/generic/babel/luababel.def @@ -7,7 +7,7 @@ %% babel.dtx (with options: `luatex') %% %% -%% Copyright (C) 2012-2020 Javier Bezos and Johannes L. Braams. +%% Copyright (C) 2012-2021 Javier Bezos and Johannes L. Braams. %% Copyright (C) 1989-2012 Johannes L. Braams and %% any individual authors listed elsewhere in this file. %% All rights reserved. @@ -32,7 +32,7 @@ %% extension |.ins|) which are part of the distribution. %% -\ifx\AddBabelHook\@undefined +\ifx\AddBabelHook\@undefined % When plain.def, babel.sty starts \bbl@trace{Read language.dat} \ifx\bbl@readstream\@undefined \csname newread\endcsname\bbl@readstream @@ -120,27 +120,30 @@ \bbl@trace{Macros for reading patterns files} \def\bbl@get@enc#1:#2:#3\@@@{\def\bbl@hyph@enc{#2}} \ifx\babelcatcodetablenum\@undefined - \def\babelcatcodetablenum{5211} + \ifx\newcatcodetable\@undefined + \def\babelcatcodetablenum{5211} + \def\bbl@pattcodes{\numexpr\babelcatcodetablenum+1\relax} + \else + \newcatcodetable\babelcatcodetablenum + \newcatcodetable\bbl@pattcodes + \fi +\else + \def\bbl@pattcodes{\numexpr\babelcatcodetablenum+1\relax} \fi \def\bbl@luapatterns#1#2{% \bbl@get@enc#1::\@@@ \setbox\z@\hbox\bgroup \begingroup - \ifx\catcodetable\@undefined - \let\savecatcodetable\luatexsavecatcodetable - \let\initcatcodetable\luatexinitcatcodetable - \let\catcodetable\luatexcatcodetable - \fi \savecatcodetable\babelcatcodetablenum\relax - \initcatcodetable\numexpr\babelcatcodetablenum+1\relax - \catcodetable\numexpr\babelcatcodetablenum+1\relax - \catcode`\#=6 \catcode`\$=3 \catcode`\&=4 \catcode`\^=7 - \catcode`\_=8 \catcode`\{=1 \catcode`\}=2 \catcode`\~=13 - \catcode`\@=11 \catcode`\^^I=10 \catcode`\^^J=12 - \catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\.=12 - \catcode`\-=12 \catcode`\/=12 \catcode`\[=12 \catcode`\]=12 - \catcode`\`=12 \catcode`\'=12 \catcode`\"=12 - \input #1\relax + \initcatcodetable\bbl@pattcodes\relax + \catcodetable\bbl@pattcodes\relax + \catcode`\#=6 \catcode`\$=3 \catcode`\&=4 \catcode`\^=7 + \catcode`\_=8 \catcode`\{=1 \catcode`\}=2 \catcode`\~=13 + \catcode`\@=11 \catcode`\^^I=10 \catcode`\^^J=12 + \catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\.=12 + \catcode`\-=12 \catcode`\/=12 \catcode`\[=12 \catcode`\]=12 + \catcode`\`=12 \catcode`\'=12 \catcode`\"=12 + \input #1\relax \catcodetable\babelcatcodetablenum\relax \endgroup \def\bbl@tempa{#2}% @@ -173,7 +176,26 @@ {\expandafter\expandafter\expandafter\bbl@luapatterns \csname bbl@hyphendata@\the\language\endcsname}}{}} \endinput\fi -\begingroup + % Here ends \ifx\AddBabelHook\@undefined + % A few lines are only read by hyphen.cfg +\ifx\DisableBabelHook\@undefined + \AddBabelHook{luatex}{everylanguage}{% + \def\process@language##1##2##3{% + \def\process@line####1####2 ####3 ####4 {}}} + \AddBabelHook{luatex}{loadpatterns}{% + \input #1\relax + \expandafter\gdef\csname bbl@hyphendata@\the\language\endcsname + {{#1}{}}} + \AddBabelHook{luatex}{loadexceptions}{% + \input #1\relax + \def\bbl@tempb##1##2{{##1}{#1}}% + \expandafter\xdef\csname bbl@hyphendata@\the\language\endcsname + {\expandafter\expandafter\expandafter\bbl@tempb + \csname bbl@hyphendata@\the\language\endcsname}} +\endinput\fi + % Here stops reading code for hyphen.cfg + % The following is read the 2nd time it's loaded +\begingroup % TODO - to a lua file \catcode`\%=12 \catcode`\'=12 \catcode`\"=12 @@ -229,6 +251,7 @@ \endgroup \ifx\newattribute\@undefined\else \newattribute\bbl@attr@locale + \directlua{ Babel.attr_locale = luatexbase.registernumber'bbl@attr@locale'} \AddBabelHook{luatex}{beforeextras}{% \setattribute\bbl@attr@locale\localeid} \fi @@ -280,19 +303,6 @@ \bbl@ifunset{bbl@prehc@\languagename}{}% {\\\bbl@ifblank{\bbl@cs{prehc@\languagename}}{}% {\prehyphenchar=\bbl@cl{prehc}\relax}}}} -\AddBabelHook{luatex}{everylanguage}{% - \def\process@language##1##2##3{% - \def\process@line####1####2 ####3 ####4 {}}} -\AddBabelHook{luatex}{loadpatterns}{% - \input #1\relax - \expandafter\gdef\csname bbl@hyphendata@\the\language\endcsname - {{#1}{}}} -\AddBabelHook{luatex}{loadexceptions}{% - \input #1\relax - \def\bbl@tempb##1##2{{##1}{#1}}% - \expandafter\xdef\csname bbl@hyphendata@\the\language\endcsname - {\expandafter\expandafter\expandafter\bbl@tempb - \csname bbl@hyphendata@\the\language\endcsname}} \@onlypreamble\babelpatterns \AtEndOfPackage{% \newcommand\babelpatterns[2][\@empty]{% @@ -370,7 +380,7 @@ function Babel.sea_disc_to_space (head) local sea_ranges = Babel.sea_ranges local last_char = nil - local quad = 655360 ^^ 10 pt = 655360 = 10 * 65536 + local quad = 655360 ^% 10 pt = 655360 = 10 * 65536 for item in node.traverse(head) do local i = item.id if i == node.id'glyph' then @@ -380,16 +390,16 @@ quad = font.getfont(last_char.font).size for lg, rg in pairs(sea_ranges) do if last_char.char > rg[1] and last_char.char < rg[2] then - lg = lg:sub(1, 4) ^^ Remove trailing number of, eg, Cyrl1 + lg = lg:sub(1, 4) ^% Remove trailing number of, eg, Cyrl1 local intraspace = Babel.intraspaces[lg] local intrapenalty = Babel.intrapenalties[lg] local n if intrapenalty ~= 0 then - n = node.new(14, 0) ^^ penalty + n = node.new(14, 0) ^% penalty n.penalty = intrapenalty node.insert_before(head, item, n) end - n = node.new(12, 13) ^^ (glue, spaceskip) + n = node.new(12, 13) ^% (glue, spaceskip) node.setglue(n, intraspace.b * quad, intraspace.p * quad, intraspace.m * quad) @@ -452,7 +462,9 @@ node.insert_before(head, item, n) end - quad = font.getfont(item.font).size + if font.getfont(item.font) then + quad = font.getfont(item.font).size + end last_class = class last_lang = lang else % if penalty, glue or anything else @@ -522,52 +534,42 @@ \ifx\bbl@KVP@intrapenalty\@nil\else \expandafter\bbl@intrapenalty\bbl@KVP@intrapenalty\@@ \fi}} -\AddBabelHook{luatex}{loadkernel}{% - \begingroup - % Reset chars "80-"C0 to category "other", no case mapping: - \catcode`\@=11 \count@=128 - \loop\ifnum\count@<192 - \global\uccode\count@=0 \global\lccode\count@=0 - \global\catcode\count@=12 \global\sfcode\count@=1000 - \advance\count@ by 1 \repeat - % Other: - \def\O ##1 {% - \global\uccode"##1=0 \global\lccode"##1=0 - \global\catcode"##1=12 \global\sfcode"##1=1000 }% - % Letter: - \def\L ##1 ##2 ##3 {\global\catcode"##1=11 - \global\uccode"##1="##2 - \global\lccode"##1="##3 - % Uppercase letters have sfcode=999: - \ifnum"##1="##3 \else \global\sfcode"##1=999 \fi }% - % Letter without case mappings: - \def\l ##1 {\L ##1 ##1 ##1 }% - \l 00AA - \L 00B5 039C 00B5 - \l 00BA - \O 00D7 - \l 00DF - \O 00F7 - \L 00FF 0178 00FF - \endgroup - \input #1\relax} -\ifx\DisableBabelHook\@undefined\endinput\fi \AddBabelHook{babel-fontspec}{afterextras}{\bbl@switchfont} \AddBabelHook{babel-fontspec}{beforestart}{\bbl@ckeckstdfonts} \DisableBabelHook{babel-fontspec} \bbl@trace{Font handling with fontspec} +\ifx\ExplSyntaxOn\@undefined\else + \ExplSyntaxOn + \catcode`\ =10 + \def\bbl@loadfontspec{% + \usepackage{fontspec}% + \expandafter + \def\csname msg~text~>~fontspec/language-not-exist\endcsname##1##2##3##4{% + Font '\l_fontspec_fontname_tl' is using the\\% + default features for language '##1'.\\% + That's usually fine, because many languages\\% + require no specific features, but if the output is\\% + not as expected, consider selecting another font.} + \expandafter + \def\csname msg~text~>~fontspec/no-script\endcsname##1##2##3##4{% + Font '\l_fontspec_fontname_tl' is using the\\% + default features for script '##2'.\\% + That's not always wrong, but if the output is\\% + not as expected, consider selecting another font.}} + \ExplSyntaxOff +\fi \@onlypreamble\babelfont \newcommand\babelfont[2][]{% 1=langs/scripts 2=fam \bbl@foreach{#1}{% \expandafter\ifx\csname date##1\endcsname\relax - \IfFileExists{babel-##1.tex}% - {\babelprovide{##1}}% - {}% + \IfFileExists{babel-##1.tex}% + {\babelprovide{##1}}% + {}% \fi}% \edef\bbl@tempa{#1}% \def\bbl@tempb{#2}% Used by \bbl@bblfont \ifx\fontspec\@undefined - \usepackage{fontspec}% + \bbl@loadfontspec \fi \EnableBabelHook{babel-fontspec}% Just calls \bbl@switchfont \bbl@bblfont} @@ -630,7 +632,7 @@ \bbl@ifunset{bbl@##1dflt@\languagename}% {\bbl@cs{famrst@##1}% \global\bbl@csarg\let{famrst@##1}\relax}% - {\bbl@exp{% order is relevant + {\bbl@exp{% order is relevant. TODO: but sometimes wrong! \\\bbl@add\\\originalTeX{% \\\bbl@font@rst{\bbl@cl{##1dflt}}% \<##1default>\<##1family>{##1}}% @@ -672,9 +674,13 @@ \ifin@ \bbl@exp{\\\bbl@fontspec@set\\#1\expandafter\@gobbletwo#1\\#3}% \fi - \bbl@exp{% + \bbl@exp{% 'Unprotected' macros return prev values \def\\#2{#1}% eg, \rmdefault{\bbl@rmdflt@lang} - \\\bbl@ifsamestring{#2}{\f@family}{\\#3\let\\\bbl@tempa\relax}{}}} + \\\bbl@ifsamestring{#2}{\f@family}% + {\\#3% + \\\bbl@ifsamestring{\f@series}{\bfdefault}{\\\bfseries}{}% + \let\\\bbl@tempa\relax}% + {}}} \def\bbl@fontspec@set#1#2#3#4{% eg \bbl@rmdflt@lang fnt-opt fnt-nme \xxfamily \let\bbl@tempe\bbl@mapselect \let\bbl@mapselect\relax @@ -739,6 +745,7 @@ \edef\bbl@langfeatures{#2,}}} \directlua{ Babel.script_blocks = { + ['dflt'] = {}, ['Arab'] = {{0x0600, 0x06FF}, {0x08A0, 0x08FF}, {0x0750, 0x077F}, {0xFE70, 0xFEFF}, {0xFB50, 0xFDFF}, {0x1EE00, 0x1EEFF}}, ['Armn'] = {{0x0530, 0x058F}}, @@ -880,8 +887,8 @@ end \let\bbl@chprop@bmg\bbl@chprop@mirror \def\bbl@chprop@linebreak#1{% \directlua{ - Babel.Babel.cjk_characters[\the\count@] = Babel.Babel.cjk_characters[\the\count@] or {} - Babel.Babel.cjk_characters[\the\count@]['c'] = '#1' + Babel.cjk_characters[\the\count@] = Babel.cjk_characters[\the\count@] or {} + Babel.cjk_characters[\the\count@]['c'] = '#1' }} \let\bbl@chprop@lb\bbl@chprop@linebreak \def\bbl@chprop@locale#1{% @@ -890,13 +897,17 @@ end Babel.chr_to_loc[\the\count@] = \bbl@ifblank{#1}{-1000}{\the\bbl@cs{id@@#1}}\space }} -\begingroup +\begingroup % TODO - to a lua file +\catcode`\~=12 \catcode`\#=12 \catcode`\%=12 \catcode`\&=14 \directlua{ Babel.linebreaking.replacements = {} + Babel.linebreaking.replacements[0] = {} &% pre + Babel.linebreaking.replacements[1] = {} &% post + &% Discretionaries contain strings as nodes function Babel.str_to_nodes(fn, matches, base) local n, head, last if fn == nil then return nil end @@ -916,22 +927,88 @@ end return head end - function Babel.fetch_word(head, funct) + Babel.fetch_subtext = {} + + &% Merging both functions doesn't seen feasible, because there are too + &% many differences. + Babel.fetch_subtext[0] = function(head) local word_string = '' local word_nodes = {} local lang local item = head + local inmath = false while item do - if item.id == 29 - and not(item.char == 124) &% ie, not | - and not(item.char == 61) &% ie, not = - and (item.lang == lang or lang == nil) then - lang = lang or item.lang - word_string = word_string .. unicode.utf8.char(item.char) + if item.id == 11 then + inmath = (item.subtype == 0) + end + + if inmath then + &% pass + + elseif item.id == 29 then + local locale = node.get_attribute(item, Babel.attr_locale) + + if lang == locale or lang == nil then + if (item.char ~= 124) then &% ie, not | = space + lang = lang or locale + word_string = word_string .. unicode.utf8.char(item.char) + word_nodes[#word_nodes+1] = item + end + else + break + end + + elseif item.id == 12 and item.subtype == 13 then + word_string = word_string .. '|' word_nodes[#word_nodes+1] = item + &% Ignore leading unrecognized nodes, too. + elseif word_string ~= '' then + word_string = word_string .. Babel.us_char + word_nodes[#word_nodes+1] = item &% Will be ignored + end + + item = item.next + end + + &% Here and above we remove some trailing chars but not the + &% corresponding nodes. But they aren't accessed. + if word_string:sub(-1) == '|' then + word_string = word_string:sub(1,-2) + end + word_string = unicode.utf8.gsub(word_string, Babel.us_char .. '+$', '') + return word_string, word_nodes, item, lang + end + + Babel.fetch_subtext[1] = function(head) + local word_string = '' + local word_nodes = {} + local lang + local item = head + local inmath = false + + while item do + + if item.id == 11 then + inmath = (item.subtype == 0) + end + + if inmath then + &% pass + + elseif item.id == 29 then + if item.lang == lang or lang == nil then + if (item.char ~= 124) and (item.char ~= 61) then &% not =, not | + lang = lang or item.lang + word_string = word_string .. unicode.utf8.char(item.char) + word_nodes[#word_nodes+1] = item + end + else + break + end + elseif item.id == 7 and item.subtype == 2 then word_string = word_string .. '=' word_nodes[#word_nodes+1] = item @@ -940,130 +1017,230 @@ end word_string = word_string .. '|' word_nodes[#word_nodes+1] = item + &% (1) Go to next word if nothing was found, and (2) implictly + &% remove leading USs. elseif word_string == '' then &% pass + &% This is the responsible for splitting by words. + elseif (item.id == 12 and item.subtype == 13) then + break + else - return word_string, word_nodes, item, lang + word_string = word_string .. Babel.us_char + word_nodes[#word_nodes+1] = item &% Will be ignored end item = item.next end + + word_string = unicode.utf8.gsub(word_string, Babel.us_char .. '+$', '') + return word_string, word_nodes, item, lang + end + + function Babel.pre_hyphenate_replace(head) + Babel.hyphenate_replace(head, 0) end function Babel.post_hyphenate_replace(head) + Babel.hyphenate_replace(head, 1) + end + + Babel.us_char = string.char(31) + + function Babel.hyphenate_replace(head, mode) local u = unicode.utf8 - local lbkr = Babel.linebreaking.replacements + local lbkr = Babel.linebreaking.replacements[mode] + local word_head = head - while true do - local w, wn, nw, lang = Babel.fetch_word(word_head) - if not lang then return head end + while true do &% for each subtext block - if not lbkr[lang] then - break + local w, wn, nw, lang = Babel.fetch_subtext[mode](word_head) + + if Babel.debug then + print() + print('@@@@@', w, nw) end + if nw == nil and w == '' then break end + + if not lang then goto next end + if not lbkr[lang] then goto next end + + &% For each saved (pre|post)hyphenation. TODO. Reconsider how + &% loops are nested. for k=1, #lbkr[lang] do local p = lbkr[lang][k].pattern local r = lbkr[lang][k].replace + if Babel.debug then + print('=====', p, mode) + end + + &% This variable is set in some cases below to the first *byte* + &% after the match, either as found by u.match (faster) or the + &% computed position based on sc if w has changed. + local last_match = 0 + + &% For every match. while true do - local matches = { u.match(w, p) } + if Babel.debug then + print('-----') + end + local new &% used when inserting and removing nodes + local refetch = false + + local matches = { u.match(w, p, last_match) } if #matches < 2 then break end + &% Get and remove empty captures (with ()'s, which return a + &% number with the position), and keep actual captures + &% (from (...)), if any, in matches. local first = table.remove(matches, 1) - local last = table.remove(matches, #matches) + local last = table.remove(matches, #matches) + &% Non re-fetched substrings may contain \31, which separates + &% subsubstrings. + if string.find(w:sub(first, last-1), Babel.us_char) then break end + + local save_last = last &% with A()BC()D, points to D - &% Fix offsets, from bytes to unicode. + &% Fix offsets, from bytes to unicode. Explained above. first = u.len(w:sub(1, first-1)) + 1 - last = u.len(w:sub(1, last-1)) + last = u.len(w:sub(1, last-1)) &% now last points to C - local new &% used when inserting and removing nodes - local changed = 0 + if Babel.debug then + print(p) + print('', 'sc', 'first', 'last', 'last_m', 'w') + end - &% This loop traverses the replace list and takes the - &% corresponding actions - for q = first, last do - local crep = r[q-first+1] - local char_node = wn[q] + &% This loop traverses the matched substring and takes the + &% corresponding action stored in the replacement list. + &% sc = the position in substr nodes / string + &% rc = the replacement table index + local sc = first-1 + local rc = 0 + while rc < last-first+1 do &% for each replacement + if Babel.debug then + print('.....') + end + sc = sc + 1 + rc = rc + 1 + local crep = r[rc] + local char_node = wn[sc] local char_base = char_node + local end_replacement = false if crep and crep.data then char_base = wn[crep.data+first-1] end - if crep == {} then - break - elseif crep == nil then - changed = changed + 1 + if Babel.debug then + print('*', sc, first, last, last_match, w) + end + + if crep and next(crep) == nil then &% {} + last_match = save_last + + elseif crep == nil then &% remove node.remove(head, char_node) - elseif crep and (crep.pre or crep.no or crep.post) then - changed = changed + 1 - d = node.new(7, 0) &% (disc, discretionary) - d.pre = Babel.str_to_nodes(crep.pre, matches, char_base) - d.post = Babel.str_to_nodes(crep.post, matches, char_base) + table.remove(wn, sc) + w = u.sub(w, 1, sc-1) .. u.sub(w, sc+1) + last_match = utf8.offset(w, sc) + sc = sc - 1 &% Nothing has been inserted + + elseif mode == 1 and crep and (crep.pre or crep.no or crep.post) then + local d = node.new(7, 0) &% (disc, discretionary) + d.pre = Babel.str_to_nodes(crep.pre, matches, char_base) + d.post = Babel.str_to_nodes(crep.post, matches, char_base) d.replace = Babel.str_to_nodes(crep.no, matches, char_base) d.attr = char_base.attr if crep.pre == nil then &% TeXbook p96 - d.penalty = crep.penalty or tex.hyphenpenalty + d.penalty = crep.penalty or tex.hyphenpenalty else - d.penalty = crep.penalty or tex.exhyphenpenalty + d.penalty = crep.penalty or tex.exhyphenpenalty end head, new = node.insert_before(head, char_node, d) - node.remove(head, char_node) - if q == 1 then - word_head = new - end + end_replacement = true + + elseif crep and crep.penalty then + local d = node.new(14, 0) &% (penalty, userpenalty) + d.attr = char_base.attr + d.penalty = crep.penalty + head, new = node.insert_before(head, char_node, d) + end_replacement = true + elseif crep and crep.string then - changed = changed + 1 local str = crep.string(matches) - if str == '' then - if q == 1 then + if str == '' then &% Gather with nil + refetch = true + if sc == 1 then word_head = char_node.next end head, new = node.remove(head, char_node) elseif char_node.id == 29 and u.len(str) == 1 then char_node.char = string.utfvalue(str) + w = u.sub(w, 1, sc-1) .. str .. u.sub(w, sc+1) + last_match = utf8.offset(w, sc+1) else + refetch = true local n for s in string.utfvalues(str) do if char_node.id == 7 then - log('Automatic hyphens cannot be replaced, just removed.') + &% TODO. Remove this limitation. + texio.write_nl('Automatic hyphens cannot be replaced, just removed.') else n = node.copy(char_base) end n.char = s - if q == 1 then + if sc == 1 then head, new = node.insert_before(head, char_node, n) word_head = new else node.insert_before(head, char_node, n) end end - node.remove(head, char_node) end &% string length - end &% if char and char.string - end &% for char in match - if changed > 20 then - texio.write('Too many changes. Ignoring the rest.') - elseif changed > 0 then - w, wn, nw = Babel.fetch_word(word_head) + end &% if char and char.string (ie replacement cases) + + &% Shared by disc and penalty. + if end_replacement then + if sc == 1 then + word_head = new + end + if crep.insert then + last_match = save_last + else + node.remove(head, char_node) + w = u.sub(w, 1, sc-1) .. Babel.us_char .. u.sub(w, sc+1) + last_match = utf8.offset(w, sc) + end + end + end &% for each replacement + + if Babel.debug then + print('/', sc, first, last, last_match, w) + end + + &% TODO. refetch will be eventually unnecesary. + if refetch then + w, wn, nw, lang = Babel.fetch_subtext[mode](word_head) end end &% for match end &% for patterns + + ::next:: word_head = nw - end &% for words + end &% for substring return head end - &% The following functions belong to the next macro - &% This table stores capture maps, numbered consecutively Babel.capture_maps = {} + &% The following functions belong to the next macro function Babel.capture_func(key, cap) local ret = "[[" .. cap:gsub('{([0-9])}', "]]..m[%1]..[[") .. "]]" ret = ret:gsub('{([0-9])|([^|]+)|(.-)}', Babel.capture_func_map) @@ -1092,7 +1269,6 @@ end return "]]..Babel.capt_map(m[" .. capno .. "]," .. (mlen) .. ").." .. "[[" end - } \catcode`\#=6 \gdef\babelposthyphenation#1#2#3{&% @@ -1105,6 +1281,7 @@ end {\bbl@add@list\babeltempb{nil}}&% {\directlua{ local rep = [[##1]] + rep = rep:gsub('^%s*(insert)%s*,', 'insert = true, ') rep = rep:gsub( '(no)%s*=%s*([^%s,]*)', Babel.capture_func) rep = rep:gsub( '(pre)%s*=%s*([^%s,]*)', Babel.capture_func) rep = rep:gsub( '(post)%s*=%s*([^%s,]*)', Babel.capture_func) @@ -1112,13 +1289,15 @@ end tex.print([[\string\babeltempa{{]] .. rep .. [[}}]]) }}}&% \directlua{ - local lbkr = Babel.linebreaking.replacements + local lbkr = Babel.linebreaking.replacements[1] local u = unicode.utf8 &% Convert pattern: - local patt = string.gsub([[#2]], '%s', '') + local patt = string.gsub([==[#2]==], '%s', '') if not u.find(patt, '()', nil, true) then patt = '()' .. patt .. '()' end + patt = string.gsub(patt, '%(%)%^', '^()') + patt = string.gsub(patt, '%$%(%)', '()$') patt = u.gsub(patt, '{(.)}', function (n) return '%' .. (tonumber(n) and (tonumber(n)+1) or n) @@ -1128,12 +1307,50 @@ end { pattern = patt, replace = { \babeltempb } }) }&% \endgroup} +\gdef\babelprehyphenation#1#2#3{&% + \bbl@activateprehyphen + \begingroup + \def\babeltempa{\bbl@add@list\babeltempb}&% + \let\babeltempb\@empty + \bbl@foreach{#3}{&% + \bbl@ifsamestring{##1}{remove}&% + {\bbl@add@list\babeltempb{nil}}&% + {\directlua{ + local rep = [[##1]] + rep = rep:gsub('^%s*(insert)%s*,', 'insert = true, ') + rep = rep:gsub('(string)%s*=%s*([^%s,]*)', Babel.capture_func) + tex.print([[\string\babeltempa{{]] .. rep .. [[}}]]) + }}}&% + \directlua{ + local lbkr = Babel.linebreaking.replacements[0] + local u = unicode.utf8 + &% Convert pattern: + local patt = string.gsub([==[#2]==], '%s', '') + if not u.find(patt, '()', nil, true) then + patt = '()' .. patt .. '()' + end + &% patt = string.gsub(patt, '%(%)%^', '^()') + &% patt = string.gsub(patt, '([^%%])%$%(%)', '%1()$') + patt = u.gsub(patt, '{(.)}', + function (n) + return '%' .. (tonumber(n) and (tonumber(n)+1) or n) + end) + lbkr[\the\csname bbl@id@@#1\endcsname] = lbkr[\the\csname bbl@id@@#1\endcsname] or {} + table.insert(lbkr[\the\csname bbl@id@@#1\endcsname], + { pattern = patt, replace = { \babeltempb } }) + }&% + \endgroup} \endgroup \def\bbl@activateposthyphen{% \let\bbl@activateposthyphen\relax \directlua{ Babel.linebreaking.add_after(Babel.post_hyphenate_replace) }} +\def\bbl@activateprehyphen{% + \let\bbl@activateprehyphen\relax + \directlua{ + Babel.linebreaking.add_before(Babel.pre_hyphenate_replace) + }} \bbl@trace{Redefinitions for bidi layout} \ifx\@eqnnum\@undefined\else \ifx\bbl@attr@dir\@undefined\else @@ -1143,7 +1360,7 @@ end \fi \fi \ifx\bbl@opt@layout\@nnil\endinput\fi % if no layout -\ifx\bbl@beforeforeign\leavevmode % A poor test for bidi= +\ifnum\bbl@bidimode>\z@ \def\bbl@nextfake#1{% non-local changes, use always inside a group! \bbl@exp{% \mathdir\the\bodydir @@ -1192,25 +1409,23 @@ end {} \IfBabelLayout{graphics} {\let\bbl@pictresetdir\relax - \def\bbl@pictsetdir{% + \def\bbl@pictsetdir#1{% \ifcase\bbl@thetextdir \let\bbl@pictresetdir\relax \else - \textdir TLT\relax - \def\bbl@pictresetdir{\textdir TRT\relax}% + \bodydir TLT + % \(text|par)dir required in pgf: + \def\bbl@pictresetdir{\bodydir TRT\pardir TRT\textdir TRT\relax}% \fi}% - \let\bbl@OL@@picture\@picture - \let\bbl@OL@put\put - \bbl@sreplace\@picture{\hskip-}{\bbl@pictsetdir\hskip-}% - \def\put(#1,#2)#3{% Not easy to patch. Better redefine. - \@killglue - \raise#2\unitlength - \hb@xt@\z@{\kern#1\unitlength{\bbl@pictresetdir#3}\hss}}% + \ifx\AddToHook\@undefined\else + \AddToHook{env/picture/begin}{\bbl@pictsetdir\z@}% + \fi \AtBeginDocument {\ifx\tikz@atbegin@node\@undefined\else \let\bbl@OL@pgfpicture\pgfpicture - \bbl@sreplace\pgfpicture{\pgfpicturetrue}{\bbl@pictsetdir\pgfpicturetrue}% - \bbl@add\pgfsys@beginpicture{\bbl@pictsetdir}% + \bbl@sreplace\pgfpicture{\pgfpicturetrue}% + {\bbl@pictsetdir\@ne\pgfpicturetrue}% + \bbl@add\pgfsys@beginpicture{\bbl@pictsetdir\@ne}% \bbl@add\tikz@atbegin@node{\bbl@pictresetdir}% \fi}} {} @@ -1232,17 +1447,17 @@ end \let\bbl@OL@p@enumiii\p@enumiii \def\p@enumiii{\p@enumii)\theenumii(}}{}}{} \bbl@trace{Bidi footnotes} -\ifx\bbl@beforeforeign\leavevmode +\ifnum\bbl@bidimode>\z@ \def\bbl@footnote#1#2#3{% \@ifnextchar[% {\bbl@footnote@o{#1}{#2}{#3}}% {\bbl@footnote@x{#1}{#2}{#3}}} - \def\bbl@footnote@x#1#2#3#4{% + \long\def\bbl@footnote@x#1#2#3#4{% \bgroup \select@language@x{\bbl@main@language}% \bbl@fn@footnote{#2#1{\ignorespaces#4}#3}% \egroup} - \def\bbl@footnote@o#1#2#3[#4]#5{% + \long\def\bbl@footnote@o#1#2#3[#4]#5{% \bgroup \select@language@x{\bbl@main@language}% \bbl@fn@footnote[#4]{#2#1{\ignorespaces#5}#3}% @@ -1251,12 +1466,12 @@ end \@ifnextchar[% {\bbl@footnotetext@o{#1}{#2}{#3}}% {\bbl@footnotetext@x{#1}{#2}{#3}}} - \def\bbl@footnotetext@x#1#2#3#4{% + \long\def\bbl@footnotetext@x#1#2#3#4{% \bgroup \select@language@x{\bbl@main@language}% \bbl@fn@footnotetext{#2#1{\ignorespaces#4}#3}% \egroup} - \def\bbl@footnotetext@o#1#2#3[#4]#5{% + \long\def\bbl@footnotetext@o#1#2#3[#4]#5{% \bgroup \select@language@x{\bbl@main@language}% \bbl@fn@footnotetext[#4]{#2#1{\ignorespaces#5}#3}% |