# -*- coding: utf-8 -*- # Korrekter rekursiver {{#if}}-Renderer (wie echtes Handlebars) zur Verifikation. import re, glob, json, os BASE=os.path.dirname(__file__) schema=json.load(open(os.path.join(BASE,"variables.schema.json"))) allvars=set(schema["properties"].keys()) def make_ctx(inc, extra=None): c={k:(True if k.startswith("FLAG_") else k) for k in allvars} for k in ["FLAG_OT_USED","FLAG_DEV_INHOUSE","FLAG_CRYPTO_PKI","FLAG_CUSTOMER_SYSTEMS"]: c[k]=False c["FLAG_INCLUDE_SHOULD"]=inc c["ORG_NAME"]="Muster GmbH"; c["TOOL_NAME"]="ISMS-Portal"; c["REVIEW_CYCLE"]="jährlich" if extra: c.update(extra) return c def render_if(t,c): # rekursiv innerste Bloecke zuerst pat=re.compile(r"\{\{#if (\w+)\}\}((?:(?!\{\{#if )(?!\{\{/if\}\}).)*?)\{\{/if\}\}",re.S) prev=None while prev!=t: prev=t t=pat.sub(lambda m:(m.group(2) if c.get(m.group(1)) else ""),t) return t def render(t,c): t=render_if(t,c) t=re.sub(r"\{\{LINK:[^}]+\}\}","[LINK]",t) t=re.sub(r"\{\{(\w+)\}\}",lambda m:str(c[m.group(1)]) if m.group(1) in c else "«MISS:%s»"%m.group(1),t) return t files=sorted(glob.glob(os.path.join(BASE,"richtlinien/*.md")))+[os.path.join(BASE,"Nachweisregister_zentral.md"),os.path.join(BASE,"ISA-Mapping-Matrix.md")] problems=0 for inc in [True,False]: c=make_ctx(inc) for fp in files: r=render(open(fp,encoding="utf-8").read(),c) bad=re.findall(r"\{\{.*?\}\}",r); miss=sorted(set(re.findall(r"«MISS:\w+»",r))) if bad or miss: problems+=1; print("!",os.path.basename(fp),"inc=%s"%inc,"open:",bad[:4],"miss:",miss[:4]) d=json.load(open(os.path.join(BASE,"mapping.json"))) fa=set() for fp in glob.glob(os.path.join(BASE,"richtlinien/*.md")): for m in re.findall(r"",open(fp,encoding="utf-8").read()): fa.add(m[0]+" "+m[1]) ma=set() for a in d["anforderungen"]: ma.add(a["req_anchor"]); ma.add(a["impl_anchor"]) # F17: mapping.json enthaelt kein 'implementation'-Feld; der Umsetzungstext wird zur # Laufzeit ueber impl_anchor (Control-IMPL-Block) aus der jeweiligen .md aufgeloest. leftover_hb=any("{{" in a["requirement"] or "{{" in a.get("implementation","") for a in d["anforderungen"]) print("Render-Probleme:",problems) print("mapping-Anker ohne Datei:",sorted(ma-fa)) print("Datei-Anker ohne mapping:",sorted(fa-ma)) print("Handlebars-Reste in mapping-Text:",leftover_hb) print("OK" if problems==0 and not (ma-fa) and not (fa-ma) and not leftover_hb else "PRUEFEN")