From 45491db9ecb6686384257f5f3c0b3927716f7393 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 24 Mar 2021 21:27:50 +0000 Subject: babel (24mar21) git-svn-id: svn://tug.org/texlive/trunk@58684 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/generic/babel/babel.def | 42 ++- Master/texmf-dist/tex/generic/babel/babel.sty | 2 +- Master/texmf-dist/tex/generic/babel/hyphen.cfg | 6 +- .../tex/generic/babel/locale/es/babel-es.ini | 7 + .../tex/generic/babel/locale/mr/babel-mr.ini | 6 +- Master/texmf-dist/tex/generic/babel/luababel.def | 292 ++++++++++++++------- Master/texmf-dist/tex/generic/babel/nil.ldf | 2 +- 7 files changed, 244 insertions(+), 113 deletions(-) (limited to 'Master/texmf-dist/tex/generic') diff --git a/Master/texmf-dist/tex/generic/babel/babel.def b/Master/texmf-dist/tex/generic/babel/babel.def index 60c7c172e36..98495230347 100644 --- a/Master/texmf-dist/tex/generic/babel/babel.def +++ b/Master/texmf-dist/tex/generic/babel/babel.def @@ -39,7 +39,7 @@ \wlog{File: #1 #4 #3 <#2>}% \let\ProvidesFile\@undefined} \fi -\ProvidesFile{babel.def}[2021/03/03 3.55 Babel common definitions] +\ProvidesFile{babel.def}[2021/03/24 3.56 Babel common definitions] \ifx\AtBeginDocument\@undefined % TODO. change test. % == Code for plain == \def\@empty{} @@ -397,8 +397,8 @@ \fi \countdef\last@language=19 % TODO. why? remove? \def\addlanguage{\csname newlanguage\endcsname} -\def\bbl@version{3.55} -\def\bbl@date{2021/03/03} +\def\bbl@version{3.56} +\def\bbl@date{2021/03/24} \def\adddialect#1#2{% \global\chardef#1#2\relax \bbl@usehooks{adddialect}{{#1}{#2}}% @@ -2335,6 +2335,7 @@ \let\bbl@KVP@intraspace\@nil \let\bbl@KVP@intrapenalty\@nil \let\bbl@KVP@onchar\@nil + \let\bbl@KVP@transforms\@nil \let\bbl@KVP@alph\@nil \let\bbl@KVP@Alph\@nil \let\bbl@KVP@labels\@nil @@ -2377,6 +2378,10 @@ \ifx\bbl@KVP@captions\@nil \let\bbl@KVP@captions\bbl@KVP@import \fi + % == + \ifx\bbl@KVP@transforms\@nil\else + \bbl@replace\bbl@KVP@transforms{ }{,}% + \fi % Load ini \bbl@ifunset{date#2}% {\bbl@provide@new{#2}}% @@ -2893,6 +2898,7 @@ From babel-\bbl@cs{lini@\languagename}.ini:\\% \bbl@cs{@kv@identification.warning#1}\\% Reported }}} +\let\bbl@release@transforms\@empty \def\bbl@ini@exports#1{% % Identification always exported \bbl@iniwarning{}% @@ -2918,6 +2924,8 @@ \ifbbl@bcptoname \bbl@csarg\xdef{bcp@map@\bbl@cl{tbcp}}{\languagename}% \fi + % Finish here transforms, too + \bbl@release@transforms\relax % \relax closes the last item. % Conditional \ifnum#1>\z@ % 0 = only info, 1, 2 = basic, (re)new \bbl@exportkey{lnbrk}{typography.linebreaking}{h}% @@ -3208,6 +3216,34 @@ \bbl@replace@finish@iii\bbl@toreplace} \def\bbl@datecntr{\expandafter\bbl@xdatecntr\expandafter} \def\bbl@xdatecntr[#1|#2]{\localenumeral{#2}{#1}} +\let\bbl@release@transforms\@empty +\@namedef{bbl@inikv@transforms.prehyphenation}{% + \bbl@transforms\babelprehyphenation} +\@namedef{bbl@inikv@transforms.posthyphenation}{% + \bbl@transforms\babelposthyphenation} +\def\bbl@transforms@aux#1#2#3,#4\relax{#1{#2}{#3}{#4}} +\begingroup + \catcode`\%=12 + \catcode`\&=14 + \gdef\bbl@transforms#1#2#3{&% + \ifx\bbl@KVP@transforms\@nil\else + \directlua{ + str = [==[#2]==] + str = str:gsub('%.%d+%.%d+$', '') + tex.print([[\def\string\babeltempa{]] .. str .. [[}]]) + }&% + \bbl@xin@{,\babeltempa,}{,\bbl@KVP@transforms,}&% + \ifin@ + \in@{.0$}{#2$}&% + \ifin@ + \bbl@add\bbl@release@transforms{&% + \relax\bbl@transforms@aux#1{\languagename}{#3}}&% + \else + \bbl@add\bbl@release@transforms{, {#3}}&% + \fi + \fi + \fi} +\endgroup \def\bbl@provide@lsys#1{% \bbl@ifunset{bbl@lname@#1}% {\bbl@load@info{#1}}% diff --git a/Master/texmf-dist/tex/generic/babel/babel.sty b/Master/texmf-dist/tex/generic/babel/babel.sty index f0c953c9951..ca2c203a858 100644 --- a/Master/texmf-dist/tex/generic/babel/babel.sty +++ b/Master/texmf-dist/tex/generic/babel/babel.sty @@ -33,7 +33,7 @@ %% \NeedsTeXFormat{LaTeX2e}[2005/12/01] -\ProvidesPackage{babel}[2021/03/03 3.55 The Babel package] +\ProvidesPackage{babel}[2021/03/24 3.56 The Babel package] \@ifpackagewith{babel}{debug} {\providecommand\bbl@trace[1]{\message{^^J[ #1 ]}}% \let\bbl@debug\@firstofone diff --git a/Master/texmf-dist/tex/generic/babel/hyphen.cfg b/Master/texmf-dist/tex/generic/babel/hyphen.cfg index 2c8ef5ce321..df8e10deb11 100644 --- a/Master/texmf-dist/tex/generic/babel/hyphen.cfg +++ b/Master/texmf-dist/tex/generic/babel/hyphen.cfg @@ -37,10 +37,10 @@ \wlog{File: #1 #4 #3 <#2>}% \let\ProvidesFile\@undefined} \fi -\ProvidesFile{hyphen.cfg}[2021/03/03 3.55 Babel hyphens] +\ProvidesFile{hyphen.cfg}[2021/03/24 3.56 Babel hyphens] \xdef\bbl@format{\jobname} -\def\bbl@version{3.55} -\def\bbl@date{2021/03/03} +\def\bbl@version{3.56} +\def\bbl@date{2021/03/24} \ifx\AtBeginDocument\@undefined \def\@empty{} \let\orig@dump\dump diff --git a/Master/texmf-dist/tex/generic/babel/locale/es/babel-es.ini b/Master/texmf-dist/tex/generic/babel/locale/es/babel-es.ini index 5ed832dd28d..733293f938f 100644 --- a/Master/texmf-dist/tex/generic/babel/locale/es/babel-es.ini +++ b/Master/texmf-dist/tex/generic/babel/locale/es/babel-es.ini @@ -183,3 +183,10 @@ plusSign = + superscriptingExponent = × [counters] + +[transforms.prehyphenation] +; Experimental. Don't use in production +percent.space.1.0 = { {d}{0025} } +percent.space.1.1 = {} +percent.space.1.2 = { insert, spacefactor = .5 .3 .5, data = 1 } +percent.space.1.3 = {} diff --git a/Master/texmf-dist/tex/generic/babel/locale/mr/babel-mr.ini b/Master/texmf-dist/tex/generic/babel/locale/mr/babel-mr.ini index 8935a54b2ad..1178e561099 100644 --- a/Master/texmf-dist/tex/generic/babel/locale/mr/babel-mr.ini +++ b/Master/texmf-dist/tex/generic/babel/locale/mr/babel-mr.ini @@ -13,8 +13,8 @@ [identification] charset = utf8 -version = 1.8 -date = 2020-10-11 +version = 1.9 +date = 2021-03-16 name.local = मराठी name.english = Marathi name.babel = marathi @@ -118,7 +118,7 @@ hyphenrules = marathi lefthyphenmin = 2 righthyphenmin = 2 hyphenchar = -prehyphenchar = 0 +prehyphenchar = posthyphenchar = exhyphenchar = preexhyphenchar = diff --git a/Master/texmf-dist/tex/generic/babel/luababel.def b/Master/texmf-dist/tex/generic/babel/luababel.def index a032fbe7631..0d00d5b238d 100644 --- a/Master/texmf-dist/tex/generic/babel/luababel.def +++ b/Master/texmf-dist/tex/generic/babel/luababel.def @@ -1046,6 +1046,31 @@ end Babel.hyphenate_replace(head, 1) end + function Babel.debug_hyph(w, wn, sc, first, last, last_match) + local ss = '' + for pp = 1, 40 do + if wn[pp] then + if wn[pp].id == 29 then + ss = ss .. unicode.utf8.char(wn[pp].char) + else + ss = ss .. '{' .. wn[pp].id .. '}' + end + end + end + print('nod', ss) + print('lst_m', + string.rep(' ', unicode.utf8.len( + string.sub(w, 1, last_match))-1) .. '>') + print('str', w) + print('sc', string.rep(' ', sc-1) .. '^') + if first == last then + print('f=l', string.rep(' ', first-1) .. '!') + else + print('f/l', string.rep(' ', first-1) .. '[' .. + string.rep(' ', last-first-1) .. ']') + end + end + Babel.us_char = string.char(31) function Babel.hyphenate_replace(head, mode) @@ -1056,11 +1081,11 @@ end while true do &% for each subtext block - local w, wn, nw, lang = Babel.fetch_subtext[mode](word_head) + local w, w_nodes, nw, lang = Babel.fetch_subtext[mode](word_head) if Babel.debug then print() - print('@@@@@', w, nw) + print((mode == 0) and '@@@@<' or '@@@@>', w) end if nw == nil and w == '' then break end @@ -1075,7 +1100,7 @@ end local r = lbkr[lang][k].replace if Babel.debug then - print('=====', p, mode) + print('*****', p, mode) end &% This variable is set in some cases below to the first *byte* @@ -1086,7 +1111,7 @@ end &% For every match. while true do if Babel.debug then - print('-----') + print('=====') end local new &% used when inserting and removing nodes local refetch = false @@ -1109,126 +1134,171 @@ end first = u.len(w:sub(1, first-1)) + 1 last = u.len(w:sub(1, last-1)) &% now last points to C - if Babel.debug then - print(p) - print('', 'sc', 'first', 'last', 'last_m', 'w') + &% This loop stores in n small table the nodes + &% corresponding to the pattern. Used by 'data' to provide a + &% predictable behavior with 'insert' (now w_nodes is modified on + &% the fly), and also access to 'remove'd nodes. + local sc = first-1 &% Used below, too + local data_nodes = {} + + for q = 1, last-first+1 do + data_nodes[q] = w_nodes[sc+q] end &% 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('.....') + print('.....', rc + 1) 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] + if Babel.debug then + Babel.debug_hyph(w, w_nodes, sc, first, last, last_match) end - if Babel.debug then - print('*', sc, first, last, last_match, w) + local crep = r[rc] + local item = w_nodes[sc] + local item_base = item + local placeholder = Babel.us_char + local d + + if crep and crep.data then + item_base = data_nodes[crep.data] end - if crep and next(crep) == nil then &% {} - last_match = save_last + if crep and next(crep) == nil then &% = {} + last_match = save_last &% Optimization + goto next - elseif crep == nil then &% remove - node.remove(head, char_node) - table.remove(wn, sc) + elseif crep == nil or crep.remove then + node.remove(head, item) + table.remove(w_nodes, 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 + sc = sc - 1 &% Nothing has been inserted. + last_match = utf8.offset(w, sc+1) + goto next + + elseif crep and crep.string then + local str = crep.string(matches) + if str == '' then &% Gather with nil + node.remove(head, item) + table.remove(w_nodes, sc) + w = u.sub(w, 1, sc-1) .. u.sub(w, sc+1) + sc = sc - 1 &% Nothing has been inserted. + else + local loop_first = true + for s in string.utfvalues(str) do + d = node.copy(item_base) + d.char = s + if loop_first then + loop_first = false + head, new = node.insert_before(head, item, d) + if sc == 1 then + word_head = head + end + w_nodes[sc] = d + w = u.sub(w, 1, sc-1) .. u.char(s) .. u.sub(w, sc+1) + else + sc = sc + 1 + head, new = node.insert_before(head, item, d) + table.insert(w_nodes, sc, new) + w = u.sub(w, 1, sc-1) .. u.char(s) .. u.sub(w, sc) + end + if Babel.debug then + print('.....', 'str') + Babel.debug_hyph(w, w_nodes, sc, first, last, last_match) + end + end &% for + node.remove(head, item) + end &% if '' + last_match = utf8.offset(w, sc+1) + goto next 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 + d = node.new(7, 0) &% (disc, discretionary) + d.pre = Babel.str_to_nodes(crep.pre, matches, item_base) + d.post = Babel.str_to_nodes(crep.post, matches, item_base) + d.replace = Babel.str_to_nodes(crep.no, matches, item_base) + d.attr = item_base.attr if crep.pre == nil then &% TeXbook p96 d.penalty = crep.penalty or tex.hyphenpenalty else d.penalty = crep.penalty or tex.exhyphenpenalty end - head, new = node.insert_before(head, char_node, d) - end_replacement = true + placeholder = '|' + head, new = node.insert_before(head, item, d) + + elseif mode == 0 and crep and (crep.pre or crep.no or crep.post) then + &% ERROR elseif crep and crep.penalty then - local d = node.new(14, 0) &% (penalty, userpenalty) - d.attr = char_base.attr + d = node.new(14, 0) &% (penalty, userpenalty) + d.attr = item_base.attr d.penalty = crep.penalty - head, new = node.insert_before(head, char_node, d) - end_replacement = true - - elseif crep and crep.string then - local str = crep.string(matches) - 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 - &% 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 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 (ie replacement cases) - - &% Shared by disc and penalty. - if end_replacement then - if sc == 1 then - word_head = new + head, new = node.insert_before(head, item, d) + + elseif crep and crep.space then + &% 655360 = 10 pt = 10 * 65536 sp + d = node.new(12, 13) &% (glue, spaceskip) + local quad = font.getfont(item_base.font).size or 655360 + node.setglue(d, crep.space[1] * quad, + crep.space[2] * quad, + crep.space[3] * quad) + if mode == 0 then + placeholder = '|' 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) + head, new = node.insert_before(head, item, d) + + elseif crep and crep.spacefactor then + d = node.new(12, 13) &% (glue, spaceskip) + local base_font = font.getfont(item_base.font) + node.setglue(d, + crep.spacefactor[1] * base_font.parameters['space'], + crep.spacefactor[2] * base_font.parameters['space_stretch'], + crep.spacefactor[3] * base_font.parameters['space_shrink']) + if mode == 0 then + placeholder = '|' end + head, new = node.insert_before(head, item, d) + + elseif mode == 0 and crep and crep.space then + &% ERROR + + end &% ie replacement cases + + &% Shared by disc, space and penalty. + if sc == 1 then + word_head = head + end + if crep.insert then + w = u.sub(w, 1, sc-1) .. placeholder .. u.sub(w, sc) + table.insert(w_nodes, sc, new) + last = last + 1 + else + w_nodes[sc] = d + node.remove(head, item) + w = u.sub(w, 1, sc-1) .. placeholder .. u.sub(w, sc+1) end + + last_match = utf8.offset(w, sc+1) + + ::next:: + 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) + print('.....', '/') + Babel.debug_hyph(w, w_nodes, sc, first, last, last_match) end end &% for match + end &% for patterns ::next:: @@ -1276,11 +1346,14 @@ end \begingroup \def\babeltempa{\bbl@add@list\babeltempb}&% \let\babeltempb\@empty - \bbl@foreach{#3}{&% + \def\bbl@tempa{#3}&% TODO. Ugly trick to preserve {}: + \bbl@replace\bbl@tempa{,}{ ,}&% + \expandafter\bbl@foreach\expandafter{\bbl@tempa}{&% \bbl@ifsamestring{##1}{remove}&% {\bbl@add@list\babeltempb{nil}}&% {\directlua{ - local rep = [[##1]] + local rep = [=[##1]=] + rep = rep:gsub('^%s*(remove)%s*$', 'remove = true') 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) @@ -1291,6 +1364,7 @@ end \directlua{ local lbkr = Babel.linebreaking.replacements[1] local u = unicode.utf8 + local id = \the\csname l@#1\endcsname &% Convert pattern: local patt = string.gsub([==[#2]==], '%s', '') if not u.find(patt, '()', nil, true) then @@ -1299,12 +1373,15 @@ end patt = string.gsub(patt, '%(%)%^', '^()') patt = string.gsub(patt, '%$%(%)', '()$') patt = u.gsub(patt, '{(.)}', - function (n) - return '%' .. (tonumber(n) and (tonumber(n)+1) or n) - end) - lbkr[\the\csname l@#1\endcsname] = lbkr[\the\csname l@#1\endcsname] or {} - table.insert(lbkr[\the\csname l@#1\endcsname], - { pattern = patt, replace = { \babeltempb } }) + function (n) + return '%' .. (tonumber(n) and (tonumber(n)+1) or n) + end) + patt = u.gsub(patt, '{(%x%x%x%x+)}', + function (n) + return u.gsub(u.char(tonumber(n, 16)), '(%p)', '%%%1') + end) + lbkr[id] = lbkr[id] or {} + table.insert(lbkr[id], { pattern = patt, replace = { \babeltempb } }) }&% \endgroup} \gdef\babelprehyphenation#1#2#3{&% @@ -1312,18 +1389,26 @@ end \begingroup \def\babeltempa{\bbl@add@list\babeltempb}&% \let\babeltempb\@empty - \bbl@foreach{#3}{&% + \def\bbl@tempa{#3}&% TODO. Ugly trick to preserve {}: + \bbl@replace\bbl@tempa{,}{ ,}&% + \expandafter\bbl@foreach\expandafter{\bbl@tempa}{&% \bbl@ifsamestring{##1}{remove}&% {\bbl@add@list\babeltempb{nil}}&% {\directlua{ - local rep = [[##1]] + local rep = [=[##1]=] + rep = rep:gsub('^%s*(remove)%s*$', 'remove = true') rep = rep:gsub('^%s*(insert)%s*,', 'insert = true, ') rep = rep:gsub('(string)%s*=%s*([^%s,]*)', Babel.capture_func) + rep = rep:gsub( '(space)%s*=%s*([%d%.]+)%s+([%d%.]+)%s+([%d%.]+)', + 'space = {' .. '%2, %3, %4' .. '}') + rep = rep:gsub( '(spacefactor)%s*=%s*([%d%.]+)%s+([%d%.]+)%s+([%d%.]+)', + 'spacefactor = {' .. '%2, %3, %4' .. '}') tex.print([[\string\babeltempa{{]] .. rep .. [[}}]]) }}}&% \directlua{ local lbkr = Babel.linebreaking.replacements[0] local u = unicode.utf8 + local id = \the\csname bbl@id@@#1\endcsname &% Convert pattern: local patt = string.gsub([==[#2]==], '%s', '') if not u.find(patt, '()', nil, true) then @@ -1332,12 +1417,15 @@ 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 } }) + function (n) + return '%' .. (tonumber(n) and (tonumber(n)+1) or n) + end) + patt = u.gsub(patt, '{(%x%x%x%x+)}', + function (n) + return u.gsub(u.char(tonumber(n, 16)), '(%p)', '%%%1') + end) + lbkr[id] = lbkr[id] or {} + table.insert(lbkr[id], { pattern = patt, replace = { \babeltempb } }) }&% \endgroup} \endgroup diff --git a/Master/texmf-dist/tex/generic/babel/nil.ldf b/Master/texmf-dist/tex/generic/babel/nil.ldf index d7733c017a6..4d4b1e326a5 100644 --- a/Master/texmf-dist/tex/generic/babel/nil.ldf +++ b/Master/texmf-dist/tex/generic/babel/nil.ldf @@ -32,7 +32,7 @@ %% extension |.ins|) which are part of the distribution. %% -\ProvidesLanguage{nil}[2021/03/03 3.55 Nil language] +\ProvidesLanguage{nil}[2021/03/24 3.56 Nil language] \LdfInit{nil}{datenil} \ifx\l@nil\@undefined \newlanguage\l@nil -- cgit v1.2.3