OS How-To
Contents
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
Preface
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.
Introduction
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.
Tokens
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.
Control Tokens
Filters
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.
Count Token
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.
IF Tokens
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".
Loop Tokens
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:
|FOR,%eqp,0,COUNT[EQUIPMENT]-1,1,1| |EQ%eqp.NAME|
|ENDFOR|
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
loop. (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:
|FOR.min,max,perLine,phrase,startLine,endLine,exists|
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,\EQ%.NAME\,,,1|"
"<" /table ">"
HTML note: The "<"table">" and "<"/table">" are the HTML table opening and closing
commands and open and close a table row respectively and and 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 "\EQ%.NAME\". The startLine is (to start the row) and the endLine is (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! Barak