Skip to content

Commit

Permalink
- added commands propset, propget, propdel, proplist, `propcl…
Browse files Browse the repository at this point in the history
…ear`

- removed commands `metadata`, `clearprops`
- added global metadata by refactoring metadata-related implementation into a _MetadataMixin class
- vp.Document's page_size is now stored as a global property
- added a warning when a layer passed to `--layer` doesn't exist
- renamed metadata to properties in `stat` (and other user facing texts)
  • Loading branch information
abey79 committed Jan 8, 2022
1 parent 892d6e7 commit 7360235
Show file tree
Hide file tree
Showing 9 changed files with 462 additions and 90 deletions.
28 changes: 20 additions & 8 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ CLI reference
.. click:: vpype_cli:circle
:prog: circle

.. _cmd_clearprops:
.. click:: vpype_cli:clearprops
:prog: clearprops

.. _cmd_color:
.. click:: vpype_cli:color
:prog: color
Expand Down Expand Up @@ -95,10 +91,6 @@ CLI reference
.. click:: vpype_cli:lswap
:prog: lswap

.. _cmd_metadata:
.. click:: vpype_cli:metadata
:prog: metadata

.. _cmd_multipass:
.. click:: vpype_cli:multipass
:prog: multipass
Expand All @@ -119,6 +111,26 @@ CLI reference
.. click:: vpype_cli:penwidth
:prog: penwidth

.. _cmd_propclear:
.. click:: vpype_cli:propclear
:prog: propclear

.. _cmd_propdel:
.. click:: vpype_cli:propdel
:prog: propdel

.. _cmd_propget:
.. click:: vpype_cli:propget
:prog: propget

.. _cmd_proplist:
.. click:: vpype_cli:proplist
:prog: proplist

.. _cmd_propset:
.. click:: vpype_cli:propset
:prog: propset

.. _cmd_random:
.. click:: vpype_cli:random
:prog: random
Expand Down
107 changes: 103 additions & 4 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,18 @@ class Command:
Command("squiggles"),
Command("text 'hello wold'"),
Command("penwidth 0.15mm", preserves_metadata=False),
Command("metadata vp:name my_name", preserves_metadata=False),
Command("color red", preserves_metadata=False),
Command("name my_name", preserves_metadata=False),
Command("clearprops", preserves_metadata=False),
Command("propset -g prop:global hello", preserves_metadata=False),
Command("propset -l 1 prop:local hello", preserves_metadata=False),
Command("propget -g prop:global"),
Command("propget -l 1 prop:global"),
Command("proplist -g"),
Command("proplist -l 1"),
Command("propdel -g prop:global", preserves_metadata=False),
Command("propdel -l 1 prop:layer", preserves_metadata=False),
Command("propclear -g", preserves_metadata=False),
Command("propclear -l 1", preserves_metadata=False),
]

# noinspection SpellCheckingInspection
Expand Down Expand Up @@ -131,8 +139,8 @@ def test_commands_keeps_page_size(runner, cmd):

args = cmd.command

if args.split()[0] in ["pagesize", "layout"]:
return
if args.split()[0] in ["pagesize", "layout"] or args.startswith("propclear -g"):
pytest.skip(f"command {args.split()[0]} fail this test by design")

page_size = None

Expand Down Expand Up @@ -551,3 +559,94 @@ def test_text_command_wrap(font_name, options):
def test_text_command_empty():
doc = execute("text ''")
assert doc.is_empty()


@pytest.mark.parametrize(
("cmd", "expected_output"),
[
("propset -l1 prop val", ""),
("propset -g prop val", ""),
("propget -g prop", "global property prop: n/a"),
("line 0 0 1 1 propget -l1 prop", "layer 1 property prop: n/a"),
(
"line 0 0 1 1 propset -l1 -t int prop 10 propget -l1 prop",
"layer 1 property prop: (int) 10",
),
(
"line 0 0 1 1 propset -l1 -t str prop hello propget -l1 prop",
"layer 1 property prop: (str) hello",
),
(
"line 0 0 1 1 propset -l1 -t float prop 10.2 propget -l1 prop",
"layer 1 property prop: (float) 10.2",
),
(
"line 0 0 1 1 propset -l1 -t color prop red propget -l1 prop",
"layer 1 property prop: (color) #ff0000",
),
(
"pens rgb proplist -l all",
"listing 2 properties for layer 1\n"
" vp:color: (color) #ff0000\n"
" vp:name: (str) red\n"
"listing 2 properties for layer 2\n"
" vp:color: (color) #008000\n"
" vp:name: (str) green\n"
"listing 2 properties for layer 3\n"
" vp:color: (color) #0000ff\n"
" vp:name: (str) blue",
),
(
"pens rgb propdel -l1 vp:color proplist -l all",
"listing 1 properties for layer 1\n vp:name: (str) red\n"
"listing 2 properties for layer 2\n"
" vp:color: (color) #008000\n"
" vp:name: (str) green\n"
"listing 2 properties for layer 3\n"
" vp:color: (color) #0000ff\n"
" vp:name: (str) blue",
),
(
"pens rgb propdel -l all vp:color proplist -l all",
"listing 1 properties for layer 1\n vp:name: (str) red\n"
"listing 1 properties for layer 2\n vp:name: (str) green\n"
"listing 1 properties for layer 3\n vp:name: (str) blue",
),
(
"pens rgb propdel -l all vp:color proplist -l 2",
"listing 1 properties for layer 2\n vp:name: (str) green",
),
(
"pens rgb propclear -l all proplist",
"listing 0 properties for layer 1\n"
"listing 0 properties for layer 2\n"
"listing 0 properties for layer 3\n",
),
(
"pagesize 400x1200 proplist -g",
"listing 1 global properties\n vp:page_size: (tuple) (400.0, 1200.0)",
),
(
"pagesize 400x1200 propdel -g vp:page_size proplist -g",
"listing 0 global properties",
),
("propset -g -t int prop 10 propget -g prop", "global property prop: (int) 10"),
(
"propset -g -t float prop 11.2 propget -g prop",
"global property prop: (float) 11.2",
),
("propset -g -t str prop hello propget -g prop", "global property prop: (str) hello"),
(
"propset -g -t color prop blue propget -g prop",
"global property prop: (color) #0000ff",
),
(
"pagesize a4 propset -g prop val propclear -g proplist -g",
"listing 0 global properties",
),
],
)
def test_property_commands(runner, cmd, expected_output):
res = runner.invoke(cli, cmd)
assert res.exit_code == 0
assert res.stdout.strip() == expected_output.strip()
4 changes: 2 additions & 2 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,11 @@ def test_line_collection_merge(lines, merge_lines):
assert _line_set(lc) == _line_set(merge_lines)


