Named Number Registers: PART 2 - CSS counter

This is part 2 of our series of articles on Named Number Registers.
In this article we talk about the CSS counters 
We will also have a look at lists and the use of CSS counters in ordered lists.
We will use lists as an example to demonstrate how multi-level CSS counters works.
And finally we will take a short look under the hood how multi-level CSS counters translate into XPP number registers.
So what does this all have to do with Named Number Registers you might ask.
CSS counters and Named Number Registers are the same. 
When we use them inside CSS we call them 'counters'.
And when we use them in macro's or in XyPerl we call them 'Named Number Registers'.

CSS counters

CSS Counters are part of the CSS2 standard.
The XPP CSS implementation is a complete implementation that supports all of the CSS2 counters features (and even a bit more).

1. CSS counter properties: (re)setting and incrementing

In CSS you can use the following properties to work with a CSS counter ( in our example named 'section').

counter-reset: section;

= 'reset' the counter named 'section' to 0

counter-increment: section;

= increment the counter named 'section' by 1

You can also add an optional value after the counter name. This is how the CSS rules would look:

section100 {
    counter-reset: section 100;
}
sectionAndSkip { 
    counter-increment: section 2;
}

= set the counter 'section' to 100 when encountering the element 'section100' and when encountering the element 'sectionAndSkip add 2 to the existing value of the counter 'section'.

And because an element can only have a given property only once, you can not use multiple counter-reset or counter-increment properties in a given rule. but instead you simply list the counters you want to operate on in one go, all separated by a space and all in the same property:

counter-reset: chapter section para;

or even:

counter-reset: chapter 1 section 0 para 1

2. Outputting the value of a CSS counter

As with any other text that you want to generate in CSS, you will have to output the value of a CSS counter inside a 'content' property.

CSS

h3::before {
    counter-increment: section;
    content: "Section " counter(section) ": ";
}

XML

<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>

Output

Section 1: Introduction
Section 2: Body
Section 3: Conclusion

As you can see the default output style is a decimal number. You can define an optional output style.
Changing our CSS in the example above to:

h3::before {
    counter-increment: section;
    content: "Section " counter(section, upper-roman) ": ";
}

Gives us the following output:

Section I: Introduction
Section II: Body
Section III: Conclusion

The (long) list of possible output styles is a combination of CSS output styles and xpp specific output styles (e.g.: -xpp-ans).
The complete list can be found in the XPP CSS documentation.
Just search for the 'list-style-type' property.

3. CSS Counter names

As for the counter name, you are free to invent any name that contains any combination of a-z, A-Z, 0-9, _ and -.(e.g para-num)
Counter names are case sensitive, so counter 'section' is different from counter 'Section'.

However you can not use the following CSS keywords as name for your counter: 'none', 'inherit', 'unset' or 'initial'.
Also the name can not start with two dashes.

And XPP has 2 predefined counters: 'page' and 'pages'. Use counter(page) to return the current page number (= %p4) and counter(pages) to return the total number of pages (%totpage). 

4. CSS list

An ordered list is very simple to set up in CSS (and in XPP/CSS)
You just define your list element as an ordered list type, you tell the system what numbering you want to use (decimal, lower-roman, etc).
And finally you define what element you want to use to use as a list item.
Lets take the example of a typical HTML ol/li list

CSS

ol {
list-style-type: decimal;
}
li {
display: list-item;
margin-left: 1.5em;
}

XML

<ol>
<li>first item</li>
<li>second item
<ol>
<li>first item</li>
<li>second item</li>
<li>third item</li>
</ol>
</li>
<li>third item</li>
</ol>

output

1. first item
2. second item
1. first item
2. second item
3. third item
3. third item

As you can see this type of list can have several levels and each level will use its own numbering.
Note also that when you terminal the list, the all level of the list counter will be reset to 0.

The strange thing is that all of this works without using a named CSS counter. It simply just works.
We will see further down that even in XPP no (regular?) number registers are used to perform this trick.
Maybe engineering can enlighten us how this actually works within XPP. (a extra set of secret number registers?)

CSS lists with CSS counters 

Now using a simple list declaration is fine as long as you are satisfied with the default numbering of have a number + period.
But if you want to do something more or less fancy, you will have to declare your list using a CSS counter that you name yourself.
Like this you will be able to define how your list counter will be ouptut.

Taking the same example as above your CSS would become:
CSS

ol {
list-style-type: decimal;
counter-reset: list;
}
li {
display: list-item;
margin-left: 1.5em;
}
li::before {
counter-increment: list;
content: counter(list) -xpp-perl(qalz);
}

This would produce almost the same output as above just that there will be no period following the number.

output

1 first item
2 second item
1 first item
2 second item
3 third item
3 third item

Note that when you want to use your own counter, you also will have to reset and increment the counter yourself.

You can easily ask for double or triple numbering depending on the level of nesting.
All you have to do is to replace the counter(list) by counters(list, ".") and you are done.
The second argument to the counters() function allows you to specify the separator that will get used when outputting the different levels. 
This time lets have a look at an example done in XPP.

CSS

output

CSS counters and number registers

Inside XPP CSS counters are just another name for Named Number Registers. They are one and the same but when you use a Named Number Registers in a CSS style sheet, you call it a CSS counter and when you use it outside CSS you call it a Named Number Register. (more about this in part 3 of this series).

The CSS counters in XPP are implemented using number registers. For each named counter, an XPP number register is allocated and assigned
the value of the named counter. The first reference to a named counter assigns it to number register 255. Subsequent new counter names/levels will allocate number registers counting backwards from 255 down to 7.

This dynamic allocation can change at any yime. The link between the CSS counter/level and what number register is used, is stored in the job.dld file so that information can be maintained over different compose or editing sessions.

Here is an XPP example of which number registers get used.
CSS

In this example we are going to use 2 CSS counters: ol and list.
The ol counter is used 2 levels deep and the list counter is used 3 levels deep.
At the end of both lists I have dumped the last 6 number registers (255 to 250).
And this makes it completely clear that you better not even try to predict what number register gets used for what counter/level

When you would try to duplicate this example on your system, you will most probably see that things get stored in a different way.
It all depends in what order you define and compose things.