summaryrefslogtreecommitdiff
path: root/tex/context/base/m-spreadsheet.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/m-spreadsheet.mkiv')
-rw-r--r--tex/context/base/m-spreadsheet.mkiv295
1 files changed, 123 insertions, 172 deletions
diff --git a/tex/context/base/m-spreadsheet.mkiv b/tex/context/base/m-spreadsheet.mkiv
index 839214096..ed9a92d05 100644
--- a/tex/context/base/m-spreadsheet.mkiv
+++ b/tex/context/base/m-spreadsheet.mkiv
@@ -13,192 +13,139 @@
%D This is an experimental follow up on discussion on the mailing list.
-\startluacode
-local byte, format = string.byte, string.format
-local R, P, C, Cs, Cc, Carg, lpegmatch = lpeg.R, lpeg.P, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Carg, lpeg.match
-
-local spreadsheets = { }
-moduledata.spreadsheets = spreadsheets
-
-local data = { }
-spreadsheets.data = data
-
-local stack, current = { }, "default"
-
-local mt ; mt = {
- __index = function(t,k)
- local v = { }
- setmetatable(v,mt)
- t[k] = v
- return v
- end,
-}
-
-function spreadsheets.reset(name)
- if not name or name == "" then name = "default" end
- local d = { }
- setmetatable(d,mt)
- data[name] = d
-end
-
-function spreadsheets.start(name)
- if not name or name == "" then name = "default" end
- table.insert(stack,current)
- current = name
- if not data[current] then
- local d = { }
- setmetatable(d,mt)
- data[current] = d
- end
-end
-
-function spreadsheets.stop()
- current = table.remove(stack)
-end
-
-spreadsheets.reset()
-
-local offset = byte("A") - 1
-
-local function assign(s,n)
- return format("moduledata.spreadsheets.data['%s'][%s]",n,byte(s)-offset)
-end
-
--------- datacell(name,a,b,...)
-function datacell(a,b,...)
- local n = 0
- if b then
- local t = { a, b, ... }
- for i=1,#t do
- n = n * (i-1) * 26 + byte(t[i]) - offset
- end
- else
- n = byte(a) - offset
- end
- -- return format("dat['%s'][%s]",name,n)
- return format("dat[%s]",n)
-end
-
------ cell = (Carg(1) * C(R("AZ"))^1) / datacell * (Cc("[") * (R("09")^1) * Cc("]") + #P(1))
-local cell = C(R("AZ"))^1 / datacell * (Cc("[") * (R("09")^1) * Cc("]") + #P(1))
-local pattern = Cs(Cc("return ") * (cell + P(1))^0)
-
-local functions = { }
-spreadsheets.functions = functions
-
-function functions.sum(c,f,t)
- if f and t then
- local r = 0
- for i=f,t do
- r = r + c[i]
- end
- return r
- else
- return 0
- end
-end
-
-function functions.fmt(pattern,n)
- return format("%"..pattern,n)
-end
-
-local template = [[
- local spr = moduledata.spreadsheets.functions
- local dat = moduledata.spreadsheets.data['%s']
- local sum = spr.sum
- local fmt = spr.fmt
- %s
-]]
-
-local function execute(name,r,c,str)
- if name == "" then name = current if name == "" then name = "default" end end
- str = lpegmatch(pattern,str,1,name)
- str = format(template,name,str)
- -- print(str)
- local result = loadstring(str)
- result = result and result() or 0
- data[name][c][r] = result
- return result
-end
-
-function spreadsheets.set(name,r,c,str)
- if name == "" then name = current if name == "" then name = "default" end end
- execute(name,r,c,str)
-end
-
-function spreadsheets.get(name,r,c,str)
- if name == "" then name = current if name == "" then name = "default" end end
- if not str or str == "" then
- context(data[name][c][r] or 0)
- else
- local result = execute(name,r,c,str)
- if result then
- if type(result) == "number" then
- data[name][c][r] = result
- end
- context(result)
- end
- end
-end
-
-function spreadsheets.doifelsecell(name,r,c)
- if name == "" then name = current if name == "" then name = "default" end end
- local d = data[name]
- commands.testcase(d and d[c][r])
-end
-
-function spreadsheets.show(name)
- if name == "" then name = current if name == "" then name = "default" end end
- table.print(data[name],name)
-end
-\stopluacode
+\registerctxluafile{m-spreadsheet}{1.001}
\unprotect
% todo: get(...) set(..) ctx(...)
-\unexpanded\def\resetspreadsheet {\dosingleempty\doresetspreadsheet}
-\unexpanded\def\doresetspreadsheet [#1]{\ctxlua{moduledata.spreadsheets.reset("#1")}}
-\unexpanded\def\startspreadsheet {\dosingleempty\dostartspreadsheet}
-\unexpanded\def\dostartspreadsheet [#1]{\ctxlua{moduledata.spreadsheets.start("#1")}}
-\unexpanded\def\stopspreadsheet {\ctxlua{moduledata.spreadsheets.stop()}}
-\unexpanded\def\showspreadsheet {\dosingleempty\doshowspreadsheet}
-\unexpanded\def\doshowspreadsheet [#1]{\ctxlua{moduledata.spreadsheets.show("#1")}}
-\unexpanded\def\getspreadsheet {\dosingleempty\dogetspreadsheet}
-\unexpanded\def\dosetspreadsheet [#1]#2#3#4{\ctxlua{moduledata.spreadsheets.set ("#1",\number#2,\number#3,"#4")}}
-\unexpanded\def\setspreadsheet {\dosingleempty\dosetspreadsheet}
-\unexpanded\def\dogetspreadsheet [#1]#2#3#4{\ctxlua{moduledata.spreadsheets.get ("#1",\number#2,\number#3,"#4")}}
-\unexpanded\def\doifelsespreadsheetcell {\dosingleempty\dodoifelsespreadsheetcell}
-\unexpanded\def\dodoifelsespreadsheetcell[#1]#2#3{\ctxlua{moduledata.spreadsheets.doifelsecell("#1","#2","#3")}}
-
-\def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}}
-\def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}}
+\installcorenamespace{spreadsheet}
+
+\installcommandhandler \??spreadsheet {spreadsheet} \??spreadsheet
+
+\appendtoks
+ \ctxlua{moduledata.spreadsheets.setup{ % global !
+ period = "\spreadsheetparameter\c!period",
+ comma = "\spreadsheetparameter\c!comma",
+ split = "\spreadsheetparameter\c!split",
+ }}%
+\to \everysetupspreadsheet
+
+\setupspreadsheet
+ [%\c!comma=,
+ %\c!period=,
+ \c!split=\v!no]
+
+\unexpanded\def\resetspreadsheet
+ {\dosingleempty\module_spreadsheet_reset}
+
+\unexpanded\def\module_spreadsheet_reset[#1]%
+ {\ctxlua{moduledata.spreadsheets.reset("#1")}}
+
+\unexpanded\def\startspreadsheet
+ {\dosingleempty\module_spreadsheet_start}
+
+\unexpanded\def\module_spreadsheet_start[#1]%
+ {\pushmacro\currentspreadsheet
+ \edef\currentspreadsheet{#1}%
+ \checkspreadsheetparent
+ \edef\m_spreadsheet_period{\spreadsheetparameter\c!period}%
+ \edef\m_spreadsheet_comma {\spreadsheetparameter\c!comma}%
+ \ctxlua{moduledata.spreadsheets.start("#1", {
+ period = \!!bs\detokenize\expandafter{\m_spreadsheet_period}\!!es,
+ comma = \!!bs\detokenize\expandafter{\m_spreadsheet_comma}\!!es,
+ split = "\spreadsheetparameter\c!split",
+ })}}
+
+\unexpanded\def\stopspreadsheet
+ {\ctxlua{moduledata.spreadsheets.stop()}%
+ \popmacro\currentspreadsheet}
+
+\unexpanded\def\showspreadsheet
+ {\dosingleempty\module_spreadsheet_show}
+
+\unexpanded\def\module_spreadsheet_show[#1]%
+ {\ctxlua{moduledata.spreadsheets.tocontext("#1")}}
+
+\unexpanded\def\inspectspreadsheet
+ {\dosingleempty\module_spreadsheet_inspect}
+
+\unexpanded\def\module_spreadsheet_inspect[#1]%
+ {\ctxlua{moduledata.spreadsheets.inspect("#1")}}
+
+\unexpanded\def\setspreadsheet
+ {\dosingleempty\module_spreadsheet_set}
+
+\unexpanded\def\module_spreadsheet_set[#1]#2#3#4%
+ {\ctxlua{moduledata.spreadsheets.set("#1",\number#2,\number#3,"#4")}}
+
+\unexpanded\def\getspreadsheet
+ {\dosingleempty\module_spreadsheet_get}
+
+\unexpanded\def\module_spreadsheet_get[#1]#2#3#4%
+ {\ctxlua{moduledata.spreadsheets.get("#1",\number#2,\number#3,"#4")}}
+
+\unexpanded\def\doifelsespreadsheetcell
+ {\dosingleempty\module_spreadsheet_doifelse_cell}
+
+\unexpanded\def\module_spreadsheet_doifelse_cell[#1]#2#3%
+ {\ctxlua{moduledata.spreadsheets.doifelsecell("#1",\number#2,\number#3)}}
+
+\ifdefined\tblrow
+
+ \def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}}
+ \def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}}
+
+\else
+
+ \def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\c_tabl_ntb_row+1,\number\c_tabl_ntb_col,\!!bs#1\!!es)}}
+ \def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\c_tabl_ntb_row+1,\number\c_tabl_ntb_col,\!!bs#1\!!es)}}
+
+\fi
\appendtoks
- \resetspreadsheet
+ \module_spreadsheet_reset[\currentspreadsheet]%
\let\setspr\TABLEsetspreadsheet
\let\getspr\TABLEgetspreadsheet
\to \everyTABLEpass
\unexpanded\def\startspreadsheettable % quick and dirty
- {\dosingleempty\dostartspreadsheettable}
+ {\dodoubleempty\module_spreadsheet_start_table}
-\unexpanded\def\dostartspreadsheettable[#1]%
+\unexpanded\def\module_spreadsheet_start_table[#1][#2]%
{\bgroup
- \startspreadsheet[#1]%%
- \def\startrow{\bTR}%
- \def\stoprow {\eTR}%
- \def\startcell##1\stopcell{\bTD\getspr{##1}\eTD}%
- \bTABLE[\c!align=flushright]}
+ \let\startrow \module_spreadsheet_row_start
+ \let\stoprow \module_spreadsheet_row_stop
+ \let\startcell\module_spreadsheet_cell_start
+ \let\stopcell \module_spreadsheet_cell_stop
+ \doifassignmentelse{#1}
+ {\module_spreadsheet_start
+ \bTABLE[\c!align=\v!flushright,#1]}
+ {\module_spreadsheet_start[#1]%
+ \bTABLE[\c!align=\v!flushright,#2]}}
\unexpanded\def\stopspreadsheettable
{\eTABLE
\stopspreadsheet
\egroup}
+\unexpanded\def\module_spreadsheet_row_start{\bTR}
+\unexpanded\def\module_spreadsheet_row_stop {\eTR}
+
+\unexpanded\def\module_spreadsheet_cell_start
+ {\doifnextoptionalelse\module_spreadsheet_cell_start_yes\module_spreadsheet_cell_start_nop}
+
+\unexpanded\def\module_spreadsheet_cell_start_yes[#1]#2\stopcell
+ {\bTD[#1]\getspr{#2}\eTD}
+
+\unexpanded\def\module_spreadsheet_cell_start_nop#1\stopcell
+ {\bTD\getspr{#1}\eTD}
+
+\let\module_spreadsheet_cell_stop\relax
+
\protect
-\doifnotmode{demo}{\endinput}
+\continueifinputfile{m-spreadsheet.mkiv}
\starttext
@@ -220,10 +167,12 @@ end
\bTD[nx=2] \bf \getspr{string.format("\letterpercent0.3f",(A[3] + B[3]) /100)} \eTD
\eTR
\bTR
- \bTD[nx=2] \bf \getspr{fmt("0.3f",(sum(A,1,2)) / 10)} \eTD
+ \bTD[nx=2] \bf \getspr{fmt("@0.3f",(sum(A,1,2)) / 10)} \eTD
\eTR
\eTABLE
+\setupspreadsheet[mysheet]
+
\startspreadsheet[mysheet]
\bTABLE[align=middle]
@@ -231,7 +180,7 @@ end
\bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD
\eTR
\bTR
- \bTD \getspr{20} \eTD \bTD \getspr{4+3} \eTD
+ \bTD \getspr{20} \eTD \bTD \getspr{4+3.5} \eTD
\eTR
\bTR
\bTD \getspr{A[1] + A[2]} \eTD
@@ -244,17 +193,19 @@ end
\stopspreadsheet
-\startspreadsheettable
+\blank
+
+\setupspreadsheet[test][period={{\bf\middlered .}},comma={{\bf\middlegreen ,}},split=yes]
+
+\startspreadsheettable[test]
\startrow
- \startcell 3 \stopcell
- \startcell 9 \stopcell
+ \startcell 123456.78 \stopcell
+ \startcell 1234567.89 \stopcell
\startcell A[1] + B[1] \stopcell
\stoprow
\stopspreadsheettable
-bla bla \getspreadsheet[mysheet]{2}{2}{}
-
-bla bla \getspreadsheet[mysheet]{4}{1}{}
+\blank
% \showspreadsheet
% \showspreadsheet[mysheet]