Wednesday, August 12th, 2015

pollen-count

pollen, racket, programming

Table of Contents

1. Introducing pollen-count

pollen-count is a Racket library for use with Pollen. It allows for numbering of sections, figures, tables, etc. and cross references to these numbers. The source code is available on Github.

2. Enumerations

pollen-count is designed to enumerate sections, figures, tables, etc. To do this the required number of counters is defined along with a hashmap of tags and counters. Any time a tag in the hashmap is encountered its associated counter will be incremented and the new value stored with that instance of the tag.

Counters can specify a parent counter. A print function associated with the counter will concatenate its number with its parent’s number with a specified separator. The function to make a counter is make-counter, its argument list is defined as follows:

1
(make-counter initial render [parent #f] [separator "."])

initial is a number (this will likely always be 0), render is a function taking a number and returning a string (used when the count is printed: typically you’ll use number->string but you might want to use Alpha to replace, for example, the number 1 with “A”), parent is another counter, and separator is an optional string to use between this counter’s count and its parent’s when printed.

Example code for making counters:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#|
Define counters and map of tags to counters
|#
(define section-counter (make-counter 0 number->string))
(define subsection-counter (make-counter 0 number->string section-counter))
(define subsubsection-counter (make-counter 0 number->string subsection-counter))
(define figure-counter (make-counter 0 number->string))
(define footnote-counter (make-counter 0 number->string))
(define tag-counters (hash 'section section-counter
                           'subsection subsection-counter
                           'subsubsection subsubsection-counter
                           'figure figure-counter
                           'footnote footnote-counter))

3. References

The other function of pollen-count is to references. The library will recognise two tags ref and hyperref, examples are shown below:

1
See Figure ◊ref{fig:tree}. See also ◊hyperref["Figure "]{fig:tree2}.

The difference between the two is that ref is simply replaced by the number associated with fig:tree whereas hyperref generates a hyperlink with some additional specified text (so that the word “Figure” is also included as part of the link).

You are now asking where fig:tree and fig:tree2 are specified. The other half of references are labels. The library recognise the tag label. For example, in this blog I specify sections with the section tag. If I want to then ref this section I add a label within this section:

1
◊section{Introduction ◊label{sec:intro}}

Somewhere else in the document I can then reference the introduction:

1
As stated in ◊hyperref["Section "]{sec:intro}...

4. Generation

The enumerations and references will typically be applied in the root function specified in directory-require.rkt. The function numebr-and-xref is provided by pollen-count. It takes as arguments the hashmap of tags to counters as explained in Section 2 and the document txexpr and returns another txexpr which includes the substituted references. For example:

1
(define refd (number-and-xref tag-counters xs-nohead))

At that point refd has not replaced the text of the section tag with the numbered equivalent. The number is stored as an attribute called data-number. In my blog code I then replace the section tag with an appropriate h tag and modify the text to include the generated number. The following function takes care of this but it is not part of pollen-count.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#|
Function to replace section tags after numbering
|#
(define (make-section tx heading)
  (make-txexpr heading
               (if (attrs-have-key? tx 'id)
                   (get-attrs tx)
                   (merge-attrs (get-attrs tx) 'id (gensym)))
               (if (attrs-have-key? tx 'data-number)
                   (append (list (attr-ref tx 'data-number) ". ") (get-elements tx))
                   (get-elements tx))))

5. Installation

The library can be installed with the following command:

1
raco pkg install git://github.com/malcolmstill/pollen-count

I have also uploaded the library to http://pkgs.racket-lang.org/ so it should be available at some point in the package catalog (though this is the first time I’m trying to do this so I could well have made a mistake).

6. To do

There are a number of improvements for the library that I have in mind and I need to put together some scribble documentation. If you have any issues or suggestions please use the issues page on Github.

7. Further reading

The source code for this blog is available on Github. This may be useful for understanding the usage outlined above.

Comments

comments powered by Disqus