From 5a0a66f4c894d5827b9482f074841d07a73921b1 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Wed, 20 May 2026 18:29:29 +0100 Subject: [PATCH] feat(docs): add nexus page BBCode generator - README.md: add user-facing Requirements, Installation, Compatibility block wrapped in nexus:start/end markers before dev Prerequisites - docs/nexus-page.md: wrap generated sections in generated:start/end markers - scripts/generate-nexus-page.py: extract nexus block from README, convert Markdown to BBCode, inject into nexus-page.md template, print to stdout --- README.md | 28 +++++- docs/nexus-page.md | 16 +++- scripts/generate-nexus-page.py | 168 +++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 6 deletions(-) create mode 100755 scripts/generate-nexus-page.py diff --git a/README.md b/README.md index 174f7f8..fb04981 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,33 @@ Supports building on **Linux** (cross-compilation via `clang-cl` + [xwin](https: --- -## Prerequisites + +## Requirements + +- [SKSE64](https://skse.silverlock.org/) +- [Address Library for SKSE Plugins](https://www.nexusmods.com/skyrimspecialedition/mods/32444) + +## Installation + +**Mod manager (recommended):** +1. Install the requirements above. +2. Install ExampleMod via your mod manager. +3. Launch Skyrim via SKSE. + +**Manual:** +1. Install the requirements above. +2. Copy `ExampleMod.dll` to `Data\SKSE\Plugins\`. +3. Launch Skyrim via SKSE. + +## Compatibility + +- Compatible with Skyrim SE and AE. +- No ESP/ESL required. + + +--- + +## Prerequisites (Developer) ### All platforms - [Git](https://git-scm.com/) diff --git a/docs/nexus-page.md b/docs/nexus-page.md index 901c5b3..5ed9d9e 100644 --- a/docs/nexus-page.md +++ b/docs/nexus-page.md @@ -14,19 +14,24 @@ ## Long Description (BBCode) + + ```bbcode [center][size=5][b]ExampleMod[/b][/size] [i]Tagline here[/i][/center] [line] -[size=4][b]Overview[/b][/size] +[size=4][b][color=#B8953E]Overview[/color][/b][/size] Describe what the mod does. [line] -[size=4][b]Requirements[/b][/size] + +[size=4][b][color=#B8953E]Requirements[/color][/b][/size] [list] [*][url=https://skse.silverlock.org/]SKSE64[/url] @@ -35,7 +40,7 @@ Describe what the mod does. [line] -[size=4][b]Installation[/b][/size] +[size=4][b][color=#B8953E]Installation[/color][/b][/size] [b]Mod manager (recommended):[/b] [list=1] @@ -53,16 +58,17 @@ Describe what the mod does. [line] -[size=4][b]Compatibility[/b][/size] +[size=4][b][color=#B8953E]Compatibility[/color][/b][/size] [list] [*]Compatible with Skyrim SE and AE. [*]No ESP/ESL required. [/list] + [line] -[size=4][b]Credits[/b][/size] +[size=4][b][color=#B8953E]Credits[/color][/b][/size] [list] [*][url=https://skse.silverlock.org/]SKSE[/url] by the SKSE Team diff --git a/scripts/generate-nexus-page.py b/scripts/generate-nexus-page.py new file mode 100755 index 0000000..272a33d --- /dev/null +++ b/scripts/generate-nexus-page.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 +"""Generate nexus-page BBCode from README.md user-facing content. + +Reads the block between and in README.md, +converts it to BBCode, substitutes it into the region +of docs/nexus-page.md in memory, and prints the result to stdout. + +Usage: + python3 scripts/generate-nexus-page.py + python3 scripts/generate-nexus-page.py | xclip -selection clipboard +""" + +import argparse +import re +import sys +from pathlib import Path + +README = Path(__file__).parent.parent / "README.md" +NEXUS_TEMPLATE = Path(__file__).parent.parent / "docs" / "nexus-page.md" + +NEXUS_START = "" +NEXUS_END = "" +GEN_START = "" +GEN_END = "" +BBCODE_FENCE_OPEN = "```bbcode" +BBCODE_FENCE_CLOSE = "```" + + +def extract_block(text: str, start_marker: str, end_marker: str) -> str: + start = text.find(start_marker) + if start == -1: + sys.exit(f"error: marker not found: {start_marker!r}") + end = text.find(end_marker, start + len(start_marker)) + if end == -1: + sys.exit(f"error: marker not found: {end_marker!r}") + return text[start + len(start_marker):end].strip() + + +def md_to_bbcode(md: str) -> str: + lines = md.splitlines() + output: list[str] = [] + i = 0 + first_heading = True + + while i < len(lines): + line = lines[i] + + # ## Heading + if line.startswith("## "): + heading = line[3:].strip() + if not first_heading: + output.append("") + output.append("[line]") + output.append("") + first_heading = False + output.append(f"[size=4][b][color=#B8953E]{heading}[/color][/b][/size]") + i += 1 + continue + + # Unordered list block + if line.startswith("- "): + items: list[str] = [] + while i < len(lines) and lines[i].startswith("- "): + items.append(convert_inline(lines[i][2:].strip())) + i += 1 + output.append("[list]") + for item in items: + output.append(f"[*]{item}") + output.append("[/list]") + continue + + # Ordered list block — may be preceded by a bold label line + if re.match(r"\d+\. ", line): + items = [] + while i < len(lines) and re.match(r"\d+\. ", lines[i]): + items.append(convert_inline(re.sub(r"^\d+\. ", "", lines[i]))) + i += 1 + output.append("[list=1]") + for item in items: + output.append(f"[*]{item}") + output.append("[/list]") + continue + + # Bold label (e.g. **Mod manager (recommended):**) + if re.match(r"\*\*.+\*\*", line): + output.append(convert_inline(line)) + i += 1 + continue + + # Blank line + if line.strip() == "": + output.append("") + i += 1 + continue + + # Plain paragraph (pass through inline conversion) + stripped = line.strip() + if stripped and not stripped.startswith("