From 340f67e538f27ac27bdeb3c1d831f0fbe2fca4af Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:02:02 -0400
Subject: [PATCH 01/20] refs #203: Made it possible to pass along dotted string
path to tag. This will prevent quite a few circular imports.
---
pydocx/models.py | 17 ++++++++++++++++-
pydocx/openxml/wordprocessing/deleted_run.py | 3 +--
pydocx/openxml/wordprocessing/inserted_run.py | 3 +--
pydocx/openxml/wordprocessing/smart_tag_run.py | 3 +--
pydocx/openxml/wordprocessing/table.py | 5 -----
pydocx/openxml/wordprocessing/table_cell.py | 2 +-
6 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/pydocx/models.py b/pydocx/models.py
index e8e70545..f75e26bd 100644
--- a/pydocx/models.py
+++ b/pydocx/models.py
@@ -5,6 +5,7 @@
unicode_literals,
)
+import importlib
import inspect
from collections import defaultdict
@@ -120,9 +121,23 @@ class ParkingLot(XmlModel):
def __init__(self, *types, **kwargs):
default = kwargs.pop('default', [])
super(XmlCollection, self).__init__(self, default=default)
- self.types = set(types)
+ self._types = types
self._name_to_type_map = None
+ @property
+ def types(self):
+ return set(self._set_types(*self._types))
+
+ def _set_types(self, *types):
+ base_path = 'pydocx.openxml.{}'
+ for _type in types:
+ if isinstance(_type, basestring):
+ path, klass, = _type.rsplit('.', 1)
+ module = importlib.import_module(base_path.format(path))
+ yield getattr(module, klass)
+ else:
+ yield _type
+
@property
def name_to_type_map(self):
if self._name_to_type_map is None:
diff --git a/pydocx/openxml/wordprocessing/deleted_run.py b/pydocx/openxml/wordprocessing/deleted_run.py
index dedf6917..3d55ff69 100644
--- a/pydocx/openxml/wordprocessing/deleted_run.py
+++ b/pydocx/openxml/wordprocessing/deleted_run.py
@@ -16,7 +16,6 @@ class DeletedRun(XmlModel):
children = XmlCollection(
Run,
SmartTagRun,
+ 'wordprocessing.DeletedRun',
# TODO Needs InsertedRun
)
-
-DeletedRun.children.types.add(DeletedRun)
diff --git a/pydocx/openxml/wordprocessing/inserted_run.py b/pydocx/openxml/wordprocessing/inserted_run.py
index cc19ec72..7fc0255c 100644
--- a/pydocx/openxml/wordprocessing/inserted_run.py
+++ b/pydocx/openxml/wordprocessing/inserted_run.py
@@ -16,7 +16,6 @@ class InsertedRun(XmlModel):
children = XmlCollection(
Run,
SmartTagRun,
+ 'wordprocessing.InsertedRun',
# TODO Needs DeletedRun
)
-
-InsertedRun.children.types.add(InsertedRun)
diff --git a/pydocx/openxml/wordprocessing/smart_tag_run.py b/pydocx/openxml/wordprocessing/smart_tag_run.py
index e56fd0fe..dfa906f9 100644
--- a/pydocx/openxml/wordprocessing/smart_tag_run.py
+++ b/pydocx/openxml/wordprocessing/smart_tag_run.py
@@ -14,6 +14,5 @@ class SmartTagRun(XmlModel):
children = XmlCollection(
Run,
+ 'wordprocessing.SmartTagRun',
)
-
-SmartTagRun.children.types.add(SmartTagRun)
diff --git a/pydocx/openxml/wordprocessing/table.py b/pydocx/openxml/wordprocessing/table.py
index 2fc85907..61314b29 100644
--- a/pydocx/openxml/wordprocessing/table.py
+++ b/pydocx/openxml/wordprocessing/table.py
@@ -8,7 +8,6 @@
from collections import defaultdict
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.wordprocessing.table_cell import TableCell
from pydocx.openxml.wordprocessing.table_row import TableRow
@@ -46,7 +45,3 @@ def calculate_table_cell_spans(self):
if active_rowspan_for_column:
cell_to_rowspan_count[active_rowspan_for_column] += 1 # noqa
return dict(cell_to_rowspan_count)
-
-
-# Python makes defining nested class hierarchies at the global level difficult
-TableCell.children.types.add(Table)
diff --git a/pydocx/openxml/wordprocessing/table_cell.py b/pydocx/openxml/wordprocessing/table_cell.py
index 7df2dc31..8a538e86 100644
--- a/pydocx/openxml/wordprocessing/table_cell.py
+++ b/pydocx/openxml/wordprocessing/table_cell.py
@@ -17,5 +17,5 @@ class TableCell(XmlModel):
children = XmlCollection(
Paragraph,
- # Table is added in wordprocessing.table
+ 'wordprocessing.Table',
)
From d0b2cb62ce7a621db4711d9e0ad8445beafb5204 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:03:37 -0400
Subject: [PATCH 02/20] refs #203: Added new test files.
---
tests/fixtures/textbox.docx | Bin 0 -> 4710 bytes
tests/fixtures/textbox.html | 4 ++++
2 files changed, 4 insertions(+)
create mode 100644 tests/fixtures/textbox.docx
create mode 100644 tests/fixtures/textbox.html
diff --git a/tests/fixtures/textbox.docx b/tests/fixtures/textbox.docx
new file mode 100644
index 0000000000000000000000000000000000000000..5ad956b2345ccc5c584ff4a406ae364ab2c4fc43
GIT binary patch
literal 4710
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
a&+vb;4ho?py&C|4nsh0WXv^|*$^QdHSLKcX
literal 0
HcmV?d00001
diff --git a/tests/fixtures/textbox.html b/tests/fixtures/textbox.html
new file mode 100644
index 00000000..e834424b
--- /dev/null
+++ b/tests/fixtures/textbox.html
@@ -0,0 +1,4 @@
+AAA
+BBB
+CCC
+DDD
From 368e957aa9ca60c388162b973e73d054ee99823b Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:04:13 -0400
Subject: [PATCH 03/20] refs #203: Alphabetize all the things.
---
tests/export/test_docx.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tests/export/test_docx.py b/tests/export/test_docx.py
index a1a96895..9afc1a4a 100644
--- a/tests/export/test_docx.py
+++ b/tests/export/test_docx.py
@@ -24,16 +24,15 @@ def convert(path, *args, **kwargs):
class ConvertDocxToHtmlTestCase(DocXFixtureTestCaseFactory):
cases = (
- 'read_same_image_multiple_times',
'all_configured_styles',
+ 'export_from_googledocs',
+ 'external_image',
+ 'has_missing_image',
+ 'has_missing_image',
'has_title',
'inline_tags',
- 'has_missing_image',
'justification',
'list_in_table',
- 'external_image',
- 'export_from_googledocs',
- 'has_missing_image',
'lists_with_styles',
'missing_numbering',
'missing_style',
@@ -41,6 +40,8 @@ class ConvertDocxToHtmlTestCase(DocXFixtureTestCaseFactory):
'nested_table_rowspan',
'nested_tables',
'no_break_hyphen',
+ 'read_same_image_multiple_times',
+ 'rotate_image',
'shift_enter',
'simple',
'simple_lists',
@@ -48,10 +49,9 @@ class ConvertDocxToHtmlTestCase(DocXFixtureTestCaseFactory):
'special_chars',
'styled_bolding',
'table_col_row_span',
+ 'table_with_multi_rowspan',
'tables_in_lists',
'track_changes_on',
- 'table_with_multi_rowspan',
- 'rotate_image'
)
@raises(MalformedDocxException)
From 60156807ca12f22a6744ab39f4d56477b0f9918e Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:04:32 -0400
Subject: [PATCH 04/20] refs #203: Added the new test to the runner.
---
tests/export/test_docx.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/export/test_docx.py b/tests/export/test_docx.py
index 9afc1a4a..977a6e82 100644
--- a/tests/export/test_docx.py
+++ b/tests/export/test_docx.py
@@ -51,6 +51,7 @@ class ConvertDocxToHtmlTestCase(DocXFixtureTestCaseFactory):
'table_col_row_span',
'table_with_multi_rowspan',
'tables_in_lists',
+ 'textbox',
'track_changes_on',
)
From 47b0a2e4451acbddd173f27846f6e8e19b5fab90 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:05:19 -0400
Subject: [PATCH 05/20] refs #203: Added the new tags needed to deal with
textboxes
---
.../openxml/markup_compatibility/__init__.py | 7 ++++++
.../markup_compatibility/alternate_content.py | 14 +++++++++++
.../openxml/markup_compatibility/fallback.py | 14 +++++++++++
pydocx/openxml/vml/shape.py | 3 ++-
pydocx/openxml/wordprocessing/__init__.py | 2 ++
pydocx/openxml/wordprocessing/run.py | 2 ++
pydocx/openxml/wordprocessing/textbox.py | 24 +++++++++++++++++++
7 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 pydocx/openxml/markup_compatibility/__init__.py
create mode 100644 pydocx/openxml/markup_compatibility/alternate_content.py
create mode 100644 pydocx/openxml/markup_compatibility/fallback.py
create mode 100644 pydocx/openxml/wordprocessing/textbox.py
diff --git a/pydocx/openxml/markup_compatibility/__init__.py b/pydocx/openxml/markup_compatibility/__init__.py
new file mode 100644
index 00000000..14f8fbbe
--- /dev/null
+++ b/pydocx/openxml/markup_compatibility/__init__.py
@@ -0,0 +1,7 @@
+from pydocx.openxml.markup_compatibility.alternate_content import AlternateContent
+from pydocx.openxml.markup_compatibility.fallback import Fallback
+
+__all__ = [
+ 'AlternateContent',
+ 'Fallback',
+]
diff --git a/pydocx/openxml/markup_compatibility/alternate_content.py b/pydocx/openxml/markup_compatibility/alternate_content.py
new file mode 100644
index 00000000..78fb8b4e
--- /dev/null
+++ b/pydocx/openxml/markup_compatibility/alternate_content.py
@@ -0,0 +1,14 @@
+# coding: utf-8
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+)
+
+from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.markup_compatibility.fallback import Fallback
+
+
+class AlternateContent(XmlModel):
+ XML_TAG = 'AlternateContent'
+ children = XmlCollection(Fallback)
diff --git a/pydocx/openxml/markup_compatibility/fallback.py b/pydocx/openxml/markup_compatibility/fallback.py
new file mode 100644
index 00000000..b281576a
--- /dev/null
+++ b/pydocx/openxml/markup_compatibility/fallback.py
@@ -0,0 +1,14 @@
+# coding: utf-8
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+)
+
+from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.wordprocessing.picture import Picture
+
+
+class Fallback(XmlModel):
+ XML_TAG = 'Fallback'
+ children = XmlCollection(Picture)
diff --git a/pydocx/openxml/vml/shape.py b/pydocx/openxml/vml/shape.py
index 457b6c67..8fdd83f6 100644
--- a/pydocx/openxml/vml/shape.py
+++ b/pydocx/openxml/vml/shape.py
@@ -7,13 +7,14 @@
from pydocx.models import XmlModel, XmlCollection, XmlAttribute
from pydocx.openxml.vml.image_data import ImageData
+from pydocx.openxml.wordprocessing.textbox import Textbox
class Shape(XmlModel):
XML_TAG = 'shape'
style = XmlAttribute()
- children = XmlCollection(ImageData)
+ children = XmlCollection(ImageData, Textbox)
# TODO perhaps we could have a prepare_style, or clean_style convention?
diff --git a/pydocx/openxml/wordprocessing/__init__.py b/pydocx/openxml/wordprocessing/__init__.py
index 916f2cf8..bab1673d 100644
--- a/pydocx/openxml/wordprocessing/__init__.py
+++ b/pydocx/openxml/wordprocessing/__init__.py
@@ -40,6 +40,7 @@
from pydocx.openxml.wordprocessing.table_cell_properties import TableCellProperties # noqa
from pydocx.openxml.wordprocessing.table_row import TableRow
from pydocx.openxml.wordprocessing.text import Text
+from pydocx.openxml.wordprocessing.textbox import Textbox
__all__ = [
'AbstractNum',
@@ -79,6 +80,7 @@
'Styles',
'TabChar',
'Table',
+ 'Textbox',
'TableCell',
'TableRow',
'Text',
diff --git a/pydocx/openxml/wordprocessing/run.py b/pydocx/openxml/wordprocessing/run.py
index fcd9f6f0..2acdb944 100644
--- a/pydocx/openxml/wordprocessing/run.py
+++ b/pydocx/openxml/wordprocessing/run.py
@@ -20,6 +20,7 @@
from pydocx.openxml.wordprocessing.footnote_reference import FootnoteReference
from pydocx.openxml.wordprocessing.footnote_reference_mark import FootnoteReferenceMark
from pydocx.openxml.wordprocessing.embedded_object import EmbeddedObject
+from pydocx.openxml.markup_compatibility import AlternateContent
from pydocx.util.memoize import memoized
@@ -41,6 +42,7 @@ class Run(XmlModel):
FootnoteReferenceMark,
FieldChar,
FieldCode,
+ AlternateContent,
)
def get_style_chain_stack(self):
diff --git a/pydocx/openxml/wordprocessing/textbox.py b/pydocx/openxml/wordprocessing/textbox.py
new file mode 100644
index 00000000..c959e103
--- /dev/null
+++ b/pydocx/openxml/wordprocessing/textbox.py
@@ -0,0 +1,24 @@
+# coding: utf-8
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+)
+
+from pydocx.models import XmlModel, XmlCollection
+# from pydocx.openxml.wordprocessing import Paragraph
+
+
+class TxBxContent(XmlModel):
+ XML_TAG = 'txbxContent'
+ children = XmlCollection(
+ 'wordprocessing.Paragraph',
+ )
+
+
+class Textbox(XmlModel):
+ XML_TAG = 'textbox'
+
+ children = XmlCollection(
+ TxBxContent,
+ )
From d2b373cd6d720c8e65cf35bb2f5ef083ee99889e Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:20:07 -0400
Subject: [PATCH 06/20] refs #203: "Fixed" the test. I am getting nested
paragraphs, so I'll need to figure that out.
---
pydocx/export/base.py | 19 ++++++++++++++++++-
pydocx/openxml/wordprocessing/__init__.py | 5 +++--
pydocx/openxml/wordprocessing/textbox.py | 1 -
tests/fixtures/textbox.html | 5 +++--
4 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/pydocx/export/base.py b/pydocx/export/base.py
index 7d364c70..b0456153 100644
--- a/pydocx/export/base.py
+++ b/pydocx/export/base.py
@@ -15,7 +15,7 @@
NumberingSpan,
NumberingSpanBuilder,
)
-from pydocx.openxml import wordprocessing, vml
+from pydocx.openxml import wordprocessing, vml, markup_compatibility
from pydocx.openxml.packaging import WordprocessingDocument
@@ -67,6 +67,10 @@ def __init__(self, path):
wordprocessing.EmbeddedObject: self.export_embedded_object,
NumberingSpan: self.export_numbering_span,
NumberingItem: self.export_numbering_item,
+ markup_compatibility.AlternateContent: self.export_alternate_content,
+ markup_compatibility.Fallback: self.export_fallback,
+ wordprocessing.Textbox: self.export_textbox,
+ wordprocessing.TxBxContent: self.export_textbox_content,
}
self.field_type_to_export_func_map = {
'HYPERLINK': getattr(self, 'export_field_hyperlink', None),
@@ -531,3 +535,16 @@ def export_field_char(self, field_char):
def export_field_code(self, field_code):
pass
+
+ def export_textbox(self, textbox):
+ return self.yield_nested(textbox.children, self.export_node)
+
+ def export_textbox_content(self, textbox_content):
+ return self.yield_nested(textbox_content.children, self.export_node)
+
+ # Markup Compatibility exporters
+ def export_alternate_content(self, alternate_content):
+ return self.yield_nested(alternate_content.children, self.export_node)
+
+ def export_fallback(self, fallback):
+ return self.yield_nested(fallback.children, self.export_node)
diff --git a/pydocx/openxml/wordprocessing/__init__.py b/pydocx/openxml/wordprocessing/__init__.py
index bab1673d..be7d7f85 100644
--- a/pydocx/openxml/wordprocessing/__init__.py
+++ b/pydocx/openxml/wordprocessing/__init__.py
@@ -40,7 +40,7 @@
from pydocx.openxml.wordprocessing.table_cell_properties import TableCellProperties # noqa
from pydocx.openxml.wordprocessing.table_row import TableRow
from pydocx.openxml.wordprocessing.text import Text
-from pydocx.openxml.wordprocessing.textbox import Textbox
+from pydocx.openxml.wordprocessing.textbox import Textbox, TxBxContent
__all__ = [
'AbstractNum',
@@ -80,8 +80,9 @@
'Styles',
'TabChar',
'Table',
- 'Textbox',
'TableCell',
'TableRow',
'Text',
+ 'Textbox',
+ 'TxBxContent',
]
diff --git a/pydocx/openxml/wordprocessing/textbox.py b/pydocx/openxml/wordprocessing/textbox.py
index c959e103..f759200b 100644
--- a/pydocx/openxml/wordprocessing/textbox.py
+++ b/pydocx/openxml/wordprocessing/textbox.py
@@ -6,7 +6,6 @@
)
from pydocx.models import XmlModel, XmlCollection
-# from pydocx.openxml.wordprocessing import Paragraph
class TxBxContent(XmlModel):
diff --git a/tests/fixtures/textbox.html b/tests/fixtures/textbox.html
index e834424b..2640dda2 100644
--- a/tests/fixtures/textbox.html
+++ b/tests/fixtures/textbox.html
@@ -1,4 +1,5 @@
+
AAA
BBB
-CCC
-DDD
+CCCDDD
+
From 2937c06e54fc3e10c4d2c4ea9be27ce04125ffcb Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 15:30:54 -0400
Subject: [PATCH 07/20] refs #203: Get the rest of the tests to pass.
---
pydocx/models.py | 9 +++++----
tox.ini | 1 +
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/pydocx/models.py b/pydocx/models.py
index f75e26bd..e7cd1102 100644
--- a/pydocx/models.py
+++ b/pydocx/models.py
@@ -129,14 +129,15 @@ def types(self):
return set(self._set_types(*self._types))
def _set_types(self, *types):
- base_path = 'pydocx.openxml.{}'
+ base_path = 'pydocx.openxml.{0}'
for _type in types:
- if isinstance(_type, basestring):
+ try:
path, klass, = _type.rsplit('.', 1)
+ except AttributeError:
+ yield _type
+ else:
module = importlib.import_module(base_path.format(path))
yield getattr(module, klass)
- else:
- yield _type
@property
def name_to_type_map(self):
diff --git a/tox.ini b/tox.ini
index 8c79be6f..253c446f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,6 +12,7 @@ commands =
deps =
-rrequirements/testing.txt
defusedxml: defusedxml==0.4.1
+ py26: importlib
[testenv:docs]
commands =
From fed6498797a56f0008e18818b17f706e861a8f3e Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 16:22:07 -0400
Subject: [PATCH 08/20] refs #203: Update to the new hotness on the touched
files.
---
.../markup_compatibility/alternate_content.py | 3 +-
.../openxml/markup_compatibility/fallback.py | 3 +-
pydocx/openxml/vml/shape.py | 4 +-
pydocx/openxml/wordprocessing/deleted_run.py | 6 +--
pydocx/openxml/wordprocessing/inserted_run.py | 6 +--
pydocx/openxml/wordprocessing/run.py | 39 +++++++------------
.../openxml/wordprocessing/smart_tag_run.py | 3 +-
pydocx/openxml/wordprocessing/table.py | 3 +-
pydocx/openxml/wordprocessing/table_cell.py | 3 +-
9 files changed, 23 insertions(+), 47 deletions(-)
diff --git a/pydocx/openxml/markup_compatibility/alternate_content.py b/pydocx/openxml/markup_compatibility/alternate_content.py
index 78fb8b4e..45bbb50a 100644
--- a/pydocx/openxml/markup_compatibility/alternate_content.py
+++ b/pydocx/openxml/markup_compatibility/alternate_content.py
@@ -6,9 +6,8 @@
)
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.markup_compatibility.fallback import Fallback
class AlternateContent(XmlModel):
XML_TAG = 'AlternateContent'
- children = XmlCollection(Fallback)
+ children = XmlCollection('markup_compatibility.Fallback')
diff --git a/pydocx/openxml/markup_compatibility/fallback.py b/pydocx/openxml/markup_compatibility/fallback.py
index b281576a..45cb9afe 100644
--- a/pydocx/openxml/markup_compatibility/fallback.py
+++ b/pydocx/openxml/markup_compatibility/fallback.py
@@ -6,9 +6,8 @@
)
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.wordprocessing.picture import Picture
class Fallback(XmlModel):
XML_TAG = 'Fallback'
- children = XmlCollection(Picture)
+ children = XmlCollection('wordprocessing.Picture')
diff --git a/pydocx/openxml/vml/shape.py b/pydocx/openxml/vml/shape.py
index 8fdd83f6..b0d84f73 100644
--- a/pydocx/openxml/vml/shape.py
+++ b/pydocx/openxml/vml/shape.py
@@ -6,15 +6,13 @@
)
from pydocx.models import XmlModel, XmlCollection, XmlAttribute
-from pydocx.openxml.vml.image_data import ImageData
-from pydocx.openxml.wordprocessing.textbox import Textbox
class Shape(XmlModel):
XML_TAG = 'shape'
style = XmlAttribute()
- children = XmlCollection(ImageData, Textbox)
+ children = XmlCollection('vml.ImageData', 'wordprocessing.Textbox')
# TODO perhaps we could have a prepare_style, or clean_style convention?
diff --git a/pydocx/openxml/wordprocessing/deleted_run.py b/pydocx/openxml/wordprocessing/deleted_run.py
index 3d55ff69..acce6951 100644
--- a/pydocx/openxml/wordprocessing/deleted_run.py
+++ b/pydocx/openxml/wordprocessing/deleted_run.py
@@ -6,16 +6,14 @@
)
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.wordprocessing.run import Run
-from pydocx.openxml.wordprocessing.smart_tag_run import SmartTagRun
class DeletedRun(XmlModel):
XML_TAG = 'del'
children = XmlCollection(
- Run,
- SmartTagRun,
+ 'wordprocessing.Run',
+ 'wordprocessing.SmartTagRun',
'wordprocessing.DeletedRun',
# TODO Needs InsertedRun
)
diff --git a/pydocx/openxml/wordprocessing/inserted_run.py b/pydocx/openxml/wordprocessing/inserted_run.py
index 7fc0255c..8d0dd0cb 100644
--- a/pydocx/openxml/wordprocessing/inserted_run.py
+++ b/pydocx/openxml/wordprocessing/inserted_run.py
@@ -6,16 +6,14 @@
)
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.wordprocessing.run import Run
-from pydocx.openxml.wordprocessing.smart_tag_run import SmartTagRun
class InsertedRun(XmlModel):
XML_TAG = 'ins'
children = XmlCollection(
- Run,
- SmartTagRun,
+ 'wordprocessing.Run',
+ 'wordprocessing.SmartTagRun',
'wordprocessing.InsertedRun',
# TODO Needs DeletedRun
)
diff --git a/pydocx/openxml/wordprocessing/run.py b/pydocx/openxml/wordprocessing/run.py
index 2acdb944..3766c98f 100644
--- a/pydocx/openxml/wordprocessing/run.py
+++ b/pydocx/openxml/wordprocessing/run.py
@@ -8,19 +8,6 @@
from pydocx.models import XmlModel, XmlCollection, XmlChild
from pydocx.openxml.wordprocessing.run_properties import RunProperties
-from pydocx.openxml.wordprocessing.br import Break
-from pydocx.openxml.wordprocessing.drawing import Drawing
-from pydocx.openxml.wordprocessing.field_char import FieldChar
-from pydocx.openxml.wordprocessing.field_code import FieldCode
-from pydocx.openxml.wordprocessing.picture import Picture
-from pydocx.openxml.wordprocessing.no_break_hyphen import NoBreakHyphen
-from pydocx.openxml.wordprocessing.text import Text
-from pydocx.openxml.wordprocessing.tab_char import TabChar
-from pydocx.openxml.wordprocessing.deleted_text import DeletedText
-from pydocx.openxml.wordprocessing.footnote_reference import FootnoteReference
-from pydocx.openxml.wordprocessing.footnote_reference_mark import FootnoteReferenceMark
-from pydocx.openxml.wordprocessing.embedded_object import EmbeddedObject
-from pydocx.openxml.markup_compatibility import AlternateContent
from pydocx.util.memoize import memoized
@@ -30,19 +17,19 @@ class Run(XmlModel):
properties = XmlChild(type=RunProperties)
children = XmlCollection(
- EmbeddedObject,
- TabChar,
- Break,
- NoBreakHyphen,
- Text,
- Drawing,
- Picture,
- DeletedText,
- FootnoteReference,
- FootnoteReferenceMark,
- FieldChar,
- FieldCode,
- AlternateContent,
+ 'wordprocessing.EmbeddedObject',
+ 'wordprocessing.TabChar',
+ 'wordprocessing.Break',
+ 'wordprocessing.NoBreakHyphen',
+ 'wordprocessing.Text',
+ 'wordprocessing.Drawing',
+ 'wordprocessing.Picture',
+ 'wordprocessing.DeletedText',
+ 'wordprocessing.FootnoteReference',
+ 'wordprocessing.FootnoteReferenceMark',
+ 'wordprocessing.FieldChar',
+ 'wordprocessing.FieldCode',
+ 'markup_compatibility.AlternateContent',
)
def get_style_chain_stack(self):
diff --git a/pydocx/openxml/wordprocessing/smart_tag_run.py b/pydocx/openxml/wordprocessing/smart_tag_run.py
index dfa906f9..1d8c0ee9 100644
--- a/pydocx/openxml/wordprocessing/smart_tag_run.py
+++ b/pydocx/openxml/wordprocessing/smart_tag_run.py
@@ -6,13 +6,12 @@
)
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.wordprocessing.run import Run
class SmartTagRun(XmlModel):
XML_TAG = 'smartTag'
children = XmlCollection(
- Run,
+ 'wordprocessing.Run',
'wordprocessing.SmartTagRun',
)
diff --git a/pydocx/openxml/wordprocessing/table.py b/pydocx/openxml/wordprocessing/table.py
index 61314b29..60c710b1 100644
--- a/pydocx/openxml/wordprocessing/table.py
+++ b/pydocx/openxml/wordprocessing/table.py
@@ -8,14 +8,13 @@
from collections import defaultdict
from pydocx.models import XmlModel, XmlCollection
-from pydocx.openxml.wordprocessing.table_row import TableRow
class Table(XmlModel):
XML_TAG = 'tbl'
rows = XmlCollection(
- TableRow,
+ 'wordprocessing.TableRow',
)
def calculate_table_cell_spans(self):
diff --git a/pydocx/openxml/wordprocessing/table_cell.py b/pydocx/openxml/wordprocessing/table_cell.py
index 8a538e86..84320f29 100644
--- a/pydocx/openxml/wordprocessing/table_cell.py
+++ b/pydocx/openxml/wordprocessing/table_cell.py
@@ -6,7 +6,6 @@
)
from pydocx.models import XmlModel, XmlCollection, XmlChild
-from pydocx.openxml.wordprocessing.paragraph import Paragraph
from pydocx.openxml.wordprocessing.table_cell_properties import TableCellProperties # noqa
@@ -16,6 +15,6 @@ class TableCell(XmlModel):
properties = XmlChild(type=TableCellProperties)
children = XmlCollection(
- Paragraph,
+ 'wordprocessing.Paragraph',
'wordprocessing.Table',
)
From 563354c428686ee890aba70c3123d9524fe6437f Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 16:27:24 -0400
Subject: [PATCH 09/20] refs #203: Update note.
---
CHANGELOG.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 2cb69817..291ca6e2 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,3 +1,8 @@
+**dev**
+
+- Textboxes have been implemented. We no longer lose the content inside of
+ them.
+
**0.9.6**
- Fixed issue in PyDocX CLI tool and added new test cases for the same
From b80b0882b73023e38cac17cc4901aaf704138639 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 16:50:18 -0400
Subject: [PATCH 10/20] refs #203: Moved the definition of the textbox.
---
pydocx/openxml/vml/__init__.py | 2 ++
pydocx/openxml/vml/textbox.py | 16 ++++++++++++++++
pydocx/openxml/wordprocessing/__init__.py | 3 +--
pydocx/openxml/wordprocessing/textbox.py | 8 --------
4 files changed, 19 insertions(+), 10 deletions(-)
create mode 100644 pydocx/openxml/vml/textbox.py
diff --git a/pydocx/openxml/vml/__init__.py b/pydocx/openxml/vml/__init__.py
index f44a969f..a2547821 100644
--- a/pydocx/openxml/vml/__init__.py
+++ b/pydocx/openxml/vml/__init__.py
@@ -1,8 +1,10 @@
# coding: utf-8
from pydocx.openxml.vml.image_data import ImageData
from pydocx.openxml.vml.shape import Shape
+from pydocx.openxml.vml.textbox import Textbox
__all__ = [
'ImageData',
'Shape',
+ 'Textbox',
]
diff --git a/pydocx/openxml/vml/textbox.py b/pydocx/openxml/vml/textbox.py
new file mode 100644
index 00000000..8cf196dd
--- /dev/null
+++ b/pydocx/openxml/vml/textbox.py
@@ -0,0 +1,16 @@
+# coding: utf-8
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+)
+
+from pydocx.models import XmlModel, XmlCollection
+
+
+class Textbox(XmlModel):
+ XML_TAG = 'textbox'
+
+ children = XmlCollection(
+ 'wordprocessing.TxBxContent',
+ )
diff --git a/pydocx/openxml/wordprocessing/__init__.py b/pydocx/openxml/wordprocessing/__init__.py
index be7d7f85..eacdec40 100644
--- a/pydocx/openxml/wordprocessing/__init__.py
+++ b/pydocx/openxml/wordprocessing/__init__.py
@@ -40,7 +40,7 @@
from pydocx.openxml.wordprocessing.table_cell_properties import TableCellProperties # noqa
from pydocx.openxml.wordprocessing.table_row import TableRow
from pydocx.openxml.wordprocessing.text import Text
-from pydocx.openxml.wordprocessing.textbox import Textbox, TxBxContent
+from pydocx.openxml.wordprocessing.textbox import TxBxContent
__all__ = [
'AbstractNum',
@@ -83,6 +83,5 @@
'TableCell',
'TableRow',
'Text',
- 'Textbox',
'TxBxContent',
]
diff --git a/pydocx/openxml/wordprocessing/textbox.py b/pydocx/openxml/wordprocessing/textbox.py
index f759200b..a6176804 100644
--- a/pydocx/openxml/wordprocessing/textbox.py
+++ b/pydocx/openxml/wordprocessing/textbox.py
@@ -13,11 +13,3 @@ class TxBxContent(XmlModel):
children = XmlCollection(
'wordprocessing.Paragraph',
)
-
-
-class Textbox(XmlModel):
- XML_TAG = 'textbox'
-
- children = XmlCollection(
- TxBxContent,
- )
From afb093d2f9ec93d88ae981f0be74f7f9461be1b2 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 16:52:40 -0400
Subject: [PATCH 11/20] refs #203: Update the references to Textbox
---
pydocx/export/base.py | 2 +-
pydocx/openxml/vml/shape.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pydocx/export/base.py b/pydocx/export/base.py
index b0456153..e88e8986 100644
--- a/pydocx/export/base.py
+++ b/pydocx/export/base.py
@@ -64,12 +64,12 @@ def __init__(self, path):
wordprocessing.SimpleField: self.export_simple_field,
vml.Shape: self.export_vml_shape,
vml.ImageData: self.export_vml_image_data,
+ vml.Textbox: self.export_textbox,
wordprocessing.EmbeddedObject: self.export_embedded_object,
NumberingSpan: self.export_numbering_span,
NumberingItem: self.export_numbering_item,
markup_compatibility.AlternateContent: self.export_alternate_content,
markup_compatibility.Fallback: self.export_fallback,
- wordprocessing.Textbox: self.export_textbox,
wordprocessing.TxBxContent: self.export_textbox_content,
}
self.field_type_to_export_func_map = {
diff --git a/pydocx/openxml/vml/shape.py b/pydocx/openxml/vml/shape.py
index b0d84f73..8fea39a1 100644
--- a/pydocx/openxml/vml/shape.py
+++ b/pydocx/openxml/vml/shape.py
@@ -12,7 +12,7 @@ class Shape(XmlModel):
XML_TAG = 'shape'
style = XmlAttribute()
- children = XmlCollection('vml.ImageData', 'wordprocessing.Textbox')
+ children = XmlCollection('vml.ImageData', 'vml.Textbox')
# TODO perhaps we could have a prepare_style, or clean_style convention?
From f735783e268fff5315c0e61528aaf0fb17cfed84 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Wed, 11 May 2016 16:56:05 -0400
Subject: [PATCH 12/20] refs #203: Renamed the textbox content file.
---
pydocx/openxml/wordprocessing/__init__.py | 2 +-
.../openxml/wordprocessing/{textbox.py => textbox_content.py} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename pydocx/openxml/wordprocessing/{textbox.py => textbox_content.py} (100%)
diff --git a/pydocx/openxml/wordprocessing/__init__.py b/pydocx/openxml/wordprocessing/__init__.py
index eacdec40..2430064d 100644
--- a/pydocx/openxml/wordprocessing/__init__.py
+++ b/pydocx/openxml/wordprocessing/__init__.py
@@ -40,7 +40,7 @@
from pydocx.openxml.wordprocessing.table_cell_properties import TableCellProperties # noqa
from pydocx.openxml.wordprocessing.table_row import TableRow
from pydocx.openxml.wordprocessing.text import Text
-from pydocx.openxml.wordprocessing.textbox import TxBxContent
+from pydocx.openxml.wordprocessing.textbox_content import TxBxContent
__all__ = [
'AbstractNum',
diff --git a/pydocx/openxml/wordprocessing/textbox.py b/pydocx/openxml/wordprocessing/textbox_content.py
similarity index 100%
rename from pydocx/openxml/wordprocessing/textbox.py
rename to pydocx/openxml/wordprocessing/textbox_content.py
From 338a25b59fb721f3305d5e272ebda844a7d34c7e Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Thu, 12 May 2016 12:32:37 -0400
Subject: [PATCH 13/20] refs #203: Removed a comma.
---
pydocx/models.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pydocx/models.py b/pydocx/models.py
index e7cd1102..960f3963 100644
--- a/pydocx/models.py
+++ b/pydocx/models.py
@@ -132,7 +132,7 @@ def _set_types(self, *types):
base_path = 'pydocx.openxml.{0}'
for _type in types:
try:
- path, klass, = _type.rsplit('.', 1)
+ path, klass = _type.rsplit('.', 1)
except AttributeError:
yield _type
else:
From 7e5fc4bf3da9305b27a8d57f5f828baf2ab0b5ed Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Thu, 12 May 2016 12:32:51 -0400
Subject: [PATCH 14/20] refs #203: Added XML based tests.
---
.../export/html/test_markup_compatibility.py | 91 +++++++++++++++++++
1 file changed, 91 insertions(+)
create mode 100644 tests/export/html/test_markup_compatibility.py
diff --git a/tests/export/html/test_markup_compatibility.py b/tests/export/html/test_markup_compatibility.py
new file mode 100644
index 00000000..06d1cded
--- /dev/null
+++ b/tests/export/html/test_markup_compatibility.py
@@ -0,0 +1,91 @@
+# coding: utf-8
+
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+)
+
+from pydocx.test import DocumentGeneratorTestCase
+from pydocx.test.utils import WordprocessingDocumentFactory
+from pydocx.openxml.packaging import MainDocumentPart
+
+
+class TableTestCase(DocumentGeneratorTestCase):
+ def test_textbox_with_content(self):
+ document_xml = '''
+
+
+
+
+
+
+
+
+
+
+ AAA
+
+
+
+
+
+
+
+
+
+
+ '''
+
+ document = WordprocessingDocumentFactory()
+ document.add(MainDocumentPart, document_xml)
+
+ expected_html = '''
+
+
+ AAA
+
+
+ '''
+ self.assert_document_generates_html(document, expected_html)
+
+ def test_textbox_with_content_outside_of_textbox(self):
+ document_xml = '''
+
+ AAA
+
+
+
+
+
+
+
+
+
+ BBB
+
+
+
+
+
+
+
+
+
+ CCC
+
+ '''
+
+ document = WordprocessingDocumentFactory()
+ document.add(MainDocumentPart, document_xml)
+
+ expected_html = '''
+
+ AAA
+
+ BBB
+
+ CCC
+
+ '''
+ self.assert_document_generates_html(document, expected_html)
From 030b0d0590f877a17eb5156b69ce452288fc9bba Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Thu, 12 May 2016 14:51:23 -0400
Subject: [PATCH 15/20] refs #203: Update test.
---
tests/export/html/test_markup_compatibility.py | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/tests/export/html/test_markup_compatibility.py b/tests/export/html/test_markup_compatibility.py
index 06d1cded..b98c2192 100644
--- a/tests/export/html/test_markup_compatibility.py
+++ b/tests/export/html/test_markup_compatibility.py
@@ -54,6 +54,7 @@ def test_textbox_with_content_outside_of_textbox(self):
AAA
+ BBB
@@ -62,7 +63,7 @@ def test_textbox_with_content_outside_of_textbox(self):
- BBB
+ CCC
@@ -71,8 +72,9 @@ def test_textbox_with_content_outside_of_textbox(self):
+ DDD
- CCC
+ EEE
'''
@@ -81,11 +83,11 @@ def test_textbox_with_content_outside_of_textbox(self):
expected_html = '''
- AAA
+ AAABBB
- BBB
+ CCC
- CCC
+ DDDEEE
'''
self.assert_document_generates_html(document, expected_html)
From 1ce2887742f83946365c4b3876b4f53226001e86 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Thu, 12 May 2016 15:45:40 -0400
Subject: [PATCH 16/20] refs #203: Added tests without markup compat.
---
tests/export/html/test_textbox.py | 85 +++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 tests/export/html/test_textbox.py
diff --git a/tests/export/html/test_textbox.py b/tests/export/html/test_textbox.py
new file mode 100644
index 00000000..6d7cc5da
--- /dev/null
+++ b/tests/export/html/test_textbox.py
@@ -0,0 +1,85 @@
+# coding: utf-8
+
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+)
+
+from pydocx.test import DocumentGeneratorTestCase
+from pydocx.test.utils import WordprocessingDocumentFactory
+from pydocx.openxml.packaging import MainDocumentPart
+
+
+class TableTestCase(DocumentGeneratorTestCase):
+ def test_textbox_with_content(self):
+ document_xml = '''
+
+
+
+
+
+
+
+
+ AAA
+
+
+
+
+
+
+
+
+ '''
+
+ document = WordprocessingDocumentFactory()
+ document.add(MainDocumentPart, document_xml)
+
+ expected_html = '''
+
+
+ AAA
+
+
+ '''
+ self.assert_document_generates_html(document, expected_html)
+
+ def test_textbox_with_content_outside_of_textbox(self):
+ document_xml = '''
+
+ AAA
+
+ BBB
+
+
+
+
+
+
+ CCC
+
+
+
+
+
+
+ DDD
+
+ EEE
+
+ '''
+
+ document = WordprocessingDocumentFactory()
+ document.add(MainDocumentPart, document_xml)
+
+ expected_html = '''
+
+ AAABBB
+
+ CCC
+
+ DDDEEE
+
+ '''
+ self.assert_document_generates_html(document, expected_html)
From 6b738c118575de731a10c932da991e754354e7e5 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Fri, 13 May 2016 12:36:06 -0400
Subject: [PATCH 17/20] refs #203: name change.
---
pydocx/export/base.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/pydocx/export/base.py b/pydocx/export/base.py
index 1b91a7fa..bee990bf 100644
--- a/pydocx/export/base.py
+++ b/pydocx/export/base.py
@@ -15,7 +15,7 @@
NumberingSpan,
NumberingSpanBuilder,
)
-from pydocx.openxml import wordprocessing, vml, markup_compatibility
+from pydocx.openxml import markup_compatibility, vml, wordprocessing
from pydocx.openxml.packaging import WordprocessingDocument
@@ -68,8 +68,8 @@ def __init__(self, path):
wordprocessing.EmbeddedObject: self.export_embedded_object,
NumberingSpan: self.export_numbering_span,
NumberingItem: self.export_numbering_item,
- markup_compatibility.AlternateContent: self.export_alternate_content,
- markup_compatibility.Fallback: self.export_fallback,
+ markup_compatibility.AlternateContent: self.export_markup_compatibility_alternate_content, # noqa
+ markup_compatibility.Fallback: self.export_markup_compatibility_fallback,
wordprocessing.TxBxContent: self.export_textbox_content,
}
self.field_type_to_export_func_map = {
@@ -547,8 +547,8 @@ def export_textbox_content(self, textbox_content):
return self.yield_nested(textbox_content.children, self.export_node)
# Markup Compatibility exporters
- def export_alternate_content(self, alternate_content):
+ def export_markup_compatibility_alternate_content(self, alternate_content):
return self.yield_nested(alternate_content.children, self.export_node)
- def export_fallback(self, fallback):
+ def export_markup_compatibility_fallback(self, fallback):
return self.yield_nested(fallback.children, self.export_node)
From 5554636dc6f37e8aa23b6aa9a6841c691f3ee094 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Fri, 13 May 2016 12:37:36 -0400
Subject: [PATCH 18/20] Revert "refs #203: Update to the new hotness on the
touched files."
This reverts commit fed6498797a56f0008e18818b17f706e861a8f3e.
---
.../markup_compatibility/alternate_content.py | 3 +-
.../openxml/markup_compatibility/fallback.py | 3 +-
pydocx/openxml/vml/shape.py | 4 +-
pydocx/openxml/wordprocessing/deleted_run.py | 6 ++-
pydocx/openxml/wordprocessing/inserted_run.py | 6 ++-
pydocx/openxml/wordprocessing/run.py | 39 ++++++++++++-------
.../openxml/wordprocessing/smart_tag_run.py | 3 +-
pydocx/openxml/wordprocessing/table.py | 3 +-
pydocx/openxml/wordprocessing/table_cell.py | 3 +-
9 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/pydocx/openxml/markup_compatibility/alternate_content.py b/pydocx/openxml/markup_compatibility/alternate_content.py
index 45bbb50a..78fb8b4e 100644
--- a/pydocx/openxml/markup_compatibility/alternate_content.py
+++ b/pydocx/openxml/markup_compatibility/alternate_content.py
@@ -6,8 +6,9 @@
)
from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.markup_compatibility.fallback import Fallback
class AlternateContent(XmlModel):
XML_TAG = 'AlternateContent'
- children = XmlCollection('markup_compatibility.Fallback')
+ children = XmlCollection(Fallback)
diff --git a/pydocx/openxml/markup_compatibility/fallback.py b/pydocx/openxml/markup_compatibility/fallback.py
index 45cb9afe..b281576a 100644
--- a/pydocx/openxml/markup_compatibility/fallback.py
+++ b/pydocx/openxml/markup_compatibility/fallback.py
@@ -6,8 +6,9 @@
)
from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.wordprocessing.picture import Picture
class Fallback(XmlModel):
XML_TAG = 'Fallback'
- children = XmlCollection('wordprocessing.Picture')
+ children = XmlCollection(Picture)
diff --git a/pydocx/openxml/vml/shape.py b/pydocx/openxml/vml/shape.py
index 8fea39a1..c73ceeaa 100644
--- a/pydocx/openxml/vml/shape.py
+++ b/pydocx/openxml/vml/shape.py
@@ -6,14 +6,14 @@
)
from pydocx.models import XmlModel, XmlCollection, XmlAttribute
+from pydocx.openxml.vml.image_data import ImageData
class Shape(XmlModel):
XML_TAG = 'shape'
style = XmlAttribute()
- children = XmlCollection('vml.ImageData', 'vml.Textbox')
-
+ children = XmlCollection(ImageData, 'vml.Textbox')
# TODO perhaps we could have a prepare_style, or clean_style convention?
def get_style(self):
diff --git a/pydocx/openxml/wordprocessing/deleted_run.py b/pydocx/openxml/wordprocessing/deleted_run.py
index acce6951..3d55ff69 100644
--- a/pydocx/openxml/wordprocessing/deleted_run.py
+++ b/pydocx/openxml/wordprocessing/deleted_run.py
@@ -6,14 +6,16 @@
)
from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.wordprocessing.run import Run
+from pydocx.openxml.wordprocessing.smart_tag_run import SmartTagRun
class DeletedRun(XmlModel):
XML_TAG = 'del'
children = XmlCollection(
- 'wordprocessing.Run',
- 'wordprocessing.SmartTagRun',
+ Run,
+ SmartTagRun,
'wordprocessing.DeletedRun',
# TODO Needs InsertedRun
)
diff --git a/pydocx/openxml/wordprocessing/inserted_run.py b/pydocx/openxml/wordprocessing/inserted_run.py
index 8d0dd0cb..7fc0255c 100644
--- a/pydocx/openxml/wordprocessing/inserted_run.py
+++ b/pydocx/openxml/wordprocessing/inserted_run.py
@@ -6,14 +6,16 @@
)
from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.wordprocessing.run import Run
+from pydocx.openxml.wordprocessing.smart_tag_run import SmartTagRun
class InsertedRun(XmlModel):
XML_TAG = 'ins'
children = XmlCollection(
- 'wordprocessing.Run',
- 'wordprocessing.SmartTagRun',
+ Run,
+ SmartTagRun,
'wordprocessing.InsertedRun',
# TODO Needs DeletedRun
)
diff --git a/pydocx/openxml/wordprocessing/run.py b/pydocx/openxml/wordprocessing/run.py
index 3766c98f..2acdb944 100644
--- a/pydocx/openxml/wordprocessing/run.py
+++ b/pydocx/openxml/wordprocessing/run.py
@@ -8,6 +8,19 @@
from pydocx.models import XmlModel, XmlCollection, XmlChild
from pydocx.openxml.wordprocessing.run_properties import RunProperties
+from pydocx.openxml.wordprocessing.br import Break
+from pydocx.openxml.wordprocessing.drawing import Drawing
+from pydocx.openxml.wordprocessing.field_char import FieldChar
+from pydocx.openxml.wordprocessing.field_code import FieldCode
+from pydocx.openxml.wordprocessing.picture import Picture
+from pydocx.openxml.wordprocessing.no_break_hyphen import NoBreakHyphen
+from pydocx.openxml.wordprocessing.text import Text
+from pydocx.openxml.wordprocessing.tab_char import TabChar
+from pydocx.openxml.wordprocessing.deleted_text import DeletedText
+from pydocx.openxml.wordprocessing.footnote_reference import FootnoteReference
+from pydocx.openxml.wordprocessing.footnote_reference_mark import FootnoteReferenceMark
+from pydocx.openxml.wordprocessing.embedded_object import EmbeddedObject
+from pydocx.openxml.markup_compatibility import AlternateContent
from pydocx.util.memoize import memoized
@@ -17,19 +30,19 @@ class Run(XmlModel):
properties = XmlChild(type=RunProperties)
children = XmlCollection(
- 'wordprocessing.EmbeddedObject',
- 'wordprocessing.TabChar',
- 'wordprocessing.Break',
- 'wordprocessing.NoBreakHyphen',
- 'wordprocessing.Text',
- 'wordprocessing.Drawing',
- 'wordprocessing.Picture',
- 'wordprocessing.DeletedText',
- 'wordprocessing.FootnoteReference',
- 'wordprocessing.FootnoteReferenceMark',
- 'wordprocessing.FieldChar',
- 'wordprocessing.FieldCode',
- 'markup_compatibility.AlternateContent',
+ EmbeddedObject,
+ TabChar,
+ Break,
+ NoBreakHyphen,
+ Text,
+ Drawing,
+ Picture,
+ DeletedText,
+ FootnoteReference,
+ FootnoteReferenceMark,
+ FieldChar,
+ FieldCode,
+ AlternateContent,
)
def get_style_chain_stack(self):
diff --git a/pydocx/openxml/wordprocessing/smart_tag_run.py b/pydocx/openxml/wordprocessing/smart_tag_run.py
index 1d8c0ee9..dfa906f9 100644
--- a/pydocx/openxml/wordprocessing/smart_tag_run.py
+++ b/pydocx/openxml/wordprocessing/smart_tag_run.py
@@ -6,12 +6,13 @@
)
from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.wordprocessing.run import Run
class SmartTagRun(XmlModel):
XML_TAG = 'smartTag'
children = XmlCollection(
- 'wordprocessing.Run',
+ Run,
'wordprocessing.SmartTagRun',
)
diff --git a/pydocx/openxml/wordprocessing/table.py b/pydocx/openxml/wordprocessing/table.py
index 60c710b1..61314b29 100644
--- a/pydocx/openxml/wordprocessing/table.py
+++ b/pydocx/openxml/wordprocessing/table.py
@@ -8,13 +8,14 @@
from collections import defaultdict
from pydocx.models import XmlModel, XmlCollection
+from pydocx.openxml.wordprocessing.table_row import TableRow
class Table(XmlModel):
XML_TAG = 'tbl'
rows = XmlCollection(
- 'wordprocessing.TableRow',
+ TableRow,
)
def calculate_table_cell_spans(self):
diff --git a/pydocx/openxml/wordprocessing/table_cell.py b/pydocx/openxml/wordprocessing/table_cell.py
index 84320f29..8a538e86 100644
--- a/pydocx/openxml/wordprocessing/table_cell.py
+++ b/pydocx/openxml/wordprocessing/table_cell.py
@@ -6,6 +6,7 @@
)
from pydocx.models import XmlModel, XmlCollection, XmlChild
+from pydocx.openxml.wordprocessing.paragraph import Paragraph
from pydocx.openxml.wordprocessing.table_cell_properties import TableCellProperties # noqa
@@ -15,6 +16,6 @@ class TableCell(XmlModel):
properties = XmlChild(type=TableCellProperties)
children = XmlCollection(
- 'wordprocessing.Paragraph',
+ Paragraph,
'wordprocessing.Table',
)
From 4d12156fba236b113e97b40c7630ff4faf19bf0b Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Fri, 13 May 2016 12:38:51 -0400
Subject: [PATCH 19/20] refs #203: Added a comment.
---
pydocx/openxml/markup_compatibility/fallback.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/pydocx/openxml/markup_compatibility/fallback.py b/pydocx/openxml/markup_compatibility/fallback.py
index b281576a..397091e4 100644
--- a/pydocx/openxml/markup_compatibility/fallback.py
+++ b/pydocx/openxml/markup_compatibility/fallback.py
@@ -11,4 +11,5 @@
class Fallback(XmlModel):
XML_TAG = 'Fallback'
+ # TODO #204: actually include all of the children defined in the spec.
children = XmlCollection(Picture)
From 7e20b60fc4c187a5e1ffe34a443c853337073178 Mon Sep 17 00:00:00 2001
From: Jason Ward
Date: Fri, 13 May 2016 14:07:13 -0400
Subject: [PATCH 20/20] refs #203: Removed a dead comment.
---
pydocx/export/base.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/pydocx/export/base.py b/pydocx/export/base.py
index bee990bf..baae919b 100644
--- a/pydocx/export/base.py
+++ b/pydocx/export/base.py
@@ -546,7 +546,6 @@ def export_textbox(self, textbox):
def export_textbox_content(self, textbox_content):
return self.yield_nested(textbox_content.children, self.export_node)
- # Markup Compatibility exporters
def export_markup_compatibility_alternate_content(self, alternate_content):
return self.yield_nested(alternate_content.children, self.export_node)