tS Docs

Table of content

Сборник документации в виде статичных html страниц размещенных на github pages.

Для добавления и редактирвания страниц используются .md файлы (файлы разметки markdown) и особый билд-скрипт на python3, который конвертирует файлы в html. Все файлы лежат в одном репозитории.

Структура репозитория

.
|   
├── src
│   ├── style.css              // Таблица стилей
│   ├── keywords.js            // Автогенерируемый файл для поисковика
│   ├── searchWidget.js        // Скрипт виджета поиска
│   ├── autocompleter.js       // Вспомогательный скрипт поиска (автозаполнение ключевыъ слов)
│   └── searcher.js            // Скрипт поиска и фильтрации
|
|   // Структура исходных файлов
├── md
│   ├── Section1        // Раздел 1 и страницы раздела
│   │   ├── page1.md
│   │   └── page2.md
│   ├── Section2
|   |   ├── SubSection1
│   │   │   └── page5.md
│   │   ├── page3.md
│   │   └── page4.md
│   ├── build.py        // Билд-скрипт
│   └── validate.py     // Скрипт для валидации страницы
|
|   // Готовые html-страницы
├── index.html
├── Section1
│   ├── page1.html
│   └── page2.html
├── Section2
|   ├── SubSection1
│   │   └── page5.html
│   ├── page3.html
│   └── page4.html

Исходные .md файлы рассортированы в папки, не более 2х уровней глубины. В конфиге билд-скрипте задана структура первого уровня, структуры второго уровня задаются непосредственно в метаданных головной страницы.

MD страницы

Данные хранятся и редактируются в .md страницах, которые затем будут конвертирваны в html страницы билд-скриптом. Страницы должны использовать стандартный markdown syntax с некоторыми расширениями.

Metadata

Первой строкой должна идти строка метаданных вида

@Meta(key1=value1, key2=value2, key3=value3) NORENDER

пары ключ-значения разделяются запятыми. Ключи:

Расширенный синтаксис

Структура и дропдауны

Секции (дропдауны 1-го уровня)

Список секций хардкодится в билд-скрипт - имя дропдауна и папка для страниц. Порядок секций в навигационной панели тоже задается в билд-скрипте.

SECTION_CONFIGURATION = {
 "order": ["_docs", "_sop", "_tco", "_mmo", "_srv"],  # Порядок следования секций в navbar'е

 # Описание секции
 "_sop": {
  "title": "SOPs",  # Отображаемое название секции в navbar'e
  "tooltip": "Standard Operation Procedures",  # Текст для всплывающего текста при наведении (опционально), html-свойство title
  "src": "SOP"  # Имя папки первого уровня где хранятся страницы
 },
 "_docs": {
  "title": "Документация",
  "src": "Docs"
 },
 "_tco": {
  "title": "TCO",
  "tooltip": "Training Center Office",
  "src": "TCO"
 }
 ...
};

Все страницы в указанной папке для секции рассматриваются как элементы дропдауна. При этом исходя из метаданныз конкретной страницы задается сам факт добавления страницы в дропдаун (флаг Hide), положение страницы в дропдауне (ключ Position) и отображаемое название страницы в дропдауне (ключ Title).

Дропдауны 2-го уровня

Если в метаданных страницы имеется не пустой ключ Subpages, то для данной страницы в дропдауне добавляется дропдаун 2го уровня и наполняется страницами найденными в директории /md/<SomeSection>/<Subpages_Value>/ (например, на странице /md/MMO/tsFramework.md в метаданных указано Subpages=tSF, дропдаун 2го уровня будет собран из страниц в /md/MMO/tSF/*.md).

Дропдаун 2-го уровня может быть двух видов:

Билд-скрипт

Общая схема работы

  1. Считывается SECTION_CONFIGURATION и формируется базовая структура navbar'а
  2. Для каждой заданной секции вычитываем все .md файлы в директории
  3. Для каждого .md файла считываем метаданные
    • если в метаданных нет ключа Title, то найти и вычитать заголовок первого уровня
  4. Для каждого .md файла имеющего не пустой Subpages - считываем все .md файлы в соответствующей суб-директории
  5. Формируем navbar учитывая:
    • секцию к которой относится страница
    • желаемую позицию страницы в дропдауне (ключ Position)
    • желаемое имя страницы (ключ Title или заголовок первого уровня)
    • наличие дропдауна второго уровня (ключ Subpages)
    • необходимость отображать страницу в дропдауне (ключ Hide=1, тем не менее если одновременно есть непустой ключ Subpages - то добавляем элемент по шаблону HTML_DROPDOWN_EXTENDED_INACTIVE - т.е. не выбираемый элемент с дропдауном второго уровня)
    • известную структуру файлов для задания ссылок на страницу
  6. Вновь проходим по всем страницам всех секций:
    • пррепроцессим
    • конвертируем markdown в html (также получаем table of content из расширения toc)
  7. Использя общий шаблон html страницы, сформированный navbar и конвертированный markdown - форматируем готовую html страницу и сохраняем ее в соответствующую папку в корне

Парсинг markdown

Препроцессинг

Вычлененные заголовки (Mata.Title или заголовок #) имеют отдельную роль в формировании страницы. Если значение Meta.Title задано, то используем его в HTML-заголовке страницы (чтобы на вкладке браузера было видно что за страница открыта). Если Meta.Title не задан, то везде используется первый найденный заголовок первого уровня - в HTML-заголовке страницы и как название статьи (выделено отдельным элементом, см. шаблоны).

HTML

<div class="navbar"> <!-- Собственно панель с разделами -->
    <div class="dropdown"> <!-- Блок задающий раздел -->
        <button class="dropbtn">SOP</button>  <!-- Заголовок раздела - тут SOP -->
            <div class="dropdown-content">  <!-- Блок элементов дропдауна -->
                <a href="#">Графические меры контроля</a>  <!-- Элемент дропдауна, где href = ссылка на соответствующую страницу-->
                <a href="#">Формации</a>    
            </div>
        </div>
    </div>
</div>

Шаблоны

Страница

HTML_PAGE = '''<!DOCTYPE html>
<html>
    <head>
        {head}
    </head>
    <body>
        {body}
    </body>
</html>'''

Заголовок страницы

HTML_HEAD = '''
 <meta charset="utf-8"/>
 <title>tS Docs - {title}</title>  

 <link rel="icon" href="src/img/ts_icon.png">
 <link rel="stylesheet" href="src/style.css">
 <script src="https://code.jquery.com/jquery-3.4.1.min.js"
 integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
 crossorigin="anonymous"></script>
'''

Тело страницы

HTML_BODY = '''
<div id="header">
 <div id="header-title">
  <span><a href="https://tacticalshift.github.io" style="text-decoration: none; color: inherit;">tS</a></span> <tt id='header-sans'>Docs</tt>
 </div>
 {navbar}
</div>
<div id="wrapper">
 <div class="title"><h1>{title}</h1></div>
 <div class="toc">
  {toc}
 </div>
 <div class="article">
  {article}
 </div>
</div>
'''
HTML_NAVBAR_SECTION = '''
 <div class="navbar">
  {dropdowns}
 </div>
'''

Секция (Дропдаун 1го уровня)

HTML_DROPDOWN_SECTION = '''
    <div class="dropdown">
        <button class="dropbtn" title="{tooltip}">{title}</button>
        <div class="dropdown-content">
          {elements}
        </div>
    </div>
'''

Элемент-ссылка дропдауна

HTML_DROPDOWN_ELEMENT = '<a href="{url}">{title}</a>'

Элемент-ссылка списка с дропдауном 2го уровня

HTML_DROPDOWN_EXTENDED = '''
 <div class="dropdown-2l">
  <a href="{url}">{title}<arrow>⇨</arrow></a>
  <div class="dropdown-2l-content">
   {subpages}
  </div>
 </div>
'''

Элемент списка (неактивный) с дропдауном 2го уровня

HTML_DROPDOWN_EXTENDED_INACTIVE = '''
 <div class="dropdown-2l">
  <span>{title}<arrow>⇨</arrow></span>
  <div class="dropdown-2l-content">
   {subpages}
  </div>
 </div>
'''