# About verbatim in LaTeX (and LuaTeX)

What I intend to do...

Initially, I wanted to write a series of environments that help me typeset verbatim environments. For example, I would like

\begin{myverb}{stylea}
\end{myverb}


to be equivalent to:

\begin{minted}{fontsize=\small, bgcolor=white}
\end{minted}


Essentially, each key corresponds to a specific combination of parameters for minted (or any other verbatim) environment. However, due to special implementations of verbatim environments in LaTeX, I realize that there is no easy way of doing this. By far, I only know two possible approaches:

1. Use tcblisting+minted with a self-defined style and use \tcbset to change it programmatically.
2. Save the entire verbatim environment as file and read with \input.

(I skimmed through tcblisting's source code, maybe these two approaches are fundamentally the same?)

Even though I think I have found a way of achieving my goals, I still want to ask the following questions because I am unable to explain many phenomena that happened throughout my own experiments. Please pardon my weak understandings on TeX and LuaTeX mechanisms.

My specific questions

1. From my understanding, by saving the verbatim environment into files, we are able to decouple our code from regular TeX parsing routine. In this case, the alternative outlet is the file system. In LuaTeX, another scripting engine (i.e. Lua) is introduced apart from TeX engine. I would like to know if it is possible to use LuaTeX to do this directly, without the need of file system I/O? Using tex.print does not work work as expected (see question 2). Essentially, is it possible for LuaTeX to \input from Lua strings, instead of files?

2. Why does the first one work but the second doesn't?

% https://tex.stackexchange.com/questions/410481/verbatim-with-direct-lua/410482#410482
\directlua{tex.print([[\unexpanded{\begin{verbatim}]]..'one\rtwo'..[[\end{verbatim}}]])}

% using minted package
\directlua{tex.print([[\unexpanded{\begin{minted}{python}]]..'one\rtwo'..[[\end{minted}}]])}

1. Why does tcblisting work with minted back-end?
% using minted via tcblisting
\directlua{tex.print([[\unexpanded{\begin{tcblisting}{listing engine=minted, minted language=python}]]..'one\rtwo'..[[\end{tcblisting}}]])}

1. Why does \directlua work but luacode* doesn't?
\directlua{
tex.print([[\unexpanded{\begin{verbatim}abc\end{verbatim}}]])
}

\begin{luacode*}
tex.print([[\unexpanded{\begin{verbatim}abc\end{verbatim}}]])
\end{luacode*}


Possible preamble

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{verbatim}
\usepackage{luacode}
\usepackage{minted}
\usepackage{tcolorbox}

\tcbuselibrary{listings, minted}


After reading the LuaTeX reference, I realize that it is possible to directly \input from Lua strings. The key is to override find_read_file and open_read_file callbacks, which allows us to write our own back-end for \input commands. For details, please see the code below.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{verbatim}
\usepackage{luacode, luatexbase}
\usepackage{tcolorbox}
\usepackage{minted}
\usepackage{datetime2}
\usepackage{expl3}
\usepackage{minted}

\tcbuselibrary{listings, minted}

\begin{document}

\begin{luacode*}
TeXFileBuffer = {content={}, finished=false}

function TeXFileBuffer:new()
o = {}
setmetatable(o, self)
self.__index = self
return o
end

function TeXFileBuffer:clear()
while #self.content ~= 0 do rawset(self.content, #self.content, nil) end
end

function TeXFileBuffer:content_to_string()
return table.concat(self.content, "")
end

function TeXFileBuffer:use()
tex.write(self:content_to_string())
end

function TeXFileBuffer:append(data)
table.insert(self.content, data)
end

function TeXFileBuffer:append_carriage_return(data)
self:append("\r")
end

function _tex_buffer_remove_callback(name, description)
for k, v in pairs(luatexbase.callback_descriptions(name)) do
if v == description then
texio.write("\nsafely removing callback " .. name .. " : " .. description)
luatexbase.remove_from_callback(name, description)
end
end
end

function tex_buffer_remove_callback()
end

local ret = nil
if not env["finished"] then
ret = env["content"]
env["finished"] = true
-- remove callback immediately
tex_buffer_remove_callback()
end
return ret
end

-- arguments and return value doesn't matter
texio.write("\nTeXFileBuffer tries to find ".. asked_name .. " id=" .. id_number)
end

function TeXFileBuffer:register_callback()
tex_file_buffer_read = function (filename)
local env = {}
texio.write("\nTeXFileBuffer opens ".. filename)
env["finished"] = false
env["content"] = self:content_to_string()
return env
end

-- register callback
end

-- create a TeXFilebuffer instance
tex_file_buffer = TeXFileBuffer:new()
\end{luacode*}

\makeatletter
\newcommand{\TFBInputAsFile}{
\directlua{tex_file_buffer:register_callback()}
% read some random file, which automatically removes the callback

% \input will do an file existance check before actually reading it.
% therefore, if using LaTeX's input, random-file will be opned twice
% here, I am using TeX's \@@input primitive instead
\@@input randomfile
}
\makeatother

\newcommand{\TFBAppend}[1]{
\directlua{tex_file_buffer:append("\luaescapestring{\unexpanded{#1}}")}
}

\newcommand{\TFBAppendCR}{
\directlua{tex_file_buffer:append_carriage_return()}
}

\newcommand{\TFBClear}{
\directlua{tex_file_buffer:clear()}
}

\newcommand{\TFBUse}{
\directlua{tex_file_buffer:use()}
}

\ExplSyntaxOn

\str_clear:N \l_tmpa_str
\exp_args:Nx \TFBAppend {\c_backslash_str begin{minted}{python}} \TFBAppendCR
\exp_args:Nx \TFBAppend {print("abc")} \TFBAppendCR
\exp_args:Nx \TFBAppend {\c_backslash_str end{minted}}

\ExplSyntaxOff

\TFBUse
\TFBInputAsFile

\par\DTMNow

\end{document}


The output document looks like this:

I am not sure how much performance gain this solution has compared to file system I/O.