clone

every nostr nip as a chapter of an illustrated, early-2000s printed game manual

main
nip.guide / qa.py
qa.py 1.6K
1import re, sys, glob, os, json2ok = True3files = sorted(glob.glob('site/nips/*.html'))4m = {n['num'] for n in json.load(open('manifest.json'))}5for f in files:6 t = open(f).read(); num = os.path.basename(f)[:-5].upper()7 err = []8 if 'ยท' in t: err.append('banned middle dot')9 if f'NIP {num} / F4' not in t: err.append('bad/missing pageno')10 if '<h5' in t: err.append('h5 used (use h3 class="cardhead")')11 if '<main class="spread">' not in t or '</main>' not in t: err.append('missing <main class="spread"> landmark')12 if t.count('rel="preload"') != 7: err.append('font preload links missing/wrong count')13 if 'favicon.svg' not in t: err.append('missing favicon link')14 if 'assets/webmcp.js' not in t: err.append('missing webmcp script tag')15 if t.count('<table class="ref"') != t.count('<div class="tscroll"><table class="ref"'):16 err.append('table.ref without tscroll wrapper')17 for tag in ['div','table','figure','svg','aside','section']:18 o, c = len(re.findall(f'<{tag}[ >]', t)), t.count(f'</{tag}>')19 if o != c: err.append(f'unbalanced <{tag}> {o}/{c}')20 for href in re.findall(r'href="([^"#]+\.html)"', t):21 if href.startswith('http'): continue22 base = os.path.basename(href).replace('.html','').upper()23 if href not in ('../index.html','index.html') and base not in m: err.append(f'dead link {href}')24 if any(ch.isupper() for ch in os.path.basename(href).replace('.html','')): err.append(f'uppercase link {href}')25 if err: ok = False; print(f'{f}: ' + '; '.join(err))26print(f'{len(files)} files checked -', 'ALL CLEAN' if ok else 'ISSUES FOUND')