summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/babel/luababel.def
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-05-14 21:24:22 +0000
committerKarl Berry <karl@freefriends.org>2020-05-14 21:24:22 +0000
commit0ceebb71618356e1ae06cdfd3cff81e322f2307b (patch)
treefb643d2536a1177f17c7c90410226f1accef7c31 /Master/texmf-dist/tex/generic/babel/luababel.def
parentbb587f3190ec7933ee6a18e994099e566c6e8009 (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.def209
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}}%