linkcad.plugin
The plugin module provides the framework for creating tools, format readers, and format writers. Use linkcad.v1.plugin in scripts and plugins; the top-level linkcad.plugin module exposes the same current API for compatibility.
from linkcad.v1.plugin import ( tool, Tool, Option, TableColumn, format_reader, FormatReader, DrawingContext, DrawingBuilder, format_writer, FormatWriter, WriterContext, WriterController, DialogSpec, ChoiceItem, EventLog, Phase, LayerFlags, SortOrder, HolesMode, PolygonType, EndCap, FillRule,)Decorators
@tool()
Registers a class as a menu tool. See Tool Decorator.
@tool(name="My Tool", menu="Tools/Custom")class MyTool(Tool): def run(self, drawing) -> None: ...@format_reader()
Registers a class as a file import format. See Format Decorators.
@format_reader(name="My Format", extensions=["*.myf"])class MyReader(FormatReader): def read(self, path: Path, drawing: DrawingContext) -> None: ...FormatReader also provides parse_file(filepath, builder, file_size, progress_callback), the native bridge used by LinkCAD. Implement read() in user plugins and let the bridge call it.
@format_writer()
Registers a class as a file export format. See Format Decorators.
@format_writer(name="My Format", extensions=["*.myf"])class MyWriter(FormatWriter): def write(self, path: Path, drawing: WriterContext) -> None: ...FormatWriter also provides write_file(filepath, controller, progress_callback=None), the native bridge used by LinkCAD. Implement write() in user plugins and let the bridge call it.
Option Class
Option provides factory methods for defining typed, persistent options:
| Factory | Result Type | UI Control |
|---|---|---|
Option.integer(label, default, min, max) | int | Spin box |
Option.real(label, default, min, max, decimals) | float | Double spin box |
Option.boolean(label, default) | bool | Checkbox |
Option.string(label, default) | str | Text field |
Option.choice(label, choices, default) | str | Dropdown |
Option.path(label, default, file_filter) | str | File picker |
Option.color(label, default) | str | Color picker |
Option.table(label, columns, default) | list[dict] | Editable grid |
Option.cell_choice(label, default) | str | Cell dropdown |
All factories accept optional tooltip and enabled_when parameters.
Context Classes
DrawingContext
Pythonic builder interface for format readers. Methods:
cell(name, main=False)— context manager for creating cellsiter_lines(path, encoding="utf-8")— line iterator with progressiter_binary(path, chunk_size=8192)— binary iterator with progressprogress— get/set progress from0.0to1.0
WriterContext
Pythonic reader interface for format writers. Methods:
shapes(cell=None, layer=None)— iterate shapes with progressshapes_by_layer(cell=None)— shapes grouped by layershapes_by_cell(layer=None)— shapes grouped by cellcells()/cell_names()— cell name iteration/listlayers()/layer_names()— layer name iteration/listcell_count()/shape_count()— countsmain_cell_name()— top cell nameflatten— get/set hierarchy flatteningprogress— get/set progress from0.0to1.0
ShapeInfo
Data class yielded by WriterContext.shapes():
layer_name: str— layer namecell_name: str— cell namevertices: list[tuple]—(x, y)coordinates when availableis_polygon: bool— polygon vs. polyline-like outputwidth: int— polyline widthis_closed: bool— whether the shape is closed
Native Format Interfaces
DrawingContext and WriterContext cover most format plugins. The native DrawingBuilder and WriterController interfaces are also exposed for plugins that need direct parity with LinkCAD’s low-level format API.
DrawingBuilder
DrawingBuilder is supplied to import plugins by the LinkCAD runtime. It is not created directly by user code.
| Property | Description |
|---|---|
builder.resolution | Curve tessellation settings |
builder.cell | Current cell, or None |
builder.layer | Current layer, or None |
builder.cell_object | Most recently created cell object, or None |
builder.drawing | Drawing being constructed |
| Method group | Methods |
|---|---|
| Drawing metadata | set_drawing_name(name), set_drawing_modif_time(time), set_drawing_access_time(time), set_progress(percent) |
| Cells | open_cell(name_or_number, is_main_cell=False, reopen=False), close_cell(), delete_cell(), set_cell_name(name), set_cell_modif_time(time), set_cell_access_time(time), find_cell(name) |
| Layers | select_layer(name_or_number), select_layer(major, minor), set_layer_comment(comment), set_layer_color(rgba), set_layer_enabled(enabled), set_layer_z(z), set_layer_polarity_positive(positive=True), set_layer_polarity_group(group_name), set_layer_polarity_sequence(sequence) |
| Shapes | create_polygon(vertices, make_simple=False), create_polygon_with_bulges(vertices, bulges), create_rectangle(corner1, corner2), create_polyline(width, vertices, closed=False, end_cap=EndCap.Round), create_circle(center, diameter, donut=False), create_arc(center, radius, width, start_angle=0.0, end_angle=360.0, end_cap=EndCap.Round), create_donut(center, mean_diameter, width), create_nurbs(width, degree, knots, control_points, periodic=False), create_nurbs_weighted(width, degree, knots, control_points, weights, periodic=False) |
| Text | create_text(), set_text_position(position), set_text_height(height), set_text_stroke_width(width), set_text_style(flags, mask=TextStyleMask.None_), set_formatted_text(text), set_unformatted_text(text), set_text_font(font_name), set_text_width_factor(factor), set_text_obliquing_angle(angle_degrees), set_text_mirrored_x(mirror=True), set_text_mirrored_y(mirror=True), set_text_rotation(angle_degrees, absolute=False), set_text_box_width(width), set_text_line_spacing(spacing) |
| References | create_ref(cell_name_or_number), scale_ref(scale, absolute=False), mirror_ref_x(negate=True), mirror_ref_y(negate=True), rotate_ref(angle_degrees, absolute=False), translate_ref(position), set_ref_array_spacing(dx, dy), set_ref_array_size(cols, rows) |
| Context | save_context(), enter_context(handle), leave_context() |
| Logging | log_info(message), log_warning(message), log_error(message) |
| Properties and styles | set_entity_layer_style(flags), set_current_cell_object_real_property(name, value), set_current_cell_object_bool_property(name, value) |
| Fonts | DrawingBuilder.register_odb_fonts(fonts_dir) |
from linkcad.v1.db import EndCap, TextStyle, TextStyleMaskfrom linkcad.v1.geom import Point
builder.open_cell("TOP", is_main_cell=True)builder.select_layer("metal1")builder.create_arc(Point(0, 0), radius=10_000, width=500, end_cap=EndCap.Round)builder.create_text()builder.set_text_position(Point(0, 12_000))builder.set_text_height(1_000)builder.set_text_style(TextStyle.AlignHCenter, TextStyleMask.AlignH)builder.set_unformatted_text("TOP")builder.close_cell()WriterController
WriterController is supplied to export plugins by the LinkCAD runtime. It is not created directly by user code.
| Property | Description |
|---|---|
controller.file_name | Output file path |
controller.resolution | Curve tessellation settings |
controller.layer_count | Number of enabled layers |
controller.main_cell | Main cell |
controller.object_count | Current processed-object count |
controller.total_object_count | Total objects to export |
controller.fill_rule | Current FillRule |
controller.drawing | Drawing being exported |
controller.transformation | Current persistent coordinate transformation |
| Method group | Methods |
|---|---|
| Logging and progress | log_info(message), log_warning(message), log_error(message), set_progress(percent), init_progress_counter(force_flattened=False), set_object_count(count), set_total_object_count(count) |
| Export configuration | flatten_cell_hierarchy(mode=True), set_polygon_mode(holes_mode, polygon_type) |
| Layers | start_enum_layers(sort_order=SortOrder.Regular), next_layer(), layers(sort_order=SortOrder.Regular), get_layer_names() |
| Cells | start_enum_cells(), next_cell(layer=None), cells(layer=None), get_cells(), get_cell_count() |
| Fonts | start_enum_fonts(), next_font(), fonts() |
| Transformations | get_transformation(persistent=False), transform_point(point), transform_distance(distance) |
| Rendering | render_cell(cell, layer=None, xform=None), render_cell_in_layer_order(cell, xform=None) |
| Shape helpers | get_total_shape_count(), get_shapes(cell_name, flatten=False) |
HolesMode and PolygonType are available from the stable plugin module and are used by WriterController.set_polygon_mode():
from linkcad.v1.plugin import HolesMode, PolygonType
controller.set_polygon_mode(HolesMode.Link, PolygonType.AllowComplex)DialogSpec
DialogSpec describes a format or tool options dialog declaratively. It mirrors the Rust plugin dialog model and serializes to the JSON format consumed by the LinkCAD UI.
from linkcad.v1.plugin import DialogSpec, ChoiceItem
spec = ( DialogSpec("Import Options") .group("Geometry") .bool_field("merge", "Merge polygons", True) .int_field("facets", "Minimum facets", 4, 256, 32) .combo_field("units", "Units", ["nm", "um", "mm"], "um") .group_in_row("Layers", row=1) .single_select_list( "layer", "Layer", [ChoiceItem.with_display("metal1", "Metal 1")], ))
json_payload = spec.to_json()| Type | Purpose |
|---|---|
DialogSpec(title) | Top-level dialog descriptor |
DialogGroup(label, row=None) | Group of related fields; groups with the same row can be laid out side-by-side |
UiWidget(option_name, label, kind) | Single UI element in a group |
WidgetKind(kind_type, **kwargs) | Widget type plus configuration |
ChoiceItem(value, display, description=None) | List/combo-box choice item |
| Builder method | Description |
|---|---|
group(label) | Start a group |
group_in_row(label, row) | Start a group assigned to a row |
bool_field(option_name, label, default) | Checkbox |
int_field(option_name, label, min, max, default) | Integer spin box |
real_field(option_name, label, min, max, default) | Floating-point spin box |
string_field(option_name, label, default) | Text line |
combo_field(option_name, label, choices, default) | Combo box from string choices |
single_select_list(option_name, label, static_choices=None, inspection_key=None) | Single-select list |
multi_select_list(option_name, label, static_choices=None, inspection_key=None, value_separator=",") | Multi-select list |
note(text) | Display-only note |
separator() | Horizontal separator |
to_json() | Serialize to JSON |
ChoiceItem provides simple(value), with_display(value, display), and full(value, display, description) factory methods.
Format Metadata
Reader and writer decorators attach a FormatInfo object to the plugin class. For lower-level format constraints, use linkcad.v1.conv.Format and FormatAttributes; see linkcad.conv.
from linkcad.v1.conv import Format, FormatAttributes
fmt = Format()fmt.set_attributes(FormatAttributes.LAYER_NAMES | FormatAttributes.CELL_NAMES)fmt.set_layer_name_length(32)Exceptions
| Exception | Use |
|---|---|
PluginError | Base class for all plugin errors |
ParseError | File parsing errors; accepts line and path keyword arguments |
WriteError | File writing errors |
ValidationError | Option validation errors |
TableColumn
Data class for defining table option columns:
key: str— dict keylabel: str— column headercol_type: str—string,integer,real,choice,cell_choicedefault: Any— default valuechoices: list[str]— forchoicecolumnsdecimals: int— forrealcolumnsmin_value/max_value— for numeric columns
Enums
| Enum | Values | Use |
|---|---|---|
Phase | ParsedFile, ParsedAll, ClosedOpenCells, ResolvedRefs, SelectedMainCell, ResolvedLayersByBlock, AutoNumberedZ | Reader post-processing phase hooks |
LayerFlags | Normal, ByLayer, ByBlock | Entity layer-property inheritance for DrawingBuilder.set_entity_layer_style() |
SortOrder | Regular, Reverse | Layer enumeration order for WriterController |
EndCap | Round, SquareExtended, SquareFlat | Re-export of linkcad.v1.db.EndCap for builder shape creation |
FillRule | NonZero, EvenOdd | Re-export of linkcad.v1.db.FillRule for writer fill-rule handling |
Writer polygon-mode enums are available from linkcad.v1.plugin:
| Enum | Values | Use |
|---|---|---|
HolesMode | Link, Split, Extract, Keep | How holes are represented during polygon export |
PolygonType | AllowComplex, ForceSimple | Whether rendered polygons may be complex |