""" Kapselt bleeter/html/style.css fuer die Einbettung in pc-live. Warum nicht einfach einbinden: die Datei setzt Regeln auf *, html und body. Die wuerden den gesamten PC einfaerben – Schrift, Hintergrund, alles. Also bekommt jeder Selektor ein .bl-root davor, und die globalen Regeln werden umgeschrieben statt uebernommen. Rein mechanisch, damit es sich wiederholen laesst, wenn bleeter sein Aussehen aendert: python3 nui/css/erzeuge-bleeter-css.py """ import io, re import os # Aus dem Verzeichnis dieser Datei heraus aufrufbar: # python3 nui/css/erzeuge-bleeter-css.py HERE = os.path.dirname(os.path.abspath(__file__)) SRC = os.path.join(HERE, '..', '..', '..', 'bleeter', 'html', 'style.css') DST = os.path.join(HERE, 'bleeter-embedded.css') SCOPE = '.bl-root' # Vom Wurzelelement uebernehmen wir Farben, Schrift und Variablen – aber kein # Layout. Im Original ist .bleeter-root ein bildschirmfuellendes Overlay # (position:fixed; inset:0). Uebernaehme man das, laege die App ueber dem # gesamten PC, inklusive Titelleiste – man kaeme nicht mehr heraus. ROOT_SELECTORS = (':root', 'html', 'body') ROOT_KEEP = ('color', 'font-family', 'font-size', 'font-weight', 'letter-spacing', 'line-height') def is_root_selector(sel): return sel in ROOT_SELECTORS or sel.startswith('.bleeter-root') def filter_root_declarations(body): """Nur Variablen und Schrift behalten, alles Raeumliche verwerfen.""" kept = [] for decl in body.split(';'): decl = decl.strip() if not decl: continue prop = decl.split(':', 1)[0].strip().lower() if prop.startswith('--') or prop in ROOT_KEEP: kept.append(decl) return ';'.join(kept) def scope_selector(sel): sel = sel.strip() if not sel: return sel if is_root_selector(sel): return SCOPE if sel == '*': return SCOPE + ' *' return SCOPE + ' ' + sel def rule(selector_list, body): sels_raw = [s.strip() for s in selector_list.split(',')] if any(is_root_selector(s) for s in sels_raw): body = filter_root_declarations(body) if not body: return None sels = ','.join(scope_selector(s) for s in sels_raw) return sels + '{' + body.strip() + '}' def scope_block(block): parts = [] for m in re.finditer(r'([^{}]+)\{([^{}]*)\}', block, flags=re.S): r = rule(m.group(1), m.group(2)) if r: parts.append(r) return '\n'.join(parts) css = re.sub(r'/\*.*?\*/', '', io.open(SRC, encoding='utf-8').read(), flags=re.S) out, i, n = [], 0, len(css) while i < n: m = re.match(r'\s*@(media|supports|keyframes|-webkit-keyframes)([^{]*)\{', css[i:]) if m: depth, j = 1, i + m.end() while j < n and depth: if css[j] == '{': depth += 1 elif css[j] == '}': depth -= 1 j += 1 inner = css[i + m.end(): j - 1] head = '@' + m.group(1) + m.group(2) + '{' # Prozentschritte in keyframes sind keine Selektoren out.append(head + (inner if 'keyframes' in m.group(1) else scope_block(inner)) + '}') i = j continue m = re.match(r'([^{}]+)\{([^{}]*)\}', css[i:], flags=re.S) if not m: i += 1 continue r = rule(m.group(1), m.group(2)) if r: out.append(r) i += m.end() header = ( '/* Erzeugt aus bleeter/html/style.css – nicht von Hand aendern.\n' ' Jeder Selektor ist auf .bl-root gekapselt, damit Bleeters Farben und\n' ' Schrift nicht den uebrigen PC einfaerben. */\n' ) io.open(DST, 'w', encoding='utf-8').write(header + '\n'.join(out) + '\n') print(f'{len(out)} Regeln -> {DST}')