\newif\ifenigmaisrunningplain \ifcsname ver@enigma.sty\endcsname\else \enigmaisrunningplaintrue \input{luatexbase.sty} \catcode`\@=11 % \else latex \fi \catcode`\_=11 % There’s no reason why this shouldn’t be the case. \catcode`\!=11 %D Nice tool from luat-ini.mkiv. This really helps with those annoying %D string separators of Lua’s that clutter the source. \def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems \edef\!!bs{[\luastringsep[} \edef\!!es{]\luastringsep]} %D \startdocsection[title=Prerequisites] %D \startparagraph %D Package loading and the namespacing issue are commented on in %D \identifier{enigma.lua}. %D \stopparagraph \directlua{ packagedata = packagedata or { } dofile(kpse.find_file\!!bs enigma.lua\!!es) } %D \startparagraph %D First, create somthing like \CONTEXT’s asciimode. We found %D \texmacro{newluatexcatcodetable} in \identifier{luacode.sty} and it %D seems to get the job done. %D \stopparagraph \newluatexcatcodetable \enigmasetupcatcodes \bgroup \def\escapecatcode {0} \def\begingroupcatcode {1} \def\endgroupcatcode {2} \def\spacecatcode {10} \def\lettercatcode {11} \setluatexcatcodetable\enigmasetupcatcodes { \catcode`\^^I = \spacecatcode % tab \catcode`\ = \spacecatcode \catcode`\{ = \begingroupcatcode \catcode`\} = \endgroupcatcode \catcode`\^^L = \lettercatcode % form feed \catcode`\^^M = \lettercatcode % eol } \egroup %D \stopdocsection %D \startdocsection[title=Setups] %D \startparagraph %D Once the proper catcodes are in place, the setup macro %D \texmacro{do_setup_enigma} doesn’t to anything besides passing stuff %D through to Lua. %D \stopparagraph \def\do_setup_enigma#1{% \directlua{ local enigma = packagedata.enigma local current_args = enigma.parse_args(\!!bs\detokenize{#1}\!!es) enigma.save_raw_args(current_args, \!!bs\current_enigma_id\!!es) enigma.new_callback(enigma.new_machine(\!!bs\current_enigma_id\!!es), \!!bs\current_enigma_id\!!es) }% \egroup% } %D The module setup \texmacro{setupenigma} expects key=value, notation. %D All the logic is at the Lua end, not much to see here … \def\setupenigma#1{% \bgroup \edef\current_enigma_id{#1} \luatexcatcodetable \enigmasetupcatcodes \do_setup_enigma% } %D \stopdocsection %D \startdocsection[title=Encoding Macros] %D \startparagraph %D The environment of \texmacro{start} and %D \texmacro{stop} allow enabling of Enigma encoding in %D different parts of the document. %D \stopparagraph \edef\c!pre_linebreak_filter{pre_linebreak_filter} \def\do_define_enigma#1{% \@EA\gdef\csname start\current_enigma_id\endcsname{% \endgraf \bgroup% \directlua{% if packagedata.enigma and packagedata.enigma.machines[ \!!bs#1\!!es] then luatexbase.add_to_callback(\!!bs\c!pre_linebreak_filter\!!es, packagedata.enigma.callbacks[ \!!bs#1\!!es], \!!bs#1\!!es) else print\!!bs ENIGMA: No machine of that name: #1!\!!es os.exit() end }% }% \@EA\gdef\csname stop\current_enigma_id\endcsname{% \endgraf \directlua{ luatexbase.remove_from_callback(\!!bs\c!pre_linebreak_filter\!!es, \!!bs#1\!!es) packagedata.enigma.machines[ \!!bs#1\!!es]:processed_chars() }% \egroup% }% } \def\defineenigma#1{% \begingroup \let\@EA\expandafter \edef\current_enigma_id{#1}% \@EA\do_define_enigma\@EA{\current_enigma_id}% \endgroup% } %D \stopdocsection \catcode`\_=8 % \popcatcodes \catcode`\!=12 % reserved according to source2e \ifenigmaisrunningplain\catcode`\@=12\fi % vim:ft=tex:sw=2:ts=2:expandtab:tw=72