From 0007e732879fcc6ca51538c6f13ea4db1e521aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 22 May 2026 16:23:43 +0200 Subject: [PATCH 01/41] Setup Pages Github action. --- .github/workflows/main.yml | 0 .github/workflows/pages.yaml | 32 +++++++++---- .github/workflows/plantuml.yml | 28 ----------- .gitignore | 5 +- pyproject.toml | 4 +- setup.py | 46 +++++++++++++++++++ tools/README.md | 79 ++++++++++++++++++++++++++++---- tools/build.sh | 61 ++++++++++++++++++++++++ tools/configuration.py | 3 +- tools/expand_docs/expand_docs.py | 50 ++++++++++++++------ 10 files changed, 246 insertions(+), 62 deletions(-) delete mode 100644 .github/workflows/main.yml delete mode 100644 .github/workflows/plantuml.yml create mode 100644 setup.py create mode 100644 tools/build.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 01502b13..90be6423 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -1,6 +1,6 @@ -# This is a basic workflow to help you get started with Actions +# Builds the docs and deploys them to GitHub pages. -name: CI +name: Pages # Controls when the workflow will run on: @@ -10,12 +10,17 @@ on: pull_request: branches: [ "main" ] +permissions: + contents: read + pages: write + id-token: write + # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" + build: # The type of runner that the job will run on runs-on: ubuntu-latest @@ -27,10 +32,19 @@ jobs: # Runs a single command using the runners shell - name: Run a one-line script - run: echo Hello, world! + run: | + ./tools/build.sh + + - uses: actions/upload-pages-artifact@v3 + with: + path: site - # Runs a set of commands using the runners shell - - name: Run a multi-line script - run: | - echo Add other actions to build, - echo test, and deploy your project. + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.github/workflows/plantuml.yml b/.github/workflows/plantuml.yml deleted file mode 100644 index 6eaaa3e7..00000000 --- a/.github/workflows/plantuml.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Embed PlantUML in Markdown - -on: - push: - branches: [ main ] - paths: - - '**/*.md' - - '**/*.puml' - pull_request: - paths: - - '**/*.md' - - '**/*.puml' - workflow_dispatch: - -permissions: - contents: write - -jobs: - embed-puml-markdown: - runs-on: ubuntu-latest - steps: - - name: Check out the repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Embed PlantUML inside Markdown - uses: alessandro-marcantoni/puml-markdown@v0.1.1 \ No newline at end of file diff --git a/.gitignore b/.gitignore index b023e8ab..40044042 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ generated/xcore/contab/netex.html templates/README.md~ tools/schematron_builder/__pycache__/template2schematron.cpython-313.pyc __pycache__ -netex_rg_ch.egg-info \ No newline at end of file +netex_rg_ch.egg-info +dist/ +site/ +build/ \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 82bfc82b..fc75763a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [build-system] -requires = ["setuptools>=70", "wheel"] +requires = ["setuptools>=70"] build-backend = "setuptools.build_meta" [project] name = "netex-rg-ch" -version = "0.1.0" +version = "0.1.1" description = "Provides tools to help building the NeTEx RG." requires-python = ">=3.13" dependencies = [ diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..c2be3921 --- /dev/null +++ b/setup.py @@ -0,0 +1,46 @@ +# setup.py - tiny hook to build docs into ./site) +import os +import subprocess +import sys +from pathlib import Path +from setuptools import setup, Command +from setuptools.command.sdist import sdist as _sdist + +class build_docs(Command): + """Generate documentation into ./site.""" + description = "Build project documentation into ./site" + user_options = [ + ("clean", None, "clean the output directory before building"), + ] + + def initialize_options(self): + self.clean = False + + def finalize_options(self): + self.clean = bool(self.clean) + + def run(self): + outdir = Path("site") + if self.clean and outdir.exists(): + import shutil + shutil.rmtree(outdir) + outdir.mkdir(exist_ok=True) + + # run tools here ... + cmd = [sys.executable, "-m", "tools.expand_docs.expand_docs", "--out", str(outdir)] + self.announce(f"Running: {' '.join(cmd)}", level=2) + # Build environment variables if you want to pass context + env = dict(os.environ) + env.setdefault("PYTHONHASHSEED", "0") + subprocess.check_call(cmd, env=env) # fails the build on nonzero exit + self.announce(f"Docs generated in {outdir}", level=2) + +class sdist(_sdist): + def run(self): + # Build docs before sdist (writes to ./site but we will exclude it from sdist) + self.run_command("build_docs") + super().run() + +cmdclass = {"build_docs": build_docs, "sdist": sdist} + +setup(cmdclass=cmdclass) diff --git a/tools/README.md b/tools/README.md index f60e4e79..0b42c5fc 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,16 +1,53 @@ # Tools for the Swiss NeTEx RG -## Install Tools with uv +## How to setup and run the build -The package manager `uv` simplifies the build and installation of scripts for the tools. +The build builds the tools and runs them to create the generated documents in the directory `site`. -- Dependencies are managed by `uv`, as configured in `pyproject.toml` and more detailed in `uv.lock`. -- `uv` provides an os-independent interface for scripts -- The generated tool scripts run on Windows, Mac or Linux +### Steps involved to setup and run the build + +1. Install the [uv package manager](#install-the-uv-package-manager) +2. Initialize the [virtual environment](#initialize-the-virtual-environment) +3. [Run the build]() + +For more information about the build framework, see [Build Automation](#build-automation). + +### Install the uv package manager + +Install the uv package manager: +- See [uv package manager](https://docs.astral.sh/uv/) +- if you have pip installed, you can run `pip install uv` + +### Initialize the virtual environment + +#### Mac/Linux + +Run the following following commands in the project root directory: +```sh +uv venv +uv sync +sh ./venv/bin/activate +``` + +#### Windows + +Run the following following commands in the project root directory: + +``` shell +uv venv +uv sync +venv\bin\activate.bat +``` -### Install the package manager +### Run the build -See [uv package manager](https://docs.astral.sh/uv/) +If everything is setup correctly, you should be able to run the build doing `python -m build` in the project root directory. + + +## Tool Scripts + +The `pyproject.toml` is configured to generate scripts for the tools. +These tool scripts are not required for the build, but they may be useful for running tools locally. ### Prerequisites: Set PYTHONPATH and PATH @@ -52,4 +89,30 @@ This generates executable scripts for Linux/Mac and Windows in subdirectories of ### How to add a new Script - Add a new entry in the `[project.scripts]` section of `pyproject.toml`. -- If the script requires another package, use `uv add` to added to the environment. \ No newline at end of file +- If the script requires another package, use `uv add` to added to the environment. + +## Build Automation Framework + +### Package Manager + +The package manager `uv` simplifies the build and installation of scripts for the tools. + +- Dependencies are managed by `uv`, as configured in `pyproject.toml` and more detailed in `uv.lock`. +- `uv` provides an os-independent interface for scripts + - Generated tool scripts run on Windows, Mac or Linux + +### Project build + +Components of the build automation: +- [pyproject.toml](../pyproject.toml) is configured with `setuptools` (https://setuptools.pypa.io/en/latest/) + - docs can be generated running `python -m build` +- `setup.py` in the root project acts as the interface for the build + - here we can add tools to be run during the build. +- The build writes all output to directory `site`, excluded from git + +### Github Action + +The Github Action [pages.yaml](../.github/pages.yaml) runs the script [build.sh](./build.sh) (can also be tested locally) + - triggered after commits to main branch (e.g. after the merge of a branch) + - runs the build via the `python -m build` mechanism + - uploads generated docs to GitHub Pages diff --git a/tools/build.sh b/tools/build.sh new file mode 100644 index 00000000..b8a27417 --- /dev/null +++ b/tools/build.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Build script for the github action. +# - can also be run and tested locally (Mac or Linux) +# - use "python -m build to build docs otherwise +set -Eeuo pipefail +IFS=$'\n\t' + +# --- Configuration (override via environment variables) --- +PYTHON="${PYTHON_BIN:-python3}" # or "python" if that's your default +VENV_DIR="${VENV_DIR:-.venv-build}" # ephemeral venv only for build tools +OUTDIR="${OUTDIR:-dist}" # where artifacts go +EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS:-}" # e.g. "--no-isolation" (not recommended) +TEST_INSTALL="${TEST_INSTALL:-1}" # 1 to smoke-test installing the wheel + +# --- Move to repo root --- +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" +REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." &>/dev/null && pwd)" +cd "$REPO_ROOT" + +echo "==> Building package in $REPO_ROOT" + +# --- Pre-flight checks --- +if [[ ! -f pyproject.toml ]]; then + echo "Error: pyproject.toml not found in repository root: $REPO_ROOT" >&2 + exit 1 +fi + +# --- Clean previous build outputs --- +# rm -rf "$OUTDIR" build .pytest_cache +mkdir -p "$OUTDIR" + +# --- Create isolated venv for build tools --- +if [[ ! -d "$VENV_DIR" ]]; then + echo "==> Creating build venv at $VENV_DIR" + $PYTHON -m venv "$VENV_DIR" +fi + +# shellcheck source=/dev/null +source "$VENV_DIR/bin/activate" +$PYTHON -m pip install --upgrade pip setuptools +$PYTHON -m pip install --upgrade build + +# If you use setuptools-scm, ensure it's present for version derivation +if grep -qiE 'setuptools[-_]scm' pyproject.toml; then + $PYTHON -m pip install --upgrade setuptools-scm +fi + +# --- Make builds more reproducible (optional but harmless) --- +export PYTHONHASHSEED=0 +export SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log -1 --pretty=%ct 2>/dev/null || date +%s)}" + +# --- Build sdist and wheel --- +echo "==> Running python -m build" +$PYTHON -m build --sdist --wheel --outdir "$OUTDIR" $EXTRA_BUILD_ARGS + +# --- List outputs --- +echo "==> Produced artifacts:" +ls -lh "$OUTDIR" + +deactivate +echo "==> Build complete." diff --git a/tools/configuration.py b/tools/configuration.py index d780577e..57cc4d12 100644 --- a/tools/configuration.py +++ b/tools/configuration.py @@ -7,6 +7,7 @@ TEMPLATES_DIR = PROJECT_DIR.joinpath("../templates") # Generated documents -GENERATED_DIR = PROJECT_DIR.joinpath("../generated") +GENERATED_DIR = PROJECT_DIR.joinpath("../site") +GENERATED_DOCS_DIR = GENERATED_DIR.joinpath("/docs") XSD_FILE_PATH = PROJECT_DIR.joinpath("../xsd/xsd/NeTEx_publication.xsd") diff --git a/tools/expand_docs/expand_docs.py b/tools/expand_docs/expand_docs.py index 34a3e419..177272e5 100644 --- a/tools/expand_docs/expand_docs.py +++ b/tools/expand_docs/expand_docs.py @@ -6,15 +6,22 @@ import shutil import argparse import re +from abc import ABC + +from setuptools import Command + +from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR + def copy_media_folder(input_folder, output_folder): """Copy media folder from input to output.""" media_src = os.path.join(input_folder, 'media') media_dst = os.path.join(output_folder, 'media') - + if os.path.exists(media_src): shutil.copytree(media_src, media_dst, dirs_exist_ok=True) + def include_xml_snippet(match, base_folder): """Include XML snippet content directly.""" snippet_path = match.group(1) @@ -23,12 +30,13 @@ def include_xml_snippet(match, base_folder): # base_folder is already the docs folder, so go up one level to project root project_root = os.path.abspath(os.path.join(base_folder, '..')) full_path = os.path.join(project_root, 'generated', 'xml-snippets', snippet_path) - + if os.path.exists(full_path): with open(full_path, 'r', encoding='utf-8') as f: return f"```xml\n{f.read()}\n```" return match.group(0) + def include_markdown_table(match, base_folder): """Include markdown table content directly.""" table_path = match.group(1) @@ -37,7 +45,7 @@ def include_markdown_table(match, base_folder): # base_folder is already the docs folder, so go up one level to project root project_root = os.path.abspath(os.path.join(base_folder, '..')) full_path = os.path.join(project_root, 'generated', 'markdown-examples', table_path) - + if os.path.exists(full_path): with open(full_path, 'r', encoding='utf-8') as f: content = f.read() @@ -54,43 +62,59 @@ def include_markdown_table(match, base_folder): return '\n'.join(table_lines) return match.group(0) + def process_markdown_file(input_path, output_path, base_folder): """Process a single markdown file.""" with open(input_path, 'r', encoding='utf-8') as f: content = f.read() - + # Process XML snippets - match the entire line prefix and link (flexible text) xml_pattern = r'(?:- )?\[.*?\]\(\.\./generated/xml-snippets/([^)]+\.xml)\)' content = re.sub(xml_pattern, lambda m: '\n\n' + include_xml_snippet(m, base_folder) + '\n\n', content) - + # Process markdown tables - match the entire line prefix and link (flexible text) md_pattern = r'(?:- )?\[.*?\]\(\.\./generated/markdown-examples/([^)]+\.md)\)' content = re.sub(md_pattern, lambda m: '\n\n' + include_markdown_table(m, base_folder) + '\n\n', content) - + # Write processed content with open(output_path, 'w', encoding='utf-8') as f: f.write(content) + def main(): parser = argparse.ArgumentParser(description='Expand documentation by including examples and tables.') - parser.add_argument('--docs', required=True, help='Input documentation folder') - parser.add_argument('--out', required=True, help='Output folder') + parser.add_argument('--docs', default=DOCS_DIR, help=f"Input documentation folder (default = {DOCS_DIR})") + parser.add_argument('--out', default=GENERATED_DOCS_DIR, help=f"Output folder (default = {GENERATED_DOCS_DIR})") args = parser.parse_args() - + # Create output folder if it doesn't exist os.makedirs(args.out, exist_ok=True) - + # Copy media folder copy_media_folder(args.docs, args.out) - + # Process each markdown file for filename in os.listdir(args.docs): if filename.endswith('.md'): input_path = os.path.join(args.docs, filename) output_path = os.path.join(args.out, filename) process_markdown_file(input_path, output_path, args.docs) - + print(f"Documentation expanded successfully to {args.out}") + if __name__ == '__main__': - main() \ No newline at end of file + main() + + +class ExpandDocs(Command, ABC): + """Setuptools plugin for the project build.""" + + def run(self) -> None: + """ + Execute the actions intended by the command. + (Side effects **SHOULD** only take place when :meth:`run` is executed, + for example, creating new files or writing to the terminal output). + """ + main() + pass \ No newline at end of file From 7d065d9e200fc2b407249c4552ba95cf4588db08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 22 May 2026 16:35:30 +0200 Subject: [PATCH 02/41] Correct description for setup of virtual env. --- tools/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/README.md b/tools/README.md index 0b42c5fc..57239fd7 100644 --- a/tools/README.md +++ b/tools/README.md @@ -24,9 +24,9 @@ Install the uv package manager: Run the following following commands in the project root directory: ```sh -uv venv +uv .venv +source .venv/bin/activate uv sync -sh ./venv/bin/activate ``` #### Windows @@ -34,9 +34,9 @@ sh ./venv/bin/activate Run the following following commands in the project root directory: ``` shell -uv venv +uv .venv +.venv\bin\activate.bat uv sync -venv\bin\activate.bat ``` ### Run the build From bcd50f2d30cb3ad8be895adf3ff3c750fd97d917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 22 May 2026 16:36:31 +0200 Subject: [PATCH 03/41] Update uv.lock. --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 09019363..c1ed9cc8 100644 --- a/uv.lock +++ b/uv.lock @@ -217,7 +217,7 @@ wheels = [ [[package]] name = "netex-rg-ch" -version = "0.1.0" +version = "0.1.1" source = { editable = "." } dependencies = [ { name = "lxml" }, From 2b4997af0cc9838c282acdfdc8a88d9c9bd74491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 22 May 2026 17:51:28 +0200 Subject: [PATCH 04/41] Update description of build module installation. --- .gitignore | 3 ++- pyproject.toml | 6 +++--- tools/README.md | 18 ++++++++++++++---- uv.lock | 4 ++-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 40044042..6d4a4cd4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ __pycache__ netex_rg_ch.egg-info dist/ site/ -build/ \ No newline at end of file +build/ +netex_rg_ch_test.egg-info/ \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fc75763a..48de31a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,9 @@ requires = ["setuptools>=70"] build-backend = "setuptools.build_meta" [project] -name = "netex-rg-ch" -version = "0.1.1" -description = "Provides tools to help building the NeTEx RG." +name = "netex-rg-ch-test" +version = "0.1.2" +description = "Testing tools to help building the NeTEx RG." requires-python = ">=3.13" dependencies = [ "lxml","pyschematron" diff --git a/tools/README.md b/tools/README.md index 57239fd7..ebd55af7 100644 --- a/tools/README.md +++ b/tools/README.md @@ -8,7 +8,8 @@ The build builds the tools and runs them to create the generated documents in th 1. Install the [uv package manager](#install-the-uv-package-manager) 2. Initialize the [virtual environment](#initialize-the-virtual-environment) -3. [Run the build]() +3. Install the [build module](#install-build-module) +4. [Run the build]() For more information about the build framework, see [Build Automation](#build-automation). @@ -24,7 +25,7 @@ Install the uv package manager: Run the following following commands in the project root directory: ```sh -uv .venv +uv venv source .venv/bin/activate uv sync ``` @@ -34,15 +35,24 @@ uv sync Run the following following commands in the project root directory: ``` shell -uv .venv +uv venv .venv\bin\activate.bat uv sync ``` +### Install build module +Make sure you have an up-to-date version of `pip` and of module `build` used to run the build: +``` +python -m ensurepip +python -m pip install --upgrade pip build +``` ### Run the build -If everything is setup correctly, you should be able to run the build doing `python -m build` in the project root directory. +If everything is setup correctly, you should be able to the build from your project root directory: +``` +python -m build +``` ## Tool Scripts diff --git a/uv.lock b/uv.lock index c1ed9cc8..8c6dbab0 100644 --- a/uv.lock +++ b/uv.lock @@ -216,8 +216,8 @@ wheels = [ ] [[package]] -name = "netex-rg-ch" -version = "0.1.1" +name = "netex-rg-ch-test" +version = "0.1.2" source = { editable = "." } dependencies = [ { name = "lxml" }, From a654c12447ae081f5ecf9f9d7913d13284078aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 22 May 2026 18:02:01 +0200 Subject: [PATCH 05/41] Move github action property to right place. --- .github/workflows/pages.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 90be6423..a4e07fc1 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -10,14 +10,14 @@ on: pull_request: branches: [ "main" ] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + permissions: contents: read pages: write id-token: write - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: From 54d8cb3e058547d9d4132e5d1971c9b907bfd57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 22 May 2026 18:09:05 +0200 Subject: [PATCH 06/41] Make build.sh executable. (#3) --- tools/build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/build.sh diff --git a/tools/build.sh b/tools/build.sh old mode 100644 new mode 100755 From 2763af5b6853cb115ff9f29c868d6c6d6fce0f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 29 May 2026 14:38:44 +0200 Subject: [PATCH 07/41] Setup build with setuptools (#4) * Make build.sh executable. * Introduce md2html and toolchain.py. * Add dependencies for the build. * Optimize imports. * Documentation note regarding build module. --- pyproject.toml | 4 +- setup.py | 21 ++++----- tools/README.md | 2 + tools/configuration.py | 2 +- tools/expand_docs/expand_docs.py | 46 ++++++-------------- tools/md2html/__init__.py | 0 tools/md2html/md2html.py | 74 ++++++++++++++++++++++++++++++++ tools/toolchain.py | 17 ++++++++ uv.lock | 58 +++++++++++++++++++++++++ 9 files changed, 176 insertions(+), 48 deletions(-) create mode 100644 tools/md2html/__init__.py create mode 100644 tools/md2html/md2html.py create mode 100644 tools/toolchain.py diff --git a/pyproject.toml b/pyproject.toml index 48de31a2..14a83c40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=70"] +requires = ["setuptools>=70","markdown","pygments"] build-backend = "setuptools.build_meta" [project] @@ -8,7 +8,7 @@ version = "0.1.2" description = "Testing tools to help building the NeTEx RG." requires-python = ">=3.13" dependencies = [ - "lxml","pyschematron" + "lxml","pyschematron","pygments","build","pip","markdown" ] [project.scripts] diff --git a/setup.py b/setup.py index c2be3921..44b24324 100644 --- a/setup.py +++ b/setup.py @@ -2,13 +2,13 @@ import os import subprocess import sys -from pathlib import Path + from setuptools import setup, Command from setuptools.command.sdist import sdist as _sdist class build_docs(Command): - """Generate documentation into ./site.""" - description = "Build project documentation into ./site" + + description = "Build project documentation." user_options = [ ("clean", None, "clean the output directory before building"), ] @@ -20,20 +20,15 @@ def finalize_options(self): self.clean = bool(self.clean) def run(self): - outdir = Path("site") - if self.clean and outdir.exists(): - import shutil - shutil.rmtree(outdir) - outdir.mkdir(exist_ok=True) - - # run tools here ... - cmd = [sys.executable, "-m", "tools.expand_docs.expand_docs", "--out", str(outdir)] + + cmd = [sys.executable, "-m", "tools.toolchain", "--target", "docs"] + self.announce(f"Running: {' '.join(cmd)}", level=2) - # Build environment variables if you want to pass context + # Build environment variables to pass context env = dict(os.environ) env.setdefault("PYTHONHASHSEED", "0") subprocess.check_call(cmd, env=env) # fails the build on nonzero exit - self.announce(f"Docs generated in {outdir}", level=2) + self.announce(f"Docs generated.", level=2) class sdist(_sdist): def run(self): diff --git a/tools/README.md b/tools/README.md index ebd55af7..be6e7f60 100644 --- a/tools/README.md +++ b/tools/README.md @@ -41,6 +41,8 @@ uv sync ``` ### Install build module +> This can be skipped as the `build` module is now part of the build dependencies. + Make sure you have an up-to-date version of `pip` and of module `build` used to run the build: ``` python -m ensurepip diff --git a/tools/configuration.py b/tools/configuration.py index 57cc4d12..21419320 100644 --- a/tools/configuration.py +++ b/tools/configuration.py @@ -8,6 +8,6 @@ # Generated documents GENERATED_DIR = PROJECT_DIR.joinpath("../site") -GENERATED_DOCS_DIR = GENERATED_DIR.joinpath("/docs") +GENERATED_DOCS_DIR = GENERATED_DIR.joinpath("docs") XSD_FILE_PATH = PROJECT_DIR.joinpath("../xsd/xsd/NeTEx_publication.xsd") diff --git a/tools/expand_docs/expand_docs.py b/tools/expand_docs/expand_docs.py index 177272e5..03333902 100644 --- a/tools/expand_docs/expand_docs.py +++ b/tools/expand_docs/expand_docs.py @@ -6,13 +6,8 @@ import shutil import argparse import re -from abc import ABC - -from setuptools import Command - from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR - def copy_media_folder(input_folder, output_folder): """Copy media folder from input to output.""" media_src = os.path.join(input_folder, 'media') @@ -80,41 +75,28 @@ def process_markdown_file(input_path, output_path, base_folder): with open(output_path, 'w', encoding='utf-8') as f: f.write(content) - -def main(): - parser = argparse.ArgumentParser(description='Expand documentation by including examples and tables.') - parser.add_argument('--docs', default=DOCS_DIR, help=f"Input documentation folder (default = {DOCS_DIR})") - parser.add_argument('--out', default=GENERATED_DOCS_DIR, help=f"Output folder (default = {GENERATED_DOCS_DIR})") - args = parser.parse_args() - +def expand_docs(input_dir: str, output_dir: str): # Create output folder if it doesn't exist - os.makedirs(args.out, exist_ok=True) + os.makedirs(output_dir, exist_ok=True) # Copy media folder - copy_media_folder(args.docs, args.out) + copy_media_folder(input_dir, output_dir) # Process each markdown file - for filename in os.listdir(args.docs): + for filename in os.listdir(input_dir): if filename.endswith('.md'): - input_path = os.path.join(args.docs, filename) - output_path = os.path.join(args.out, filename) - process_markdown_file(input_path, output_path, args.docs) + input_md = os.path.join(input_dir, filename) + output_md = os.path.join(output_dir, filename) + process_markdown_file(input_md, output_md, input_dir) - print(f"Documentation expanded successfully to {args.out}") + print(f"Documentation expanded successfully to {output_dir}") +def main(): + parser = argparse.ArgumentParser(description='Expand documentation by including examples and tables.') + parser.add_argument('--docs', default=DOCS_DIR, help=f"Input documentation folder (default = {DOCS_DIR})") + parser.add_argument('--out', default=GENERATED_DOCS_DIR, help=f"Output folder (default = {GENERATED_DOCS_DIR})") + args = parser.parse_args() + expand_docs(args.docs, args.out) if __name__ == '__main__': main() - - -class ExpandDocs(Command, ABC): - """Setuptools plugin for the project build.""" - - def run(self) -> None: - """ - Execute the actions intended by the command. - (Side effects **SHOULD** only take place when :meth:`run` is executed, - for example, creating new files or writing to the terminal output). - """ - main() - pass \ No newline at end of file diff --git a/tools/md2html/__init__.py b/tools/md2html/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tools/md2html/md2html.py b/tools/md2html/md2html.py new file mode 100644 index 00000000..5c5c78da --- /dev/null +++ b/tools/md2html/md2html.py @@ -0,0 +1,74 @@ +import argparse +import os +import re + +import markdown +from pygments.formatters import HtmlFormatter + +from tools.configuration import GENERATED_DOCS_DIR + +MD_LINK_PATTERN = re.compile(r'(\[.*\])(\(.*\.)(md)(.*\))') +MD_LINK_REPLACEMENT = r'\1\2html\4' + +def generate_html(md: str) -> str: + + md_with_html_links = MD_LINK_PATTERN.sub(MD_LINK_REPLACEMENT, md) + body = generate_html_body(md_with_html_links) + + # Generate CSS for code highlighting + code_css = HtmlFormatter().get_style_defs(".codehilite") + + # Wrap in a simple HTML template + return f""" + + + + Title + + + + + {body} + + """ + +def generate_html_body(md: str) -> str: + """Convert Markdown to HTML fragment.""" + body = markdown.markdown( + md, + extensions=[ + "extra", # tables, footnotes, etc. + "fenced_code", # triple-backtick code blocks + "codehilite" # Pygments-based syntax highlighting + ], + extension_configs={ + "codehilite": {"guess_lang": True, "noclasses": False} + }, + ) + return body + +def generate_html_files(src_dir: str): + """Generate HTML files from all markdown files in src_dir.""" + for filename in os.listdir(src_dir): + if filename.endswith('.md'): + md_path = os.path.join(src_dir, filename) + with open(md_path, 'r', encoding='utf-8') as f: + md = f.read() + html = generate_html(md) + html_path = md_path.replace('.md', '.html') + with open(html_path, 'w', encoding='utf-8') as f: + f.write(html) + print(f"Generated HTML files in {src_dir}") + +def main(): + parser = argparse.ArgumentParser(description='Generate HTML files from Markdown files.') + parser.add_argument('--dir', default=GENERATED_DOCS_DIR, help=f"Folder to search for md files (default = {GENERATED_DOCS_DIR})") + args = parser.parse_args() + generate_html_files(args.dir) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/tools/toolchain.py b/tools/toolchain.py new file mode 100644 index 00000000..e3f4dc35 --- /dev/null +++ b/tools/toolchain.py @@ -0,0 +1,17 @@ +import argparse +import shutil + +from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR +from tools.expand_docs.expand_docs import expand_docs +from tools.md2html.md2html import generate_html_files + + +def main(): + parser = argparse.ArgumentParser(description='Run tools to generate documents.') + parser.add_argument('--target', default="docs", help=f"Target to generate (default: docs)") + args = parser.parse_args() + expand_docs(DOCS_DIR, GENERATED_DOCS_DIR) + generate_html_files(GENERATED_DOCS_DIR) + +if __name__ == '__main__': + main() diff --git a/uv.lock b/uv.lock index 8c6dbab0..a9382746 100644 --- a/uv.lock +++ b/uv.lock @@ -20,6 +20,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566, upload-time = "2020-05-11T07:59:49.499Z" }, ] +[[package]] +name = "build" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/e0/df5e171f685f82f37b12e1f208064e24244911079d7b767447d1af7e0d70/build-1.5.0.tar.gz", hash = "sha256:302c22c3ba2a0fd5f3911918651341ebb3896176cbdec15bd421f80b1afc7647", size = 89796, upload-time = "2026-04-30T03:18:25.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl", hash = "sha256:13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f", size = 26018, upload-time = "2026-04-30T03:18:23.644Z" }, +] + [[package]] name = "click" version = "8.3.3" @@ -142,6 +156,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/39/53/8ba3cd5984f8363635450c93f63e541a0721b362bb32ae0d8237d9674aee/lxml-6.0.4-cp314-cp314t-win_arm64.whl", hash = "sha256:1dcd9e6cb9b7df808ea33daebd1801f37a8f50e8c075013ed2a2343246727838", size = 3816184, upload-time = "2026-04-12T16:26:57.011Z" }, ] +[[package]] +name = "markdown" +version = "3.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950", size = 368805, upload-time = "2026-02-09T14:57:26.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36", size = 108180, upload-time = "2026-02-09T14:57:25.787Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -220,16 +243,42 @@ name = "netex-rg-ch-test" version = "0.1.2" source = { editable = "." } dependencies = [ + { name = "build" }, { name = "lxml" }, + { name = "markdown" }, + { name = "pip" }, + { name = "pygments" }, { name = "pyschematron" }, ] [package.metadata] requires-dist = [ + { name = "build" }, { name = "lxml" }, + { name = "markdown" }, + { name = "pip" }, + { name = "pygments" }, { name = "pyschematron" }, ] +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pip" +version = "26.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/48/cb9b7a682f6fe01a4221e1728941dd4ac3cd9090a17db3779d6ff490b602/pip-26.1.1.tar.gz", hash = "sha256:d36762751d156a4ee895de8af39aa0abeeeb577f93a2eca6ab62467bbf0f8a78", size = 1840400, upload-time = "2026-05-04T19:02:21.248Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl", hash = "sha256:99cb1c2899893b075ff56e4ed0af55669a955b49ad7fb8d8603ecdaf4ed653fb", size = 1812777, upload-time = "2026-05-04T19:02:18.9Z" }, +] + [[package]] name = "pygments" version = "2.20.0" @@ -239,6 +288,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + [[package]] name = "pyschematron" version = "1.1.14" From 1a0ec25364c203a762a189c59994232722496c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 29 May 2026 17:34:29 +0200 Subject: [PATCH 08/41] Add md builder (#5) * Add md tables to build. * Remove arg parser. * Optimize imports. * Do not add __pycache__ to git. --- .gitignore | 2 + pyproject.toml | 2 +- tools/configuration.py | 1 + .../__pycache__/md_builder.cpython-313.pyc | Bin 26570 -> 26881 bytes tools/md_builder/md_builder.py | 55 +++++++++--------- tools/toolchain.py | 20 ++++--- tools/validation/xml_validator.py | 5 +- 7 files changed, 43 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 6d4a4cd4..b575335c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ generated/xcore/contab/netex.html templates/README.md~ tools/schematron_builder/__pycache__/template2schematron.cpython-313.pyc __pycache__ +**/__pycache__/ + netex_rg_ch.egg-info dist/ site/ diff --git a/pyproject.toml b/pyproject.toml index 14a83c40..849a3ef4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=70","markdown","pygments"] +requires = ["setuptools>=70","markdown","pygments","lxml"] build-backend = "setuptools.build_meta" [project] diff --git a/tools/configuration.py b/tools/configuration.py index 21419320..0e2948b2 100644 --- a/tools/configuration.py +++ b/tools/configuration.py @@ -9,5 +9,6 @@ # Generated documents GENERATED_DIR = PROJECT_DIR.joinpath("../site") GENERATED_DOCS_DIR = GENERATED_DIR.joinpath("docs") +GENERATED_TABLES_DIR = GENERATED_DIR.joinpath("markdown-examples") XSD_FILE_PATH = PROJECT_DIR.joinpath("../xsd/xsd/NeTEx_publication.xsd") diff --git a/tools/md_builder/__pycache__/md_builder.cpython-313.pyc b/tools/md_builder/__pycache__/md_builder.cpython-313.pyc index 361d315e616c193cf2f655674b3c4d634d8e05a2..f788f7789122f7da638632e43adca30dfd4fd4b6 100644 GIT binary patch delta 4319 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 delta 3897 zcmZ8kYiwNA5x(cX_GNqR^*XjUvAup_uVLdn>_Ge?;SrKJhRB-@t{t+u-o3WhS>JWe zT@$lZbwH&}lvZGlfDj%@h)_uTgM@7-2yxY2l+=_Ag(?K#A8B4phAR1 z#9l%P{}rjoep*+!O2G}eVg%SrVEQ%R~PEO|^%O@dfD z>kNm}QyGxU2AQk}3xPSERl?zEGm&jz-Fkx{&8 z+r=7M1f=ClrL{y1HWJI+H>t;x#z>l0!9->5pgiv(K{j68M(Ws!;?oLMfzR$LsVhSw zTe!Nlb=vIEQ~HE%WN3)}qNJuiggV_5Nh6ky$ET{Bd$T0ij&gi#xiaa= zSW3TFPlXi9*=ulaEh;KlP|j_mDy#C9lM>eMTf2S*%J>jU5z0{7F_JVAS}J8ZjWnH@ z)G}k1Jf2P(v>Zh$*pt2*XC;uKY8qgF_PtM<*yE*bs=XYWEA1hxnAhLrMZeIBJcM$$ z`v+9Anmrq6^(~raVj2a5w1|BYC{r{T{EmGeh>O&l+q<$$RO|5dT6VIkfz-3VRJHC# zTP^vZmfCMQbt7TIv5(od_n;^Sx8)k>+p!blhtivHtW4u3D7U$Y-ioY6j~Lp7P8-ZX;n5H)PU>B79j>^EE3!_}3Qt6;{&O$D!c!1mXw>l6wTujjt3zU;ikHX6nhlaD44 z>H+SgI+D0$8b(-+&EZTzjI_k32Mxb|9de=>~)w0W8IwOeHgP6EZd<+=77Kq8J{bl{A3# zIKrZfXal}WClR6u+^vNp=_w-t(H|R0rgVA$Cl=3|-jBmJb~?099YV67T@H0uU=r9n z+=UeP@=BoC+LnNXkK zH23Jb;||EWa7QCK!Xh2bfxY-z27w#IU608D&VH<;C-f+gUtxU-6K!d!9h@NrdB% zcGdfy1LK4 zmYm3~>28x|9!B+eDNr6Aga=#5YX=FBkBvCliLlIc7+S7TJp*+XYLF#q#(n(k?I<~c z($6EDLEw2*LeogUg22yhKT;}Jyp4UesaZXWjLockbL}=fQ~G-Zym#my0L&7A;J)RV zv}w~OyOx&P#XqA@Os2GqZpYGVAfL`Xu=#11ofzD)Je8s>-23ajkE3SpV)Wp`VIjpm zz7&K!1b9I6h`1j_EU8}~$$IVu$HH|2ba&RdFzBYoQO8rPVn-u+hV|^&5Pks}&mr(A z&`^P6G?gCKQYOVXwbNx3snhJ#juioPlI2^h&#{H#V$x^Wg&hqI+;Sc)OXk0XZ}ZIH z=AUPkeOt&mwy$p|MELo>D&+$Z@Sncer>I__;v&01{JC%Xe?`;40N*3(T2_JaoGd3VDf)DVqMeqUp41IXIY^Tk9rDY?dxaRNvD|h)fHZxDRSedv zJgnYgn+F4Aob4HG0>gejSf}8H`)cmDgT15zi|XRz07`=I)!)eMk0W)^bFq&{RumTr z>&13rO9h1?2mAX-^~OBIAVc^Hewn31u?=Qy%SmQkbN$RiUbo8D8JHNYh%^hTGgCH2nvJE(+%8z!tv|50D+E~h- zclgn?im1|#2?LLz4%OI{APi`1&D~|*Hw9s+c9A#99)Xu0xye~{jrCj~+{CaycK_Y( zN|yp}MBI3p8O~+9TwGT|Z=pAwi%YwHEVrbulj}3wLye1uWZ_U2{AhTFn)3XpD}o(r z;YLXm3@Ix0hqz5c0|hhCibsU}YGD1+Q5QvB*Lvy>(g)GIOv3wPUxEaz=@G8cQ@ku> zXvgt+pj~qn3ihi4#m{46rNM`->7I5fmbNr)bZSZ z4SAT|^h*RxOZpYU*8q@{GPc@K&S!uXK>jxXmTP(<#mlcr|AS0BIgz@8@GS!G3+90` zvE^P~(Cun2PiW9P{s42AAo|RAh#(viKJ=6w?K*VZcdDSc=L)KhB~FYzId*Jt&Rx*_ zo*eqnf8EKwVDBUH6P{Vm$;7+z^~kF|=|2-V z6?kFSi$iCJUJ1V^qhwXhiS5U?gP!au_P(~W!4?^~=-+VI1=Gd#CpTX7b{&@gCS0qBnx3Wy+s|5maUl!ow{YY5xkx+kGaLubKshRf`65n^hts?Qw?`B8F8XD*8 i0%Ql7?`S2hR}w^!3l3*5N|pbRoeyofA_;PUFZ+MoA)4O+ diff --git a/tools/md_builder/md_builder.py b/tools/md_builder/md_builder.py index 4aae0e5d..fade671a 100644 --- a/tools/md_builder/md_builder.py +++ b/tools/md_builder/md_builder.py @@ -5,22 +5,12 @@ with type information from XSD schemas. """ -import os -import sys import argparse -from lxml import etree -from collections import defaultdict -import re - +import os -def parse_args(): - """Parse command line arguments""" - parser = argparse.ArgumentParser(description='Generate markdown documentation from NeTEx templates') - parser.add_argument('-i', '--input', required=True, help='Input folder containing XML templates') - parser.add_argument('-o', '--output', required=True, help='Output folder for markdown files') - parser.add_argument('-x', '--xsd', required=True, help='XSD schema file for type information') - return parser.parse_args() +from lxml import etree +from tools.configuration import TEMPLATES_DIR, GENERATED_TABLES_DIR, XSD_FILE_PATH def load_xsd_type_info(xsd_path): """Load type and cardinality information from XSD""" @@ -695,7 +685,7 @@ def check_referenced_files_exist(data, template_dir): return True -def process_ch_profile_templates(input_dir, output_dir, xsd_type_info): +def process_ch_profile_templates(input_dir: str, output_dir: str, xsd_type_info): """Process ch-profile template files and generate MD files""" ch_profile_files = [f for f in os.listdir(input_dir) if f.startswith('ch-profile_') and f.endswith('.xml')] @@ -724,40 +714,36 @@ def process_ch_profile_templates(input_dir, output_dir, xsd_type_info): print(f"No data extracted from ch-profile template {xml_file}") -def main(): - args = parse_args() - +def build_markdown_tables(input_path: str, output_path: str, xsd_path: str): + # Load XSD type information - print(f"Loading XSD from {args.xsd}") - xsd_type_info = load_xsd_type_info(args.xsd) + print(f"Loading XSD from {xsd_path}") + xsd_type_info = load_xsd_type_info(xsd_path) print(f"Loaded {len(xsd_type_info)} type definitions") - - # Store XSD path for metadata extraction - xsd_path = args.xsd - + # Create output directory - os.makedirs(args.output, exist_ok=True) + os.makedirs(output_path, exist_ok=True) # Process ch-profile templates first - process_ch_profile_templates(args.input, args.output, xsd_type_info) + process_ch_profile_templates(input_path, output_path, xsd_type_info) # Process all XML files in input directory - xml_files = [f for f in os.listdir(args.input) if f.endswith('.xml') and not f.startswith('ch-profile_')] + xml_files = [f for f in os.listdir(input_path) if f.endswith('.xml') and not f.startswith('ch-profile_')] for xml_file in xml_files: print(f"Processing {xml_file}") - file_path = os.path.join(args.input, xml_file) + file_path = os.path.join(input_path, xml_file) # Parse template data = parse_template_file(file_path, xsd_type_info) if data: # Check for missing referenced files - check_referenced_files_exist(data, args.input) + check_referenced_files_exist(data, input_path) # Generate markdown filename (remove .xml, add .md) md_filename = os.path.splitext(xml_file)[0] + '.md' - md_path = os.path.join(args.output, md_filename) + md_path = os.path.join(output_path, md_filename) # Generate markdown content element_name = os.path.splitext(xml_file)[0] @@ -773,6 +759,17 @@ def main(): print(f"Processed {len(xml_files)} files") +def parse_args(): + """Parse command line arguments""" + parser = argparse.ArgumentParser(description='Generate markdown documentation from NeTEx templates') + parser.add_argument('-i', '--input', default=TEMPLATES_DIR, help=f'Input folder containing XML templates (Default = {TEMPLATES_DIR})') + parser.add_argument('-o', '--output', default=GENERATED_TABLES_DIR, help=f'Output folder for markdown files (Default = {GENERATED_TABLES_DIR})') + parser.add_argument('-x', '--xsd', default=XSD_FILE_PATH, help=f'XSD schema file for type information (Default = {XSD_FILE_PATH})') + return parser.parse_args() + +def main(): + args = parse_args() + build_markdown_tables(args.input, args.output, args.xsd) if __name__ == '__main__': main() \ No newline at end of file diff --git a/tools/toolchain.py b/tools/toolchain.py index e3f4dc35..3742f0fd 100644 --- a/tools/toolchain.py +++ b/tools/toolchain.py @@ -1,17 +1,19 @@ -import argparse -import shutil - -from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR +from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR, XSD_FILE_PATH, GENERATED_TABLES_DIR, TEMPLATES_DIR from tools.expand_docs.expand_docs import expand_docs from tools.md2html.md2html import generate_html_files +from tools.md_builder.md_builder import build_markdown_tables - -def main(): - parser = argparse.ArgumentParser(description='Run tools to generate documents.') - parser.add_argument('--target', default="docs", help=f"Target to generate (default: docs)") - args = parser.parse_args() +def generate_docs(): expand_docs(DOCS_DIR, GENERATED_DOCS_DIR) generate_html_files(GENERATED_DOCS_DIR) +def generate_tables(): + build_markdown_tables(TEMPLATES_DIR, GENERATED_TABLES_DIR, XSD_FILE_PATH) + generate_html_files(GENERATED_TABLES_DIR) + +def main(): + generate_docs() + generate_tables() + if __name__ == '__main__': main() diff --git a/tools/validation/xml_validator.py b/tools/validation/xml_validator.py index 0e29206f..dd4b4eca 100644 --- a/tools/validation/xml_validator.py +++ b/tools/validation/xml_validator.py @@ -8,8 +8,7 @@ import os import sys from lxml import etree -#from tools.configuration import XSD_FILE_PATH -XSD_FILE_PATH ="../xsd/xsd/NeTEx_publication.xsd" +from tools.configuration import XSD_FILE_PATH def load_schema(xsd_path): try: @@ -89,7 +88,7 @@ def main(): if os.path.isdir(args.xml): validate_folder(args.xml, args.xsd) else: - schema = load_schema(xsd_path) + schema = load_schema(XSD_FILE_PATH) if not schema: exit validate_xml(args.xml, schema) From d66860e8411d9aed019f3f029acad943f715eb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 29 May 2026 17:44:12 +0200 Subject: [PATCH 09/41] Delete tools/md_builder/__pycache__ directory --- .../__pycache__/md_builder.cpython-313.pyc | Bin 26881 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/md_builder/__pycache__/md_builder.cpython-313.pyc diff --git a/tools/md_builder/__pycache__/md_builder.cpython-313.pyc b/tools/md_builder/__pycache__/md_builder.cpython-313.pyc deleted file mode 100644 index f788f7789122f7da638632e43adca30dfd4fd4b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26881 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 From 1c549f7d2a8e653eeab134922c2f50e9f3cc2168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 29 May 2026 23:30:44 +0200 Subject: [PATCH 10/41] Add Jekyll files (#6) * Do not add __pycache__ to git. * Add jekyll files. --- .gitignore | 2 +- jekyll/.gitignore | 8 + jekyll/404.html | 25 ++ jekyll/Gemfile | 33 +++ jekyll/Gemfile.lock | 250 ++++++++++++++++++ jekyll/_config.yml | 55 ++++ .../2026-05-29-welcome-to-jekyll.markdown | 29 ++ jekyll/about.markdown | 18 ++ tools/configuration.py | 10 +- tools/expand_docs/expand_docs.py | 4 +- tools/md2html/md2html.py | 4 +- tools/md_builder/md_builder.py | 16 +- tools/toolchain.py | 30 ++- 13 files changed, 460 insertions(+), 24 deletions(-) create mode 100644 jekyll/.gitignore create mode 100644 jekyll/404.html create mode 100644 jekyll/Gemfile create mode 100644 jekyll/Gemfile.lock create mode 100644 jekyll/_config.yml create mode 100644 jekyll/_posts/2026-05-29-welcome-to-jekyll.markdown create mode 100644 jekyll/about.markdown diff --git a/.gitignore b/.gitignore index b575335c..5b970ae0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,6 @@ __pycache__ netex_rg_ch.egg-info dist/ -site/ build/ +site/ netex_rg_ch_test.egg-info/ \ No newline at end of file diff --git a/jekyll/.gitignore b/jekyll/.gitignore new file mode 100644 index 00000000..59444bc7 --- /dev/null +++ b/jekyll/.gitignore @@ -0,0 +1,8 @@ +_site +.sass-cache +.jekyll-cache +.jekyll-metadata +vendor +docs +media +tables diff --git a/jekyll/404.html b/jekyll/404.html new file mode 100644 index 00000000..3a16ab53 --- /dev/null +++ b/jekyll/404.html @@ -0,0 +1,25 @@ +--- +permalink: /404.html +layout: page +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found.

