texlive[64060] trunk: texlogsieve (5aug22)

commits+karl at tug.org commits+karl at tug.org
Fri Aug 5 23:34:17 CEST 2022


Revision: 64060
          http://tug.org/svn/texlive?view=revision&revision=64060
Author:   karl
Date:     2022-08-05 23:34:16 +0200 (Fri, 05 Aug 2022)
Log Message:
-----------
texlogsieve (5aug22)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve
    trunk/Master/texmf-dist/doc/man/man1/texlogsieve.1
    trunk/Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdf
    trunk/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdf
    trunk/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex
    trunk/Master/texmf-dist/scripts/texlogsieve/texlogsieve

Modified: trunk/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve	2022-08-05 21:33:57 UTC (rev 64059)
+++ trunk/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve	2022-08-05 21:34:16 UTC (rev 64060)
@@ -176,8 +176,14 @@
    is indented to start after the end of the first, as in the example
    above. If the content of a line does not fit, a part of it (the
    beginning for the first line and the end for the second line) may
-   be replaced by "...".
+   be replaced by "...". error_line must be < 255 and half_error_line
+   must be < error_line -15. If error_line >= max_print_line or
+   half_error_line >= max_print_line, TeX does line wrapping as usual
+   (see below). If either is exactly max_print_line (which is true
+   for the default values), things get confusing, so TeX may add a
+   blank line when wrapping.
 
+
    LaTeX errors usually follow the format
 
        ! LaTeX/Package/Class BLAH Error: some description
@@ -620,10 +626,8 @@
   while Lines:numLines() < 15 do
       tmp = logfile:read("*line")
       if tmp == nil then break end
-      -- We *need* to remove blank lines here because
-      -- sometimes a wrapped line is followed by a blank
-      -- line, which messes our detection of wrapped lines.
-      if tmp ~= "" then Lines:append(tmp) end
+      -- Do not skip blank lines here, we need to do it in Lines:append()
+      Lines:append(tmp)
   end
 
   -- proceed to the next line
@@ -744,6 +748,9 @@
   -- messages, this is set to true (used in showSummary)
   SHOULD_RERUN_LATEX = false
 
+  -- If there were parse errors, we should say so in showSummary
+  PARSE_ERROR = false
+
   -- Did we detect any error messages?
   ERRORS_DETECTED = false
 
@@ -898,42 +905,7 @@
   Lines:append(line)
 end
 
