Übergeben von Makroargumenten (# 1, # 2, ..) an Lua-Variablen

Oct 05 2020

Diese Frage ist wahrscheinlich trivial, aber ich habe vor ein paar Stunden angefangen, Lua (La) TeX zu erkunden.

Die MWE ist die folgende:

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("}")

Ich weiß, dass ich \newcommanddie texDatei einfügen und dann directluadie Befehlsdefinition aufrufen kann , aber in meinem tatsächlichen Anwendungsfall durchlaufe ich eine Tabelle, in der die Schlüssel die Befehlsnamen sind, also muss ich das so lassen, wie es ist.

BEARBEITEN : Da meine anfängliche Frage möglicherweise ein XY-Problem war, veröffentliche ich unten meinen tatsächlichen Anwendungsfall.

Mein Ziel ist es, anhand einer Reihe von Theoremumgebungen, die im thmtoolsPaket definiert sind, diese neu zu definieren, indem sie in eine tcolorboxUmgebung eingebettet werden .

Ich begann dies über zu tun, wurde expl3aber sehr schnell frustriert, teils wegen meiner Inkompetenz in der LaTeX3-Programmierweise, teils weil die Programmierung in LaTeX im Vergleich zu jeder anderen "normalen" Programmiersprache (für Schleifen, if-Anweisungen usw.) So schmerzhaft ist. ), weshalb begonnen wird, tiefer in LuaTeX einzutauchen.

Nun zum Code. Ich habe diesen Tisch

boxed_theorems = {
  definition = "definition",
  example = "example",
  lemma = "theorem",
  theorem = "theorem",
  corollary = "theorem",
  proof = "proof",
}

wo die Schlüssel sind umwelt Namen (wieder aus thmtools kommen), und die Werte sind tcolorboxOptionen (hier definition, example, theoremund proofsind ein Haufen von tcolorbox Stile.

Die Art und Weise, wie ich diese Tabelle (und den Rest der über eingeschlossenen .lua-Datei \directlua) durchlaufe, ist die folgende:

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")

Antworten

1 Mico Oct 05 2020 at 20:05

Ich denke, es ist einfacher, LaTeX-Makros in der .tex-Datei einzurichten und den Lua-Code in Funktionen zu gruppieren, die Argumente akzeptieren und zurückgeben können.

ZB test.texkönnte wie folgt sein:

\documentclass{article}
\directlua{require("test.lua")}
\newcommand\foo[1]{\directlua{foo("#1")}}
\begin{document}
\foo{bar}
\end{document}

während test.luakönnte enthalten

function foo ( s )
   tex.sprint ( "\\textit{"..s.."}" )
end
DavidCarlisle Oct 05 2020 at 20:34

Beachten Sie, dass die von akkumulierten Zeichenfolgen tex.printerst nach Abschluss des Lua-Blocks an TeX zurückgegeben werden, sodass an dem Punkt, der #1als Argument verarbeitet wird, kein Lua aktiv ist bar. Um Ihre Frage wie geschrieben zu beantworten, müssen Sie Lua an diesem Punkt erneut eingeben, wie hier gezeigt.

Dies wird gedruckt

arg is: barbaz

Von Lua wurde das Zeigen der Schnur baran Lua weitergegeben.

und setzt dies, was meiner Meinung nach Ihre beabsichtigte Ausgabe ist.

Dies ist jedoch mit ziemlicher Sicherheit nicht der beste Weg, um sich Ihrem tatsächlichen Anwendungsfall zu nähern.

\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("}")