+
diff --git a/jekyll/Gemfile b/jekyll/Gemfile new file mode 100644 index 00000000..395750a0 --- /dev/null +++ b/jekyll/Gemfile @@ -0,0 +1,33 @@ +source "https://rubygems.org" +# Hello! This is where you manage which Jekyll version is used to run. +# When you want to use a different version, change it below, save the +# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: +# +# bundle exec jekyll serve +# +# This will help ensure the proper Jekyll version is running. +# Happy Jekylling! +gem "jekyll", "~> 4.4.1" +# This is the default theme for new Jekyll sites. You may change this to anything you like. +gem "minima", "~> 2.5" +# If you want to use GitHub Pages, remove the "gem "jekyll"" above and +# uncomment the line below. To upgrade, run `bundle update github-pages`. +# gem "github-pages", group: :jekyll_plugins +# If you have any plugins, put them here! +group :jekyll_plugins do + gem "jekyll-feed", "~> 0.12" +end + +# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem +# and associated library. +platforms :mingw, :x64_mingw, :mswin, :jruby do + gem "tzinfo", ">= 1", "< 3" + gem "tzinfo-data" +end + +# Performance-booster for watching directories on Windows +gem "wdm", "~> 0.1", :platforms => [:mingw, :x64_mingw, :mswin] + +# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem +# do not have a Java counterpart. +gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby] diff --git a/jekyll/Gemfile.lock b/jekyll/Gemfile.lock new file mode 100644 index 00000000..edb59c6a --- /dev/null +++ b/jekyll/Gemfile.lock @@ -0,0 +1,250 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + base64 (0.3.0) + bigdecimal (4.1.2) + colorator (1.1.0) + concurrent-ruby (1.3.6) + csv (3.3.5) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + eventmachine (1.2.7) + ffi (1.17.4) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) + ffi (1.17.4-x86_64-darwin) + ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) + forwardable-extended (2.6.0) + google-protobuf (4.35.0) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-aarch64-linux-gnu) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-aarch64-linux-musl) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-arm64-darwin) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-x86-linux-gnu) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-x86-linux-musl) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-x86_64-darwin) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-x86_64-linux-gnu) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.0-x86_64-linux-musl) + bigdecimal + rake (~> 13.3) + http_parser.rb (0.8.1) + i18n (1.14.8) + concurrent-ruby (~> 1.0) + jekyll (4.4.1) + addressable (~> 2.4) + base64 (~> 0.2) + colorator (~> 1.0) + csv (~> 3.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (>= 2.0, < 4.0) + jekyll-watch (~> 2.0) + json (~> 2.6) + kramdown (~> 2.3, >= 2.3.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.3, >= 0.3.6) + pathutil (~> 0.9) + rouge (>= 3.0, < 5.0) + safe_yaml (~> 1.0) + terminal-table (>= 1.8, < 4.0) + webrick (~> 1.7) + jekyll-feed (0.17.0) + jekyll (>= 3.7, < 5.0) + jekyll-sass-converter (3.1.0) + sass-embedded (~> 1.75) + jekyll-seo-tag (2.9.0) + jekyll (>= 3.8, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + json (2.19.7) + kramdown (2.5.2) + rexml (>= 3.4.4) + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.10.0) + logger + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) + mercenary (0.4.0) + minima (2.5.2) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (7.0.5) + rake (13.4.2) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.4.4) + rouge (4.7.0) + safe_yaml (1.0.5) + sass-embedded (1.100.0) + google-protobuf (~> 4.31) + rake (>= 13) + sass-embedded (1.100.0-aarch64-linux-android) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-aarch64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-aarch64-linux-musl) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-arm-linux-androideabi) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-arm-linux-gnueabihf) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-arm-linux-musleabihf) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-arm64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-riscv64-linux-android) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-riscv64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-riscv64-linux-musl) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-x86_64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-x86_64-linux-android) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-x86_64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.100.0-x86_64-linux-musl) + google-protobuf (~> 4.31) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.6.0) + webrick (1.9.2) + +PLATFORMS + aarch64-linux-android + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-androideabi + arm-linux-gnu + arm-linux-gnueabihf + arm-linux-musl + arm-linux-musleabihf + arm64-darwin + riscv64-linux-android + riscv64-linux-gnu + riscv64-linux-musl + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-android + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + http_parser.rb (~> 0.6.0) + jekyll (~> 4.4.1) + jekyll-feed (~> 0.12) + minima (~> 2.5) + tzinfo (>= 1, < 3) + tzinfo-data + wdm (~> 0.1) + +CHECKSUMS + addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + bundler (4.0.12) sha256=7f8b757d28dfb636e7b24fba2344ac6dd13b5b24f4b46d62573d483f211825ac + colorator (1.1.0) sha256=e2f85daf57af47d740db2a32191d1bdfb0f6503a0dfbc8327d0c9154d5ddfc38 + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f + em-websocket (0.5.3) sha256=f56a92bde4e6cb879256d58ee31f124181f68f8887bd14d53d5d9a292758c6a8 + eventmachine (1.2.7) sha256=994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972 + ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf + ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df + ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 + ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564 + ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95 + ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b + ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf + ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809 + ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 + ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d + ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e + forwardable-extended (2.6.0) sha256=1bec948c469bbddfadeb3bd90eb8c85f6e627a412a3e852acfd7eaedbac3ec97 + google-protobuf (4.35.0) sha256=95346162c792ed78c9a28cbf2d937a53f706de6df36a27471582f63f03c30c0d + google-protobuf (4.35.0-aarch64-linux-gnu) sha256=2cabd61b420918aec1564f9f7414e455bf922d20c5f8139d62783df5558a7aea + google-protobuf (4.35.0-aarch64-linux-musl) sha256=f6b11f3420a4564f68e8233c95eac6924f6a727dfc2f81a56af2e09add551501 + google-protobuf (4.35.0-arm64-darwin) sha256=66ab26d3fc82b8950702e53ab16c198e3c0ea3f2a38aaaf1f32152da45593ac5 + google-protobuf (4.35.0-x86-linux-gnu) sha256=7a5b5681c7d7bf28e1a6e285e45bf55c4ef47b7b1ca8af6ff79964255efece9a + google-protobuf (4.35.0-x86-linux-musl) sha256=f481b63b176c0335db8b50e46f033c0956857a599d9feafdd891a5c18ce28d43 + google-protobuf (4.35.0-x86_64-darwin) sha256=05eb5c8bc9899135befff496fc0a3642e7ff3d0943f043841dcc456f5654fea0 + google-protobuf (4.35.0-x86_64-linux-gnu) sha256=999226f3b00cd9fddb1b26851d16060212fa1d90c406aaad47e574682b716059 + google-protobuf (4.35.0-x86_64-linux-musl) sha256=be0218520d77b2aee898b363514b03819f6f63f9c041ae0d0d79b4ce5247bffd + http_parser.rb (0.8.1) sha256=9ae8df145b39aa5398b2f90090d651c67bd8e2ebfe4507c966579f641e11097a + i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 + jekyll (4.4.1) sha256=4c1144d857a5b2b80d45b8cf5138289579a9f8136aadfa6dd684b31fe2bc18c1 + jekyll-feed (0.17.0) sha256=689aab16c877949bb9e7a5c436de6278318a51ecb974792232fd94d8b3acfcc3 + jekyll-sass-converter (3.1.0) sha256=83925d84f1d134410c11d0c6643b0093e82e3a3cf127e90757a85294a3862443 + jekyll-seo-tag (2.9.0) sha256=0260015a8e1df9bf195cdfb0c675b7b2883fd8cbf12556e1c1cbe36a831c6852 + jekyll-watch (2.2.1) sha256=bc44ed43f5e0a552836245a54dbff3ea7421ecc2856707e8a1ee203a8387a7e1 + json (2.19.7) sha256=fe432c8639f6efff69f9d73b518a3705d9581ab93156f981ea72806e1e5bcc3e + kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 + liquid (4.0.4) sha256=4fcfebb1a045e47918388dbb7a0925e7c3893e58d2bd6c3b3c73ec17a2d8fdb3 + listen (3.10.0) sha256=c6e182db62143aeccc2e1960033bebe7445309c7272061979bb098d03760c9d2 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + mercenary (0.4.0) sha256=b25a1e4a59adca88665e08e24acf0af30da5b5d859f7d8f38fba52c28f405138 + minima (2.5.2) sha256=9c434e3b7bc4a0f0ab488910438ed3757a0502ff1060d172f361907fc38aa45a + pathutil (0.16.2) sha256=e43b74365631cab4f6d5e4228f812927efc9cb2c71e62976edcb252ee948d589 + public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 + rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe + rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 + rouge (4.7.0) sha256=dba5896715c0325c362e895460a6d350803dbf6427454f49a47500f3193ea739 + safe_yaml (1.0.5) sha256=a6ac2d64b7eb027bdeeca1851fe7e7af0d668e133e8a88066a0c6f7087d9f848 + sass-embedded (1.100.0) sha256=b7d4831f304be5ba8717b2a1307644164b63dc158113a67f469e90578d3fc092 + sass-embedded (1.100.0-aarch64-linux-android) sha256=9603e1c26bea0396e849e3c3bb75b6843a43bae7a32c580084fd6c64260d9ef8 + sass-embedded (1.100.0-aarch64-linux-gnu) sha256=c13187f8eaae7e7e64246b18eb896534a84465a17198829ef65730db4662860e + sass-embedded (1.100.0-aarch64-linux-musl) sha256=1b0945a66cd4e40f505db73b1e790e2561e07e6d9fd04ef6ebbf279835666b3f + sass-embedded (1.100.0-arm-linux-androideabi) sha256=9948122504b69e20dc82a3b8fc20b3a61ea58a4713a713f64630b4c9a36f11e1 + sass-embedded (1.100.0-arm-linux-gnueabihf) sha256=a2de272bb02977ea91acaf3fecb6d8e09e4989501efbfc5375da4b5e7bff001d + sass-embedded (1.100.0-arm-linux-musleabihf) sha256=ce19837c10bab5ae6785f10b435a57a64ca027a99875cd701dc6fd3af317cbe5 + sass-embedded (1.100.0-arm64-darwin) sha256=d294b32c3b7bed293ad39bd392713c07f1df5454e65fa0f8d80dadbdba8a0cf4 + sass-embedded (1.100.0-riscv64-linux-android) sha256=148669225f027eeedea0a27e474dc69448567c030c56792114894f55a68af38e + sass-embedded (1.100.0-riscv64-linux-gnu) sha256=880ff1fca280b45b4d223366606aa634177adf38e793ad521426be7ad70a1ef2 + sass-embedded (1.100.0-riscv64-linux-musl) sha256=a8568d17343dcf0278d48b2efb4b3490ebe3ba0279ec4d69753e8ce4fd0614fa + sass-embedded (1.100.0-x86_64-darwin) sha256=3db80c837a60712de3461d5aa1be43c7056a0584d7182a8ae7a8996d64ab46d3 + sass-embedded (1.100.0-x86_64-linux-android) sha256=1600dbddf82c83344a5bc2a5e163081efdf15661f782922603574328888cd2cc + sass-embedded (1.100.0-x86_64-linux-gnu) sha256=58dd0a8a4f0dd78881b90d8b0e4d0eed042d54865b19b71384d91091ade93e18 + sass-embedded (1.100.0-x86_64-linux-musl) sha256=03dbee81bf93e770c725caf0c895e04c7b049ebef56b8a7002fcf21e6bedf7c5 + terminal-table (3.0.2) sha256=f951b6af5f3e00203fb290a669e0a85c5dd5b051b3b023392ccfd67ba5abae91 + unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a + webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 + +BUNDLED WITH + 4.0.12 diff --git a/jekyll/_config.yml b/jekyll/_config.yml new file mode 100644 index 00000000..afff3a86 --- /dev/null +++ b/jekyll/_config.yml @@ -0,0 +1,55 @@ +# Welcome to Jekyll! +# +# This config file is meant for settings that affect your whole blog, values +# which you are expected to set up once and rarely edit after that. If you find +# yourself editing this file very often, consider using Jekyll's data files +# feature for the data you need to update frequently. +# +# For technical reasons, this file is *NOT* reloaded automatically when you use +# 'bundle exec jekyll serve'. If you change this file, please restart the server process. +# +# If you need help with YAML syntax, here are some quick references for you: +# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml +# https://learnxinyminutes.com/docs/yaml/ +# +# Site settings +# These are used to personalize your new site. If you look in the HTML files, +# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. +# You can create any custom variable you would like, and they will be accessible +# in the templates via {{ site.myvariable }}. + +title: NeTEx Realization Guide for Switzerland +email: your-email@example.com +description: >- # this means to ignore newlines until "baseurl:" + Write an awesome description for your new site here. You can edit this + line in _config.yml. It will appear in your document head meta (for + Google search results) and in your feed.xml site description. +baseurl: "" # the subpath of your site, e.g. /blog +url: "" # the base hostname & protocol for your site, e.g. http://example.com +twitter_username: jekyllrb +github_username: jekyll + +# Build settings +theme: minima +plugins: + - jekyll-feed + +# Exclude from processing. +# The following items will not be processed, by default. +# Any item listed under the `exclude:` key here will be automatically added to +# the internal "default list". +# +# Excluded items can be processed by explicitly listing the directories or +# their entries' file path in the `include:` list. +# +# exclude: +# - .sass-cache/ +# - .jekyll-cache/ +# - gemfiles/ +# - Gemfile +# - Gemfile.lock +# - node_modules/ +# - vendor/bundle/ +# - vendor/cache/ +# - vendor/gems/ +# - vendor/ruby/ diff --git a/jekyll/_posts/2026-05-29-welcome-to-jekyll.markdown b/jekyll/_posts/2026-05-29-welcome-to-jekyll.markdown new file mode 100644 index 00000000..13215d5b --- /dev/null +++ b/jekyll/_posts/2026-05-29-welcome-to-jekyll.markdown @@ -0,0 +1,29 @@ +--- +layout: post +title: "Welcome to Jekyll!" +date: 2026-05-29 20:35:41 +0200 +categories: jekyll update +--- +You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated. + +Jekyll requires blog post files to be named according to the following format: + +`YEAR-MONTH-DAY-title.MARKUP` + +Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works. + +Jekyll also offers powerful support for code snippets: + +{% highlight ruby %} +def print_hi(name) + puts "Hi, #{name}" +end +print_hi('Tom') +#=> prints 'Hi, Tom' to STDOUT. +{% endhighlight %} + +Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk]. + +[jekyll-docs]: https://jekyllrb.com/docs/home +[jekyll-gh]: https://github.com/jekyll/jekyll +[jekyll-talk]: https://talk.jekyllrb.com/ diff --git a/jekyll/about.markdown b/jekyll/about.markdown new file mode 100644 index 00000000..8b4e0b28 --- /dev/null +++ b/jekyll/about.markdown @@ -0,0 +1,18 @@ +--- +layout: page +title: About +permalink: /about/ +--- + +This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](https://jekyllrb.com/) + +You can find the source code for Minima at GitHub: +[jekyll][jekyll-organization] / +[minima](https://github.com/jekyll/minima) + +You can find the source code for Jekyll at GitHub: +[jekyll][jekyll-organization] / +[jekyll](https://github.com/jekyll/jekyll) + + +[jekyll-organization]: https://github.com/jekyll diff --git a/tools/configuration.py b/tools/configuration.py index 0e2948b2..9515dd72 100644 --- a/tools/configuration.py +++ b/tools/configuration.py @@ -5,10 +5,12 @@ # Source documents DOCS_DIR = PROJECT_DIR.joinpath("../docs") TEMPLATES_DIR = PROJECT_DIR.joinpath("../templates") +JEKYLL_DIR = PROJECT_DIR.joinpath("../jekyll") + +XSD_FILE_PATH = PROJECT_DIR.joinpath("../xsd/xsd/NeTEx_publication.xsd") # Generated documents -GENERATED_DIR = PROJECT_DIR.joinpath("../site") -GENERATED_DOCS_DIR = GENERATED_DIR.joinpath("docs") -GENERATED_TABLES_DIR = GENERATED_DIR.joinpath("markdown-examples") +SITE_DIR = PROJECT_DIR.joinpath("../site") +SITE_TABLES_DIR = SITE_DIR.joinpath("tables") + -XSD_FILE_PATH = PROJECT_DIR.joinpath("../xsd/xsd/NeTEx_publication.xsd") diff --git a/tools/expand_docs/expand_docs.py b/tools/expand_docs/expand_docs.py index 03333902..2f685931 100644 --- a/tools/expand_docs/expand_docs.py +++ b/tools/expand_docs/expand_docs.py @@ -6,7 +6,7 @@ import shutil import argparse import re -from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR +from tools.configuration import DOCS_DIR, SITE_DIR def copy_media_folder(input_folder, output_folder): """Copy media folder from input to output.""" @@ -94,7 +94,7 @@ def expand_docs(input_dir: str, output_dir: str): def main(): parser = argparse.ArgumentParser(description='Expand documentation by including examples and tables.') parser.add_argument('--docs', default=DOCS_DIR, help=f"Input documentation folder (default = {DOCS_DIR})") - parser.add_argument('--out', default=GENERATED_DOCS_DIR, help=f"Output folder (default = {GENERATED_DOCS_DIR})") + parser.add_argument('--out', default=SITE_DIR, help=f"Output folder (default = {SITE_DIR})") args = parser.parse_args() expand_docs(args.docs, args.out) diff --git a/tools/md2html/md2html.py b/tools/md2html/md2html.py index 5c5c78da..a1b1d87f 100644 --- a/tools/md2html/md2html.py +++ b/tools/md2html/md2html.py @@ -5,7 +5,7 @@ import markdown from pygments.formatters import HtmlFormatter -from tools.configuration import GENERATED_DOCS_DIR +from tools.configuration import SITE_DIR MD_LINK_PATTERN = re.compile(r'(\[.*\])(\(.*\.)(md)(.*\))') MD_LINK_REPLACEMENT = r'\1\2html\4' @@ -66,7 +66,7 @@ def generate_html_files(src_dir: str): def main(): parser = argparse.ArgumentParser(description='Generate HTML files from Markdown files.') - parser.add_argument('--dir', default=GENERATED_DOCS_DIR, help=f"Folder to search for md files (default = {GENERATED_DOCS_DIR})") + parser.add_argument('--dir', default=SITE_DIR, help=f"Folder to search for md files (default = {SITE_DIR})") args = parser.parse_args() generate_html_files(args.dir) diff --git a/tools/md_builder/md_builder.py b/tools/md_builder/md_builder.py index fade671a..79c7635a 100644 --- a/tools/md_builder/md_builder.py +++ b/tools/md_builder/md_builder.py @@ -7,10 +7,8 @@ import argparse import os - from lxml import etree - -from tools.configuration import TEMPLATES_DIR, GENERATED_TABLES_DIR, XSD_FILE_PATH +from tools.configuration import TEMPLATES_DIR, XSD_FILE_PATH, SITE_TABLES_DIR def load_xsd_type_info(xsd_path): """Load type and cardinality information from XSD""" @@ -519,7 +517,7 @@ def process_element(element, level=0): return None -def generate_markdown_table(data, filename, xsd_type_info): +def generate_markdown_table(data, filename, xsd_path: str, xsd_type_info): """Generate markdown table from parsed data""" if not data: return '' @@ -685,7 +683,7 @@ def check_referenced_files_exist(data, template_dir): return True -def process_ch_profile_templates(input_dir: str, output_dir: str, xsd_type_info): +def process_ch_profile_templates(input_dir: str, output_dir: str, xsd_path: str, xsd_type_info): """Process ch-profile template files and generate MD files""" ch_profile_files = [f for f in os.listdir(input_dir) if f.startswith('ch-profile_') and f.endswith('.xml')] @@ -703,7 +701,7 @@ def process_ch_profile_templates(input_dir: str, output_dir: str, xsd_type_info) # Generate markdown content element_name = os.path.splitext(xml_file)[0] - markdown_content = generate_markdown_table(data, element_name, xsd_type_info) + markdown_content = generate_markdown_table(data, element_name, xsd_path, xsd_type_info) # Write to file with open(md_path, 'w', encoding='utf-8') as f: @@ -725,7 +723,7 @@ def build_markdown_tables(input_path: str, output_path: str, xsd_path: str): os.makedirs(output_path, exist_ok=True) # Process ch-profile templates first - process_ch_profile_templates(input_path, output_path, xsd_type_info) + process_ch_profile_templates(input_path, output_path, xsd_path, xsd_type_info) # Process all XML files in input directory xml_files = [f for f in os.listdir(input_path) if f.endswith('.xml') and not f.startswith('ch-profile_')] @@ -747,7 +745,7 @@ def build_markdown_tables(input_path: str, output_path: str, xsd_path: str): # Generate markdown content element_name = os.path.splitext(xml_file)[0] - markdown_content = generate_markdown_table(data, element_name, xsd_type_info) + markdown_content = generate_markdown_table(data, element_name, xsd_path, xsd_type_info) # Write to file with open(md_path, 'w', encoding='utf-8') as f: @@ -763,7 +761,7 @@ def parse_args(): """Parse command line arguments""" parser = argparse.ArgumentParser(description='Generate markdown documentation from NeTEx templates') parser.add_argument('-i', '--input', default=TEMPLATES_DIR, help=f'Input folder containing XML templates (Default = {TEMPLATES_DIR})') - parser.add_argument('-o', '--output', default=GENERATED_TABLES_DIR, help=f'Output folder for markdown files (Default = {GENERATED_TABLES_DIR})') + parser.add_argument('-o', '--output', default=SITE_TABLES_DIR, help=f'Output folder for markdown files (Default = {SITE_TABLES_DIR})') parser.add_argument('-x', '--xsd', default=XSD_FILE_PATH, help=f'XSD schema file for type information (Default = {XSD_FILE_PATH})') return parser.parse_args() diff --git a/tools/toolchain.py b/tools/toolchain.py index 3742f0fd..47e22a9d 100644 --- a/tools/toolchain.py +++ b/tools/toolchain.py @@ -1,17 +1,35 @@ -from tools.configuration import DOCS_DIR, GENERATED_DOCS_DIR, XSD_FILE_PATH, GENERATED_TABLES_DIR, TEMPLATES_DIR + +import os +import shutil +from pathlib import Path + +from tools.configuration import DOCS_DIR, SITE_DIR, XSD_FILE_PATH, SITE_TABLES_DIR, TEMPLATES_DIR, JEKYLL_DIR from tools.expand_docs.expand_docs import expand_docs -from tools.md2html.md2html import generate_html_files from tools.md_builder.md_builder import build_markdown_tables + +def clean(dir: str): + dir_path = Path(dir) + if dir_path.exists(): + shutil.rmtree(dir) + os.makedirs(dir, exist_ok=True) + +def copy_jekyll_files(): + src = Path(JEKYLL_DIR) + dst = Path(SITE_DIR) + shutil.copytree(src, dst, dirs_exist_ok=True) + def generate_docs(): - expand_docs(DOCS_DIR, GENERATED_DOCS_DIR) - generate_html_files(GENERATED_DOCS_DIR) + expand_docs(DOCS_DIR, SITE_DIR) + # generate_html_files(SITE_DIR) def generate_tables(): - build_markdown_tables(TEMPLATES_DIR, GENERATED_TABLES_DIR, XSD_FILE_PATH) - generate_html_files(GENERATED_TABLES_DIR) + build_markdown_tables(TEMPLATES_DIR, SITE_TABLES_DIR, XSD_FILE_PATH) + # generate_html_files(SITE_TABLES_DIR) def main(): + clean(SITE_DIR) + copy_jekyll_files() generate_docs() generate_tables() From 0b893ec8ceb0fe951d7d33a3ac1d110fbac30341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 29 May 2026 23:45:25 +0200 Subject: [PATCH 11/41] Modified jekyll config for markdown. (#7) --- jekyll/_config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index afff3a86..7aace6b1 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -24,13 +24,13 @@ description: >- # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. -baseurl: "" # the subpath of your site, e.g. /blog -url: "" # the base hostname & protocol for your site, e.g. http://example.com -twitter_username: jekyllrb -github_username: jekyll +baseurl: "/netexRgTest" # the subpath of your site, e.g. /blog + +url: "https://opentdatach.github.io" # the base hostname & protocol for your site, e.g. http://example.com # Build settings theme: minima +markdown: kramdown plugins: - jekyll-feed From 268812c5c18427c1faa178d36811eed0e706b13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 29 May 2026 23:49:38 +0200 Subject: [PATCH 12/41] Rename docs/README.md. --- docs/{README.md => index.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{README.md => index.md} (100%) diff --git a/docs/README.md b/docs/index.md similarity index 100% rename from docs/README.md rename to docs/index.md From 4d9dae542a8649142ffcc6da8aad3fc383ed539e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 00:14:45 +0200 Subject: [PATCH 13/41] Switch to github-pages gem. --- jekyll/.gitignore | 4 +--- jekyll/Gemfile | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jekyll/.gitignore b/jekyll/.gitignore index 59444bc7..918de83e 100644 --- a/jekyll/.gitignore +++ b/jekyll/.gitignore @@ -3,6 +3,4 @@ _site .jekyll-cache .jekyll-metadata vendor -docs -media -tables +Gemfile.lock diff --git a/jekyll/Gemfile b/jekyll/Gemfile index 395750a0..987a07da 100644 --- a/jekyll/Gemfile +++ b/jekyll/Gemfile @@ -7,7 +7,8 @@ source "https://rubygems.org" # # This will help ensure the proper Jekyll version is running. # Happy Jekylling! -gem "jekyll", "~> 4.4.1" +# gem "jekyll", "~> 4.4.1" +gem "github-pages","~> 232",group: :jekyll_plugins # This is the default theme for new Jekyll sites. You may change this to anything you like. gem "minima", "~> 2.5" # If you want to use GitHub Pages, remove the "gem "jekyll"" above and From 927bbcced1c24f004f4c9a99cdecdcd3f82cfb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 00:24:10 +0200 Subject: [PATCH 14/41] Try different config. --- jekyll/_config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 7aace6b1..0e44bf41 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -24,8 +24,8 @@ description: >- # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. -baseurl: "/netexRgTest" # the subpath of your site, e.g. /blog - +baseurl: "netexRgTest" # the subpath of your site, e.g. /blog +domain: "opentdatach.github.io" url: "https://opentdatach.github.io" # the base hostname & protocol for your site, e.g. http://example.com # Build settings From c4715ed3e9b43f2cf8cd328544378081f8d95259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 00:31:15 +0200 Subject: [PATCH 15/41] Try different config. --- jekyll/_config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 0e44bf41..8da521c7 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -24,9 +24,9 @@ description: >- # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. -baseurl: "netexRgTest" # the subpath of your site, e.g. /blog -domain: "opentdatach.github.io" -url: "https://opentdatach.github.io" # the base hostname & protocol for your site, e.g. http://example.com +baseurl: /netexRgTest # the subpath of your site, e.g. /blog +domain: opentdatach.github.io +url: https://opentdatach.github.io # the base hostname & protocol for your site, e.g. http://example.com # Build settings theme: minima From f2fecdaa63a44dd00fe6e4bcdf34accaf91c84e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 01:16:40 +0200 Subject: [PATCH 16/41] Try different config. --- jekyll/Gemfile | 4 ++-- jekyll/_config.yml | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/jekyll/Gemfile b/jekyll/Gemfile index 987a07da..c5484fa0 100644 --- a/jekyll/Gemfile +++ b/jekyll/Gemfile @@ -8,15 +8,15 @@ source "https://rubygems.org" # This will help ensure the proper Jekyll version is running. # Happy Jekylling! # gem "jekyll", "~> 4.4.1" -gem "github-pages","~> 232",group: :jekyll_plugins # This is the default theme for new Jekyll sites. You may change this to anything you like. gem "minima", "~> 2.5" # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. -# gem "github-pages", group: :jekyll_plugins +gem "github-pages", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do gem "jekyll-feed", "~> 0.12" + gem 'jekyll-commonmark-ghpages' end # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 8da521c7..d41371cb 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -29,8 +29,11 @@ domain: opentdatach.github.io url: https://opentdatach.github.io # the base hostname & protocol for your site, e.g. http://example.com # Build settings -theme: minima -markdown: kramdown +theme: jekyll-theme-minimal +markdown: CommonMarkGhPages +commonmark: + options: ["UNSAFE","SMART","FOOTNOTES"] + extensions: ["strikethrough","autolink","table","tagfilter"] plugins: - jekyll-feed From 1ab48d9c55b43aeafb6c02f1f0ef7239e9d430e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 01:25:24 +0200 Subject: [PATCH 17/41] Try new version of deploy-pages. --- .github/workflows/pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index a4e07fc1..31960330 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -47,4 +47,4 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file + uses: actions/deploy-pages@v5 \ No newline at end of file From 11567014e0af660d78e3d2b7c7847d1fbb3ee3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 06:28:43 +0200 Subject: [PATCH 18/41] Try GFM markdown processor. --- jekyll/_config.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index d41371cb..99b78ab6 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -29,11 +29,8 @@ domain: opentdatach.github.io url: https://opentdatach.github.io # the base hostname & protocol for your site, e.g. http://example.com # Build settings -theme: jekyll-theme-minimal -markdown: CommonMarkGhPages -commonmark: - options: ["UNSAFE","SMART","FOOTNOTES"] - extensions: ["strikethrough","autolink","table","tagfilter"] +theme: minima +markdown: GFM plugins: - jekyll-feed From e64a599dabe841ce7b431230d763e912d27415bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 06:33:07 +0200 Subject: [PATCH 19/41] Remove plugin. --- jekyll/_config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 99b78ab6..9dded0d7 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -31,8 +31,8 @@ url: https://opentdatach.github.io # the base hostname & protocol for your site, # Build settings theme: minima markdown: GFM -plugins: - - jekyll-feed +# plugins: +# - jekyll-feed # Exclude from processing. # The following items will not be processed, by default. From 3ad337577888eb1d8d76ad93976b3338e7e21299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:08:50 +0200 Subject: [PATCH 20/41] Add jekyll build to Pages action. --- .github/workflows/pages.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 31960330..87f4d156 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -27,6 +27,20 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.1 + - name: Install bundler and gems + run: | + gem install bundler + bundle install --jobs 4 --retry 3 + - name: Jekyll build + run: bundle exec jekyll build -d site + + - uses: actions/upload-pages-artifact@v3 + with: + path: site + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v4 From ec0cfe39f48a10944b703bedf0d9c2e06772feaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:29:02 +0200 Subject: [PATCH 21/41] Reorder sequence of steps of the build job. --- .github/workflows/pages.yaml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 87f4d156..6b08633c 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -1,5 +1,4 @@ # Builds the docs and deploys them to GitHub pages. - name: Pages # Controls when the workflow will run @@ -18,41 +17,42 @@ permissions: pages: write id-token: write -# A workflow run is made up of one or more jobs that can run sequentially or in parallel +# Workflow run composed of build and deploy jobs jobs: + # Builds and uploads artifact for GitHib pages build: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: + + # Checks out git repository + - uses: actions/checkout@v4 + + # Builds tools and generates md docs under ./site + - name: Build tools and generate md docs + run: | + ./tools/build.sh + + # Builds static html web pages with jekyll under ./site - uses: ruby/setup-ruby@v1 with: ruby-version: 3.1 - - name: Install bundler and gems + - name: Install bundler and gems for jekyll run: | gem install bundler bundle install --jobs 4 --retry 3 - - name: Jekyll build + - name: Build static html web page with jekyll run: bundle exec jekyll build -d site + # Creates and uploads the build artifact from ./site - uses: actions/upload-pages-artifact@v3 with: path: site - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 - - # Runs a single command using the runners shell - - name: Run a one-line script - run: | - ./tools/build.sh - - - uses: actions/upload-pages-artifact@v3 - with: - path: site - + # Deploys artifact to GitHub pages deploy: needs: build runs-on: ubuntu-latest From 0f974c570f0970fd41d983ae04838b18b27c5d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:32:26 +0200 Subject: [PATCH 22/41] Change dir to site. --- .github/workflows/pages.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 6b08633c..7e8d086e 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -42,6 +42,7 @@ jobs: ruby-version: 3.1 - name: Install bundler and gems for jekyll run: | + cd site gem install bundler bundle install --jobs 4 --retry 3 - name: Build static html web page with jekyll From 5f061e21377f9ff607d89740d64fb10b16444277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:34:40 +0200 Subject: [PATCH 23/41] Build jekyll on current dir. --- .github/workflows/pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 7e8d086e..f634348a 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -46,7 +46,7 @@ jobs: gem install bundler bundle install --jobs 4 --retry 3 - name: Build static html web page with jekyll - run: bundle exec jekyll build -d site + run: bundle exec jekyll build # Creates and uploads the build artifact from ./site - uses: actions/upload-pages-artifact@v3 From 022daf801cc3e36cad60ce5f514bffdddb97c1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:37:36 +0200 Subject: [PATCH 24/41] Build jekyll on site. --- .github/workflows/pages.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index f634348a..38841c59 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -46,7 +46,9 @@ jobs: gem install bundler bundle install --jobs 4 --retry 3 - name: Build static html web page with jekyll - run: bundle exec jekyll build + run: | + cd site + bundle exec jekyll build # Creates and uploads the build artifact from ./site - uses: actions/upload-pages-artifact@v3 From 442d3c9c8e5c32ff7763ada1931d94bbe3391a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:40:38 +0200 Subject: [PATCH 25/41] Verify Gemfile. --- .github/workflows/pages.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 38841c59..14d0f918 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -48,6 +48,7 @@ jobs: - name: Build static html web page with jekyll run: | cd site + ls Gemfile bundle exec jekyll build # Creates and uploads the build artifact from ./site From 6036a72574aa75b0db1c28e4f3b832f69390e208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:47:01 +0200 Subject: [PATCH 26/41] Upload static html pages. --- .github/workflows/pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 14d0f918..55ed95c0 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -54,7 +54,7 @@ jobs: # Creates and uploads the build artifact from ./site - uses: actions/upload-pages-artifact@v3 with: - path: site + path: site/_site # Deploys artifact to GitHub pages deploy: From f3ea33719ca46ade2031bb9160e0796f9e47f4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 16:57:46 +0200 Subject: [PATCH 27/41] Change site title. --- .github/workflows/pages.yaml | 2 +- jekyll/_config.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 55ed95c0..3aaebcd6 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -1,5 +1,5 @@ # Builds the docs and deploys them to GitHub pages. -name: Pages +name: Build and deploy docs to Github Pages # Controls when the workflow will run on: diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 9dded0d7..32299b56 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -18,7 +18,7 @@ # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. -title: NeTEx Realization Guide for Switzerland +title: Swiss profile 2.0 for NeTEx 2.0 - Realisation directive for public transport in Switzerland email: your-email@example.com description: >- # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this From 0c0c51ed2969d0d3a7b345097d8022bc240361b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 17:07:15 +0200 Subject: [PATCH 28/41] Rework site description and email. --- .github/workflows/pages.yaml | 2 +- jekyll/_config.yml | 21 ++++++--------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 3aaebcd6..ff810ae7 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -1,5 +1,5 @@ # Builds the docs and deploys them to GitHub pages. -name: Build and deploy docs to Github Pages +name: Build and deploy to Github Pages # Controls when the workflow will run on: diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 32299b56..22bc540c 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -1,29 +1,20 @@ -# Welcome to Jekyll! -# -# This config file is meant for settings that affect your whole blog, values -# which you are expected to set up once and rarely edit after that. If you find -# yourself editing this file very often, consider using Jekyll's data files -# feature for the data you need to update frequently. +# Jekyll config file # # For technical reasons, this file is *NOT* reloaded automatically when you use # 'bundle exec jekyll serve'. If you change this file, please restart the server process. # -# If you need help with YAML syntax, here are some quick references for you: -# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml -# https://learnxinyminutes.com/docs/yaml/ -# # Site settings # These are used to personalize your new site. If you look in the HTML files, # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. -title: Swiss profile 2.0 for NeTEx 2.0 - Realisation directive for public transport in Switzerland -email: your-email@example.com +title: Swiss profile 2.0 for NeTEx 2.0 +email: opendata@sbb.ch description: >- # this means to ignore newlines until "baseurl:" - Write an awesome description for your new site here. You can edit this - line in _config.yml. It will appear in your document head meta (for - Google search results) and in your feed.xml site description. + This document describes the realisation specifications for the data transfer between SKI and the public transport in + Switzerland, based on the official NeTEx standard. It provides detailed clarifications and describes deviations from + the official standard, with the aim of achieving consistent use throughout public transport in Switzerland. baseurl: /netexRgTest # the subpath of your site, e.g. /blog domain: opentdatach.github.io url: https://opentdatach.github.io # the base hostname & protocol for your site, e.g. http://example.com From c3009626c8631ef873ef8d4bc2746ea0b929175a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 17:11:12 +0200 Subject: [PATCH 29/41] Shorten site description. --- jekyll/_config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 22bc540c..1de0b563 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -13,8 +13,7 @@ title: Swiss profile 2.0 for NeTEx 2.0 email: opendata@sbb.ch description: >- # this means to ignore newlines until "baseurl:" This document describes the realisation specifications for the data transfer between SKI and the public transport in - Switzerland, based on the official NeTEx standard. It provides detailed clarifications and describes deviations from - the official standard, with the aim of achieving consistent use throughout public transport in Switzerland. + Switzerland, based on the official NeTEx standard. baseurl: /netexRgTest # the subpath of your site, e.g. /blog domain: opentdatach.github.io url: https://opentdatach.github.io # the base hostname & protocol for your site, e.g. http://example.com From 022395f77a39595771fbc79ba937707521529c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 17:20:27 +0200 Subject: [PATCH 30/41] Set to DRAFT. --- jekyll/_config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 1de0b563..14423e25 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -9,8 +9,8 @@ # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. -title: Swiss profile 2.0 for NeTEx 2.0 -email: opendata@sbb.ch +title: DRAFT Swiss profile 2.0 for NeTEx 2.0 +email: info.fachbus@sbb.ch description: >- # this means to ignore newlines until "baseurl:" This document describes the realisation specifications for the data transfer between SKI and the public transport in Switzerland, based on the official NeTEx standard. From 2925ff4fb7ea2e5e6e19180f34b1ff8a0881ae5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 17:34:05 +0200 Subject: [PATCH 31/41] Fix index page. --- docs/index.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 104e9911..57922b32 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,7 @@ -# Swiss profile 2.0 for NeTEx 2.0 - Realisation directive for public transport in Switzerland +--- +title: Swiss profile 2.0 for NeTEx 2.0 - Realisation directive for public transport in Switzerland +layout: default +--- This document describes the realisation specifications for the data transfer between SKI and the public transport in Switzerland, based on the official NeTEx standard. It provides detailed clarifications and describes deviations from the official standard, with the aim of achieving consistent use throughout public transport in Switzerland. From 999f23896822b233a59b809f2ab4332b5b68abec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Sat, 30 May 2026 18:00:00 +0200 Subject: [PATCH 32/41] Fix index page. --- docs/index.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/index.md b/docs/index.md index 57922b32..104e9911 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,4 @@ ---- -title: Swiss profile 2.0 for NeTEx 2.0 - Realisation directive for public transport in Switzerland -layout: default ---- +# Swiss profile 2.0 for NeTEx 2.0 - Realisation directive for public transport in Switzerland This document describes the realisation specifications for the data transfer between SKI and the public transport in Switzerland, based on the official NeTEx standard. It provides detailed clarifications and describes deviations from the official standard, with the aim of achieving consistent use throughout public transport in Switzerland. From 373d5c86497bd21c957ed3d28a55d7304c9ac84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 11:02:53 +0200 Subject: [PATCH 33/41] Fix duplicate tiles using jekyll-titles-from-headings plugin. --- jekyll/Gemfile | 1 + jekyll/Gemfile.lock | 444 ++++++++++++++++++++++++++++++++------------ jekyll/_config.yml | 10 +- 3 files changed, 336 insertions(+), 119 deletions(-) diff --git a/jekyll/Gemfile b/jekyll/Gemfile index c5484fa0..96c09788 100644 --- a/jekyll/Gemfile +++ b/jekyll/Gemfile @@ -17,6 +17,7 @@ gem "github-pages", group: :jekyll_plugins group :jekyll_plugins do gem "jekyll-feed", "~> 0.12" gem 'jekyll-commonmark-ghpages' + gem 'jekyll-titles-from-headings' end # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/jekyll/Gemfile.lock b/jekyll/Gemfile.lock index edb59c6a..7fe7da70 100644 --- a/jekyll/Gemfile.lock +++ b/jekyll/Gemfile.lock @@ -1,17 +1,51 @@ GEM remote: https://rubygems.org/ specs: + activesupport (8.1.3) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) base64 (0.3.0) bigdecimal (4.1.2) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) colorator (1.1.0) + commonmarker (0.23.12) concurrent-ruby (1.3.6) + connection_pool (3.0.2) csv (3.3.5) + dnsruby (1.73.1) + base64 (>= 0.2) + logger (~> 1.6) + simpleidn (~> 0.2.1) + drb (2.2.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) + ethon (0.18.0) + ffi (>= 1.15.0) + logger eventmachine (1.2.7) + execjs (2.10.1) + faraday (2.14.2) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.3) + net-http (~> 0.5) ffi (1.17.4) ffi (1.17.4-aarch64-linux-gnu) ffi (1.17.4-aarch64-linux-musl) @@ -24,66 +58,178 @@ GEM ffi (1.17.4-x86_64-linux-gnu) ffi (1.17.4-x86_64-linux-musl) forwardable-extended (2.6.0) - google-protobuf (4.35.0) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-aarch64-linux-gnu) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-aarch64-linux-musl) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-arm64-darwin) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-x86-linux-gnu) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-x86-linux-musl) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-x86_64-darwin) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-x86_64-linux-gnu) - bigdecimal - rake (~> 13.3) - google-protobuf (4.35.0-x86_64-linux-musl) - bigdecimal - rake (~> 13.3) + gemoji (4.1.0) + github-pages (232) + github-pages-health-check (= 1.18.2) + jekyll (= 3.10.0) + jekyll-avatar (= 0.8.0) + jekyll-coffeescript (= 1.2.2) + jekyll-commonmark-ghpages (= 0.5.1) + jekyll-default-layout (= 0.1.5) + jekyll-feed (= 0.17.0) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.16.1) + jekyll-include-cache (= 0.2.1) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.8.0) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.2.0) + jekyll-theme-cayman (= 0.2.0) + jekyll-theme-dinky (= 0.2.0) + jekyll-theme-hacker (= 0.2.0) + jekyll-theme-leap-day (= 0.2.0) + jekyll-theme-merlot (= 0.2.0) + jekyll-theme-midnight (= 0.2.0) + jekyll-theme-minimal (= 0.2.0) + jekyll-theme-modernist (= 0.2.0) + jekyll-theme-primer (= 0.6.0) + jekyll-theme-slate (= 0.2.0) + jekyll-theme-tactile (= 0.2.0) + jekyll-theme-time-machine (= 0.2.0) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.13.0) + kramdown (= 2.4.0) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.4) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.16.2, < 2.0) + rouge (= 3.30.0) + terminal-table (~> 1.4) + webrick (~> 1.8) + github-pages-health-check (1.18.2) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (>= 4, < 8) + public_suffix (>= 3.0, < 6.0) + typhoeus (~> 1.3) + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) http_parser.rb (0.8.1) i18n (1.14.8) concurrent-ruby (~> 1.0) - jekyll (4.4.1) + jekyll (3.10.0) addressable (~> 2.4) - base64 (~> 0.2) colorator (~> 1.0) csv (~> 3.0) em-websocket (~> 0.5) - i18n (~> 1.0) - jekyll-sass-converter (>= 2.0, < 4.0) + i18n (>= 0.7, < 2) + jekyll-sass-converter (~> 1.0) jekyll-watch (~> 2.0) - json (~> 2.6) - kramdown (~> 2.3, >= 2.3.1) - kramdown-parser-gfm (~> 1.0) + kramdown (>= 1.17, < 3) liquid (~> 4.0) - mercenary (~> 0.3, >= 0.3.6) + mercenary (~> 0.3.3) pathutil (~> 0.9) - rouge (>= 3.0, < 5.0) + rouge (>= 1.7, < 4) safe_yaml (~> 1.0) - terminal-table (>= 1.8, < 4.0) - webrick (~> 1.7) + webrick (>= 1.0) + jekyll-avatar (0.8.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.2.2) + coffee-script (~> 2.2) + coffee-script-source (~> 1.12) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.5.1) + commonmarker (>= 0.23.7, < 1.1.0) + jekyll (>= 3.9, < 4.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 5.0) + jekyll-default-layout (0.1.5) + jekyll (>= 3.0, < 5.0) jekyll-feed (0.17.0) jekyll (>= 3.7, < 5.0) - jekyll-sass-converter (3.1.0) - sass-embedded (~> 1.75) - jekyll-seo-tag (2.9.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.16.1) + jekyll (>= 3.4, < 5.0) + octokit (>= 4, < 7, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.3) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.8.0) jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.6.0) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) jekyll-watch (2.2.1) listen (~> 3.0) + jemoji (0.13.0) + gemoji (>= 3, < 5) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) json (2.19.7) - kramdown (2.5.2) - rexml (>= 3.4.4) + kramdown (2.4.0) + rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) liquid (4.0.4) @@ -92,55 +238,69 @@ GEM rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) logger (1.7.0) - mercenary (0.4.0) - minima (2.5.2) + mercenary (0.3.6) + mini_portile2 (2.8.9) + minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) + minitest (6.0.6) + drb (~> 2.0) + prism (~> 1.5) + net-http (0.9.1) + uri (>= 0.11.1) + nokogiri (1.19.3) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + nokogiri (1.19.3-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.19.3-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.19.3-arm64-darwin) + racc (~> 1.4) + nokogiri (1.19.3-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.19.3-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-x86_64-linux-musl) + racc (~> 1.4) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (7.0.5) - rake (13.4.2) + prism (1.9.0) + public_suffix (5.1.1) + racc (1.8.1) rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) rexml (3.4.4) - rouge (4.7.0) + rouge (3.30.0) + rubyzip (2.4.1) safe_yaml (1.0.5) - sass-embedded (1.100.0) - google-protobuf (~> 4.31) - rake (>= 13) - sass-embedded (1.100.0-aarch64-linux-android) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-aarch64-linux-gnu) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-aarch64-linux-musl) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-arm-linux-androideabi) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-arm-linux-gnueabihf) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-arm-linux-musleabihf) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-arm64-darwin) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-riscv64-linux-android) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-riscv64-linux-gnu) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-riscv64-linux-musl) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-x86_64-darwin) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-x86_64-linux-android) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-x86_64-linux-gnu) - google-protobuf (~> 4.31) - sass-embedded (1.100.0-x86_64-linux-musl) - google-protobuf (~> 4.31) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - unicode-display_width (2.6.0) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.9.3) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + securerandom (0.4.1) + simpleidn (0.2.3) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + typhoeus (1.6.0) + ethon (>= 0.18.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (1.8.0) + uri (1.1.1) webrick (1.9.2) PLATFORMS @@ -165,24 +325,37 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + github-pages http_parser.rb (~> 0.6.0) - jekyll (~> 4.4.1) + jekyll-commonmark-ghpages jekyll-feed (~> 0.12) + jekyll-titles-from-headings minima (~> 2.5) tzinfo (>= 1, < 3) tzinfo-data wdm (~> 0.1) CHECKSUMS + activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd bundler (4.0.12) sha256=7f8b757d28dfb636e7b24fba2344ac6dd13b5b24f4b46d62573d483f211825ac + coffee-script (2.4.1) sha256=82fe281e11b93c8117b98c5ea8063e71741870f1c4fbb27177d7d6333dd38765 + coffee-script-source (1.12.2) sha256=e12b16fd8927fbbf8b87cb2e9a85a6cf457c6881cc7ff8b1af15b31f70da07a4 colorator (1.1.0) sha256=e2f85daf57af47d740db2a32191d1bdfb0f6503a0dfbc8327d0c9154d5ddfc38 + commonmarker (0.23.12) sha256=da2d2f89c7c7b51c42c6e69ace3ab5df39497683f86e83aca7087c671d523ccd concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f + dnsruby (1.73.1) sha256=6cf327f5fe2768deadb5e3f3e899ff1ae110aefcef43fef32e1e55e71289e992 + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 em-websocket (0.5.3) sha256=f56a92bde4e6cb879256d58ee31f124181f68f8887bd14d53d5d9a292758c6a8 + ethon (0.18.0) sha256=b598afc9f30448cb068b850714b7d6948e941476095d04f90a4ac65b8d6efcb2 eventmachine (1.2.7) sha256=994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972 + execjs (2.10.1) sha256=abe0ae028467eb8e30c10814eb934d07876a691aae7e803d813b7ce5a75e73f1 + faraday (2.14.2) sha256=73ccb9994a9e8648f010e32eca2ae82e41c57860aa10932cda29418b9e0223ad + faraday-net_http (3.4.3) sha256=9db13becec9312f345a769eeeecf9049c9287d54c0ae053d7235228993a4eec1 ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 @@ -195,55 +368,90 @@ CHECKSUMS ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e forwardable-extended (2.6.0) sha256=1bec948c469bbddfadeb3bd90eb8c85f6e627a412a3e852acfd7eaedbac3ec97 - google-protobuf (4.35.0) sha256=95346162c792ed78c9a28cbf2d937a53f706de6df36a27471582f63f03c30c0d - google-protobuf (4.35.0-aarch64-linux-gnu) sha256=2cabd61b420918aec1564f9f7414e455bf922d20c5f8139d62783df5558a7aea - google-protobuf (4.35.0-aarch64-linux-musl) sha256=f6b11f3420a4564f68e8233c95eac6924f6a727dfc2f81a56af2e09add551501 - google-protobuf (4.35.0-arm64-darwin) sha256=66ab26d3fc82b8950702e53ab16c198e3c0ea3f2a38aaaf1f32152da45593ac5 - google-protobuf (4.35.0-x86-linux-gnu) sha256=7a5b5681c7d7bf28e1a6e285e45bf55c4ef47b7b1ca8af6ff79964255efece9a - google-protobuf (4.35.0-x86-linux-musl) sha256=f481b63b176c0335db8b50e46f033c0956857a599d9feafdd891a5c18ce28d43 - google-protobuf (4.35.0-x86_64-darwin) sha256=05eb5c8bc9899135befff496fc0a3642e7ff3d0943f043841dcc456f5654fea0 - google-protobuf (4.35.0-x86_64-linux-gnu) sha256=999226f3b00cd9fddb1b26851d16060212fa1d90c406aaad47e574682b716059 - google-protobuf (4.35.0-x86_64-linux-musl) sha256=be0218520d77b2aee898b363514b03819f6f63f9c041ae0d0d79b4ce5247bffd + gemoji (4.1.0) sha256=734434020cbe964ea9d19086798797a47d23a170892de0ce55b74aa65d2ddc1a + github-pages (232) sha256=2b40493d7327627e4ce45c47f4a9d4394e5eaa151f9d29bb924ff424c3132287 + github-pages-health-check (1.18.2) sha256=df893d4f5a4161477e8525b993dbe1c1eb63fbb86fb07b6e80996fd37a18843d + html-pipeline (2.14.3) sha256=8a1d4d7128b2141913387cac0f8ba898bb6812557001acc0c2b46910f59413a0 http_parser.rb (0.8.1) sha256=9ae8df145b39aa5398b2f90090d651c67bd8e2ebfe4507c966579f641e11097a i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 - jekyll (4.4.1) sha256=4c1144d857a5b2b80d45b8cf5138289579a9f8136aadfa6dd684b31fe2bc18c1 + jekyll (3.10.0) sha256=c4213b761dc7dfe7d499eb742d0476a02d8503e440c2610e19774ee7f0db8d90 + jekyll-avatar (0.8.0) sha256=ea736277c2de54a21300122096700517972a722d5c68ca83f8723b4999abfd4b + jekyll-coffeescript (1.2.2) sha256=894e71c2071a834e76eb7e8044944440a0c81c2c7092532fed1503b13d331110 + jekyll-commonmark (1.4.0) sha256=1731e658fe09ce040271e6878f83ad45bbf8d17b10ad03bf343546cca30f4844 + jekyll-commonmark-ghpages (0.5.1) sha256=d56722f23393e45625e6e1bac6d3c64bb5f5cdf6ca547338160536d61c27a4a4 + jekyll-default-layout (0.1.5) sha256=c626be4e4a5deafca123539da2cd22ff873be350cafd4da134039efdf24320af jekyll-feed (0.17.0) sha256=689aab16c877949bb9e7a5c436de6278318a51ecb974792232fd94d8b3acfcc3 - jekyll-sass-converter (3.1.0) sha256=83925d84f1d134410c11d0c6643b0093e82e3a3cf127e90757a85294a3862443 - jekyll-seo-tag (2.9.0) sha256=0260015a8e1df9bf195cdfb0c675b7b2883fd8cbf12556e1c1cbe36a831c6852 + jekyll-gist (1.5.0) sha256=495b6483552a3e2975a2752964ea7acddd545bc6e13ce2be15a50cec8d4c9f0f + jekyll-github-metadata (2.16.1) sha256=4cf29988bdaf24774a7bc07fae71e54424ddfaa2895f742d8fa3036d0db65b4c + jekyll-include-cache (0.2.1) sha256=c7d4b9e551732a27442cb2ce853ba36a2f69c66603694b8c1184c99ab1a1a205 + jekyll-mentions (1.6.0) sha256=39e801024cb6f2319b3f78a29999d0068ef5f68bc5202b8757d5354fef311ed9 + jekyll-optional-front-matter (0.3.2) sha256=ecdc061d711472469fcf04da617653b553e914c038a17df3b6a5f6f92aeb761b + jekyll-paginate (1.1.0) sha256=880aadf4b02529a93541d508c5cbb744f014cbfc071d0263a31f25ec9066eb64 + jekyll-readme-index (0.3.0) sha256=d74cc4de46b2d350229be7409495149e656a31fb5a5fe3fe6135dbf7435e1e32 + jekyll-redirect-from (0.16.0) sha256=6635cae569ef9b0f90ffb71ec014ba977177fafb44d32a2b0526288d4d9be6db + jekyll-relative-links (0.6.1) sha256=d11301f57b39e94b6c04fff2a3b145fe2f6a27be631a403e2542fa2e1548dd6d + jekyll-remote-theme (0.4.3) sha256=d3fde726484fb3df04de9e347baf75aaa3d5bfea771a330412e0c52608e54b40 + jekyll-sass-converter (1.5.2) sha256=53773669e414dc3bb070113befacb808576025a28cfa4a4accc682e90a9c1101 + jekyll-seo-tag (2.8.0) sha256=3f2ed1916d56f14ebfa38e24acde9b7c946df70cb183af2cb5f0598f21ae6818 + jekyll-sitemap (1.4.0) sha256=0de08c5debc185ea5a8f980e1025c7cd3f8e0c35c8b6ef592f15c46235cf4218 + jekyll-swiss (1.0.0) sha256=c299a855dca881fe868f21545c5489be50ddfbc0d54a80e8dbeb5a2ddc4888a3 + jekyll-theme-architect (0.2.0) sha256=7275d3dcaa6b34fcf92f2fe5cee92d49d66706d3b523003b1e67e9c668ff0440 + jekyll-theme-cayman (0.2.0) sha256=3c5f14f9c72a8eb03ecc74f9a3e5ecbbc55f9381339978b42dec216921865f2a + jekyll-theme-dinky (0.2.0) sha256=720b257091f0de3aa9394b25fd97d1b2b12cfaf00e060aff170f60e218a32c7c + jekyll-theme-hacker (0.2.0) sha256=816bf9f992ded0b1e1e69d8dece2574e8480efb5e9f84a2e1ac83bd717b8f78a + jekyll-theme-leap-day (0.2.0) sha256=921ea8305ae0285a881c9aa9dbe2375ed6f404b4f90067458e596891ef5ac7d1 + jekyll-theme-merlot (0.2.0) sha256=cbf2b21b62423561ca5b62e406dbb08f085e3a45daa7b3b4b9b3f24d08ded545 + jekyll-theme-midnight (0.2.0) sha256=009ff367350e83ff6095d98837bb411adb07b59a76f59f1d4a33ef927bb391de + jekyll-theme-minimal (0.2.0) sha256=a225210c35573ad2c9e57b81f16f678ca6c314394ec692502ccc6189d7e52d82 + jekyll-theme-modernist (0.2.0) sha256=4be775bc5edd53864c5e40c000c34db0dfd82dac800cff50371ef11da66dfbcf + jekyll-theme-primer (0.6.0) sha256=ce27282798217eb0957ba01ab3bf12996476348b625736fa8448f7a1b8a307b3 + jekyll-theme-slate (0.2.0) sha256=5e40909de712bbbefbc7a29f17c55bffa326c222f0a13ee1656229a7d43c3439 + jekyll-theme-tactile (0.2.0) sha256=b7861b48aed5b2385d7a146b13f31cb6f37afe3107f4a6b93b1c932b2d242652 + jekyll-theme-time-machine (0.2.0) sha256=bc3490a7eccfc24ca671780c9d4f531500936a361690020b19defe6105d74fe2 + jekyll-titles-from-headings (0.5.3) sha256=77366754e361ea7b5d87881f5b1380835f5ce910c240a4d9ac2d7afe86d28481 jekyll-watch (2.2.1) sha256=bc44ed43f5e0a552836245a54dbff3ea7421ecc2856707e8a1ee203a8387a7e1 + jemoji (0.13.0) sha256=5d4c3e8e2cbbb2b73997c31294f6f70c94e4d4fade039373e86835bcf5529e7c json (2.19.7) sha256=fe432c8639f6efff69f9d73b518a3705d9581ab93156f981ea72806e1e5bcc3e - kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown (2.4.0) sha256=b62e5bcbd6ea20c7a6730ebbb2a107237856e14f29cebf5b10c876cc1a2481c5 kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 liquid (4.0.4) sha256=4fcfebb1a045e47918388dbb7a0925e7c3893e58d2bd6c3b3c73ec17a2d8fdb3 listen (3.10.0) sha256=c6e182db62143aeccc2e1960033bebe7445309c7272061979bb098d03760c9d2 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 - mercenary (0.4.0) sha256=b25a1e4a59adca88665e08e24acf0af30da5b5d859f7d8f38fba52c28f405138 - minima (2.5.2) sha256=9c434e3b7bc4a0f0ab488910438ed3757a0502ff1060d172f361907fc38aa45a + mercenary (0.3.6) sha256=2a084b18f5692c86a633e185d5311ba6d11fc46c802eb414ae05368178078a82 + mini_portile2 (2.8.9) sha256=0cd7c7f824e010c072e33f68bc02d85a00aeb6fce05bb4819c03dfd3c140c289 + minima (2.5.1) sha256=520e52bc631fb16cbb8100660f6caa44f97859e2fa7e397d508deb18739567be + minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1 + net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 + nokogiri (1.19.3) sha256=78312cbac32a40c812780d9678221b79d51288eec00054c1a8d15f7ce05960e8 + nokogiri (1.19.3-aarch64-linux-gnu) sha256=46b89e5d7b9e844c2ee360794240c6ea2a4e6fa0c5892a4ed487db621224b639 + nokogiri (1.19.3-aarch64-linux-musl) sha256=8392dfdcd21be7a94dbbe9ccc138dea01b97b24cb2dc02a114ca98bfb1d9a0b7 + nokogiri (1.19.3-arm-linux-gnu) sha256=3919d5ffc334ad778a4a9eb88fda7dcb8b1fb58c8a52ac640c6dcd2f038e774f + nokogiri (1.19.3-arm-linux-musl) sha256=9ce1cb6346bb9c67b1550eb537aa183ead91e4b6eadb2f36ade02d8dd2a79fb6 + nokogiri (1.19.3-arm64-darwin) sha256=71b9bd424b1b7abc18b05052a1a3cfd3627abdca62be280854cc411791357e42 + nokogiri (1.19.3-x86_64-darwin) sha256=77f3fba57d46c53ab31e62fc6c28f705109d1bf6264356c76f132b2be5728d4d + nokogiri (1.19.3-x86_64-linux-gnu) sha256=2f5078620fe12e83669b5b17311b32532a8153d02eee7ad06948b926d6080976 + nokogiri (1.19.3-x86_64-linux-musl) sha256=248c906d2166eca5efb56d52fdee5f9a1f51d69a72e2b64fdac647b4ce39ea3f + octokit (4.25.1) sha256=c02092ee82dcdfe84db0e0ea630a70d32becc54245a4f0bacfd21c010df09b96 pathutil (0.16.2) sha256=e43b74365631cab4f6d5e4228f812927efc9cb2c71e62976edcb252ee948d589 - public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 - rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + public_suffix (5.1.1) sha256=250ec74630d735194c797491c85e3c6a141d7b5d9bd0b66a3fa6268cf67066ed + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 - rouge (4.7.0) sha256=dba5896715c0325c362e895460a6d350803dbf6427454f49a47500f3193ea739 + rouge (3.30.0) sha256=a3d353222aa72e49e2c86726c0bcfd719f82592f57d494474655f48e669eceb6 + rubyzip (2.4.1) sha256=8577c88edc1fde8935eb91064c5cb1aef9ad5494b940cf19c775ee833e075615 safe_yaml (1.0.5) sha256=a6ac2d64b7eb027bdeeca1851fe7e7af0d668e133e8a88066a0c6f7087d9f848 - sass-embedded (1.100.0) sha256=b7d4831f304be5ba8717b2a1307644164b63dc158113a67f469e90578d3fc092 - sass-embedded (1.100.0-aarch64-linux-android) sha256=9603e1c26bea0396e849e3c3bb75b6843a43bae7a32c580084fd6c64260d9ef8 - sass-embedded (1.100.0-aarch64-linux-gnu) sha256=c13187f8eaae7e7e64246b18eb896534a84465a17198829ef65730db4662860e - sass-embedded (1.100.0-aarch64-linux-musl) sha256=1b0945a66cd4e40f505db73b1e790e2561e07e6d9fd04ef6ebbf279835666b3f - sass-embedded (1.100.0-arm-linux-androideabi) sha256=9948122504b69e20dc82a3b8fc20b3a61ea58a4713a713f64630b4c9a36f11e1 - sass-embedded (1.100.0-arm-linux-gnueabihf) sha256=a2de272bb02977ea91acaf3fecb6d8e09e4989501efbfc5375da4b5e7bff001d - sass-embedded (1.100.0-arm-linux-musleabihf) sha256=ce19837c10bab5ae6785f10b435a57a64ca027a99875cd701dc6fd3af317cbe5 - sass-embedded (1.100.0-arm64-darwin) sha256=d294b32c3b7bed293ad39bd392713c07f1df5454e65fa0f8d80dadbdba8a0cf4 - sass-embedded (1.100.0-riscv64-linux-android) sha256=148669225f027eeedea0a27e474dc69448567c030c56792114894f55a68af38e - sass-embedded (1.100.0-riscv64-linux-gnu) sha256=880ff1fca280b45b4d223366606aa634177adf38e793ad521426be7ad70a1ef2 - sass-embedded (1.100.0-riscv64-linux-musl) sha256=a8568d17343dcf0278d48b2efb4b3490ebe3ba0279ec4d69753e8ce4fd0614fa - sass-embedded (1.100.0-x86_64-darwin) sha256=3db80c837a60712de3461d5aa1be43c7056a0584d7182a8ae7a8996d64ab46d3 - sass-embedded (1.100.0-x86_64-linux-android) sha256=1600dbddf82c83344a5bc2a5e163081efdf15661f782922603574328888cd2cc - sass-embedded (1.100.0-x86_64-linux-gnu) sha256=58dd0a8a4f0dd78881b90d8b0e4d0eed042d54865b19b71384d91091ade93e18 - sass-embedded (1.100.0-x86_64-linux-musl) sha256=03dbee81bf93e770c725caf0c895e04c7b049ebef56b8a7002fcf21e6bedf7c5 - terminal-table (3.0.2) sha256=f951b6af5f3e00203fb290a669e0a85c5dd5b051b3b023392ccfd67ba5abae91 - unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a + sass (3.7.4) sha256=808b0d39053aa69068df939e24671fe84fd5a9d3314486e1a1457d0934a4255d + sass-listen (4.0.0) sha256=ae9dcb76dd3e234329e5ba6e213f48e532c5a3e7b0b4d8a87f13aaca0cc18377 + sawyer (0.9.3) sha256=0d0f19298408047037638639fe62f4794483fb04320269169bd41af2bdcf5e41 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + simpleidn (0.2.3) sha256=08ce96f03fa1605286be22651ba0fc9c0b2d6272c9b27a260bc88be05b0d2c29 + terminal-table (1.8.0) sha256=13371f069af18e9baa4e44d404a4ada9301899ce0530c237ac1a96c19f652294 + typhoeus (1.6.0) sha256=bacc41c23e379547e29801dc235cd1699b70b955a1ba3d32b2b877aa844c331d + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + unicode-display_width (1.8.0) sha256=0292132d364d59fcdd83f144910c48b3c8332b28a14c5c04bb093dd165600488 + uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH diff --git a/jekyll/_config.yml b/jekyll/_config.yml index 14423e25..e8e1db22 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -20,7 +20,15 @@ url: https://opentdatach.github.io # the base hostname & protocol for your site, # Build settings theme: minima -markdown: GFM +plugins: + - jekyll-titles-from-headings + +titles_from_headings: + enabled: true + strip_title: true + collections: true + +# markdown: GFM # plugins: # - jekyll-feed From 8ffa954c778424993f9a944b3b9e69de100c45e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 11:59:17 +0200 Subject: [PATCH 34/41] Remove header links. --- jekyll/_includes/header.html | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 jekyll/_includes/header.html diff --git a/jekyll/_includes/header.html b/jekyll/_includes/header.html new file mode 100644 index 00000000..64f06fc2 --- /dev/null +++ b/jekyll/_includes/header.html @@ -0,0 +1,21 @@ + From 4240a324062b6aff5256173f96c1bfc7aa3c0671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 12:08:11 +0200 Subject: [PATCH 35/41] Add post. --- jekyll/_posts/2026-06-01-Welcome-NeTEx-RG-ch-2.0.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 jekyll/_posts/2026-06-01-Welcome-NeTEx-RG-ch-2.0.md diff --git a/jekyll/_posts/2026-06-01-Welcome-NeTEx-RG-ch-2.0.md b/jekyll/_posts/2026-06-01-Welcome-NeTEx-RG-ch-2.0.md new file mode 100644 index 00000000..246b8f7c --- /dev/null +++ b/jekyll/_posts/2026-06-01-Welcome-NeTEx-RG-ch-2.0.md @@ -0,0 +1,7 @@ +--- +layout: post +title: "Welcome to first draft documentation generated with Jekyll" +date: 2026-06-01 12:00:00 +0200 +categories: NeTEx +--- +Welcome to the first draft documentation generated with Jekyll and minima theme. From 2372f2d264cd85af0f3e4ece11810ae3bfc1ee66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 12:09:24 +0200 Subject: [PATCH 36/41] Remove RSS feed. --- jekyll/Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jekyll/Gemfile b/jekyll/Gemfile index 96c09788..dee8389f 100644 --- a/jekyll/Gemfile +++ b/jekyll/Gemfile @@ -15,7 +15,7 @@ gem "minima", "~> 2.5" gem "github-pages", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do - gem "jekyll-feed", "~> 0.12" +# gem "jekyll-feed", "~> 0.12" gem 'jekyll-commonmark-ghpages' gem 'jekyll-titles-from-headings' end From 32d5b63dcbdc99364ccd8df93f6a296a538f1dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 14:29:31 +0200 Subject: [PATCH 37/41] Fix link targets in expanded tables. --- tools/expand_docs/expand_docs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/expand_docs/expand_docs.py b/tools/expand_docs/expand_docs.py index 2f685931..a93ccc51 100644 --- a/tools/expand_docs/expand_docs.py +++ b/tools/expand_docs/expand_docs.py @@ -8,6 +8,9 @@ import re from tools.configuration import DOCS_DIR, SITE_DIR +TABLE_MD_LINK_TARGET_PATTERN = re.compile(r'(\[.*])\((.*(\.)md).*\)') +TABLE_MD_LINK_TARGET_REPLACEMENT = r'\1(./tables/\2)' + def copy_media_folder(input_folder, output_folder): """Copy media folder from input to output.""" media_src = os.path.join(input_folder, 'media') @@ -31,7 +34,6 @@ def include_xml_snippet(match, base_folder): return f"```xml\n{f.read()}\n```" return match.group(0) - def include_markdown_table(match, base_folder): """Include markdown table content directly.""" table_path = match.group(1) @@ -51,6 +53,8 @@ def include_markdown_table(match, base_folder): for line in lines: if line.startswith('|') or line.startswith('---'): in_table = True + # correct md link target + line = TABLE_MD_LINK_TARGET_PATTERN.sub(TABLE_MD_LINK_TARGET_REPLACEMENT,line) table_lines.append(line) elif in_table: break From 23f3483534c30122af758e0bd18d93546e74445e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 14:58:56 +0200 Subject: [PATCH 38/41] Fix anchor targets. --- docs/06_stops.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/06_stops.md b/docs/06_stops.md index 0b976fc6..3a7acd64 100644 --- a/docs/06_stops.md +++ b/docs/06_stops.md @@ -2,10 +2,10 @@ In this chapter: - [SiteFrame](#siteframe) -- [StopPlace](#StopPlace) -- [Quay](#Quay) -- [TopographicPlace](#TopographicPlace) -- [Centroid](#Centroid) +- [StopPlace](#stopplace) +- [Quay](#quay) +- [TopographicPlace](#topographicplace) +- [Centroid](#centroid) ## SiteFrame *→ [Glossary definition](A4_annex_glossary.md#siteframe)* @@ -70,7 +70,7 @@ classDiagram `SiteFrame` is independent of other frames but provides the physical stop infrastructure that `ServiceFrame` references through `PassengerStopAssignments`. `TimetableFrame` indirectly depends on `SiteFrame` through the `JourneyPattern` stop sequence. `SiteFrame` is typically wrapped in a `CompositeFrame` within a `PublicationDelivery`. ## StopPlace -*→ [Glossary definition](A4_annex_glossary.md#StopPlace)* +*→ [Glossary definition](A4_annex_glossary.md#stopplace)* ### Purpose A named physical or virtual location where passengers can board or alight from public transport, containing one or more `Quays`. From a462926bf5c437743ce57600923aa79a278bf7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Mon, 1 Jun 2026 15:49:47 +0200 Subject: [PATCH 39/41] Fix anchor targets. --- docs/06_stops.md | 2 +- jekyll/Gemfile | 2 +- jekyll/Gemfile.lock | 2 -- jekyll/_config.yml | 1 + 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/06_stops.md b/docs/06_stops.md index 3a7acd64..5a2425d6 100644 --- a/docs/06_stops.md +++ b/docs/06_stops.md @@ -13,7 +13,7 @@ In this chapter: ### Purpose A `SiteFrame` contains the physical infrastructure model for public transport — `StopPlace`s, `Quay`s, and topographic context. It defines the spatial elements that passengers interact with and that other frames reference for stop assignments. -```mermaid +```mermaid! classDiagram %% Styles classDef frame fill:#FFF8E1,stroke:#FFB300; diff --git a/jekyll/Gemfile b/jekyll/Gemfile index dee8389f..a7794965 100644 --- a/jekyll/Gemfile +++ b/jekyll/Gemfile @@ -16,8 +16,8 @@ gem "github-pages", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do # gem "jekyll-feed", "~> 0.12" - gem 'jekyll-commonmark-ghpages' gem 'jekyll-titles-from-headings' + # gem 'jekyll-mermaid-prebuild' end # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/jekyll/Gemfile.lock b/jekyll/Gemfile.lock index 7fe7da70..b842ec1e 100644 --- a/jekyll/Gemfile.lock +++ b/jekyll/Gemfile.lock @@ -327,8 +327,6 @@ PLATFORMS DEPENDENCIES github-pages http_parser.rb (~> 0.6.0) - jekyll-commonmark-ghpages - jekyll-feed (~> 0.12) jekyll-titles-from-headings minima (~> 2.5) tzinfo (>= 1, < 3) diff --git a/jekyll/_config.yml b/jekyll/_config.yml index e8e1db22..ddc6c2b0 100644 --- a/jekyll/_config.yml +++ b/jekyll/_config.yml @@ -22,6 +22,7 @@ url: https://opentdatach.github.io # the base hostname & protocol for your site, theme: minima plugins: - jekyll-titles-from-headings +# - jekyll-mermaid-prebuild titles_from_headings: enabled: true From 03a8faaa7f917e3aad5ba4fb9b4eb32e4393fbc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 12 Jun 2026 10:50:18 +0200 Subject: [PATCH 40/41] Complete build setup description after test with Windows. --- tools/README.md | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/tools/README.md b/tools/README.md index be6e7f60..f84f487d 100644 --- a/tools/README.md +++ b/tools/README.md @@ -32,13 +32,26 @@ uv sync #### Windows -Run the following following commands in the project root directory: +Create the virtual environment directory `venv` running the following command in the project root directory (needs `uv`, see [Install the uv package manager](#install-the-uv-package-manager) above): ``` shell uv venv -.venv\bin\activate.bat +``` + +It may respond like this, or similar: +``` +Using CPython 3.14.6 +Creating virtual environment at: .venv +Activate with: .venv\Scripts\activate +``` + +Run the activation script to activate the virtual environment as proposed in the output above. Then, do the sync to download +the project dependencies: + +``` shell uv sync ``` + ### Install build module > This can be skipped as the `build` module is now part of the build dependencies. @@ -53,9 +66,13 @@ python -m pip install --upgrade pip build If everything is setup correctly, you should be able to the build from your project root directory: ``` -python -m build +uv run python -m build ``` +### Configure PyCharm with uv Python Interpreter + +In the PyCharm settings you may configure the Python interpreter with `uv` based on the `.venv` directory of the project. + ## Tool Scripts The `pyproject.toml` is configured to generate scripts for the tools. @@ -118,8 +135,9 @@ The package manager `uv` simplifies the build and installation of scripts for th Components of the build automation: - [pyproject.toml](../pyproject.toml) is configured with `setuptools` (https://setuptools.pypa.io/en/latest/) - docs can be generated running `python -m build` -- `setup.py` in the root project acts as the interface for the build - - here we can add tools to be run during the build. +- `setup.py` in the root project acts as the interface for the build system + - runs `tools.toolchain` from `tools/toolchain.py` to generate the docs + - here we can add tools to be run during the build. - The build writes all output to directory `site`, excluded from git ### Github Action From 203bdb6d9db1eb48f3f0aef0f3cf784f50691ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20St=C3=B6ckli?= Date: Fri, 12 Jun 2026 11:57:22 +0200 Subject: [PATCH 41/41] Correct project settings. --- pyproject.toml | 6 +++--- uv.lock | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 849a3ef4..1ee95249 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,9 @@ requires = ["setuptools>=70","markdown","pygments","lxml"] build-backend = "setuptools.build_meta" [project] -name = "netex-rg-ch-test" -version = "0.1.2" -description = "Testing tools to help building the NeTEx RG." +name = "netex-rg-ch" +version = "0.1.3" +description = "Tools to build docs for NeTEx RG CH." requires-python = ">=3.13" dependencies = [ "lxml","pyschematron","pygments","build","pip","markdown" diff --git a/uv.lock b/uv.lock index a9382746..5bafd803 100644 --- a/uv.lock +++ b/uv.lock @@ -239,8 +239,8 @@ wheels = [ ] [[package]] -name = "netex-rg-ch-test" -version = "0.1.2" +name = "netex-rg-ch" +version = "0.1.3" source = { editable = "." } dependencies = [ { name = "build" },