From 9f7bd12ed4560e888d9eaa5398c5a0bdc5779759 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 16 Mar 2021 22:11:47 +0000 Subject: lua-typo (16mar21) git-svn-id: svn://tug.org/texlive/trunk@58441 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/lualatex/lua-typo/lua-typo.dtx | 265 ++++++++++++--------- 1 file changed, 149 insertions(+), 116 deletions(-) (limited to 'Master/texmf-dist/source/lualatex/lua-typo/lua-typo.dtx') 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|sty> - [2021/03/03 v.0.30 Daniel Flipo] + [2021/03/14 v.0.32 Daniel Flipo] % %<*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) -% texio.write_nl('PRE=' .. tostring(pre.char)) +% texio.write_nl('PRE=' .. tostring(pre.char)) end if post then set_attribute(post,attr,color) -% texio.write_nl('POST=' .. tostring(post.char)) +% texio.write_nl('POST=' .. tostring(post.char)) end - if replace then - set_attribute(replace,attr,color) -% texio.write_nl('REPL=' .. tostring(replace.char)) + if repl then + set_attribute(repl,attr,color) +% texio.write_nl('REPL=' .. tostring(repl.char)) end % 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) % 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 % texio.write_nl('EOLnewsub=' .. newsub) match = true - elseif oldlast == newlast and len >= MinFull then + elseif oldlast == newlast and string.len(newlast) >= MinFull then % 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, '^_', '') % texio.write_nl('EOLfullmatch=' .. newsub) -% texio.write_nl('***MATCH=' .. newsub .. +% texio.write_nl('***EOLMATCH=' .. newsub .. % " on page " .. pageno) % 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 % texio.write_nl('BOLsigold=' .. old) % 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 % 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 % 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 -% texio.write_nl('BOLfullmatch=' .. newsub) -% texio.write_nl('***MATCH=' .. newsub .. -% " on page " .. pageno) -% texio.write_nl(' ') + newsub = string.gsub(newsub, '_$', '') --$ +% texio.write_nl('BOLfullmatch=' .. newsub) +% texio.write_nl('***BOLMATCH=' .. newsub .. +% " on page " .. pageno) +% 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) -% texio.write_nl('***MATCH=' .. string.char(lchar) .. -% " on page " .. pageno) -% texio.write_nl(' ') +% texio.write_nl('***RGXMATCH=' .. string.char(lchar) .. +% " on page " .. pageno) +% 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) -% texio.write_nl('***MATCH=' .. pattern .. +% texio.write_nl('***RGXMATCH=' .. pattern .. % " on page " .. pageno) % texio.write_nl(' ') end @@ -1411,7 +1430,7 @@ local check_regexpr = function (glyph) if match then color_node(pprev,COLOR) color_node(glyph,COLOR) -% texio.write_nl('***MATCH=' .. pattern .. +% texio.write_nl('***RGXMATCH=' .. pattern .. % " on page " .. pageno) % 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 -% texio.write_nl('***OVERFULL line on page ' .. pageno) -% texio.write_nl(' ') +% texio.write_nl('***OVERFULL line on page ' .. pageno) +% 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 -% texio.write_nl('***UNDERFULL line on page ' .. -% tex.getcount("c@page")) -% texio.write_nl(' ') +% texio.write_nl('***UNDERFULL line on page ' .. +% tex.getcount("c@page")) +% 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 -% texio.write_nl('***Last line too short, page ' .. pageno) -% texio.write_nl(' ') +% texio.write_nl('***Last line too short, page ' .. pageno) +% 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 -% texio.write_nl('***Last line nearly full, page ' .. pageno) -% texio.write_nl(' ') +% texio.write_nl('***Last line nearly full, page ' .. pageno) +% 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 -% texio.write_nl('***HYPH issue page ' .. pageno) -% texio.write_nl(' ') +% texio.write_nl('***HYPH issue page ' .. pageno) +% 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 % texio.write_nl('***LAST WORD SPLIT page ' .. pageno) % 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) % texio.write_nl('***Only ' .. pagelines .. % ' lines on page ' .. pageno) % 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 -- cgit v1.2.3