diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/babel/luababel.def')
-rw-r--r-- | Master/texmf-dist/tex/generic/babel/luababel.def | 292 |
1 files changed, 190 insertions, 102 deletions
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 |