-function processCommandLine(args)
-  HEARTBEAT = true
-  PAGE_DELAY = true
-  ONLY_SUMMARY = false
-  SHOW_SUMMARY = true
-  SHOW_SHIPOUTS = false
-  RAW = false
-  SILENCE_REPETITIONS = true
-  MINLEVEL = WARNING
-  BE_REDUNDANT = false
-  FILE_BANNER = true
-  DETAILED_UNDEROVER_SUMMARY = true
-  DETAILED_REFERENCE_SUMMARY = true
-  DETAILED_CITATION_SUMMARY = true
-
-  COLOR = false
-
-  SILENCE_STRINGS = {}
-  SILENCE_PKGS = {} -- just the package names
-  SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
-  SILENCE_FILES_RECURSIVE = {} -- same
-
-  -- The user may redefine the severity level of some messages.
-  FORCED_DEBUG = {}
-  FORCED_INFO = {}
-  FORCED_WARNING = {}
-  FORCED_CRITICAL = {}
-
-  -- "-l level -c configFile"
-  local optionsWithArgs = "lc"
-  local vars = simpleGetopt(args, optionsWithArgs)
-
-  --help
-  -- "-h"
-  if vars.help or vars.h then
-      local msg = [[
+helpmsg = [[
 Usage: texlogsieve [OPTION]... [INPUT FILE]
 texlogsieve reads a LaTeX log file (or the standard input), filters
 out less relevant messages, and displays a summary report.
@@ -994,23 +966,60 @@
                                          text EXCERPT to CRITICAL; can be used
                                          multiple times
   -c cfgfile, --config-file=cfgfile      read options from given config file
-                                         in addition to texlogsieverc
+                                         in addition to default config files
+  -v, --verbose                          Display info on texlogsieve config
   -h, --help                             give this help list
   --version                              print program version]]
 
-      for _, line in ipairs(linesToTable(msg)) do print(line) end
+versionmsg = [[
+texlogsieve 1.3.0
+Copyright (C) 2021, 2022 Nelson Lago <lago at ime.usp.br>
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.]]
+
+function processCommandLine(args)
+  HEARTBEAT = true
+  PAGE_DELAY = true
+  ONLY_SUMMARY = false
+  SHOW_SUMMARY = true
+  SHOW_SHIPOUTS = false
+  RAW = false
+  SILENCE_REPETITIONS = true
+  MINLEVEL = WARNING
+  BE_REDUNDANT = false
+  FILE_BANNER = true
+  DETAILED_UNDEROVER_SUMMARY = true
+  DETAILED_REFERENCE_SUMMARY = true
+  DETAILED_CITATION_SUMMARY = true
+
+  COLOR = false
+
+  SILENCE_STRINGS = {}
+  SILENCE_PKGS = {} -- just the package names
+  SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
+  SILENCE_FILES_RECURSIVE = {} -- same
+
+  -- The user may redefine the severity level of some messages.
+  FORCED_DEBUG = {}
+  FORCED_INFO = {}
+  FORCED_WARNING = {}
+  FORCED_CRITICAL = {}
+
+  -- "-l level -c configFile"
+  local optionsWithArgs = "lc"
+  local vars = simpleGetopt(args, optionsWithArgs)
+
+  --help
+  -- "-h"
+  if vars.help or vars.h then
+      for _, line in ipairs(linesToTable(helpmsg)) do print(line) end
       os.exit(0)
   end
 
   --version
   if vars.version then
-      print("texlogsieve 1.2.0")
-      print("Copyright (C) 2021, 2022 Nelson Lago <lago at ime.usp.br>")
-      print("License GPLv3+: GNU GPL version 3 or later "
-            .. "<https://gnu.org/licenses/gpl.html>.")
-      print("This is free software: you are free to change "
-            .. "and redistribute it.")
-      print("There is NO WARRANTY, to the extent permitted by law.")
+      for _, line in ipairs(linesToTable(versionmsg)) do print(line) end
       os.exit(0)
   end
 
@@ -1029,6 +1038,21 @@
   local filename = kpse.find_file('texlogsieverc')
   if filename ~= nil then table.insert(configFileNames, 1, filename) end
 
+  if os.type == "unix" then
+      filename = kpse.find_file(os.getenv("HOME") .. "/.texlogsieverc")
+  else
+      -- https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
+      -- %LOCALAPPDATA% corresponds to C:\Users\<username>\AppData\Local .
+      filename = kpse.find_file(os.getenv("%LOCALAPPDATA%") .. "/texlogsieverc")
+      if filename == nil then
+          -- %APPDATA% is "C:\Users\<username>\AppData\Roaming" or
+          -- "C:\Documents and Settings\<username>\Application Data"
+          filename = kpse.find_file(os.getenv("%APPDATA%") .. "/texlogsieverc")
+      end
+  end
+
+  if filename ~= nil then table.insert(configFileNames, 1, filename) end
+
   for _, filename in ipairs(configFileNames) do
       local configFile = assert(io.open(filename, "r"))
       vars = processConfigFile(configFile, vars)
@@ -1353,6 +1377,39 @@
   vars['set-to-level-critical'] = nil
 
 
+  --verbose
+  -- "-v"
+  if vars['verbose'] or vars.v then
+      local msg = ""
+
+      for _, name in ipairs(configFileNames) do msg = msg .. name .. ", " end
+
+      if msg == "" then
+          print("texlogsieve: no config files, using defaults")
+      else
+          msg = string.sub(msg, 1, -3)
+          print("texlogsieve: using config files: " .. msg)
+      end
+
+      msg = "texlogsieve: minlevel is "
+      if     MINLEVEL == 0 then msg = msg .. 'DEBUG'
+      elseif MINLEVEL == 1 then msg = msg .. 'INFO'
+      elseif MINLEVEL == 2 then msg = msg .. 'WARNING'
+      elseif MINLEVEL == 3 then msg = msg .. 'CRITICAL'
+      else                      msg = msg .. 'UNKNOWN'
+      end
+
+      print(msg)
+
+      if RAW then
+          print("texlogsieve: using raw (unwrap-only) mode")
+      end
+  end
+
+  vars['verbose'] = nil
+  vars.v = nil
+
+
   local unknown_options = false
   for k, v in pairs(vars) do
       print('    texlogsieve: unknown option "' .. k .. '"')
@@ -1581,13 +1638,13 @@
 end
 
 function showFileBanner(msg)
+  if msg.filename == "DUMMY" then PARSE_ERROR = true end
+
   if not FILE_BANNER then return end
 
   if msg.filename ~= nil
                 and msg.filename ~= ""
                 and msg.filename ~= lastFileBanner
-                -- TODO: "DUMMY" should never happen, but
-                --       what should we do if it does?
   then
       lastFileBanner = msg.filename
       local txt = "From file " .. msg.filename .. ":"
@@ -1674,7 +1731,7 @@
 function showSummary()
   local somethingInSummary = false
 
-  if SHOULD_RERUN_LATEX or ERRORS_DETECTED then
+  if SHOULD_RERUN_LATEX or ERRORS_DETECTED or PARSE_ERROR then
       somethingInSummary = true
   else
       for _, summary in ipairs(summaries) do
@@ -1716,6 +1773,15 @@
       print()
   end
 
+  if PARSE_ERROR then
+      local txt = "** texlogsieve got confused during log processing **" ..
+                  "\n" .. "   messages may be missing or filenames may be" ..
+                  "\n" .. "   incorrect, check the LaTeX logfile directly"
+      if COLOR then txt = red(txt) end
+      print(txt)
+      print()
+  end
+
   if ERRORS_DETECTED then
       local txt = "** There were errors during processing! Generated PDF is probably defective **"
       if COLOR then txt = red(txt) end
@@ -2169,9 +2235,11 @@
       else
           -- This should never happen, but if it does
           -- we will probably end up in an endless loop
-          io.stderr:write("    texlogsieve: parsing error in "
-                               .. "fpHandler:process()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum .. " (fpHandler:process)\n")
 
+          PARSE_ERROR = true
+
           dispatch(self.message)
           self.message = nil
           self.doit = self.startProcessing
@@ -2199,8 +2267,10 @@
   Lines:handledChars(last)
 
   if self.stack:pop() == nil then
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "fpHandler:processClose()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum .. " (fpHandler:processClose)\n")
+
+      PARSE_ERROR = true
   end
 
   if self.stack:empty() then
@@ -2276,9 +2346,12 @@
   end
 
   if last == nil then
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "underOverFullBoxHandler:handleFirstLine()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum
+                           .. " (underOverFullBoxHandler:handleFirstLine)\n")
 
+      PARSE_ERROR = true
+
       self.doit = self.handleFirstLine
       dispatch(self.message)
       self.message = nil
@@ -2439,9 +2512,12 @@
   for _, val in ipairs(tmp) do table.insert(self.captures, val) end
 
   if last == nil then
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "stringsHandler:handleLines()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum
+                           .. " (stringsHandler:handleLines)\n")
 
+      PARSE_ERROR = true
+
       dispatch(self.message)
       self.message = nil
       self.doit = self.handleFirstLine
@@ -3570,9 +3646,11 @@
       flushUnrecognizedMessages()
       local last = unwrapUntilStringMatches(data.filename)
       if last == nil then
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "openParensHandler:doit()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum
+                               .. " (openParensHandler:doit)\n")
 
