Maybe one of the most powerful features of pcb-rnd is the parametric footprint facility. This allows on-the-fly generation of footprints (AKA sub-circuits) using a script.

There are a number of useful generic scripts included with pcb-rnd, for generating such things as DIP, QFN, BGA, etc footprints, but what if you want to write your own parametric footprint script?

Well, it's not actually that hard, and this should help you get started.

Parametric footprint scripts can be written in any language you choose. However, for ultimate portability it is recommended that you use awk or sh as your language of choice since both are pretty much guaranteed to exist on any standard system and won't rely on the user installing anything special. But the choice of language is entirely up to you.

For any parametric script to operate properly within the GUI a properly formatted set of control information is required. While it's not essential for your script to be usable, without it the GUI will not be able to present a properties editing panel for the user to select different values.

This is done by informing pcb-rnd of such things as what parameters the script requires, what the purpose of the script is, and other such "meta" information. This is communicated to pcb-rnd by the script being executed and being passed the --help flag.

The script then needs to return (on Standard Out) the meta information in the correct format.

The basic format of meta information is simple:

@@command[:item] <data and arguments>

The meta information can be broken down into two distinct groups: header and parameter information.

Header format

The header information describes the script as whole. It includes such things as the description, a short usage example, and the list of parameters that are to follow.

A typical header section (extracted from the DIP footprint generator) may look something like this:

@@example dip(18)
@@purpose Generate classic DIP packages.
@@desc Generate thru-hole DIP packages with variable number of pins and
@@desc row spacing
@@params n, spacing

Here we give an example of dip(18) which is used to pre-fill the footprint selection dialog's entry box. The purpose is a brief one-line overview of what the script does, and desc gives more detail about what it does and how it works. You can have as many @@desc entries as you need to include all the information you desire.

Finally we have the list of parameters. Here we are defining two parameters, n and spacing. These parameters are passed to your script when executed using the names we define here as a key, in the format name=value. We get to define how the parameters actually work later on though.

Parameter lists

Following the header is the list of parameters and any control information that goes along with them. Each command slightly changes the way in which an individual parameter (specified as :parameter) is handled by the GUI.

Primarily you need to give each parameter a description. For example:

@@param:n number of pins
@@param:spacing spacing between the two rows of pins

These descriptions are used in tooltips which appear when you hover over an entry box in the GUI. Secondary to that you can specify a number of other options to change how the value is displayed in the GUI. These are the options for the spacing parameter in the DIP footprint generator:

@@default:spacing 100 mil

We're saying here that the spacing parameter is an optional one (@@optional:spacing) so it won't be included in the command parameters when calling the script if no value has been entered. We're also defining it as a "dimension" (a size with distance units, like mil, mm, um, etc) with the @@dim:spacing command. On top of that we give it a default value. It is important to note that, since this is an optional value, the "default" is purely for information purposes only. It is added to the tooltip in the GUI, but it doesn't get sent to your script in the case of nothing being entered. It is important for the sake of continuity that the script itself imposes the same default value for a missing parameter as you specify in the header.

Another type of parameter is the enum. This results in a dropdown list (or "combo box" if you prefer) of options that the user can select from. To make a parameter an enum, instead of specifying @@dim:... you need to specify a number of @@enum:... entries. Each entry corresponds to one choice in the list, and you can have as many choices as you need. The basic format for an enum is:

@@enum:<parameter> <key> <descriptive text>

For example, from the "connector" parametric footprint, we have this enum:

#@@enum:eshift:x shift columns
#@@enum:eshift:y shift rows
#@@enum:eshift:none do not shift anything

This provides three options to select from, one "shift columns", one "shift rows" and one "do not shift anything". When you want to specify a default value for the parameter you need to use the "key" specified in the enum - that is "x", "y" or "none" in the example above. This then allows the GUI to display the correct default entry selected in the options panel.

A third type of parameter is a boolean. This translates to a "true" or "false" value. Unfortunately the GUI doesn't display this any differently to a normal parameter (checkboxes are planned for the future), so manually entering "true" or "false" into the GUI is required.


Finally there is the option of adding a "preview_args" command for a parameter. This is used by the website to generate examples to demonstrate how the option affects the output. Any additional parameters your script needs for the current parameter to make sense and generate a valid output can be set here. For example the connector script has this entry:

@@preview_args:etrunc 2,3,eshift=x

This value will be combined with values for the etrunc parameter to generate different outputs. Since etrunc is a bool type parameter the resultant parameter lists that would be used would look somewhat like:


Parameter passing

A word, now, on how parameters are passed to your script. The policy of the GUI is "least changes necessary" to the existing text in the library window. When a parametric footprint is first selected the entry box is populated with whatever is specified in the @@example command. Any positional dependent parameters that are specified as just a value in the example will remain as just a value when passed to the script. Any additional parameters not in the example will be appended to the parameter list with their name. This makes a hybrid positional-and-named parameter list which your script has to be able to handle properly.

To take the @@example from the connector parametric footprint as a starting point:

@@example connector(2, 3, silkmark=external, spacing=100)

You can see that the first two parameters are specified as just numbers. These correspond to the first two parameters in the @@params nx, ny, spacing, silkmark, eshift, etrunc list. These two parameters will always be replaced with just the value. All other parameters will be added as name=value pairs.

From this point on it is now the job of your script to parse these parameters properly and generate a suitable footprint file. It should pass the footprint data back to pcb-rnd on Standard Out ideally in lihata format, although any other footprint format (such as PCB .fp format, or tEDAx format) could theoretically be used if that is more appropriate.

If your script needs to report an error it should do so on Standard Error as simple text.