gpoore / minted

minted is a LaTeX package that provides syntax highlighting using the Pygments library. Highlighted source code can be customized using fancyvrb.
1.73k stars 125 forks source link

problems with escapeinside and --enable-pipes #370

Closed emeth69 closed 9 months ago

emeth69 commented 10 months ago

Dear Minted Experts, I'm trying to run some (linux) commands insides a minted piece of code without success.

This is a MWE

\documentclass[9pt,xcolor=svgnames]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[scaled=.90]{beramono}

\usepackage{filecontents} % to overwrite generated files

\usepackage[cachedir=.\jobname-cache]{minted}

\setminted{fontfamily=tt,fontsize=\footnotesize,encoding=utf8,style=trac,escapeinside=``}

\begin{filecontents*}[overwrite]{/tmp/escapeinside-bug.txt}
  `\makeatletter\@@input|"scalac -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*'"\makeatother`

  `\input{|"ocamlc -version"}`

  `\immediate\write18{ocamlc -version > /tmp/ocaml-version.txt}
  \input /tmp/ocaml-version.txt`

  `\input "|date "`
\end{filecontents*}

\begin{document}

  \textcolor{red}{Out Minted}

  \makeatletter\@@input|"scalac -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*'"\makeatother

  \input{|"eval $(which ocaml) -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*'"}

  \immediate\write18{ocamlc -version > /tmp/ocaml-version.txt}
  \input /tmp/ocaml-version.txt

  \input "|date "

  \bigskip

  \textcolor{red}{In Minted}

  \inputminted{shell-session}{/tmp/escapeinside-bug.txt}%

\end{document}

The MWE shows different ways to run linux commands both in plain LaTeX and through a minted piece of code.

When I compile it with: openout_any=a pdflatex --enable-pipes --shell-escape MWE.tex I get:

pdflatex: unrecognized option '--enables-pipes'
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex)
 \write18 enabled.
entering extended mode
(./escapeinfo-bug.tex
LaTeX2e <2022-11-01> patch level 1
L3 programming layer <2023-02-22>
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/article.cls
Document Class: article 2022/07/02 v1.4n Standard LaTeX document class
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/size10.clo))
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/inputenc.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/fontenc.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/bera/beramono.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/keyval.sty))
(/usr/local/texlive/2022/texmf-dist/tex/latex/filecontents/filecontents.sty

Package filecontents Warning: This package is obsolete. Disabling it and
(filecontents)                passing control to the filecontents environment
(filecontents)                defined by the LaTeX kernel.

) (/usr/local/texlive/2022/texmf-dist/tex/latex/minted/minted.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/kvoptions/kvoptions.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/kvsetkeys/kvsetkeys.sty))
(/usr/local/texlive/2022/texmf-dist/tex/latex/fvextra/fvextra.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/etoolbox/etoolbox.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/fancyvrb/fancyvrb.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/upquote/upquote.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/textcomp.sty))
(/usr/local/texlive/2022/texmf-dist/tex/latex/lineno/lineno.sty))
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/ifthen.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/tools/calc.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/tools/shellesc.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/ifplatform/ifplatform.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/infwarerr/infwarerr.sty)
(/usr/local/texlive/2022/texmf-dist/tex/generic/iftex/iftex.sty))
(/usr/local/texlive/2022/texmf-dist/tex/generic/catchfile/catchfile.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/etexcmds/etexcmds.sty))
(/usr/local/texlive/2022/texmf-dist/tex/generic/iftex/ifluatex.sty)
(./escapeinfo-bug.w18))
(/usr/local/texlive/2022/texmf-dist/tex/generic/xstring/xstring.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/xstring/xstring.tex))
(/usr/local/texlive/2022/texmf-dist/tex/latex/framed/framed.sty)
(/usr/local/texlive/2022/texmf-dist/tex/latex/float/float.sty))

