Template:Spell table/doc

This template was based on split table and modified so that it will automatically generate spell categories for the class/level pairs listed in the table. It generates two categories for each pair, of the form:

and

See example below.

If the class is a domain (a 3rd-edition method of organizing spells of a similar nature or theme) or a sphere (a 2nd-edition method of organizing priest spells), the second category will not be generated as agreed upon in this forum discussion.

Rituals have now been added as a variant and this template generates two unique categories for them. The categories were agreed upon in this template talk discussion. Rituals were formalized in 4th edition but exist in all editions in one form or another. In 4th edition, rituals have a "category" that classifies one or more skills or powers that can be drawn upon to perform the ritual. To document a ritual with this template, replace the spellcaster class with the "category" of the ritual, e.g., "Exploration", and specify the level as normal. The "category" can be entered in any of the following ways: Any other format may not generate the wiki categories correctly. The wiki categories generated by this template for an Exploration ritual would be:

and

Usage
Same as split table except for the addition of three parameters:
 * edition : Required. Value can be anything but by convention we are using 1e, 2e, 3e, 4e, or 5e. It will convert any input to lower-case.
 * variant : Optional. For 4th edition and later. Known values are Discipline, Evocation, Exploit, Hex, Prayer, Channel Divinity Prayer, Spell, and Ritual. The default is Spell. Not case-sensitive.
 * nocat : Optional. Setting this to true will suppress the generation of categories. Used mainly for documentation pages like this one.

Examples
This is an example of the template being used inside the Spell template (most parts of template not shown).

This will generate the following categories: Note that the Spell template will generate additional categories not shown here.
 * Category:Druid evocations (4e)
 * Category:2nd-level druid evocations (4e)
 * Category:Shaman evocations (4e)
 * Category:3rd-level shaman evocations (4e)
 * Category:Druid spells (3e)
 * Category:2nd-level druid spells (3e)

This is an example of the template being used inside the Ritual template (most parts of template not shown).

This will generate the following categories: Note that the Ritual template will generate additional categories not shown here.
 * Category:Exploration rituals (4e)
 * Category:4th-level rituals (4e)

Under the Hood
This template makes use of a number of helper templates that assist in breaking apart and formatting elements of the table data, namely the class (e.g., Wizard, Cleric), spell sphere or domain, ritual category, and the level (a non-negative integer). The helper templates are:
 * Nth : Converts a number to its counting or ranking form.  returns .
 * Power plural : Returns the plural form of a power title.  returns '. Case is not preserved; it returns a lower-case string. If new powers are added, please add them to Power plural. The default value is '. The variable plural is set to the output of this template (see example below).
 * Stripref : Returns everything up to, but not including, the first "&lt;" symbol, if any. This will remove any &lt;ref&gt; tags or other HTML markup that might be appended to a string.
 * Rootlink : This template returns everything to the left of the first "|" in a string. If an alternate name is given to a link, e.g.,, then this template returns  
 * Unlink : Returns the string between square brackets.  returns . It shouldn't matter how many brackets are present, including zero.

Here is a pseudo-code explanation of what this template does for each row of the table:
 * if a class (or sphere or domain or ritual category) or a level are specified
 * then
 * if the variant is ritual
 * then
 * Generate
 * Generate
 * else
 * Generate
 * if this is not a spell sphere or spell domain
 * then
 * Generate
 * else
 * Do nothing (i.e., suppress this type of category for spheres and domains)

Here is the implementation of the pseudo-code that operates on the first class/level pair, with spaces added to make it more readable:

The rest of the template is essentially 19 more repeats of this block of code. As you can see, the categories depend on both the class and level, so please make sure you specify the data in pairs.

Rituals
Starting with this invocation of the template:

