# encoding: utf-8 """ Custom element classes related to paragraph properties (CT_PPr). """ from ...enum.text import ( WD_ALIGN_PARAGRAPH, WD_LINE_SPACING, WD_TAB_ALIGNMENT, WD_TAB_LEADER ) from ...shared import Length from ..simpletypes import ST_SignedTwipsMeasure, ST_TwipsMeasure from ..xmlchemy import ( BaseOxmlElement, OneOrMore, OptionalAttribute, RequiredAttribute, ZeroOrOne ) class CT_Ind(BaseOxmlElement): """ ```` element, specifying paragraph indentation. """ left = OptionalAttribute('w:left', ST_SignedTwipsMeasure) right = OptionalAttribute('w:right', ST_SignedTwipsMeasure) firstLine = OptionalAttribute('w:firstLine', ST_TwipsMeasure) hanging = OptionalAttribute('w:hanging', ST_TwipsMeasure) class CT_Jc(BaseOxmlElement): """ ```` element, specifying paragraph justification. """ val = RequiredAttribute('w:val', WD_ALIGN_PARAGRAPH) class CT_PPr(BaseOxmlElement): """ ```` element, containing the properties for a paragraph. """ _tag_seq = ( 'w:pStyle', 'w:keepNext', 'w:keepLines', 'w:pageBreakBefore', 'w:framePr', 'w:widowControl', 'w:numPr', 'w:suppressLineNumbers', 'w:pBdr', 'w:shd', 'w:tabs', 'w:suppressAutoHyphens', 'w:kinsoku', 'w:wordWrap', 'w:overflowPunct', 'w:topLinePunct', 'w:autoSpaceDE', 'w:autoSpaceDN', 'w:bidi', 'w:adjustRightInd', 'w:snapToGrid', 'w:spacing', 'w:ind', 'w:contextualSpacing', 'w:mirrorIndents', 'w:suppressOverlap', 'w:jc', 'w:textDirection', 'w:textAlignment', 'w:textboxTightWrap', 'w:outlineLvl', 'w:divId', 'w:cnfStyle', 'w:rPr', 'w:sectPr', 'w:pPrChange' ) pStyle = ZeroOrOne('w:pStyle', successors=_tag_seq[1:]) keepNext = ZeroOrOne('w:keepNext', successors=_tag_seq[2:]) keepLines = ZeroOrOne('w:keepLines', successors=_tag_seq[3:]) pageBreakBefore = ZeroOrOne('w:pageBreakBefore', successors=_tag_seq[4:]) widowControl = ZeroOrOne('w:widowControl', successors=_tag_seq[6:]) numPr = ZeroOrOne('w:numPr', successors=_tag_seq[7:]) tabs = ZeroOrOne('w:tabs', successors=_tag_seq[11:]) spacing = ZeroOrOne('w:spacing', successors=_tag_seq[22:]) ind = ZeroOrOne('w:ind', successors=_tag_seq[23:]) jc = ZeroOrOne('w:jc', successors=_tag_seq[27:]) sectPr = ZeroOrOne('w:sectPr', successors=_tag_seq[35:]) del _tag_seq @property def first_line_indent(self): """ A |Length| value calculated from the values of `w:ind/@w:firstLine` and `w:ind/@w:hanging`. Returns |None| if the `w:ind` child is not present. """ ind = self.ind if ind is None: return None hanging = ind.hanging if hanging is not None: return Length(-hanging) firstLine = ind.firstLine if firstLine is None: return None return firstLine @first_line_indent.setter def first_line_indent(self, value): if self.ind is None and value is None: return ind = self.get_or_add_ind() ind.firstLine = ind.hanging = None if value is None: return elif value < 0: ind.hanging = -value else: ind.firstLine = value @property def ind_left(self): """ The value of `w:ind/@w:left` or |None| if not present. """ ind = self.ind if ind is None: return None return ind.left @ind_left.setter def ind_left(self, value): if value is None and self.ind is None: return ind = self.get_or_add_ind() ind.left = value @property def ind_right(self): """ The value of `w:ind/@w:right` or |None| if not present. """ ind = self.ind if ind is None: return None return ind.right @ind_right.setter def ind_right(self, value): if value is None and self.ind is None: return ind = self.get_or_add_ind() ind.right = value @property def jc_val(self): """ The value of the ```` child element or |None| if not present. """ jc = self.jc if jc is None: return None return jc.val @jc_val.setter def jc_val(self, value): if value is None: self._remove_jc() return self.get_or_add_jc().val = value @property def keepLines_val(self): """ The value of `keepLines/@val` or |None| if not present. """ keepLines = self.keepLines if keepLines is None: return None return keepLines.val @keepLines_val.setter def keepLines_val(self, value): if value is None: self._remove_keepLines() else: self.get_or_add_keepLines().val = value @property def keepNext_val(self): """ The value of `keepNext/@val` or |None| if not present. """ keepNext = self.keepNext if keepNext is None: return None return keepNext.val @keepNext_val.setter def keepNext_val(self, value): if value is None: self._remove_keepNext() else: self.get_or_add_keepNext().val = value @property def pageBreakBefore_val(self): """ The value of `pageBreakBefore/@val` or |None| if not present. """ pageBreakBefore = self.pageBreakBefore if pageBreakBefore is None: return None return pageBreakBefore.val @pageBreakBefore_val.setter def pageBreakBefore_val(self, value): if value is None: self._remove_pageBreakBefore() else: self.get_or_add_pageBreakBefore().val = value @property def spacing_after(self): """ The value of `w:spacing/@w:after` or |None| if not present. """ spacing = self.spacing if spacing is None: return None return spacing.after @spacing_after.setter def spacing_after(self, value): if value is None and self.spacing is None: return self.get_or_add_spacing().after = value @property def spacing_before(self): """ The value of `w:spacing/@w:before` or |None| if not present. """ spacing = self.spacing if spacing is None: return None return spacing.before @spacing_before.setter def spacing_before(self, value): if value is None and self.spacing is None: return self.get_or_add_spacing().before = value @property def spacing_line(self): """ The value of `w:spacing/@w:line` or |None| if not present. """ spacing = self.spacing if spacing is None: return None return spacing.line @spacing_line.setter def spacing_line(self, value): if value is None and self.spacing is None: return self.get_or_add_spacing().line = value @property def spacing_lineRule(self): """ The value of `w:spacing/@w:lineRule` as a member of the :ref:`WdLineSpacing` enumeration. Only the `MULTIPLE`, `EXACTLY`, and `AT_LEAST` members are used. It is the responsibility of the client to calculate the use of `SINGLE`, `DOUBLE`, and `MULTIPLE` based on the value of `w:spacing/@w:line` if that behavior is desired. """ spacing = self.spacing if spacing is None: return None lineRule = spacing.lineRule if lineRule is None and spacing.line is not None: return WD_LINE_SPACING.MULTIPLE return lineRule @spacing_lineRule.setter def spacing_lineRule(self, value): if value is None and self.spacing is None: return self.get_or_add_spacing().lineRule = value @property def style(self): """ String contained in child, or None if that element is not present. """ pStyle = self.pStyle if pStyle is None: return None return pStyle.val @style.setter def style(self, style): """ Set val attribute of child element to *style*, adding a new element if necessary. If *style* is |None|, remove the element if present. """ if style is None: self._remove_pStyle() return pStyle = self.get_or_add_pStyle() pStyle.val = style @property def widowControl_val(self): """ The value of `widowControl/@val` or |None| if not present. """ widowControl = self.widowControl if widowControl is None: return None return widowControl.val @widowControl_val.setter def widowControl_val(self, value): if value is None: self._remove_widowControl() else: self.get_or_add_widowControl().val = value class CT_Spacing(BaseOxmlElement): """ ```` element, specifying paragraph spacing attributes such as space before and line spacing. """ after = OptionalAttribute('w:after', ST_TwipsMeasure) before = OptionalAttribute('w:before', ST_TwipsMeasure) line = OptionalAttribute('w:line', ST_SignedTwipsMeasure) lineRule = OptionalAttribute('w:lineRule', WD_LINE_SPACING) class CT_TabStop(BaseOxmlElement): """ ```` element, representing an individual tab stop. """ val = RequiredAttribute('w:val', WD_TAB_ALIGNMENT) leader = OptionalAttribute( 'w:leader', WD_TAB_LEADER, default=WD_TAB_LEADER.SPACES ) pos = RequiredAttribute('w:pos', ST_SignedTwipsMeasure) class CT_TabStops(BaseOxmlElement): """ ```` element, container for a sorted sequence of tab stops. """ tab = OneOrMore('w:tab', successors=()) def insert_tab_in_order(self, pos, align, leader): """ Insert a newly created `w:tab` child element in *pos* order. """ new_tab = self._new_tab() new_tab.pos, new_tab.val, new_tab.leader = pos, align, leader for tab in self.tab_lst: if new_tab.pos < tab.pos: tab.addprevious(new_tab) return new_tab self.append(new_tab) return new_tab