Source code for neoscore.core.paper

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Optional

from neoscore.core.units import ZERO, Inch, Mm, Unit


[docs]@dataclass(frozen=True) class Paper: """A specification for a paper geometry used to lay out pages""" width: Unit height: Unit margin_top: Unit = field(default_factory=lambda: ZERO) margin_right: Unit = field(default_factory=lambda: ZERO) margin_bottom: Unit = field(default_factory=lambda: ZERO) margin_left: Unit = field(default_factory=lambda: ZERO) gutter: Unit = field(default_factory=lambda: ZERO) live_width: Unit = field(init=False) live_height: Unit = field(init=False) def __post_init__(self): # This hack is needed to assign derived fields on frozen dataclasses # See https://stackoverflow.com/a/54119384/5615927 super().__setattr__( "live_width", self.width - self.gutter - self.margin_left - self.margin_right, ) super().__setattr__( "live_height", self.height - self.margin_bottom - self.margin_top )
[docs] def make_rotation(self) -> Paper: """Create a 90-degree clockwise rotation of this paper. The ``gutter`` field is left unchanged. """ return Paper( self.height, self.width, self.margin_left, self.margin_top, self.margin_right, self.margin_bottom, self.gutter, )
[docs] def modified( self, width: Optional[Unit] = None, height: Optional[Unit] = None, margin_top: Optional[Unit] = None, margin_right: Optional[Unit] = None, margin_bottom: Optional[Unit] = None, margin_left: Optional[Unit] = None, gutter: Optional[Unit] = None, ) -> Paper: """Derive a new ``Paper`` from this one with any given changed attributes.""" return Paper( width if width is not None else self.width, height if height is not None else self.height, margin_top if margin_top is not None else self.margin_top, margin_right if margin_right is not None else self.margin_right, margin_bottom if margin_bottom is not None else self.margin_bottom, margin_left if margin_left is not None else self.margin_left, gutter if gutter is not None else self.gutter, )
# Templates for common paper types are declared below A4 = Paper(Mm(210), Mm(297), Mm(20), Mm(20), Mm(20), Mm(20), ZERO) """Template for A4-sized portrait paper""" LETTER = Paper(Inch(8.5), Inch(11), Inch(1), Inch(1), Inch(1), Inch(1), ZERO) """Template for letter-sized portrait paper"""