@@ -463,6 +463,21 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta):
See also the BaseSpreadsheet base class for additional documentation about
methods you must and can define, the definition of RT and ST, etc.
"""
# Defined in the XSL spec, "Definitions of Units of Measure"
MEASUREMENT_UNITS = frozenset([
'cm',
'em',
'in',
'mm',
'pc',
'pt',
'px',
])
MEASUREMENT_RE = re.compile(
r'([-+]?(?:\d+\.?|\.\d+|\d+\.\d+))({})'.format('|'.join(MEASUREMENT_UNITS)),
re.ASCII,
)
def __init__(self, rt_wrapper: Optional[rtutil.RT]=None) -> None:
self.rt_wrapper = rt_wrapper
self.locale = babel.core.Locale.default('LC_MONETARY')
@@ -576,6 +591,29 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta):
### Styles
def column_style(self, width: Union[float, str], **attrs: Any) -> odf.style.Style:
if not isinstance(width, str) or (width and not width[-1].isalpha()):
width = f'{width}in'
match = self.MEASUREMENT_RE.fullmatch(width)
if match is None:
raise ValueError(f"invalid width {width!r}")
width_float = float(match.group(1))
if width_float <= 0:
# Per the OpenDocument spec, column-width is a positiveLength.
raise ValueError(f"width {width!r} must be positive")
width = '{:.3g}{}'.format(width_float, match.group(2))
retval = self.ensure_child(
self.document.automaticstyles,
odf.style.Style,
name=f'col_{width.replace(".", "_")}'
retval.setAttribute('family', 'table-column')
if retval.firstChild is None:
retval.addElement(odf.style.TableColumnProperties(
columnwidth=width, **attrs
))
return retval
def _build_currency_style(
self,
root: odf.element.Element,
@@ -875,20 +913,6 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta):
aligned_style.addElement(odf.style.ParagraphProperties(textalign=textalign))
setattr(self, f'style_{textalign}text', aligned_style)
self.style_col1: odf.style.Style
self.style_col1_25: odf.style.Style
self.style_col1_5: odf.style.Style
self.style_col1_75: odf.style.Style
self.style_col2: odf.style.Style
for width in ['1', '1.25', '1.5', '1.75', '2']:
width_name = width.replace('.', '_')
column_style = self.replace_child(
self.document.automaticstyles, odf.style.Style, name=f'col_{width_name}',
column_style.setAttribute('family', 'table-column')
column_style.addElement(odf.style.TableColumnProperties(columnwidth=f'{width}in'))
setattr(self, f'style_col{width_name}', column_style)
### Rows and cells
def add_row(self, *cells: odf.table.TableCell, **attrs: Any) -> odf.table.TableRow: