Как устроен документ
Редактор разделяет настройки на два уровня: документ целиком и отдельные разделы внутри него. Это важно, потому что стили, скрипты, переменные, языки и экспорт работают по-разному в зависимости от уровня.
Уровень документа
На уровне документа хранятся общие параметры всего итогового HTML-файла: название документа, заголовок экспортированного файла, язык документа, логотип, фавикон, Open Graph-поля, настройки шапки и подвала, цветовые схемы, поиск, переключатель языков и другие глобальные опции.
Здесь же находятся ресурсы, которые относятся ко всему документу сразу: переменные, список поддерживаемых языков контента, пользовательские стили и пользовательские скрипты.
При экспорте document CSS вставляется прямо в <head> итогового файла, а document JavaScript добавляется перед закрывающим </body>. Такой код работает глобально и может влиять на все страницы, меню, шапку, подвал и любые элементы интерфейса чтения.
Если в документе заданы внешние CSS- или JS-файлы, они не встраиваются внутрь HTML, а подключаются как обычные <link> и <script src>. Это удобно для CDN и аналитики, но для работы таких файлов нужен доступ к сети и стабильный внешний URL.
Минификация document CSS и document scripts выполняется во время экспорта. В редакторе код не исполняется как в готовом экспортированном файле: итоговое поведение нужно проверять именно в экспортированном HTML.
Типы разделов
page — основной тип раздела для контента, который должен открываться прямо внутри документа: инструкции, explanation, onboarding, release notes, tutorial, policy, knowledge base article и любые страницы с текстом, изображениями, примерами, поиском, оглавлением, локальными стилями, section scripts и мультиязычностью.
link нужен не для контента, а для маршрутизации читателя. Используйте его, когда сам материал должен открываться по URL: внешний сайт, внешняя документация, страница поддержки, GitHub, форма, отдельный сервис или даже другой разделенный документ.
related нужен для переиспользования shared page-раздела в нескольких местах. Используйте его, когда одна и та же страница должна появляться в нескольких документах: общая установка, требования, блок безопасности, единые условия интеграции, FAQ или типовой onboarding. Вы обновляете источник один раз, а related-разделы получают тот же контент, section styles, section scripts и поведение оглавления.
api используйте для структурированной API Reference по C#-коду: пространства имен, классы, структуры, интерфейсы, records, enums, delegates, конструкторы, методы, свойства, индексаторы, поля, параметры методов и XML summary. Такой раздел подходит для SDK, библиотек, внутренних платформ, game tools и plugin APIs, где reference нужно регулярно собирать из исходников и держать синхронной с кодом.
dynamic используйте для встроенного JSON-источника, который описывает корневую страницу, вложенные страницы и переиспользуемые Base64-ресурсы. Содержимое каждой страницы может иметь тип html или markdown. Экспортированный viewer создает эти страницы во время выполнения. Ресурсы подключаются через res://resource-id; внешний JSON и внешние ресурсы страниц не поддерживаются.
Подготовка API-раздела
API-раздел в One File Docs принимает JSON. Рабочий процесс простой: извлеките описание API из C#-исходников во внешний JSON-файл, затем загрузите этот файл в раздел типа api.
Для этого используются два связанных инструмента:
- CSharpApiExtractor — основной Roslyn-based extractor, который сканирует
.cs-файлы и строит JSON-описание public API. - CSharpApiExtractorGUI — desktop GUI-оболочка для того же extraction workflow, ориентированная на более простой ручной экспорт и работу с несколькими проектами без программирования.
CSharpApiExtractor читает .cs-файлы напрямую, не требует разбора .csproj, берет summary из комментариев /// и формирует JSON с описанием public API. Отдельно он собирает undocumented items в список MissedItems, чтобы было проще контролировать качество reference-документации.
CSharpApiExtractor выбирайте для автоматической сборки: CI/CD, регулярные релизы, несколько пакетов и сценарии, где JSON должен обновляться вместе с кодом.
CSharpApiExtractorGUI выбирайте для ручной работы: редкие обновления, разовый экспорт, несколько project-конфигураций и случаи, когда JSON удобнее собрать через desktop-интерфейс.
Если reference — только часть документа, размещайте справку в api-разделе, а guides, tutorials, migration notes и integration walkthroughs оформляйте как обычные page-разделы рядом.
Структура разделов
Разделы образуют дерево. У каждого раздела есть заголовок, внутренний ID, тип, позиция в иерархии и, при необходимости, родительский раздел. Именно из ID собираются пути и якоря внутри экспортированного файла и HTML.
Раздел можно скрыть из меню, не удаляя из документа, или полностью исключить из экспорта. Если родительский раздел исключен из экспорта, его дочерние разделы тоже не попадут в итоговый файл.
Для многоязычных документов у раздела можно указать конкретный язык или режим all. Тогда экспортированный файл покажет только подходящие страницы для выбранного языка.
Внутренняя перелинковка
Внутренние ссылки строятся на основе ID разделов и id якорей внутри контента. Поэтому перед перелинковкой сначала проверьте, что у нужной страницы задан понятный и стабильный ID в настройках раздела.
Чтобы сослаться на другой раздел, используйте обычную ссылку с hash-путем вида #section-id. Если раздел вложенный, путь будет составным: #parent-id/child-id.
Если ссылка должна вести не просто на страницу, а сразу к конкретному месту внутри нее, добавьте anchor после пути раздела: #section-id/anchor-id или #parent-id/child-id/anchor-id.
Якорь внутри страницы можно получить несколькими способами: задать id у заголовка или другого HTML-элемента вручную, использовать anchor-вставку в визуальном редакторе, либо включить генерацию оглавления, чтобы экспортированный файл сам проставил id у заголовков h1, h2 и h3.
Практически это выглядит так: ссылка #installation откроет страницу раздела, а ссылка #installation/system-requirements откроет ту же страницу и прокрутит экспортированный файл к якорю system-requirements.
Такую ссылку можно поставить прямо в контент page-раздела через обычный диалог вставки ссылки. Если нужен отдельный пункт меню, создайте раздел типа link и укажите тот же внутренний hash-адрес в поле URL.
Стили и скрипты документа
Document-level custom code нужен для общих правил: брендовые цвета, типографика, общие UI-правки интерфейса чтения, глобальные обработчики событий, счетчики, интеграции и общие хелперы.
Этот код подставляется в экспорт уже после сборки итогового файла. Поэтому document CSS может переопределять встроенные стили One File Docs, а document scripts могут обращаться к глобальному JavaScript API через window.OneFileDocsViewer.
В document CSS и scripts работают переменные документа и шаблонные условия. Если в коде есть {{productName}} или блоки вида {% if productName %}...{% endif %}, при экспорте они будут сначала раскрыты, а уже потом вставлены в HTML.
Стили и скрипты разделов
У каждого раздела можно задать собственные CSS, JavaScript, а также списки внешних CSS- и JS-файлов. Эти настройки действуют только на экспортированный файл и не являются глобальными настройками всего документа.
Section CSS работает как активный стиль текущей страницы. Когда пользователь открывает раздел, экспортированный файл записывает его CSS в отдельный <style id="active-section-custom-css">. При переходе в другой раздел это содержимое заменяется, а если CSS у нового раздела нет, стиль удаляется.
Внешние CSS-файлы раздела подключаются только на время просмотра этого раздела. При переключении страницы экспортированный файл удаляет предыдущие section stylesheet links и добавляет новые.
Section scripts выполняются при рендеринге раздела. Это значит, что один и тот же скрипт запускается заново каждый раз, когда пользователь снова открывает страницу. Если код добавляет обработчики событий, таймеры или DOM-узлы, его лучше писать идемпотентно, чтобы повторный вход в раздел не создавал дубликаты.
Внешние JS-файлы раздела тоже подключаются динамически при открытии страницы и снимаются при переходе на другую. Для сложной логики это полезно, когда код нужен только на одном экране, а не во всем документе.
Во время работы section scripts экспортированный файл генерирует события начала и завершения через API. Это позволяет привязывать аналитику, отладку и собственные интеграции к моменту показа конкретной страницы.
Что учитывать на практике
- Document custom code используйте для правил, которые должны жить во всем HTML-файле.
- Section custom code используйте для локальной логики конкретной страницы.
- Если нужен офлайн-результат одним файлом, не полагайтесь на внешние CSS и JS URL.
- Если section script изменяет DOM, рассчитывайте на повторный запуск при повторном открытии раздела.
- Если нужно переиспользование поведения и оформления, выносите страницу в shared-раздел и подключайте ее через
related. - Пользовательские стили и скрипты доступны только на Pro и применяются именно при экспорте.