|
| 1 | + |
| 2 | +Tab Stop Specification |
| 3 | +==================== |
| 4 | + |
| 5 | +WordprocessingML allows for custom specification of tab stops at the paragraph |
| 6 | +level. Tab stop spacing is a subset of paragraph formatting in this system, |
| 7 | +so will be implemented within the docx.text.parfmt.ParagraphFormatting object. |
| 8 | +Tab stops will be handled as a List-like TabStops object made up of TabStop |
| 9 | +objects. |
| 10 | + |
| 11 | +A TabStop object has three properties, alignment, leader, and position. |
| 12 | +Alignment is a WD_TAB_ALIGNMENT member and position is a Length() object. |
| 13 | + |
| 14 | +TabStops must be in position order within the XML. If they are not, the out- |
| 15 | +of-order tab stop will appear in the ruler and in the properties dialog, but |
| 16 | +will not actually be used by Word. |
| 17 | + |
| 18 | +Tab character insertion is already properly handled as part of Runs. This |
| 19 | +feature deals with the horizontal spacing of tabs within the document only. |
| 20 | + |
| 21 | + |
| 22 | +Protocol |
| 23 | +~~~~~~~~ |
| 24 | + |
| 25 | +.. highlight:: python |
| 26 | + |
| 27 | +Getting and setting tab stops:: |
| 28 | + |
| 29 | + >>> paragraph_format.tab_stops |
| 30 | + <docx.text.parfmt.TabStops object at 0x104ea8c30> |
| 31 | + >>> print paragraph_format.tab_stops |
| 32 | + [] |
| 33 | + >>> paragraph_format.tab_stops.append( |
| 34 | + TabStop(Inches(1), WD_TAB_ALIGNMENT.LEFT)) # 1 inch |
| 35 | + >>> paragraph_format.tab_stops.append( |
| 36 | + TabStop(Twips(2880))) # Defaults to Left, 2 inches |
| 37 | + >>> len(paragraph_format.tab_stops) |
| 38 | + 2 |
| 39 | + >>> paragraph_format.tab_stops.append( |
| 40 | + TabStop(Inches(4.5), WD_TAB_ALIGNMENT.DECIMAL)) # 4.5 inches |
| 41 | + >>> paragraph_format.tab_stops.append( |
| 42 | + TabStop(Inches(7), WD_TAB_ALIGNMENT.RIGHT)) # 7 inches |
| 43 | + >>> paragraph_format.tab_stops.append( |
| 44 | + TabStop(Mm(76.2))) # 3 inches |
| 45 | + >>> paragraph_format.tab_stops |
| 46 | + <docx.text.parfmt.TabStops object at 0x104ea8c30> |
| 47 | + >>> print paragraph_format.tab_stops |
| 48 | + [(1440, LEFT (0)), (2880, LEFT (0)), (4320, LEFT (0)), (6480, DECIMAL (3)), |
| 49 | + (10080, RIGHT (2))] |
| 50 | + >>> print paragraph_format.tab_stops[2] |
| 51 | + [(4320, LEFT (0))] |
| 52 | + >>> del(paragraph_format)[2]) |
| 53 | + >>> paragraph_format[1].position = Inches(2.5) |
| 54 | + >>> paragraph_format[1].alignment = WD_TAB_ALIGNMENT.RIGHT |
| 55 | + >>> for tab_stop in paragraph_format.tab_stops: |
| 56 | + >>> print tab_stop |
| 57 | + (1440, LEFT (0)) |
| 58 | + (3600, RIGHT (2)) |
| 59 | + (6480, DECIMAL (3)) |
| 60 | + (10080, RIGHT (2)) |
| 61 | + >>> paragraph_format.tabs.clear() # default tabs |
| 62 | + >>> paragraph_format.tab_stops |
| 63 | + <docx.text.parfmt.TabStops object at 0x104ea8c30> |
| 64 | + >>> print paragraph_format.tab_stops |
| 65 | + [] |
| 66 | + |
| 67 | + |
| 68 | +XML Semantics |
| 69 | +~~~~~~~~~~~~~ |
| 70 | + |
| 71 | +* Tab stops have a type (w:val), which allows the specification of left, |
| 72 | + center, right, decimal, bar, and list alignment. |
| 73 | + |
| 74 | +* The details of the list alignment are elusive. (I have not been able to |
| 75 | + create this type of tab stops in Word, even within lists. Perhaps a later |
| 76 | + version of Word than I use is required.) |
| 77 | + |
| 78 | +* Tab stop positions (w:pos) are stored in XML in twips. |
| 79 | + |
| 80 | +* Tab stops can have a "leader" (w:leader) character. I do not intent to |
| 81 | + implement support for leader characters at this time. |
| 82 | + |
| 83 | +Specimen XML |
| 84 | +~~~~~~~~~~~~ |
| 85 | + |
| 86 | +.. highlight:: xml |
| 87 | + |
| 88 | +:: |
| 89 | + |
| 90 | + <w:pPr> |
| 91 | + <w:tabs> |
| 92 | + <w:tab w:val="left" w:pos="1440"/> |
| 93 | + <w:tab w:val="left" w:leader="dot" w:pos="2880"/> |
| 94 | + <w:tab w:val="left" w:pos="4320"/> |
| 95 | + <w:tab w:val="decimal" w:pos="6480"/> |
| 96 | + <w:tab w:val="right" w:leader="underscore" w:pos="10080"/> |
| 97 | + </w:tabs> |
| 98 | + </w:pPr> |
| 99 | + |
| 100 | + |
| 101 | +Enumerations |
| 102 | +------------ |
| 103 | + |
| 104 | +* `WdTabAlignment Enumeration on MSDN`_ |
| 105 | + |
| 106 | +.. _WdTabAlignment Enumeration on MSDN: |
| 107 | + https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx |
| 108 | + |
| 109 | +* `WdTabLeader Enumeration on MSDN`_ |
| 110 | + |
| 111 | +.. _WdTabLeader Enumeration on MSDN: |
| 112 | + https://msdn.microsoft.com/en-us/library/office/ff845050.aspx |
| 113 | + |
| 114 | + |
| 115 | +MS API Protocol |
| 116 | +~~~~~~~~~~~~~~~ |
| 117 | +The MS API defines a `TabStops object`_ which is made up of `TabStop objects`_. |
| 118 | + |
| 119 | +.. _TabStops object: |
| 120 | + https://msdn.microsoft.com/EN-US/library/office/ff192806.aspx |
| 121 | + |
| 122 | +.. _TabStop objects: |
| 123 | + https://msdn.microsoft.com/EN-US/library/office/ff195736.aspx |
| 124 | + |
| 125 | +Schema excerpt |
| 126 | +-------------- |
| 127 | + |
| 128 | +:: |
| 129 | + |
| 130 | + <xsd:complexType name="CT_PPr"> <!-- denormalized --> |
| 131 | + <xsd:sequence> |
| 132 | + <xsd:element name="pStyle" type="CT_String" |
| 133 | + minOccurs="0"/> |
| 134 | + <xsd:element name="keepNext" type="CT_OnOff" |
| 135 | + minOccurs="0"/> |
| 136 | + <xsd:element name="keepLines" type="CT_OnOff" |
| 137 | + minOccurs="0"/> |
| 138 | + <xsd:element name="pageBreakBefore" type="CT_OnOff" |
| 139 | + minOccurs="0"/> |
| 140 | + <xsd:element name="framePr" type="CT_FramePr" |
| 141 | + minOccurs="0"/> |
| 142 | + <xsd:element name="widowControl" type="CT_OnOff" |
| 143 | + minOccurs="0"/> |
| 144 | + <xsd:element name="numPr" type="CT_NumPr" |
| 145 | + minOccurs="0"/> |
| 146 | + <xsd:element name="suppressLineNumbers" type="CT_OnOff" |
| 147 | + minOccurs="0"/> |
| 148 | + <xsd:element name="pBdr" type="CT_PBdr" |
| 149 | + minOccurs="0"/> |
| 150 | + <xsd:element name="shd" type="CT_Shd" |
| 151 | + minOccurs="0"/> |
| 152 | + <xsd:element name="tabs" type="CT_Tabs" |
| 153 | + minOccurs="0"/> |
| 154 | + <xsd:element name="suppressAutoHyphens" type="CT_OnOff" |
| 155 | + minOccurs="0"/> |
| 156 | + <xsd:element name="kinsoku" type="CT_OnOff" |
| 157 | + minOccurs="0"/> |
| 158 | + <xsd:element name="wordWrap" type="CT_OnOff" |
| 159 | + minOccurs="0"/> |
| 160 | + <xsd:element name="overflowPunct" type="CT_OnOff" |
| 161 | + minOccurs="0"/> |
| 162 | + <xsd:element name="topLinePunct" type="CT_OnOff" |
| 163 | + minOccurs="0"/> |
| 164 | + <xsd:element name="autoSpaceDE" type="CT_OnOff" |
| 165 | + minOccurs="0"/> |
| 166 | + <xsd:element name="autoSpaceDN" type="CT_OnOff" |
| 167 | + minOccurs="0"/> |
| 168 | + <xsd:element name="bidi" type="CT_OnOff" |
| 169 | + minOccurs="0"/> |
| 170 | + <xsd:element name="adjustRightInd" type="CT_OnOff" |
| 171 | + minOccurs="0"/> |
| 172 | + <xsd:element name="snapToGrid" type="CT_OnOff" |
| 173 | + minOccurs="0"/> |
| 174 | + <xsd:element name="spacing" type="CT_Spacing" |
| 175 | + minOccurs="0"/> |
| 176 | + <xsd:element name="ind" type="CT_Ind" |
| 177 | + minOccurs="0"/> |
| 178 | + <xsd:element name="contextualSpacing" type="CT_OnOff" |
| 179 | + minOccurs="0"/> |
| 180 | + <xsd:element name="mirrorIndents" type="CT_OnOff" |
| 181 | + minOccurs="0"/> |
| 182 | + <xsd:element name="suppressOverlap" type="CT_OnOff" |
| 183 | + minOccurs="0"/> |
| 184 | + <xsd:element name="jc" type="CT_Jc" |
| 185 | + minOccurs="0"/> |
| 186 | + <xsd:element name="textDirection" type="CT_TextDirection" |
| 187 | + minOccurs="0"/> |
| 188 | + <xsd:element name="textAlignment" type="CT_TextAlignment" |
| 189 | + minOccurs="0"/> |
| 190 | + <xsd:element name="textboxTightWrap" type="CT_TextboxTightWrap" |
| 191 | + minOccurs="0"/> |
| 192 | + <xsd:element name="outlineLvl" type="CT_DecimalNumber" |
| 193 | + minOccurs="0"/> |
| 194 | + <xsd:element name="divId" type="CT_DecimalNumber" |
| 195 | + minOccurs="0"/> |
| 196 | + <xsd:element name="cnfStyle" type="CT_Cnf" |
| 197 | + minOccurs="0"/> |
| 198 | + <xsd:element name="rPr" type="CT_ParaRPr" |
| 199 | + minOccurs="0"/> |
| 200 | + <xsd:element name="sectPr" type="CT_SectPr" |
| 201 | + minOccurs="0"/> |
| 202 | + <xsd:element name="pPrChange" type="CT_PPrChange" |
| 203 | + minOccurs="0"/> |
| 204 | + </xsd:sequence> |
| 205 | + </xsd:complexType> |
| 206 | + |
| 207 | + |
| 208 | + <xsd:complexType name="CT_Tabs"> |
| 209 | + <xsd:sequence> |
| 210 | + <xsd:element name="tab" type="CT_TabStop" maxOccurs="unbounded"/> |
| 211 | + </xsd:sequence> |
| 212 | + </xsd:complexType> |
| 213 | + |
| 214 | + <xsd:complexType name="CT_TabStop"> |
| 215 | + <xsd:sequence> |
| 216 | + <xsd:element name="val" type="ST_TabType" use="required"> |
| 217 | + <xsd:element name="leader" type="ST_TabTic"> |
| 218 | + <xsd:element name="pos" type="ST_SignedTwipsMeasure" use="required"> |
| 219 | + </xsd:sequence> |
| 220 | + </xsd:complexType> |
| 221 | + |
| 222 | + <!-- simple types --> |
| 223 | + <xsd:simpleType name="ST_TabType"> |
| 224 | + <xsd:restriction base="xsd:string"> |
| 225 | + <xsd:enumeration value="bar"> <!-- wdAlignTabBar 4 --> |
| 226 | + <xsd:enumeration value="center"> <!-- wdAlignTabCenter 1 --> |
| 227 | + <xsd:enumeration value="decimal"> <!-- wdAlignTabDecimal 3 --> |
| 228 | + <xsd:enumeration value="left"> <!-- wdAlignTabLeft 0 --> |
| 229 | + <xsd:enumeration value="list"> <!-- wdAlignTabList 6 --> |
| 230 | + <xsd:enumeration value="right"> <!-- wdAlignTabRight 2 --> |
| 231 | + </xsd:restriction> |
| 232 | + </xsd:simpleType> |
| 233 | + |
| 234 | + <xsd:simpleType name="St_TabTic"> |
| 235 | + <xsd:restriction base="xsd:string"> |
| 236 | + <xsd:enumeration value="hyphen"> <!-- wdTabLeaderDashes 2 --> |
| 237 | + <xsd:enumeration value="dot"> <!-- wdTabLeaderDots 1 --> |
| 238 | + <xsd:enumeration value="??"> <!-- wdTabLeaderHeavy 4 --> |
| 239 | + <xsd:enumeration value="underscore"> <!-- wdTabLeaderLines 3 --> |
| 240 | + <xsd:enumeration value="??"> <!-- wdTabLeaderMidleDot 5 --> |
| 241 | + <xsd:enumeration value=""> <!-- wdTabLeaderSpaces 0 --> |
| 242 | + </xsd:restriction> |
| 243 | + </xsd:simpleType> |
0 commit comments