+          PARSE_ERROR = true
       else
           Lines:handledChars(last)
       end
@@ -3772,9 +3850,11 @@
       flushUnrecognizedMessages()
       local last = unwrapUntilStringMatches(data.latexPage)
       if last == nil then
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "openSquareBracketHandler:doit()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum
+                               .. " (openSquareBracketHandler:doit)\n")
 
+          PARSE_ERROR = true
       else
           Lines:handledChars(last)
       end
@@ -3993,9 +4073,11 @@
   -- "processing UTF-8 mapping" - this should never happen
   dispatch(self.message)
   self.message = nil
-  io.stderr:write("    texlogsieve: parsing error in "
-                   .. "utf8FontMapHandler:handleSecondLine()\n")
+  io.stderr:write("    texlogsieve: parsing error near input line "
+                       .. Lines.linenum
+                       .. " (utf8FontMapHandler:handleSecondLine)\n")
 
+  PARSE_ERROR = true
   Lines:handledChars()
   self.doit = self.handleFirstLine
   return true
@@ -4025,9 +4107,11 @@
       dispatch(self.message)
       self.message = nil
       flushUnrecognizedMessages()
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "utf8FontMapHandler:handleOtherLines()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum
+                           .. " (utf8FontMapHandler:handleOtherLines)\n")
 
+      PARSE_ERROR = true
       self.numTries = 0
       self.foundOtherLines = false
       self.doit = self.handleFirstLine
@@ -4972,8 +5056,8 @@
             if files[msg.filename] == nil then
                 files[msg.filename] = {}
             end
-            if msg.linenum ~= "" then
-                table.insert(files[msg.filename], msg.linenum)
+            if tonumber(msg.linenum) then
+                table.insert(files[msg.filename], tonumber(msg.linenum))
             end
         end
     end
@@ -5147,23 +5231,7 @@
 unusedLabelsSummary = citationsSummary:new()
 unusedLabelsSummary.header = 'Unused labels:'
 
-function unusedLabelsSummary:processSingleMessageList(messages)
-  local text = ""
-  local pages, files = self:pageAndFileList(messages)
-  local key = messages[1].key
-  if key == "" then key = '???' end
 
-  if self:detailed() then
-      if COLOR then key = red(key) end
-      text = key .. ' in ' .. pages .. " (" .. files .. ")"
-  else
-      text = key
-  end
-
-  return text
-end
-
-
 -- This is a little different from the others; we do not want to
 -- treat different messages differently, only report that there were
 -- under/overfull boxes in pages X, Y, and Z. So we store messages
@@ -5371,6 +5439,66 @@
 end
 
 
