mirror of
https://github.com/alexandrev/xslt-lab.git
synced 2026-09-13 08:43:16 +00:00
a04beb0ec4
- App: parse ?xslt=, ?xml=, ?version=, ?title= query params on load (base64url-encoded) to pre-populate the editor from external links - App: Share button in XSLT toolbar generates a preload URL for the current tab and copies it to clipboard (icon flips to ✓ for 2s) - Icon: add share and check icons - Blog: 225 reference pages now include a tryUrl frontmatter field with the first example pre-encoded; layout renders "Open live example in XSLT Playground →" CTA pointing directly to that URL - Script: scripts/add_try_urls.py to regenerate tryUrl fields Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Reads all /xslt/functions/*.md pages, extracts the first XSLT + XML example,
|
|
and adds a `tryUrl` field to the frontmatter that links directly to xsltplayground.com
|
|
with the example pre-loaded via base64url query params.
|
|
"""
|
|
import os
|
|
import re
|
|
import base64
|
|
|
|
FUNCTIONS_DIR = os.path.join(
|
|
os.path.dirname(__file__),
|
|
"..", "site", "content", "xslt", "functions"
|
|
)
|
|
BASE_URL = "https://xsltplayground.com/"
|
|
FALLBACK_XML = '<?xml version="1.0" encoding="UTF-8"?>\n<root/>'
|
|
|
|
|
|
def b64url(s: str) -> str:
|
|
return base64.urlsafe_b64encode(s.encode("utf-8")).rstrip(b"=").decode("ascii")
|
|
|
|
|
|
def extract_block(content: str, label: str) -> str | None:
|
|
pattern = rf"\*\*{re.escape(label)}:\*\*\s*```xml\s*\n(.*?)\n```"
|
|
m = re.search(pattern, content, re.DOTALL)
|
|
return m.group(1).strip() if m else None
|
|
|
|
|
|
def process_file(filepath: str) -> str:
|
|
with open(filepath, encoding="utf-8") as f:
|
|
text = f.read()
|
|
|
|
# Match YAML frontmatter block
|
|
fm_match = re.match(r"^---\n(.*?)\n---\n", text, re.DOTALL)
|
|
if not fm_match:
|
|
return "no-frontmatter"
|
|
|
|
fm_text = fm_match.group(1)
|
|
if "tryUrl:" in fm_text:
|
|
return "already-set"
|
|
|
|
# Extract version from frontmatter
|
|
version_m = re.search(r'^version:\s*["\']?([^"\'\n]+)["\']?', fm_text, re.MULTILINE)
|
|
version = version_m.group(1).strip() if version_m else "1.0"
|
|
|
|
content = text[fm_match.end():]
|
|
|
|
xslt = extract_block(content, "Stylesheet")
|
|
xml = extract_block(content, "Input XML")
|
|
|
|
if not xslt:
|
|
return "no-xslt"
|
|
|
|
if not xml:
|
|
xml = FALLBACK_XML
|
|
|
|
url = f"{BASE_URL}?xslt={b64url(xslt)}&xml={b64url(xml)}&version={version}"
|
|
|
|
# Insert tryUrl before the closing --- of the frontmatter
|
|
insert_pos = fm_match.end() - 4 # points to start of closing ---\n
|
|
new_text = text[:insert_pos] + f'tryUrl: "{url}"\n' + text[insert_pos:]
|
|
|
|
with open(filepath, "w", encoding="utf-8") as f:
|
|
f.write(new_text)
|
|
|
|
return "ok"
|
|
|
|
|
|
def main():
|
|
functions_dir = os.path.abspath(FUNCTIONS_DIR)
|
|
files = [
|
|
f for f in os.listdir(functions_dir)
|
|
if f.endswith(".md") and f != "_index.md"
|
|
]
|
|
|
|
counts = {"ok": 0, "already-set": 0, "no-xslt": 0, "no-frontmatter": 0, "error": 0}
|
|
|
|
for fname in sorted(files):
|
|
fpath = os.path.join(functions_dir, fname)
|
|
try:
|
|
result = process_file(fpath)
|
|
counts[result] = counts.get(result, 0) + 1
|
|
if result not in ("ok", "already-set"):
|
|
print(f" SKIP [{result}] {fname}")
|
|
except Exception as e:
|
|
counts["error"] += 1
|
|
print(f" ERROR {fname}: {e}")
|
|
|
|
print(f"\nDone: {counts['ok']} updated, {counts['already-set']} already had tryUrl, "
|
|
f"{counts['no-xslt']} skipped (no stylesheet found), {counts['error']} errors")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|