Unstructuredunstructured 0.27.6 · Python 3.11+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
21 small wins to finish your pathNext lesson

Email, Word and PowerPoint

Three formats that are not plain text at all, and all three come back through the same call with the same kind of elements.

The handbook needs two Office documents and nothing in this course ships a binary file you cannot read. This twelve line script builds both of them.

python
from docx import Document
from pptx import Presentation
doc = Document()
doc.add_heading("Returns", 1)
doc.add_paragraph("You can return an item within 30 days of delivery.")
doc.add_paragraph("The item must be unused.", style="List Bullet")
doc.save("returns.docx")
deck = Presentation()
slide = deck.slides.add_slide(deck.slide_layouts[1])
slide.shapes.title.text = "Q3 support review"
slide.placeholders[1].text = "Refund requests fell to 2 percent of orders."
deck.save("q3.pptx")

It writes a Word file with a heading, a paragraph and a bullet, and a one slide deck with a title and a line of text. Importing it runs it.

The Word document

Example
import make_office
from unstructured.partition.auto import partition

for element in partition("returns.docx"):
    print(element.category, "|", element.text)

The heading is a Title, the paragraph is NarrativeText and the bullet is a ListItem. The labels come from the Word styles rather than from the ladder in lesson 5, which is why Returns is a heading here and Thanks! was a heading in a text file for a much worse reason.

The slide deck

Example
import make_office
from unstructured.partition.auto import partition

for element in partition("q3.pptx"):
    print(element.category, "| page", element.metadata.page_number,
          "|", element.text)

A slide is a page, so both elements carry page_number 1. That is the first of the six handbook documents to fill that field in, and it is what lets a citation say which slide an answer came from.

The email

Email needs no extra at all; it is handled by the base package. What it adds is the headers, which lesson 6 already showed as metadata.

Example
from unstructured.partition.auto import partition

elements = partition("ravi.eml")
for element in elements:
    print(element.category, "|", element.text)
print(elements[0].metadata.subject)

The headers did not become elements. They are metadata on every element of the message, and the elements are the body. The documentation mentions an include_headers argument that brings them back as elements. It is not a parameter of partition_email in this version, and because every partitioner accepts **kwargs, passing it raises nothing and changes nothing. The headers are in the metadata or they are nowhere.

Outlook's own .msg format is a different partitioner behind the msg extra, which is installed here. The older .doc and .ppt formats are handled by converting them with LibreOffice first, so they need soffice on your path.
Try it yourself
  • Add a second slide to make_office.py and check the page numbers.
  • Add a table to the Word document with doc.add_table and see what element it becomes.
  • Print metadata.sent_from for every element of the email.

Slow is fine. Stopping is the only problem.