LaTeX Warning: Writing or overwriting file `.//tmp/escapeinside-bug.txt'.

(/usr/local/texlive/2022/texmf-dist/tex/latex/xcolor/xcolor.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/color.cfg)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-def/pdftex.def)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/mathcolor.ltx))/usr/local/bin/pygmentize

(/usr/local/texlive/2022/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)

LaTeX Warning: Unused global option(s):
    [9pt,xcolor].

(./escapeinfo-bug.aux)
(/usr/local/texlive/2022/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
) (|scalac -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*')warning: kpathsea: |eval $(which ocaml) -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*': Unrecognized variable construct `$('.
warning: kpathsea: |eval $(which ocaml) -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*': Unrecognized variable construct `$('.

(|eval $(which ocaml) -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digi
t:]]*') (/tmp/ocaml-version.txt) (|date )
(./.escapeinfo-bug-cache/trac.pygstyle)
(./.escapeinfo-bug-cache/A4B99271E89E8B7F653733DCA2F2CF79388B2B1571C3667151961A
8AD2F1804B.pygtex (/usr/local/texlive/2022/texmf-dist/tex/latex/bera/t1fvm.fd)
(/usr/local/texlive/2022/texmf-dist/tex/latex/bera/ts1fvm.fd)
! Missing endcsname inserted.
<to be read again> 

l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Use of ??? doesn't match its definition.
<argument> ???  
                ! LaTeX Error:  invalid in file name. Lost: -version".
l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Use of ??? doesn't match its definition.
<argument> ???  
                ! LaTeX Error: Unbalanced quotes in file name '|"ocamlc'.
l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Missing endcsname inserted.
<to be read again> 

l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Use of ??? doesn't match its definition.
<argument> ???  
                ! LaTeX Error:  invalid in file name. Lost: -version".
l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Use of ??? doesn't match its definition.
<argument> ???  
                ! LaTeX Error: Unbalanced quotes in file name '|"ocamlc'.
l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Missing endcsname inserted.
<to be read again> 

l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Use of ??? doesn't match its definition.
<argument> ???  
                ! LaTeX Error:  invalid in file name. Lost: -version".
l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? ! Use of ??? doesn't match its definition.
<argument> ???  
                ! LaTeX Error: Unbalanced quotes in file name '|"ocamlc'.
l.4 ...o}{  }\PYG{esc}{\input{|"ocamlc -version"}}

? (|ocamlc)sh: -c: line 1: unexpected EOF while looking for matching ``'
sh: -c: line 2: syntax error: unexpected end of file
system returned with code 512
 (/usr/local/texlive/2022/texmf-dist/tex/latex/tools/.tex
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/t1cmtt.fd)
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/ts1cmtt.fd) File\ ignored)
(/usr/local/texlive/2022/texmf-dist/tex/latex/tools/.tex File\ ignored))
[1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
(./escapeinfo-bug.aux) ){/usr/local/texlive/2022/texmf-dist/fonts/enc/dvips/cm-
super/cm-super-ts1.enc}{/usr/local/texlive/2022/texmf-dist/fonts/enc/dvips/base
/8r.enc}{/usr/local/texlive/2022/texmf-dist/fonts/enc/dvips/cm-super/cm-super-t
1.enc}</usr/local/exts/texmf/fonts/type1/public/bera/fvmr8a.pfb></usr/local/tex
live/2022/texmf-dist/fonts/type1/public/cm-super/sfrm1000.pfb></usr/local/texli
ve/2022/texmf-dist/fonts/type1/public/cm-super/sftt0800.pfb>
Output written on escapeinfo-bug.pdf (1 page, 43663 bytes).
Transcript written on escapeinfo-bug.log.

All the approaches work perfectly when in normal LaTeX (in spite of the error message about --enable-pipes) but they fail when I escape from \inputminted. I have tried different escape characters without any lucky.

I'm using pygmentize 2.16.1, minted v2.7, pdfTeX 3.141592653-2.6-1.40.24 and kpathsea version 6.3.4.

Any help is appreciated.

Thank you

gpoore commented 10 months ago

minted is intended for typesetting code, not running code. escapeinside allows small snippets of LaTeX code to be included within computer code that is otherwise typeset verbatim. It is not intended for \input{|...} or \write18.

I'd suggest saving the output of each of your \input{|...} or \write18 in a file, and then \inputminted those files individually.

