summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-03-24 21:27:50 +0000
committerKarl Berry <karl@freefriends.org>2021-03-24 21:27:50 +0000
commit45491db9ecb6686384257f5f3c0b3927716f7393 (patch)
tree6c3c9017ea55245586c4a3602be5d31698869f9b
parent4b61c48d71003f644004c8031f91a916d0a3b23a (diff)
babel (24mar21)
git-svn-id: svn://tug.org/texlive/trunk@58684 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/babel/README.md23
-rw-r--r--Master/texmf-dist/doc/latex/babel/babel.pdfbin818518 -> 824234 bytes
-rw-r--r--Master/texmf-dist/source/latex/babel/babel.dtx419
-rw-r--r--Master/texmf-dist/source/latex/babel/babel.ins2
-rw-r--r--Master/texmf-dist/source/latex/babel/bbcompat.dtx2
-rw-r--r--Master/texmf-dist/source/latex/babel/locale.zipbin778243 -> 778354 bytes
-rw-r--r--Master/texmf-dist/tex/generic/babel/babel.def42
-rw-r--r--Master/texmf-dist/tex/generic/babel/babel.sty2
-rw-r--r--Master/texmf-dist/tex/generic/babel/hyphen.cfg6
-rw-r--r--Master/texmf-dist/tex/generic/babel/locale/es/babel-es.ini7
-rw-r--r--Master/texmf-dist/tex/generic/babel/locale/mr/babel-mr.ini6
-rw-r--r--Master/texmf-dist/tex/generic/babel/luababel.def292
-rw-r--r--Master/texmf-dist/tex/generic/babel/nil.ldf2
13 files changed, 540 insertions, 263 deletions
diff --git a/Master/texmf-dist/doc/latex/babel/README.md b/Master/texmf-dist/doc/latex/babel/README.md
index 1ec95e18268..723cf41d822 100644
--- a/Master/texmf-dist/doc/latex/babel/README.md
+++ b/Master/texmf-dist/doc/latex/babel/README.md
@@ -1,4 +1,4 @@
-## Babel 3.55
+## Babel 3.56
This package manages culturally-determined typographical (and other)
rules, and hyphenation patterns for a wide range of languages. Many
@@ -8,9 +8,9 @@ is a set of ini files for about 250 languages.
The latest stable version is available on <https://ctan.org/pkg/babel>.
-Changes in version 3.55 are described in:
+Changes in version 3.56 are described in:
-https://github.com/latex3/babel/blob/master/news-guides/news/whats-new-in-babel-3.55.md
+https://github.com/latex3/babel/blob/master/news-guides/news/whats-new-in-babel-3.56.md
Apart from the manual, you can find information on some aspects of babel at:
@@ -46,16 +46,19 @@ respective authors.
### Summary of Latest changes
```
-3.55 2021-03-03??
- * Captions for Uyghur.
+3.56 2021-03-24
+ * Transforms (\babelprehyphenation, \babelposthyphenation)
+ - Key 'space', in em units.
+ - Key 'spacefactor', based on the current word separation.
+ - Multiple 'insert's allowed.
+ - Definable in 'ini' files.
+ - Arbitrary characters in pattern.
* Fixes:
- - Wrong caption in Romanian for Index (#117).
- - Missing lines in ngermanb.sty (#118).
- * There is also some tentative code to improve pgfpicture with
- RTL texts.
+ - 'insert' and 'data' didn't always set/get the expected node.
+ - Hyphen was not shown in Marathi (#123)
```
### Previous changes
-See https://github.com/latex3/babel/blob/master/news-guides/news/
+See https://github.com/latex3/babel/blob/master/news-guides/README.md#whats-new
diff --git a/Master/texmf-dist/doc/latex/babel/babel.pdf b/Master/texmf-dist/doc/latex/babel/babel.pdf
index 89135c5cb23..588c656f93e 100644
--- a/Master/texmf-dist/doc/latex/babel/babel.pdf
+++ b/Master/texmf-dist/doc/latex/babel/babel.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/babel/babel.dtx b/Master/texmf-dist/source/latex/babel/babel.dtx
index e91394c7bfb..9c8ff775c03 100644
--- a/Master/texmf-dist/source/latex/babel/babel.dtx
+++ b/Master/texmf-dist/source/latex/babel/babel.dtx
@@ -31,7 +31,7 @@
%
% \iffalse
%<*filedriver>
-\ProvidesFile{babel.dtx}[2021/03/03 v3.55 The Babel package]
+\ProvidesFile{babel.dtx}[2021/03/24 v3.56 The Babel package]
\documentclass{ltxdoc}
\GetFileInfo{babel.dtx}
\usepackage{fontspec}
@@ -750,22 +750,6 @@ environment of |\foreignlanguage|, except when the option |bidi| is
set -- in this case, |\foreignlanguage| emits a |\leavevmode|, while
|otherlanguage*| does not.
-\Describe{\begin\menv{hyphenrules}}{\marg{language}\Eenv{hyphenrules}}
-
-The environment \Lenv{hyphenrules} can be used to select \emph{only} the
-hyphenation rules to be used (it can be used as command, too). This can
-for instance be used to select `nohyphenation', provided that in
-\file{language.dat} the `language' \textsf{nohyphenation} is defined by
-loading \file{zerohyph.tex}. It deactivates language shorthands, too
-(but not user shorthands).
-
-Except for these simple uses, |hyphenrules| is deprecated and
-|otherlanguage*| (the starred version) is preferred, because the former
-does not take into account possible changes in encodings of characters
-like, say, |'| done by some languages (eg, \textsf{italian},
-\textsf{french}, \textsf{ukraineb}). To set hyphenation exceptions, use
-|\babelhyphenation| (see below).
-
\subsection{More on selection}
\Describe{\babeltags}{\char`\{\m{tag1} \texttt{=} \m{language1}, \m{tag2}
@@ -2967,6 +2951,28 @@ font encodings are the same, like in Unicode based engines.
language, you can add at least some typical cases.
\end{note}
+\begin{note}
+ To set hyphenation exceptions in the preamble before any language is
+ explicitly set with a selector, use |\babelhyphenation| instead of
+ |\hyphenation|. In the preamble the hyphenation rules are not always
+ fully set up and an error can be raised.
+\end{note}
+
+\Describe{\begin\menv{hyphenrules}}{\marg{language}\Eenv{hyphenrules}}
+
+The environment \Lenv{hyphenrules} can be used to select \emph{only} the
+hyphenation rules to be used (it can be used as command, too). This can
+for instance be used to select `nohyphenation', provided that in
+\file{language.dat} the `language' \textsf{nohyphenation} is defined by
+loading \file{zerohyph.tex}. It deactivates language shorthands, too
+(but not user shorthands).
+
+Except for these simple uses, |hyphenrules| is deprecated and
+|otherlanguage*| (the starred version) is preferred, because the former
+does not take into account possible changes in encodings of characters
+like, say, |'| done by some languages (eg, \textsf{italian},
+\textsf{french}, \textsf{ukraineb}).
+
\Describe{\babelpatterns}{\texttt{[}\langlist\texttt{]}%
\marg{patterns}}
@@ -3002,6 +3008,18 @@ Unicode engines, spacing is based on the ``current'' em unit (the size
of the previous char in \luatex, and the font size set by the last
|\selectfont| in \xetex).
+\subsection{Transforms}
+
+Transforms (only \luatex) provide a way to process the text on the
+typesetting level in several language-dependent ways, like non-standard
+hyphenation, special line breaking rules, script to script conversion,
+spacing conventions and so on.\footnote{They are similar in concept,
+but not the same, as those in Unicode.}
+
+It currently embraces |\babelprehyphenation| and
+|\babelposthyphenation|, which have been available for several months.
+\New{3.56} In this version they can be defined in |ini| files, too.
+
\Describe{\babelposthyphenation}{\marg{hyphenrules-name}%
\marg{lua-pattern}\marg{replacement}}
@@ -3042,20 +3060,15 @@ future implementation may alternatively accept \textsf{lpeg}.
\Describe{\babelprehyphenation}{\marg{locale-name}%
\marg{lua-pattern}\marg{replacement}}
-
-\New{3.44-3-52} This command is not strictly about hyphenation, but
-it is included here because it is a clear counterpart of
-|\babelposthyphenation|. It is similar to the latter, but (as its name
-implies) applied before hyphenation. There are other differences: (1)
-the first argument is the locale instead the name of hyphenation
-patterns; (2) in the search patterns |=| has no special meaning, while
-\verb+|+ stands for an ordinary space; (3) in the replacement,
-discretionaries are not accepted.
-It handles glyphs and spaces (but you can not insert spaces).
+\New{3.44-3-52} It is similar to the latter, but (as its name implies)
+applied before hyphenation. There are other differences: (1) the first
+argument is the locale instead the name of hyphenation patterns; (2) in
+the search patterns |=| has no special meaning, while \verb+|+ stands
+for an ordinary space; (3) in the replacement, discretionaries are not
+accepted.
-Performance is still somewhat poor in some cases, but it is fast in the
-typical ones.
+It handles glyphs and spaces.
This feature is activated with the first |\babelposthyphenation| or
|\babelprehyphenation|.
@@ -4849,8 +4862,8 @@ help from Bernd Raichle, for which I am grateful.
% \section{Tools}
%
% \begin{macrocode}
-%<<version=3.55>>
-%<<date=2021/03/03>>
+%<<version=3.56>>
+%<<date=2021/03/24>>
% \end{macrocode}
%
% \textbf{Do not use the following macros in \texttt{ldf} files. They
@@ -10657,6 +10670,7 @@ help from Bernd Raichle, for which I am grateful.
\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
@@ -10699,6 +10713,10 @@ help from Bernd Raichle, for which I am grateful.
\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}}%
@@ -11294,6 +11312,8 @@ help from Bernd Raichle, for which I am grateful.
\bbl@cs{@kv@identification.warning#1}\\%
Reported }}}
%
+\let\bbl@release@transforms\@empty
+%
\def\bbl@ini@exports#1{%
% Identification always exported
\bbl@iniwarning{}%
@@ -11319,6 +11339,8 @@ help from Bernd Raichle, for which I am grateful.
\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}%
@@ -11676,6 +11698,39 @@ help from Bernd Raichle, for which I am grateful.
\def\bbl@xdatecntr[#1|#2]{\localenumeral{#2}{#1}}
% \end{macrocode}
%
+% \textbf{Transforms.}
+%
+% \begin{macrocode}
+\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
+% \end{macrocode}
+%
% Language and Script values to be used when defining a font or
% setting the direction are set with the following macros.
%
@@ -13881,6 +13936,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)
@@ -13891,11 +13971,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
@@ -13906,11 +13986,11 @@ end
&% For each saved (pre|post)hyphenation. TODO. Reconsider how
&% loops are nested.
for k=1, #lbkr[lang] do
- local p = lbkr[lang][k].pattern
+ local p = lbkr[lang][k].pattern
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*
@@ -13918,10 +13998,10 @@ end
&% computed position based on sc if w has changed.
local last_match = 0
- &% For every match.
+ &% For every match.
while true do
if Babel.debug then
- print('-----')
+ print('=====')
end
local new &% used when inserting and removing nodes
local refetch = false
@@ -13933,7 +14013,7 @@ end
&% number with the position), and keep actual captures
&% (from (...)), if any, in matches.
local first = table.remove(matches, 1)
- local last = table.remove(matches, #matches)
+ local last = table.remove(matches, #matches)
&% Non re-fetched substrings may contain \31, which separates
&% subsubstrings.
if string.find(w:sub(first, last-1), Babel.us_char) then break end
@@ -13944,126 +14024,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)
+ print('.....', '/')
+ Babel.debug_hyph(w, w_nodes, sc, first, last, last_match)
end
- &% TODO. refetch will be eventually unnecesary.
- if refetch then
- w, wn, nw, lang = Babel.fetch_subtext[mode](word_head)
- end
-
end &% for match
+
end &% for patterns
::next::
@@ -14128,11 +14253,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)
@@ -14143,6 +14271,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
@@ -14151,12 +14280,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}
% TODO. Copypaste pattern.
@@ -14165,18 +14297,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
@@ -14185,12 +14325,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
@@ -21080,13 +21223,13 @@ function Babel.bidi(head, ispar, hdir)
first_et = nil
has_en = false
end
-
+
-- Force mathdir in math if ON (currently works as expected only
-- with 'l')
if inmath and d == 'on' then
d = ('TRT' == tex.mathdir) and 'r' or 'l'
end
-
+
if d then
if d == 'al' then
d = 'r'
diff --git a/Master/texmf-dist/source/latex/babel/babel.ins b/Master/texmf-dist/source/latex/babel/babel.ins
index 29d689b4b86..bb675249c6f 100644
--- a/Master/texmf-dist/source/latex/babel/babel.ins
+++ b/Master/texmf-dist/source/latex/babel/babel.ins
@@ -26,7 +26,7 @@
%% and covered by LPPL is defined by the unpacking scripts (with
%% extension .ins) which are part of the distribution.
%%
-\def\filedate{2021/03/03}
+\def\filedate{2021/03/24}
\def\batchfile{babel.ins}
\input docstrip.tex
diff --git a/Master/texmf-dist/source/latex/babel/bbcompat.dtx b/Master/texmf-dist/source/latex/babel/bbcompat.dtx
index 91092197f2a..efd3eb77dbf 100644
--- a/Master/texmf-dist/source/latex/babel/bbcompat.dtx
+++ b/Master/texmf-dist/source/latex/babel/bbcompat.dtx
@@ -30,7 +30,7 @@
%
% \iffalse
%<*dtx>
-\ProvidesFile{bbcompat.dtx}[2021/03/03 v3.55]
+\ProvidesFile{bbcompat.dtx}[2021/03/24 v3.56]
%</dtx>
%
%% File 'bbcompat.dtx'
diff --git a/Master/texmf-dist/source/latex/babel/locale.zip b/Master/texmf-dist/source/latex/babel/locale.zip
index 34b8e0b0e11..0f9331de0cd 100644
--- a/Master/texmf-dist/source/latex/babel/locale.zip
+++ b/Master/texmf-dist/source/latex/babel/locale.zip
Binary files differ
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