agentleFS
dewildewil/claude-toolkit/skills/md-docx/SKILL.md

md-docx

Skill9 starsChanged 3 months agoMITView on GitHub

Собрать .docx из markdown, когда документ пойдет на правки: \"сделай docx\", \"нужен ворд\", \"отправь на вычитку\". Документ на чтение и рассылку - скилл `md-pdf`.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

Files
SKILL.md

md-docx

Конвертация markdown -> .docx без внешних зависимостей: .docx - это zip с XML, и скрипт собирает его сам через zipfile. Скрипт-эталон - scripts/md-docx.py (top-level папка scripts/ в корне проекта). Не нужны python-docx, pandoc и LibreOffice.

Разбор markdown общий с md-pdf: md-docx.py подтягивает md_to_html из соседнего scripts/md-pdf.py, поэтому оба скрипта должны лежать рядом - без md-pdf.py сборка docx остановится с сообщением об этом. Следствие удобное: контракт markdown у обоих форматов один, и правка разбора чинит сразу оба.

Когда НЕ применять

  • Документ идет на чтение и печать - причина брать PDF не только в формате: docx выглядит по-разному в разных версиях Word и LibreOffice, а получатель может случайно изменить текст.
  • Нужны колонтитулы с нумерацией страниц - в docx-ветке их нет, это умеет только PDF.
  • Нужна верстка сложнее нашего контракта - вложенные списки, выравнивание колонок, сноски, оглавление. Конвертер их не поддерживает намеренно; такому документу нужен не конвертер, а редактор.
  • Исходник не markdown - скилл собирает документ из md, а не конвертирует произвольные форматы.

Какой формат когда

Документ пойдетФорматПочему
на чтение, рассылку, печатьPDF (md-pdf)верстка фиксирована, открывается везде одинаково
на правки, вычитку, согласованиеdocx (md-docx)получатель правит прямо в файле, включает рецензирование, оставляет комментарии

Спрашивать пользователя, какой формат нужен, не надо, если это ясно из задачи ("на вычитку" -> docx, "отправить клиенту на согласование" -> docx, "распечатать" -> PDF). Неясно - спроси одной строкой.

CLI

python3 scripts/md-docx.py тз.md                       # тз.docx рядом с исходником
python3 scripts/md-docx.py тз.md --out /path/x.docx    # свой путь
python3 scripts/md-docx.py тз.md --title "Отчет"       # иначе первый H1, иначе имя файла
python3 scripts/md-docx.py тз.md --author "Имя"        # иначе DOC_AUTHOR, иначе DOCX_AUTHOR, иначе dwl

Оформление. Два необязательных флага, симметричных md-pdf.py - один markdown собирается в оба формата, поэтому интерфейс общий:

  • --photo <файл> - фото в правом верхнем углу первой страницы (--photo-width 30mm, --photo-height 38mm). Кадрируется по рамке, как object-fit: cover в PDF-ветке, а не вписывается с искажением пропорций - иначе форматы разъезжаются на глаз.
  • --separators - горизонтальные разделители: черта под заголовком секции (H2) и тонкая над должностью (H4). По умолчанию выключено: черта под каждым H2 уместна в резюме, но не в ТЗ и не в протоколе встречи.

Метаданные

Свойства файла проставляются всегда, без флагов - по правилу rules/document-metadata.md: автор (--author -> DOC_AUTHOR -> DOCX_AUTHOR -> dwl), заголовок, текущие даты создания и изменения; comments, keywords, category, subject пустые. Следов инструмента сборки в свойствах не остается - именно этот дефект (author: python-docx, дата 2013 г.) и породил правило.

Проверка после сборки - часть верификации артефакта:

python3 - <<'PY'
import zipfile, xml.etree.ElementTree as ET
z = zipfile.ZipFile("тз.docx")
print(z.read("docProps/core.xml").decode()[:400])
W = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"
d = ET.fromstring(z.read("word/document.xml"))
print("параграфов:", sum(1 for _ in d.iter(W+"p")), "таблиц:", len(list(d.iter(W+"tbl"))))
PY

