## CAM support

The purpose of the CAM support is to provide an unified interface to export a a board in different file formats, using different exporter plugins. The interface consists a CLI layer (each export plugin's "cam" option) and an optional GUI (the CAM plugin).

### CAM export support in each other plugins

Each CAM-plugin-compatible exporter plugin offers an option called "cam". The syntax and capabilities are the same for all exporter's cam option.

The syntax is:

    outfile=layergrp[,layergrp,...][;opt][;opt...]

where:

- outfile is the output file name (unlatered by the code)
- layergrp: one or more layer group definitions separated by comma (see below)
- optionally a list of exporter options in the same format as on direct command line (e.g. --verbose); when there's overlap on any state/definition between opts and CAM operation, the effect of the opt is ignored

Syntax of the layer group definition:

- @layername (e.g. "@top_copper" if the group's name is top_copper)
- location-material (e.g. "top-copper" for any layer group that is copper and is on the top side)
- type[-type...] (more generally: a list of layer type flags)
- type:offs (e.g. "copper:+2" means the second copper layer group from the top, "copper:-3" means the third copper layer group from the bottom; offs is counted from 1, +1 meaning top outer layer, -1 meaning bottom outer layer)

(TODO: optionally prefixed with + or - for polarity and something for bloat/shrink)

Examples:

directive | explanation
--- | ---
bot.gbr=@bottom_copper,@bottom_silk | export layer groups called bottom_copper and bottom_silk (by group name)
asm=top-assy | export the top assembly group, by type
fabrication.ps=fab | export any fab layer group, by type
gnd=copper:2 | export the second copper layer group from the top (the first internal copper layer group under the top copper layer group, if it is a multilayer board; for 2 layer boards this will be the bottom copper layer group)
gnd=intern-copper:1 | similar to the above, but addresses the first internal copper layer group explicitly so it can not end up being the bottom copper layer group
pwr=copper:-2 | export the second copper layer group from the bottom (the first internal copper layer group above the bottom copper layer group, if it is a multilayer board; for 2 layer boards this will be the top copper layer group)
gnd=intern-copper:-1 | similar to the above, but addresses the last internal copper layer group explicitly so it can not end up being the top copper layer group

### CAM plugin

The CAM plugin is a way to manage output "jobs": collections of cam export settings for reproducing export packages in various formats.

...

A job is a script that contains zero or more export directives, separated by semicolons or newlines. An export directive is one of these:

    desc text
    prefix path
    plugin name [--option value] [--option value] ...
    write outfile=layergrp[,layergrp,...]

desc is a free form one-liner that describes what the job is for. Multiple desc directives may be present (to bypass the limitation that the text can not contain newlines).

The prefix directive sets up a file name prefix that is active until the next prefix directive or end of the script. Before the first prefix directive the prefix is an empty string. Any outfile will be prefixed with the current prefix. If the prefix contains at least one path separator, the directories it refers to are also created. (It is sort of a 'mkdir -p path; cd path' in the shell sense.)

The plugin directive selects a plugin and sets plugin specific options. The plugin and options are active until the next plugin directive or the end of the script. The first outfile directive must be preceeded by a plugin directive.

The write directive argument has the same syntax as the cam argument for each cam-capable exporter, see above. Each write is a call to an exporter the same way as if pcb-rnd was called with --cam and -x with the exporter and options taken from the last plugin directive.

For example, the following config tree defines a job called doc_png that generates two 600 DPI images from the sides of the board, copper and silk combined, all in the doc/ dir (that is created if necessary):

    li:pcb-rnd-conf-v1 {
    	ha:overwrite {
    		ha:plugins {
    			ha:cam {
    				li:jobs {
    					doc_png {
    						desc export top and bottom copper and silk in 600 DPI pngs
    						prefix doc/
    						plugin png --dpi 600
    						write top.png=top-copper,top-silk
    						write bottom.png=bottom-copper,bottom-silk
    					}
    				}
    			}
    		}
    	}
    }

Once the above subtree is loaded in the config, the following action triggers the export:

    cam(call, doc_png)

### Tips for using with various exporters

When exporting to ps, consider using the --no-show-toc. It is possible to combine multiple layers (e.g. top silk and top copper, which may be useful for a single-layer board) using the --single-page option.