summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/babel/luababel.def
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/babel/luababel.def')
-rw-r--r--Master/texmf-dist/tex/generic/babel/luababel.def292
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