summaryrefslogtreecommitdiff
path: root/support/texlogsieve/texlogsieve.tex
blob: d44af80df994df3c7c0f5d6ba89d8db112e01ed1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
% texlogsieve - filter and summarize LaTeX log files
%
% Copyright (C) 2021, 2022 Nelson Lago <lago@ime.usp.br>
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <https://www.gnu.org/licenses/>.
%
% Code etc: https://gitlab.com/lago/texlogsieve

\documentclass{ltxdoc}

\usepackage[hyperref,svgnames,x11names,table]{xcolor}
\usepackage{url}
\urlstyle{sf}
\usepackage{hyperref}
\hypersetup{
  colorlinks=true,
  citecolor=DarkGreen,
  linkcolor=NavyBlue,
  urlcolor=DarkRed,
  filecolor=green,
  anchorcolor=black,
}

\usepackage{libertinus}
\usepackage[scale=.85]{sourcecodepro}
\usepackage{microtype}
\usepackage{metalogo}

\hyphenation{tex-log-sieve tex-log-sieverc}

\RecordChanges

\changes{1.0.0-beta-1}{2021/12/16}{First public prerelease}
\changes{1.0.0-beta-2}{2022/01/04}{Automatically read \texttt{texlogsieverc}
                                    if it exists}
\changes{1.0.0-beta-2}{2022/01/04}{Add options \texttt{-\/-be-redundant}
                                    and \texttt{-\/-box-detail}}
\changes{1.0.0-beta-2}{2022/01/04}{Add options
                                    \texttt{-\/-set-to-level-[levelname]}}
\changes{1.0.0-beta-2}{2022/01/04}{Include silenced messages in summaries}
\changes{1.0.0-beta-2}{2022/01/04}{Substitute empty citation/label keys
                                    for ``???''}
\changes{1.0.0-beta-2}{2022/01/04}{Fix bug that prevented
                                    \texttt{-\/-add-[info\textbar
                                    warning]-message} from working}
\changes{1.0.0-beta-2}{2022/01/04}{Misc small bugfixes}
\changes{1.0.0-beta-3}{2022/02/02}{Add options
                                    \texttt{-\/-summary-detail},
                                    \texttt{-\/-ref-detail},
                                    \texttt{-\/-cite-detail}}
\changes{1.0.0-beta-3}{2022/02/02}{Abort on invalid command-line options}
\changes{1.0.0-beta-3}{2022/02/02}{Detect ``please rerun`` messages and
                                    add them to the summary}
\changes{1.0.0-beta-3}{2022/02/02}{Fix line unwrapping with \XeTeX}
\changes{1.0.0-final={1.0.0}}{2022/02/09}{Better compatibility with MiK\TeX\ for
                                 Windows}
\changes{1.0.0-final={1.0.0}}{2022/02/09}{If possible, use the \texttt{.fls} file}
\changes{1.0.0-final={1.0.0}}{2022/02/09}{Add options \texttt{-\/-file-banner}
                                 and \texttt{-\/-color}}
\changes{1.0.0-final={1.0.0}}{2022/02/09}{Changed the effect of filters on the summary}
\changes{1.1.0}{2022/03/04}{Print ``No important messages to show'' when
                            nothing is printed}
\changes{1.1.0}{2022/03/04}{Fix bug with filename and URL on the same line}
\changes{1.1.0}{2022/03/04}{Print warning in the summary when there are
                            error messages}
\changes{1.1.0}{2022/03/04}{Do not lose messages if the file is truncated}
\changes{1.1.1}{2022/03/05}{Fix error in variable scope}
\changes{1.1.2}{2022/03/14}{Fix bug unwrapping lines starting with ``]''}
\changes{1.1.3}{2022/04/22}{Be more careful with continuation lines in error
                            msgs}
\changes{1.2.0}{2022/07/21}{Fix bug with missing citations}
\changes{1.2.0}{2022/07/21}{Colored keys with missing citations / chars}
\changes{1.2.0}{2022/07/21}{Improved example latexmkrc in TIPS section}
\changes{1.2.0}{2022/07/21}{Summary messages include line numbers}
\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}
\changes{1.3.1}{2022/09/05}{Fix bug when searching for config files in Windows}

