# pcb-rnd - user manual

## 7.3 Export plugins

### 7.3.2 export_xy

Export_xy is a configurable template based export plugin that prints text files. The output contains an optional header, then an optional block for each subcircuit and after each such subcircuit block an optional block for each terminal in that subcircuit. In pseudo-code:

    print header_template
    foreach subc in subcircuits {
    	print subc_template
    	foreach term in s.terminals {
    		print term_template
    	}
    }

Templates can reference to the current term, the current subc and global properties (such as board properties).

#### 7.3.2.1 Template configuration

Each xy export format has an user assigned ID (which is the short name of the format). There is a list of strings in the config tree under plugins/export_xy/templates; each item is named as ID.something where something is:

- ID.name: the long name of the format (as shown on the UI); mandatory
- ID.hdr: header template, printed once when the output file is opened; optional
- ID.subc: subcircuit template, printed once when a subcircuit is entered; optional
- ID.term: terminal template, printed once for each terminal within each subcircuit; optional

Templates are text strings; they are printed as is, keeping all newlines and whitespace. Portions in between % signs are substituted, depending on the context.

#### 7.3.2.2. Substitution keywords

keyword | description
--- | ---
%UTC% | current date and time in UTC
%author% | board author
%title% | board title
%suffix% | coordinate unit (mm or mil)
%boardw% | boward width (unit suffixed coord)
%boardh% | boward height (unit suffixed coord)
%subc.a.KEY% | paste the current subcircuit's attribute value of the attribute whose name matches KEY; print "n/a" for non-existing attributes
%subc.a.KEY|unk% | same as %subc.a.KEY% but print "unknown" instead of "n/a"
%subc.a.KEY?yes% | same as %subc.a.KEY% but print "yes" if attribute value represents true, "n/a" otherwise
%subc.a.KEY?yes:nope% | same as %subc.a.KEY% but print "yes" if attribute value represents true, "nope" otherwise
%subc.refdes% | print the refdes of the current subcircuit
%subc.refdes_% | print the cleaned refdes of the current subcircuit
%subc.footprint% | print the footprint name of the current subcircuit
%subc.footprint_% | print the cleaned footprint name of the current subcircuit
%subc.value% | print the value of the current subcircuit
%subc.value_% | print the cleaned value of the current subcircuit
%subc.x% | print the X coordinate of the origin of the subcircuit (coord with unit suffix)
%subc.y% | print the Y coordinate of the origin of the subcircuit (coord with unit suffix)
%subc.side-x% | same as %subc.x% but on the bottom side use bottom-pnp-origin
%subc.side-y% | same as %subc.y% but on the bottom side use bottom-pnp-origin
%subc.padcx% | print the X coordinate calculated from padstacks of the subcircuit (coord with unit suffix)
%subc.padcy% | print the Y coordinate calculated from padstacks of the subcircuit (coord with unit suffix)
%subc.side-cx% | same as %subc.padcx% but on the bottom side use bottom-pnp-origin
%subc.side-cy% | same as %subc.padcy% but on the bottom side use bottom-pnp-origin
%subc.pad_width% | print the total width calculated from padstacks of the subcircuit (coord with unit suffix)
%subc.pad_height% | print the total height calculated from padstacks of the subcircuit (coord with unit suffix)
%subc.pad_width_prerot% | print the total width calculated from padstacks of the subcircuit, before applying rotation (coord with unit suffix)
%subc.pad_height_prerot% | print the total height calculated from padstacks of the subcircuit, before applying rotation (coord with unit suffix)
%subc.rot% | print the subc rotation value in degrees
%subc.negrot% | print the subc -1 * rotation value in degrees
%subc.side-rot% | TODO
%subc.side-negrot% | TODO
%subc.siderot% | broken, do not use
%subc.270-rot% | print the subc rotation value in degrees, subtracted from 270
%subc.side270-rot% | broken, do not use
%subc.side% | "top" or "bottom" (determined by subc placement, the subc aux layer)
%subc.num-side% | "1" for top or "2" for bottom (determined by subc placement, the subc aux layer)
%subc.count% | integer value, incremented by one before processing each subcircuit
%subc.smdvsthru% | "SMD" if contains padstacks but no padstack with hole; "PTH" if contains padstack with hole; "0" if neither
%subc.smdvsthrunum% | "2" if contains padstacks but no padstack with hole; "1" if contains padstack with hole; "0" if neither
%subc.pincout% | "pin" or "pad" count. Do not use.
%term.netname% | name of the net the current terminal should be connected to according to the netlist; "NC" for no connection

Cleaned means any character that is non-alphanumeric, not "." and not "-" and not "+" is replaced with "_".

#### 7.3.2.3. Vendor specific rotation and translation

Some vendors (pick-and-place fabs) require the XY match their idea of the footprint with the same name. This especially affects rotation. A way to work this around is using xy::translate and xy::rotate attributes in a subcircuit. Values should be set on a per footprint name basis to compensate the mismatch between vendor's footprint orientation/origin and the subcircuit's.

When xy::rotate is present, it is specified in degrees and it is added to the original rotation of the subcircuit.

When xy::translate is present, it is specified as a pair of coordinates with units, for x and y offset. The pair is separated with whitespace or comma or semicolon. There must not be whitespace between the number and unit suffix in the coordinates. The x and y values are added to the origin of the subcircuit, in unrotated subc coordinate system. In other words it describes anoffset from the "pcb-rnd origin" of the subc to the pick-and-place origin of the subc when the subc is in neutral (non-rotated, non-mirrored) state.

Different vendors may require different translations. To overcome this problem xy_export offers an optional --vendor argument. When specified, it is inserted in the attribute name, e.g. for --vendor foo the attribute names xy::foo::translate and xy::foo::rotate are used instead of the plain xy::translate and xy::rotate.