Source code for fastpyxl.styles.alignment

# Copyright (c) 2010-2024 fastpyxl

from fastpyxl.compat import safe_string
from fastpyxl.typed_serialisable.base import Serialisable
from fastpyxl.typed_serialisable.errors import FieldValidationError
from fastpyxl.typed_serialisable.fields import AliasField, Field


horizontal_alignments = (
    "general", "left", "center", "right", "fill", "justify", "centerContinuous",
    "distributed", )
vertical_aligments = (
    "top", "center", "bottom", "justify", "distributed",
)


def _enum_converter(value, allowed_values, field_name: str):
    if value is None:
        return None
    if value not in allowed_values:
        raise FieldValidationError(f"{field_name} rejected value {value!r}")
    return value


def _text_rotation_converter(value):
    if value is None:
        return None
    try:
        numeric = int(value)
    except Exception as exc:  # pragma: no cover
        raise FieldValidationError(f"textRotation rejected value {value!r}") from exc
    if numeric not in range(181) and numeric != 255:
        raise FieldValidationError(f"textRotation rejected value {value!r}")
    return numeric


def _range_converter(value, *, field_name: str, min_value: float, max_value: float | None):
    if value is None:
        return None
    try:
        numeric = float(value)
    except Exception as exc:  # pragma: no cover
        raise FieldValidationError(f"{field_name} rejected value {value!r}") from exc
    if numeric < min_value:
        raise FieldValidationError(f"{field_name} rejected value {value!r}")
    if max_value is not None and numeric > max_value:
        raise FieldValidationError(f"{field_name} rejected value {value!r}")
    return numeric


[docs] class Alignment(Serialisable): """Alignment options for use in styles.""" tagname = "alignment" horizontal: str | None = Field.attribute( expected_type=str, allow_none=True, converter=lambda v: _enum_converter(v, horizontal_alignments, "horizontal"), default=None, ) vertical: str | None = Field.attribute( expected_type=str, allow_none=True, converter=lambda v: _enum_converter(v, vertical_aligments, "vertical"), default=None, ) textRotation: int | None = Field.attribute( expected_type=int, allow_none=True, converter=_text_rotation_converter, default=None, ) text_rotation: int | None = AliasField("textRotation", default=None) wrapText: bool | None = Field.attribute(expected_type=bool, allow_none=True, default=None) wrap_text: bool | None = AliasField("wrapText", default=None) shrinkToFit: bool | None = Field.attribute(expected_type=bool, allow_none=True, default=None) shrink_to_fit: bool | None = AliasField("shrinkToFit", default=None) indent: float | int | None = Field.attribute( expected_type=float, allow_none=True, converter=lambda v: _range_converter(v, field_name="indent", min_value=0, max_value=255), default=None, ) relativeIndent: float | int | None = Field.attribute( expected_type=float, allow_none=True, converter=lambda v: _range_converter(v, field_name="relativeIndent", min_value=-255, max_value=255), default=None, ) justifyLastLine: bool | None = Field.attribute(expected_type=bool, allow_none=True, default=None) readingOrder: float | int | None = Field.attribute( expected_type=float, allow_none=True, converter=lambda v: _range_converter(v, field_name="readingOrder", min_value=0, max_value=None), default=None, ) def __init__(self, horizontal=None, vertical=None, textRotation=0, wrapText=None, shrinkToFit=None, indent=0, relativeIndent=0, justifyLastLine=None, readingOrder=0, text_rotation=None, wrap_text=None, shrink_to_fit=None, mergeCell=None): self.horizontal = horizontal self.vertical = vertical self.indent = indent self.relativeIndent = relativeIndent self.justifyLastLine = justifyLastLine self.readingOrder = readingOrder if text_rotation is not None: textRotation = text_rotation if textRotation is not None: self.textRotation = int(textRotation) if wrap_text is not None: wrapText = wrap_text self.wrapText = wrapText if shrink_to_fit is not None: shrinkToFit = shrink_to_fit self.shrinkToFit = shrinkToFit # mergeCell is vestigial def __iter__(self): explicit_bool_attrs = ("wrapText", "shrinkToFit", "justifyLastLine") for attr in self.__attrs__: value = getattr(self, attr) if value is None: continue if attr in explicit_bool_attrs: yield attr, safe_string(value) elif value != 0: yield attr, safe_string(value)