惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
O
OpenAI News
Cloudbric
Cloudbric
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
J
Java Code Geeks
Help Net Security
Help Net Security
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
Security Archives - TechRepublic
Security Archives - TechRepublic
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
人人都是产品经理
人人都是产品经理
H
Help Net Security
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
Jina AI
Jina AI
S
Security @ Cisco Blogs
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
TaoSecurity Blog
TaoSecurity Blog
MongoDB | Blog
MongoDB | Blog
WordPress大学
WordPress大学
F
Fortinet All Blogs
S
Securelist
M
MIT News - Artificial intelligence
V
Vulnerabilities – Threatpost
小众软件
小众软件
T
Tenable Blog
Y
Y Combinator Blog
T
Threat Research - Cisco Blogs
博客园 - 叶小钗
N
News | PayPal Newsroom
A
About on SuperTechFans
C
CERT Recently Published Vulnerability Notes
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Разбор реализации docs-as-code на базе Sphinx
shkvk (InfoW · 2026-05-08 · via Все публикации подряд на Хабре

Привет, Хабр! Меня зовут Артём Зеленкин, приятно познакомиться! Я работаю техническим писателем около 20 лет, сейчас занимаюсь документированием в подразделении ARMA компании Infowatch. Для создания и поддержки актуальности документации по продуктам линейки ARMA мы используем docs-as-code. Что из этого получается, можно посмотреть на сайте с документацией (там же можно скачать pdf-версию, чтобы сравнить, как оно выглядит в разных форматах при тех же исходных данных).

В данной статье я не пытаюсь рассказать, что такое docs-as-code (думаю, статей по теме достаточно), а рассказываю, как этот принцип реализован у нас. Может, вам тоже пригодится.

Чтобы сэкономить ваше время, сначала потрачу его, добавив ниже краткое описание параграфов. Всё-таки это не научная статья, поэтому не обязательно читать целиком.

  • «История» — лично-историческая часть, которую можно было не писать, но с неё всё началось. Полезно для понимания контекста.

  • «Процессы» — подход к документированию в команде и что можно найти общего в работе техписа по docs-as-code с работой программиста

  • «Технические моменты» — немного наблюдений по процессу установки и настройки Sphinx, структуре проекта и работе с reStructuredText, а ещё тут я разбираю небольшой пример. Выполнив эти несколько простых шагов, вы сможете добавить в резюме «Опыт работы с docs-as-code». Наверное

  • «На прощание» — небольшое заключение

История

Начну с начала. С начала 2025 года, когда мне повезло приступить к работе в техническом департаменте ARMA компании Infowatch. Кроме обязательных задач по документированию, мне регулярно напоминали, что у меня есть замечательная возможность написать статью на Хабр. Компания поощряет хабротворчество, поэтому это и правда была возможность. Но я всё откладывал и откладывал. Всё-таки, Хабр открытая площадка, которую посещают разные люди, и не факт, что кому-то зайдёт мой стиль, или сама реализация, или ещё чего. Я делаю документацию и никого не трогаю. А ещё трудно описать что-то, с чем только начинаешь знакомиться. А вдруг я не так понял? А вдруг это очевидно и поэтому не стоит упоминания? Или наоборот, всё будет настолько сложно, что я не смогу объяснить? Вот в документации всё чётко. Понятно, для кого и чего мы её пишем (для комплекта поставки, шутка... да?). Всё ещё не решил, вырезать рефлексию из статьи или нет. Если вы это читаете, значит, решил оставить… или забыл убрать, и ревьюеры забыли… Раз есть, значит так надо.

Справедливости ради, Sphinx и reStructuredText (rst) я уже знал. Правда, предыдущий опыт был неудачным, на одном из прошлых мест работы внедряли связку doxygen-sphinx, но, во-первых, то была внутренняя документация, а, во-вторых, не взлетело. Технически оно работало, но документировать подробными комментариями не зашло команде (интересно, почему? 😊). А rst не помню, где встречал, все языки разметки плюс-минус одинаковые, так что может по этому было легко.

В любом случае именно с docs-as-code я столкнулся впервые. Всегда хотел быть программистом, но не смог в абстрактное мышление и стал техписом. А тут всё как у

взрослых

программистов: есть репозиторий, построчно правим исходники, собираем локально для проверки, коммитим, пушим, можно делать ревью, ребейзить, черри-пикать, сташить и другие умные слова. В общем docs-as-code — любовь с первого взгляда. Больше не хочу делать документацию никак иначе (а придётся, эту вот статью я начал писать конечно же в ворде, — для разных задач разные инструменты, да и статейки на Конфлюенс тоже приходится писать, но это другое).

Тут же я «пришёл» на своё удалённое рабочее место, прочитал пару инструкций, выслушал несколько советов, настроил окружение и… всё. Работаю по docs-as-code больше года. И сейчас попробую рассказать как.

Процессы

Для меня docs-as-code — это не только sphinx и git, но и то, как мы работаем с текстом в рамках задачи по разработке, когда документация — это часть продукта наряду с его функциональностью, так что и дорабатывается она так же.

Как это выглядит в общем процессе разработки (упрощённо):

  1. Разработчик (или несколько) сверяется с аналитикой и делает реализацию.

  2. Собирается тестовый стенд.

  3. QA сверяется с аналитикой и здравым смыслом, тестирует задачу в целом, если всё в порядке, передает на документирование.

  4. Технический писатель сверяется с аналитикой, смотрит реализацию, вносит правки в документацию.

  5. Документация собирается на тестовом (внутреннем) стенде.

  6. QA проверяет соответствие документации, реализации и аналитики (для облегчения нагрузки на QA можно проверять документацию в рамках регрессионного тестирования и только по произошедшим изменениям, т.е. без полной вычитки).

Замечаете сходство? Воооот. Специалисты вносят построчные изменения в исходники, затем может быть локальная сборка для самотестирования и/или передача в тестирование, после которого всё сливается в основную ветку (aka master), и на выходе получаем работающий продукт с приростом функциональности и полную документацию с учётом этого прироста. Есть ли ценность этой схожести процессов, или это просто забавный факт?

Ценность есть. Во-вторых, техпис, работающий с подобным инструментарием, чуть лучше понимает разработчиков, а во-первых, подход docs-as-code унаследовал от разработки ПО много полезного:

  1. Размер репозитория — это сумма изменений (с рисунками, к сожалению, не работает, но всё равно это проще, чем хранить все версии сборок).

  2. Все правки абсолютно прозрачны, мы знаем, кто, когда и что поменял (и даже почему, если коммит-сообщение толковое).

  3. Можно откатиться на любое из прошлых состояний (например, чтобы собрать оттуда предыдущую версию документации).

  4. Несколько «разработчиков документации» могут работать в одном репозитории (при этом разрешение конфликтов для человекочитаемого текста намного проще, чем для кода).

  5. Сборка итоговых документов производится на основании заданных параметров, что убирает человеческий фактор при верстке.

  6. Техпис работает в тех же инструментах, что и разработка. Девопсам и админам не нужно подстраиваться к особенностям специализированного ПО, так как хранение, сборка документации и выкладывание её в общий доступ являются достаточно обычной задачей (не обязательно простой, есть нюансы, спасибо нашим админам, что всё это подняли и поддерживают, но это не какое-то специализированное ПО, с которым без стековефлоу не разобраться).

  7. Результат доступен сразу после сборки — онлайн (удобно обсуждать документацию, зная, что все видят одну и ту же версию).

  8. Можно разнообразить рабочие процессы использованием функционала Git.

Всё это происходит в рамках одной задачи на разработку, где документирование является завершающим этапом разработки, а не чем-то дополнительным. В итоге меньше планирования, согласований и просто меньше задач.

Релизная документация собирается как итог мелких изменений по задачам. Закончили разработку — документация готова (есть правки по замечаниям на регрессе и нюансы с оформлением, но это часть работы, не отменяющая преимуществ подхода).

Что до комфорта конкретного технического писателя, то очень удобно добавлять мелкие правки, не прорабатывая весь документ, ведь по некоторым продуктам пакет документации насчитывает сотни страниц.

Минусы? Они есть:

  1. В сравнении с WYSIWYG-редакторами верстка ограничена общим стилем сборки, подвигать каждый абзац и подогнать страницы и оформление в реальном времени не получится, про рамки ГОСТ страшно даже думать. И если не удаётся идеально подобрать и настроить стиль, приходится дорабатывать итоговый документ руками.

  2. В сравнении с разработкой ПО нет автоматического тестирования. Всё нужно проверять глазами. Но это относится к любой пользовательской документации и docs-as-code не решает эту проблему полностью, хотя сильно облегчает вычитку изменений.

Возможно, я не заметил какие-то другие минусы, но общее впечатление от подхода у меня крайне положительное. Чего и вам желаю!

Технические моменты

Подготовка

Есть инструкция https://sphinx-ru.readthedocs.io/archive/win-sphinx.html . Она частично устарела, но всё равно полезна для старта. На что стоит обратить внимание:

  1. Мне пришлось добавить путь до директории Scripts в переменные окружения системы. По умолчанию этого не произошло и команды не опознавались.

  2. Чтобы что-то собрать из rst, Git (https://git-scm.com/install/windows) не нужен, но я не представляю, как можно использовать docs-as-code без системы управления версиями. В данной статье рассмотрим локальную сборку. Использование гитлаба и подобных систем не отличается от использования их для работы с кодом.

  3. После окончания базовой установки можно смело добавить ещё пару модулей:

    • Тема. Визуальный стиль онлайн-документации определяется темой. Если возьмём популярную Read The Docs, нужно её установить — pip install sphinx_rtd_theme. Тему можно допилить под себя или поменять на другую. Используемая тема задаётся в конфигурационном файле conf.py, вернусь к этому позже.

    • Чтобы собирать документы в формате docx, устанавливаем расширение docxbuilder (https://docxbuilder.readthedocs.io/en/latest/docxbuilder.html ). Команда: pip install docxbuilder. Использование расширений тоже задаётся через conf.py.

  4. Озаботиться наличием какого-нибудь редактора для исходных файлов. Я использую VS Code (взять можно или из MS Store, или из https://code.visualstudio.com/). Для него даже были плагины, позволяющие видеть, как будет выглядеть текст после сборки, но они устарели, ничего другого найти не удалось, и я привык предвидеть, как оно будет выглядеть после сборки. Чем дольше так работаешь, тем легче и точнее просто работать в rst (что не отменяет проверку после сборки, чтобы ничего не съехало).

На этом подготовка закончена, можно создавать структуру файлов. Самый простой способ начать — это использовать команду sphinx-quickstart, находясь в каталоге документации. Нужно будет ответить на несколько вопросов, и в результате сформируется минимальная структура. Что до самих вопросов, то для ознакомительных целей принципиальной разницы нет, но могу отметить, что мне лично комфортнее разделять каталоги исходников и сборки (ответ «y» на первый вопрос), а выбор языка определяет текст элементов интерфейса и не имеет прямого отношения к языку проекта.

Допустим, мы создали директорию docs любым удобным способом и внутри неё хотим выполнить команду. Для этого директорию нужно открыть в Командной строке или PowerShell Windows (например, выбрать «Открыть в Терминале» по правой кнопке мыши).

Выполняем sphinx-quickstart и в результате сформируется следующая структура:

docs
└── build
| └── html (каталог появится после сборки)
| ├── ...
| └── index.html (корневая страница собранной документации)
└── source
| ├── _templates (место для каких-то шаблонов, но мы их не используем)
| ├── _static (файлы, не являющиеся исходным кодом, например, картинки)
| ├── conf.py (конфигурационные параметры Sphinx для этого проекта)
| └── index.rst (корневой файл проекта, от него собирается остальная структура)
├── make.bat (командный файл, для сборки через команду make, но мы используем sphinx-build, поэтому можно удалить, чтобы не смущало)
└── Makefile (инструкции для сборки командой make, тоже не обязательно, в нашем случае)

Интересными являются файлы conf.py и index.rst, разберём их подробнее.
conf.py

Если пропустить все закомментированные строки, а также информацию о проекте, то окажется, что собственно конфигурация — это всего несколько строк, большинство из которых можно не трогать. В нашем проекте мы потрогали:

  1. extensions = [ ] — здесь задействуются расширения. Например, вышеупомянутый docxbuilder, чтобы выгружать docx-файлы. Выглядит это вот так: extensions = ['docxbuilder']

Если планируете использовать документ-шаблон, его можно добавить через параметр docx_style = 'имя_файла_шаблона.docx', через шаблон можно задать форматирование, стили, титульный и так далее. Но это уже вордовская тема.

  1. html_theme = 'alabaster' — выбор визуальной темы. Вместо дефолтной 'alabaster' можно поставить Read The Docs, вот так: html_theme = 'sphinx_rtd_theme'

Вот и вся конфигурация. Теперь перейдём собственно к документации.

index.rst — это уже rst-формат, и наполнение файла должно соблюдать синтаксис языка разметки reStructuredText. Кратко о языке тут: Стандартный синтаксис разметки reStructuredText — Генератор документации Sphinx 1.0 documentation (sphinx-ru.readthedocs.io). Дополнительно используется разметка от самого Sphinx, кратко тут: Конструкции разметки Sphinx — Генератор документации Sphinx 1.0 documentation (sphinx-ru.readthedocs.io). Чтобы не погружаться в детали, разберём пример построчно.

Если убрать комментарии из полезного в файле, останется вот это:

Название проекта

=================

 

.. toctree::

   :maxdepth: 2

   :caption: Contents:

Текст над линией из «=» заголовок всей документации. В rst «=» показывает заголовок первого уровня (для каждого уровня своё).

Структура под .. toctree:: позволяет задать подраздел документации, где :maxdepth: указывает уровень вложенности содержания, а :caption: заголовок содержания (может быть несколько содержаний, именно так сделано у нас https://docs.iwarma.ru/, где на одной странице собрана документация по нескольким продуктам).

Разбор примера

Прежде чем разбирать правки по этапам, давайте соберём пустой проект.

Для этого откроем директорию docs в Командной строке или PowerShell Windows и выполним команду:

sphinx-build -b html source build/html ,

где sphinx-build – собственно, команда;
-b – параметр сборки. -b обычная сборка. Ещё можно использовать -M, чтобы имитировать make-сборку;
html – тип сборки (если захотим собрать, например, вордовский документ, здесь будет docx);
source – путь до каталога исходных текстов (так как выполняем команду из родительского каталога, можно указать имя, но можно использовать и полный путь, хоть от c:\);
build/html – аналогично путь до каталога, где будет формироваться результат сборки документации.

Чтобы открыть собранную документацию, переходим в build, там в html и открываем index.html

Если ранее в conf.py включили тему Read The Docs, получим примерно такое:


Если тема другая, внешний вид будет отличаться, но наполнение будет таким же. Правда, вы упустите приятную (для начинающих) особенность темы — ссылку «Посмотреть исходный код страницы» в правом верхнем углу.

Как я уже упоминал, использование docs-as-code без контроля версий я себе плохо представляю. Поэтому создадим репозиторий:

  1. Правой кнопкой на каталог source

  2. Выбрать Open git bash here

  3. git init

В каталоге появится набор файлов Git (скорее всего, скрытых от пользователя), но нас интересует только пара файлов, состояние которых хотим отслеживать с помощью Git. Это всё те же conf.py и index.rst. Добавим их в репозиторий:

git add --all

(можно было «git add .» или ещё чего, но в «--all» наглядности больше)

И теперь:

git commit -m "Начальное состояние проекта"

Готово. У нас есть репозиторий с некоторым базовым состоянием.

Не закрывайте окно git bash, оно нам ещё пригодится.

Теперь можно перейти к созданию текста. Ничего не мешает добавить текст прямо в index.rst, хотя для сложных проектов это не очень удобно. У нас тут проект минимальный, так что добавим текст прямо под заголовком проекта. Например,  «Съешь же ещё этих мягких французских булок, да выпей чаю», так как люблю набирать панграммы на клавиатуре. Каждому своё. Не забудьте сохранить изменения.

Повторим сборку sphinx-build -b html source build/html (мы уже дважды выполняем эту команду, и дальше будем, так что для кого-то может быть удобно создать и использовать пакетный bat-файл).

Открываем index.html и видим, что поменялось.

Если результат нас устраивает, можно добавить изменения в репозиторий:

git add index.rst
git commit -m "Добавлен текст про булки"

Мы добавили второй коммит, и благодаря Git мы сможем отменить изменения, посмотреть, что было добавлено, переключиться на состояние конкретного коммита и многое другое, что делается при работе в репозитории, например, с программным кодом. Люблю эту тему, но не хочу зависать на работе с Git, поэтому движемся дальше.

Я бы сказал, что для первого знакомства с docs-as-code этого достаточно, но не скажу, а отмечу ещё пару-тройку моментов:

  1. Создание структуры документации, когда кроме заглавной страницы существуют подразделы.

  2. Добавление рисунков и ссылок.

  3. Сборка в docx и публикация вовне.

Подразделы

Когда выше разбирали файл index.rst , подразделы показывались там в блоках toctree. Позже мы имели возможность убедиться, что эти блоки никак не отражаются в итоговом тексте. Действительно, что бы вы ни писали в toctree, оно не имеет смысла, пока там нет ссылки на подраздел. Что ж, давайте создадим подраздел.

В директории source создадим директорию, скажем, chapters, а внутри неё создадим файл chapter_1.rst
(чтобы создавать файлы с расширением rst из Проводника Windows, может понадобиться включить отображение расширений файлов)

В chapter_1.rst добавим какой-нибудь текст, например:
«Эй, жлоб! Где туз? Прячь юных съемщиц в шкаф.»

Обратите внимание (а если хочется – проверьте), хотя в проекте есть файл с текстом, он не попадёт в сборку, пока не будет упомянут в «вышестоящем» файле (в нашем случае это index.rst).

Откроем index.rst и в разделе toctree под строкой caption добавим:

chapters/chapter_1

Здесь расширение rst указывать не обязательно, а вот отступ от края обязательно должен соответствовать вложенным строкам toctree, чтобы sphinx понял, что это не просто случайный текст:

.. toctree::

   :maxdepth: 2

   :caption: Раздел документации:

 

   chapters/chapter_1

Если теперь собрать sphinx-build -b html source build/html, как мы делали ранее, текст попадёт в документацию (чтобы его увидеть, придётся нажать кнопку «Следующая» в правом нижнем углу), но он не отобразится в дереве страниц слева (кроме того, при сборке будет несколько красных сообщений о ссылке на документ без заголовка).

Чтобы это исправить, добавим в начало файла chapter_1.rst заголовок:

Панграмма
==========

И повторим sphinx-build -b html source build/html.

Теперь ссылка на подраздел должна появиться в структуре слева.

Не забываем добавлять изменения в репозиторий:

git add index.rst
git add chapters/chapter_1.rst
git commit -m "Добавлена ещё одна панграмма"

Тут читатель, не привыкший к Git с рождения, подумает: «А нет ли другого интерфейса для выполнения рутинных операций?». Конечно! Кто-то любит fork, кто-то tortoise, а кто-то и встроенным Git GUI пользоваться умеет, но это уже дело вкуса.

Рисунки и ссылки

Разумеется, ссылаться на разделы можно не только через toctree. Да и не только на разделы, а и на другие элементы. Разберем всё это на пример добавления рисунка, так как в rst все ссылки работают схожим образом.

Для начала найдём какой-нибудь файл с изображением, которое мы хотим добавить в текст. В рабочих проектах используем только png, но другие форматы тоже поддерживаются (jpeg точно).

Файл можно как просто положить в _static, так и создать структуру для рисунков. В любом случае, нужно будет указывать путь до файла от корня проекта (где лежит index.rst).

Я нашел какой-то бесплатный файл с манулом и длинным названием, переименовал его в manul.jpg и положил в _static.

После чего внёс изменения в chapter_1.rst, и теперь он выглядит так:

Панграмма

===============

Эй, жлоб! Где туз? Прячь юных съемщиц в шкаф.

 

Ссылка на рисунок :ref:Рисунок -- Сам рисунок <manul>.

 

.. _manul: 

 

.. figure:: /_static/manul.jpg

       :width: 700

       :align: center

       :alt: 

 

       Рисунок -- Сам рисунок

Тут есть ссылка (:ref:Рисунок -- Сам рисунок <manul>), идентификатор раздела (.. _manul:), на который можно сослаться, и внутри раздела свойства добавляемого рисунка (.. figure:: и далее).

На всякий случай, index.rst выглядит так:

Пример документации

========================

 

Съешь же ещё этих мягких французских булок, да выпей чаю.

 

.. toctree::

   :maxdepth: 2

   :caption: Раздел документации:

 

   chapters/chapter_1

А файловая структура вот такая:

docs

└── build

|       └── html

|               ├── остальные файлы сборки

|               └── index.html

└── source

        ├── chapters

        |       └── chapter_1.rst

        ├── _static

        |       └── manul.jpg

        ├── conf.py

        └── index.rst

Ну и раз на то пошло, вот так выглядит минимальный conf.py

project = 'Пример документации'

copyright = '2026, Имя проекта'

author = 'Имя автора'

 

# -- General configuration ---------------------------------------------------

 

extensions = ['docxbuilder']

 

templates_path = ['_templates']

exclude_patterns = []

 

language = 'ru'

 

# -- Options for HTML output -------------------------------------------------

 

html_theme = 'sphinx_rtd_theme'

html_static_path = ['_static']

Снова sphinx-build -b html source build/html , и в итоге у меня получилось вот так:

Размер рисунка можно задавать как width, так и scale в процентах от исходного. Но рисунок всё равно будет вписан в документацию по ширине. Лично мне width больше нравится. Более предсказуемо.

Итого, ссылки (на что угодно) оформляются как

:ref:текст_ссылки <идентификатор> ,

если текст ссылки не нужен (например, ссылка на раздел, где текст берётся из названия раздела), можно оставить

:ref:идентификатор .

Обратите внимание, идентификатор в ссылке задаётся без «_» (нижнего подчеркивания) в начале, тогда как в тексте он всегда начинается с «_», точнее даже с «.. _» (две точки, пробел, нижнее подчеркивание).

Ссылки на параграфы внутри текста создаются аналогичным образом.

Ну и, конечно, не забудьте добавить изменения в репозиторий:

git add --all
git commit -m "Добавлен один манул"

Вордовский документ и внешняя документация

Сборка всего этого добра в docx не требует больших усилий (если установили расширение docxbuilder, конечно), ведь необходимо и достаточно в команде сборки поменять html на docx и найти собранный файл в соответствующем каталоге.

Пара слов о публикации на внешнем сайте. У нас это автосборка в Гитлабе и авторазмещение на сервере, но для начала можно физически копировать результат сборки в структуру веб сайта. Впрочем, это как будто выходит за рамки данной статьи.

На прощание

Я был удивлён, насколько комфортно реализуется подход docs-as-code. Перенос имеющейся документации в новый формат — процесс непростой, зато работать так одно удовольствие. Если специалист хоть немного знаком с Гитом и каким-либо языком разметки/программирования, вопросов не возникнет, но даже если нет, можно работать, не погружаясь в детали реализации (например, создать пакетные файлы для основных операций со Sphinx).

Единственное, что может смутить техписа, привыкшего к WYSIWYG-редакторам, это писать на языке разметки, а результат смотреть после сборки. Есть решения, близкие к WYSIWYG, но мы в команде быстро привыкли: изменил исходник -> собрал и проверил локально -> коммит-пуш-MR -> еще раз проверил на стенде -> задача закрыта.

Спасибо за внимание!