Releases: abey79/vpype
1.15.0
New features and improvements
- Added a
lineshufflecommand to randomize the plotting order of lines in the current geometry (thanks to @gatesphere) (#715) - Added a
cropcriclecommand to crop the current geometry to a circle (#808) - Added a
--orientationoption to thepagerotatecommand to conditionally rotate the page to a target orientation (thanks to @gatesphere) (#705) - Added support for Python 3.13 and dropped support for Python 3.10 (#784)
Bug fixes
- Fixed a crash when reading SVG with simplify active (via the
read --simplifycommand or the read APIs withsimplify=True) (thanks to @nataquinones) (#732) - Fixed the formatting of many commands' help text and added a snapshot test to avoid future regressions (#810)
- Fixed erroneous mention of
--page-sizeinlayout's inline help
Other changes
- Use Ruff for code formatting (supersedes Black) (#737)
1.14.0
New features and improvements
- Added support for Python 3.12 and dropped support for Python 3.9 (#681)
- Added a
--no-bboxoption to thelayoutcommand to use the pre-existing page size instead of the geometry bounding box as basis for layout (#682) - Added a
--flipoption to thereversecommand to also flip the line direction (#654) - Added a
--hyphenate LANGoption to thetextcommand (thanks to @pepijndevos) (#668)
Bug fixes
- Fixed issue with
ImageRendererwhere the GL context wasn't released, ultimately causing a crash when running the test suite (which could involve many hundreds of context creation) (#616) - Fixed CLI help for the
lreversecommand (#683)
Other changes
1.13.0
New features and improvements
- Added support for Python 3.11 and dropped support for Python 3.8 (#581)
- Added the
lidbuilt-in expression variable for generator and layer processor commands (#605)
Bug fixes
- Fixed a design issue with the
readcommand where disjoint groups of digits in layer names could be used to determine layer IDs. Only the first contiguous group of digits is used now, so a layer named "01-layer1" has layer ID of 1 instead of 11 (#606) - Fixed an issue on Wayland-based Linux distributions where using the viewer (e.g. with the
showcommand) would crash (#607)
Known issue
- As of PySide 6.4.2, a refresh issue arises on macOS when the viewer window is resized by a window manager (#603)
1.12.1
1.12.0
New features and improvements
- The
layoutcommand now properly handles thetightspecial case by fitting the page size around the existing geometries, accommodating for a margin if provided (#556) - Added new units (
yd,mi, andkm) (#541) - Added
inchunit as a synonym toin, useful for expressions (in whichinis a reserved keyword) (#541) - Migrated to PySide6 (from PySide2), which simplifies installation on Apple silicon Macs (#552, #559, #567)
Bug fixes
- Fixed a viewer issue where page width/height of 0 would lead to errors and a blank display (#555)
- Fixed a viewer issue where fitting the view to the document would not adjust when page size changes (vsketch only) (#564)
API changes
- Added
vpype.format_length()to convert pixel length into human-readable string with units (#541)
Other changes
- Updated svgelements to 1.8.4, which fixes issue with some SVG constructs used by Matplotlib exports (#549)
- Poetry 1.2 or later is not required (developer only) (#541)
- A
justfileis now provided for most common operations (install, build the documentation, etc.) (#541) - Migrated to Plausible.io (from Google Analytics) for vpype.readthedocs.io (#546)
vpype 1.11.0
Release date: 2022-07-06
New features and improvements
- Added the
splitdistcommand to split layers by drawing distance (thanks to @LoicGoulefert) (#487, #501) - Added
--keep-page-sizeoption togridcommand (#506) - Added meters (
m) and feet (ft) to the supported units (#498, #508) - Improved the
linemergealgorithm by making it less dependent on line order (#496) - Added HPGL configurations for the Houston Instrument DMP-161, HP7550, Roland DXY 1xxxseries and sketchmate plotters (thanks to @jimmykl and @ithinkido) (#472, #474)
- The
forfilecommand now sorts the files by their name before processing them (#506)
Bug fixes
- Fixed an issue with blocks where certain nested commands could lead totally unexpected results (#506)
- Fixed an issue with the
lmovecommand where order would not be respected in certain cases such aslmove all 2(the content of layer 2 was placed before that of layer 1) (#506) - Fixed an issue with expressions where some variable names corresponding to units (e.g.
m) could not be used (expressions may now reuse these names) (#506)
API changes
- Removed the faulty
temp_document()context manager fromvpype_cli.State()(#506) - Added equality operator to
vpype.LineCollectionandvpype.Document(#506)
Other changes
vpype 1.10.0
New features and improvements
-
Added the
alphacommand to set layer opacity without changing the base color (#447, #451) -
Improved support for layer pen width and opacity in the viewer (#448)
- The "Pen Width" and "Pen Opacity" menus are now named "Default Pen Width" and "Default Pen Opacity".
- The layer opacity is now used for display by default. It can be overridden by the default pen opacity by checking the "Override" item from the "Default Pen Opacity" menu.
- The layer pen width is now used for display by default as well. Likewise, it can be overridden by checking the "Override" item from the "Default Pen Width" menu.
-
Added HPGL configuration for the Calcomp Artisan plotter (thanks to Andee Collard and @ithinkido) (#418)
-
Added the
--dont-set-dateoption to thewritecommand (#442) -
The
readcommand now better handles SVGs with missingwidthorheightattributes (#446)When the
widthorheightattribute is missing or expressed as percent, thereadcommand now attempts to use theviewBoxattribute to set the page size, defaulting to 1000x1000px if missing. This behavior can be overridden with the--display-sizeand the--display-landscapeparameters.
Bug fixes
- Fixed an issue with
forlayerwhere the_nvariable was improperly set (#443) - Fixed an issue with
writewhere layer opacity was included in thestrokeattribute instead of usingstroke-opacity, which, although compliant, was not compatible with Inkscape (#429) - Fixed an issue with
vpype --helpwhere commands from plug-ins would not be listed (#444) - Fixed a minor issue where plug-ins would be reloaded each time
vpype_cli.execute()is called (#444) - Fixed a rendering inconsistency in the viewer where the ruler width could vary by one pixel depending on the OpenGL driver/GPU/OS combination (#448)
API changes
- Changed the parameter name of both
vpype_viewer.Engine()andvpype_viewer.render_image()frompen_widthandpen_opacitytodefault_pen_widthanddefault_pen_opacity(breaking change) (#448) - Added
override_pen_widthandoverride_pen_opacityboolean parameters to bothvpype_viewer.Engine()andvpype_viewer.render_image()(#448) - Added
vpype_cli.FloatType(),vpype_cli.IntRangeType(),vpype_cli.FloatRangeType(), andvpype_cli.ChoiceType()(#430, #447) - Changed
vpype.Document.add_to_sources()to also modify thevp_sourceproperty (#431) - Added a
set_date:bool = Trueargument tovpype.write_svg()(#442) - Changed the default value of
default_widthanddefault_heightarguments ofvpype.read_svg()(and friends) toNoneto allowsvgelementbetter handle missingwidth/heightattributes (#446)
Other changes
vpype 1.9.0
A commented version of these release notes is available in my annotated release notes post.
Note: This is the last version of vpype to support Python 3.7.
New features and improvements
-
Added support for global and per-layer properties (#359)
This feature introduces metadata to the pipeline in the form of properties which may either be attached to specific layers (layer property) or all of them (global property). Properties are identified by a name and may be of arbitrary type (e.g. integer, floating point, color, etc.). A number of system properties with a specific name (prefixed with
vp_) and type are introduced to support some of the new features. -
Layer color, pen width, and name are now customizable (#359, #376, #389)
- The
readcommands now sets layer color, pen width, and name based on the input SVG if possible. - The new
color,penwdith, andnamecommands can be used to modify layer color, pen width, and name. - The new
penscommand can apply a predefined or custom scheme on multiple layers at once. Two common schemes are built-in:rgbandcmyk. Custom schemes can be defined in the configuration file. - The
showandwritecommands now take into account these layer properties.
- The
-
The
readcommand now records the source SVG paths in thevp_sourceandvp_sourcessystem properties (see the documentation) (#397, #406, #408) -
Added property substitution to CLI user input (#395)
The input provided to most commands' arguments and options may now contain substitution patterns which will be replaced by the corresponding property value. Property substitution patterns are marked with curly braces (e.g.
{property_name}) and support the same formatting capabilities as the Python'sformat()function. -
Added expression substitution to CLI user input (#397)
The input provided to most command's arguments and options may now contain expression patterns which are evaluated before the command is executed. Expression patterns are marked with the percent symbol
%(e.g.%3+4%) and support a large subset of the Python language. A lot of examples were added in the cookbook. -
Added the
--attroption to thereadcommand to (optionally) sort geometries by attributes (e.g. stroke color, stroke width, etc.) instead of by SVG layer (#378, #389) -
The
readandwritecommands now preserve a sub-set of SVG attributes (experimental) (#359, #389)The
readcommand identifies SVG attributes (e.g.stroke-dasharray) which are common in all geometries within each layer. These attributes are saved as layer properties with their name prefixed withsvg_(e.g.svg_stroke-dasharray). Thewritecommand can optionally restore these attributes in the output SVG using the--restore-attribsoption. -
Introduced new commands for low-level inspection and modification of properties (#359)
propget: gets the value of a given global or layer propertyproplist: lists all global and/or layer properties and their valuepropset: sets the value of a given global or layer propertypropdel: deletes a given global or layer propertypropclear: removes all global and/or layer properties
-
Updated layer operation commands to handle properties (#359)
- When a single source layer is specified and
--probis not used, thelcopyandlmovecommands now copy the source layer's properties to the destination layer (possibly overwriting existing properties). - When
--probis not used, thelswapcommand now swaps the layer properties as well. - These behaviors can be disabled with the
--no-propoption.
- When a single source layer is specified and
-
Improved block processors (#395, #397)
- Simplified and improved the infrastructure underlying block processors for better extensibility.
- The
beginmarker is now optional and implied whenever a block processor command is encountered. Note: theendmarker must always be used to mark the end of a block. - Commands inside the block now have access to the current layer structure and its metadata.
-
Improved the
gridblock processor (#397)- The page size is now updated according to the grid size.
- The command now sets expression variables for use in the nested pipeline.
- Cells are now first iterated along rows instead of columns.
-
The
repeatblock processor now sets expression variables for use in the nested pipeline (#397) -
Added
forfileblock processor to iterate over a list of file (#397) -
Added
forlayerblock processor to iterate over the existing layers (#397) -
Added the
evalcommand as placeholder for executing expressions (#397) -
The
readcommand now will ignore a missing file if--no-failparameter is used (#397) -
Changed the initial default target layer to 1 (#395)
Previously, the first generator command of the pipeline would default to create a new layer if the
--layeroption was not provided. This could lead to unexpected behaviour in several situation. The target layer is now layer 1. For subsequent generators, the existing behaviour of using the previous generator target layer as default remains. -
Added
pagerotatecommand, to rotate the page layout (including geometries) by 90 degrees (#404) -
Added
--keepoption to theldeletecommand (to delete all layers but those specified) (#383) -
Providing a non-existent layer ID to any
--layerparameter now generates a note (visible with--verbose) (#359, #382)
Bug fixes
- Fixed an issue with the
randomcommand when using non-square area (#395)
API changes
-
Moved all CLI-related APIs from
vpypetovpype_cli(#388)A number of CLI-related APIs remained in the
vpypepackage for historical reasons. They are now located in thevpype_clipackage for consistency and to allow for future extensions.- Moved the following decorators, classes, and functions from the
vpypepackage to thevpype_clipackage. Importing fromvpypewill now generate a deprecation warning:@block_processor@generator@global_processor@layer_processor@pass_stateAngleTypeLayerTypeLengthTypePageSizeTypemultiple_to_layer_ids()single_to_layer_id()
- Moved and renamed
vpype.VpypeStatetovpype_cli.State. Using the old name will generate a deprecation warning. - Removed the following long-time deprecated aliases:
vpype.Length(alias tovpype_cli.LengthType)vpype.VectorData(alias tovpype.Document)vpype.convert()(alias tovpype.convert_length())vpype.convert_page_format()(alias tovpype.convert_page_size())vpype.PAGE_FORMATS(alias tovpype.PAGE_SIZES)
- Moved the following decorators, classes, and functions from the
-
Added support for property substitution in Click type subclasses (#395)
- Existing type classes (
AngleType,LengthType,PageSizeType) now support property substitution. - Added
TextTypeandIntegerTypeto be used instead ofstr, resp.int, when property substitution support is desired.
- Existing type classes (
-
Updated the block processor API (breaking change) (#395)
Block processor commands (decorated with
@block_processor) are no longer sub-classes ofBlockProcessor(which has been removed). The are instead regular functions (like commands of other types) which take aStateinstance and a list of processors as first arguments. -
Added methods to
vpype_cli.Stateto support expression and property substitution, deferred arguments/options evaluation and block processor implementations (#395, #397) -
vpype.Documentandvpype.LineCollectionhave multiple, non-breaking additions to support metadata (in particular through thevpype._MetadataMixinmix-in class) (#359, #397) -
Renamed
vpype.Document.empty_copy()tovpype.Document.clone()for coherence withvpype.LineCollection(the old name remains for backward compatibility) (#359, #380) -
Added
vpype.read_svg_by_attribute()to read SVG while sorting geometries by arbitrary attributes (#378) -
Added an argument to
vpype_cli.execute()to pass global option such as--verbose(#378)
Other changes
- Renamed the bundled config file to
vpype_config.toml(#359) - Pinned poetry-core to 1.0.8 to enable editable installs (#410)
- Changed dependencies to dataclasses (instead of attrs) and tomli (instead of toml) (#362)
- Removed dependency to click-plugin (#388)
- Improved documentation, in particular the Fundamentals and Cookbook sections (#359, #363, #397)
vpype 1.8.1
Security fix:
- Updated Pillow to 9.0.0 due to vulnerabilities in previous versions (CVE-2022-22815, CVE-2022-22817, CVE-2022-22816)
vpype 1.8.0
New features and improvements:
-
Added
lswapcommand to swap the content of two layers (#300) -
Added
lreversecommand to reverse the order of paths within a layer (#300) -
Improved HPGL export (#253, #310, #316, #335)
- Relative coordinates are now used by default to reduce file size. If absolute coordinates are needed, they a new
--absoluteoption for thewritecommand. - A homing command (as defined by the
final_pu_paramsconfiguration parameter) is no longer emitted between layers.
- Relative coordinates are now used by default to reduce file size. If absolute coordinates are needed, they a new
-
The viewer (
showcommand) now catches interruptions from the terminal (ctrl-C) and closes itself (#321) -
The
readcommand now accepts-as file path to read from the standard input (#322)
Bug fixes:
- Fixed issue with HPGL export where page size auto-detection would fail when using the default device from the config file (instead of specifying the device with
--device) (#328) - Fixed issue where the viewer would crash with empty layers (#339)
Other changes: