#!/usr/bin/env python3 """Render the generated MediaWiki crafting page to a standalone HTML file with MediaWiki (Vector skin) styling, so it can be eyeballed locally. Handles exactly the subset of wikitext our generator emits: headings, bold/italic, [[links]], {| wikitable sortable |}, * lists, , __TOC__, [[Category:]]. """ import re, sys, html, pathlib SRC = pathlib.Path('/home/downloadpizza/sand_tools/wiki/Crafting.mediawiki') OUT = pathlib.Path.home() / 'sand_tools' / 'wiki_site' / 'index.html' def inline(t): # links: [[Target]] or [[Target|Label]] def lk(m): tgt = m.group(1); lab = m.group(2) or tgt return f'{html.escape(lab)}' t = re.sub(r'\[\[([^\]|]+)(?:\|([^\]]+))?\]\]', lk, t) t = re.sub(r"'''(.+?)'''", r'\1', t) t = re.sub(r"''(.+?)''", r'\1', t) return t # note: × / already valid HTML, pass through def render(wt): out = [] cats = [] lines = wt.splitlines() i = 0 while i < len(lines): ln = lines[i] if ln.strip() == '__TOC__': i += 1; continue m = re.match(r'\[\[Category:([^\]]+)\]\]', ln.strip()) if m: cats.append(m.group(1)); i += 1; continue h = re.match(r'^(=+)\s*(.*?)\s*=+\s*$', ln) if h: lvl = len(h.group(1)) out.append(f'{inline(h.group(2))}') i += 1; continue if ln.startswith('{|'): # table cls = 'wikitable' if 'sortable' in ln: cls += ' sortable' out.append(f'') i += 1 while i < len(lines) and not lines[i].startswith('|}'): row = lines[i] if row.startswith('!'): cells = row[1:].split('!!') out.append('' + ''.join( f'' for c in cells) + '') elif row.startswith('|-'): pass elif row.startswith('|'): cells = row[1:].split('||') out.append('' + ''.join( f'' for c in cells) + '') i += 1 out.append('
{inline(_celltext(c))}
{inline(_celltext(c))}
') i += 1; continue if ln.startswith('* '): items = [] while i < len(lines) and lines[i].startswith('* '): items.append(f'
  • {inline(lines[i][2:])}
  • '); i += 1 out.append(''); continue if ln.strip() == '': i += 1; continue out.append(f'

    {inline(ln)}

    ') i += 1 if cats: out.append('') return '\n'.join(out) def _celltext(c): # strip optional "attr=... | text" cell prefix if '|' in c and not c.strip().startswith('['): # only split on a | that's an attribute separator (before any [[ ) pre, _, post = c.partition('|') if '[[' not in pre: return post.strip() return c.strip() PAGE = """ {title} - SAND Wiki (local test)
    Local render for testing — not a live MediaWiki. Links are inert; sorting is basic JS.

    {title}

    {body}
    """ if __name__ == '__main__': wt = SRC.read_text() OUT.parent.mkdir(parents=True, exist_ok=True) OUT.write_text(PAGE.format(title='Crafting', body=render(wt))) print(f"wrote {OUT}")