|
It is possible to define user functions to help
the writing of complex texts. In other text processor this facility
is usually named user macro. Scribe functions are
implemented in
Bigloo, a variant of the
Scheme programming language.
It is recommended to define user functions before
the call to the document
is called. A user function may operate side effects
(such as storing information in a hash table). Its return value will
be considered as any Scribe expression.
1.1 Simple example of user function
|
Let us suppose that we have to include a table such as:
Name | Value |
One | 1 |
Two | 2 |
PI | 3.1415 |
Cos | Standard library |
Sin | Standard library |
Foo | ??? |
#t | yes |
#f | no |
|
Fig. 1: An example of table
On this table, the "Names" are centered and displayed in green. The
"Values" are formated accordingly to there type. Integers are flushed left,
reals are flushed right. Strings are displayed in a bold face and centered.
Booleans are represented by the two strings yes and no.
Since it is tedious to strictly follow this formating rules and good way
to ensure compliance is to use a function in order to format the table.
This is what the example-table function does:
(define (example-table . items)
(center
(apply table
:border (if (eq? *scribe-format* 'html) #f 1)
(tr :bg *api-arguments-description-color*
(th :width .2 "Name")
(th :width .8 "Value"))
(map (lambda (i)
(let ((name (car i))
(val (cadr i)))
(tr :bg *api-example-color*
(td :align 'left (color :fg "#00aa00" name))
(cond
((integer? val)
(td :align 'left val))
((real? val)
(td :align 'right val))
((string? val)
(td :align 'center (bold val)))
((boolean? val)
(td :align 'center (it (if val "yes" "no"))))
(else
(td :align 'center "???"))))))
items)))) |
.
It may happens that some user function accept configuration or optional
arguments. For instance, let us suppose that we want to provide a mean
to configure the table of the previous example.
We want to provide a mean to choose the color of the "Names" and
the layout of the "Values". The customized table could be rendered as:
Name | Value |
One | 1 |
Two | 2 |
PI | 3.1415 |
Cos | Standard library |
Sin | Standard library |
Foo | ??? |
#t | yes |
#f | no |
|
Fig. 2: Customized example of table
This kind of functions can be implemented with regular Scheme
functions but Scribe provided a special form to help at this
task.
(define-markup arguments . body) | Scribe special form |
argument | description |
:arguments | The arguments of the markup function. |
:body | The body of the markup function. |
A markup function is a regular Scheme function. It can be
used in all the contexts a Scheme function call be used. It differs
with traditional functions in that it enables keyword
parameters. A keyword parameter is an argument whose actual value is
named by the formal name of the parameter. A keyword parameter
may or may not have a default. A keyword parameter with a default
value is optional. On a function call is such a paramter is not
passed, the body of the function is evaluated with the keyword
parameter bound to its default value. A keyword parameter is
specified with a Bigloo keyword instead of a symbol.
In the body of function, the value of the keyword parameter is fetch
using the symbol associated with the keyword. For instance, a keyword
parameter :color will be referenced to in the body of a
function a color. A keyword parameter with a default value
is specified with a list whose first element is a keyword and second
element the default value.
For instance, the definition of the function enabling user customization
in example table is:
(define-markup (example-table2 :fg (:integer 'left) (:real 'right)
(:string 'center) (:boolean 'center) . items)
(center
(apply table
:border (if (eq? *scribe-format* 'html) #f 1)
(tr :bg *api-arguments-description-color*
(th :width .2 "Name")
(th :width .8 "Value"))
(map (lambda (i)
(let ((name (car i))
(val (cadr i)))
(tr :bg *api-example-color*
(td :align 'left (color :fg fg name))
(cond
((integer? val)
(td :align integer val))
((real? val)
(td :align real val))
((string? val)
(td :align string (bold val)))
((boolean? val)
(td :align boolean (it (if val "yes" "no"))))
(else
(td :align 'center "???"))))))
items))))
|
The call to example-table2 that produces the
Figure above is:
(example-table2 :fg "#aa2222"
:integer 'center
:real 'center
'("One" 1)
'("Two" 2)
'("PI" 3.1415)
'("Cos" "Standard library")
'("Sin" "Standard library")
'("Foo" #unspecified)
'("#t" #t)
'("#f" #f))
|
|