Skip to content

Commit

Permalink
Add --orientation option to pagerotate command (#705)
Browse files Browse the repository at this point in the history
* Added '--orientation' option to pagerotate command, to allow conditionally rotating a page to a target orientation.

* Added warning message to pagerotate if not rotating due to page orientation target.

* - Swapped `click.Choice` for `ChoiceType` for `--orientation` option of `pagerotate` command, per @abey79
- Added new tests for `pagerotate --orientation`
- Updated CHANGELOG.md

* Add sanity checks to pagerotate for orientation option.

---------

Co-authored-by: Antoine Beyeler <[email protected]>
  • Loading branch information
gatesphere and abey79 authored Apr 5, 2024
1 parent 1df9e63 commit 9c9de12
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Release date: UNRELEASED

### New features and improvements

* ...
* Added a `--orientation` option to the `pagerotate` command to conditionally rotate the page to a target orientation (thanks to @gatesphere) (#705)

### Bug fixes

Expand Down
22 changes: 22 additions & 0 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,28 @@ def test_pagerotate_error(caplog):
assert "page size is not defined, page not rotated" in caplog.text


def test_pagerotate_orientation():
doc = vpype_cli.execute("random pagesize a4 pagerotate -o landscape")
assert doc.page_size == pytest.approx((1122.5196850393702, 793.7007874015749))

doc = vpype_cli.execute("random pagesize a4 pagerotate -cw -o landscape")
assert doc.page_size == pytest.approx((1122.5196850393702, 793.7007874015749))

doc = vpype_cli.execute("random pagesize --landscape a4 pagerotate -o portrait")
assert doc.page_size == pytest.approx((793.7007874015749, 1122.5196850393702))

doc = vpype_cli.execute("random pagesize --landscape a4 pagerotate -cw -o portrait")
assert doc.page_size == pytest.approx((793.7007874015749, 1122.5196850393702))


def test_pagerotate_orientation_error():
doc = vpype_cli.execute("random pagesize a4 pagerotate -o portrait")
assert doc.page_size == pytest.approx((793.7007874015749, 1122.5196850393702))

doc = vpype_cli.execute("random pagesize --landscape a4 pagerotate -o landscape")
assert doc.page_size == pytest.approx((1122.5196850393702, 793.7007874015749))


def test_help(runner):
res = runner.invoke(cli, "--help")

Expand Down
34 changes: 31 additions & 3 deletions vpype_cli/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@

from .cli import cli
from .decorators import global_processor, layer_processor
from .types import IntegerType, LayerType, LengthType, PageSizeType, multiple_to_layer_ids
from .types import (
ChoiceType,
IntegerType,
LayerType,
LengthType,
PageSizeType,
multiple_to_layer_ids,
)

__all__ = (
"crop",
Expand Down Expand Up @@ -662,12 +669,20 @@ def layout(
is_flag=True,
help="Rotate clockwise instead of the default counter-clockwise",
)
@click.option(
"--orientation",
"-o",
type=ChoiceType(["portrait", "landscape"]),
help="Conditionally rotate only if the final orientation matches this option",
)
@global_processor
def pagerotate(document: vp.Document, clockwise: bool):
def pagerotate(document: vp.Document, clockwise: bool, orientation: str | None):
"""Rotate the page by 90 degrees.
This command rotates the page by 90 degrees counter-clockwise. If the `--clockwise` option
is passed, it rotates the page clockwise instead.
is passed, it rotates the page clockwise instead. If the `--orientation` option is given
a value of either 'portrait' or 'landscape', the page will only be rotated if the final
orientation would match that choice.
Note: if the page size is not defined, an error is printed and the page is not rotated.
"""
Expand All @@ -677,6 +692,19 @@ def pagerotate(document: vp.Document, clockwise: bool):
return document
w, h = page_size

# sanity checks
if orientation is not None and orientation not in ["portrait", "landscape"]:
logging.warning(
f"pagerotate: orientation value '{orientation}' not one of 'portrait', 'landscape'"
)
return document

# check orientation constraint, and do nothing if target orientation
# won't match desired result
if (orientation == "portrait" and h > w) or (orientation == "landscape" and w > h):
logging.debug("pagerotate: page already in target orientation, page not rotated")
return document

if clockwise:
document.rotate(math.pi / 2)
document.translate(h, 0)
Expand Down

0 comments on commit 9c9de12

Please sign in to comment.