summaryrefslogtreecommitdiff
path: root/module/tex/context
diff options
context:
space:
mode:
Diffstat (limited to 'module/tex/context')
-rw-r--r--module/tex/context/third/simpleslides/automata/automata-eca.lua108
-rw-r--r--module/tex/context/third/simpleslides/automata/automata-life.lua420
-rw-r--r--module/tex/context/third/simpleslides/automata/automata-main.lua247
-rw-r--r--module/tex/context/third/simpleslides/automata/automatarc-global.lua63
-rw-r--r--module/tex/context/third/simpleslides/automata/parsers/parser-rle.lua95
-rw-r--r--module/tex/context/third/simpleslides/simpleslides-s-Automaton.tex261
6 files changed, 1194 insertions, 0 deletions
diff --git a/module/tex/context/third/simpleslides/automata/automata-eca.lua b/module/tex/context/third/simpleslides/automata/automata-eca.lua
new file mode 100644
index 0000000..95d1f71
--- /dev/null
+++ b/module/tex/context/third/simpleslides/automata/automata-eca.lua
@@ -0,0 +1,108 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: automata-eca.lua
+-- DESCRIPTION: drawing elementary cellular automata
+-- REQUIREMENTS: ConTeXt MkIV with Simple Slides module
+-- BUGS: uncountable
+-- AUTHOR: Philipp Gesang (Phg), <megas.kapaneus@gmail.com>
+-- VERSION: 1.0
+-- CREATED: 14/08/10 19:43:35 CEST
+--------------------------------------------------------------------------------
+--
+
+environment.loadluafile( "automata-life" )
+
+local help = gol.helpers
+
+local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match
+
+
+eca = {}
+
+
+function eca.parse_file (fname)
+ local f = assert(io.open(fname, "r"), "No such file: "..fname..".")
+ local init = f:read("*all")
+ f:close()
+
+ return help.strip(init)
+end
+
+function eca.to_base(number, base)
+ local alphabet, result, cnt, remainder = "0123456789abcdef", "", 0
+ while number > 0 do
+ cnt = cnt + 1
+ number, remainder = math.floor(number / base), (number % base) + 1
+ result = string.sub(alphabet, remainder, remainder) .. result
+ end
+ return result
+end
+
+function eca.gen_rule(nr)
+ local rules = {}
+ local states = { "111", "110", "101", "100", "011", "010", "001", "000" }
+
+ nr = string.format("%8s",eca.to_base(nr, 2)):gsub(" ", "0")
+
+ local n = 1
+ while n <= #states do
+ rules[states[n]] = nr:sub(n,n)
+ n = n + 1
+ end
+
+ return rules
+end
+
+function eca.next_line(from, rule)
+ local new = ""
+ from = "0"..from.."0" -- assume dead borders
+ --from = string.format("0%s0", from) -- too slow
+
+ local cell = C(S"01")
+ local cells= Ct(cell * #(cell * cell)) / function (t)
+ local three = t[1]..t[2]..t[3]
+ new = new .. rule[three]
+ end
+ lpeg.match(cells^1, from)
+ return new
+end
+
+function eca.stripcells (str, dir, cnt)
+ if dir == "left" then
+ return str:sub( cnt )
+ elseif dir == "right" then
+ return str:sub( 0, str:len() - cnt )
+ else -- assume ambilateral clipping
+ return str:sub( cnt, str:len() - cnt )
+ end
+end
+
+function eca.gen_frame(from, lines, rule)
+
+ local cnt = 1
+ local c = mplife.setup.current
+
+ local new = { [1] = eca.stripcells(from, c.clip, c.diff ) }
+
+ repeat
+ from = eca.next_line(from, rule)
+ table.insert( new, eca.stripcells(from, c.clip, c.diff) )
+ cnt = cnt + 1
+ until cnt == lines
+ return eca.next_line(from, rule), new
+end
+
+function eca.successive (current)
+ local thisframe
+ current.from, thisframe = eca.gen_frame(current.from, current.framesize, current.rule)
+ if not context then -- cli invocation
+ for _,j in ipairs(thisframe) do
+ io.write(j:gsub("0","·"):gsub("1","O").."\n")
+ end
+ else
+
+ end
+ return 0
+end
+
+return eca
diff --git a/module/tex/context/third/simpleslides/automata/automata-life.lua b/module/tex/context/third/simpleslides/automata/automata-life.lua
new file mode 100644
index 0000000..01fc97b
--- /dev/null
+++ b/module/tex/context/third/simpleslides/automata/automata-life.lua
@@ -0,0 +1,420 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: automata-life.lua
+-- DESCRIPTION: Conway's Game of Life?
+-- REQUIREMENTS: ConTeXt MkIV / Simple Slides module
+-- BUGS: almost infinite but not quite
+-- AUTHOR: Philipp Gesang (Phg), <megas.kapaneus@gmail.com>
+-- VERSION: 1.0
+-- CREATED: 05/08/10 12:03:11 CEST
+--------------------------------------------------------------------------------
+--
+
+gol = {}
+
+gol.helpers = {}
+
+local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match
+
+
+-- http://lua-users.org/lists/lua-l/2009-06/msg00343.html
+gol.helpers.utfchar = R("\000\127") +
+ R("\194\223") * R("\128\191") +
+ R("\224\240") * R("\128\191") * R("\128\191") +
+ R("\241\244") * R("\128\191") * R("\128\191") * R("\128\191")
+
+
+-- by Roberto, captures everything in a table
+-- http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html
+function gol.helpers.split (s, sep)
+ sep = P(sep)
+ local elem = C((1 - sep)^0)
+ local p = Ct(elem * (sep * elem)^0) -- make a table capture
+ return match(p, s)
+end
+
+-- Modified to match left and right of one separator only.
+function gol.helpers.split_once (s, sep)
+ local utfchar = gol.helpers.utfchar
+ sep = S(sep)
+ local left = C((1 - sep)^0)
+ local right = C((utfchar)^0)
+ local p = Ct(left * sep * right)
+ return p:match(s)
+end
+
+-- Modified stripper from Roberto to support trimming other chars than whitespace
+function gol.helpers.strip(str, chars)
+ local chars = chars or " \t\v\n"
+ chars = S(chars)
+ local nochars = 1 - chars
+ local stripper = chars^0 * C((chars^0 * nochars^1)^0)
+
+ return match(stripper,str) or ""
+end
+
+function gol.helpers.dead_row(len)
+ local row = ""
+ local dead = "0"
+ for i=1, len, 1 do
+ row = row .. dead
+ end
+ return row
+end
+
+-- Read rules of type "B3[/.-]S23"
+-- => “birth” of a new cell if exactly 3 adjacent cells are “alive”
+-- => “staying alive” of cells with two or three adjacent “live” cells
+function gol.parse_rule (raw_rule)
+ local help = gol.helpers
+ local b_s = help.split_once (raw_rule, "/.-")
+ local tmp_b = help.strip(b_s[1], "B")
+ local tmp_s = help.strip(b_s[2], "S")
+
+ local b, s = {}, {}
+
+ -- single digits express birth/stay conditions
+ local n = 1
+ repeat
+ table.insert( b, tonumber(tmp_b:sub(n,n)) )
+ n = n + 1
+ until n > string.len(tmp_b)
+
+ n = 1
+ repeat
+ table.insert( s, tonumber(tmp_s:sub(n,n)) )
+ n = n + 1
+ until n > string.len(tmp_s)
+
+ return { birth = b, stay = s }
+end
+
+function gol.apply_rule (cell, cnt, rule, fade, keep)
+ --local live, dead = "1", "0"
+ --local new = dead
+ local new = 0
+ local live = "1"
+ local stay = rule.stay
+ local birth = rule.birth
+
+ -- checking if cnt matches the numbers from the conditions list
+ if cell == live then
+ for _, cond in ipairs(stay) do
+ if cnt == cond then
+ new = "1"
+ break
+ end
+ end
+ else -- ==dead
+ for _, cond in ipairs(birth) do
+ if cnt == cond then
+ new = "1"
+ break
+ end
+ end
+ end
+
+ if fade then
+ if not (live == new) then
+ local add = tonumber (cell)
+ if not add then -- == "D"
+ add = "D"
+ else
+ if add and add < 9 and add ~= 0 then
+ add = add + 1
+ elseif keep and add and add == 9 then -- marking dead cells once alive
+ add = "D"
+ else
+ add = 0
+ end
+ end
+ new = tostring(add)
+ end
+ end
+
+ return new
+end
+
+gol.formats = {}
+
+gol.formats[".gol"] = function (fname)
+ local tmp = {} -- return an array
+ local len -- check for equal line length
+
+ if fname:sub(-4,-1) ~= ".gol" then
+ fname = fname .. ".gol"
+ end
+
+ local file = assert(io.open(fname, "r"), "Not a file: " .. fname)
+ local data = file:read("*all")
+ file:close()
+
+ local cell = R"09" + P"D"
+ local nl = Cs(P"\n") / ""
+ local line = Cs(cell^1) / function (l)
+ if not len then len = string.len(l) end
+ if len ~= string.len(l) then
+ -- inconsistent horizontal sizes; kill off program
+ return nil
+ else
+ table.insert(tmp,l)
+ end
+ end
+
+ local gol_parser = Cs(line * (nl + line)^0)
+
+ if gol_parser:match(data) then
+ if context then
+ context.writestatus("simpleslides", "Sucessfully loaded frame from "..fname..".")
+ end
+ return tmp
+ else
+ return false
+ end
+end
+
+gol.formats[".cell"] = function (fname)
+ return false -- stub
+end
+
+gol.formats[".rle"] = function (fname)
+ environment.loadluafile( "parser-rle" )
+ return gol.rleparser(fname)
+end
+
+function gol.extend_area(rows)
+ local tmp = {}
+ local c = mplife.setup.current
+
+ context.writestatus("simpleslides","Extending area horizontally by "..c.extendx.."cells.")
+ context.writestatus("simpleslides","Extending area vertically by "..c.extendy.."cells.")
+
+ if c.extendy > 0 then
+ local row = ""
+ for i=1, rows[1]:len(), 1 do -- buildling an empty row
+ row = row.."0"
+ end
+
+ for i=1, c.extendy, 1 do
+ table.insert(tmp, row)
+ end
+
+ for _, r in ipairs(rows) do
+ table.insert(tmp, r)
+ end
+
+ for i=1, c.extendy, 1 do
+ table.insert(tmp, row)
+ end
+ end
+
+ if c.extendx > 0 then
+ local add = ""
+ for i=1, c.extendx, 1 do -- building an empty pre- and suffix
+ add = add .. "0"
+ end
+
+ for n, r in ipairs(tmp) do
+ tmp[n] = add .. r .. add
+ end
+ end
+
+ return tmp
+end
+
+function gol.parse_file (fname)
+ local p_suf = P"." * (1-P".")^3 * -P(1)
+ local p_fn = (1-p_suf)^1 * C(p_suf)
+ local suffix = p_fn:match(fname) or ".gol" -- assume .gol format as default
+
+ local tmp = gol.formats[suffix] ( fname )
+ if mplife and mplife.setup.current and (
+ mplife.setup.current.extendx > 0 or
+ mplife.setup.current.extendy > 0) then
+ tmp = gol.extend_area(tmp)
+ end
+ return tmp
+end
+
+
+--- Computing single lines and whole frames and intervals thereof
+
+function gol.next_line (rows, rule)
+ local live = "1"
+
+ local fade = false
+ if mplife then
+ fade = mplife.setup.current.fade
+ end
+
+ local n = 1
+ local max = string.len(rows[2])
+
+ local cell = R("09") + P("D")
+ local nocell = 1-cell
+ local ce = Cs(cell) / function (current)
+
+ local env = {}
+ local lpos, rpos -- positions left of / right of current
+
+ -- toroidal, flips over at borders
+ if n == 1 then
+ lpos = max
+ else
+ lpos = n - 1
+ end
+
+ if n == max then
+ rpos = 1
+ else
+ rpos = n + 1
+ end
+
+ -- +---+---+---+
+ -- |nw | n | ne|
+ -- +---+---+---+
+ -- |w | c | e| env[ironment] of current
+ -- +---+---+---+
+ -- |sw | s | se|
+ -- +---+---+---+
+
+ env.nw = string.sub( rows[1], lpos, lpos )
+ env.n = string.sub( rows[1], n , n )
+ env.ne = string.sub( rows[1], rpos, rpos )
+
+ env.w = string.sub( rows[2], rpos, rpos )
+ env.e = string.sub( rows[2], lpos, lpos )
+
+ env.sw = string.sub( rows[3], lpos, lpos )
+ env.s = string.sub( rows[3], n , n )
+ env.se = string.sub( rows[3], rpos, rpos )
+
+ -- counting live cells in the environment
+ local cnt = 0
+ for _, chr in pairs(env) do
+ if chr == live then
+ cnt = cnt + 1
+ end
+ end
+
+ n = n + 1
+ --
+ -- adding new cell according to ruleset
+ return gol.apply_rule(current, cnt, rule, fade, true)
+ end
+
+ local noce = Cs(nocell) / ""
+ local c = Cs(ce * (noce + ce)^0)
+
+ return c:match(rows[2])
+end
+
+function gol.next_frame (old, rule)
+ local new = {}
+
+ local n = 1
+
+ repeat
+ local rows = {}
+
+ rows[2] = old[n] -- current
+
+ -- toroidal
+ rows[1] = old[n-1] or old[#old] -- last
+ rows[3] = old[n+1] or old[1] -- next
+
+ new[n] = gol.next_line( rows, rule )
+
+ n = n + 1
+ until n > #old
+
+ return new
+end
+
+-- get the nth frame starting from init
+function gol.frame (init, rule, n)
+ local frame = init
+ local gnext = gol.next_frame
+
+ for i=1, n, 1 do
+ frame = gnext( frame, rule )
+ end
+
+ return frame
+end
+
+-- get array of frames until nth [from offset]
+function gol.frames (init, rule, n, offset)
+ local frames = {}
+ local last
+ local gnext = gol.next_frame
+
+ -- “fast forward”
+ if offset then
+ last = gol.frame( init, rule, offset )
+ else
+ last = init
+ end
+
+ for i=1, n, 1 do
+ frames[i] = last
+ last = gnext( last, rule )
+ end
+
+ return frames
+end
+
+--- pretty printing frames (ascii)
+
+-- pp a heading: len should exceed length of mark + 4
+function gol.pre_section (len, mark)
+ local mark = mark or "Frame"
+ local t = "-"
+
+ local s = t..t.." "..mark.." "
+ if s:len() < len then
+ for n=1, len - s:len(), 1 do
+ s = s..t
+ end
+ end
+
+ io.write ("\n\n"..s.."\n")
+end
+
+function gol.pre_frame (frame)
+ local repl = {
+ ["0"] = "·",
+ ["1"] = "O",
+ ["2"] = "2",
+ ["3"] = "3",
+ ["4"] = "4",
+ ["5"] = "5",
+ ["6"] = "6",
+ ["7"] = "7",
+ ["8"] = "8",
+ ["9"] = "9",
+ }
+
+ local cell = R"09" + P"D"
+ local nocell = 1-cell
+ local ce = Cs(cell) / repl
+ local noce = Cs(nocell) / ""
+ local c = Cs(ce * (noce + ce)^0)
+
+ for j, row in ipairs(frame) do
+ io.write("\n" .. c:match(row))
+ end
+end
+
+function gol.pre_movie (frames, section)
+ for i, frame in ipairs(frames) do
+ if section then
+ local l = string.len(frame[1])
+ gol.pre_section( l, "Nr. " .. tostring(i) )
+ end
+ gol.pre_frame( frame )
+ end
+ io.write("\n")
+end
+
+return gol
diff --git a/module/tex/context/third/simpleslides/automata/automata-main.lua b/module/tex/context/third/simpleslides/automata/automata-main.lua
new file mode 100644
index 0000000..c7d1435
--- /dev/null
+++ b/module/tex/context/third/simpleslides/automata/automata-main.lua
@@ -0,0 +1,247 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: automata-main.lua
+-- USAGE: use with ConTeXt MkIV and the Simple Slides Module
+-- DESCRIPTION: Metapost output for Conway's Game of Life and Elementary
+-- Cellular Automata
+-- AUTHOR: Philipp Gesang (Phg), <megas.kapaneus@gmail.com>
+-- VERSION: 1.0
+-- CREATED: 06/08/10 12:28:35 CEST
+--------------------------------------------------------------------------------
+--
+
+environment.loadluafile( "automata-life" )
+environment.loadluafile( "automata-eca" )
+
+local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match
+
+mplife = {}
+
+mplife.setup = mplife.setup or {}
+
+if context then
+ environment.loadluafile( "automatarc-global" )
+ environment.loadluafile( "automatarc-eca" )
+else -- assuming we're staying in pwd
+ require ( "automatarc-eca" )
+end
+
+mplife.setup.current = {}
+
+
+do
+ local g, r, c = mplife.setup.global, mplife.setup.rc, mplife.setup.current
+ for key,_ in pairs(g) do
+ c[key] = r[key] or g[key] -- prefer local settings
+ end
+ mplife.setup.current = c
+end
+
+mplife.format = {
+
+ nl = "\n", space = " ",
+
+ opar = "(", cpar = ")",
+
+ hyphen = "-", comma = ",",
+ scolon = ";", path = "--",
+
+ filldraw = "fill", -- "draw",
+ draw = "draw",
+ cycle = "cycle",
+
+ p = function (x,y)
+ return string.format("(%s,%s)", x, y)
+ end,
+}
+
+function mplife.runcode (mpcode)
+ --context.startMPcode()
+ context(mpcode)
+ --context.stopMPcode()
+ --context.MPdrawing(mpcode) -- comes with next beta!
+end
+
+function mplife.draw_grid(grid, settings)
+ local h = gol.helpers
+ local c = mplife.setup.current
+ local pat = ""
+ if type(grid) == "string" then
+ grid = h.split(grid, "\n") -- may leave an empty string as last item
+ if grid[#grid] == "" then grid[#grid] = nil end
+ end
+
+ local max = {}
+ max.x, max.y = grid[1]:len(), #grid
+
+ local n = 0
+ while grid[#grid-n] ~= nil do
+ local row = grid[#grid-n]
+ local pos = 1
+
+ local cell = Cs(R("09") + P("D")) / function (char)
+ --repeat
+ local opacity = c.opacity
+ local p = { x = pos-1, y = n}
+
+ local fill, fade_level = true
+ --fill = true
+
+ if fill and c.fade then
+ fade_level = tonumber(char)
+ end
+
+ if not fade_level then -- no number --> cell once dead (marked "D")
+ fade_level = 9.3
+ end
+
+ if fade_level ~= 0 then -- skip dead cells
+ if fade_level == 1 then
+ pat = pat .. string.format("%s %s shifted (%s,%s) withcolor transparent (1,%s,%s);\n",
+ "draw", c.gestalt, p.x, p.y, opacity*2, settings.color)
+ else
+ opacity = opacity - (fade_level * opacity * .1)
+ end
+ pat = pat .. string.format("%s %s scaled .9 shifted (%s+.05,%s+.05) withcolor transparent (1,%s,%s);\n",
+ "filldraw", c.gestalt, p.x, p.y, opacity, settings.color)
+ end
+ pos = pos + 1
+ end
+
+ local line = cell * ((1-cell) + cell)^0
+ line:match(row)
+ pat = pat .. "\n"
+ n = n + 1
+ end
+
+ pat = pat .. string.format([[
+path border;
+border = (0,0)--(%s,0)--(%s,%s)--(0,%s)--cycle;
+setbounds currentpicture to boundingbox border ;
+]], max.x, max.x, max.y, max.y)
+
+ mplife.runcode(pat)
+ return true
+end
+
+--- testing section
+
+function mplife.checker(n)
+ local squares = ""
+ local cnt = 0
+ for y=1, n, 1 do
+ for x=1, n, 1 do
+ local fill
+ if cnt % 2 == 0 then fill = true end
+ local p = { x = x, y = y }
+ squares = squares .. mplife.p_square( p, fill )
+ cnt = cnt + 1
+ end
+ if n % 2 == 0 then cnt = cnt + 1 end -- needed for even column numbers
+ end
+ return squares
+end
+
+function mplife.rand_pattern(n, digits)
+ local pat = ""
+ for y=1, n, 1 do
+ for x=1, n, 1 do
+ pat = pat .. math.random(0,digits)
+ end
+ pat = pat .. "\n"
+ end
+ return pat
+end
+
+--- interfacing with life.lua
+
+function mplife.life_frame (frame)
+ --local c = mplife.setup.current
+
+ mplife.draw_grid(frame)
+
+ return true
+end
+
+function mplife.life_movie (frames, next_page)
+ local c = mplife.setup.current
+ for i, frame in ipairs(frames) do
+ context(c.before_frame)
+ mplife.life_frame(frame)
+ context(c.after_frame)
+ end
+end
+
+function mplife.life_frames ()
+ local c = mplife.setup.current
+
+
+ local frames = gol.frames( c.init, c.rule, c.frames, c.firstframe )
+ mplife.life_movie( frames, false )
+ return true
+end
+
+function mplife.gol_successive ()
+ local c = mplife.setup.current
+ local settings = {}
+ if mplife.slides then
+ settings.color = "\\MPcolor{simpleslides:contrastcolor}"
+ else
+ context.definecolor({ "automaton:color" }, c.color)
+ settings.color = "\\MPcolor{automaton:color}"
+ end
+ context(c.before_frame)
+ mplife.draw_grid(c.last, settings)
+ context(c.after_frame)
+ mplife.setup.current.last = gol.next_frame( c.last, c.rule )
+ return true
+end
+
+function mplife.eca_successive ()
+ local c = mplife.setup.current
+ local settings = {}
+
+ if mplife.slides then
+ settings.color = "\\MPcolor{simpleslides:contrastcolor}"
+ else
+ context.definecolor({ "automaton:color" }, c.color)
+ settings.color = "\\MPcolor{automaton:color}"
+ end
+
+ local thisframe
+
+ mplife.setup.current.init, thisframe = eca.gen_frame(c.init, c.framesize, c.rule)
+ context(c.before_frame)
+ mplife.draw_grid(thisframe, settings)
+ context(c.after_frame)
+ return true
+end
+
+function mplife.main ()
+ local c = mplife.setup.current
+
+ if context then
+ context.definecolor({ "lifesquare" }, c.color)
+ end
+ --mplife.successive()
+ --context(c.preamble) -- only once
+ --context.starttext()
+
+ --mplife.runcode (mplife.checker(20))
+
+ --mplife.draw_grid(mplife.rand_pattern(10,6))
+
+ --mplife.life_frames()
+
+ --for i=1,10,1 do
+ --context("\\input knuth")
+ --context.page()
+ --end
+ --context.stoptext()
+ return 0
+end
+
+
+if not mplife.slides then -- standalone
+ return mplife.main()
+end
diff --git a/module/tex/context/third/simpleslides/automata/automatarc-global.lua b/module/tex/context/third/simpleslides/automata/automatarc-global.lua
new file mode 100644
index 0000000..22f8fd9
--- /dev/null
+++ b/module/tex/context/third/simpleslides/automata/automatarc-global.lua
@@ -0,0 +1,63 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: automatarc-global.lua
+-- USAGE: with ConTeXt
+-- DESCRIPTION: default settings for the automaton module
+-- AUTHOR: Philipp Gesang (Phg), <megas.kapaneus@gmail.com>
+-- VERSION: 1.0
+-- CREATED: 13/08/10 10:35:46 CEST
+--------------------------------------------------------------------------------
+--
+
+if not mplife then return 1 end
+
+mplife.setup.global = {}
+
+do
+ local c = {}
+
+-- c.file = "sships.gol"
+-- c.init = gol.parse_file(c.file)
+-- c.last = c.init -- for successive mode
+
+ c.rule = gol.parse_rule("B3/S23") -- default Conway
+
+ c.aspect = 3/4 -- actually 1/(x/y), for eca mode
+
+ c.extendxy = 0
+ c.extendx = 0
+ c.extendy = 0
+
+ c.pensize = .1
+ c.color = { r = .6, g = .6, b = .8 }
+ c.opacity = 1/3
+ c.fade = true
+ c.gestalt = "unitsquare" -- try "unitcircle"
+
+ c.firstframe = 1
+ c.frames = 5
+
+ c.preamble = [[
+\setupcolors[state=start]
+\setupbackgrounds[state=start]
+\setuppapersize[S6][S6]
+
+\setuppagenumbering[state=stop,location=]
+
+\defineoverlay[back][\ctxlua{mplife.successive()}]
+
+\setupbackgrounds [page] [background=back]
+]]
+ c.before_frame = [[
+\startMPcode
+pickup pencircle xyscaled (.25*]] .. c.pensize .. [[pt, ]] .. c.pensize .. [[pt) rotated 45;
+]]
+ c.after_frame = [[
+currentpicture := currentpicture xysized (\the\paperwidth, \the\paperheight);
+\stopMPcode
+]]
+
+ mplife.setup.global = c
+end
+
+return mplife.setup.global
diff --git a/module/tex/context/third/simpleslides/automata/parsers/parser-rle.lua b/module/tex/context/third/simpleslides/automata/parsers/parser-rle.lua
new file mode 100644
index 0000000..e51eeea
--- /dev/null
+++ b/module/tex/context/third/simpleslides/automata/parsers/parser-rle.lua
@@ -0,0 +1,95 @@
+-- http://psoup.math.wisc.edu/mcell/ca_files_formats.html#RLE
+local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match
+
+local rows = {}
+local coords = {}
+
+local n_row = 1
+rows[n_row] = ""
+
+local eol = P"\n"
+local hashmark = P"#"
+local space = S" \t"
+local whitespace = S(" \n\t")^0
+local num = R"09"
+local comma = P","
+local exclam = P"!"
+local equals = P"="
+local dollar = P"$"
+local state = S"bo"
+--local sign = S("+-")^0 -- support negative grid values? not yet, if ever…
+
+local comment = hashmark * (1-eol)^0 * eol
+
+local getx = space^0 * P"x" * space^0 * equals * space^0 * C(num^1) / function (x)
+ coords.x = tonumber(x)
+end
+local gety = space^0 * P"y" * space^0 * equals * space^0 * C(num^1) / function (y)
+ coords.y = tonumber(y)
+end
+geometry = getx * comma * gety * (1-eol)^0 * eol
+
+local function n_of_t (n, c)
+ local tmp = ""
+ if c == "o" then -- live
+ c = "1"
+ else -- dead
+ c = "0"
+ end
+
+ for i=1, n, 1 do
+ tmp = tmp .. c
+ end
+ return tmp
+end
+
+local cell = C(num^0) * C(state) / function (n, c)
+ if n == "" then
+ n = 1
+ end
+
+ if n_of_t (tonumber(n), c) == nil then
+ end
+ rows[n_row] = rows[n_row] .. n_of_t (tonumber(n), c)
+end
+
+local line = whitespace * (cell * whitespace)^0 * C(num^0) / function (empty)
+
+ if rows[n_row]:len() < coords.x then -- fill grid with dead cells
+ rows[n_row] = rows[n_row] .. n_of_t( coords.x - rows[n_row]:len(), "0" )
+ end
+
+ if empty ~= "" then
+ for n=1, tonumber(empty)-1, 1 do
+ n_row = n_row + 1
+ rows[n_row] = n_of_t( coords.x, "0" )
+ end
+ end
+
+ n_row = n_row + 1
+
+ if n_row <= coords.y then
+ rows[n_row] = ""
+ end
+end
+
+local p_rle = comment^0 * geometry * line * (dollar * line)^0 * whitespace * exclam
+
+function gol.rleparser(fname)
+ local file = assert(io.open(fname, "r"), "Not a file: " .. fname)
+ local data = file:read("*all")
+ file:close()
+
+ if p_rle:match(data) then
+ if context then
+ context.writestatus("simpleslides", "Sucessfully loaded frame from "..fname..".")
+ end
+ return rows
+ else
+ if context then
+ context.writestatus("simpleslides", "There were problems loading file "..fname..".")
+ end
+ return false
+ end
+end
+
diff --git a/module/tex/context/third/simpleslides/simpleslides-s-Automaton.tex b/module/tex/context/third/simpleslides/simpleslides-s-Automaton.tex
new file mode 100644
index 0000000..0fa089a
--- /dev/null
+++ b/module/tex/context/third/simpleslides/simpleslides-s-Automaton.tex
@@ -0,0 +1,261 @@
+%D \module
+%D [ file=simpleslides-s-Automaton,
+%D version=2010-08-10-15:28:22+0200,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Module --- Automaton Style,
+%D author=Philipp Gesang,
+%D date=\currentdate,
+%D copyright={Philipp Gesang}]
+%C
+%C Copyright 2007 Aditya Mahajan and Thomas A. Schmitz
+%C This file may be distributed under the GNU General Public License v. 2.0.
+%C Modified 2010 by Philipp Gesang
+
+%D Providing presentation Backgrounds according to Conway's Game of Life.
+%D Initially based on the BigNumber theme by A. Mahajan and Th. Schmitz. (Many,
+%D many thanks!)
+
+\writestatus{simpleslides}{loading Theme Automata}
+
+\startmodule[simpleslides-s-Automaton]
+
+\setupmodule[
+ mode=,
+ file=,
+ rule=,
+ extendxy=,
+ clip=,
+] % using defaults from lua config
+
+\ctxlua{environment.loadluafile( "automata-main" )}
+\ctxlua{mplife.slides = true}
+
+\unprotect
+
+%D First, we change the page layout to have more space all around
+
+\setuplayout [ width=fit,
+ margin=2cm,
+ height=fit,
+ leftmargindistance=.2cm,
+ rightmargindistance=.2cm,
+ header=18mm,
+ headerdistance=.3cm,
+ footer=0cm,
+ footerdistance=0mm,
+ topspace=.5cm,
+ backspace=1.9cm,
+ location=singlesided]
+
+\setuplayout [simpleslides:layout:horizontal][header=14mm]
+\setuplayout [simpleslides:layout:vertical] [header=0mm]
+\setuplayout [simpleslides:layout:title]
+
+\setuplayer[simpleslides:layer:slidetitle]
+ [width=\paperwidth,
+ height=\paperheight,x=20mm]
+
+%D Next we a generic frames, which will be used by other macros to
+%D get a consistent look and feel.
+
+\defineframed[simpleslides:framed:small]
+ [ frame=off,
+ offset=0pt,
+ width=1.7cm,
+ align=middle]
+
+\setupcombinations[distance=2.5em]
+
+%D These macros are used for placing figures/pictures:
+
+\define\NormalHeight {\textheight}
+\define\NormalWidth {.46\textwidth}
+\define\PictureFrameHeight {\textheight}
+\define\PictureFrameWidth {.46\textwidth}
+
+%D This module has two color schemes, a blue one and a red one.
+
+\startsetups simpleslides:setups:blue
+\definecolor [simpleslides:contrastcolor] [r=0.7,g=0.7,b=0.9]
+%\definecolor [simpleslides:backgroundcolor] [s=1]
+\definecolor [simpleslides:backgroundoutside] [r=0.9,g=0.9,b=0.95]
+\definecolor [simpleslides:backgroundscreen] [s=.975]
+\definecolor [simpleslides:textcolor] [s=0]
+\stopsetups
+
+\startsetups simpleslides:setups:red
+\definecolor [simpleslides:contrastcolor] [r=0.4]
+%\definecolor [simpleslides:backgroundcolor] [s=.95]
+\definecolor [simpleslides:backgroundoutside] [r=0.5,g=0.2,b=0.2]
+\definecolor [simpleslides:backgroundscreen] [s=.4]
+\definecolor [simpleslides:textcolor] [s=1]
+\stopsetups
+
+%D Now we choose the scheme that the user asked for
+
+\doifsetupselse
+ {simpleslides:setups:\moduleparameter{simpleslides}{color}}
+ {\setups{simpleslides:setups:\moduleparameter{simpleslides}{color}}}
+ {\setups{simpleslides:setups:blue}}
+
+\setupcolors[textcolor={simpleslides:textcolor}]
+
+%D Set the initial snapshot (from file) and the rule, if given.
+
+\doifsomethingelse{\moduleparameter{simpleslides}{mode}}
+{\ctxlua{
+mplife.setup.current.mode = "\luaescapestring{\moduleparameter{simpleslides}{mode}}"
+if mplife.setup.current.mode == "life" then
+ mplife.successive = mplife.gol_successive
+else
+ environment.loadluafile("automata-eca")
+ mplife.successive = mplife.eca_successive
+end}}
+{\ctxlua{mplife.successive = mplife.gol_successive}}
+
+%D The number of dead cells to add left and right / before and after
+%D the initial frame.
+
+\doifsomething{\moduleparameter{simpleslides}{extendxy}}{\ctxlua
+ {mplife.setup.current.extendx = tonumber("\luaescapestring{\moduleparameter{simpleslides}{extendxy}}")
+ mplife.setup.current.extendy = tonumber("\luaescapestring{\moduleparameter{simpleslides}{extendxy}}") }}
+
+\doifsomething{\moduleparameter{simpleslides}{extendx}}{\ctxlua
+ {mplife.setup.current.extendx = tonumber("\luaescapestring{\moduleparameter{simpleslides}{extendx}}") }}
+
+\doifsomething{\moduleparameter{simpleslides}{extendy}}{\ctxlua
+ {mplife.setup.current.extendy = tonumber("\luaescapestring{\moduleparameter{simpleslides}{extendy}}") }}
+
+\doifsomething{\moduleparameter{simpleslides}{file}}{\ctxlua{
+mplife.setup.current.file = "\luaescapestring{\moduleparameter{simpleslides}{file}}"
+}}
+
+\doifsomething{\moduleparameter{simpleslides}{clip}}{\ctxlua
+ {mplife.setup.current.clip = "\luaescapestring{\moduleparameter{simpleslides}{clip}}" }}
+
+\startluacode
+do
+ local c = mplife.setup.current
+ if c.mode == "life" then
+ c.init = gol.parse_file(c.file)
+ c.last = c.init
+ else
+ c.init = eca.parse_file(c.file)
+ c.framesize = math.floor(c.aspect * c.init:len())
+ c.pages = structure.counters.record("realpage")["last"]
+ -- Clipping is essential to cope with left/right propagation of
+ -- patterns. E.g. with rule 158 the total propagation at iteration
+ -- n is itself n to the left and n to the right. Whereas rule 102
+ -- (a Sierpiński fractal generator) protrudes only to the left at
+ -- a rate of n.
+ -- Frames cannot be simply cut off at the borders with adjacient
+ -- cells treated as “dead” because it would distort the pattern.
+ -- Therefore, frames are generated as complete sections which are
+ -- clipped to the desired size, as specified by the initial row.
+ -- To determine whether to clip your pattern to the left, right,
+ -- or in both directions, check the propagation at
+ -- string.format("http://mathworld.wolfram.com/Rule%s.html", rule)
+ -- or consult Wolfram's “A New Kind of Science” but beware not to
+ -- buy everything he claims…
+ if c.clip then
+ c.xneeded = c.pages * c.framesize
+ if c.clip == "both" then -- Assume initial pattern is centered.
+ c.diff = c.xneeded - math.ceil(c.init:len()/2)
+ else
+ c.diff = c.xneeded - c.init:len()
+ end
+ if c.diff > 0 then
+ local affix = ""
+ for i=1, c.diff, 1 do
+ affix = affix .. "0"
+ end
+ if c.clip == "left" or c.clip == "both" then
+ c.init = affix .. c.init
+ end
+ if c.clip == "right" or c.clip == "both" then
+ c.init = c.init .. affix
+ end
+ end
+ end
+ end
+ mplife.setup.current = c
+end
+\stopluacode
+
+\doifsomething{\moduleparameter{simpleslides}{rule}}{\ctxlua{
+if mplife.setup.current.mode == "life" then
+ mplife.setup.current.rule = gol.parse_rule("\luaescapestring{\moduleparameter{simpleslides}{rule}}")
+else
+ mplife.setup.current.rule = eca.gen_rule(tonumber("\luaescapestring{\moduleparameter{simpleslides}{rule}}"))
+end
+}}
+
+%D We also use \METAPOST\ to draw the horizontal and vertical page backgrounds.
+%D Backgrounds will be of solid color, the ornament gets the transparency.
+
+\startuniqueMPgraphic{simpleslides:MP:horizontal}
+StartPage ;
+fill Page withcolor \MPcolor{simpleslides:backgroundoutside} ;
+fill Field[Text][Text] enlarged 0.2cm
+ withcolor \MPcolor{simpleslides:backgroundscreen} ;
+StopPage ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{simpleslides:MP:vertical}
+StartPage ;
+fill Page withcolor \MPcolor{simpleslides:backgroundoutside} ;
+
+z1 = urcorner Field[Text][Text] shifted (.2cm,0) ;
+z2 = lrcorner Field[Text][Text] shifted (.2cm,-.2cm) ;
+z3 = z1 shifted (-8.05cm,0) ;
+z4 = (x3,y2) ;
+
+save Main ;
+path Main ;
+Main := z1 -- z2 -- z4 -- z3 --cycle ;
+
+fill Main withcolor \MPcolor{simpleslides:backgroundscreen} ;
+StopPage ;
+\stopuniqueMPgraphic
+
+
+%D We define these backgrounds as overlays:
+
+\defineoverlay
+ [simpleslides:background:horizontal]
+ [\useMPgraphic{simpleslides:MP:horizontal}]
+
+\defineoverlay
+ [simpleslides:background:vertical]
+ [\useMPgraphic{simpleslides:MP:vertical}]
+
+\defineoverlay
+ [simpleslides:background:title]
+ [\useMPgraphic{simpleslides:MP:horizontal}]
+
+\defineoverlay
+ [simpleslides:background:ornament]
+ [\ctxlua{mplife.successive()}]
+
+%D The slide title is placed on the top of the text area. The layer takes care
+%D of the positioning.
+
+\setupSlideTitle
+ [\c!after=,
+ \c!alternative=layer,
+ \c!width=\textwidth,
+ \c!height=2.5cm,
+ \c!command=\doSlideTitle]
+
+
+%D Squares are used as the first level of itemizations
+
+\definesymbol[1][$\square$]
+\setupitemize[1][inmargin]
+%\setupitemize[each][joinedup,unpacked]
+
+\protect
+\stopmodule
+
+\endinput
+