diff options
author | Karl Berry <karl@freefriends.org> | 2020-05-14 21:24:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-05-14 21:24:22 +0000 |
commit | 0ceebb71618356e1ae06cdfd3cff81e322f2307b (patch) | |
tree | fb643d2536a1177f17c7c90410226f1accef7c31 /Master/texmf-dist/tex/generic/babel/luababel.def | |
parent | bb587f3190ec7933ee6a18e994099e566c6e8009 (diff) |
babel (13may20)
git-svn-id: svn://tug.org/texlive/trunk@55143 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 | 209 |
1 files changed, 198 insertions, 11 deletions
diff --git a/Master/texmf-dist/tex/generic/babel/luababel.def b/Master/texmf-dist/tex/generic/babel/luababel.def index 1767810fa08..6420f102887 100644 --- a/Master/texmf-dist/tex/generic/babel/luababel.def +++ b/Master/texmf-dist/tex/generic/babel/luababel.def @@ -251,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 @@ -859,8 +860,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{% @@ -874,7 +875,8 @@ end \catcode`\%=12 \catcode`\&=14 \directlua{ - Babel.linebreaking.replacements = {} + Babel.linebreaking.post_replacements = {} + Babel.linebreaking.pre_replacements = {} function Babel.str_to_nodes(fn, matches, base) local n, head, last @@ -900,25 +902,30 @@ end 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 not inmath and (item.lang == lang or lang == nil) then lang = lang or item.lang word_string = word_string .. unicode.utf8.char(item.char) word_nodes[#word_nodes+1] = item - elseif item.id == 7 and item.subtype == 2 then + elseif item.id == 7 and item.subtype == 2 and not inmath then word_string = word_string .. '=' word_nodes[#word_nodes+1] = item - elseif item.id == 7 and item.subtype == 3 then + elseif item.id == 7 and item.subtype == 3 and not inmath then word_string = word_string .. '|' word_nodes[#word_nodes+1] = item + elseif item.id == node.id'math' then + inmath = (item.subtype == 0) + elseif word_string == '' then &% pass @@ -932,7 +939,7 @@ end function Babel.post_hyphenate_replace(head) local u = unicode.utf8 - local lbkr = Babel.linebreaking.replacements + local lbkr = Babel.linebreaking.post_replacements local word_head = head while true do @@ -1038,6 +1045,152 @@ end return head end + &%%% + &% Preliminary code for \babelprehyphenation + &% TODO. Copypaste pattern. Merge with fetch_word + function Babel.fetch_subtext(head, funct) + local word_string = '' + local word_nodes = {} + local lang + local item = head + local inmath = false + + while item do + + if item.id == 29 then + local locale = node.get_attribute(item, Babel.attr_locale) + + if not(item.char == 124) &% ie, not | = space + and not inmath + and (locale == lang or lang == nil) then + lang = lang or locale + word_string = word_string .. unicode.utf8.char(item.char) + word_nodes[#word_nodes+1] = item + end + + if item == node.tail(head) then + item = nil + return word_string, word_nodes, item, lang + end + + elseif item.id == 12 and item.subtype == 13 and not inmath then + word_string = word_string .. '|' + word_nodes[#word_nodes+1] = item + + if item == node.tail(head) then + item = nil + return word_string, word_nodes, item, lang + end + + elseif item.id == node.id'math' then + inmath = (item.subtype == 0) + + elseif word_string == '' then + &% pass + + else + return word_string, word_nodes, item, lang + end + + item = item.next + end + end + + &% TODO. Copypaste pattern. Merge with pre_hyphenate_replace + function Babel.pre_hyphenate_replace(head) + local u = unicode.utf8 + local lbkr = Babel.linebreaking.pre_replacements + local word_head = head + + while true do + local w, wn, nw, lang = Babel.fetch_subtext(word_head) + if not lang then return head end + + if not lbkr[lang] then + break + end + + for k=1, #lbkr[lang] do + local p = lbkr[lang][k].pattern + local r = lbkr[lang][k].replace + + while true do + local matches = { u.match(w, p) } + if #matches < 2 then break end + + local first = table.remove(matches, 1) + local last = table.remove(matches, #matches) + + &% Fix offsets, from bytes to unicode. + first = u.len(w:sub(1, first-1)) + 1 + last = u.len(w:sub(1, last-1)) + + local new &% used when inserting and removing nodes + local changed = 0 + + &% 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] + local char_base = char_node + + 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 + node.remove(head, char_node) + elseif crep and crep.string then + changed = changed + 1 + local str = crep.string(matches) + if str == '' then + if q == 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) + else + local n + for s in string.utfvalues(str) do + if char_node.id == 7 then + log('Automatic hyphens cannot be replaced, just removed.') + else + n = node.copy(char_base) + end + n.char = s + if q == 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 + &% For one-to-one can we modifiy directly the + &% values without re-fetching? Very likely. + w, wn, nw = Babel.fetch_subtext(word_head) + end + + end &% for match + end &% for patterns + word_head = nw + end &% for words + return head + end + &%%% end of preliminary code for \babelprehyphenation + &% The following functions belong to the next macro &% This table stores capture maps, numbered consecutively @@ -1071,7 +1224,6 @@ end return "]]..Babel.capt_map(m[" .. capno .. "]," .. (mlen) .. ").." .. "[[" end - } \catcode`\#=6 \gdef\babelposthyphenation#1#2#3{&% @@ -1091,10 +1243,10 @@ end tex.print([[\string\babeltempa{{]] .. rep .. [[}}]]) }}}&% \directlua{ - local lbkr = Babel.linebreaking.replacements + local lbkr = Babel.linebreaking.post_replacements 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 @@ -1107,12 +1259,47 @@ 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('(string)%s*=%s*([^%s,]*)', Babel.capture_func) + tex.print([[\string\babeltempa{{]] .. rep .. [[}}]]) + }}}&% + \directlua{ + local lbkr = Babel.linebreaking.pre_replacements + local u = unicode.utf8 + &% Convert pattern: + local patt = string.gsub([==[#2]==], '%s', '') + if not u.find(patt, '()', nil, true) then + patt = '()' .. patt .. '()' + end + 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 @@ -1122,7 +1309,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 @@ -1211,7 +1398,7 @@ 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}}% |