aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mammoth/conversion.py52
-rw-r--r--mammoth/documents.py38
-rw-r--r--mammoth/docx/document_xml.py31
-rw-r--r--tests/conversion_tests.py10
-rw-r--r--tests/docx/document_xml_tests.py4
5 files changed, 72 insertions, 63 deletions
diff --git a/mammoth/conversion.py b/mammoth/conversion.py
index 9eaa3d2..6ef13c8 100644
--- a/mammoth/conversion.py
+++ b/mammoth/conversion.py
@@ -35,7 +35,7 @@ class DocumentConverter(object):
self.messages = []
self._style_map = style_map
self._uniquifier = generate_uniquifier()
- self._footnote_ids = []
+ self._note_references = []
self._converters = {
documents.Document: self._convert_document,
documents.Paragraph: self._convert_paragraph,
@@ -48,8 +48,8 @@ class DocumentConverter(object):
documents.TableCell: self._convert_table_cell,
documents.LineBreak: self._line_break,
documents.Image: convert_image or images.inline(self._convert_image),
- documents.FootnoteReference: self._convert_footnote_reference,
- documents.Footnote: self._convert_footnote,
+ documents.NoteReference: self._convert_note_reference,
+ documents.Note: self._convert_note,
}
self._convert_underline = convert_underline
@@ -62,11 +62,11 @@ class DocumentConverter(object):
self._convert_elements_to_html(document.children, html_generator)
html_generator.end_all()
html_generator.start("ol")
- footnotes = [
- document.footnotes.find_footnote_by_id(footnote_id)
- for footnote_id in self._footnote_ids
+ notes = [
+ document.notes.resolve(reference)
+ for reference in self._note_references
]
- self._convert_elements_to_html(footnotes, html_generator)
+ self._convert_elements_to_html(notes, html_generator)
html_generator.end()
@@ -146,29 +146,29 @@ class DocumentConverter(object):
"src": "data:{0};base64,{1}".format(image.content_type, encoded_src)
}
- def _convert_footnote_reference(self, footnote_reference, html_generator):
- uid = self._footnote_uid(footnote_reference.footnote_id)
+ def _convert_note_reference(self, note_reference, html_generator):
+ uid = self._note_uid(note_reference.note_id)
html_generator.start("sup")
html_generator.start("a", {
- "href": "#footnote-" + uid,
- "id": "footnote-ref-" + uid
+ "href": "#{0}-{1}".format(note_reference.note_type, uid),
+ "id": "{0}-ref-{1}".format(note_reference.note_type, uid),
})
- self._footnote_ids.append(footnote_reference.footnote_id);
- footnote_number = len(self._footnote_ids)
- html_generator.text("[{0}]".format(footnote_number))
+ self._note_references.append(note_reference);
+ note_number = len(self._note_references)
+ html_generator.text("[{0}]".format(note_number))
html_generator.end()
html_generator.end()
- def _convert_footnote(self, footnote, html_generator):
- uid = self._footnote_uid(footnote.id)
- html_generator.start("li", {"id": "footnote-{0}".format(uid)})
- footnote_generator = HtmlGenerator()
- self._convert_elements_to_html(footnote.body, footnote_generator)
- footnote_generator.text(" ")
- footnote_generator.start("a", {"href": "#footnote-ref-{0}".format(uid)})
- footnote_generator.text(_up_arrow)
- footnote_generator.end_all()
- html_generator.append(footnote_generator)
+ def _convert_note(self, note, html_generator):
+ uid = self._note_uid(note.id)
+ html_generator.start("li", {"id": "{0}-{1}".format(note.note_type, uid)})
+ note_generator = HtmlGenerator()
+ self._convert_elements_to_html(note.body, note_generator)
+ note_generator.text(" ")
+ note_generator.start("a", {"href": "#{0}-ref-{1}".format(note.note_type, uid)})
+ note_generator.text(_up_arrow)
+ note_generator.end_all()
+ html_generator.append(note_generator)
html_generator.end()
@@ -200,8 +200,8 @@ class DocumentConverter(object):
return default
- def _footnote_uid(self, footnote_id):
- return "{0}-{1}".format(self._uniquifier, footnote_id)
+ def _note_uid(self, note_id):
+ return "{0}-{1}".format(self._uniquifier, note_id)
def _document_matcher_matches(matcher, element, element_type):
diff --git a/mammoth/documents.py b/mammoth/documents.py
index e7a46c4..9effce8 100644
--- a/mammoth/documents.py
+++ b/mammoth/documents.py
@@ -1,7 +1,7 @@
import dodge
-Document = dodge.data_class("Document", ["children", "footnotes"])
+Document = dodge.data_class("Document", ["children", "notes"])
Paragraph = dodge.data_class("Paragraph", ["children", "style_id", "style_name", "numbering"])
Run = dodge.data_class("Run", [
"children", "style_id", "style_name", "is_bold", "is_italic",
@@ -25,10 +25,10 @@ class Image(object):
self.open = open
-def document(children, footnotes=None):
- if footnotes is None:
- footnotes = Footnotes({})
- return Document(children, footnotes)
+def document(children, notes=None):
+ if notes is None:
+ notes = Notes({})
+ return Document(children, notes)
def paragraph(children, style_id=None, style_name=None, numbering=None):
return Paragraph(children, style_id, style_name, numbering)
@@ -67,22 +67,32 @@ def numbering_level(level_index, is_ordered):
_NumberingLevel = dodge.data_class("NumberingLevel", ["level_index", "is_ordered"])
-footnote = Footnote = dodge.data_class("Footnote", ["id", "body"])
+note = Note = dodge.data_class("Note", ["note_type", "id", "body"])
-class Footnotes(object):
- def __init__(self, footnotes):
- self._footnotes = footnotes
+class Notes(object):
+ def __init__(self, notes):
+ self._notes = notes
- def find_footnote_by_id(self, id):
- return self._footnotes[id]
+ def find_note(self, note_type, note_id):
+ return self._notes[(note_type, note_id)]
+
+ def resolve(self, reference):
+ return self.find_note(reference.note_type, reference.note_id)
def __eq__(self, other):
- return isinstance(other, Footnotes) and self._footnotes == other._footnotes
+ return isinstance(other, Notes) and self._notes == other._notes
def __ne__(self, other):
return not (self == other)
-footnotes = Footnotes
+def notes(notes_list):
+ return Notes(dict(
+ (_note_key(note), note)
+ for note in notes_list
+ ))
+
+def _note_key(note):
+ return (note.note_type, note.id)
-footnote_reference = FootnoteReference = dodge.data_class("FootnoteReference", ["footnote_id"])
+note_reference = NoteReference = dodge.data_class("NoteReference", ["note_type", "note_id"])
diff --git a/mammoth/docx/document_xml.py b/mammoth/docx/document_xml.py
index d82dec4..ce035ad 100644
--- a/mammoth/docx/document_xml.py
+++ b/mammoth/docx/document_xml.py
@@ -23,12 +23,12 @@ def read_document_xml_element(element,
content_types=content_types,
relationships=relationships,
styles=styles,
- footnote_elements=footnote_elements,
+ note_elements=footnote_elements,
docx_file=docx_file,
)
return reader(element)
-def _create_reader(numbering, content_types, relationships, styles, footnote_elements, docx_file):
+def _create_reader(numbering, content_types, relationships, styles, note_elements, docx_file):
_handlers = {}
_ignored_elements = set([
"w:bookmarkStart",
@@ -134,20 +134,13 @@ def _create_reader(numbering, content_types, relationships, styles, footnote_ele
def document(element):
body_element = _find_child(element, "w:body")
children_result = _read_xml_elements(body_element.children)
- footnotes_result = results.combine(map(_read_footnote, footnote_elements))
-
- return results.map(
- lambda children, footnotes: documents.document(
- children,
- documents.footnotes(dict((footnote.id, footnote) for footnote in footnotes))
- ),
- children_result, footnotes_result
- )
+ notes_result = results.combine(map(_read_note, note_elements)).map(documents.notes)
+ return results.map(documents.document, children_result, notes_result)
- def _read_footnote(element):
+ def _read_note(element):
return _read_xml_elements(element.body).map(
- lambda body: documents.footnote(element.id, body))
+ lambda body: documents.note(element.note_type, element.id, body))
@handler("w:tab")
@@ -228,9 +221,15 @@ def _create_reader(numbering, content_types, relationships, styles, footnote_ele
image = documents.image(alt_text=alt_text, content_type=content_type, open=open_image)
return results.success(image)
- @handler("w:footnoteReference")
- def footnote_reference(element):
- return results.success(documents.footnote_reference(element.attributes["w:id"]))
+ def note_reference_reader(note_type):
+ @handler("w:{0}Reference".format(note_type))
+ def note_reference(element):
+ return results.success(documents.note_reference(note_type, element.attributes["w:id"]))
+
+ return note_reference
+
+ note_reference_reader("footnote")
+ note_reference_reader("endnote")
def read(element):
handler = _handlers.get(element.name)
diff --git a/tests/conversion_tests.py b/tests/conversion_tests.py
index 246671d..39c57cd 100644
--- a/tests/conversion_tests.py
+++ b/tests/conversion_tests.py
@@ -286,7 +286,7 @@ def can_define_custom_conversion_for_images():
@istest
def footnote_reference_is_converted_to_superscript_intra_page_link():
- footnote_reference = documents.footnote_reference("4")
+ footnote_reference = documents.note_reference("footnote", "4")
result = convert_document_element_to_html(
footnote_reference,
generate_uniquifier=lambda: 42
@@ -296,15 +296,15 @@ def footnote_reference_is_converted_to_superscript_intra_page_link():
@istest
def footnotes_are_included_after_the_main_body():
- footnote_reference = documents.footnote_reference("4")
+ footnote_reference = documents.note_reference("footnote", "4")
document = documents.document(
[documents.paragraph([
_run_with_text("Knock knock"),
documents.run([footnote_reference])
])],
- footnotes=documents.Footnotes({
- "4": documents.Footnote("4", [_paragraph_with_text("Who's there?")])
- })
+ notes=documents.notes([
+ documents.note("footnote", "4", [_paragraph_with_text("Who's there?")])
+ ])
)
result = convert_document_element_to_html(
document,
diff --git a/tests/docx/document_xml_tests.py b/tests/docx/document_xml_tests.py
index 8e2cb8d..a0d29b9 100644
--- a/tests/docx/document_xml_tests.py
+++ b/tests/docx/document_xml_tests.py
@@ -321,7 +321,7 @@ class ReadXmlElementTests(object):
document_xml = xml_element("w:document", {}, [body_xml])
document = _read_and_get_document_xml_element(document_xml, footnote_elements=footnotes)
- footnote = document.footnotes.find_footnote_by_id("4")
+ footnote = document.notes.find_note("footnote", "4")
assert_equal("4", footnote.id)
assert isinstance(footnote.body[0], documents.Paragraph)
@@ -329,7 +329,7 @@ class ReadXmlElementTests(object):
def footnote_reference_has_id_read(self):
footnote_xml = xml_element("w:footnoteReference", {"w:id": "4"})
footnote = _read_and_get_document_xml_element(footnote_xml)
- assert_equal("4", footnote.footnote_id)
+ assert_equal("4", footnote.note_id)
@istest
def ignored_elements_are_ignored_without_message(self):