summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex')
-rw-r--r--doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex760
1 files changed, 760 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex b/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex
new file mode 100644
index 000000000..c5c99e97d
--- /dev/null
+++ b/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex
@@ -0,0 +1,760 @@
+% language=uk
+
+% author : Hans Hagen
+% copyright : PRAGMA ADE & ConTeXt Development Team
+% license : Creative Commons Attribution ShareAlike 4.0 International
+% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
+% origin : the ConTeXt distribution
+%
+% comment : Because this manual is distributed with TeX distributions it comes with a rather
+% liberal license. We try to adapt these documents to upgrades in the (sub)systems
+% that they describe. Using parts of the content otherwise can therefore conflict
+% with existing functionality and we cannot be held responsible for that. Many of
+% the manuals contain characteristic graphics and personal notes or examples that
+% make no sense when used out-of-context.
+%
+% comment : Some chapters might have been published in TugBoat, the NTG Maps, the ConTeXt
+% Group journal or otherwise. Thanks to the editors for corrections. Also thanks
+% to users for testing, feedback and corrections.
+
+\usemodule[spreadsheet]
+\usemodule[art-01,abr-02]
+
+\definecolor[darkred] [r=.4]
+\definecolor[darkgreen][g=.4]
+\definecolor[darkblue] [b=.4]
+
+\definecolor[maincolor] [darkred]
+\definecolor[extracolor][darkblue]
+
+\setuptyping
+ [color=extracolor]
+
+\setuptype
+ [color=extracolor]
+
+\setuphead
+ [section]
+ [color=maincolor]
+
+\setupbodyfont
+ [10pt]
+
+\setupinteraction
+ [hidden]
+
+% \setupnumbering
+% [alternative=doublesided]
+
+\startdocument
+ [metadata:author=Hans Hagen,
+ metadata:title=Simple Spreadsheets,
+ author=Hans Hagen,
+ affiliation=PRAGMA ADE,
+ location=Hasselt NL,
+ title=Simple Spreadsheets,
+ extra=ConTeXt MkIV,
+ support=www.contextgarden.net,
+ website=www.pragma-ade.nl]
+
+\startMPpage
+
+ StartPage;
+
+ numeric n, m ; n := 3 * 4 ; m := 4 * 4 ;
+ numeric w, h ; w := PaperWidth/n ; h := PaperHeight/m ;
+
+ for i=1 upto n :
+ for j=1 upto m :
+ fill
+ unitsquare
+ xysized (w,h)
+ shifted ((i-1)*w,(j-1)*h)
+ withcolor .5[i*red/n,j*blue/m]
+ ;
+ endfor ;
+ endfor ;
+
+ for i=1 upto n :
+ for j=1 upto m :
+ draw
+ textext("\tt" & char(64+i) & if j < 10 : "0" else : "" fi & decimal j)
+ xysized (.7*w,.7*h)
+ shifted (i*w-.5w,(m+1-j)*h-.5h)
+ withcolor .5[(n+1-i)*green/n,(m+1-j)*yellow/m]
+ ;
+ endfor ;
+ endfor ;
+
+ draw
+ textext.llft("\ssbf{\documentvariable{title}}")
+ xsized (PaperHeight-h)
+ rotated 90
+ shifted (PaperWidth-1.75w,PaperHeight-h/2)
+ withcolor white
+ ;
+
+ draw
+ textext.llft("\ssbf{\documentvariable{extra}}")
+ ysized (h/2)
+ shifted (PaperWidth-2.5w,3.75h)
+ withcolor white
+ ;
+
+
+ draw
+ textext.llft("\ssbf{\documentvariable{author}}")
+ ysized (h/2)
+ shifted (PaperWidth-2.5w,2.75h)
+ withcolor white
+ ;
+
+ draw
+ textext.llft("\ssbf \currentdate")
+ ysized (h/2)
+ shifted (PaperWidth-2.5w,1.75h)
+ withcolor white
+ ;
+
+ StopPage;
+
+\stopMPpage
+
+% \page[empty] \setuppagenumber[start=1]
+
+\startsubject[title={Contents}]
+
+\placelist[section][criterium=all,interaction=all]
+
+\stopsubject
+
+\startsection [title={Introduction}]
+
+Occasionally a question pops up on the \CONTEXT\ mailing list and answering it
+becomes a nice distraction from a boring task at hand. The spreadsheet module is
+the result of such a diversion. As with more support code in \CONTEXT, this is
+not a replacement for \quote {the real thing} but just a nice feature for simple
+cases. The module is loaded with
+
+\starttyping
+\usemodule[spreadsheet]
+\stoptyping
+
+So this is (at least currently) not one of the core functionalities but an
+add||on. Of course some useful extensions might appear in the future.
+
+\stopsection
+
+\startsection [title={Spreadsheet tables}]
+
+We can use \LUA\ in each cell, because under the hood it is all \LUA. There is
+some basic parsing applied so that we can use the usual \type {A..Z} variables to
+access cells.
+
+\startbuffer[demo]
+\startspreadsheettable[test]
+ \startrow
+ \startcell 1.1 \stopcell
+ \startcell 2.1 \stopcell
+ \startcell A[1] + B[1] \stopcell
+ \stoprow
+ \startrow
+ \startcell 2.1 \stopcell
+ \startcell 2.2 \stopcell
+ \startcell A[2] + B[2] \stopcell
+ \stoprow
+ \startrow
+ \startcell A[1] + B[1] \stopcell
+ \startcell A[2] + B[2] \stopcell
+ \startcell A[3] + B[3] \stopcell
+ \stoprow
+\stopspreadsheettable
+\stopbuffer
+
+\typebuffer[demo]
+
+The rendering is shown in \in {figure} [spreadsheet:1]. Keep in mind that in
+\LUA\ all calculations are done using floats, at least in \LUA\ versions with
+version numbers preceding 5.3.
+
+\placefigure
+ [here]
+ [spreadsheet:1]
+ {A simple spreadsheet.}
+ {\getbuffer[demo]}
+
+The last cell can also look like this:
+
+\starttyping
+\startcell
+function()
+ local s = 0
+ for i=1,2 do
+ for j=1,2 do
+ s = s + dat[i][j]
+ end
+ end
+ return s
+end
+\stopcell
+\stoptyping
+
+The content of a cell is either a number or a function. In this example
+we just loop over the (already set) cells and calculate their sum. The
+\type {dat} variable accesses the grid of cells.
+
+\starttyping
+\startcell
+function()
+ local s = 0
+ for i=1,2 do
+ for j=1,2 do
+ s = s + dat[i][j]
+ end
+ end
+ tmp.total = s
+end
+\stopcell
+\stoptyping
+
+In this variant we store the sum in the table \type {tmp} which is local to the
+current sheet. Another table is \type {fnc} where we can store functions. This
+table is shared between all sheets. There are two predefined functions:
+
+\starttyping
+sum(columnname,firstrow,lastrow)
+fmt(specification,n)
+\stoptyping
+
+The \type {sum} function works top||down in columns, and roughly looks like
+this:
+
+\starttyping
+function sum(currentcolumn,firstrow,lastrow)
+ local r = 0
+ for i = firstrow, lastrow do
+ r = r + cells[currentcolumn][i]
+ end
+ return r
+end
+\stoptyping
+
+The last two arguments are optional:
+
+\starttyping
+sum(columnname,lastrow)
+\stoptyping
+
+This is equivalent to:
+
+\starttyping
+function sum(currentcolumn,lastrow)
+ local r = 0
+ for i = 1, lastrow do
+ r = r + cells[currentcolumn][i]
+ end
+ return r
+end
+\stoptyping
+
+While:
+
+\starttyping
+sum(columnname)
+\stoptyping
+
+boils down to:
+
+\starttyping
+function sum(currentcolumn)
+ local r = 0
+ for i = 1, currentrow do
+ r = r + cells[currentcolumn][i]
+ end
+ return r
+end
+\stoptyping
+
+Empty cells or cells that have no numbers are skipped. Let's now see these
+functions in action:
+
+\startbuffer[demo]
+\startspreadsheettable[test]
+ \startrow
+ \startcell 1.1 \stopcell \startcell 2.1 \stopcell
+ \stoprow
+ \startrow
+ \startcell 2.1 \stopcell \startcell 2.2 \stopcell
+ \stoprow
+ \startrow
+ \startcell
+ function()
+ local s = 0
+ for i=1,2 do
+ for j=1,2 do
+ s = s + dat[i][j]
+ end
+ end
+ context.bold(s)
+ end
+ \stopcell
+ \startcell
+ function()
+ local s = 1
+ for i=1,2 do
+ for j=1,2 do
+ s = s * dat[i][j]
+ end
+ end
+ context.bold(fmt("@.1f",s))
+ end
+ \stopcell
+ \stoprow
+\stopspreadsheettable
+\stopbuffer
+
+\typebuffer[demo]
+
+The result is shown in \in {figure} [spreadsheet:2]. Watch the \type {fmt} call:
+we use an at sign instead of a percent to please \TEX.
+
+\placefigure
+ [here]
+ [spreadsheet:2]
+ {Cells can be (complex) functions.}
+ {\getbuffer[demo]}
+
+Keep in mind that we're typesetting and that doing complex calculations is not
+our main objective. A typical application of this module is in making bills, for
+which you can combine it with the correspondence modules. We leave that as an
+exercise for the reader and stick to a simple example.
+
+\startbuffer[demo]
+\startspreadsheettable[test]
+ \startrow
+ \startcell[align=flushleft,width=8cm] "item one" \stopcell
+ \startcell[align=flushright,width=3cm] @ "0.2f EUR" 3.50 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "item two" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" 8.45 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "tax 19\percent" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" 0.19 * (B[1]+B[2]) \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "total 1" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" sum(B,1,3) \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "total 2" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" B[1] + B[2] + B[3] \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "total 3" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" sum(B) \stopcell
+ \stoprow
+\stopspreadsheettable
+\stopbuffer
+
+\typebuffer[demo]
+
+Here (and in \in {figure} [spreadsheet:8]) you see a quick and more
+readable way to format cell content. The \type {@} in the template is
+optional, but needed in cases like this:
+
+\starttyping
+@ "(@0.2f) EUR" 8.45
+\stoptyping
+
+A \type {@} is only prepended when no \type {@} is given in the template.
+
+\placefigure
+ [here]
+ [spreadsheet:8]
+ {Cells can be formatted by using \type {@} directives.}
+ {\getbuffer[demo]}
+
+In practice this table we can be less specific and let \type {\sum} behave more
+automatical. That way the coding can be simplified (see \in {figure}
+[spreadsheet:7]) and also look nicer.
+
+\startbuffer[demo]
+\startspreadsheettable[test][frame=off]
+ \startrow
+ \startcell[align=flushleft,width=8cm] "The first item" \stopcell
+ \startcell[align=flushright,width=3cm] @ "0.2f EUR" 3.50 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "The second item" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" 8.45 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "The third item" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" 5.90 \stopcell
+ \stoprow
+ \startrow[topframe=on]
+ \startcell[align=flushleft] "VAT 19\percent" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" 0.19 * sum(B) \stopcell
+ \stoprow
+ \startrow[topframe=on]
+ \startcell[align=flushleft] "\bf Grand total" \stopcell
+ \startcell[align=flushright] @ "0.2f EUR" sum(B) \stopcell
+ \stoprow
+\stopspreadsheettable
+\stopbuffer
+
+\typebuffer[demo]
+
+\placefigure
+ [here]
+ [spreadsheet:7]
+ {The \type {sum} function accumulates stepwise.}
+ {\getbuffer[demo]}
+
+There are a few more special start characters. This is demonstrated in \in
+{figure} [spreadsheet:9]. An \type {=} character is ignored. \footnote {Taco
+suggested to support this because some spreadsheet programs use that character to
+flush a value.} When we start with an \type {!}, the content is not typeset.
+Strings can be surrounded by single or double quotes and are not really
+processed.
+
+\startbuffer[demo]
+\startspreadsheettable[test][offset=1ex]
+ \startrow
+ \startcell[align=flushleft] "first" \stopcell
+ \startcell[align=flushleft] '\type{@ "[@i]" 1}' \stopcell
+ \startcell[align=flushright,width=3cm] @ "[@i]" 1 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "second" \stopcell
+ \startcell[align=flushleft] '\type{= 2}' \stopcell
+ \startcell[align=flushright] = 2 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "third" \stopcell
+ \startcell[align=flushleft] '\type{! 3}' \stopcell
+ \startcell[align=flushright] ! 3 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "fourth" \stopcell
+ \startcell[align=flushleft] '\type{4}' \stopcell
+ \startcell[align=flushright] 4 \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "\bf total one" \stopcell
+ \startcell[align=flushleft] '\type{sum(C)}' \stopcell
+ \startcell[align=flushright] sum(C) \stopcell
+ \stoprow
+ \startrow
+ \startcell[align=flushleft] "\bf total two" \stopcell
+ \startcell[align=flushleft] '\type{= sum(C)}' \stopcell
+ \startcell[align=flushright] = sum(C) \stopcell
+ \stoprow
+\stopspreadsheettable
+\stopbuffer
+
+\typebuffer[demo]
+
+The \type {sum} function is clever enough not to include itself in the
+summation. Only preceding cells are taken into account, given that they
+represent a number.
+
+\placefigure
+ [here]
+ [spreadsheet:9]
+ {Cells can be hidden by \type {!} and can contain strings only.}
+ {\getbuffer[demo]}
+
+\stopsection
+
+\startsection [title={Normal tables}]
+
+In the previous examples we used \TEX\ commands for structuring the sheet but
+the content of cells is \LUA\ code. It is also possible to stick to a regular
+table and use specific commands to set and get cell data.
+
+\startbuffer[demo]
+\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{fmt("@0.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
+\stopbuffer
+
+\typebuffer[demo]
+
+The method to use depends on the complexity of the table. If there is
+more text than data then this method is probably more comfortable.
+
+\placefigure
+ [here]
+ [spreadsheet:3]
+ {A sheet can be filled and accessed from regular tables.}
+ {\getbuffer[demo]}
+
+% \setupspreadsheet[mysheet]
+%
+% \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.5} \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
+
+\stopsection
+
+\startsection[title={A few settings}]
+
+It's possible to influence the rendering. The following example demonstrates
+this. We don't use any formatting directives.
+
+\startbuffer[demo]
+\startspreadsheettable[test]
+ \startrow
+ \startcell 123456.78 \stopcell
+ \stoprow
+ \startrow
+ \startcell 1234567.89 \stopcell
+ \stoprow
+ \startrow
+ \startcell A[1] + A[2] \stopcell
+ \stoprow
+\stopspreadsheettable
+\stopbuffer
+
+\typebuffer[demo]
+
+\placefigure
+ [here]
+ [spreadsheet:4]
+ {Formatting (large) numbers.}
+ {\getbuffer[demo]}
+
+\in {Figure} [spreadsheet:4] demonstrates how this gets rendered by
+default. However, often you want numbers to be split in parts separated by
+periods and commas. This can be done as follows:
+
+\startbuffer[setup]
+\definehighlight[BoldAndRed] [style=bold,color=darkred]
+\definehighlight[BoldAndGreen][style=bold,color=darkgreen]
+
+\setupspreadsheet
+ [test]
+ [period={\BoldAndRed{.}},
+ comma={\BoldAndGreen{,}},
+ split=yes]
+\stopbuffer
+
+\typebuffer[setup] \getbuffer[setup]
+
+\placefigure
+ [here]
+ [spreadsheet:5]
+ {Formatting (large) numbers with style and color.}
+ {\getbuffer[setup,demo]}
+
+\stopsection
+
+\startsection[title={The \LUA\ end}]
+
+You can also use spreadsheets from within \LUA. The following example is
+rather straightforward:
+
+\startbuffer[demo-a]
+\startluacode
+context.startspreadsheettable { "test" }
+ context.startrow()
+ context.startcell() context("123456.78") context.stopcell()
+ context.stoprow()
+ context.startrow()
+ context.startcell() context("1234567.89") context.stopcell()
+ context.stoprow()
+ context.startrow()
+ context.startcell() context("A[1] + A[2]") context.stopcell()
+ context.stoprow()
+context.stopspreadsheettable()
+\stopluacode
+\stopbuffer
+
+\typebuffer[demo-a]
+
+However, even more \LUA|-|ish is the next variant:
+
+\startbuffer[demo-b]
+\startluacode
+ local set = moduledata.spreadsheets.set
+ local get = moduledata.spreadsheets.get
+
+ moduledata.spreadsheets.start("test")
+ set("test",1,1,"123456.78")
+ set("test",2,1,"1234567.89")
+ set("test",3,1,"A[1] + A[2]")
+ moduledata.spreadsheets.stop()
+
+ context.bTABLE()
+ context.bTR()
+ context.bTD() context(get("test",1,1)) context.eTD()
+ context.eTR()
+ context.bTR()
+ context.bTD() context(get("test",2,1)) context.eTD()
+ context.eTR()
+ context.bTR()
+ context.bTD() context(get("test",3,1)) context.eTD()
+ context.eTR()
+ context.eTABLE()
+\stopluacode
+\stopbuffer
+
+\typebuffer[demo-b]
+
+Of course the second variant does not make much sense as we can do this way
+more efficient by not using a spreadsheet at all:
+
+\startbuffer[demo-c]
+\startluacode
+ local A1, A2 = 123456.78, 1234567.89
+ context.bTABLE()
+ context.bTR()
+ context.bTD() context(A1) context.eTD()
+ context.eTR()
+ context.bTR()
+ context.bTD() context(A2) context.eTD()
+ context.eTR()
+ context.bTR()
+ context.bTD() context(A1+A2) context.eTD()
+ context.eTR()
+ context.eTABLE()
+\stopluacode
+\stopbuffer
+
+\typebuffer[demo-c]
+
+You can of course use format explicitly. Here we use the normal percent
+directives because we're in \LUA, and not in \TEX, where percentage
+signs are a bit of an issue.
+
+\startbuffer[demo-d]
+\startluacode
+ local A1, A2 = 123456.78, 1234567.89
+ local options = { align = "flushright" }
+ context.bTABLE()
+ context.bTR()
+ context.bTD(options)
+ context("%0.2f",A1)
+ context.eTD()
+ context.eTR()
+ context.bTR()
+ context.bTD(options)
+ context("%0.2f",A2)
+ context.eTD()
+ context.eTR()
+ context.bTR()
+ context.bTD(options)
+ context("%0.2f",A1+A2)
+ context.eTD()
+ context.eTR()
+ context.eTABLE()
+\stopluacode
+\stopbuffer
+
+\typebuffer[demo-d]
+
+As expected and shown in \in {figure} [spreadsheet:6], only the first and last
+variant gets the numbers typeset nicely.
+
+\placefigure
+ [here]
+ [spreadsheet:6]
+ {Spreadsheets purely done as \CONTEXT\ \LUA\ Document.}
+ {\startcombination[4*1]
+ {\getbuffer[demo-a]} {}
+ {\getbuffer[demo-b]} {}
+ {\getbuffer[demo-c]} {}
+ {\getbuffer[demo-d]} {}
+ \stopcombination}
+
+\stopsection
+
+\startsection[title={Helper macros}]
+
+There are two helper macros that you can use to see what is stored in a
+spreadsheet:
+
+\starttyping
+\inspectspreadsheet[test]
+\showspreadsheet [test]
+\stoptyping
+
+The first command reports the content of \type {test} to the console, and
+the second one typesets it in the running text:
+
+\blank
+\showspreadsheet[test]
+\blank
+
+Another helper function is \type {\doifelsespreadsheetcell}, You can use this
+one to check if a cell is set.
+
+\startbuffer[demo]
+(1,1): \doifelsespreadsheetcell[test]{1}{1}{set}{unset}
+(2,2): \doifelsespreadsheetcell[test]{2}{2}{set}{unset}
+(9,9): \doifelsespreadsheetcell[test]{9}{9}{set}{unset}
+\stopbuffer
+
+\typebuffer[demo]
+
+This gives:
+
+\startlines
+\getbuffer[demo]
+\stoplines
+
+There is not much more to say about this module, apart from that it is a
+nice example of a \TEX\ and \LUA\ mix. Maybe some more (basic) functionality
+will be added in the future but it all depends on usage.
+
+\stopsection
+
+\startsubject[title={Colofon}]
+
+\starttabulate[|B|p|]
+\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC version \NC \currentdate \NC \NR
+\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
+\stoptabulate
+
+\stopsubject
+
+\stopdocument