File: tabstops.py

package info (click to toggle)
python-docx 0.8.11%2Bdfsg1-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 6,640 kB
  • sloc: xml: 25,311; python: 21,911; makefile: 168
file content (143 lines) | stat: -rw-r--r-- 4,183 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# encoding: utf-8

"""
Tabstop-related proxy types.
"""

from __future__ import (
    absolute_import, division, print_function, unicode_literals
)

from ..shared import ElementProxy
from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER


class TabStops(ElementProxy):
    """
    A sequence of |TabStop| objects providing access to the tab stops of
    a paragraph or paragraph style. Supports iteration, indexed access, del,
    and len(). It is accesed using the :attr:`~.ParagraphFormat.tab_stops`
    property of ParagraphFormat; it is not intended to be constructed
    directly.
    """

    __slots__ = ('_pPr')

    def __init__(self, element):
        super(TabStops, self).__init__(element, None)
        self._pPr = element

    def __delitem__(self, idx):
        """
        Remove the tab at offset *idx* in this sequence.
        """
        tabs = self._pPr.tabs
        try:
            tabs.remove(tabs[idx])
        except (AttributeError, IndexError):
            raise IndexError('tab index out of range')

        if len(tabs) == 0:
            self._pPr.remove(tabs)

    def __getitem__(self, idx):
        """
        Enables list-style access by index.
        """
        tabs = self._pPr.tabs
        if tabs is None:
            raise IndexError('TabStops object is empty')
        tab = tabs.tab_lst[idx]
        return TabStop(tab)

    def __iter__(self):
        """
        Generate a TabStop object for each of the w:tab elements, in XML
        document order.
        """
        tabs = self._pPr.tabs
        if tabs is not None:
            for tab in tabs.tab_lst:
                yield TabStop(tab)

    def __len__(self):
        tabs = self._pPr.tabs
        if tabs is None:
            return 0
        return len(tabs.tab_lst)

    def add_tab_stop(self, position, alignment=WD_TAB_ALIGNMENT.LEFT,
                     leader=WD_TAB_LEADER.SPACES):
        """
        Add a new tab stop at *position*, a |Length| object specifying the
        location of the tab stop relative to the paragraph edge. A negative
        *position* value is valid and appears in hanging indentation. Tab
        alignment defaults to left, but may be specified by passing a member
        of the :ref:`WdTabAlignment` enumeration as *alignment*. An optional
        leader character can be specified by passing a member of the
        :ref:`WdTabLeader` enumeration as *leader*.
        """
        tabs = self._pPr.get_or_add_tabs()
        tab = tabs.insert_tab_in_order(position, alignment, leader)
        return TabStop(tab)

    def clear_all(self):
        """
        Remove all custom tab stops.
        """
        self._pPr._remove_tabs()


class TabStop(ElementProxy):
    """
    An individual tab stop applying to a paragraph or style. Accessed using
    list semantics on its containing |TabStops| object.
    """

    __slots__ = ('_tab')

    def __init__(self, element):
        super(TabStop, self).__init__(element, None)
        self._tab = element

    @property
    def alignment(self):
        """
        A member of :ref:`WdTabAlignment` specifying the alignment setting
        for this tab stop. Read/write.
        """
        return self._tab.val

    @alignment.setter
    def alignment(self, value):
        self._tab.val = value

    @property
    def leader(self):
        """
        A member of :ref:`WdTabLeader` specifying a repeating character used
        as a "leader", filling in the space spanned by this tab. Assigning
        |None| produces the same result as assigning `WD_TAB_LEADER.SPACES`.
        Read/write.
        """
        return self._tab.leader

    @leader.setter
    def leader(self, value):
        self._tab.leader = value

    @property
    def position(self):
        """
        A |Length| object representing the distance of this tab stop from the
        inside edge of the paragraph. May be positive or negative.
        Read/write.
        """
        return self._tab.pos

    @position.setter
    def position(self, value):
        tab = self._tab
        tabs = tab.getparent()
        self._tab = tabs.insert_tab_in_order(value, tab.val, tab.leader)
        tabs.remove(tab)