# The Calc Moin Macro

## 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

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

## 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)>>
* 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)>>.```

## 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.

calc (last edited 2008-08-12 07:38:20 by GustavoNiemeyer)