Barak's Email Note
Since there seem to be a few OS questions cropping up, I thought I'd post a OS help file I started a while ago (note it is *not* complete, but what's there might still be helpful).
Hopefully the formatting on this will still be readable after e-mailing...
Creating Character Sheet Templates
This guide is in the main going to focus on using the tokens effectively and appropriately. For simplicity, we will primarily use HTML examples, some of which may be fairly complicated, with XML/XSL examples for PDF templates given as needed. If you need help with HTML you should visit www.w3c.org and read their tutorials. For XML/XSL information ??? After going over the basics, I will be taking you through the steps I used to create a sheet to display a character's known spells and spellbooks.
You will need to have a basic understanding of how PCGen uses character sheet templates to create them. When you "Export" a character, the program will ask you which template you would like to use. PCGen starts by reading that template into memory. PCGen scans for special character sets called "tokens" as it reads the template. These tokens represent various bits of information about the character you are exporting. When PCGen encounters one of these tokens, it retrieves the information from the character file and inserts the information into the spot where the token was. PCGen writes the file out to disk with the information in place of the tokens once it has completely loaded the file.
A sample line in an HTML template file might be:
Character Name: |NAME|
If you open the template with an HTML browser you would see:
Character Name: |NAME|
When you open the output file after exporting a character named George using that template you would see:
Character Name: George
The bodies of the templates themselves can be done in HTML or XML/XSL for PDF. In either case, the tokens used to get information from PCGen into the sheet are the same. A word of warning: PCGen only changes the token, nothing else. If you put in bad HTML or XML/XSL code, bad HTML or XML/XSL code will come out.
The first and most important thing I want to stress is to read the documentation on the individual output tokens. Then read them again. There are many subtleties in the use of the tokens contained there that cannot be covered in a tutorial.
Through some frustrating trial and error I learned a few important things regarding basic Character Sheet design:
1) Decide on a specific purpose/use for your template. There are LOTS of tokens and there is no need to try and use them all.
2) Figure out what's going to go on the sheet. Are you just going to show the main AC? Are you going to want to show all the modifiers that make up the total AC? Do you want spell lists? Etc.
3) Identify most of your tokens beforehand. Once you have decided what you want on the sheet, it's time to start figuring out what tokens you need to use. It is easiest to sketch a simple layout on a sheet of paper and fill in what tokens go where so you have a quick reference. You don't have to get them all right now, but it is very helpful to have them right there so you don't have to go digging around through the documentation looking for the proper token when you're actually trying to type in the sheet.
Now down to the true nuts and bolts, the tokens. First, some general notes:
1) All tokens are CAPITALIZED. There may be variables or options that are not, but the token itself will be.
2) All tokens are delimited (set apart) from the rest of the text on the character sheets by either the | (pipe) character, a \ (single backslash) or a \\ (double backslash), depending on where the token is used. There are no spaces between the beginning and end of the token and the delimiter characters. The token documentation has the delimiter characters left out for ease of reading.
3) Some tokens output a single item, some output comma delimited lists.
4) Not all tokens make PCGen output something. Some are control commands that make comparisons, cause loops or apply filters. We will discuss these shortly.
5) Many tokens use variables so you can get at certain aspects. Variables come immediately after the token with a period "." between them. For example the token EXPORT can provide date and time information on a sheet using EXPORT.DATE and EXPORT.TIME. The variables that may be used with each token are listed in the output sheet token documentation. Not all variables are capitalized. Some numeric variables start at zero (0) but those should be noted in the documentation for the token.
The first and easiest to understand of the control tokens are the filter tokens. These are used to stop the normal output if the filter condition is not met. Filters all begin with a % (percent) sign and will run from the moment they are invoked until they encounter a different filter or until they encounter the end of filter token, which is a single % symbol (E.g. |%|) In case this wasn't clear, what it essentially means is that one, and only one, filter may be active at any time. Nested filters are not supported.
The simplest ones are in the form |%TOKEN|. Here PCGen simply checks to see if the character has the appropriate data. A good use of these simple filters is to suppress spell list blocks for non-spellcasters so you can use the same character sheet for both types of characters and not have an empty spell list cluttering things up for a non-spellcaster. Examples of these types of tokens would be |%SPELLISTBOOK| or |%BIO|.
Some slightly more complex filters are in the form of |%ARMORx| and |%WEAPONx|. In these filters x represents the number of appropriate items (armor type or weapon type for the above examples) that the character must have in order for the filter to allow output. For example: |%WEAPON3| means that there would be no output after the filter until it reaches the next filter or filter end token unless the character has at least three weapons. If the character has three weapons the output would proceed as normal.
The next form a filter may take is that of classname=level or SPELLLISTCLASSx=level. For example, |%BARD=3| would filter output if the character did not have at least three Bard levels. |%SPELLLISTCLASS0=2| would filter output if the character did not have at least two levels in his first spellcasting class. SPELLLISTCLASS is one of the tokens that starts at zero as mentioned earlier.
The final form of filter is one that uses variables. They all start with %VAR and take the form of |%VAR.name.label.value|. The "name" is the name of any variable that has been set up in the LST files using the VAR tag. The label is a comparator and must be one of the following:
. EQ (equals) . NEQ (not equal) . LT (less than) . LTEQ (less than or equal to) . GT (greater than) . GTEQ (greater than or equal to).
An example using the variable TOTALPOWERPOINTS defined in a LST from the Psionic Handbook would be: |%VAR.TOTALPOWERPOINTS.GTEQ.1|. This would filter output unless the variable TOTALPOWERPOINTS was greater than or equal to 1.
All of the available filters are listed in the output sheet token documentation with the exception of the VAR ones which are too numerous to include since every VAR in every LST can be used as a filter.
The second special token is the COUNT token. This token also takes a variable, but in a slightly different form. The variable for the COUNT token goes inside a set of  (square brackets). This token returns the number of items of the variable type given. |COUNT[CLASSES]| would return the number of classes a character has. While this has some limited use as an actual output token, these tags are more often used to set the upper limit in a FOR loop, which will be explained shortly.
All of the available variables for the COUNT token are listed in the output sheet token documentation.
The next set tokens in our review of control tokens are the IIF/OIF tokens. The simpler of the two is the OIF token. It is used to evaluate an expression and return a value (text or number). This token is in the form |OIF(expr,true,false)|. There are only certain expressions that may be used, and they are listed in the output sheet token documentation. The "true" and "false" parts may be anything you want them to be. |OIF(SPELLCASTER0=PREPARE,Yes,No)| would return "Yes" if the character's first spellcasting class had to prepare spells and "No" if it didn't.
The IIF token has a much broader range and does not return output itself. The IIF statement takes the form of:
|IIF(expr)| true actions |ELSE| false actions |ENDIF|
The IIF token, like the OIF token, can only take the expressions listed in the output sheet documentation as usable with IF tokens. The power of this token is in the ability to perform a whole series of actions based upon the evaluation of the expression. An example of the IIF token could be:
|IIF(SKILL0.UNTRAINED)| * |ELSE| x |ENDIF|
This bit would check to see if your first skill (SKILL0) is usable untrained. If the skill is, it outputs an "*" otherwise it outputs an "x".
The last set of control tokens we need to cover are the FOR/DFOR tokens. These tokens provide loop capabilities for creating lists on character sheets. These lists can include equipment, classes, skills, spells, etc.
The FOR loops come in three forms. The format of the first is:
|FOR,%var,min,max,step,exists| character stuff |ENDFOR|
In this token, %var is a variable name that you assign when you create a loop. It should not/cannot be the same as a variable defined in a LST by the VAR tag. Whenever you use that variable within that loop, it will be evaluated and return the current iteration number. The min and max values are the start and end points for the loop. It is normal to start the loops at zero because most of the arrays in PCGen are zero indexed, meaning they start at zero. You may use the COUNT[xxx] token in the max field to tell the loop when to stop. The step field is how much you want it to increment the variable each time it goes through the loop (this is usually 1). The exists field controls how the loop acts if it runs out of data before the max value is reached. There are only three valid values for the exists field: 0, 1 or 2. If the exists field is a 0, the loop will continue processing until the max is reached. If it is a 1, then the loop will stop processing the contents of the loop and continue on through the sheet as if the loop had reached the max. If exists is 2 and the character sheet is currently within a filter, PCGen will not print anything else until the end of the filter |%| is reached or another filter is begun The |ENDFOR| token tells the program where the loop ends and is required when you use a |FOR, loop.
Here is an example demonstrating a FOR loop:
This loop will generate a list of the names of all of your equipment, one
item to a line using the EQx.Name token, where x is the current count in the
is an HTML line break.)
Example output for a typical starting fighter would be:
Half-Plate Outfit (Explorer's) Shield (Large/Steel) Battleaxe
The variable in the above loop is %eqp. The min is 0. The max is COUNT[EQUIPMENT]-1. I subtracted 1 because we are going to cycle through the equipment list and the equipment list array starts at 0 while the COUNT statement starts at 1. Because of this we need to reduce the actual count by 1. The increment is going to be 1 and the loop will exit immediately if it runs out of items before the max is reached.
Notice the use of the variable %eqp to define the equipment number each time through. Using loop variables properly, you can accomplish the creation of large lists with relatively little effort. This is the main reason to use loops.
One last thing to know about these kinds of loops is that they may be nested. For example:
|FOR,%spbk,0,COUNT[SPELLBOOKS]-1,1,1| |SPELLBOOKNAME%spbk| |FOR,%lvl,0,9,1,1| |SPELLLISTBOOK%spbk.%lvl| |ENDFOR| |ENDFOR|
This would create a list of spells for each of your spellbooks (by level).
The spell list loop is said to be nested inside of the spell book loop. This allows us to use two variables. If you need more variables, you may nest more loops. Notice that each loop needs its own |ENDFOR| statement.
The format for the next kind of FOR loop looks like this:
This kind of FOR loop can be used to generate multi-column lists. Notice that the character following the FOR is a period instead of a comma. There is no variable name in this kind of loop; to get the current increment of the FOR loop you would use the "%" (percent) symbol. The min and max variables are the start and end points for the loop. The perLine variable is how many phrases will be repeated before the endLine is printed (e.g. 3 if you wanted a 3-column list). The phrase is the code that is parsed for tokens. You must use "\" (backslash) characters instead of "|" (pipe) characters to delimit tokens within a FOR loop phrase. The startLine will be output at the beginning of the loop and after the endLine. The endLine variable will be printed every perLine times through the loop.
This type of FOR loop does not require an |ENDFOR| tag. This type of FOR loop cannot be nested.
NOTE: If you are using this type of FOR loop to create a party sheet (psheet*.*) you must use a "\\" double backslash to delimit the tokens within the phrase. Party sheets will be covered elsewhere, but it is important to be aware of it.
A real example (for a single character sheet):
"<" table ">" "|FOR.0,COUNT[EQUIPMENT]-1,2,<td>\EQ%.NAME\</td>,<tr>,</tr>,1|" "<" /table ">"
HTML note: The "<"table">" and "<"/table">" are the HTML table opening and closing commands <tr> and </tr> open and close a table row respectively and <td> and </td> open and close a single piece of data in the table. The extra Quotes "<" ">" were to allow the WIKI to display these tags.
This would produce a table of two columns listing the names of all your equipment.
Example Output: Half-Plate Outfit (Explorer's) Shield(large/Steel) Battleaxe
There is no named variable in this loop. The min is 0. The max is COUNT[EQUIPMENT]-1. The perLine is 2, so there will be two phrases output before the endLine. The phrase is "<td>\EQ%.NAME\</td>". The startLine is <tr> (to start the row) and the endLine is </tr> (to end the row).
The final type of for loop is the DFOR loop. While the format of the loop itself is fairly complicated, what it does isn't. Instead of creating a table of elements across and then down, it creates a table of elements down and then across.
To illustrate the difference between the different loops:
FOR, Loop Output FOR. loop Output DFOR Loop Output 1 1 2 3 1 4 2 4 5 6 2 5 3 3 6 4 5 6
Hope this might help people!