+--[[ ##### QUEUE ##### ]]--
+-- Adapted from https://www.lua.org/pil/11.4.html (in 2022)
+-- We use this for the input line counter
+
+Queue = {}
+
+function Queue:new()
+  local o = {}
+  setmetatable(o, self)
+  self.__index = self
+  o.first = 0
+  o.last = -1
+  return o
+end
+
+function Queue:pushleft(val)
+  self.first = self.first -1
+  self[self.first] = val
+end
+
+function Queue:pushright(val)
+  self.last = self.last +1
+  self[self.last] = val
+end
+
+function Queue:popleft()
+  if self.first > self.last then return nil end
+  local val = self[self.first]
+  self[self.first] = nil
+  self.first = self.first +1
+  return val
+end
+
+function Queue:popright()
+  if self.first > self.last then return nil end
+  local val = self[self.last]
+  self[self.last] = nil
+  self.last = self.last -1
+  return val
+end
+
+function Queue:peekleft()
+  if self.first > self.last then return nil end
+  return self[self.first]
+end
+
+function Queue:peekright()
+  if self.first > self.last then return nil end
+  return self[self.last]
+end
+
+function Queue:size()
+  return self.last - self.first +1
+end
+
+function Queue:empty()
+    return self.first > self.last
+end
+
+
 --[[ ##### GLOBTOPATTERN ##### ]]--
 
 -- convert a file glob to a lua pattern
@@ -5644,6 +5772,8 @@
 
 Lines = {}
 Lines.wrapped = {} -- memoization
+Lines.linenum = 0
+Lines.blankLines = Queue:new()
 
 function Lines:gotoNextLine()
   self.current = table.remove(self, 1)
@@ -5650,6 +5780,12 @@
   self.currentWrapped = table.remove(self.wrapped, 1)
   self.atBeginningOfLine = true
 
+  self.linenum = self.linenum +1
+  -- blank lines have to be counted too
+  if not self.blankLines:empty() then
+      self.linenum = self.linenum + self.blankLines:popleft()
+  end
+
   -- When unwrapping lines, we need to check whether a line is of
   -- the "right" size. However, we modify the content of currentLine
   -- during processing, so we capture its initial length here. See
@@ -5691,8 +5827,23 @@
 end
 
 function Lines:append(x)
-    table.insert(self, x)
-    table.insert(self.wrapped, "unknown") -- cannot use "nil"
+    -- We *need* to remove blank lines here because sometimes a wrapped
+    -- line is followed by a blank line, which messes our detection of
+    -- wrapped lines. However, the line we skip here is not the line we
+    -- are processing right now; we will encounter it in the future. So,
+    -- to keep line numbers right, we need to adjust the count later too.
+    if x == "" then
+        if not self.blankLines:empty() then
+            self.blankLines:pushright(self.blankLines:popright() +1)
+        else
+            self.blankLines:pushright(1)
+        end
+    else
+        self.blankLines:pushright(0)
+
+        table.insert(self, x)
+        table.insert(self.wrapped, "unknown") -- cannot use "nil"
+    end
 end
 
 function Lines:get(n)
@@ -5847,9 +5998,11 @@
       if Lines:seemsWrapped() then
           Lines:unwrapOneLine()
       else
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "unwrapUntilPatternMatches()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum
+                               .. " (unwrapUntilPatternMatches)\n")
 
+          PARSE_ERROR = true
           break
       end
   end
@@ -6008,9 +6161,10 @@
 
       -- no closing quote or the line is too short; can we unwrap this line?
       if not Lines:seemsWrapped(position) then
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "guessQuotedFilename()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum .. " (guessQuotedFilename)\n")
 
+          PARSE_ERROR = true
           return true, nil
       end
 

Modified: trunk/Master/texmf-dist/doc/man/man1/texlogsieve.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/texlogsieve.1	2022-08-05 21:33:57 UTC (rev 64059)
+++ trunk/Master/texmf-dist/doc/man/man1/texlogsieve.1	2022-08-05 21:34:16 UTC (rev 64060)
@@ -1,4 +1,4 @@
-.TH TEXLOGSIEVE "1" "July 2022" "texlogsieve 1.2.0" "User Commands"
+.TH TEXLOGSIEVE "1" "August 2022" "texlogsieve 1.3.0" "User Commands"
 
 .SH NAME
 
@@ -198,10 +198,15 @@
 
 .TP
 \fB\-c\fR \fI\,CFGFILE\/\fR, \fB\-\-config\-file\fR=\fI\,CFGFILE\/\fR
-Read options from the given configuration file in addition to
-\fI\,texlogsieverc\/\fR.
+Read options from the given configuration file in addition to the
+default config files (see the \fBCONFIGURATION FILE\fR section).
 
 .TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Print the list of configuration files read and a short summary of the
+most important active configuration options.
+
+.TP
 \fB\-h\fR, \fB\-\-help\fR
 Show concise options description.
 
@@ -226,13 +231,14 @@
 .SH CONFIGURATION FILE
 
 texlogsieve always searches automatically for the (optional)
-\fI\,texlogsieverc\/\fR configuration file in the TeX path (i.e., it searches
-using Kpathsea). In the default configuration, the current directory is in
-the search path, so adding a config file with that name to the project
-directory is enough to make it work. Options in the config file are exactly
-the same as the long command-line options described above, but without the
-preceding \[lq]\-\-\[rq] characters. Lines starting with a \[lq]#\[rq] sign
-are comments. An example configuration file:
+\fI\,texlogsieverc\/\fR configuration file in \fI\,$TEXINPUTS\/\fR (i.e.,
+it searches using Kpathsea). In the default configuration, the current
+directory is in \fI\,$TEXINPUTS\/\fR, so adding a config file with that
+name to the project directory is enough to make it work. Options in
+the config file are exactly the same as the long command-line options
+described above, but without the preceding \[lq]\-\-\[rq] characters.
+Lines starting with a \[lq]#\[rq] sign are comments. An example
+configuration file:
 
 .RS
 .EX
@@ -256,13 +262,22 @@
 .EE
 .RE
 
+If you'd like to also have a generic configuration file for all your projects
+(a good idea), put it at \fI\,$HOME/.texlogsieverc\/\fR in unix-like systems;
+in Windows, put it either at \fI\,%LOCALAPPDATA%\etexlogsieverc\/\fR
+(\fI\,C:\eUsers\e<username>\eAppData\eLocal\/\fR)
+or \fI\,%APPDATA%\etexlogsieverc\/\fR (\fI\,C:\eDocuments and
+Settings\e<username>\eApplication Data\/\fR or
+\fI\,C:\eUsers\e<username>\eAppData\eRoaming).
+
 .SH LIMITATIONS
 
 texlogsieve does not try to do anything smart about error messages (but it
-shows a warning in the summary if one is detected); if there is an error,
-you probably want to take a look directly at the log file anyway. It also
-cannot detect if LaTeX stops for user input, so you should \fBreally\fR
-run LaTeX in \fI\,nonstopmode\/\fR when texlogsieve is reading from a pipe.
+shows a warning in the summary if one is detected; check the \fBTIPS\fR
+section of the pdf documentation regarding this); if there is an error, you
+probably want to take a look directly at the log file anyway. It also cannot
+detect if LaTeX stops for user input, so you should \fBreally\fR run LaTeX
+in \fI\,nonstopmode\/\fR when texlogsieve is reading from a pipe.
 
 Since it needs to know what messages to expect, texlogsieve is currently
 geared towards LaTeX; I have no idea how it would work with ConTeXt or plain

Modified: trunk/Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex	2022-08-05 21:33:57 UTC (rev 64059)
+++ trunk/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex	2022-08-05 21:34:16 UTC (rev 64060)
@@ -37,6 +37,8 @@
 \usepackage{microtype}
 \usepackage{metalogo}
 
+\hyphenation{tex-log-sieve tex-log-sieverc}
+
 \RecordChanges
 
 \changes{1.0.0-beta-1}{2021/12/16}{First public prerelease}
@@ -84,12 +86,18 @@
 \changes{1.2.0}{2022/07/21}{Summary messages use singular and plural
                             for pages and files}
 \changes{1.2.0}{2022/07/21}{Add unused labels to summary}
+\changes{1.3.0}{2022/08/05}{Sort line numbers in summary}
+\changes{1.3.0}{2022/08/05}{Indicate whether there were parse errors
+                            in summary}
+\changes{1.3.0}{2022/08/05}{Add line number to parse error messages}
+\changes{1.3.0}{2022/08/05}{Add \texttt{-\/-verbose} option}
+\changes{1.3.0}{2022/08/05}{Search for a config file in the user's homedir too}
 
 \begin{document}
 
 \title{\textsf{texlogsieve}:\thanks{This document
-corresponds to \textsf{texlogsieve}~1.2.0,
-dated~2022-07-21.}\\[.3\baselineskip]
+corresponds to \textsf{texlogsieve}~1.3.0,
+dated~2022-08-05.}\\[.3\baselineskip]
 {\normalsize(yet another program to)\\[-.6\baselineskip]}
 {\large filter and summarize \LaTeX\ log files}
 }
@@ -138,12 +146,12 @@
 \href{https://gricad-gitlab.univ-grenoble-alpes.fr/labbeju/latex-packages}
 {\texttt{texlogfilter}}, and others.
 
-Note that it does not try to do anything smart about error messages
-(but it shows a warning in the summary if one is detected); if there
-is an error, you probably want to take a look directly at the log file
-anyway. It also cannot detect if \LaTeX{} stops for user input, so
-you should \textbf{really} run \LaTeX\ in \texttt{nonstopmode} when
-\texttt{texlogsieve} is reading from a pipe.
+Note that it does not try to do anything smart about error messages (but
+it shows a warning in the summary if one is detected; check the ``Tips''
+section regarding this); if there is an error, you probably want to take
+a look directly at the log file anyway. It also cannot detect if \LaTeX{}
+stops for user input, so you should \textbf{really} run \LaTeX\ in
+\texttt{nonstopmode} when \texttt{texlogsieve} is reading from a pipe.
 
 \texttt{texlogsieve} \textbf{must} be run from the same directory as
 \verb/[pdf|lua|xe]latex/, because it searches for the files used during
@@ -223,13 +231,14 @@
 \section{Configuration File}
 
 \texttt{texlogsieve} always searches automatically for the (optional)
-\texttt{texlogsieverc} configuration file in the \TeX\ path (i.e., it
-searches using \texttt{Kpathsea}). In the default configuration, the
-current directory is in the search path, so adding a config file with that
-name to the project directory is enough to make it work. Options in the
-config file are exactly the same as the long command-line options described
-below, but without the preceding ``\texttt{-\/-}'' characters. Lines
-starting with a ``\#'' sign are comments. An example configuration file:
+\texttt{texlogsieverc} configuration file in \texttt{\$TEXINPUTS} (i.e.,
+it searches using \texttt{Kpathsea}). In the default configuration, the
+current directory is in \texttt{\$TEXINPUTS}, so adding a config file
+with that name to the project directory is enough to make it work.
+Options in the config file are exactly the same as the long command-line
+options described below, but without the preceding ``\texttt{-\/-}''
+characters. Lines starting with a ``\#'' sign are comments. An example
+configuration file:
 
 \begin{quote}
 \begin{verbatim}
@@ -246,6 +255,16 @@
 \end{verbatim}
 \end{quote}
 
+If you'd like to also have a generic configuration file for all your projects
+(a good idea), put it at \texttt{\$HOME/.texlogsieverc} in unix-like systems;
+in Windows, put it either at \texttt{\%LOCALAPPDATA\%\textbackslash{}%
+texlogsieverc} (\texttt{C:\textbackslash{}Users\textbackslash{}<username>%
+\textbackslash{}AppData\textbackslash{}Local}) or \texttt{\%APPDATA\%%
+\textbackslash{}texlogsieverc} (\texttt{C:\textbackslash{}Documents and
+Settings\textbackslash{}<username>\textbackslash{}Application Data} or
+\texttt{C:\textbackslash{}Users\textbackslash{}<username>\textbackslash{}%
+AppData\textbackslash{}Roaming}).
+
 \section{Options}
 
 \begin{description}
@@ -426,11 +445,17 @@
 
 \begin{description}
 \item[\texttt{-c CFGFILE}, \texttt{-\/-config-file=CFGFILE}]~\\
-Read options from the given configuration file in addition to
-\texttt{texlogsieverc}.
+Read options from the given configuration file in addition to the
+default config files (see the ``Configuration File'' section).
 \end{description}
 
 \begin{description}
+\item[\texttt{-v}, \texttt{-\/-verbose}]~\\
+Print the list of configuration files read and a short summary of the
+most important active configuration options.
+\end{description}
+
+\begin{description}
 \item[\texttt{-h}, \texttt{-\/-help}]
 Show concise options description.
 \end{description}
@@ -449,9 +474,8 @@
   \texttt{silence-[something]} and \texttt{set-to-level-[something]} options:
   You will get reasonably quiet output but still be notified of problems. Since
   you probably always use essentially the same set of packages and classes,
-  the file will be useable in other \LaTeX\ projects too (you may even put
-  it somewhere in your \TeX\ path, like \texttt{\$HOME/texmf/tex/latex} on
-  Unix-like systems).
+  the file will be useable in other \LaTeX\ projects too; just put it in one
+  of the places discussed in the ``Configuration File'' section.
 
   \item \texttt{texlogsieve} has no smarts to deal with error messages, but
   you may use options \texttt{-l unknown -\/-no-page-delay -\/-no-summary

Modified: trunk/Master/texmf-dist/scripts/texlogsieve/texlogsieve
===================================================================
--- trunk/Master/texmf-dist/scripts/texlogsieve/texlogsieve	2022-08-05 21:33:57 UTC (rev 64059)
+++ trunk/Master/texmf-dist/scripts/texlogsieve/texlogsieve	2022-08-05 21:34:16 UTC (rev 64060)
@@ -176,8 +176,14 @@
    is indented to start after the end of the first, as in the example
    above. If the content of a line does not fit, a part of it (the
    beginning for the first line and the end for the second line) may
-   be replaced by "...".
+   be replaced by "...". error_line must be < 255 and half_error_line
+   must be < error_line -15. If error_line >= max_print_line or
+   half_error_line >= max_print_line, TeX does line wrapping as usual
+   (see below). If either is exactly max_print_line (which is true
+   for the default values), things get confusing, so TeX may add a
+   blank line when wrapping.
 
+
    LaTeX errors usually follow the format
 
        ! LaTeX/Package/Class BLAH Error: some description
@@ -620,10 +626,8 @@
   while Lines:numLines() < 15 do
       tmp = logfile:read("*line")
       if tmp == nil then break end
-      -- We *need* to remove blank lines here because
-      -- sometimes a wrapped line is followed by a blank
-      -- line, which messes our detection of wrapped lines.
-      if tmp ~= "" then Lines:append(tmp) end
+      -- Do not skip blank lines here, we need to do it in Lines:append()
+      Lines:append(tmp)
   end
 
   -- proceed to the next line
@@ -744,6 +748,9 @@
   -- messages, this is set to true (used in showSummary)
   SHOULD_RERUN_LATEX = false
 
+  -- If there were parse errors, we should say so in showSummary
+  PARSE_ERROR = false
+
   -- Did we detect any error messages?
   ERRORS_DETECTED = false
 
@@ -898,42 +905,7 @@
   Lines:append(line)
 end
 
-function processCommandLine(args)
-  HEARTBEAT = true
-  PAGE_DELAY = true
-  ONLY_SUMMARY = false
-  SHOW_SUMMARY = true
-  SHOW_SHIPOUTS = false
-  RAW = false
-  SILENCE_REPETITIONS = true
-  MINLEVEL = WARNING
-  BE_REDUNDANT = false
-  FILE_BANNER = true
-  DETAILED_UNDEROVER_SUMMARY = true
-  DETAILED_REFERENCE_SUMMARY = true
-  DETAILED_CITATION_SUMMARY = true
-
-  COLOR = false
-
-  SILENCE_STRINGS = {}
-  SILENCE_PKGS = {} -- just the package names
-  SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
-  SILENCE_FILES_RECURSIVE = {} -- same
-
-  -- The user may redefine the severity level of some messages.
-  FORCED_DEBUG = {}
-  FORCED_INFO = {}
-  FORCED_WARNING = {}
-  FORCED_CRITICAL = {}
-
-  -- "-l level -c configFile"
-  local optionsWithArgs = "lc"
-  local vars = simpleGetopt(args, optionsWithArgs)
-
-  --help
-  -- "-h"
-  if vars.help or vars.h then
-      local msg = [[
+helpmsg = [[
 Usage: texlogsieve [OPTION]... [INPUT FILE]
 texlogsieve reads a LaTeX log file (or the standard input), filters
 out less relevant messages, and displays a summary report.
@@ -994,23 +966,60 @@
                                          text EXCERPT to CRITICAL; can be used
                                          multiple times
   -c cfgfile, --config-file=cfgfile      read options from given config file
-                                         in addition to texlogsieverc
+                                         in addition to default config files
+  -v, --verbose                          Display info on texlogsieve config
   -h, --help                             give this help list
   --version                              print program version]]
 
-      for _, line in ipairs(linesToTable(msg)) do print(line) end
+versionmsg = [[
+texlogsieve 1.3.0
+Copyright (C) 2021, 2022 Nelson Lago <lago at ime.usp.br>
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.]]
+
+function processCommandLine(args)
+  HEARTBEAT = true
+  PAGE_DELAY = true
+  ONLY_SUMMARY = false
+  SHOW_SUMMARY = true
+  SHOW_SHIPOUTS = false
+  RAW = false
+  SILENCE_REPETITIONS = true
+  MINLEVEL = WARNING
+  BE_REDUNDANT = false
+  FILE_BANNER = true
+  DETAILED_UNDEROVER_SUMMARY = true
+  DETAILED_REFERENCE_SUMMARY = true
+  DETAILED_CITATION_SUMMARY = true
+
+  COLOR = false
+
+  SILENCE_STRINGS = {}
+  SILENCE_PKGS = {} -- just the package names
+  SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
+  SILENCE_FILES_RECURSIVE = {} -- same
+
+  -- The user may redefine the severity level of some messages.
+  FORCED_DEBUG = {}
+  FORCED_INFO = {}
+  FORCED_WARNING = {}
+  FORCED_CRITICAL = {}
+
+  -- "-l level -c configFile"
+  local optionsWithArgs = "lc"
+  local vars = simpleGetopt(args, optionsWithArgs)
+
+  --help
+  -- "-h"
+  if vars.help or vars.h then
+      for _, line in ipairs(linesToTable(helpmsg)) do print(line) end
       os.exit(0)
   end
 
   --version
   if vars.version then
-      print("texlogsieve 1.2.0")
-      print("Copyright (C) 2021, 2022 Nelson Lago <lago at ime.usp.br>")
-      print("License GPLv3+: GNU GPL version 3 or later "
-            .. "<https://gnu.org/licenses/gpl.html>.")
-      print("This is free software: you are free to change "
-            .. "and redistribute it.")
-      print("There is NO WARRANTY, to the extent permitted by law.")
+      for _, line in ipairs(linesToTable(versionmsg)) do print(line) end
       os.exit(0)
   end
 
@@ -1029,6 +1038,21 @@
   local filename = kpse.find_file('texlogsieverc')
   if filename ~= nil then table.insert(configFileNames, 1, filename) end
 
+  if os.type == "unix" then
+      filename = kpse.find_file(os.getenv("HOME") .. "/.texlogsieverc")
+  else
+      -- https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
+      -- %LOCALAPPDATA% corresponds to C:\Users\<username>\AppData\Local .
+      filename = kpse.find_file(os.getenv("%LOCALAPPDATA%") .. "/texlogsieverc")
+      if filename == nil then
+          -- %APPDATA% is "C:\Users\<username>\AppData\Roaming" or
+          -- "C:\Documents and Settings\<username>\Application Data"
+          filename = kpse.find_file(os.getenv("%APPDATA%") .. "/texlogsieverc")
+      end
+  end
+
+  if filename ~= nil then table.insert(configFileNames, 1, filename) end
+
   for _, filename in ipairs(configFileNames) do
       local configFile = assert(io.open(filename, "r"))
       vars = processConfigFile(configFile, vars)
@@ -1353,6 +1377,39 @@
   vars['set-to-level-critical'] = nil
 
 
+  --verbose
+  -- "-v"
+  if vars['verbose'] or vars.v then
+      local msg = ""
+
+      for _, name in ipairs(configFileNames) do msg = msg .. name .. ", " end
+
+      if msg == "" then
+          print("texlogsieve: no config files, using defaults")
+      else
+          msg = string.sub(msg, 1, -3)
+          print("texlogsieve: using config files: " .. msg)
+      end
+
+      msg = "texlogsieve: minlevel is "
+      if     MINLEVEL == 0 then msg = msg .. 'DEBUG'
+      elseif MINLEVEL == 1 then msg = msg .. 'INFO'
+      elseif MINLEVEL == 2 then msg = msg .. 'WARNING'
+      elseif MINLEVEL == 3 then msg = msg .. 'CRITICAL'
+      else                      msg = msg .. 'UNKNOWN'
+      end
+
+      print(msg)
+
+      if RAW then
+          print("texlogsieve: using raw (unwrap-only) mode")
+      end
+  end
+
+  vars['verbose'] = nil
+  vars.v = nil
+
+
   local unknown_options = false
   for k, v in pairs(vars) do
       print('    texlogsieve: unknown option "' .. k .. '"')
@@ -1581,13 +1638,13 @@
 end
 
 function showFileBanner(msg)
+  if msg.filename == "DUMMY" then PARSE_ERROR = true end
+
   if not FILE_BANNER then return end
 
   if msg.filename ~= nil
                 and msg.filename ~= ""
                 and msg.filename ~= lastFileBanner
-                -- TODO: "DUMMY" should never happen, but
-                --       what should we do if it does?
   then
       lastFileBanner = msg.filename
       local txt = "From file " .. msg.filename .. ":"
@@ -1674,7 +1731,7 @@
 function showSummary()
   local somethingInSummary = false
 
-  if SHOULD_RERUN_LATEX or ERRORS_DETECTED then
+  if SHOULD_RERUN_LATEX or ERRORS_DETECTED or PARSE_ERROR then
       somethingInSummary = true
   else
       for _, summary in ipairs(summaries) do
@@ -1716,6 +1773,15 @@
       print()
   end
 
+  if PARSE_ERROR then
+      local txt = "** texlogsieve got confused during log processing **" ..
+                  "\n" .. "   messages may be missing or filenames may be" ..
+                  "\n" .. "   incorrect, check the LaTeX logfile directly"
+      if COLOR then txt = red(txt) end
+      print(txt)
+      print()
+  end
+
   if ERRORS_DETECTED then
       local txt = "** There were errors during processing! Generated PDF is probably defective **"
       if COLOR then txt = red(txt) end
@@ -2169,9 +2235,11 @@
       else
           -- This should never happen, but if it does
           -- we will probably end up in an endless loop
-          io.stderr:write("    texlogsieve: parsing error in "
-                               .. "fpHandler:process()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum .. " (fpHandler:process)\n")
 
+          PARSE_ERROR = true
+
           dispatch(self.message)
           self.message = nil
           self.doit = self.startProcessing
@@ -2199,8 +2267,10 @@
   Lines:handledChars(last)
 
   if self.stack:pop() == nil then
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "fpHandler:processClose()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum .. " (fpHandler:processClose)\n")
+
+      PARSE_ERROR = true
   end
 
   if self.stack:empty() then
@@ -2276,9 +2346,12 @@
   end
 
   if last == nil then
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "underOverFullBoxHandler:handleFirstLine()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum
+                           .. " (underOverFullBoxHandler:handleFirstLine)\n")
 
+      PARSE_ERROR = true
+
       self.doit = self.handleFirstLine
       dispatch(self.message)
       self.message = nil
@@ -2439,9 +2512,12 @@
   for _, val in ipairs(tmp) do table.insert(self.captures, val) end
 
   if last == nil then
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "stringsHandler:handleLines()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum
+                           .. " (stringsHandler:handleLines)\n")
 
+      PARSE_ERROR = true
+
       dispatch(self.message)
       self.message = nil
       self.doit = self.handleFirstLine
@@ -3570,9 +3646,11 @@
       flushUnrecognizedMessages()
       local last = unwrapUntilStringMatches(data.filename)
       if last == nil then
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "openParensHandler:doit()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum
+                               .. " (openParensHandler:doit)\n")
 
+          PARSE_ERROR = true
       else
           Lines:handledChars(last)
       end
@@ -3772,9 +3850,11 @@
       flushUnrecognizedMessages()
       local last = unwrapUntilStringMatches(data.latexPage)
       if last == nil then
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "openSquareBracketHandler:doit()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum
+                               .. " (openSquareBracketHandler:doit)\n")
 
+          PARSE_ERROR = true
       else
           Lines:handledChars(last)
       end
@@ -3993,9 +4073,11 @@
   -- "processing UTF-8 mapping" - this should never happen
   dispatch(self.message)
   self.message = nil
-  io.stderr:write("    texlogsieve: parsing error in "
-                   .. "utf8FontMapHandler:handleSecondLine()\n")
+  io.stderr:write("    texlogsieve: parsing error near input line "
+                       .. Lines.linenum
+                       .. " (utf8FontMapHandler:handleSecondLine)\n")
 
+  PARSE_ERROR = true
   Lines:handledChars()
   self.doit = self.handleFirstLine
   return true
@@ -4025,9 +4107,11 @@
       dispatch(self.message)
       self.message = nil
       flushUnrecognizedMessages()
-      io.stderr:write("    texlogsieve: parsing error in "
-                       .. "utf8FontMapHandler:handleOtherLines()\n")
+      io.stderr:write("    texlogsieve: parsing error near input line "
+                           .. Lines.linenum
+                           .. " (utf8FontMapHandler:handleOtherLines)\n")
 
+      PARSE_ERROR = true
       self.numTries = 0
       self.foundOtherLines = false
       self.doit = self.handleFirstLine
@@ -4972,8 +5056,8 @@
             if files[msg.filename] == nil then
                 files[msg.filename] = {}
             end
-            if msg.linenum ~= "" then
-                table.insert(files[msg.filename], msg.linenum)
+            if tonumber(msg.linenum) then
+                table.insert(files[msg.filename], tonumber(msg.linenum))
             end
         end
     end
@@ -5147,23 +5231,7 @@
 unusedLabelsSummary = citationsSummary:new()
 unusedLabelsSummary.header = 'Unused labels:'
 
-function unusedLabelsSummary:processSingleMessageList(messages)
-  local text = ""
-  local pages, files = self:pageAndFileList(messages)
-  local key = messages[1].key
-  if key == "" then key = '???' end
 
-  if self:detailed() then
-      if COLOR then key = red(key) end
-      text = key .. ' in ' .. pages .. " (" .. files .. ")"
-  else
-      text = key
-  end
-
-  return text
-end
-
-
 -- This is a little different from the others; we do not want to
 -- treat different messages differently, only report that there were
 -- under/overfull boxes in pages X, Y, and Z. So we store messages
@@ -5371,6 +5439,66 @@
 end
 
 
+--[[ ##### QUEUE ##### ]]--
+-- Adapted from https://www.lua.org/pil/11.4.html (in 2022)
+-- We use this for the input line counter
+
+Queue = {}
+
+function Queue:new()
+  local o = {}
+  setmetatable(o, self)
+  self.__index = self
+  o.first = 0
+  o.last = -1
+  return o
+end
+
+function Queue:pushleft(val)
+  self.first = self.first -1
+  self[self.first] = val
+end
+
+function Queue:pushright(val)
+  self.last = self.last +1
+  self[self.last] = val
+end
+
+function Queue:popleft()
+  if self.first > self.last then return nil end
+  local val = self[self.first]
+  self[self.first] = nil
+  self.first = self.first +1
+  return val
+end
+
+function Queue:popright()
+  if self.first > self.last then return nil end
+  local val = self[self.last]
+  self[self.last] = nil
+  self.last = self.last -1
+  return val
+end
+
+function Queue:peekleft()
+  if self.first > self.last then return nil end
+  return self[self.first]
+end
+
+function Queue:peekright()
+  if self.first > self.last then return nil end
+  return self[self.last]
+end
+
+function Queue:size()
+  return self.last - self.first +1
+end
+
+function Queue:empty()
+    return self.first > self.last
+end
+
+
 --[[ ##### GLOBTOPATTERN ##### ]]--
 
 -- convert a file glob to a lua pattern
@@ -5644,6 +5772,8 @@
 
 Lines = {}
 Lines.wrapped = {} -- memoization
+Lines.linenum = 0
+Lines.blankLines = Queue:new()
 
 function Lines:gotoNextLine()
   self.current = table.remove(self, 1)
@@ -5650,6 +5780,12 @@
   self.currentWrapped = table.remove(self.wrapped, 1)
   self.atBeginningOfLine = true
 
+  self.linenum = self.linenum +1
+  -- blank lines have to be counted too
+  if not self.blankLines:empty() then
+      self.linenum = self.linenum + self.blankLines:popleft()
+  end
+
   -- When unwrapping lines, we need to check whether a line is of
   -- the "right" size. However, we modify the content of currentLine
   -- during processing, so we capture its initial length here. See
@@ -5691,8 +5827,23 @@
 end
 
 function Lines:append(x)
-    table.insert(self, x)
-    table.insert(self.wrapped, "unknown") -- cannot use "nil"
+    -- We *need* to remove blank lines here because sometimes a wrapped
+    -- line is followed by a blank line, which messes our detection of
+    -- wrapped lines. However, the line we skip here is not the line we
+    -- are processing right now; we will encounter it in the future. So,
+    -- to keep line numbers right, we need to adjust the count later too.
+    if x == "" then
+        if not self.blankLines:empty() then
+            self.blankLines:pushright(self.blankLines:popright() +1)
+        else
+            self.blankLines:pushright(1)
+        end
+    else
+        self.blankLines:pushright(0)
+
+        table.insert(self, x)
+        table.insert(self.wrapped, "unknown") -- cannot use "nil"
+    end
 end
 
 function Lines:get(n)
@@ -5847,9 +5998,11 @@
       if Lines:seemsWrapped() then
           Lines:unwrapOneLine()
       else
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "unwrapUntilPatternMatches()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum
+                               .. " (unwrapUntilPatternMatches)\n")
 
+          PARSE_ERROR = true
           break
       end
   end
@@ -6008,9 +6161,10 @@
 
       -- no closing quote or the line is too short; can we unwrap this line?
       if not Lines:seemsWrapped(position) then
-          io.stderr:write("    texlogsieve: parsing error in "
-                           .. "guessQuotedFilename()\n")
+          io.stderr:write("    texlogsieve: parsing error near input line "
+                               .. Lines.linenum .. " (guessQuotedFilename)\n")
 
+          PARSE_ERROR = true
           return true, nil
       end
 



More information about the tex-live-commits mailing list.