The value of  will be   and the value of   will be. This is hopefully a worst case scenario: ritual cateogries don't have to be linked and the Ritual template has better ways to handle references in the infobox. Since both positional arguments have a value (which means  evaluates to a non-empty string), we proceed to the next if statement: {{#ifeq:{{lc:{{{variant|}}}}}|ritual which converts the value of parameter variant to lower case (so you could specify  or   and it would still work) and compares it to "ritual". Since they are equal in this example, we generate our first category. Breaking down the first Category line, start with this: [[Category:{{ucfirst:{{lc:{{unlink|{{#sub:{{stripref|{{{1}}}}}|0|{{#pos:{{stripref|{{{1}}}}}|ritual}}}} }} }} }} It's a lot of nested functions, so start with the deepest and work our way out: {{#pos:{{stripref|{{{1}}}}}|ritual}} Substituting the value of  we get {{#pos:{{stripref|Exploration}}|ritual}} Stripref removes any trailing &lt;ref&gt; tags, but there are none, so the unmodified string is returned: {{#pos: Exploration |ritual}} #pos: returns the (zero-based) starting position of a string within another string, in this case "ritual" within " ". The answer is {{#pos:Exploration|ritual}}. (Note that if the string is not found the answer is 0. This would be true if the ritual-category were given as "Exploration" instead of " ", for example). We take this answer and go up a couple levels in our deeply nested expression: {{#sub:{{stripref|{{{1}}}}}|0|14}} We already know that stripref doesn't find any &lt;ref&gt; tags, so we have: {{#sub:Exploration|0|14}} The #sub: function returns a substring starting at position 0 for a length of 14 characters and truncating the rest, which gives us {{#sub:[[Exploration ritual|Exploration]]|0|14}}. (Continuing the note above, if the length was 0, no truncation would take place, so "Exploration" would be unmodified.) Continuing from the inside out, we now have [[Category:{{ucfirst:{{lc:{{unlink|[[Exploration}} }} }} The unlink function removes square brackets from around a string, leaving Exploration. Finally, we convert what's left to lower case and then capitalize the first letter. For Exploration this doesn't change anything, but if the ritual type were "Shou Lung" then it would return "Shou lung". So far, we have generated this much of a category: [[Category:Exploration Picking up the rest of the first category line, we have {{#var:plural}} ({{lc:{{{edition}}}}})]] The variable plural was set to rituals by calling the {{tl|Power plural}} template with the value of variant, and edition was set to 4e in the invocation of {{tl|Spell table}} shown above (4E would also work because we convert it to lower case with lc:). Putting it all together we get our first category:

Moving on to the next line

The part that is new is [[Category:{{nth|{{stripref|{{{2}}}}}}}-level Substituting the value of  we get: [[Category:{{nth|{{stripref|3 }}}}-level Stripref finally has something to do, and returns 3, which nth converts to 3rd, leaving [[Category:3rd-level Concatenating the rest of the line gives us our second category:

Non-rituals
The next line of the code is the else branch of the if that checks to see if we were dealing with a ritual. Let's choose a different invocation of the template to match the code being analyzed:

In this case, variant is not set,  is   and   is 2. Since variant is not set, Power plural returns the default, spells and this is set as the value of the variable plural. The line of code is:

The only difference between this and our first ritual-related category is the rootlink function instead of the #sub: function. We start in the middle with

The stripref function removes the   and returns  . The rootlink function just removes everything to the right of a pipe symbol, "|", but since we don't have one, the string is still  . Unlink removes the square brackets leaving  . Finally, we convert everything to lower case and then capitalize the first character, yielding  . Adding plural and edition we get a complete category:

Now we come to another if statement. This one decides if the class (the value of ) is a spell domain or a spell sphere, and skips making an Nth-level category if so. Let's look and see how this works: {{#ifeq:{{#rpos:{{lc:{{{1}}}}}|domain}}|{{#rpos:{{lc:{{{1}}}}}|sphere}} The #rpos function starts at the end of the given string and searches from right to left for the first occurrence of the search string. The first #rpos searches for domain inside the lower case version of  . The second #rpos searches for sphere. If it finds the search string, then #rpos returns the (zero-based) index of the beginning of the search string. If it doesn't find it, then it returns –1. The #ifeq: statement compares these two results. Since  contains neither domain nor sphere, both results are –1 and therefore equal, so we take the then branch and generate another category. If either domain or sphere were found, then the two numbers would not be equal and we would take the else branch, which does nothing. So, taking the then branch we see

All of these elements have been explained previously, so suffice it to say that this generates