117 lines
3.6 KiB
Python
117 lines
3.6 KiB
Python
|
|
"""
|
|||
|
|
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}')
|