summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/lualatex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-03-04 22:09:16 +0000
committerKarl Berry <karl@freefriends.org>2021-03-04 22:09:16 +0000
commit7df76069beaebbde72a91ad3fd9102eee6857877 (patch)
tree86d6965281030f20bbe7c22ae4967edb9a281d0a /Master/texmf-dist/tex/lualatex
parentb1279daa67e27985c60f1b13293e22c5c596386c (diff)
lua-typo (4mar21)
git-svn-id: svn://tug.org/texlive/trunk@58124 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/lualatex')
-rw-r--r--Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.cfg48
-rw-r--r--Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.sty853
2 files changed, 901 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.cfg b/Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.cfg
new file mode 100644
index 00000000000..a395e4fe2a5
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.cfg
@@ -0,0 +1,48 @@
+%%% Configuration file for lua-typo.sty
+%%% These settings can also be overruled in the preamble.
+
+%% Minimum gap between end of paragraphs’ last lines and the right margin
+\luatypoBackPI=1em\relax
+\luatypoBackFuzz=2pt\relax
+
+%% Minimum length of paragraphs’ last lines
+\luatypoLLminWD=2\parindent\relax
+
+%% Maximum number of consecutive hyphenated lines
+\luatypoHyphMax=2\relax
+
+%% Nearly empty pages: minimum number of lines
+\luatypoPageMin=5\relax
+
+%% Maximum acceptable stretch before a line is tagged as Underfull
+\luatypoStretchMax=200\relax
+
+%% Minimum number of matching characters for words at begin/end of line
+\luatypoMinFull=3\relax
+\luatypoMinPart=4\relax
+
+%% Default colours = red, cyan, mygrey
+\definecolor{mygrey}{gray}{0.6}
+\definecolor{myred}{rgb}{1,0.55,0}
+\luatypoSetColor0{red} % Paragraph last full line hyphenated
+\luatypoSetColor1{red} % Page last word hyphenated
+\luatypoSetColor2{red} % Hyphens ending two many consecutive lines
+\luatypoSetColor3{red} % Short word at end of line
+\luatypoSetColor4{cyan} % Widow
+\luatypoSetColor5{cyan} % Orphan
+\luatypoSetColor6{cyan} % Paragraph ending on a short line
+\luatypoSetColor7{blue} % Overfull lines
+\luatypoSetColor8{blue} % Underfull lines
+\luatypoSetColor9{red} % Nearly empty page (just a few lines)
+\luatypoSetColor{10}{myred} % First word matches
+\luatypoSetColor{11}{myred} % Last word matches
+\luatypoSetColor{12}{mygrey}% Paragraph ending on a nearly full line
+
+%% Language specific settings (example for French only currently):
+%% short words (two letters max) to be avoided at end of lines.
+%% French:
+%%\luatypoOneChar{french}{'À à Ô'}
+%%\luatypoTwoChars{french}{'Je Tu Il On'}
+%%
+%%
+%% End of file `lua-typo.cfg'.
diff --git a/Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.sty b/Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.sty
new file mode 100644
index 00000000000..0408dc24a18
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/lua-typo/lua-typo.sty
@@ -0,0 +1,853 @@
+%%
+%% This is file `lua-typo.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% lua-typo.dtx (with options: `sty')
+%%
+\NeedsTeXFormat{LaTeX2e}[2020/01/01]
+\ProvidesPackage{lua-typo}
+ [2021/03/03 v.0.30 Daniel Flipo]
+\ifdefined\directlua
+ \RequirePackage{luatexbase,luacode,luacolor}
+ \RequirePackage{kvoptions,atveryend}
+\else
+ \PackageError{This package is meant for LuaTeX only! Aborting}
+ {No more information available, sorry!}
+\fi
+\newdimen\luatypoLLminWD
+\newdimen\luatypoBackPI
+\newdimen\luatypoBackFuzz
+\newcount\luatypoStretchMax
+\newcount\luatypoHyphMax
+\newcount\luatypoPageMin
+\newcount\luatypoMinFull
+\newcount\luatypoMinPart
+\newcount\luatypo@LANGno
+\newcount\luatypo@options
+\newtoks\luatypo@single
+\newtoks\luatypo@double
+\begin{luacode}
+luatypo = { }
+\end{luacode}
+\SetupKeyvalOptions{
+ family=luatypo,
+ prefix=LT@,
+}
+\DeclareBoolOption[false]{ShowOptions}
+\DeclareBoolOption[false]{None}
+\DeclareBoolOption[false]{All}
+\DeclareBoolOption[false]{BackParindent}
+\DeclareBoolOption[false]{ShortLines}
+\DeclareBoolOption[false]{ShortPages}
+\DeclareBoolOption[false]{OverfullLines}
+\DeclareBoolOption[false]{UnderfullLines}
+\DeclareBoolOption[false]{Widows}
+\DeclareBoolOption[false]{Orphans}
+\DeclareBoolOption[false]{EOPHyphens}
+\DeclareBoolOption[false]{RepeatedHyphens}
+\DeclareBoolOption[false]{ParLastHyphen}
+\DeclareBoolOption[false]{EOLShortWords}
+\DeclareBoolOption[false]{FirstWordMatch}
+\DeclareBoolOption[false]{LastWordMatch}
+\AddToKeyvalOption{luatypo}{All}{%
+ \LT@ShortLinestrue \LT@ShortPagestrue
+ \LT@OverfullLinestrue \LT@UnderfullLinestrue
+ \LT@Widowstrue \LT@Orphanstrue
+ \LT@EOPHyphenstrue \LT@RepeatedHyphenstrue
+ \LT@ParLastHyphentrue \LT@EOLShortWordstrue
+ \LT@FirstWordMatchtrue \LT@LastWordMatchtrue
+ \LT@BackParindenttrue
+}
+\ProcessKeyvalOptions{luatypo}
+\AtEndOfPackage{%
+ \ifLT@None
+ \directlua{ luatypo.None = true }%
+ \else
+ \directlua{ luatypo.None = false }%
+ \fi
+ \ifLT@BackParindent
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.BackParindent = true }%
+ \else
+ \directlua{ luatypo.BackParindent = false }%
+ \fi
+ \ifLT@ShortLines
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.ShortLines = true }%
+ \else
+ \directlua{ luatypo.ShortLines = false }%
+ \fi
+ \ifLT@ShortPages
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.ShortPages = true }%
+ \else
+ \directlua{ luatypo.ShortPages = false }%
+ \fi
+ \ifLT@OverfullLines
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.OverfullLines = true }%
+ \else
+ \directlua{ luatypo.OverfullLines = false }%
+ \fi
+ \ifLT@UnderfullLines
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.UnderfullLines = true }%
+ \else
+ \directlua{ luatypo.UnderfullLines = false }%
+ \fi
+ \ifLT@Widows
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.Widows = true }%
+ \else
+ \directlua{ luatypo.Widows = false }%
+ \fi
+ \ifLT@Orphans
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.Orphans = true }%
+ \else
+ \directlua{ luatypo.Orphans = false }%
+ \fi
+ \ifLT@EOPHyphens
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.EOPHyphens = true }%
+ \else
+ \directlua{ luatypo.EOPHyphens = false }%
+ \fi
+ \ifLT@RepeatedHyphens
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.RepeatedHyphens = true }%
+ \else
+ \directlua{ luatypo.RepeatedHyphens = false }%
+ \fi
+ \ifLT@ParLastHyphen
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.ParLastHyphen = true }%
+ \else
+ \directlua{ luatypo.ParLastHyphen = false }%
+ \fi
+ \ifLT@EOLShortWords
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.EOLShortWords = true }%
+ \else
+ \directlua{ luatypo.EOLShortWords = false }%
+ \fi
+ \ifLT@FirstWordMatch
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.FirstWordMatch = true }%
+ \else
+ \directlua{ luatypo.FirstWordMatch = false }%
+ \fi
+ \ifLT@LastWordMatch
+ \advance\luatypo@options by 1
+ \directlua{ luatypo.LastWordMatch = true }%
+ \else
+ \directlua{ luatypo.LastWordMatch = false }%
+ \fi
+}
+\ifLT@ShowOptions
+ \GenericWarning{* }{%
+ *** List of possible options for lua-typo ***\MessageBreak
+ [Default values between brackets]%
+ \MessageBreak
+ ShowOptions [false]\MessageBreak
+ None [false]\MessageBreak
+ BackParindent [false]\MessageBreak
+ ShortLines [false]\MessageBreak
+ ShortPages [false]\MessageBreak
+ OverfullLines [false]\MessageBreak
+ UnderfullLines [false]\MessageBreak
+ Widows [false]\MessageBreak
+ Orphans [false]\MessageBreak
+ EOPHyphens [false]\MessageBreak
+ RepeatedHyphens [false]\MessageBreak
+ ParLastHyphen [false]\MessageBreak
+ EOLShortWords [false]\MessageBreak
+ FirstWordMatch [false]\MessageBreak
+ LastWordMatch [false]\MessageBreak
+ \MessageBreak
+ *********************************************%
+ \MessageBreak Lua-typo [ShowOptions]
+ }%
+\fi
+\AtBeginDocument{%
+ \directlua{
+ luatypo.HYPHmax = tex.count.luatypoHyphMax
+ luatypo.PAGEmin = tex.count.luatypoPageMin
+ luatypo.Stretch = tex.count.luatypoStretchMax
+ luatypo.MinFull = tex.count.luatypoMinFull
+ luatypo.MinPart = tex.count.luatypoMinPart
+ luatypo.LLminWD = tex.dimen.luatypoLLminWD
+ luatypo.BackPI = tex.dimen.luatypoBackPI
+ luatypo.BackFuzz = tex.dimen.luatypoBackFuzz
+ }%
+}
+\AtVeryEndDocument{%
+\ifnum\luatypo@options = 0 \LT@Nonetrue \fi
+\ifLT@None
+ \directlua{
+ texio.write_nl(' ')
+ texio.write_nl('***********************************')
+ texio.write_nl('*** lua-typo loaded with NO option:')
+ texio.write_nl('*** NO CHECK PERFORMED! ***')
+ texio.write_nl('***********************************')
+ texio.write_nl(' ')
+ }%
+\else
+ \directlua{
+ texio.write_nl(' ')
+ texio.write_nl('*************************************')
+ if luatypo.pagelist == "" then
+ 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)
+ end
+ texio.write_nl('***********************************')
+ texio.write_nl(' ')
+ }%
+\fi}
+\newcommand*{\luatypoOneChar}[2]{%
+ \def\luatypo@LANG{#1}\luatypo@single={#2}%
+ \ifcsname l@\luatypo@LANG\endcsname
+ \luatypo@LANGno=\the\csname l@\luatypo@LANG\endcsname \relax
+ \directlua{
+ local langno = \the\luatypo@LANGno
+ local string = \the\luatypo@single
+ luatypo.single[langno] = " "
+ for p, c in utf8.codes(string) do
+ local s = string.char(c)
+ luatypo.single[langno] = luatypo.single[langno] .. s
+ end
+ }%
+ \else
+ \PackageWarning{luatypo}{Unknown language "\luatypo@LANG",
+ \MessageBreak \protect\luatypoOneChar\space command ignored}%
+ \fi}
+\newcommand*{\luatypoTwoChars}[2]{%
+ \def\luatypo@LANG{#1}\luatypo@double={#2}%
+ \ifcsname l@\luatypo@LANG\endcsname
+ \luatypo@LANGno=\the\csname l@\luatypo@LANG\endcsname \relax
+ \directlua{
+ local langno = \the\luatypo@LANGno
+ local string = \the\luatypo@double
+ luatypo.double[langno] = " "
+ for p, c in utf8.codes(string) do
+ local s = string.char(c)
+ luatypo.double[langno] = luatypo.double[langno] .. s
+ end
+ }%
+ \else
+ \PackageWarning{luatypo}{Unknown language "\luatypo@LANG",
+ \MessageBreak \protect\luatypoTwoChars\space command ignored}%
+ \fi}
+\newcommand*{\luatypoSetColor}[2]{%
+ \begingroup
+ \color{#2}%
+ \directlua{luatypo.colortbl[#1]=\the\LuaCol@Attribute}%
+ \endgroup
+}
+\begin{luacode}
+luatypo.single = { }
+luatypo.double = { }
+luatypo.colortbl = { }
+luatypo.pagelist = ""
+
+local hyphcount = 0
+local parlines = 0
+local pagelines = 0
+local pageno = 0
+local pageflag = false
+
+local char_to_discard = { }
+char_to_discard[string.byte(",")] = true
+char_to_discard[string.byte(".")] = true
+char_to_discard[string.byte("!")] = true
+char_to_discard[string.byte("?")] = true
+char_to_discard[string.byte(":")] = true
+char_to_discard[string.byte(";")] = true
+char_to_discard[string.byte("-")] = true
+
+local split_lig = { }
+split_lig[0xFB00] = "ff"
+split_lig[0xFB01] = "fi"
+split_lig[0xFB02] = "fl"
+split_lig[0xFB03] = "ffi"
+split_lig[0xFB04] = "ffl"
+
+local DISC = node.id("disc")
+local GLYPH = node.id("glyph")
+local GLUE = node.id("glue")
+local KERN = node.id("kern")
+local HLIST = node.id("hlist")
+local LPAR = node.id("local_par")
+local MKERN = node.id("margin_kern")
+local PENALTY = node.id("penalty")
+local USRSKIP = 0
+local PARSKIP = 3
+local LFTSKIP = 8
+local RGTSKIP = 9
+local TOPSKIP = 10
+local PARFILL = 15
+local LINE = 1
+local BOX = 2
+local USER = 0
+local HYPH = 0x2D
+
+local effective_glue = node.effective_glue
+local set_attribute = node.set_attribute
+local slide = node.slide
+local traverse = node.traverse
+local traverse_id = node.traverse_id
+local has_field = node.has_field
+local uses_font = node.uses_font
+local is_glyph = node.is_glyph
+
+local color_node = function (node, color)
+ local attr = oberdiek.luacolor.getattribute()
+ if node.id == DISC then
+ local pre = node.pre
+ local post = node.post
+ local replace = node.replace
+ if pre then
+ set_attribute(pre,attr,color)
+ end
+ if post then
+ set_attribute(post,attr,color)
+ end
+ if replace then
+ set_attribute(replace,attr,color)
+ end
+ else
+ set_attribute(node,attr,color)
+ end
+end
+local color_hbox = function (head, color)
+ local first = head.head
+ for n in traverse(first) do
+ color_node(n, color)
+ end
+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
+ color_hbox(n, color)
+ else
+ color_node(n, color)
+ end
+ end
+end
+local signature = function (node, string, swap)
+ local n = node
+ local str = string
+ if n.id == GLYPH then
+ local b, id = is_glyph(n)
+ if b and not char_to_discard[b] then
+ if b == 0x2019 then b = 0x27 end
+ if b < 0x100 then
+ str = str .. string.char(b)
+ elseif split_lig[b] then
+ local c = split_lig[b]
+ if swap then
+ c = string.reverse(c)
+ end
+ str = str .. c
+ end
+ end
+ elseif n.id == DISC then
+ local pre = n.pre
+ local post = n.post
+ local c1 = ""
+ local c2 = ""
+ if pre and pre.char and pre.char ~= HYPH and pre.char < 0x100 then
+ c1 = string.char(pre.char)
+ end
+ if post and post.char then
+ if post.char < 0x100 then
+ c2 = string.char(post.char)
+ elseif split_lig[post.char] then
+ c2 = split_lig[post.char]
+ if swap then
+ c2 = string.reverse(c2)
+ end
+ end
+ end
+ if swap then
+ str = str .. c2 .. c1
+ else
+ str = str .. c1 .. c2
+ end
+ end
+ local len = string.len(str)
+ return len, str
+end
+local check_last_word = function (old, node, color, flag)
+ local match = false
+ local new = ""
+ local len = 0
+ if flag then
+ local swap = true
+ local lastn = node
+ while lastn and lastn.id ~= GLYPH and lastn.prev do
+ lastn = lastn.prev
+ end
+ local n = lastn
+ repeat
+ len, new = signature (n, new, swap)
+ n = n.prev
+ until not n or n.id == GLUE
+ 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
+ end
+ new = string.reverse(new)
+ local MinFull = luatypo.MinFull
+ 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
+ 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
+ match = true
+ elseif oldlast == newlast and len >= MinFull then
+ match = true
+ oldsub = oldlast
+ newsub = newlast
+ k = len
+ end
+ if match then
+ local osub = oldsub
+ local nsub = newsub
+ while osub == nsub and k < maxlen do
+ k = k +1
+ osub = string.sub(old,-k)
+ nsub = string.sub(new,-k)
+ if osub == nsub then
+ newsub = nsub
+ end
+ end
+ 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)
+ elseif n then
+ newsub = newsub .. "_"
+ len = len + 1
+ end
+ n = n.prev
+ until not n or newsub == oldsub or len >= k
+ end
+ end
+ return new, match
+end
+local check_first_word = function (old, node, color, flag)
+ local match = false
+ local swap = false
+ local new = ""
+ local len = 0
+ local start = node
+ local n = start
+ while n and n.id ~= GLUE do
+ len, new = signature (n, new, swap)
+ n = n.next
+ end
+ n = n.next
+ new = new .. "_"
+ while n and n.id ~= GLUE do
+ len, new = signature (n, new, swap)
+ n = n.next
+ end
+ if flag then
+ local MinFull = luatypo.MinFull
+ 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
+ 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
+ match = true
+ k = L
+ elseif oldfirst == newfirst and len >= MinFull then
+ match = true
+ oldsub = oldfirst
+ newsub = newfirst
+ k = len
+ end
+ if match then
+ local osub = oldsub
+ local nsub = newsub
+ while osub == nsub and k < maxlen do
+ k = k + 1
+ osub = string.sub(old,1,k)
+ nsub = string.sub(new,1,k)
+ if osub == nsub then
+ newsub = nsub
+ end
+ end
+ if k < MinPart then
+ match =false
+ end
+ end
+ if match then
+ oldsub = newsub
+ local newsub = ""
+ local k = string.len(oldsub)
+ local n = start
+ repeat
+ if n and n.id ~= GLUE then
+ color_node(n, color)
+ len, 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
+ end
+ end
+ return new, match
+end
+local check_regexpr = function (glyph)
+ local COLOR = luatypo.colortbl[3]
+ local lang = glyph.lang
+ local match = false
+ local lchar, id = is_glyph(glyph)
+ local previous = glyph.prev
+ if lang and luatypo.single[lang] then
+ if lchar and lchar < 0x100 and previous and previous.id == GLUE then
+ match = string.find(luatypo.single[lang], string.char(lchar))
+ if match then
+ color_node(glyph,COLOR)
+ end
+ end
+ end
+ if lang and luatypo.double[lang] then
+ if lchar and previous and previous.id == GLYPH then
+ local pchar, id = is_glyph(previous)
+ local pprev = previous.prev
+ if pchar and pchar < 0x100 and pprev and pprev.id == GLUE then
+ local pattern = string.char(pchar) .. string.char(lchar)
+ match = string.find(luatypo.double[lang], pattern)
+ if match then
+ color_node(previous,COLOR)
+ color_node(glyph,COLOR)
+ end
+ end
+ elseif lchar and previous and previous.id == KERN then
+ local pprev = previous.prev
+ if pprev and pprev.id == GLYPH then
+ local pchar, id = is_glyph(pprev)
+ local ppprev = pprev.prev
+ if pchar and pchar < 0x100 and ppprev and ppprev.id == GLUE then
+ local pattern = string.char(pchar) .. string.char(lchar)
+ match = string.find(luatypo.double[lang], pattern)
+ if match then
+ color_node(pprev,COLOR)
+ color_node(glyph,COLOR)
+ end
+ end
+ end
+ end
+ end
+ return match
+end
+local show_pre_disc = function (disc, color)
+ local n = disc
+ while n.id ~= GLUE do
+ color_node(n, color)
+ n = n.prev
+ end
+ return n
+end
+luatypo.check_page = function (head)
+ local PAGEmin = luatypo.PAGEmin
+ local HYPHmax = luatypo.HYPHmax
+ local LLminWD = luatypo.LLminWD
+ local BackPI = luatypo.BackPI
+ local BackFuzz = luatypo.BackFuzz
+ local BackParindent = luatypo.BackParindent
+ local ShortLines = luatypo.ShortLines
+ local ShortPages = luatypo.ShortPages
+ local OverfullLines = luatypo.OverfullLines
+ local UnderfullLines = luatypo.UnderfullLines
+ local Widows = luatypo.Widows
+ local Orphans = luatypo.Orphans
+ local EOPHyphens = luatypo.EOPHyphens
+ local RepeatedHyphens = luatypo.RepeatedHyphens
+ local FirstWordMatch = luatypo.FirstWordMatch
+ local ParLastHyphen = luatypo.ParLastHyphen
+ local EOLShortWords = luatypo.EOLShortWords
+ local LastWordMatch = luatypo.LastWordMatch
+ local Stretch = math.max(luatypo.Stretch/100,1)
+
+ local orphanflag = false
+ local widowflag = false
+ local lwhyphflag = false
+ local match1 = false
+ local match2 = false
+ local firstwd = ""
+ local lastwd = ""
+ while head do
+ local nextnode = head.next
+ local prevnode = head.prev
+ local pprevnode = nil
+ if prevnode then
+ pprevnode = prevnode.prev
+ end
+ if head.id == GLUE and head.subtype == TOPSKIP then
+ pageflag = false
+ match1 = false
+ pageno = tex.getcount("c@page")
+ hyphcount = 0
+ pagelines = 0
+ firstwd = ""
+ lastwd = ""
+ elseif head.id == HLIST and head.subtype == LINE then
+ local first = head.head
+ if first.id == MKERN or
+ (first.id == GLUE and first.subtype == LFTSKIP) then
+ first = first.next
+ end
+ pagelines = pagelines + 1
+ local ListItem = false
+ 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
+ end
+ if head.glue_set == 1 and head.glue_sign == 2 and
+ head.glue_order == 0 and OverfullLines then
+ 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
+ local COLOR = luatypo.colortbl[8]
+ pageflag = true
+ color_line (head, COLOR)
+ end
+ if first.id == LPAR then
+ hyphcount = 0
+ parlines = 1
+ if not nextnode then
+ orphanflag = true
+ end
+ local nn = first.next
+ if nn and nn.id == HLIST and nn.subtype == BOX then
+ ListItem = true
+ end
+ else
+ parlines = parlines + 1
+ end
+ if FirstWordMatch then
+ local flag = not ListItem
+ local COLOR = luatypo.colortbl[10]
+ firstwd, match1 = check_first_word(firstwd, first, COLOR, flag)
+ if match1 then
+ pageflag = true
+ end
+ end
+ local ln = slide(first)
+ local pn = ln.prev
+ if pn and pn.id == GLUE and pn.subtype == PARFILL then
+ hyphcount = 0
+ orphanflag = false
+ if pagelines == 1 and parlines > 1 then
+ widowflag = true
+ end
+ local PFskip = effective_glue(pn,head)
+ if ShortLines then
+ local llwd = tex.hsize - PFskip
+ if llwd < LLminWD then
+ pageflag = true
+ local COLOR = luatypo.colortbl[6]
+ local attr = oberdiek.luacolor.getattribute()
+ color_line (head, COLOR)
+ end
+ end
+ if BackParindent and PFskip < BackPI and PFskip > BackFuzz then
+ pageflag = true
+ local COLOR = luatypo.colortbl[12]
+ local attr = oberdiek.luacolor.getattribute()
+ color_line (head, COLOR)
+ end
+ if LastWordMatch then
+ local COLOR = luatypo.colortbl[11]
+ local flag = textline
+ if PFskip > BackPI then
+ flag = false
+ end
+ lastwd, match1 = check_last_word(lastwd, pn, COLOR, flag)
+ if match1 then
+ pageflag = true
+ end
+ end
+ elseif pn and pn.id == DISC then
+ hyphcount = hyphcount + 1
+ if LastWordMatch then
+ local COLOR = luatypo.colortbl[11]
+ lastwd, match1 = check_last_word(lastwd, ln, COLOR, true)
+ if match1 then
+ pageflag = true
+ end
+ end
+ if hyphcount > HYPHmax and RepeatedHyphens then
+ local COLOR = luatypo.colortbl[2]
+ local pg = show_pre_disc (pn,COLOR)
+ pageflag = true
+ end
+ if not nextnode and EOPHyphens then
+ lwhyphflag = true
+ end
+ if nextnode and ParLastHyphen then
+ local nnnode = nextnode.next
+ local nnnnode = nil
+ if nnnode and nnnode.next then
+ nnnnode = nnnode.next
+ if nnnnode and nnnnode.id == HLIST and
+ nnnnode.subtype == 1 and nnnnode.glue_order == 2 then
+ local COLOR = luatypo.colortbl[0]
+ local pg = show_pre_disc (pn,COLOR)
+ pageflag = true
+ end
+ end
+ end
+ elseif pn and pn.id == GLYPH then
+ hyphcount = 0
+ if LastWordMatch then
+ local COLOR = luatypo.colortbl[11]
+ lastwd, match1 = check_last_word(lastwd, pn, COLOR, true)
+ end
+ if EOLShortWords then
+ match2 = check_regexpr(pn)
+ end
+ if match1 or match2 then
+ pageflag = true
+ end
+ elseif pn and pn.id == MKERN then
+ hyphcount = 0
+ local ppn = pn.prev
+ if ppn and ppn.id == GLYPH then
+ if LastWordMatch then
+ local COLOR = luatypo.colortbl[11]
+ lastwd, match1 = check_last_word(lastwd, pn, COLOR, true)
+ end
+ if EOLShortWords then
+ match2 = check_regexpr(ppn)
+ end
+ if match1 or match2 then
+ pageflag = true
+ end
+ end
+ else
+ hyphcount = 0
+ end
+ if widowflag and Widows then
+ pageflag = true
+ widowflag = false
+ local COLOR = luatypo.colortbl[4]
+ color_line (head, COLOR)
+ end
+ if orphanflag and Orphans then
+ pageflag = true
+ local COLOR = luatypo.colortbl[5]
+ color_line (head, COLOR)
+ end
+ if lwhyphflag and EOPHyphens then
+ local COLOR = luatypo.colortbl[1]
+ local pg = show_pre_disc (pn,COLOR)
+ pageflag = true
+ end
+ elseif not nextnode and head.id == GLUE and
+ head.subtype == USRSKIP then
+ if pagelines > 1 and pagelines < PAGEmin and ShortPages then
+ pageflag = true
+ local COLOR = luatypo.colortbl[9]
+ local node = head
+ while node.id ~= HLIST or node.subtype ~= LINE do
+ node = node.prev
+ end
+ color_line(node, COLOR)
+ end
+ end
+ head = nextnode
+ end
+ if pageflag then
+ luatypo.pagelist = luatypo.pagelist .. tostring(pageno) .. ", "
+ end
+ return true
+end
+return luatypo.check_page
+\end{luacode}
+\AtEndOfPackage{%
+ \directlua{
+ if not luatypo.None then
+ luatexbase.add_to_callback
+ ("pre_output_filter",luatypo.check_page,"check_page")
+ end
+ }
+}
+
+\InputIfFileExists{lua-typo.cfg}%
+ {\PackageInfo{lua-typo.sty}{'lua-typo.cfg' file loaded}}%
+ {\PackageInfo{lua-typo.sty}{'lua-typo.cfg' file not found.
+ \MessageBreak Providing default values.}%
+ \definecolor{mygrey}{gray}{0.6}%
+ \definecolor{myred}{rgb}{1,0.55,0}
+ \luatypoSetColor0{red}% Paragraph last full line hyphenated
+ \luatypoSetColor1{red}% Page last word hyphenated
+ \luatypoSetColor2{red}% Hyphens ending two many consecutive lines
+ \luatypoSetColor3{red}% Short word at end of line
+ \luatypoSetColor4{cyan}% Widow
+ \luatypoSetColor5{cyan}% Orphan
+ \luatypoSetColor6{cyan}% Paragraph ending on a short line
+ \luatypoSetColor7{blue}% Overfull lines
+ \luatypoSetColor8{blue}% Underfull lines
+ \luatypoSetColor9{red}% Nearly empty page
+ \luatypoSetColor{10}{myred}% First word matches
+ \luatypoSetColor{11}{myred}% Last word matches
+ \luatypoSetColor{12}{mygrey}% Paragraph ending on a nearly full line
+ \luatypoBackPI=1em\relax
+ \luatypoBackFuzz=2pt\relax
+ \luatypoLLminWD=2\parindent\relax
+ \luatypoStretchMax=200\relax
+ \luatypoHyphMax=2\relax
+ \luatypoPageMin=5\relax
+ \luatypoMinFull=4\relax
+ \luatypoMinPART=4\relax
+ }%
+%%
+%%
+%% End of file `lua-typo.sty'.