def test_document_empty_copy():
def test_document_clone():
doc = Document()
doc.add(LineCollection([(0, 1)]), 1)
doc.page_size = 3, 4

new_doc = doc.empty_copy()
new_doc = doc.clone()
assert len(new_doc.layers) == 0
assert new_doc.page_size == (3, 4)
8 changes: 4 additions & 4 deletions tests/test_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_viewer_engine_properties(assert_image_similarity):
def test_viewer(assert_image_similarity, file, render_kwargs):
# Note: this test relies on lack of metadata
doc = vp.read_multilayer_svg(str(TEST_FILE_DIRECTORY / file), 0.4)
doc.clear_metadata()
doc.clear_layer_metadata()

# noinspection PyArgumentList
assert_image_similarity(render_image(doc, (1024, 1024), **render_kwargs))
Expand All @@ -120,7 +120,7 @@ def test_viewer_empty_layer(assert_image_similarity, render_kwargs):
def test_viewer_zoom_scale(assert_image_similarity):
# Note: this test relies on lack of metadata
doc = vp.read_multilayer_svg(str(TEST_FILE_DIRECTORY / "issue_124/plotter.svg"), 0.4)
doc.clear_metadata()
doc.clear_layer_metadata()
renderer = ImageRenderer((1024, 1024))
renderer.engine.document = doc
renderer.engine.fit_to_viewport()
Expand All @@ -133,7 +133,7 @@ def test_viewer_zoom_scale(assert_image_similarity):
def test_viewer_scale_origin(assert_image_similarity):
# Note: this test relies on lack of metadata
doc = vp.read_multilayer_svg(str(TEST_FILE_DIRECTORY / "issue_124/plotter.svg"), 0.4)
doc.clear_metadata()
doc.clear_layer_metadata()

assert_image_similarity(
render_image(doc, view_mode=ViewMode.OUTLINE, origin=(600, 400), scale=4)
Expand All @@ -143,7 +143,7 @@ def test_viewer_scale_origin(assert_image_similarity):
def test_viewer_debug(assert_image_similarity):
# Note: this test relies on lack of metadata
doc = vp.read_multilayer_svg(str(TEST_FILE_DIRECTORY / "issue_124/plotter.svg"), 0.4)
doc.clear_metadata()
doc.clear_layer_metadata()
renderer = ImageRenderer((1024, 1024))
renderer.engine.document = doc
renderer.engine.origin = (600, 400)
Expand Down
9 changes: 8 additions & 1 deletion vpype/layers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from contextlib import contextmanager
from typing import List, Optional, Union

Expand Down Expand Up @@ -46,7 +47,13 @@ def multiple_to_layer_ids(
if layers is None or layers is LayerType.ALL:
return sorted(document.ids())
elif isinstance(layers, list):
return sorted(vid for vid in layers if document.exists(vid))
lids = []
for lid in sorted(layers):
if document.exists(lid):
lids.append(lid)
else:
logging.warning(f"layer {lid} does not exist")
return lids
else:
return []

Expand Down
10 changes: 10 additions & 0 deletions vpype/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,27 @@ def __init__(
object.__setattr__(self, "alpha", int(alpha or 255))

def as_floats(self) -> Tuple[float, float, float, float]:
"""Returns a float representation of the instance."""
return self.red / 255, self.green / 255, self.blue / 255, self.alpha / 255

def as_hex(self) -> str:
"""Return a standard, hexadecimal representation of the instance."""
return svgelements.Color(self.red, self.green, self.blue, self.alpha).hex


# layer metadata field names
METADATA_FIELD_NAME = "vp:name"
METADATA_FIELD_COLOR = "vp:color"
METADATA_FIELD_PEN_WIDTH = "vp:pen_width"

# global metadata field names
METADATA_FIELD_PAGE_SIZE = "vp:page_size"

METADATA_SYSTEM_FIELD_TYPES = {
METADATA_FIELD_NAME: str,
METADATA_FIELD_COLOR: Color,
METADATA_FIELD_PEN_WIDTH: float,
METADATA_FIELD_PAGE_SIZE: tuple,
}

# noinspection HttpUrlsUsage
Expand Down
Loading

0 comments on commit 7360235

Please sign in to comment.