From d7ccb42582f85acf30568913610ccf4d602023fb Mon Sep 17 00:00:00 2001 From: Taco Hoekwater Date: Wed, 1 Jun 2011 08:54:21 +0000 Subject: commit context 2011.05.18 git-svn-id: svn://tug.org/texlive/trunk@22719 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/context/base/m-spreadsheet.mkiv | 265 +++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 Master/texmf-dist/tex/context/base/m-spreadsheet.mkiv (limited to 'Master/texmf-dist/tex/context/base/m-spreadsheet.mkiv') diff --git a/Master/texmf-dist/tex/context/base/m-spreadsheet.mkiv b/Master/texmf-dist/tex/context/base/m-spreadsheet.mkiv new file mode 100644 index 00000000000..49f59ded9ef --- /dev/null +++ b/Master/texmf-dist/tex/context/base/m-spreadsheet.mkiv @@ -0,0 +1,265 @@ +%D \module +%D [ file=m-spreadsheet, +%D version=2011.02.21, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Spreadsheets, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%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 + +\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)}} + +\appendtoks + \resetspreadsheet + \let\setspr\TABLEsetspreadsheet + \let\getspr\TABLEgetspreadsheet +\to \everyTABLEpass + +\unexpanded\def\startspreadsheettable % quick and dirty + {\dosingleempty\dostartspreadsheettable} + +\unexpanded\def\dostartspreadsheettable[#1]% + {\bgroup + \startspreadsheet[#1]%% + \def\startrow{\bTR}% + \def\stoprow {\eTR}% + \def\startcell##1\stopcell{\bTD\getspr{##1}\eTD}% + \bTABLE[\c!align=flushright]} + +\unexpanded\def\stopspreadsheettable + {\eTABLE + \stopspreadsheet + \egroup} + +\protect + +\doifnotmode{demo}{\endinput} + +\starttext + +\bTABLE[align=middle] + \bTR + \bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD + \eTR + \bTR + \bTD \getspr{20} \eTD \bTD \getspr{4+3} \eTD + \eTR + \bTR + \bTD \getspr{A[1] + A[2]} \eTD + \bTD \getspr{B1 + B2} \eTD + \eTR + \bTR + \bTD[nx=2] \bf \getspr{(A[3] + B[3]) /100} \eTD + \eTR + \bTR + \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 + \eTR +\eTABLE + +\startspreadsheet[mysheet] + +\bTABLE[align=middle] + \bTR + \bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD + \eTR + \bTR + \bTD \getspr{20} \eTD \bTD \getspr{4+3} \eTD + \eTR + \bTR + \bTD \getspr{A[1] + A[2]} \eTD + \bTD \getspr{B[1] + B[2]} \eTD + \eTR + \bTR + \bTD[nx=2] \bf \getspr{A[3] + B[3]} \eTD + \eTR +\eTABLE + +\stopspreadsheet + +\startspreadsheettable + \startrow + \startcell 3 \stopcell + \startcell 9 \stopcell + \startcell A[1] + B[1] \stopcell + \stoprow +\stopspreadsheettable + +bla bla \getspreadsheet[mysheet]{2}{2}{} + +bla bla \getspreadsheet[mysheet]{4}{1}{} + +% \showspreadsheet +% \showspreadsheet[mysheet] + +\doifelsespreadsheetcell[mysheet]{1}{2}{YES}{NOP} +\doifelsespreadsheetcell[myshoot]{1}{2}{YES}{NOP} + +\stoptext -- cgit v1.2.3