summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/lualatex/lua-typo/lua-typo.dtx265
1 files changed, 149 insertions, 116 deletions
diff --git a/Master/texmf-dist/source/lualatex/lua-typo/lua-typo.dtx b/Master/texmf-dist/source/lualatex/lua-typo/lua-typo.dtx
index d1a4b0068a8..0208839779c 100644
--- a/Master/texmf-dist/source/lualatex/lua-typo/lua-typo.dtx
+++ b/Master/texmf-dist/source/lualatex/lua-typo/lua-typo.dtx
@@ -1,4 +1,4 @@
-% \CheckSum{337}
+% \CheckSum{336}
%
% \iffalse meta-comment
%
@@ -34,6 +34,7 @@
\postamble
\endpostamble
\let\MetaPrefix\DoubleperCent
+\askforoverwritefalse
\generate{%
\file{lua-typo.sty}{\from{lua-typo.dtx}{sty}}% {sty,msg,dbg}
\nopreamble
@@ -618,7 +619,7 @@
\ProvidesFile{lua-typo.dtx}
%</dtx>
%<*dtx|sty>
- [2021/03/03 v.0.30 Daniel Flipo]
+ [2021/03/14 v.0.32 Daniel Flipo]
%</dtx|sty>
%<*sty>
% \fi
@@ -841,7 +842,7 @@ luatypo = { }
}
% \end{macrocode}
%
-% Print the summary of offending pages ---if any-- at the
+% Print the summary of offending pages ---if any--- at the
% (very) end of document unless option |None| has been selected.
%
% \begin{macrocode}
@@ -864,8 +865,8 @@ luatypo = { }
texio.write_nl('*** lua-typo: No Typo Flaws found.')
else
texio.write_nl('*** lua-typo: WARNING *************')
- texio.write_nl('The following pages need attention: '
- .. luatypo.pagelist)
+ texio.write_nl('The following pages need attention: ')
+ texio.write(luatypo.pagelist)
end
texio.write_nl('***********************************')
texio.write_nl(' ')
@@ -955,6 +956,7 @@ local hyphcount = 0
local parlines = 0
local pagelines = 0
local pageno = 0
+local prevno = 0
local pageflag = false
local char_to_discard = { }
@@ -972,6 +974,8 @@ split_lig[0xFB01] = "fi"
split_lig[0xFB02] = "fl"
split_lig[0xFB03] = "ffi"
split_lig[0xFB04] = "ffl"
+split_lig[0xFB05] = "st"
+split_lig[0xFB06] = "st"
local DISC = node.id("disc")
local GLYPH = node.id("glyph")
@@ -982,7 +986,7 @@ local LPAR = node.id("local_par")
local MKERN = node.id("margin_kern")
local PENALTY = node.id("penalty")
% \end{macrocode}
-% GLUE subtypes:
+% Glue subtypes:
% \begin{macrocode}
local USRSKIP = 0
local PARSKIP = 3
@@ -991,7 +995,7 @@ local RGTSKIP = 9
local TOPSKIP = 10
local PARFILL = 15
% \end{macrocode}
-% HLIST subtypes:
+% Hlist subtypes:
% \begin{macrocode}
local LINE = 1
local BOX = 2
@@ -1000,6 +1004,10 @@ local BOX = 2
% \begin{macrocode}
local USER = 0
local HYPH = 0x2D
+% \end{macrocode}
+% Glyph subtypes:
+% \begin{macrocode}
+local LIGA = 0x102
local effective_glue = node.effective_glue
local set_attribute = node.set_attribute
@@ -1018,24 +1026,24 @@ local is_glyph = node.is_glyph
% \begin{macrocode}
local color_node = function (node, color)
local attr = oberdiek.luacolor.getattribute()
- if node.id == DISC then
+ if node and node.id == DISC then
local pre = node.pre
local post = node.post
- local replace = node.replace
+ local repl = node.replace
if pre then
set_attribute(pre,attr,color)
-%<dbg> texio.write_nl('PRE=' .. tostring(pre.char))
+%<dbg> texio.write_nl('PRE=' .. tostring(pre.char))
end
if post then
set_attribute(post,attr,color)
-%<dbg> texio.write_nl('POST=' .. tostring(post.char))
+%<dbg> texio.write_nl('POST=' .. tostring(post.char))
end
- if replace then
- set_attribute(replace,attr,color)
-%<dbg> texio.write_nl('REPL=' .. tostring(replace.char))
+ if repl then
+ set_attribute(repl,attr,color)
+%<dbg> texio.write_nl('REPL=' .. tostring(repl.char))
end
%<dbg> texio.write_nl(' ')
- else
+ elseif node then
set_attribute(node,attr,color)
end
end
@@ -1051,6 +1059,7 @@ local color_hbox = function (head, color)
color_node(n, color)
end
end
+% \end{macrocode}
%
% This auxillary function colours a whole line. It requires two
% arguments: a line’s node and a (named) colour.
@@ -1059,7 +1068,7 @@ end
local color_line = function (head, color)
local first = head.head
for n in traverse(first) do
- if n.id == HLIST and n.subtype == BOX then
+ if n and n.id == HLIST and n.subtype == BOX then
color_hbox(n, color)
else
color_node(n, color)
@@ -1084,14 +1093,14 @@ end
local signature = function (node, string, swap)
local n = node
local str = string
- if n.id == GLYPH then
+ if n and n.id == GLYPH then
local b, id = is_glyph(n)
if b and not char_to_discard[b] then
% \end{macrocode}
% Punctuation has to be discarded; the French apostrophe (right quote
% U+2019) has a char code ``out of range’’, we replace it with U+0027;
% Other glyphs should have char codes less than 0x100 (or 0x180?) or
-% be ligatures… standard ones (U+FB00 to U+FB04) are converted using
+% be ligatures… standard ones (U+FB00 to U+FB06) are converted using
% table |split_lig|.
% \begin{macrocode}
if b == 0x2019 then b = 0x27 end
@@ -1103,9 +1112,19 @@ local signature = function (node, string, swap)
c = string.reverse(c)
end
str = str .. c
+% \end{macrocode}
+% Experimental: store other ligatures as the last two digits of their
+% decimal code…
+% \begin{macrocode}
+ elseif n.subtype == LIGA and b > 0xE000 then
+ local c = string.sub(b,-2)
+ if swap then
+ c = string.reverse(c)
+ end
+ str = str .. c
end
end
- elseif n.id == DISC then
+ elseif n and n.id == DISC then
% \end{macrocode}
% Ligatures are split into |pre| and |post| and both parts are
% stored. In case of \emph{ffl, ffi}, the post part is also
@@ -1129,12 +1148,18 @@ local signature = function (node, string, swap)
end
end
if swap then
- str = str .. c2 .. c1
+ str = str .. c2 .. c1
else
str = str .. c1 .. c2
end
end
+% \end{macrocode}
+% The returned length is the number of \emph{letters}.
+% \begin{macrocode}
local len = string.len(str)
+ if string.find(str, "_") then
+ len = len - 1
+ end
return len, str
end
% \end{macrocode}
@@ -1150,32 +1175,30 @@ end
local check_last_word = function (old, node, color, flag)
local match = false
local new = ""
- local len = 0
- if flag then
+ local maxlen = 0
+ if flag and node then
+ local swap = true
% \end{macrocode}
-% Get the last glyph one the line, skipping discretionaries,
-% margin kerns, etc., unless |flag| cancels the whole process.
+% Step back to the last glyph or discretionary.
% \begin{macrocode}
- local swap = true
local lastn = node
- while lastn and lastn.id ~= GLYPH and lastn.prev do
+ while lastn and lastn.id ~= GLYPH and lastn.id ~= DISC do
lastn = lastn.prev
end
% \end{macrocode}
% A signature is built from the last two words on the current line.
% \begin{macrocode}
local n = lastn
- repeat
- len, new = signature (n, new, swap)
+ while n and n.id ~= GLUE do
+ maxlen, new = signature (n, new, swap)
n = n.prev
- until not n or n.id == GLUE
+ end
if n and n.id == GLUE then
new = new .. "_"
- len = len + 1
repeat
n = n.prev
- len, new = signature (n, new, swap)
- until n.id == GLUE or not n.prev
+ maxlen, new = signature (n, new, swap)
+ until not n or n.id == GLUE
end
new = string.reverse(new)
%<dbg> texio.write_nl('EOLsigold=' .. old)
@@ -1184,24 +1207,24 @@ local check_last_word = function (old, node, color, flag)
local MinPart = luatypo.MinPart
MinFull = math.min(MinPart,MinFull)
local k = MinPart
- local oldlast = string.gsub (old, '%w+_', '')
- local newlast = string.gsub (new, '%w+_', '')
- len = string.len(newlast)
- if len < MinPart then
+ local oldlast = string.gsub (old, '.*_', '')
+ local newlast = string.gsub (new, '.*_', '')
+ local i = string.find(new, "_")
+ if i and i > maxlen - MinPart + 1 then
k = MinPart + 1
end
local oldsub = string.sub(old,-k)
local newsub = string.sub(new,-k)
- local maxlen = string.len(new)
- if oldsub == newsub then
+ local l = string.len(new)
+ if oldsub == newsub and l >= k then
%<dbg> texio.write_nl('EOLnewsub=' .. newsub)
match = true
- elseif oldlast == newlast and len >= MinFull then
+ elseif oldlast == newlast and string.len(newlast) >= MinFull then
%<dbg> texio.write_nl('EOLnewlast=' .. newlast)
match = true
oldsub = oldlast
newsub = newlast
- k = len
+ k = string.len(newlast)
end
if match then
% \end{macrocode}
@@ -1209,7 +1232,7 @@ local check_last_word = function (old, node, color, flag)
% \begin{macrocode}
local osub = oldsub
local nsub = newsub
- while osub == nsub and k < maxlen do
+ while osub == nsub and k <= maxlen do
k = k +1
osub = string.sub(old,-k)
nsub = string.sub(new,-k)
@@ -1217,8 +1240,9 @@ local check_last_word = function (old, node, color, flag)
newsub = nsub
end
end
+ newsub = string.gsub(newsub, '^_', '')
%<dbg> texio.write_nl('EOLfullmatch=' .. newsub)
-%<msg> texio.write_nl('***MATCH=' .. newsub ..
+%<msg> texio.write_nl('***EOLMATCH=' .. newsub ..
%<msg> " on page " .. pageno)
%<msg> texio.write_nl(' ')
% \end{macrocode}
@@ -1226,18 +1250,16 @@ local check_last_word = function (old, node, color, flag)
% \begin{macrocode}
oldsub = string.reverse(newsub)
local newsub = ""
- local k = string.len(oldsub)
local n = lastn
repeat
if n and n.id ~= GLUE then
color_node(n, color)
- len, newsub = signature(n, newsub, swap)
+ l, newsub = signature(n, newsub, swap)
elseif n then
newsub = newsub .. "_"
- len = len + 1
end
n = n.prev
- until not n or newsub == oldsub or len >= k
+ until not n or newsub == oldsub or l >= k
end
end
return new, match
@@ -1252,19 +1274,23 @@ local check_first_word = function (old, node, color, flag)
local match = false
local swap = false
local new = ""
- local len = 0
+ local maxlen = 0
local start = node
local n = start
- while n and n.id ~= GLUE do
- len, new = signature (n, new, swap)
- n = n.next
+ while n and n.id ~= GLYPH and n.id ~= DISC do
+ n = n.next
end
- n = n.next
- new = new .. "_"
while n and n.id ~= GLUE do
- len, new = signature (n, new, swap)
+ maxlen, new = signature (n, new, swap)
n = n.next
end
+ if n and n.id == GLUE then
+ new = new .. "_"
+ repeat
+ n = n.next
+ maxlen, new = signature (n, new, swap)
+ until not n or n.id == GLUE
+ end
%<dbg> texio.write_nl('BOLsigold=' .. old)
%<dbg> texio.write(' BOLsig=' .. new)
% \end{macrocode}
@@ -1277,28 +1303,26 @@ local check_first_word = function (old, node, color, flag)
local MinPart = luatypo.MinPart
MinFull = math.min(MinPart,MinFull)
local k = MinPart
- local L = MinPart -1
local oldsub = ""
local newsub = ""
- local oldfirst = string.gsub (old, '_%w+', '')
- local newfirst = string.gsub (new, '_%w+', '')
- len = string.len(newfirst)
- if len < MinPart then
+ local oldfirst = string.gsub (old, '_.*', '')
+ local newfirst = string.gsub (new, '_.*', '')
+ local i = string.find(new, "_")
+ if i and i <= MinPart then
k = MinPart + 1
end
- local maxlen = string.len(new)
- local oldsub = string.sub(old,1,L)
- local newsub = string.sub(new,1,L)
- if oldsub == newsub then
+ local oldsub = string.sub(old,1,k)
+ local newsub = string.sub(new,1,k)
+ local l = string.len(newsub)
+ if oldsub == newsub and l >= k then
%<dbg> texio.write_nl('BOLnewsub=' .. newsub)
match = true
- k = L
- elseif oldfirst == newfirst and len >= MinFull then
+ elseif oldfirst == newfirst and string.len(newfirst) >= MinFull then
%<dbg> texio.write_nl('BOLnewfirst=' .. newfirst)
match = true
oldsub = oldfirst
newsub = newfirst
- k = len
+ k = string.len(newfirst)
end
if match then
% \end{macrocode}
@@ -1306,7 +1330,7 @@ local check_first_word = function (old, node, color, flag)
% \begin{macrocode}
local osub = oldsub
local nsub = newsub
- while osub == nsub and k < maxlen do
+ while osub == nsub and k <= maxlen do
k = k + 1
osub = string.sub(old,1,k)
nsub = string.sub(new,1,k)
@@ -1314,15 +1338,11 @@ local check_first_word = function (old, node, color, flag)
newsub = nsub
end
end
- if k < MinPart then
- match =false
- end
- end
- if match then
-%<dbg> texio.write_nl('BOLfullmatch=' .. newsub)
-%<msg> texio.write_nl('***MATCH=' .. newsub ..
-%<msg> " on page " .. pageno)
-%<msg> texio.write_nl(' ')
+ newsub = string.gsub(newsub, '_$', '') --$
+%<dbg> texio.write_nl('BOLfullmatch=' .. newsub)
+%<msg> texio.write_nl('***BOLMATCH=' .. newsub ..
+%<msg> " on page " .. pageno)
+%<msg> texio.write_nl(' ')
% \end{macrocode}
% Lest's colour the matching string.
% \begin{macrocode}
@@ -1333,13 +1353,12 @@ local check_first_word = function (old, node, color, flag)
repeat
if n and n.id ~= GLUE then
color_node(n, color)
- len, newsub = signature(n, newsub, swap)
+ l, newsub = signature(n, newsub, swap)
elseif n then
newsub = newsub .. "_"
- len = len + 1
end
n = n.next
- until not n or newsub == oldsub or len >= k
+ until not n or newsub == oldsub or l >= k
end
end
return new, match
@@ -1370,9 +1389,9 @@ local check_regexpr = function (glyph)
match = string.find(luatypo.single[lang], string.char(lchar))
if match then
color_node(glyph,COLOR)
-%<msg> texio.write_nl('***MATCH=' .. string.char(lchar) ..
-%<msg> " on page " .. pageno)
-%<msg> texio.write_nl(' ')
+%<msg> texio.write_nl('***RGXMATCH=' .. string.char(lchar) ..
+%<msg> " on page " .. pageno)
+%<msg> texio.write_nl(' ')
end
end
end
@@ -1392,7 +1411,7 @@ local check_regexpr = function (glyph)
if match then
color_node(previous,COLOR)
color_node(glyph,COLOR)
-%<msg> texio.write_nl('***MATCH=' .. pattern ..
+%<msg> texio.write_nl('***RGXMATCH=' .. pattern ..
%<msg> " on page " .. pageno)
%<msg> texio.write_nl(' ')
end
@@ -1411,7 +1430,7 @@ local check_regexpr = function (glyph)
if match then
color_node(pprev,COLOR)
color_node(glyph,COLOR)
-%<msg> texio.write_nl('***MATCH=' .. pattern ..
+%<msg> texio.write_nl('***RGXMATCH=' .. pattern ..
%<msg> " on page " .. pageno)
%<msg> texio.write_nl(' ')
end
@@ -1430,7 +1449,7 @@ end
% \begin{macrocode}
local show_pre_disc = function (disc, color)
local n = disc
- while n.id ~= GLUE do
+ while n and n.id ~= GLUE do
color_node(n, color)
n = n.prev
end
@@ -1485,13 +1504,16 @@ luatypo.check_page = function (head)
% |hyphcount| hold the number the consecutive hyphenated lines.
% \begin{macrocode}
if head.id == GLUE and head.subtype == TOPSKIP then
- pageflag = false
- match1 = false
pageno = tex.getcount("c@page")
hyphcount = 0
- pagelines = 0
- firstwd = ""
- lastwd = ""
+ if pageno > prevno then
+ pageflag = false
+ pagelines = 0
+ match1 = false
+ firstwd = ""
+ lastwd = ""
+ prevno = pageno
+ end
elseif head.id == HLIST and head.subtype == LINE then
% \end{macrocode}
% The current node is a line, |first| is the line’s first node.
@@ -1507,30 +1529,34 @@ luatypo.check_page = function (head)
% \end{macrocode}
% Is this line really a text line (one glyph at least)?
% \begin{macrocode}
- local textline = true
- local n = first
- while (n and n.id ~= GLYPH) and
- not (n.id == GLUE and n.subtype == RGTSKIP) do
- n = n.next
- end
- if n.id == GLUE then
- textline = false
+ local textline = false
+ if first.id == GLYPH then
+ textline = true
+ else
+ local n = first
+ repeat
+ n = n.next
+ if n and n.id == GLYPH then
+ textline = true
+ break
+ end
+ until not n or (n.id == GLUE and n.subtype == RGTSKIP)
end
% \end{macrocode}
% Is this line overfull or underfull?
% \begin{macrocode}
if head.glue_set == 1 and head.glue_sign == 2 and
head.glue_order == 0 and OverfullLines then
-%<msg> texio.write_nl('***OVERFULL line on page ' .. pageno)
-%<msg> texio.write_nl(' ')
+%<msg> texio.write_nl('***OVERFULL line on page ' .. pageno)
+%<msg> texio.write_nl(' ')
pageflag = true
local COLOR = luatypo.colortbl[7]
color_line (head, COLOR)
elseif head.glue_set >= Stretch and head.glue_sign == 1 and
head.glue_order == 0 and UnderfullLines then
-%<msg> texio.write_nl('***UNDERFULL line on page ' ..
-%<msg> tex.getcount("c@page"))
-%<msg> texio.write_nl(' ')
+%<msg> texio.write_nl('***UNDERFULL line on page ' ..
+%<msg> tex.getcount("c@page"))
+%<msg> texio.write_nl(' ')
local COLOR = luatypo.colortbl[8]
pageflag = true
color_line (head, COLOR)
@@ -1540,7 +1566,7 @@ luatypo.check_page = function (head)
% \begin{macrocode}
if first.id == LPAR then
% \end{macrocode}
-% It starts a paragraph,
+% It starts a paragraph…
% \begin{macrocode}
hyphcount = 0
parlines = 1
@@ -1586,7 +1612,7 @@ luatypo.check_page = function (head)
orphanflag = false
% \end{macrocode}
% but it is a widow if it is the page’s first line and it does’nt
-% start a new paragraph. Orphans and widows will be colored later.
+% start a new paragraph.\\ Orphans and widows will be colored later.
% \begin{macrocode}
if pagelines == 1 and parlines > 1 then
widowflag = true
@@ -1605,8 +1631,8 @@ luatypo.check_page = function (head)
% |llwd| is the line’s length. Is it too short?
% \begin{macrocode}
if llwd < LLminWD then
-%<msg> texio.write_nl('***Last line too short, page ' .. pageno)
-%<msg> texio.write_nl(' ')
+%<msg> texio.write_nl('***Last line too short, page ' .. pageno)
+%<msg> texio.write_nl(' ')
pageflag = true
local COLOR = luatypo.colortbl[6]
local attr = oberdiek.luacolor.getattribute()
@@ -1620,8 +1646,8 @@ luatypo.check_page = function (head)
% Is this line nearly full? (ending too close to the right margin)
% \begin{macrocode}
if BackParindent and PFskip < BackPI and PFskip > BackFuzz then
-%<msg> texio.write_nl('***Last line nearly full, page ' .. pageno)
-%<msg> texio.write_nl(' ')
+%<msg> texio.write_nl('***Last line nearly full, page ' .. pageno)
+%<msg> texio.write_nl(' ')
pageflag = true
local COLOR = luatypo.colortbl[12]
local attr = oberdiek.luacolor.getattribute()
@@ -1657,8 +1683,8 @@ luatypo.check_page = function (head)
local COLOR = luatypo.colortbl[2]
local pg = show_pre_disc (pn,COLOR)
pageflag = true
-%<msg> texio.write_nl('***HYPH issue page ' .. pageno)
-%<msg> texio.write_nl(' ')
+%<msg> texio.write_nl('***HYPH issue page ' .. pageno)
+%<msg> texio.write_nl(' ')
end
if not nextnode and EOPHyphens then
% \end{macrocode}
@@ -1758,9 +1784,9 @@ luatypo.check_page = function (head)
if lwhyphflag and EOPHyphens then
%<msg> texio.write_nl('***LAST WORD SPLIT page ' .. pageno)
%<msg> texio.write_nl(' ')
+ pageflag = true
local COLOR = luatypo.colortbl[1]
local pg = show_pre_disc (pn,COLOR)
- pageflag = true
end
% \end{macrocode}
% Track empty pages: check the number of lines at end of page.
@@ -1776,20 +1802,27 @@ luatypo.check_page = function (head)
%<msg> texio.write_nl('***Only ' .. pagelines ..
%<msg> ' lines on page ' .. pageno)
%<msg> texio.write_nl(' ')
- local node = head
- while node.id ~= HLIST or node.subtype ~= LINE do
- node = node.prev
+ local n = head
+ while n and (n.id ~= HLIST or n.subtype ~= LINE) do
+ n = n.prev
+ end
+ if n then
+ color_line(n, COLOR)
end
- color_line(node, COLOR)
end
end
head = nextnode
end
% \end{macrocode}
% Add this page number to the summary if any flaw has been found on it.
+% Skip duplicates.
% \begin{macrocode}
if pageflag then
- luatypo.pagelist = luatypo.pagelist .. tostring(pageno) .. ", "
+ local pl = luatypo.pagelist
+ local p = tonumber(string.match(pl, "%s(%d+),%s$"))
+ if not p or pageno > p then
+ luatypo.pagelist = luatypo.pagelist .. tostring(pageno) .. ", "
+ end
end
return true
end