Модуль mammoth
предназначен для преобразования документов .docx
, например, созданных в Microsoft Word, Google Docs и LibreOffice в HTML. Этот модуль стремится создавать простой и чистый HTML, используя семантическую информацию в документе и игнорируя другие детали. Например, mammoth
преобразует любой абзац со стилем Heading 1
в элементы <h1>
и не пытается точно скопировать стиль (шрифт, размер текста, цвет и т. д.) заголовка.
Существует большое несоответствие между структурой, используемой в .docx
, и структурой HTML, а это означает, что преобразование вряд ли будет идеальным для более сложных документов. Модуль mammoth
работает лучше всего, если в документе Microsoft Word, стили используются только для семантической разметки.
В настоящее время поддерживаются следующая разметка .docx
:
.docx
в HTML. Например, можно преобразовать заголовок WarningHeading
в h1.warning
, предоставив соответствующее сопоставление стилей.mammoth
в виртуальное окружение:# создаем виртуальное окружение $ python3 -m venv .venv --prompt VirtualEnv # активируем виртуальное окружение $ source .venv/bin/activate # ставим модуль mammoth (VirtualEnv) :~$ python3 -m pip install mammoth --upgrade
DOCX
в HTML в командной строке;DOCX
в HTML в коде Python;DOCX
в HTML в командной строке.Чтобы преобразовать DOCX
-файлы в HTML, используя командную строку, необходимо команде mammoth
передать путь к файлу с расширением .docx
и указать выходной файл. Например:
$ mammoth document.docx output.html
Если выходной файл не указан, то выходные данные записываются в стандартный вывод сонсоли.
Результатом является HTML-фрагмент в кодировке UTF-8, а не полный HTML-документ. Так как кодировка явно не задана в HTML-фрагменте, то открытие выходного файла в веб-браузере может привести к неправильному отображению символов Unicode, если браузер по умолчанию не использует UTF-8.
DOCX
.По умолчанию изображения включаются в выходной HTML-код. Если указан выходной каталог параметром --output-dir
, то изображения записываются в указанную папку в отдельные файлы (очень удобно для извлечения изображений из документа DOCX
). Например:
$ mammoth document.docx --output-dir=img-dir
Существующие файлы будут перезаписаны, если они есть.
Пользовательскую карту стилей можно прочитать из файла с помощью параметра --style-map
. Например:
$ mammoth document.docx output.html --style-map=custom-style-map.txt
Где custom-style-map.txt
- текстовый файл с описанием пользовательских стилей выглядит примерно так:
p[style-name='Aside Heading'] => div.aside > h2:fresh p[style-name='Aside Text'] => div.aside > p:fresh
Описание синтаксиса для составления карт стилей можно посмотреть в разделе "Написание пользовательских карт стилей".
DOCX
в HTML в коде Python.Чтобы преобразовать существующий файл .docx
в HTML, необходимо передать файлоподобный объект в функцию mammoth.convert_to_html()
. Файл должен быть открыт в бинарном режиме. Например:
import mammoth with open("document.docx", "rb") as docx_file: result = mammoth.convert_to_html(docx_file) # сгенерированный HTML html = result.value # предупреждения во время конвертации messages = result.messages
Также можно извлечь необработанный текст документа с помощью функции mammoth.extract_raw_text()
. Эта функция игнорирует все форматирование в документе. За каждым абзацем следует две новые строки.
with open("document.docx", "rb") as docx_file: result = mammoth.extract_raw_text(docx_file) # Необработанный текст text = result.value # предупреждения во время конвертации messages = result.messages # Any messages
mammoth.convert_to_html(fileobj, **kwargs)
:Функция mammoth.convert_to_html()
преобразует исходный документ DOCX в HTML.
Принимаемые аргументы:
fileobj
: файлоподобный объект, содержащий исходный документ. Файлы должны открываться в двоичном режиме.style_map
: строка, задающая отображение стилей Word в HTML. Описание синтаксиса приведено в разделе "Написание пользовательских карт стилей".include_embedded_style_map
: по умолчанию, если документ содержит встроенную карту стилей, то она объединяется с картой стилей по умолчанию. Чтобы игнорировать любые встроенные карты стилей, передайте include_embedded_style_map=False
.include_default_style_map
: по умолчанию карта стилей, переданная в style_map
, объединяется с картой стилей по умолчанию. Чтобы полностью отказаться от использования карты стилей по умолчанию, передайте include_default_style_map=False
.convert_image
: по умолчанию изображения преобразуются в элементы <img>
с указанием источника, встроенного в атрибут src
. Установите этот аргумент в значение конвертера изображений, чтобы переопределить поведение по умолчанию.ignore_empty_paragraphs
: по умолчанию пустые абзацы игнорируются. Установите для этого параметра значение False
, чтобы сохранить пустые абзацы в выходных данных.id_prefix
: строка, добавляемая к любым сгенерированным идентификаторам, таким как те, которые используются закладками, сносками и концевыми примечаниями. По умолчанию используется пустая строка.Возвращает результат со следующими свойствами:
value
: сгенерированный HTML;messages
: любые сообщения, такие как ошибки и предупреждения, сгенерированные во время преобразования.Каждое сообщение messages
имеет следующие свойства:
type
: строка, представляющая тип сообщения, например "warning"
.messages
: строка, содержащая фактическое сообщение.По умолчанию модуль mammoth
сопоставляет некоторые общие стили .docx
с элементами HTML. Например, абзац с названием стиля Heading 1
преобразуется в элемент <h1>
. Можно передать пользовательскую карту стилей, в качестве второго аргумента style_map
функции mammoth.convert_to_html()
. Допустим, что необходимо преобразовать абзацы с названием стиля Section Title
в элементы <h1>
, а абзацы с названием стиля Subsection Title
в элементы <h2>
:
import mammoth style_map = """ p[style-name='Section Title'] => h1:fresh p[style-name='Subsection Title'] => h2:fresh """ with open("document.docx", "rb") as docx_file: html = mammoth.convert_to_html(docx_file, style_map=style_map)
Пользовательские сопоставления style_map
будут использоваться вместо сопоставлений стилей по умолчанию. Чтобы вообще отказаться от сопоставления стилей по умолчанию, передайте третий ключевой аргумент include_default_style_map=False
:
html = mammoth.convert_to_html(docx_file, style_map=style_map, include_default_style_map=False)
Описание синтаксиса для составления карт стилей можно посмотреть в разделе "Написание пользовательских карт стилей".
mammoth.embed_style_map(fileobj, style_map)
:Функция mammoth.embed_style_map()
встраивает карту стилей style_map
в файл fileobj
. Когда mammoth
читает файловый объект, он будет использовать встроенную карту стилей (т.е. дополнительно передавать ее аргументом style_map
в функцию mammoth.convert_to_html
уже будет не надо).
Принимаемые аргументы:
fileobj
: файлоподобный объект, содержащий исходный документ. Файлы должны быть открыты для чтения и записи в двоичном режиме.style_map
: карта стилей для встраивания.Возвращает None
.
По умолчанию полужирный текст заключен в теги <strong>
. Это поведение можно изменить, добавив отображение стиля для b
. Например, чтобы заключить полужирный текст в теги <em>
:
style_map = "b => em" with open("document.docx", "rb") as docx_file: result = mammoth.convert_to_html(docx_file, style_map=style_map)
По умолчанию текст, выделенный курсивом, заключен в теги <em>
. Это поведение можно изменить, добавив сопоставление стилей для i
. Например, чтобы поместить текст, выделенный курсивом, в теги <strong>
:
style_map = "i => strong" with open("document.docx", "rb") as docx_file: result = mammoth.convert_to_html(docx_file, style_map=style_map)
По умолчанию подчеркивание любого текста игнорируется, поскольку подчеркивание можно спутать со ссылками в HTML-документах. Это поведение можно изменить, добавив сопоставление стилей для u
. Например, предположим, что в исходном документе для выделения используется подчеркивание. Код ниже любой явно подчеркнутый исходный текст заключает в теги <em>
:
style_map = "u => em" with open("document.docx", "rb") as docx_file: result = mammoth.convert_to_html(docx_file, style_map=style_map)
По умолчанию зачеркнутый текст заключен в теги <s>
. Это поведение можно изменить, добавив сопоставление стилей для strike
. Например, чтобы обернуть зачеркнутый текст в теги <del>
:
style_map = "strike => del" with open("document.docx", "rb") as docx_file: result = mammoth.convert_to_html(docx_file, style_map=style_map)
По умолчанию комментарии игнорируются. Чтобы включить комментарии в сгенерированный HTML-код, добавьте сопоставление стилей для comment-reference
. Например:
style_map = "comment-reference => sup" with open("document.docx", "rb") as docx_file: result = mammoth.convert_to_html(docx_file, style_map=style_map)
Комментарии будут добавлены в конец документа со ссылками на комментарии, обернутыми с использованием указанного сопоставления стилей.
По умолчанию изображения преобразуются в элементы <img>
с включенным источником в атрибут src
. Это поведение можно изменить, задав для аргумента convert_image
значение конвертера изображений.
Например, следующий код будет воспроизводить поведение по умолчанию:
def convert_image(image): with image.open() as image_bytes: encoded_src = base64.b64encode(image_bytes.read()).decode("ascii") return { "src": f"data:{image.content_type};base64,{encoded_src}" } with open("document.docx", "rb") as docx_file: mammoth.convert_to_html(docx_file, convert_image=mammoth.images.img_element(convert_image))
Конвертер изображений по умолчанию mammoth.images.data_uri
.
Конвертер изображений можно создать, вызвав mammoth.images.img_element(func)
. Это создаст элемент <img>
для каждого изображения в исходном .docx
файле. Аргумент func
должен быть функцией, принимающей один аргумент image
. Этот аргумент является преобразуемым элементом изображения и обладает следующими свойствами:
open()
: открывает файл изображения. Возвращает файлоподобный объект.content_type
: возвращает тип содержимого изображения, например image/png
.Функция func
должна возвращать список атрибутов для элемента <img>
. Как минимум, это должно включать атрибут src
. Если для изображения будет найден какой-либо альтернативный текст, он будет автоматически добавлен к атрибутам элемента.
Обратите внимание, что изображения WMF по умолчанию не обрабатываются модулем
mammoth
.
Карта стилей состоит из сопоставлений стилей, каждая из которых начинается с новой строки. Пустые строки и строки, начинающиеся с #
, игнорируются.
Отображение стиля состоит из двух частей:
При преобразовании каждого абзаца mammoth
находит первое сопоставление стилей, в котором средство сопоставления элементов документа соответствует текущему абзацу. Затем mammoth
гарантирует, что HTML-тег будет удовлетворен.
При написании сопоставлений стилей полезно понимать "свежесть" HTML-элемента. При генерации HTML mammoth
закроет HTML-тег только при необходимости. В противном случае элемент используются повторно.
Например, предположим, что одним из указанных сопоставлений стилей является p[style-name='Heading 1'] => h1
. Если mammoth
встречает абзац в .docx
с названием стиля Heading 1
, то абзац .docx
преобразуется в элемент <h1>
с тем же текстом. Если следующий абзац в .docx
также имеет название стиля Heading 1
, то текст этого абзаца будет добавлен к существующему тегу <h1>
, и не приведет к созданию нового HTML-элемента <h1>
.
В большинстве случаев, необходимо будет сгенерировать новый элемент h1
. Это можно сделать с помощью модификатора :fresh
:
p[style-name='Heading 1'] => h1:fresh
Два последовательных абзаца с Heading 1
будут преобразованы в два отдельных элемента h1
.
Повторное использование элементов полезно при создании более сложных HTML-структур. Например, предположим, что файл .docx
содержит отступы aside
. У каждого отступа aside
может быть заголовок и некоторый основной текст, которые должны содержаться в пределах одного элемента div.aside
. В этом случае могут быть полезны сопоставления стилей, подобные:
p[style-name='Aside Heading'] => div.aside > h2:fresh # и p[style-name='Aside Text'] => div.aside > p:fresh
p =>
- совпадение с любым абзацем;r =>
- совпадение с любым прогоном;table =>
- совпадение с любой таблицей;Использование в карте стилей:
# обернет абзац в <div>...</div> p => div # обернет абзац в <p>...</p> p => p # обернет прогон в <span>...</span> r => span
Чтобы сопоставить абзац, прогон или таблицу с определенным стилем документа DOCX, можно сослаться на стиль по имени. Это название стиля, которое отображается в Microsoft Word или LibreOffice. Например, чтобы сопоставить абзац с названием стиля Heading 1
:
p[style-name='Heading 1'] => h1
Можно также сопоставить имя стиля по префиксу. Например, чтобы соответствовать абзацу, имя стиля которого начинается с Heading
:
p[style-name^='Heading'] => h1
На стили также можно ссылаться по идентификатору стиля. Это идентификатор, используемый внутри файла .docx
. Чтобы сопоставить абзац или текст с определенным идентификатором стиля, нужно добавить точку, за которой следует идентификатор стиля. Например, чтобы сопоставить абзац с идентификатором стиля Heading1
:
p.Heading1 => h1
Обратите внимание, что нижеперечисленные индификаторы соответствуют только тексту, к которому явно применен жирный (курсив, подчеркнутый и т.д.) шрифт. Он не будет соответствовать тексту, который помещен в абзац или прогон со стилем - жирный (курсив, подчеркнутый и т.д.).
b =>
- соответствует явно выделенному жирным шрифтом тексту;i =>
- соответствует явно выделенному курсивом тексту;u =>
- соответствует c явно подчеркнутым текстом;strike =>
- соответствует с явно зачеркнутым текстом;all-caps =>
- соответствует со всеми заглавными буквами текста;small-caps =>
- соответствует с явно маленькими заглавными буквами;p[style-name='Comment'] => !
- !
игнорирует элемент документа. Например, чтобы игнорировать любой абзац со стилем Comment
.Смотрите примеры использования модификаторов выше, в "Изменение стилей документа Bold, Italic, Underline и т.д. в выходном HTML"
Самый простой путь преобразовать совпадение - это указать один HTML-элемент. Например, чтобы указать элемент:
`p.Heading1 => h1`
Чтобы присвоить элементу класс CSS, необходимо добавить точку, за которой следует название класса:
p.Heading1 => h1.section-title
Модификаторы должны использоваться в правильном порядке:
p[style-name^='Heading'] => h1.section-title:fresh
Чтобы указать разделитель для размещения между содержимым абзацев, которые свернуты вместе, необходимо использовать :separator('SEPARATOR STRING')
.
Например, предположим, что документ содержит блок кода, где каждая строка кода представляет собой абзац со стилем Code Block
. Можно написать сопоставление стилей для сопоставления таких абзацев с элементами <pre>
:
p[style-name='Code Block'] => pre
Поскольку <pre>
не помечен как :fresh
, то последовательные элементы <pre>
будут свернуты вместе. Однако это приводит к тому, что весь код находится в одной строке. Можно использовать :separator
для вставки новой строки между каждой строкой кода:
p[style-name='Code Block'] => pre:separator('\n')
Для указания вложенных HTML элементов необходимо использовать >
. Например, чтобы указать h2
внутри div.aside
:
p[style-name^='Heading2'] => div.aside > h2
Можно вкладывать элементы на любую глубину.