emeth69 commented 10 months ago

Unfortunately to write to a file doesn't work in my scenario. I'd like to keep the version of a REPL that I'm showing aligned with the version of the REPL installed. So most of the code will be the same but just few characters depends on where the document is compiled.

gpoore commented 10 months ago

What I'm suggesting is extending what you are doing in

  \immediate\write18{ocamlc -version > /tmp/ocaml-version.txt}
  \input /tmp/ocaml-version.txt

to the other programs. That is, use \input{|...} or \write18 to run your external program, but then save/redirect the output into a file. Then \inputminted that file (if you really need some kind of minted formatting). This should get you current version info without running into incompatibilities with trying to run code within minted. For \input{|...}, you could probably use some shell scripting to wrap your version number with \mint or \mintinline like \mint{<lang>}{<version>} and skip the temp file altogether.

emeth69 commented 10 months ago

Hi, this doesn't work but maybe I didn't got you hint correctly:

\documentclass[9pt,xcolor=svgnames]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[scaled=.90]{beramono}

\usepackage{filecontents} % to overwrite generated files

\usepackage[cachedir=.\jobname-cache]{minted}

\setminted{fontfamily=tt,fontsize=\footnotesize,encoding=utf8,style=trac,escapeinside=``}

\begin{filecontents*}[overwrite]{/tmp/escapeinside-bug.txt}
  `\immediate\write18{scalac -version > /tmp/ocaml-version.txt}
   \input /tmp/ocaml-version.txt`
\end{filecontents*}

\begin{document}

  \textcolor{red}{In Minted}

  \inputminted{shell-session}{/tmp/escapeinside-bug.txt}%

\end{document}

It compiles but it prints: %%%% This is file `.tex',%% generated with the docstrip utility.%%%% The original source files were:%%%% fil... even if the included files contains 4.12.0

Furthermore if I try to pipe the result of the command to grep some specific portions (as in | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*' ) I get:

! TeX capacity exceeded, sorry [input stack size=10000].
\curr@fontshape ->\f@encoding 
                              /\f@family /\f@series /\f@shape 
l.2 ...*[.][[:digit:]]*'> /tmp/ocaml-version.txt}}

!  ==> Fatal error occurred, no output PDF file produced!

I did something wrong?

gpoore commented 10 months ago

That is still trying to mix minted with executable code.

Why not just use

\immediate\write18{scalac -version > /tmp/ocaml-version.txt}
\input /tmp/ocaml-version.txt

or something similar directly? If you want a different font or text color, you can always add a \textcolor or texttt command around the inputed version.

emeth69 commented 10 months ago

Because my MWE shows just the critical part of the what I'm passing to minted. In the real case I'm passing to minted a complete program (a REPL session transcript to be honest) where only a small portion is changed by my command. In my view to put the whole transcript in the post was too much but if you think it can help I can post it. Sorry for the confusion.

gpoore commented 10 months ago

I don't have any more suggestions for this. minted can't really emulate a REPL by mixing in \write18, so you'll have to find another way to do what you want.

emeth69 commented 9 months ago

This message is just for those coming here with the same problem. I have solved it:

\documentclass[9pt,xcolor=svgnames]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[scaled=.90]{beramono}

\usepackage{filecontents} % to overwrite generated files

\usepackage[cachedir=.\jobname-cache]{minted}

\setminted{fontfamily=tt,fontsize=\footnotesize,encoding=utf8,style=trac,escapeinside=``}

\begin{filecontents*}[overwrite]{/tmp/escapeinside-bug.txt}
   `!/tmp/version.txt!`
\end{filecontents*}

\immediate\write18{scalac -version | grep -o '[[:digit:]]*[.][[:digit:]]*[.][[:digit:]]*'> /tmp/version.txt}

\begin{document}
  \begingroup
  \catcode`\!=\active
  \def!#1!{\input #1}
  \inputminted{shell-session}{/tmp/escapeinside-bug.txt}%
  \endgroup
\end{document}

There are few limitations in this solution, e.g., the file name can't contain a -, you have to enable pdflatex to write out of the current dir,... but this is a good starting point.