An exporter is a hid registered. During the export process, pcb-rnd calls the exporter to draw objects on layers. The GPMI layer converts these calls to bindable events. An exporter script catches the drawing events relevant to the output format and draws everything from event handlers.

An exporter is sort of a drawing backend: pcb-rnd sets up graphic contexts (gc for short) and draws on them. The first gc set up should open the output file, the last gc closed should flush/close the file.

### Theory of operation

Assume only filled circles on the top assembly layer are holes. Emit a line for each of these and ignore everything else.

### Implementation

Load packages the script depends on:

- <ref>hid</ref> for registering the new exporter;
- <ref>layout</ref> for unit conversion;
- <ref>dialogs</ref> for error reporting.

Set up an exporter hid, storing the handle of each object created in a global variable:

- create a hid using <ref>hid_create</ref>
- add two attributes (fields) to the dialog using <ref>hid_add_attribute</ref>
- register the new hid using <ref>hid_register</ref> - this makes it an exporter

Set up global state variables:

- fmt will be a cache for the format selected by the user
- conv is the conversion scale between mm and PCB internal coordinate unit
- channel specifies a file handle or indicates that the output file is open
- green_light indicates that the exporter is drawing the relevant layer

Define a make_gc callback. It is called when a new graphic context is created (e.g. for layers). An exporter is sort of a drawing backend: pcb-rnd sets up gc's and draws on them. The first gc set up should open the output file, the last gc closed should flush/close the file. Define a destroy_gc callback for the latter. GCs are destroyed at the end of the export process. Use global variable channel to make sure the file is open/close only once (see TODO <ref>script context</ref>).

Define a set_layer callback that sets green_light to true if layer name is "topasssembly", false otherwise.

Callback fill_circle is the workhorse: check if we have the green light to emit lines, then convert coordinates and diameter to mm and decide what format to use for printing a line for each filled circle.

Finally, bind all four callbacks to exporter events.