Add core Python agent with configuration management, environment setup, and deployment documentation. Includes user/agent profiles, startup scripts, and dependency management for the psagentia system.
137 lines
5.5 KiB
Python
Executable File
137 lines
5.5 KiB
Python
Executable File
"""Styles object, container for all objects in the styles part."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from warnings import warn
|
|
|
|
from docx.enum.style import WD_STYLE_TYPE
|
|
from docx.oxml.styles import CT_Styles
|
|
from docx.shared import ElementProxy
|
|
from docx.styles import BabelFish
|
|
from docx.styles.latent import LatentStyles
|
|
from docx.styles.style import BaseStyle, StyleFactory
|
|
|
|
|
|
class Styles(ElementProxy):
|
|
"""Provides access to the styles defined in a document.
|
|
|
|
Accessed using the :attr:`.Document.styles` property. Supports ``len()``, iteration,
|
|
and dictionary-style access by style name.
|
|
"""
|
|
|
|
def __init__(self, styles: CT_Styles):
|
|
super().__init__(styles)
|
|
self._element = styles
|
|
|
|
def __contains__(self, name):
|
|
"""Enables `in` operator on style name."""
|
|
internal_name = BabelFish.ui2internal(name)
|
|
return any(style.name_val == internal_name for style in self._element.style_lst)
|
|
|
|
def __getitem__(self, key: str):
|
|
"""Enables dictionary-style access by UI name.
|
|
|
|
Lookup by style id is deprecated, triggers a warning, and will be removed in a
|
|
near-future release.
|
|
"""
|
|
style_elm = self._element.get_by_name(BabelFish.ui2internal(key))
|
|
if style_elm is not None:
|
|
return StyleFactory(style_elm)
|
|
|
|
style_elm = self._element.get_by_id(key)
|
|
if style_elm is not None:
|
|
msg = "style lookup by style_id is deprecated. Use style name as key instead."
|
|
warn(msg, UserWarning, stacklevel=2)
|
|
return StyleFactory(style_elm)
|
|
|
|
raise KeyError("no style with name '%s'" % key)
|
|
|
|
def __iter__(self):
|
|
return (StyleFactory(style) for style in self._element.style_lst)
|
|
|
|
def __len__(self):
|
|
return len(self._element.style_lst)
|
|
|
|
def add_style(self, name, style_type, builtin=False):
|
|
"""Return a newly added style object of `style_type` and identified by `name`.
|
|
|
|
A builtin style can be defined by passing True for the optional `builtin`
|
|
argument.
|
|
"""
|
|
style_name = BabelFish.ui2internal(name)
|
|
if style_name in self:
|
|
raise ValueError("document already contains style '%s'" % name)
|
|
style = self._element.add_style_of_type(style_name, style_type, builtin)
|
|
return StyleFactory(style)
|
|
|
|
def default(self, style_type: WD_STYLE_TYPE):
|
|
"""Return the default style for `style_type` or |None| if no default is defined
|
|
for that type (not common)."""
|
|
style = self._element.default_for(style_type)
|
|
if style is None:
|
|
return None
|
|
return StyleFactory(style)
|
|
|
|
def get_by_id(self, style_id: str | None, style_type: WD_STYLE_TYPE):
|
|
"""Return the style of `style_type` matching `style_id`.
|
|
|
|
Returns the default for `style_type` if `style_id` is not found or is |None|, or
|
|
if the style having `style_id` is not of `style_type`.
|
|
"""
|
|
if style_id is None:
|
|
return self.default(style_type)
|
|
return self._get_by_id(style_id, style_type)
|
|
|
|
def get_style_id(self, style_or_name, style_type):
|
|
"""Return the id of the style corresponding to `style_or_name`, or |None| if
|
|
`style_or_name` is |None|.
|
|
|
|
If `style_or_name` is not a style object, the style is looked up using
|
|
`style_or_name` as a style name, raising |ValueError| if no style with that name
|
|
is defined. Raises |ValueError| if the target style is not of `style_type`.
|
|
"""
|
|
if style_or_name is None:
|
|
return None
|
|
elif isinstance(style_or_name, BaseStyle):
|
|
return self._get_style_id_from_style(style_or_name, style_type)
|
|
else:
|
|
return self._get_style_id_from_name(style_or_name, style_type)
|
|
|
|
@property
|
|
def latent_styles(self):
|
|
"""A |LatentStyles| object providing access to the default behaviors for latent
|
|
styles and the collection of |_LatentStyle| objects that define overrides of
|
|
those defaults for a particular named latent style."""
|
|
return LatentStyles(self._element.get_or_add_latentStyles())
|
|
|
|
def _get_by_id(self, style_id: str | None, style_type: WD_STYLE_TYPE):
|
|
"""Return the style of `style_type` matching `style_id`.
|
|
|
|
Returns the default for `style_type` if `style_id` is not found or if the style
|
|
having `style_id` is not of `style_type`.
|
|
"""
|
|
style = self._element.get_by_id(style_id) if style_id else None
|
|
if style is None or style.type != style_type:
|
|
return self.default(style_type)
|
|
return StyleFactory(style)
|
|
|
|
def _get_style_id_from_name(self, style_name: str, style_type: WD_STYLE_TYPE) -> str | None:
|
|
"""Return the id of the style of `style_type` corresponding to `style_name`.
|
|
|
|
Returns |None| if that style is the default style for `style_type`. Raises
|
|
|ValueError| if the named style is not found in the document or does not match
|
|
`style_type`.
|
|
"""
|
|
return self._get_style_id_from_style(self[style_name], style_type)
|
|
|
|
def _get_style_id_from_style(self, style: BaseStyle, style_type: WD_STYLE_TYPE) -> str | None:
|
|
"""Id of `style`, or |None| if it is the default style of `style_type`.
|
|
|
|
Raises |ValueError| if style is not of `style_type`.
|
|
"""
|
|
if style.type != style_type:
|
|
raise ValueError("assigned style is type %s, need type %s" % (style.type, style_type))
|
|
if style == self.default(style_type):
|
|
return None
|
|
return style.style_id
|