Проблема: Необходимо достоверно установить, подвергался ли текстовый документ изменению шрифта или форматирования, особенно если отсутствует история версий или включенное отслеживание изменений.

Причины:
1. Скрытое форматирование (Overriding Styles) — неявное изменение параметров абзаца или символа без маркировки.
2. Различия в метаданных шрифтов (Font metadata) — изменение названия шрифта, начертания, кегля, межстрочного интервала, зафиксированное во внутренней структуре файла.
3. Использование невидимых символов и полей (например, полей EQ для изменения регистра или скрытого форматирования через Word Open XML).

Решение:

1. Сравнение исходной и финальной версий через метаданные (для .docx/.odt)


Инструмент: `python-docx` + `xml.etree.ElementTree` (Python).

python
from docx import Document
import xml.etree.ElementTree as ET

def check_font_changes(docx_path1, docx_path2):
doc1 = Document(docx_path1)
doc2 = Document(docx_path2)

# Извлечение текста с тегами форматирования (w:rPr)
def get_runs_with_props(doc):
runs = []
for para in doc.paragraphs:
for run in para.runs:
# Парсинг XML для получения свойств шрифта
xml = run._element.xml
tree = ET.fromstring(xml)
ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
rpr = tree.find('.//w:rPr', ns)
runs.append({'text': run.text, 'rpr': ET.tostring(rpr, encoding='unicode') if rpr is not None else None})
return runs

runs1 = get_runs_with_props(doc1)
runs2 = get_runs_with_props(doc2)

# Сравнение по индексу или по тексту
for i, (r1, r2) in enumerate(zip(runs1, runs2)):
if r1['rpr'] != r2['rpr'] and r1['text'].strip():
print(f"Форматирование изменено на фрагменте: '{r1['text'][:40]}...'")
print(f"Было: {r1['rpr']}")
print(f"Стало: {r2['rpr']}")

check_font_changes('original.docx', 'modified.docx')


Результат: Выводит разницу в XML-свойствах шрифта (rFonts, sz, b, i, etc.).

2. Анализ скрытого форматирования через hex-дамп


Инструмент: `xxd` (Linux/Mac) или `Format-Hex` (PowerShell).

bash
<h2 id="sravnenie-binarnyh-uchastkov-otvechayuschih-za-stili">Сравнение бинарных участков, отвечающих за стили</h2>
xxd original.docx > orig.hex
xxd modified.docx > mod.hex
diff -y orig.hex mod.hex | less


Ключевые паттерны в hex:
- `rFonts` — изменение шрифта.
- `w:sz` / `w:szCs` — изменение кегля.
- `w:b` / `w:i` — включение/выключение жирности/курсива.

3. Проверка через Pandoc для выявления изменения форматирования в текстовых документах


Инструмент: `pandoc` (конвертирует в Markdown с сохранением свойств).

bash
pandoc original.docx -t markdown --wrap=none > original.md
pandoc modified.docx -t markdown --wrap=none > modified.md
diff original.md modified.md


Ограничение: Pandoc теряет часть CSS-подобных стилей, но фиксирует базовые изменения (полужирный, курсив, заголовки, моноширинный шрифт).

4. Выявление неявных изменений через сравнение стилей (Word OOXML)


Инструмент: Встроенный `zipinfo` + `grep` (работает на уровне XML).

bash
unzip -p original.docx word/document.xml > doc1.xml
unzip -p modified.docx word/document.xml > doc2.xml
<h2 id="poisk-tolko-izmeneniy-v-tegah">Поиск только изменений в тегах</h2>
grep -oP '.?' doc1.xml | sort > rprs1.txt
grep -oP '.?' doc2.xml | sort > rprs2.txt
diff rprs1.txt rprs2.txt


Если файл большой — используйте `vimdiff` для визуального сравнения XML.