Going for max minify for css, js, and html.
Some checks are pending
lint / runner / vale (push) Waiting to run
Lint / MegaLinter (push) Waiting to run

This commit is contained in:
g_it 2026-03-15 00:48:10 +01:00
commit 6f93624b4b
Signed by untrusted user who does not match committer: g_it
GPG key ID: A2B0A7C06A054627
3 changed files with 60 additions and 16 deletions

View file

@ -1,6 +1,7 @@
FROM python:3.13-slim AS builder FROM python:3.13-slim AS builder
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN apt-get update && apt-get install -y nodejs npm && npm install -g terser clean-css-cli
RUN pip install --no-cache-dir -r ./requirements.txt RUN pip install --no-cache-dir -r ./requirements.txt
RUN zensical build RUN zensical build
RUN rm ./deploy/sitemap.xml RUN rm ./deploy/sitemap.xml

View file

@ -2,30 +2,75 @@
"""Minify CSS, JS, and HTML files in the deploy directory in-place.""" """Minify CSS, JS, and HTML files in the deploy directory in-place."""
import re import re
import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
import rcssmin
import rjsmin
DEPLOY_DIR = Path("./deploy") DEPLOY_DIR = Path("./deploy")
def minify_html_content(content): def minify_css(content):
content = re.sub(r"<!--.*?-->", "", content, flags=re.DOTALL) # remove comments result = subprocess.run(
content = re.sub(r">\s+<", "><", content) # collapse whitespace between tags ["cleancss"],
content = re.sub(r"\s{2,}", " ", content) # collapse remaining whitespace input=content,
return content.strip() capture_output=True,
text=True,
)
if result.returncode != 0:
print(f" cleancss error: {result.stderr}", file=sys.stderr)
return content
return result.stdout
def minify_js(content):
result = subprocess.run(
["terser", "--compress", "--mangle"],
input=content,
capture_output=True,
text=True,
)
if result.returncode != 0:
print(f" terser error: {result.stderr}", file=sys.stderr)
return content
return result.stdout
def minify_html(content):
# Extract and preserve <pre> and <code> blocks before minifying
preserved = {}
def preserve(match):
key = f"\x00PRESERVE{len(preserved)}\x00"
preserved[key] = match.group(0)
return key
content = re.sub(r"<pre[\s\S]*?</pre>", preserve, content, flags=re.IGNORECASE)
content = re.sub(r"<code[\s\S]*?</code>", preserve, content, flags=re.IGNORECASE)
# Minify everything else
content = re.sub(r"<!--.*?-->", "", content, flags=re.DOTALL)
content = " ".join(line.strip() for line in content.splitlines())
content = re.sub(r">\s+<", "><", content)
content = re.sub(r"\s{2,}", " ", content)
content = content.strip()
# Restore preserved blocks untouched
for key, value in preserved.items():
content = content.replace(key, value)
return content
HANDLERS = {
".css": minify_css,
".js": minify_js,
".html": minify_html,
}
def minify_files(): def minify_files():
handlers = {
".css": lambda c: rcssmin.cssmin(c),
".js": lambda c: rjsmin.jsmin(c, keep_bang_comments=False),
".html": minify_html_content,
}
for file in DEPLOY_DIR.rglob("*"): for file in DEPLOY_DIR.rglob("*"):
handler = handlers.get(file.suffix) handler = HANDLERS.get(file.suffix)
if not handler: if not handler:
continue continue
content = file.read_text(encoding="utf-8") content = file.read_text(encoding="utf-8")

View file

@ -22,8 +22,6 @@ pymdown-extensions==10.21
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
PyYAML==6.0.3 PyYAML==6.0.3
pyyaml_env_tag==1.1 pyyaml_env_tag==1.1
rcssmin==1.2.2
rjsmin==1.2.4
six==1.17.0 six==1.17.0
watchdog==6.0.0 watchdog==6.0.0
zensical==0.0.27 zensical==0.0.27