Comment passer des arguments de macro (# 1, # 2, ..) aux variables Lua
Cette question est probablement triviale, mais j'ai commencé à explorer Lua (La) TeX il y a quelques heures, alors soyez patient.
Le MWE est le suivant:
test.tex:
\documentclass{article}
\directlua{require("test.lua")}
\begin{document}
\foo{bar}
\end{document}
test.lua:
tex.print("\\newcommand{\\foo}[1]{")
tex.print("\\texttt{#1}")
-- arg = ?? how do I pass #1 to arg ??
-- arg = arg .. " baz"
-- tex.print("\\textit{" .. arg .. "}")
tex.print("}")
Je sais que je pourrais mettre \newcommanddans le texfichier, puis appeler directluala définition de commande, mais dans mon cas d'utilisation réel, je boucle sur une table où les clés sont les noms de commande, je dois donc laisser cela tel quel.
EDIT : Comme ma question initiale aurait pu être un peu un problème XY, je publie mon cas d'utilisation réel ci-dessous.
Mon objectif est: étant donné un tas d'environnements de théorèmes définis par le thmtoolspackage, les redéfinir en les intégrant dans un tcolorboxenvironnement.
J'ai commencé à faire cela via expl3mais j'ai été très vite frustré, en partie à cause de mon incompétence dans la manière de programmer LaTeX3, en partie parce que la programmation en LaTeX est si pénible par rapport à tout autre langage de programmation "normal" (pour les boucles, les instructions if, etc. ), c'est pourquoi on commence à plonger plus profondément dans LuaTeX.
Passons maintenant au code. J'ai cette table
boxed_theorems = {
definition = "definition",
example = "example",
lemma = "theorem",
theorem = "theorem",
corollary = "theorem",
proof = "proof",
}
où les clés sont des noms de l' environnement (encore une fois, en provenance de thmtools), et les valeurs sont les tcolorboxoptions (ici definition, example, theoremet proofsont un tas de styles de tcolorbox.
La façon dont je boucle sur cette table (et le reste du fichier .lua inclus via \directlua) est la suivante:
tex.print("\\ExplSyntaxOn")
for theorem,tcolorbox_theorem in pairs(boxed_theorems) do
-- copy <theorem_name> in a new environment inner<theorem_name>
tex.print("\\let\\inner" .. theorem .. "\\" .. theorem)
tex.print("\\let\\endinner" .. theorem .. "\\end" .. theorem)
tex.print("\\RenewDocumentEnvironment{ " .. theorem .. " }{ O{} }{")
-- I want to be able to call the new environment like this:
--
-- \begin{theorem}[name={foo}, label={bar}, tcolorbox={baz}]
--
-- where 'name={foo}, label={bar}' is the argument of the
-- innertheorem and should be assigned to 'theorem_options',
-- while '{baz}' is an argument of the embedding tcolorbox and
-- should be assigned to 'tcolorbox_local'.
-- I haven't got that far yet (I need to create a function that
-- parses #1, hence the original post), so for now they are just
-- left empty.
theorem_options = ""
tcolorbox_local = ""
-- The rest is pretty self-explanatory
tex.print("\\begin{tcolorbox}[" .. tcolorbox_theorem .. ","
.. tcolorbox_local .. "]")
if theorem_options == "" then
tex.print("\\begin{inner" .. theorem .. "}")
else
tex.print("\\begin{inner" .. theorem .. "}[" .. theorem_options .. "]")
end
tex.print("}{")
tex.print("\\end{inner" .. theorem .. "}")
tex.print("\\end{tcolorbox}")
tex.print("}")
end
tex.print("\\ExplSyntaxOff")
Réponses
Je pense qu'il est plus simple de configurer des macros LaTeX dans le fichier .tex et de regrouper le code Lua dans des fonctions qui peuvent accepter et renvoyer des arguments.
Par exemple, test.texpourrait être comme suit:
\documentclass{article}
\directlua{require("test.lua")}
\newcommand\foo[1]{\directlua{foo("#1")}}
\begin{document}
\foo{bar}
\end{document}
tandis que test.luapourrait contenir
function foo ( s )
tex.sprint ( "\\textit{"..s.."}" )
end
Notez que les chaînes accumulées par tex.printne sont pas renvoyées à TeX tant que le bloc Lua n'est pas terminé, il n'y a donc pas de Lua actif au point #1traité comme argument bar. Donc, pour répondre à votre question telle qu'elle est écrite, vous devez entrer à nouveau dans Lua à ce stade, comme indiqué ici.
cela imprime
arg is: barbaz
De Lua, montrant que la chaîne a barété passée à Lua.
et compose ceci, qui est je pense votre sortie prévue.
Cependant, ce n'est certainement pas la meilleure façon d'aborder votre cas d'utilisation réel.
\documentclass{article}
\directlua{require("test.lua")}
\begin{document}
\foo{bar}
\directlua{
texio.write_nl('arg is: ' .. arg .. '\string\n')
}
\end{document}
test.lua
tex.print("\\newcommand{\\foo}[1]{")
tex.print("\\texttt{#1}")
tex.print("\\directlua{arg='#1' arg = arg .. 'baz' tex.print('\\\\textit{' .. arg .. '}')}")
tex.print("}")