Skip to content

Instantly share code, notes, and snippets.

@zr-tex8r
Created May 1, 2012 18:40
Show Gist options
  • Save zr-tex8r/2570350 to your computer and use it in GitHub Desktop.
Save zr-tex8r/2570350 to your computer and use it in GitHub Desktop.
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