From 893ee900813683b35a88199025e6d6620e14a8e5 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Feb 2012 12:22:39 +0100 Subject: lazy machine macros --- tex/context/third/enigma/enigma.lua | 54 +++++++++++++++++++++++++++---------- tex/plain/enigma/enigma.tex | 48 +++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 28 deletions(-) diff --git a/tex/context/third/enigma/enigma.lua b/tex/context/third/enigma/enigma.lua index 4514ca7..0e53e0a 100644 --- a/tex/context/third/enigma/enigma.lua +++ b/tex/context/third/enigma/enigma.lua @@ -29,6 +29,7 @@ libraries. \stopparagraph --ichd]]-- local iowrite = io.write +local mathfloor = math.floor local mathrandom = math.random local next = next local nodecopy = node.copy @@ -228,17 +229,18 @@ do return stringformat("\027[4;37m%s\027[0m", s) end - local s_steps = [[Total characters encoded: ]] + local s_steps = [[Total characters encoded with machine “]] local f_warnsteps = [[ (%d over permitted maximum)]] - pprint_machine_step = function (n) + pprint_machine_step = function (n, name) local sn + name = colorize(name, 36) if n > max_msg_length then sn = colorize(n, 31) .. stringformat(f_warnsteps, n - max_msg_length) else sn = colorize(n, 37) end - emit(1, s_steps .. sn .. ".") + emit(1, s_steps .. name .. "”: " .. sn .. ".") end local rotorstate = "[s \027[1;37m%s\027[0m n\027[1;37m%2d\027[0m]> " pprint_rotor = function (rotor) @@ -957,7 +959,7 @@ consists of three elements: end local processed_chars = function (machine) - pprint_machine_step(machine.step) + pprint_machine_step(machine.step, machine.name) end new = function (setup_string, pattern) local raw_settings = lpegmatch(p_init, setup_string) @@ -1013,7 +1015,7 @@ Exported functionality will be collected in the table \stopparagraph --ichd]]-- -local enigma = { } +local enigma = { machines = { }, callbacks = { } } --[[ichd \startparagraph @@ -1122,16 +1124,33 @@ do if type(str) ~= "string" then return "" end return lpegmatch(p_ans, str) end + local ensure_int = function (n) + n = tonumber(n) + if not n then return 0 end + return mathfloor(n + 0.5) + end + p_alpha = Cs((alpha + (1 - alpha / ""))^1) + local ensure_alpha = function (s) + s = tostring(s) + return lpegmatch(p_alpha, s) + end local sanitizers = { - other_chars = toboolean, - day_key = alphanum_or_space, + other_chars = toboolean, + day_key = alphanum_or_space, + rotor_setting = ensure_alpha, + verbose = ensure_int, } enigma.parse_args = function (raw) local args = lpegmatch(p_args, raw) for k, v in next, args do local f = sanitizers[k] - args[k] = f(v) + if f then + args[k] = f(v) + else + -- OPTIONAL be fascist and permit only predefined args + args[k] = v + end end return args end @@ -1148,9 +1167,9 @@ This is the interface to \TEX. \stopparagraph --ichd]]-- -enigma.new_callback = function (machine) - enigma.current_machine = machine - return function (head) +enigma.new_callback = function (machine, name) + enigma.machines [name] = machine + enigma.callbacks[name] = function (head) for n in nodetraverse(head) do --print(node, node.id) if n.id == glyph_node then @@ -1162,7 +1181,12 @@ enigma.new_callback = function (machine) local insertion = nodecopy(n) insertion.char = utf8byte(replacement) nodeinsert_before(head, n, insertion) - print(n.char, insertion.char) + elseif type(replacement) == "table" then + for i=1, #replacement do + local insertion = nodecopy(n) + insertion.char = utf8byte(replacement[i]) + nodeinsert_before(head, n, insertion) + end end noderemove(head, n) elseif n.id == glue_node then @@ -1175,8 +1199,10 @@ enigma.new_callback = function (machine) end --local teststring = [[B I II III 01 01 01]] -enigma.new_machine = function (args, pattern) - local machine = new(args.day_key, pattern) +enigma.new_machine = function (args, name) + local machine = new(args.day_key, args.rotor_setting) + machine.name = name + verbose_level = args.verbose return machine end --stub diff --git a/tex/plain/enigma/enigma.tex b/tex/plain/enigma/enigma.tex index 6827878..1849103 100644 --- a/tex/plain/enigma/enigma.tex +++ b/tex/plain/enigma/enigma.tex @@ -1,4 +1,5 @@ \input{luatexbase.sty} +\catcode`\_=11 % There’s no reason why this shouldn’t be the case. %D \startsection[title=Prerequisites] %D \startparagraph %D Package loading and the namespacing issue are commented on in @@ -42,15 +43,18 @@ \directlua{ local enigma = packagedata.enigma local current_args = enigma.parse_args([====[\detokenize{#1}]====]) - enigma.current = enigma.new_callback(enigma.new_machine(current_args, "aaa")) + enigma.new_callback(enigma.new_machine(current_args, + [====[\currentenigmaid]====]), + [====[\currentenigmaid]====]) }% \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{% +\def\setupenigma#1{% \bgroup + \edef\currentenigmaid{#1} \luatexcatcodetable \enigmasetupcatcodes \do_setup_enigma% } @@ -62,22 +66,38 @@ %D allow enabling of Enigma encoding in different parts of the document. %D \stopparagraph -\def\startenigma{% - \bgroup% - \directlua{% - if packagedata.enigma and packagedata.enigma.current then - luatexbase.add_to_callback("pre_linebreak_filter", - packagedata.enigma.current, - "enigma") - end +\def\do_define_enigma#1{ + \@EA\gdef\csname start\enigmaid\endcsname{% + \bgroup% + % \edef\currentenigmaid{\enigmaid}% + \directlua{% + if packagedata.enigma and packagedata.enigma.machines["#1"] then + luatexbase.add_to_callback("pre_linebreak_filter", + packagedata.enigma.callbacks["#1"], + "#1") + else + print([[ENIGMA: No machine of that name: #1!]]) + os.exit() + end + }% + } + + \@EA\gdef\csname stop\enigmaid\endcsname{% + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter", + "#1") + packagedata.enigma.machines["#1"]:processed_chars()}% + \egroup% }% } -\def\stopenigma{% - \directlua{luatexbase.remove_from_callback("pre_linebreak_filter", "enigma") - packagedata.enigma.current_machine:processed_chars()}% - \egroup% +\def\defineenigma#1{% + \begingroup + \let\@EA\expandafter + \edef\enigmaid{#1}% + \@EA\do_define_enigma\@EA{\enigmaid}% + \endgroup% } %D \stopsection +\catcode`\_=8 % vim:ft=tex:sw=2:ts=2:expandtab:tw=72 -- cgit v1.2.3