|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LUA/Maxima3.lua.html
-- http://anggtwu.net/LUA/Maxima3.lua
-- (find-angg "LUA/Maxima3.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2025dec24
-- Public domain.
--
-- My current way of LaTeXing Maxima logs is, or would be,
-- explained in these places:
-- https://anggtwu.net/eev-emaxima.html
-- https://anggtwu.net/eev-maxima.html#embedding-in-LaTeX
-- (find-angg "MAXIMA/2025-emaxima.mac")
--
-- See: (find-angg "MAXIMA/2025-baf-qparts.mac")
-- (find-Maxima3-links)
--
-- (defun e () (interactive) (find-angg "LUA/Maxima3.lua"))
-- (defun o () (interactive) (find-angg "LUA/Maxima2.lua"))
-- (defun oe () (interactive) (find-2a '(o) '(e)))
--
-- «.MaximaIO» (to "MaximaIO")
-- «.MaximaIO-split» (to "MaximaIO-split")
-- «.MaximaIO-tex» (to "MaximaIO-tex")
-- «.MaximaIO-changeinput» (to "MaximaIO-changeinput")
-- «.MaximaIO-tests» (to "MaximaIO-tests")
-- «.MaximaIO-tex-tests» (to "MaximaIO-tex-tests")
-- «.MaximaIO-changeinput-tests» (to "MaximaIO-changeinput-tests")
-- «.MaximaBlock» (to "MaximaBlock")
-- «.MaximaBlock-tests» (to "MaximaBlock-tests")
-- «.SplitIntoMIOs» (to "SplitIntoMIOs")
-- «.SplitIntoMIOs-tests» (to "SplitIntoMIOs-tests")
-- «.SplitIntoBlocks» (to "SplitIntoBlocks")
-- «.SplitIntoBlocks-tests» (to "SplitIntoBlocks-tests")
-- «.MaximaHead» (to "MaximaHead")
-- «.MaximaHead-tests» (to "MaximaHead-tests")
-- «.log-to-i» (to "log-to-i")
require "Co1" -- (find-angg "LUA/Co1.lua")
-- require "Pict3" -- (find-angg "LUA/Pict3.lua")
-- __ __ _ ___ ___
-- | \/ | __ ___ _(_)_ __ ___ __ _|_ _/ _ \
-- | |\/| |/ _` \ \/ / | '_ ` _ \ / _` || | | | |
-- | | | | (_| |> <| | | | | | | (_| || | |_| |
-- |_| |_|\__,_/_/\_\_|_| |_| |_|\__,_|___\___/
--
-- «MaximaIO» (to ".MaximaIO")
-- This is one of the main data structures, and its methods are a
-- kitchen sink. When we parse the contents of a "*maxima*" buffer
-- each "pair of lines with complications" like this
--
-- (%i1) 2+3;
-- (%o1) 5
--
-- becomes a MaximaIO object; the basic "complications" are that the
-- output line is optional and that the input may span several lines.
-- When we export the "pair with complications" above to a Dednat7
-- block in a .tex file it becomes this,
--
-- %M (%i1) 2+3;
-- %M (%o1) 5
--
-- and the method `totexrect' converts that MaximaIO object to
-- something like this:
--
-- \maximablue{(\%i1)\ 2+3;}
-- \maximared{(\%o1)\ }{}
-- \maximared{}{ 5}
-- \maximared{}{}
--
MaximaIO = Class {
type = "MaximaIO",
__tostring = function (mio) return mio:tostructrect():tostring() end,
__index = {
-- The state machine in the parser uses `:push'
-- to add lines to .i, .ip, or .o
push = function (mio,name,line)
mio[name] = mio[name] or Rect {}
table.insert(mio[name], line)
return mio
end,
--
-- An output format that shows the structure
rnamed = function (mio,name)
if not mio[name] then return Rect {} end
if #mio[name]==0 then return Rect {} end
local right = Rect(copy(mio[name]))
local left = Rect {format("%-3s ", name..":")}
return left..right
end,
tostructrect = function (mio)
return mio:rnamed"i" / mio:rnamed"ip" / mio:rnamed"o"
end,
--
-- An output format that reconstructs the original lines
r = function (mio,name)
if not mio[name] then return Rect {} end
if #mio[name]==0 then return Rect {} end
return Rect(copy(mio[name]))
end,
torect = function (mio,fmt)
local rect = mio:r"i" / mio:r"ip" / mio:r"o"
for i=1,#rect do rect[i] = format(fmt or "%s", rect[i]) end
return rect
end,
toMrect = function (mio) return mio:torect("%%M %s") end,
--
-- «MaximaIO-split» (to ".MaximaIO-split")
-- Most functions in this block are used by both totexrect and changeinput
match = function (mio,str,pat)
local result = str:match(pat)
if not result then PP("Doesn't match:", pat, str); error("") end
return result
end,
left = function (mio,line) return mio:match(line, "^(%(%%[io][0-9]+%) ?).*") end,
right = function (mio,line) return mio:match(line, "^%(%%[io][0-9]+%) ?(.*)") end,
spaces = function (mt,line) return (mt:left(line):gsub(".", " ")) end,
indent = function (mt,iline,ipline) return mt:spaces(iline)..ipline end,
--
-- «MaximaIO-tex» (to ".MaximaIO-tex")
-- An output format that return `\maximablue' and `\maximared' lines
co = Co.new(" \\%{}$_", "^~"),
cot = function (mio,str) return mio.co:translate(str) end,
blue0 = function (mio,a) return format("\\maximablue{%s}", a) end,
red0 = function (mio,a,b) return format("\\maximared{%s}{%s}", a,b) end,
blue = function (mio,a) return mio:blue0(mio:cot(a)) end,
red = function (mio,a,b) return mio:red0 (mio:cot(a), b) end,
blue1 = function (mio,iline) return mio:blue(iline) end,
blue2 = function (mio,iline,ipline) return mio:blue1(mio:indent(iline,ipline)) end,
red1 = function (mio,line) return mio:red(mio:left(line),mio:right(line)) end,
redleft = function (mio,line) return mio:red(mio:left(line),"") end,
redright = function (mio,line) return mio:red("",mio:right(line)) end,
totexrect = function (mio)
local iline = mio.i[1]
local irect = Rect {mio:blue1(iline)}
local iprect = Rect {}
local orect = Rect {}
for _,ipline in ipairs(mio.ip or {}) do
table.insert(iprect, mio:blue2(iline,ipline))
end
for _,oline in ipairs(mio.o or {}) do
table.insert(orect, mio:redleft(oline))
table.insert(orect, mio:redright(oline))
table.insert(orect, mio:red0("",""))
end
return irect / iprect / orect
end,
--
-- «MaximaIO-changeinput» (to ".MaximaIO-changeinput")
-- The "input" is stored in:
-- .i: the first line, like {"(%i42) [3,"}, and
-- .ip: the other lines, line {" 4,", " 5];"}.
-- The functions below are used by SplitIntoBlocks, that modifies
-- the input lines in .i and .ip to delete some blank lines and
-- the things like "/* block foo */"s.
--
ileft = function (mio) return mio:left (mio.i[1]) end,
iright = function (mio) return mio:right(mio.i[1]) end,
toinputrect = function (mio)
local irect = Rect {mio:iright()}
local iprect = mio.ip and Rect(copy(mio.ip)) or Rect {}
return irect / iprect
end,
toinputstring = function (mio) return mio:toinputrect():tostring() end,
changeinput = function (mio,newinputstring)
local r = Rect.from(newinputstring)
local r1 = table.remove(r, 1)
local i1 = mio:ileft()..(r1 or "")
mio = copy(mio)
mio.i = Rect {i1}
mio.ip = (#r > 0) and r or nil
return mio
end,
cleanblockname0 = function (mio,inputstring)
local blockname
local pat = "^\n*/%* block ([ -~]+) %*/\n(.*)$"
local bn,rest = inputstring:match(pat)
if bn then blockname,inputstring = bn,rest end
local newinputstring = inputstring:gsub("%$\n*$", "$")
return newinputstring,blockname
end,
cleanblockname = function (mio)
local inputstring = mio:toinputstring()
local newinputstring,blockname = mio:cleanblockname0(inputstring)
local newmio = mio:changeinput(newinputstring)
return newmio,blockname
end,
},
}
maximaio_test1 = MaximaIO {
i = {"(%i1) /* block foo */"},
ip = {"[2,", " 3];"},
o = {"(%o1) [2, 3]"}
}
maximaio_test2 = MaximaIO {
i = {"(%i2) 3+4;"},
o = {"(%o2) 7"}
}
maximaio_test3 = MaximaIO {
i = {"(%i2) 3+4$"}
}
-- «MaximaIO-tests» (to ".MaximaIO-tests")
-- «MaximaIO-tex-tests» (to ".MaximaIO-tex-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
m = maximaio_test2
m = maximaio_test3
m = maximaio_test1
= m:rnamed"i"
= m:rnamed"i" / m:rnamed"ip"
= m:rnamed"i" / m:rnamed"ip" / m:rnamed"foo"
= m:torect()
= m:toMrect()
= m:totexrect()
--]]
-- «MaximaIO-changeinput-tests» (to ".MaximaIO-changeinput-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
PP(m:cleanblockname0 "\n\n\n/* block foo */\nabc\ndef$\n\n")
PP(m:cleanblockname0 "\n\n\n/* block foo */\nabc\ndef;")
PP(m:cleanblockname0 "abc\ndef$\n\n")
PP(m:cleanblockname0 "abc\ndef;")
= maximaio_test1;
= maximaio_test1:changeinput("a");
= maximaio_test1:changeinput("a\nb");
= maximaio_test1:changeinput("a\nb\nc");
= maximaio_test1;
= maximaio_test1:cleanblockname();
= maximaio_test2;
= maximaio_test2:cleanblockname();
m = deepcopy(maximaio_test1)
= m
= m:push("o","f")
= m:push("o","g")
m = maximaio_test1
= m
= m:totexrect(m)
= m:toinputrect()
= m:toinputstring()
= m:changeinput("bla")
= m:changeinput("bla\nbla")
= m
--]]
-- __ __ _ ____ _ _
-- | \/ | __ ___ _(_)_ __ ___ __ _| __ )| | ___ ___| | __
-- | |\/| |/ _` \ \/ / | '_ ` _ \ / _` | _ \| |/ _ \ / __| |/ /
-- | | | | (_| |> <| | | | | | | (_| | |_) | | (_) | (__| <
-- |_| |_|\__,_/_/\_\_|_| |_| |_|\__,_|____/|_|\___/ \___|_|\_\
--
-- A MaximaBlock contains a list of MaximaIO objects and an optional
-- block name. MaximaBlocks without names and MaximaBlocks with names
-- serve different purposes, and one stage of the parsing process
-- converts, or splits, a MaximaBlock without name into several
-- MaximaBlocks with names. For example, suppose that we ran Maxima
-- and it produced a "*maxima*" buffer whose "log" part is this:
--
-- (%i1) /* block n-ary `=' */
-- nary("=.")$
-- (%i2) a =. b =. c;
-- (%o2) a =. b =. c
-- (%i3) /* block etc */
-- 2+3;
-- (%o3) 5
--
-- The class SplitIntoMIOs parses that and returns a single MaximaBlock
-- with no block name; the class SplitIntoBlocks parses that and returns
-- two `MaximaBlock's with names, that correspond to:
--
-- (block n-ary `=')
-- (%i1) nary("=.")$
-- (%i2) a =. b =. c;
-- (%o2) a =. b =. c
--
-- (block etc)
-- (%i3) 2+3;
-- (%o3) 5
--
-- Note that the MaximaIOs for (%i1) had their input parts modified.
--
-- «MaximaBlock» (to ".MaximaBlock")
MaximaBlock = Class {
type = "MaximaBlock",
__tostring = function (mb) return mb:struct():tostring() end,
__index = {
methodrect = function (mb,method)
local bigrect = Rect {}
for _,mio in ipairs(mb) do bigrect = bigrect / mio[method](mio) end
return bigrect
end,
--
namestr = function (mb) return mb.name or "<nil>" end,
struct = function (mb)
return Rect {"",
format("(block %s)", mb:namestr())}
/ mb:methodrect("tostructrect")
end,
--
ML = function (mb)
return mb:methodrect("toMrect")
/ Rect {"%L",
format('%%L maximahead:sa("%s", "")', mb:namestr()),
"\\pu"}
end,
--
ga = function (mb)
return Rect {format("\\maximagavbox{0cm}{9cm}{%s}", mb:namestr())}
end,
--
maximaboxes = function (mb) return mb:methodrect("totexrect") end,
maximaboxes1 = function (mb) return table.concat(mb:maximaboxes()) end,
vbox = function (mb,vbox)
return format("%s{%s}", vbox or "\\maximavbox", mb:maximaboxes1())
end,
sa = function (mb,altname)
return format("\\sa{%s}{%s}", altname or mb:namestr(), mb:vbox())
end,
},
}
maximablock_test = MaximaBlock {
maximaio_test1,
maximaio_test2,
maximaio_test3
}
-- «MaximaBlock-tests» (to ".MaximaBlock-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
= maximablock_test
= maximablock_test:struct()
= maximablock_test:ML()
= maximablock_test:ga()
= maximablock_test:maximaboxes()
= maximablock_test:vbox()
= maximablock_test:sa()
--]]
-- ____ _ _ _ ___ _ __ __ ___ ___
-- / ___| _ __ | (_) |_|_ _|_ __ | |_ ___ | \/ |_ _/ _ \ ___
-- \___ \| '_ \| | | __|| || '_ \| __/ _ \| |\/| || | | | / __|
-- ___) | |_) | | | |_ | || | | | || (_) | | | || | |_| \__ \
-- |____/| .__/|_|_|\__|___|_| |_|\__\___/|_| |_|___\___/|___/
-- |_|
--
-- The class SplitIntoMIOs parses the lines of a "*maxima*" buffer and
-- uses a state machine to discard the initial lines and split the
-- other ones into "mio"s, i.e., into MaximaIO objects. For example,
-- suppose that our "*maxima*" buffer contained this,
--
-- Maxima 5.49
-- Distributed under the GNU GPL
-- (%i1) [2,
-- 3];
-- (%o1) [2,3]
--
-- and we saved that into a file, and we are using SplitIntoMIOs to
-- process the lines of that file. Then:
--
-- a) in its lines 1, 2 and 4 the "io character", or "ioc", is nil,
-- b) in the line 3 the ioc is "i",
-- c) in the line 5 the ioc is "o",
-- d) the initial "state" is nil.
--
-- Here's how the state machine handles all that...
--
-- e) in the lines 1 and 2 we have state==nil and ioc==nil; these
-- lines are discarded. Internally what happens there is that in
-- :addline_inner(...) these lines run the case associated with
-- "_->_", that just returns newstate=nil;
--
-- f) in the line 3 we have state==nil and ioc=="i". This runs the
-- case tr=="_->i", that runs :addmio(), then makes that line the
-- only element in the .i of that mio, and returns newstate="i";
--
-- g) in the line 4 we have state=="i" and ioc==nil; this runs the
-- case tr=="i->_", that pushes that line into the .ip of the
-- current mio, and keeps the state as "i"...
--
-- etc, etc, etc - the actions of the other lines are easy to
-- understand.
--
-- «SplitIntoMIOs» (to ".SplitIntoMIOs")
SplitIntoMIOs = Class {
type = "SplitIntoMIOs",
new = function () return SplitIntoMIOs {mios=MaximaBlock{}} end,
fromlines = function (lines) return SplitIntoMIOs.new():addlines(lines) end,
linestoblock = function (lines) return SplitIntoMIOs.fromlines(lines).mios end,
__tostring = function (sim) return sim:tostructrect():tostring() end,
__index = {
tostructrect = function (sim)
local bigrect = Rect {}
for i=1,#sim.mios do
local leftrect = Rect {format("mios[%d]: ", i)}
local rightrect = MaximaIO(copy(sim.mios[i])):tostructrect()
bigrect = bigrect / (leftrect .. rightrect)
end
return bigrect
end,
addmio = function (sim) table.insert(sim.mios, MaximaIO{}); return sim end,
lastmio = function (sim) return sim.mios[#sim.mios] end,
push = function (sim,name,line) sim:lastmio():push(name,line); return sim end,
splitline = function (sim,line)
local ioc,n,body = line:match("^%(%%([io])([0-9]+)%) ?(.*)")
if ioc
then return ioc,n,body
else return nil,nil,line -- if ioc==nil the whole line becomes the body
end
end,
addline_inner = function (sim,state,ioc,line) -- returns newstate
local tr = (state or "_").."->"..(ioc or "_")
if tr=="_->_" then return nil end
if tr=="_->i" then sim:addmio():push("i", line); return "i" end
if tr=="i->i" then sim:addmio():push("i", line); return "i" end
if tr=="o->i" then sim:addmio():push("i", line); return "i" end
if tr=="i->_" then sim :push("ip",line); return "i" end
if tr=="i->o" then sim :push("o", line); return "o" end
error("Bad transition: %s", tr)
end,
addline = function (sim,line)
local ioc,n,body = sim:splitline(line)
local state = sim.state
local newstate = sim:addline_inner(state,ioc,line)
sim.state = newstate
return sim
end,
addlines = function (sim,lines)
if type(lines)=="string" then lines = splitlines(lines) end
for _,line in ipairs(lines) do sim:addline(line) end
return sim
end,
},
}
splitintomios_test = Rect {
"(%i1) /* block n-ary `=' */",
"nary(\"=.\")$",
"(%i2) a =. b =. c;",
"(%o2) a =. b =. c",
"(%i3) /* block etc */",
"2+3",
" +4;",
"(%o3) 9"
}
-- «SplitIntoMIOs-tests» (to ".SplitIntoMIOs-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
sim = SplitIntoMIOs {mios={
maximaio_test1,
maximaio_test2,
maximaio_test3,
}}
= sim
= sim:tostructrect()
sim = SplitIntoMIOs.fromlines(splitintomios_test)
= sim
--]]
-- ____ _ _ _ ___ _ ____ _ _
-- / ___| _ __ | (_) |_|_ _|_ __ | |_ ___ | __ )| | ___ ___| | _____
-- \___ \| '_ \| | | __|| || '_ \| __/ _ \| _ \| |/ _ \ / __| |/ / __|
-- ___) | |_) | | | |_ | || | | | || (_) | |_) | | (_) | (__| <\__ \
-- |____/| .__/|_|_|\__|___|_| |_|\__\___/|____/|_|\___/ \___|_|\_\___/
-- |_|
--
-- «SplitIntoBlocks» (to ".SplitIntoBlocks")
SplitIntoBlocks = Class {
type = "SplitIntoBlocks",
new = function () return SplitIntoBlocks {blocks={}} end,
frombigblock = function (bigblock) return SplitIntoBlocks.new():addmios(bigblock) end,
splitbigblock = function (bigblock) return SplitIntoBlocks.frombigblock(bigblock).blocks end,
fromlines = function (lines)
local bigblock = SplitIntoMIOs.linestoblock(lines)
return SplitIntoBlocks.frombigblock(bigblock)
end,
__tostring = function (sib) return sib:tostructrect():tostring() end,
__index = {
tostructrect = function (sib)
local bigrect = Rect {"Named blocks:"}
for _,block in ipairs(sib.blocks) do
bigrect = bigrect / block:struct()
end
return bigrect
end,
--
lastblock = function (sib) return sib.blocks[#sib.blocks] end,
addmio_named = function (sib,newmio,blockname)
local newblock = MaximaBlock {name=blockname, newmio}
table.insert(sib.blocks, newblock)
end,
addmio_unnamed = function (sib,newmio)
if not sib:lastblock() then return end -- discard
table.insert(sib:lastblock(), newmio)
end,
addmio = function (sib,mio)
local newmio,blockname = mio:cleanblockname()
if blockname
then sib:addmio_named (newmio,blockname)
else sib:addmio_unnamed(newmio)
end
end,
addmios = function (sib,bigblock)
for _,mio in ipairs(bigblock) do sib:addmio(mio) end
return sib
end,
--
MLs = function (sib)
local f = function (block) return block:ML():tostring() end
return mapconcat(f, sib.blocks, "\n\n")
end,
gas_in_one_slide = function (sib)
local pre = "\\scalebox{0.6}{\\def\\colwidth{9cm}\\firstcol{\n "
local mid = "\n}\\def\\colwidth{9cm}\\anothercol{\n "
local post = "\n}}"
local f = function (block) return block:ga():tostring() end
return pre .. mapconcat(f, sib.blocks, mid) .. post
end,
all_in_one_slide = function (sib)
return sib:MLs() .. "\n\n" .. sib:gas_in_one_slide()
end,
},
}
splitintoblocks_test = Rect {
"(%i0) discard_this$;",
"(%i1) /* block foo */",
"foo$",
"(%i2) /* block bar */",
"bar$",
"(%i3) plic$"
}
-- «SplitIntoBlocks-tests» (to ".SplitIntoBlocks-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
sim = SplitIntoMIOs .fromlines(splitintoblocks_test)
sib = SplitIntoBlocks.fromlines(splitintoblocks_test)
= sim
= sib
= sib.blocks[1]
= sib.blocks[1].name
= sib.blocks[1]:ML()
= sib.blocks[1]:ga()
= sib:MLs()
= sib:gas_in_one_slide()
= sib:all_in_one_slide()
--]]
-- __ __ _ _ _ _
-- | \/ | __ ___ _(_)_ __ ___ __ _| | | | ___ __ _ __| |
-- | |\/| |/ _` \ \/ / | '_ ` _ \ / _` | |_| |/ _ \/ _` |/ _` |
-- | | | | (_| |> <| | | | | | | (_| | _ | __/ (_| | (_| |
-- |_| |_|\__,_/_/\_\_|_| |_| |_|\__,_|_| |_|\___|\__,_|\__,_|
--
-- When Dednat7 processes a block of "%M"-lines like this one
--
-- %M (%i1) sin(x);
-- %M (%o1) \sin x
--
-- it simply saves those lines, minus the "%M"s, into the variable
-- "maximahead.lines". An "%M"-block is usually followed by an
-- "%L"-block and a \pu, like this:
--
-- %M (%i1) sin(x);
-- %M (%o1) \sin x
-- %L
-- %L maximahead:sa("foo", "")
-- \pu
--
-- and that "maximahead:sa("foo", "")" produces/outputs/runs this
-- LaTeX code:
--
-- \sa{foo}{\maximavbox{%
-- \maximablue{(\%i1)\ sin(x);}%
-- \maximared{(\%o1)\ }{}%
-- \maximared{}{\sin x}%
-- \maximared{}{}%
-- }}
--
-- Then running "\ga{foo}" retrieves that \maximavbox.
-- "\sa" and "\ga" are explained here:
-- (find-LATEX "edrx21.sty" "sa-and-ga")
--
-- «MaximaHead» (to ".MaximaHead")
MaximaHead = Class {
type = "MaximaHead",
__index = {
sa = function (mh, name)
local block = SplitIntoMIOs.linestoblock(maximahead.lines)
output(block:sa(name))
end,
},
}
maximahead = MaximaHead {}
registerhead = registerhead or function () return nop end
registerhead "%M" {
name = "maxima",
action = function ()
local i,j,lines = tf:getblock(3)
maximahead.lines = VTable(lines)
end,
}
maximahead_test = Rect {
"(%i1) a,",
"b;",
"(%o1) ab",
"(%i2) c$"
}
-- «MaximaHead-tests» (to ".MaximaHead-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
output = print
maximahead.lines = maximahead_test
maximahead:sa("TEST", "")
bl = SplitIntoMIOs.linestoblock(maximahead.lines)
= bl
= bl:ML()
= bl:sa()
--]]
delete_all_before_first_block = function (bigstr)
local pat = "^.-(%(%%i[0-9]+%)[ \t\n]+/%*)"
return (bigstr:gsub(pat, "%1"))
end
-- «log-to-i» (to ".log-to-i")
-- Converts a log of a Maxima session to some LaTeX/Dednat code
-- that can be inserted into a .tex file with `M-x i'. See:
-- (find-efunction 'find-Maxima3-links)
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Maxima3.lua"
bigstr = ee_readfile "/tmp/o"
= bigstr
bigstr = delete_all_before_first_block(bigstr)
= bigstr
bl = SplitIntoMIOs.linestoblock(bigstr)
= bl
= bl:struct()
bls = SplitIntoBlocks.fromlines(bigstr)
= bls
= bls.blocks[1]
= bls.blocks[1]:maximaboxes()
= bls.blocks[1]:sa()
= bls.blocks[1]:ga()
o2 = bls:all_in_one_slide()
------
= o2
------
ee_writefile("/tmp/o2", o2)
** (find-fline "/tmp/o2")
* (defun i () (interactive) (insert-file "/tmp/o2"))
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: