traintastic/manual/build.py

259 Zeilen
11 KiB
Python
Ausführbare Datei

#!/usr/bin/env python3
import sys
import os
import codecs
import operator
import shutil
import mkdocs.config
import mkdocs.commands
import mkdocs.commands.build
import yaml
from luadoc import LuaDoc
def detect_version():
if 'GITHUB_ACTIONS' in os.environ:
import codecs
import re
with codecs.open(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'shared', 'traintastic.cmake')), 'r', 'utf-8') as file:
version = re.findall(r'^set\(TRAINTASTIC_VERSION ([0-9\.]+)\)$', file.read(), re.MULTILINE)[0]
if os.environ['GITHUB_REF_TYPE'] == 'branch':
version += '-' + os.environ['CI_REF_NAME_SLUG'] + '-' + os.environ['GITHUB_RUN_NUMBER'] + '-' + os.environ['CI_SHA_SHORT']
return version
else:
return None
class TraintasticHelp:
version = ''
language = 'en'
_luadoc = None
def __init__(self, base_dir: str):
self.base_dir = os.path.abspath(base_dir)
self.output_dir = os.path.join(self.base_dir, 'output')
self._luadoc = LuaDoc(os.path.join(self.base_dir, '..'))
def build(self) -> bool:
shutil.rmtree(os.path.join(self.output_dir, self.language), ignore_errors=True)
lua_dir = os.path.join(self.base_dir, 'docs', self.language, 'appendix', 'lua')
#shutil.rmtree(lua_dir, ignore_errors=True)
self._luadoc.build(lua_dir)
self._write_mkdocs_yml()
cfg = mkdocs.config.load_config(os.path.join(self.base_dir, 'config', self.language, 'mkdocs.yml'))
cfg.plugins.on_startup(command='build', dirty=False)
try:
mkdocs.commands.build.build(cfg)
finally:
cfg.plugins.on_shutdown()
return True
def _build_luadoc_object_category_nav(self, category: dict) -> list:
nav = []
items = [{**v, 'title': self._luadoc._get_term(v['title'])} for v in category['items']]
for item in sorted(items, key=operator.itemgetter('title')):
nav.append({item['title']: os.path.join('appendix', 'lua', item['href'])})
categories = [{**v, 'name': self._luadoc._get_term(v['name'])} for v in category['categories']]
for sub_category in sorted(categories, key=operator.itemgetter('name')):
nav.append({sub_category['name']: self._build_luadoc_object_category_nav(sub_category)})
return nav
def _write_mkdocs_yml(self):
lua_libs = {}
for _, lib in self._luadoc._libs.items():
lua_libs[lib['lua_name']] = {self._luadoc._get_term(lib['name']): os.path.join('appendix', 'lua', lib['filename'])}
lua_enums = [{'All': os.path.join('appendix', 'lua', LuaDoc.FILENAME_ENUM)}]
for obj in self._luadoc._enums:
lua_enums.append({self._luadoc._get_term(obj['name']): os.path.join('appendix', 'lua', obj['filename'])})
lua_sets = [{'All': os.path.join('appendix', 'lua', LuaDoc.FILENAME_SET)}]
for obj in self._luadoc._sets:
lua_sets.append({self._luadoc._get_term(obj['name']): os.path.join('appendix', 'lua', obj['filename'])})
lua_objects = [{'All': os.path.join('appendix', 'lua', LuaDoc.FILENAME_OBJECT)}]
categories = [{**v, 'name': self._luadoc._get_term(v['name'])} for v in self._luadoc._object_categories]
for category in sorted(categories, key=operator.itemgetter('name')):
items = self._build_luadoc_object_category_nav(category)
lua_objects.append({category['name']: items})
if len(self._luadoc._object_category_other) > 0:
items = []
for obj in self._luadoc._object_category_other:
items.append((self._luadoc._get_term(obj['title']), os.path.join('appendix', 'lua', obj['href'])))
lua_objects.append({self._luadoc._get_term('object.category.other:title'): [{v[0]: v[1]} for v in sorted(items, key=operator.itemgetter(0))]})
lua_ref = [
{'Introduction': 'appendix/lua/index.md'},
{'Lua basics': 'appendix/lua/basics.md'},
{self._luadoc._get_term('globals:title'): os.path.join('appendix', 'lua', LuaDoc.FILENAME_GLOBALS)},
{self._luadoc._get_term('pv:title'): os.path.join('appendix', 'lua', LuaDoc.FILENAME_PV)},
lua_libs['class'],
{self._luadoc._get_term('enum:title'): lua_enums},
lua_libs['log'],
lua_libs['math'],
{self._luadoc._get_term('set:title'): lua_sets},
lua_libs['string'],
lua_libs['table'],
{'Objects': lua_objects},
{'Examples': os.path.join('appendix', 'lua', LuaDoc.FILENAME_EXAMPLES)},
{'Index A-Z': os.path.join('appendix', 'lua', LuaDoc.FILENAME_INDEX_AZ)},
]
config = {
'site_name': 'Traintastic manual',
'docs_dir': os.path.join('../../docs', self.language),
'extra_css': ['assets/extra.css'],
'site_dir': os.path.join(self.output_dir, self.language),
'use_directory_urls': False,
'theme': {
'name': 'material',
'custom_dir': '../../overrides/',
'language': self.language,
'icon': {
'logo': 'traintastic/logo'
},
'palette': [
{
'scheme': 'default',
'toggle': {
'icon': 'material/brightness-7',
'name': 'Switch to dark mode'
}
},
{
'scheme': 'slate',
'toggle': {
'icon': 'material/brightness-4',
'name': 'Switch to light mode'
}
}
],
'features': ['content.code.copy']
},
'markdown_extensions': [
'attr_list',
'admonition',
{
'pymdownx.highlight': {
'anchor_linenums': True,
'line_spans': '__span',
'pygments_lang_class': True
}
},
'pymdownx.inlinehilite',
'pymdownx.keys',
'pymdownx.snippets',
'pymdownx.superfences',
{
'pymdownx.escapeall': {
'hardbreak': True
}
}
],
'plugins': {
'search': {
'lang': self.language
}
},
'nav': [
{'Welcome': 'index.md'},
{'Getting started': [
{'Installation': [
{ 'Windows': 'installation/windows.md' },
{ 'Linux': 'installation/linux.md' }
]},
{'Quick start': [
{'Introduction': 'quickstart/index.md'},
{'Create your first world': 'quickstart/world.md'},
{'Connect to your command station': 'quickstart/command-station.md'},
{'Add and control a train': 'quickstart/trains.md'},
{'Create a schematic layout': [
{'Introduction': 'quickstart/layout/index.md'},
{'Drawing basics': 'quickstart/layout/drawing-basics.md'},
{'Turnout control': 'quickstart/layout/turnouts.md'},
{'Blocks and sensors': 'quickstart/layout/blocks-sensors.md'},
{'Signals': 'quickstart/layout/signals.md'}
]}
]}
]},
{'User guide': [
{'Board': [
{'Tile reference': 'user-guide/board/tile-reference.md'}
]},
{'Zones': 'user-guide/zones.md'}
]},
{'Advanced topics': [
{'Interface configuration': [
{'Introduction': 'advanced/interface/index.md'},
{'DCC-EX': 'advanced/interface/dcc-ex.md'},
{'ECoS': 'advanced/interface/ecos.md'},
{'HSI-88': 'advanced/interface/hsi-88.md'},
{'LocoNet': 'advanced/interface/loconet.md'},
{'Märklin CAN': 'advanced/interface/marklin-can.md'},
{'Traintastic DIY': 'advanced/interface/traintastic-diy.md'},
{'WiThrottle': 'advanced/interface/withrottle.md'},
{'WLANmaus': 'advanced/interface/wlanmaus.md'},
{'XpressNet': 'advanced/interface/xpressnet.md'},
{'Z21': 'advanced/interface/z21.md'}
]},
{'Scripting basics': 'advanced/scripting-basics.md'}
]},
{'Troubleshooting': [
{'Interface connection errors': 'troubleshooting/interface-connection-errors.md'}
]},
{'Appendix': [
{'Supported hardware': [
{'Overview': 'appendix/supported-hardware/index.md'},
{'Command Stations': 'appendix/supported-hardware/command-stations/index.md'},
{'Boosters': [
{'Overview': 'appendix/supported-hardware/boosters/index.md'},
{'Digikeijs DR5033': 'appendix/supported-hardware/boosters/digikeijs-dr5033.md'},
{'Uhlenblock Power 4/7/22/40/70': 'appendix/supported-hardware/boosters/uhlenbrock-power-4-7-22-40-70.md'}
]},
{'Product index': 'appendix/supported-hardware/product-index.md'}
]},
{'LocoNet reference': 'appendix/loconet.md'},
{'XpressNet reference': 'appendix/xpressnet.md'},
{'Lua scripting reference': lua_ref},
{'Traintastic DIY protocol': 'appendix/traintastic-diy-protocol.md'},
{'Command line options': 'appendix/command-line-options.md'}
]},
{'Uncategorized/WIP': [
{'Decoder function': 'wip/decoder-function.md'},
{'Input monitor': 'wip/input-monitor.md'},
{'Log messages': 'wip/log-messages.md'},
{'Trains': 'wip/trains.md'}
]}
]
}
TraintasticHelp._write_file(os.path.join(self.base_dir, 'config', self.language, 'mkdocs.yml'), yaml.dump(config))
def _write_file(filename: str, contents: str) -> None:
os.makedirs(os.path.dirname(filename), mode=0o755, exist_ok=True)
with codecs.open(filename, 'w', 'utf-8') as f:
f.write(contents)
if __name__ == '__main__':
from argparse import ArgumentParser
# Standard options:
parser = ArgumentParser()
parser.add_argument('--version', default=detect_version())
args = parser.parse_args(sys.argv[1:])
help = TraintasticHelp(os.path.abspath(os.path.dirname(__file__)))
help.version = args.version
sys.exit(0 if help.build() else 1)