0

While compiling Latex source file

\documentclass{article}

\ExplSyntaxOn \tl_new:N \l_test_value_tl \tl_set:Nn \l_test_value_tl {It's~a~test~value} \tl_show:N \l_test_value_tl \ExplSyntaxOff

\begin{document} It's an example. \end{document}

I'm getting an error without any details

pdflatex -interaction=nonstopmode -halt-on-error temp.tex
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (MiKTeX 23.12) (preloaded format=pdflatex.fmt)
 restricted \write18 enabled.
entering extended mode
(temp.tex
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-04>
(C:\Users\User\AppData\Local\Programs\MiKTeX\tex/latex/base\article.cls
Document Class: article 2023/05/17 v1.4n Standard LaTeX document class
(C:\Users\User\AppData\Local\Programs\MiKTeX\tex/latex/base\size10.clo))
> \l_test_value_tl=It's a test value.
<recently read> }

l.6 \tl_show:N \l_test_value_tl

! ==> Fatal error occurred, no output PDF file produced! Transcript written on temp.log.```

But if comment out \tl_show macro

\documentclass{article}

\ExplSyntaxOn \tl_new:N \l_test_value_tl \tl_set:Nn \l_test_value_tl {It's~a~test~value} %\tl_show:N \l_test_value_tl \ExplSyntaxOff

\begin{document} It's an example. \end{document}

the file is compiled without any errors and pdf is produced

pdflatex -interaction=nonstopmode -halt-on-error temp.tex
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (MiKTeX 23.12) (preloaded format=pdflatex.fmt)
 restricted \write18 enabled.
entering extended mode
(temp.tex
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-04>
(C:\Users\User\AppData\Local\Programs\MiKTeX\tex/latex/base\article.cls
Document Class: article 2023/05/17 v1.4n Standard LaTeX document class
(C:\Users\User\AppData\Local\Programs\MiKTeX\tex/latex/base\size10.clo))
(C:\Users\User\AppData\Local\Programs\MiKTeX\tex/latex/l3backend\l3backend-pd
ftex.def)
No file temp.aux.
[1{C:/Users/User/AppData/Local/MiKTeX/fonts/map/pdftex/pdftex.map}] (temp.aux
) )<C:/Users/User/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/c
m/cmr10.pfb>
Output written on temp.pdf (1 page, 14234 bytes).
Transcript written on temp.log.

The same problem is for other simular macros \str_show, \int_show etc.

Is this expected behaviour or I'm doing something wrong? Does anyone have an idea what could be the reason of this error?

1 Answers1

1

After some investigation I've found what is the reason of the problem above and can answer my own question myself :-).

It turned out macros for output values of variables to a terminal and a log file (\tl_show, \str_show, \int_show etc) are implemented using TeX error message mechanism. It means that pdflatex (even without -halt-on-error option) still returns a non-zero exit code and any build utilite (latexmk) or IDE calling pdflatex will be notifying about a build error. For example in case of VSCode + LaTeX-Workshop it looks like below

enter image description here

More detail about it can read here Using \show in nonstopmode causes TeXmaker to raise false alarms. Any fix?. Here How can I make TeX stop on the first error, but do not stop on \show (or \tl_show:n)? is advised how to avoid such behaviour.

It seemed the most suitable way for me is a reimplementation of macros for output values of variables to terminal. After some effort I've got following package

\RequirePackage{expl3}
\ProvidesExplPackage{DebugTools}{}{}{}

\cs_new:Npn __start_label: { [DEBUG~INFO]:[line= \int_use:N \inputlineno]:~ }

%-------------------------------------------------------------------------------------------------- % Functions for output debug info in terminal and log %--------------------------------------------------------------------------------------------------

\cs_new_protected:Npn \show:n #1 { \iow_term:e {#1} }

\cs_new_protected:Npn \show_sep: { \iow_term:n {----------------------------------------------------------------------------------------------------} }

\cs_new_protected:Npn \show_head:n #1 { \show_sep: \show:n {#1} \show_sep: }

\cs_new_protected:Npn \show_val:n #1 { \iow_term:e {__start_label: #1} }

\cs_new_protected:Npn \show_tl:N #1 { \iow_term:e {__start_label: \exp_not:N #1 =~ \tl_use:N #1} }

\cs_new_protected:Npn \show_str:N #1 { \iow_term:e {__start_label: \exp_not:N #1 =~ \str_use:N #1} }

\cs_new_protected:Npn \show_bool:N #1 { \iow_term:e {__start_label: \exp_not:N #1 =~ \bool_to_str:N #1} }

\cs_new_protected:Npn \show_int:N #1 { \iow_term:e {__start_label: \exp_not:N #1 =~ \int_use:N #1} }

\cs_new_protected:Npn \show_dim:N #1 { \iow_term:e {__start_label: \exp_not:N #1 =~ \dim_use:N #1} }

\cs_new_protected:Npn \show_clist:N #1 { \iow_term:e {__start_label: \exp_not:N #1 =~ {\clist_use:Nn #1 {,}}} }

%-------------------------------------------------------------------------------------------------- % Functions for output debug info in log %--------------------------------------------------------------------------------------------------

\cs_new_protected:Npn \log:n #1 { \iow_log:e {#1} }

\cs_new_protected:Npn \log_sep: { \iow_log:n {----------------------------------------------------------------------------------------------------} }

\cs_new_protected:Npn \log_head:n #1 { \log_sep: \log:n {#1} \log_sep: }

\cs_new_protected:Npn \log_val:n #1 { \iow_log:e {__start_label: #1} }

\cs_new_protected:Npn \log_tl:N #1 { \iow_log:e {__start_label: \exp_not:N #1 =~ \tl_use:N #1} }

\cs_new_protected:Npn \log_str:N #1 { \iow_log:e {__start_label: \exp_not:N #1 =~ \str_use:N #1} }

\cs_new_protected:Npn \log_bool:N #1 { \iow_log:e {__start_label: \exp_not:N #1 =~ \bool_to_str:N #1} }

\cs_new_protected:Npn \log_int:N #1 { \iow_log:e {__start_label: \exp_not:N #1 =~ \int_use:N #1} }

\cs_new_protected:Npn \log_dim:N #1 { \iow_log:e {__start_label: \exp_not:N #1 =~ \dim_use:N #1} }

\cs_new_protected:Npn \log_clist:N #1 { \iow_log:e {__start_label: \exp_not:N #1 =~ {\clist_use:Nn #1 {,}}} }

\endinput

with demo LaTeX source file

\documentclass{article}
\usepackage{DebugTools}

\ExplSyntaxOn \tl_new:N \l_test_value_tl \tl_set:Nn \l_test_value_tl {It's~a~test~value} \str_new:N \l_test_value_str \str_set:Nn \l_test_value_str {It's~a~test~value} \bool_new:N \l_test_value_bool \bool_set_true:N \l_test_value_bool \int_new:N \l_test_value_int \int_set:Nn \l_test_value_int {101} \dim_new:N \l_test_value_dim \dim_set:Nn \l_test_value_dim {-2.5pt} \clist_new:N \l_test_value_clist \clist_set:Nn \l_test_value_clist {a,b,3,c,5}

\show_head:n {DEBUG~INFO~FOR~TERMINAL~AND~LOG} \show_val:n {It's~a~test~value} \show_tl:N \l_test_value_tl \show_str:N \l_test_value_str \show_bool:N \l_test_value_bool \show_int:N \l_test_value_int \show_dim:N \l_test_value_dim \show_clist:N \l_test_value_clist \show_sep:

\log_head:n {DEBUG~INFO~FOR~LOG} \log_val:n {It's~a~test~value} \log_tl:N \l_test_value_tl \log_str:N \l_test_value_str \log_bool:N \l_test_value_bool \log_int:N \l_test_value_int \log_dim:N \l_test_value_dim \log_clist:N \l_test_value_clist \log_sep: \ExplSyntaxOff

\begin{document} It's an example. \end{document}

Now it's compiled without any error notifications and looks fine for my aims

enter image description here

UPDATE

Answering the question in comments I'd like to explain more detail why standard \..._show:N and \...log:N are not good for me.

\..._show:N produces following output to a terminal and a log file

> \l_test_value_tl=It's a test value.
<recently read> }

l.6 \tl_show:N \l_test_value_tl

and has next pros and cons:

Pros

  • The output is enough detail and contains the line number to easy search of a place in a source file where was produced this output.

Cons

  • The macro forces pdflatex to return a non-zero exit code what causes a build error notification in IDE.

\..._log:N produces following output only to a log file

> \l_test_value_tl=It's a test value.

and has next pros and cons:

Pros

  • The macro doesn't cause a build error notification in IDE

Cons

  • The output doesn't contain any line numbers.

Beside of this I prefer to use \..._show:N to see debug info in terminal output immediately instead of opening a log file each time after build (it's a bit annoyng).

So, I've reimplemented macros in order to achive following goals:

  • to avoid any build error notifications in IDE for \..._show:N
  • to make output format for \..._show:N and \..._log:N the same, which in addition to a variable and its value also would contain some label (to easy search of debug info in a build output) and a line number (to easy search of a place in a source file where was produced this debug info).