Открывать Word для проверки не нужно. Проверка грубая, и читать ее надо правильно: если word/document.xml парсится и число w:tbl совпадает с числом таблиц в исходнике - структура собралась. Точный подсчет w:p со своим подсчетом блоков markdown не сверяй: в w:p попадают и заголовки, и пункты списков, и параграфы внутри ячеек, и служебный пустой параграф после каждой таблицы, так что число заведомо больше "числа абзацев" в бытовом смысле. Смысл счетчика - поймать явную потерю блока, а не сойтись цифра в цифру.

Что поддержано и что нет

Блоки кода из трех и более обратных кавычек или тильд используют общий разбор с md-pdf: отступ забора до трех пробелов, закрытие тем же символом не короче открывающего и без текста после него. Незакрытый блок идет до конца файла; язык после открывающего забора не меняет оформление. Содержимое выводится буквально абзацами стиля Code с моноширинным шрифтом, включая текущий завершающий пустой абзац.

Поддержано: заголовки H1-H4, абзацы с мягким переносом, списки маркированные и нумерованные (настоящие списки Word - получатель дописывает пункт, нумерация продолжается сама; каждый нумерованный список считается с единицы, а не сквозняком через документ), GFM-таблицы с рамками и жирной шапкой, цитаты, ---, **bold**, *italic*, `code`, fenced-блоки, ссылки настоящими гиперссылками, картинки (![alt](путь)) и фото в углу первой страницы (--photo).

Про картинки: встраиваются локальные файлы PNG, JPEG и GIF; формат определяется по сигнатуре файла, а не по расширению (.jpg с PNG внутри - обычное дело после пересохранения, а Word спотыкается на несовпадении). Ширина ужимается до полосы набора. Не встроилось (нет файла, ссылка в сеть, незнакомый формат) - в документ идет [alt]: сборка не падает, но получатель видит, что здесь была картинка. Одинаковые файлы кладутся в пакет один раз.

Не поддержано (осознанно):

  • Вложенные списки и выравнивание колонок - как и в PDF-ветке (контракт разбора общий).

Нужно больше - дорабатывай конвертер, а не меняй формат исходника.

Грабли

  • Контракт таблицы строгий и общий с md-pdf - нарушишь, и блок молча станет абзацем. Условия целиком перечислены один раз, в skills/md-pdf/SKILL.md, раздел "Грабли"; здесь не повторяются, чтобы копия не разошлась с оригиналом.
  • Существующий файл перезаписывается без вопросов (симметрично md-pdf.py). Документ мог быть правлен руками или собран иначе - перед перезаписью сделай копию в scratchpad сам.
  • Word не объясняет, что не так. Битый XML или ячейка таблицы без параграфа дают одно и то же "содержимое повреждено". Поэтому проверка структуры после сборки (см. выше) - не формальность; регресс-тесты на это в tests/test_md_docx.py.
  • Правки исходника после отправки. Получатель правит уже сам .docx, и следующая сборка из markdown его правки затрет. Отдал файл на вычитку - дальше источником истины становится он, а не md; либо переноси правки в markdown руками.

Специализация под проект

Регулярный документ со своим оформлением (шаблон ТЗ, фирменная шапка, реквизиты) - локальный скилл-обертка или скрипт в проекте поверх канонического. Сам md-docx остается generic: фирменный стиль и реквизиты в канон не тащить. Так же, как у md-pdf.

Скиллы-соседи по документам: md-pdf (PDF), csv-xlsx (таблицы Excel), md-pptx (презентации).

Модель и текущие назначения

Перед новым заданием и запуском применяй маршрутизацию моделей: свежий MODELS выше канонического дефолта. Границы данных и полномочий этого навыка сохраняются.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.