Contents
Summary
The Calc Macro offers spreadsheet-like features for the Moin wiki software.
Concept
The underlying concept of the Calc Macro is very simple: spreadsheets are a way to organize text, numbers and formulas into what might be seen as a natively numeric environment: a matrix. So what would happen if we loosed some of the bolts of the numeric-oriented organization, and tried to reuse the same concepts into a more formatting-oriented environment which is naturally collaborative: a wiki.
Features
- Extraction of variables from pages using regular expressions
- Importing of variables and functions from different pages
Builtin aggregation functions (sum, max, min, avg, len)
Conditional expressions through the if function
- Custom function definition
- Decimal arithmetic
- Good error reporting
- Good test suite
Download & Installation
To get it working, download the following tarball and copy the Calc.py file to data/plugin/macro/Calc.py in your Moin instance directory.
It was verified to work with at least the following Moin versions:
- 1.6.1
- 1.6.4
Development & Bug Reporting
Code hosting and bug tracking is on Launchpad.
Contact
Gustavo Niemeyer <gustavo@niemeyer.net>
Examples
Grand-total for values
Creating a grand-total for a list of values:
* January: 123.45 * February: 456.78 <<Calc(define=months, extract_list=\w+: ([\d.]+))>> * Total: <<Calc(sum(months), format="%.2f")>>
Importable currency conversion page
Defining a CurrencyConversion page with a function for importing:
* BRL: <<Calc(1.00, define=BRL, show=1)>> * CAD: <<Calc(1.69, define=CAD, show=1)>> * EUR: <<Calc(2.67, define=EUR, show=1)>> * USD: <<Calc(1.73, define=USD, show=1)>> <<Calc(define=convert(value;from;to), expression=value * from / to)>>
Then, in another page:
<<Calc(import_from=CurrencyConversion)>> 5 EUR in USD: <<Calc(convert(5;EUR;USD), format="%.2f")>>
Exploring tables
Extracting data from a specific table column:
<<Calc(define=B, extract_list=(?:\|.*){4}(\d+))>> || A || B || || 0 || 1 || || 0 || 2 || || Sum:|| <<Calc(sum(B))>> ||
Simple variables
Using Calc as a simple variable system.
<<Calc(define=API, expression='1.7.4')>> The latest API is <<Calc(API)>>.
Parameters
Expressions
Functions
sum
Returns the sum of all values. If a list is passed as an argument, its elements will be included in the sum.
Signature:
sum(<value or list>[;<value or list>[;<value or list>...]]) => <value>
Example:
Total: <<Calc(sum(values))>>
min
Returns the minimum value in the given list.
Signature:
min(<value list>) => <value>
Example:
Minimum value: <<Calc(min(values))>>
max
Returns the maximum value in the given list.
Signature:
max(<value list>) => <value>
Example:
Maximum value: <<Calc(max(values))>>
avg
Returns the average of the values provided in the given list.
Signature:
avg(<value list>) => <value>
Example:
Maximum value: <<Calc(max(values))>>
len
Returns the length of the provided value.
Signature:
len(<value>) => <length>
Example:
Found <<Calc(len(values))>> values.
date
Returns a date value corresponding to the given year/month/day.
Signature:
date(<year>;<month>;<day>) => <date>
Example:
Her birthday is in <<Calc(days(date(year;5;4);today()))>> days!
day
Returns the sequential date of the month for the given date/time value as an integer (1-31).
Signature:
day(<date/time value>) => <day>
Example:
Christmas is on December <<Calc(day(date(year;12;25)))>>th.
days
Returns the difference between the first and the second date values.
Signature:
days(<date 1>;<date 2>) => <days>
Example:
Her birthday is in <<Calc(days(date(year;5;4);today()))>> days!
today
Returns today as a date value.
Signature:
today() => <date>
Example:
Her birthday is in <<Calc(days(date(year;5;4);today()))>> days!
weekday
Returns the day of the week as an integer for the given date value. Optionally, the second argument determines the kind of result, according to the following values:
- 1 - Returns values in the range 1-7, meaning Sunday to Saturday (default) 2 - Returns values in the range 1-7, meaning Monday to Sunday 3 - Returns values in the range 0-6, meaning Monday to Sunday
Signature:
weekday(<date value>[;<kind>]) => <weekday>
Example:
Today is <<Calc(choose(weekday(today());'Sunday';'Monday';'Tuesday';'Wednesday';'Thursday';'Friday';'Saturday')))>>
choose
Uses the first argument as an index (starting at 1) to select one of the following arguments.
Signature:
choose(<index 1-N>;<element 1>;<element 2>;...;<element N>) => <element i=index>
Example:
Today is <<Calc(choose(weekday(today());'Sunday';'Monday';'Tuesday';'Wednesday';'Thursday';'Friday';'Saturday')))>>
<<Calc(expression, extract=<content regex>, extract_list=<content regex>, define=<variable or function spec>, show=<1|0>, format=<format>, page=<page name(s)>, import=<page name(s)>)>>
All arguments are optional, including the initial expression (which may be replaced by the extract argument).
expression: Evaluated as a mathematical expression
extract: If given, must be a regular expression searched for in the evaluated page(s). The full match (or the first match group, if given) will become the value of the expression argument.
list: If set to 1, the extract pattern will be looked for more than once in the evaluated page(s), and the evaluation result of each match will be appended to a list.
assign: If given, the expression result will be assigned to a variable with the given name, and won't be displayed (unless show is also provided).
show: If set to 1, will force the expression result to be displayed, even if the assign argument is given.
page: If provided, the extract pattern will be evaluated in the matching page name(s) (may be a regex pattern, if starting with ^)
import: If provided, variables from the matching page name(s) (may be a regex pattern, if starting with ^) will be imported in the current context.
- Add "default" parameter, which is an expression used when extract fails.
- Add "render" parameter, which is the format to be rendered as (defaults to plain wiki markup).
- Support assigning to functions (assign=name(a;b)), in which case, the expression is stored instead of being evaluated.