How to pass verbatim input (contained in an environment) to a Lua function
\documentclass{article} | |
\usepackage{ixbase-spenv} | |
\usepackage{luacode} | |
\DeclareStringProcessEnvironment{makeshorthands}[2]{% | |
\directlua{ | |
make_shorthands(\luastring{#1}, \luastring{#2}) | |
} | |
} | |
\begin{luacode*} | |
shorthands = {} | |
function make_shorthands (prefix, datatable) | |
for _, row in ipairs(datatable:explode("\r+")) do | |
local key, val = row:gsub("%s.*#.*", ""):match("^%s*(%a+)=(.*)$") | |
if not key then error("bad line: "..row) end | |
local csname = "\\"..prefix..key | |
tex.sprint("\\newcommand*{", csname, "}{", val, "}") | |
end | |
end | |
\end{luacode*} | |
\begin{document} | |
% makeshorthands の用例 | |
\begin{makeshorthands}{logo} | |
luatex=Lua\TeX | |
lualatex=Lua\LaTeX | |
context=Con{\TeX}t # not have 'Lua' in name | |
texinfo=Texinfo # yeah! ^^; | |
\end{makeshorthands} | |
This is \logolualatex! ?\logotexinfo? | |
\end{document} |
% | |
% ixbase-spenv.sty | |
% | |
%% package declaration | |
\NeedsTeXFormat{LaTeX2e} | |
\ProvidesPackage{ixbase-spenv}[2012/05/02 v0.2a] | |
%% preparation | |
\def\ixbag@pkgname{ixbase-spenv} | |
\def\ixbag@error{\PackageError\ixbag@pkgname} | |
% engine check | |
\RequirePackage{ifluatex} | |
\ifluatex\else | |
\ixbag@error{LuaTeX is required} | |
{Package loading is aborted right now.} | |
\expandafter\endinput\fi\relax | |
\ifnum\luatexversion<65 | |
\ixbag@error{This LuaTeX is too old} | |
{This package requires LuaTeX v0.65 or higher.\MessageBreak | |
Package loading is aborted right now.} | |
\expandafter\endinput\fi\relax | |
% prerequisite packages | |
\RequirePackage{etoolbox} | |
\RequirePackage{luatexbase-regs} | |
\RequirePackage{luatexbase-cctb} | |
% | |
\edef\ixbag@restore@codes{% | |
\catcode33=\the\catcode33%<"> | |
\catcode126=\the\catcode126%<~> | |
\endlinechar=\the\endlinechar | |
\relax} | |
\catcode33=12 | |
\catcode126=13 | |
\endlinechar=-1 % | |
%--------------------------------------- | |
%% errors | |
\def\ixbag@err@bad@arity{ | |
\ixbag@error{Arity is too large (\the\ixbag@arity)} | |
{The arity is changed to nine.} | |
} | |
%% variables | |
\let\ixbag@envname\relax | |
\newcount\ixbag@arity | |
\let\ixbag@filter\relax | |
\newtoks\ixbag@args | |
%%<+>\DeclareStringProcessEnvironment{<name>} | |
% [<arity>][\CSfilter]{<body>} | |
% 'name' is the name of the environment to be defined | |
% 'arity' is the number of arguments, including ... | |
\protected\def\DeclareStringProcessEnvironment{ | |
\ixbag@dspenviron | |
} | |
\def\ixbag@dspenviron#1{ | |
\edef\ixbag@envname{#1} | |
\@testopt\ixbag@dspenviron@a\@ne | |
} | |
\def\ixbag@dspenviron@a[#1]{ | |
\ixbag@arity=#1\relax | |
\@testopt\ixbag@dspenviron@b! | |
} | |
\def\ixbag@dspenviron@b[#1]{ | |
\csedef{\ixbag@envname}{\noexpand\ixbag@begin{\ixbag@envname}} | |
\edef\ixbag@next{ | |
\def\expandonce{\csname ixbag@grab@\ixbag@envname\endcsname} | |
####1\detokenize\expandafter{\expanded{\string\end{\ixbag@envname}}} | |
{\unexpanded{\ixbag@grabbed{##1}}}} | |
\ixbag@next | |
\ifnum \ixbag@arity<1 \ixbag@arity=1 \fi | |
\ifnum \ixbag@arity>9 % | |
\ixbag@err@bad@arity | |
\ixbag@arity=9 % | |
\fi | |
\ifstrequal{#1}{!} | |
{\csletcs{ixbag@filter@\ixbag@envname}{ixbag@skim/\the\ixbag@arity}} | |
{\cslet{ixbag@filter@\ixbag@envname}{#1}} | |
\expandafter\ixbag@dspenviron@c | |
\csname ixbag@body@\ixbag@envname\endcsname | |
} | |
\def\ixbag@dspenviron@c#1#{ | |
\undef#1 | |
\newcommand#1[\ixbag@arity] | |
} | |
%% \ixbag@begin{<name>} | |
\def\ixbag@begin#1{ | |
\letcs\ixbag@grab{ixbag@grab@#1} | |
\letcs\ixbag@filter{ixbag@filter@#1} | |
\global\letcs\ixbag@g@do{ixbag@body@#1} | |
\ixbag@filter | |
} | |
%% \ixbag@do@grab | |
\def\ixbag@do@grab{ | |
\endlinechar=13 % | |
\luatexcatcodetable\CatcodeTableOther | |
\ixbag@grab | |
} | |
%% \ixbag@grabbed | |
\def\ixbag@grabbed{ | |
\expandafter\ixbag@grabbed@a\the\ixbag@args | |
} | |
\def\ixbag@grabbed@a{ | |
\endgroup | |
\ixbag@g@do | |
} | |
%%<+> \DeclareSPEArguments | |
\protected\def\DeclareSPEArguments#{ | |
\ixbag@dspe@args | |
} | |
\def\ixbag@dspe@args#1{ | |
\ixbag@args{#1} | |
\ixbag@do@grab | |
} | |
%% \[ixbag@skip/<N>] | |
% Simple argument filters used as default. | |
\csdef{ixbag@skim/1} | |
{\ixbag@dspe@args{}} | |
\csdef{ixbag@skim/2}#1 | |
{\ixbag@dspe@args{{#1}}} | |
\csdef{ixbag@skim/3}#1#2 | |
{\ixbag@dspe@args{{#1}{#2}}} | |
\csdef{ixbag@skim/4}#1#2#3 | |
{\ixbag@dspe@args{{#1}{#2}{#3}}} | |
\csdef{ixbag@skim/5}#1#2#3#4 | |
{\ixbag@dspe@args{{#1}{#2}{#3}{#4}}} | |
\csdef{ixbag@skim/6}#1#2#3#4#5 | |
{\ixbag@dspe@args{{#1}{#2}{#3}{#4}{#5}}} | |
\csdef{ixbag@skim/7}#1#2#3#4#5#6 | |
{\ixbag@dspe@args{{#1}{#2}{#3}{#4}{#5}{#6}}} | |
\csdef{ixbag@skim/8}#1#2#3#4#5#6#7 | |
{\ixbag@dspe@args{{#1}{#2}{#3}{#4}{#5}{#6}{#7}}} | |
\csdef{ixbag@skim/9}#1#2#3#4#5#6#7#8 | |
{\ixbag@dspe@args{{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}} | |
%--------------------------------------- | |
%% \ParseAsLaTeX | |
\newcommand*{\ParseAsLaTeX}[1]{ | |
\directlua{ixbase.spe_parse_as_latex("\luatexluaescapestring{#1}")} | |
} | |
%% \SPEString | |
\newcommand*{\SPEString}[1]{ | |
(ixbase.spe_normalize("\luatexluaescapestring{#1}")) | |
} | |
\begingroup | |
\endlinechar=10 % | |
\directlua{ | |
local cctb = luatexbase.catcodetables | |
ixbase = ixbase or {} | |
function ixbase.spe_normalize(s) | |
return s:gsub("^\string\r", ""):gsub("\string\r", "\string\n") | |
end | |
function ixbase.spe_parse_as_latex(s) | |
tex.sprint(cctb.latex, "\string\\luatexscantextokens{") | |
tex.sprint(cctb.string, ixbase.spe_normalize(s)) | |
tex.sprint(cctb.latex, "}") | |
end | |
}% | |
\endgroup% | |
%--------------------------------------- done | |
\ixbag@restore@codes | |
\endinput | |
%% EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment