From bdc2513f4f7d1df90f11266530aa29a8f2c64d5c Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 17 Jun 2012 12:20:45 +0200 Subject: [cbk] make auto-grouping an option --- doc/context/third/enigma/enigma_manual.tex | 7 +++ .../enigma/examples/enigma-example-context.tex | 1 + .../third/enigma/examples/enigma-example-latex.tex | 2 + tex/context/third/enigma/enigma.lua | 61 +++++++++++++++------- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/doc/context/third/enigma/enigma_manual.tex b/doc/context/third/enigma/enigma_manual.tex index 8a78457..bbd3ba3 100644 --- a/doc/context/third/enigma/enigma_manual.tex +++ b/doc/context/third/enigma/enigma_manual.tex @@ -138,6 +138,7 @@ the following parameters. day_key = I II III 01 01 01, rotor_setting = aaa, + spacing = yes, verbose = 1, } %% Usage ················ %% @@ -175,6 +176,7 @@ the following parameters. positions of the three rotors, the ring settings, and the plugboard wiring. \item{rotor_setting}{string} The initial rotor advancement. + \item{spacing}{boolean} Auto-space output? \item{verbose}{integer} Controls overall verbosity level (\emph{global}!). \stopitemize @@ -229,6 +231,11 @@ This is a triple of letters, each representing the initial state of one rotor (e.\,g. \type{fkd}). Historically this was not part of the day key but supposed to be chosen at random by the operating signal officer. +The output can be automatically grouped into sequences of five +characters, delimited by spaces. This does not only conform with +traditional crypto-style, but also allows for the resulting text to be +sanely broken into lines by \TEX. + %%% other_chars % The option \identifier{other_chars} determines how the machine -- in our % Unicode-aware times -- should behave when it encounters a non-Latin diff --git a/doc/context/third/enigma/examples/enigma-example-context.tex b/doc/context/third/enigma/examples/enigma-example-context.tex index 4ffe358..769c608 100644 --- a/doc/context/third/enigma/examples/enigma-example-context.tex +++ b/doc/context/third/enigma/examples/enigma-example-context.tex @@ -7,6 +7,7 @@ other_chars = no, day_key = I II III 01 01 01, rotor_setting = aaa, + spacing = yes, verbose = 3, ] diff --git a/doc/context/third/enigma/examples/enigma-example-latex.tex b/doc/context/third/enigma/examples/enigma-example-latex.tex index d04dbad..66d84d1 100644 --- a/doc/context/third/enigma/examples/enigma-example-latex.tex +++ b/doc/context/third/enigma/examples/enigma-example-latex.tex @@ -9,6 +9,8 @@ other_chars = yes, day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL, rotor_setting = ben, + spacing = yes, + verbose = 3, } %%·····································································% %% This second machine below will be used to decrypt the string. It is diff --git a/tex/context/third/enigma/enigma.lua b/tex/context/third/enigma/enigma.lua index c5772bd..ed227b7 100644 --- a/tex/context/third/enigma/enigma.lua +++ b/tex/context/third/enigma/enigma.lua @@ -1153,9 +1153,10 @@ boolean) determines whether we will keep or drop offending characters. local raw_settings = handle_day_key(setup_string, name) local rotors, ring = get_rotors(raw_settings.rotors, raw_settings.ring) - local plugboard = raw_settings.plugboard - and get_plugboard_substitution(raw_settings.plugboard) - or get_plugboard_substitution{ } + local plugboard + = raw_settings.plugboard + and get_plugboard_substitution(raw_settings.plugboard) + or get_plugboard_substitution{ } local machine = { name = name, step = 0, -- n characters encoded @@ -1167,6 +1168,7 @@ boolean) determines whether we will keep or drop offending characters. ring = ring, state = init_state, other_chars = args.other_chars, + spacing = args.spacing, ---> a>1, b>2, c>3 reflector = letter_to_value[raw_settings.reflector], plugboard = plugboard, @@ -1183,7 +1185,7 @@ boolean) determines whether we will keep or drop offending characters. --- __raw = raw_settings -- hackish but occasionally useful --- - } + } --- machine local init_state = pattern_to_state(pattern or get_random_pattern()) emit(1, pprint_init, init_state) machine:set_state(init_state) @@ -1297,6 +1299,7 @@ a sanitizer routine and, if so, apply it to its value. local sanitizers = { other_chars = toboolean, -- true = keep, false = drop + spacing = toboolean, day_key = alphanum_or_space, rotor_setting = ensure_alpha, verbose = ensure_int, @@ -1391,21 +1394,39 @@ local new_callback = function (machine, name) enigma.machines [name] = machine local space_node local mod_5 = 0 - local insert_with_spacing = function (head, n, replacement) - local insertion = nodecopy(n) - if replacement then -- inefficient but bulletproof - insertion.char = utf8byte(replacement) - --print(utf8char(n.char), "=>", utf8char(insertion.char)) + local insert_encoded + --- First we need to choose an insertion method. If autospacing is + --- requested, a space will have to be inserted every five characters. + --- The rationale behind using differend functions to implement each + --- method is that it should be faster than branching for each + --- character. + if machine.spacing then -- auto-group output + insert_encoded = function (head, n, replacement) + local insertion = nodecopy(n) + if replacement then -- inefficient but bulletproof + insertion.char = utf8byte(replacement) + --print(utf8char(n.char), "=>", utf8char(insertion.char)) + end + nodeinsert_before(head, n, insertion) + mod_5 = mod_5 + 1 + if mod_5 >= 5 then + mod_5 = 0 + nodeinsert_after(head, insertion, nodecopy(space_node)) + end + noderemove(head, n) end - nodeinsert_before(head, n, insertion) - mod_5 = mod_5 + 1 - if mod_5 >= 5 then - mod_5 = 0 - nodeinsert_after(head, insertion, nodecopy(space_node)) + else + insert_encoded = function (head, n, replacement) + local insertion = nodecopy(n) + if replacement then -- inefficient but bulletproof + insertion.char = utf8byte(replacement) + end + nodeinsert_before(head, n, insertion) + noderemove(head, n) end - noderemove(head, n) end local format_is_context_p = format_is_context_p + --- The callback proper starts here. local cbk = function (a, _, c) space_node = generate_space () local head = format_is_context_p and c or a @@ -1420,15 +1441,15 @@ local new_callback = function (machine, name) --if replacement == false then if not replacement then if machine.other_chars then - insert_with_spacing(head, n, nil) + insert_encoded(head, n, nil) else noderemove(head, n) end elseif treplacement == "string" then - insert_with_spacing(head, n, replacement) + insert_encoded(head, n, replacement) elseif treplacement == "table" then for i=1, #replacement do - insert_with_spacing(head, n, replacement) + insert_encoded(head, n, replacement) end end elseif nid == GLUE_NODE then @@ -1444,8 +1465,8 @@ local new_callback = function (machine, name) if npre and npost then local replacement_pre = machine:encode(utf8char(npre.char)) local replacement_post = machine:encode(utf8char(npost.char)) - insert_with_spacing(head, npre, replacement_pre) - insert_with_spacing(head, npost, replacement_post) + insert_encoded(head, npre, replacement_pre) + insert_encoded(head, npost, replacement_post) end noderemove(head, n) --else -- cgit v1.2.3