'
res = []
i = 0
n = len(html)
while True:
idx = html.find(marker, i)
if idx == -1:
res.append(html[i:])
break
res.append(html[i:idx])
depth = 1
j = idx + len(marker)
while depth > 0 and j < n:
oi = html.find('
', j)
if ci == -1:
j = n
break
if oi != -1 and oi < ci:
depth += 1
j = oi + 4
else:
depth -= 1
j = ci + 6
i = j
return ''.join(res)
# ------------- balanced CSS block parser -------------
def strip_css(css, is_carousel):
out = []
i = 0
n = len(css)
while i < n:
m = re.match(r'\s+', css[i:])
if m:
out.append(m.group(0)); i += m.end(); continue
m = re.match(r'/\*.*?\*/', css[i:], re.S)
if m:
out.append(m.group(0)); i += m.end(); continue
brace = css.find('{', i)
if brace == -1:
out.append(css[i:]); break
sel = css[i:brace]
depth = 1
j = brace + 1
while depth > 0 and j < n:
if css[j] == '{': depth += 1
elif css[j] == '}': depth -= 1
j += 1
body = css[brace+1:j-1]
full = css[i:j]
selnorm = sel.strip()
if selnorm.startswith('@media') or selnorm.startswith('@supports'):
out.append(selnorm + '{' + strip_css(body, is_carousel) + '}')
elif re.search(r'\.(?:metric|star)', selnorm):
pass # drop star / metric rules
elif is_carousel and re.match(r'^\.student-card', selnorm):
if '.prev' in selnorm:
pass # drop the now-unneeded prev-state rule
elif '.active' in selnorm:
out.append('.student-card.active { display: block; position: relative; pointer-events: auto; }')
elif re.match(r'^\.student-card\s*$', selnorm):
out.append('.student-card { display: none; }')
else:
out.append(full) # .student-card:hover
else:
out.append(full)
i = j
return ''.join(out)
def process_styles(html, is_carousel):
def repl(m):
css = strip_css(m.group(2), is_carousel)
css = re.sub(r'backdrop-filter\s*:\s*blur\([^)]*\);?', '', css)
return m.group(1) + css + m.group(3)
return re.sub(r'()', repl, html, flags=re.S)
# ------------- dead star JS removal -------------
def remove_function(js, name):
pat = re.compile(r'function\s+' + re.escape(name) + r'\s*\(')
m = pat.search(js)
if not m:
return js
brace = js.find('{', m.end())
if brace == -1:
return js
depth = 1
j = brace + 1
n = len(js)
while depth > 0 and j < n:
if js[j] == '{': depth += 1
elif js[j] == '}': depth -= 1
j += 1
return js[:m.start()] + js[j:]
def remove_call(js, name):
return re.sub(r'^[ \t]*' + re.escape(name) + r'\(\).*?$', '', js, flags=re.M)
def fix(html):
is_carousel = 'id="cardsSlider"' in html
html = remove_metrics(html)
html = process_styles(html, is_carousel)
if 'function initStarRatings' in html and 'initStarRatings' in html:
html = remove_call(html, 'initStarRatings')
html = remove_function(html, 'initStarRatings')
html = remove_function(html, 'setStarRating')
return html
def main(files):
for path in files:
with open(path, encoding='utf-8') as f:
html = f.read()
out = fix(html)
changed = out != html
with open(path, 'w', encoding='utf-8') as f:
f.write(out)
print(('CHANGED ' if changed else 'same ') + os.path.basename(path))
if __name__ == '__main__':
main(sys.argv[1:])