\begin{document}

\title{\textsf{texlogsieve}:\thanks{This document
corresponds to \textsf{texlogsieve}~1.3.1,
dated~2022-09-05.}\\[.3\baselineskip]
{\normalsize(yet another program to)\\[-.6\baselineskip]}
{\large filter and summarize \LaTeX\ log files}
}

\author{
Nelson Lago\\
\texttt{lago@ime.usp.br}\\
~\\
\url{https://gitlab.com/lago/texlogsieve}
}

\maketitle

\begin{abstract}

\texttt{texlogsieve} reads a \LaTeX\ log file (or the standard input if
no file is specified), filters out less relevant messages, and displays
a summary report. Highlights:

\begin{itemize}
  \item Two reports: the most important messages from the log file
        followed by a summary of repeated messages, undefined
        references etc.;
  \item The program goes to great lengths to correctly handle \TeX\ line
        wrapping and does a much better job at that than existing tools;
  \item Multiline messages are treated as a single entity;
  \item Several options to control which messages should be filtered out;
  \item No messages are accidentally removed.
\end{itemize}

\end{abstract}

\section*{Introduction}

The \LaTeX\ log file is very verbose, which is useful when debugging but
a hindrance during document preparation, as warnings such as ``missing
character'', ``undefined reference'', and others become buried among lots
of less relevant messages. This program filters out such less relevant
messages and outputs the rest, together with a final summary for the
specially important ones. It is a \texttt{texlua} script, similar in
spirit to tools such as \href{https://ctan.org/pkg/texfot}{\texttt{texfot}},
\href{https://ctan.org/pkg/texloganalyser}{\texttt{texloganalyser}},
\href{https://gitlab.com/latex-rubber/rubber}{\texttt{rubber-info}},
\href{https://ctan.org/pkg/texlog-extract}{\texttt{textlog\_extract}},
\href{https://github.com/reitzig/texlogparser}{\texttt{texlogparser}},
\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; 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
compilation (packages loaded from the current directory, files included
with \verb|\input| etc.).

\pagebreak[1]
The defaults are reasonable; hopefully, you can just do

\begin{list}{}{}
    \small\item
    \verb/[pdf|lua|xe]latex -interaction nonstopmode myfile.tex | texlogsieve/
    \par
    {\normalsize or\par}
    \verb|texlogsieve myfile.log|
\end{list}

\noindent and be satisfied with the result.

Since it needs to know what messages to expect, \texttt{texlogsieve} is
currently geared towards \LaTeX; I have no idea how it would work with
Con\TeX{}t or plain \TeX. Still, adding support to them should not be
too difficult.

If you want to know more about the \TeX\ log file and the workings of the
program, check the initial comments in the code.

\section{Unwrapping Long Lines}

\TeX\ wraps (breaks) lines longer than \texttt{max\_print\_line} (by
default, 79 characters). Most tools detect lines that are exactly 79
characters long and treat the next line as a continuation, but that fails
in quite a few cases (check the comments in the \texttt{texlogsieve} code
for a discussion on that). So, if at all possible, it is a very good idea
to set \texttt{max\_print\_line} to a really large value (such as 100,000),
effectively disabling line wrapping. It was useful in the 1980s, but not
anymore (your terminal or editor wraps automatically)\footnote{Likewise,
\texttt{error\_line} and \texttt{half\_error\_line} should be, respectively,
254 and 238 (more about these values here:
\url{https://tex.stackexchange.com/a/525972}).}.

Still, \texttt{texlogsieve} goes to great lengths to correctly handle
\TeX{} line wrapping and does a pretty good job at that. It understands
the \texttt{max\_print\_line} \TeX{} configuration variable and reads its
value from the same places as \TeX. Setting \texttt{max\_print\_line} to
a value larger than 9999 makes \texttt{texlogsieve} ignore line wrapping.

\section{Unrecognized Messages}
\label{unrecognized}

\texttt{texlogsieve} automatically handles messages such as ``Package blah
Info:\dots'' or ``LaTeX Warning:\dots''. However, many  messages do not
follow this pattern. To do its thing, \texttt{texlogsieve} should know about
these other messages beforehand. This is important for three reasons:

\begin{enumerate}
  \item Unknown messages are given maximum priority; if you do not want to
        see them, you have to use \texttt{-\/-silence-string};
  \item If the message has more than one line, each line is treated as an
        independent message. This means you need to use
        \texttt{-\/-silence-string} multiple times;
  \item In some rare cases, an unrecognized message may make
        \texttt{texlogsieve} misclassify nearby wrapped lines (if it comes
        right after a 79 characters long line of a specific type), close
        file messages (if it includes an unmatched close parens character),
        or shipout messages (if it includes an unmatched close square bracket
        character or an open square bracket character followed only by
        numbers).
\end{enumerate}

While \texttt{texlogsieve} recognizes quite a few messages out of the box,
you may run into a message generated by some package that it does not know
about (you can check for this using \texttt{-l unknown}). If that is the
case, you can use the \verb/--add-[debug|info|warning|critical]-message/
options to add it to the list of messages known to the program.

\section{Configuration File}

\texttt{texlogsieve} always searches automatically for the (optional)
\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}
no-summary-detail
no-page-delay
# no-page-delay enables shipouts, but we do not want that
no-shipouts
set-to-level-info=Hyperreferences in rotated content will be misplaced
# no need to escape the "\" (or any other) character
silence-string = Using \overbracket and \underbracket from `mathtools'
# silence a string using lua pattern matching
silence-string = ////luaotfload | aux : font no %d+ %(.-%)
silence-files = *.sty
\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}
\item[\texttt{-\/-page-delay}, \texttt{-\/-no-page-delay}]~\\
Enable/disable grouping messages by page before display. When enabled, messages
are only output after the current page is finished (shipout). The advantage is
that the page number is included in the message (default enabled).
\end{description}

\begin{description}
\item[\texttt{-\/-summary}, \texttt{-\/-no-summary}]~\\
Enable/disable final summary (default enabled).
\end{description}

\begin{description}
\item[\texttt{-\/-only-summary}]~\\
No messages, show only the final summary (default disabled).
\end{description}

\begin{description}
\item[\texttt{-\/-shipouts}, \texttt{-\/-no-shipouts}]~\\
Enable/disable reporting shipouts (default disabled with page-delay, enabled
with no-page-delay).
\end{description}

\begin{description}
\item[\texttt{-\/-file-banner}, \texttt{-\/-no-file-banner}]~\\
Show/don't show the ``From file\dots'' banner messages (default enabled,
except with level \texttt{DEBUG} as that would be redundant and confusing).
\end{description}

\begin{description}
\item[\texttt{-\/-repetitions}, \texttt{-\/-no-repetitions}]~\\
Allow/prevent repeated messages (default disabled, i.e., repeated messages
are supressed).
\end{description}

\begin{description}
\item[\texttt{-\/-be-redundant}, \texttt{-\/-no-be-redundant}]~\\
Present/suppress ordinary messages that will also appear in the summary.
This affects messages that have special summaries (such as under/overfull
boxes or undefined citations). With \texttt{-\/-no-be-redundant} (the
default), these messages are filtered out and only appear in the final
summary.
\end{description}

\begin{description}
\item[\texttt{-\/-box-detail}, \texttt{-\/-no-box-detail}]~\\
Include/exclude detailed information on under/overfull boxes in the final
summary. With \texttt{-\/-no-box-detail}, the summary presents only a list
of pages and files that had under/overfull boxes (default enabled).
\end{description}

\begin{description}
\item[\texttt{-\/-ref-detail}, \texttt{-\/-no-ref-detail}]~\\
Include/exclude detailed information on undefined references in the final
summary. With \texttt{-\/-no-ref-detail}, the summary presents only a list of
undefined references, without page numbers and filenames (default enabled).
\end{description}

\begin{description}
\item[\texttt{-\/-cite-detail}, \texttt{-\/-no-cite-detail}]~\\
Include/exclude detailed information on undefined citations in the final
summary. With \texttt{-\/-no-cite-detail}, the summary presents only a list
of undefined citations, without page numbers and filenames (default enabled).
\end{description}

\begin{description}
\item[\texttt{-\/-summary-detail}, \texttt{-\/-no-summary-detail}]~\\
Toggle \texttt{-\/-box-detail}, \texttt{-\/-ref-detail}, and
\texttt{-\/-cite-detail} at once.
\end{description}

\begin{description}
\item[\texttt{-\/-heartbeat}, \texttt{-\/-no-heartbeat}]~\\
Enable/disable progress gauge in page-delay mode (default enabled).
\end{description}

\begin{description}
\item[\texttt{-\/-color}, \texttt{-\/-no-color}]~\\
Enable/disable colored output. On Windows, this will only work with
an up-to-date Windows 10 or later (default disabled).
\end{description}

\begin{description}
\item[\texttt{-l LEVEL}, \texttt{-\/-minlevel=LEVEL}]~\\
Filter out messages with severity level lower than \texttt{LEVEL}. Valid
levels are \texttt{DEBUG} (no filtering), \texttt{INFO}, \texttt{WARNING},
\texttt{CRITICAL}, and \texttt{UNKNOWN} (default \texttt{WARNING}).
\end{description}

\begin{description}
\item[\texttt{-u}, \texttt{-\/-unwrap-only}]~\\
Do not filter messages and do not output the summary, only unwrap long,
wrapped lines. The output should be very similar (but not equal) to the
input file, but with wrapped lines reconstructed. This activates
\texttt{-l debug}, \texttt{-\/-no-summary}, \texttt{-\/-no-page-delay},
\texttt{-\/-repetitions}, \texttt{-\/-be-redundant}, \texttt{-\/-shipouts},
and \texttt{-\/-no-file-banner}, and also supresses the verbose ``open/close
file'' and ``shipout'' messages, simulating instead the \TeX{} format, with
parens and square brackets. This is useful if you prefer the reports
generated by some other tool but want to benefit from texlogsieve's line
unwrapping algorithm; the output generated by this option should be
parseable by other tools (but you probably need to coerce the other
tool not to try to unwrap lines).
\end{description}

\begin{description}
\item[\texttt{-\/-silence-package=PKGNAME}]~\\
Filter out messages that can be identified as coming from the given package.
Use this option multiple times to suppress messages from several different
packages.
\end{description}

\begin{description}
\item[\texttt{-\/-silence-string=EXCERPT OF UNWANTED MESSAGE}]~\\
Filter out messages that contain the given string (you only need to provide
part of the message text for the whole message to be suppressed). Use this
option multiple times to suppress several different messages. The string
should be a single line, but that is not a problem for multiline log
messages: space characters in the provided string match any sequence of
whitespace characters in the message, including newlines. If needed, you
may precede the string with ``////'', in which case you can use lua-style
pattern matching (\url{https://www.lua.org/pil/20.2.html}). Note that the
string is used verbatim: you may need to enclose it in quotes or escape
special characters such as ``\textbackslash'' for the benefit of the
shell, but such quoting and escaping is unnecessary (and harmful) in
the configuration file.
\end{description}

\begin{description}
\item[\texttt{-\/-silence-file=FILENAME OR FILE GLOB}]~\\
Filter out messages that have been generated while the given file was being
processed. Do \textbf{not} use absolute or relative paths, only filenames.
Simple file globs, such as ``\texttt{*.cls}'', work as expected. If you are
only using packages you already know, silencing ``\texttt{*.sty}'' may be a
good idea (note that this does not suppress all messages from all packages,
only the messages generated while the packages are being loaded). Use this
option multiple times to suppress messages from several different files.
\end{description}

\begin{description}
\item[\texttt{-\/-semisilence-file=FILENAME OR FILE GLOB}]~\\
Just like the previous option, but non-recursive. This means that messages
generated while the given file was being processed are excluded, but messages
generated by some other file that was opened by it are not. For example,
if ``\texttt{chapters.tex}'' includes (with \textbackslash input) the
files ``\texttt{chapter1.tex}'' and ``\texttt{chapter2.tex}'', using
``\texttt{-\/-silence-file=chapters.tex}'' will prevent messages generated
by any of the three files from being displayed. If, however, you use
``\texttt{-\/-semisilence-file=chapters.tex}'', messages generated by
\texttt{chapters.tex} will be suppressed, but messages generated by
\texttt{chapter1.tex} or \texttt{chapter2.tex} will not.
\end{description}

\begin{description}
\item[\texttt{-\/-add-[debug\textbar info\textbar warning\textbar
      critical]-message=MESSAGE}]~\\
Add \texttt{MESSAGE} to the list of messages known to the program with the
given severity level; see Section \ref{unrecognized} for more information
about this. Like \texttt{-\/-silence-string}, these should be a single line;
unlike \texttt{-\/-silence-string}, you need to embed \verb|\n| explicitly
to indicate line breaks (this is literally a backslash character followed
by the letter ``n'', \textbf{not} a linefeed character). You may precede
the string with ``////'' to use lua-style pattern matching, but embedding
\verb|\n| to indicate line breaks is unavoidable. Use these options multiple
times to add many different messages.
\end{description}

\begin{description}
\item[\texttt{-\/-set-to-level-[debug\textbar info\textbar warning\textbar
      critical]=EXCERPT OF MESSAGE}]~\\
Redefine the severity level of messages that contain the provided string
to the given level. Check the explanation for \texttt{-\/-silence-string},
as this works in a similar way. Use these options multiple times to change
the severity level of many different messages.
\end{description}

\begin{description}
\item[\texttt{-c CFGFILE}, \texttt{-\/-config-file=CFGFILE}]~\\
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}

\begin{description}
\item[\texttt{-\/-version}]
Print program version.
\end{description}

\section{Tips}

\begin{itemize}
  \item If the program output is still too verbose to your liking, resist
  the urge to use \texttt{-l critical} or \texttt{-\/-only-summary}. Instead,
  create a configuration file with \texttt{no-summary-detail} and appropriate
  \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; 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
  -\/-no-shipouts -\/-no-file-banner} to get almost nothing but errors.

  \item With \texttt{latexmk}, it is enough to put something like this in
  \texttt{latexmkrc}:

  \bgroup\small
  \begin{verbatim}
set_tex_cmds("-halt-on-error -interaction nonstopmode %O %S|texlogsieve");\end{verbatim}
  \egroup

  However, this means you get to see the repeated output of all iterations
  needed to produce the document. To only see the output of the last iteration,
  you may do something like this:

  \bgroup\small
  \begin{verbatim}
set_tex_cmds("-halt-on-error %O %S");

$silent = 1; # This adds "-interaction batchmode"
$silence_logfile_warnings = 1;

END {
  local $?; # do not override previous exit status
  if (-s "$root_filename.blg"
              and open my $bibfile, '<', "$root_filename.blg") {

      print("**********************\n");
      print("bibtex/biber messages:\n");
      while(my $line = <$bibfile>) {
          if ($line =~ /You.ve used/) {
              last;
          } else {
              print($line);
          };
      };
      close($bibfile);
  };

  if (-s "$root_filename.ilg"
              and open my $indfile, '<', "$root_filename.ilg") {

      print("*************************\n");
      print("makeindex/xindy messages:\n");
      while(my $line = <$indfile>) {
          print($line);
      };
      close($indfile);
  };

  if (-s "$root_filename.log") {
      print("***************\n");
      print("LaTeX messages:\n");
      Run_subst("texlogsieve %R.log");
  };
};\end{verbatim}
  \egroup
\end{itemize}

\section{License}

Copyright © 2021, 2022 Nelson Lago \textless lago@ime.usp.br\textgreater\\
License GPLv3+: GNU GPL version 3 or later
\url{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.

\PrintChanges

\end{document}