From e48cbc0eee0a34d24d8e12f4badd27aafb63e262 Mon Sep 17 00:00:00 2001 From: Mat Manna Date: Sun, 26 Apr 2026 14:57:43 -0400 Subject: [PATCH] postbuild --- .github/workflows/jekyll.yml | 7 ++++- scripts/post-build.js | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 scripts/post-build.js diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml index becd95b..5f74b3e 100644 --- a/.github/workflows/jekyll.yml +++ b/.github/workflows/jekyll.yml @@ -40,14 +40,19 @@ jobs: ruby-version: '3.1' # Not needed with a .ruby-version file bundler-cache: true # runs 'bundle install' and caches installed gems automatically cache-version: 0 # Increment this number if you need to re-download cached gems + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' - name: Setup Pages id: pages uses: actions/configure-pages@v5 - name: Build with Jekyll - # Outputs to the './_site' directory by default run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" env: JEKYLL_ENV: production + - name: Minify CSS classes + run: node scripts/post-build.js - name: Upload artifact # Automatically uploads an artifact from the './_site' directory by default uses: actions/upload-pages-artifact@v3 diff --git a/scripts/post-build.js b/scripts/post-build.js new file mode 100644 index 0000000..1e1efe5 --- /dev/null +++ b/scripts/post-build.js @@ -0,0 +1,54 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const classMap = {}; +let idx = 0; + +function processFile(filePath) { + let html = fs.readFileSync(filePath, 'utf8'); + let modified = false; + let classesFound = 0; + + const matches = html.match(/class="([^"]+)"/g) || []; + + matches.forEach(m => { + const orig = m.match(/class="([^"]+)"/)[1]; + const classArr = orig.split(' ').filter(c => c); + const newArr = classArr.map(c => { + // Skip icons, no-*, and variant classes (dark:, [1]) + if (c.startsWith('fa-') || c.startsWith('no-') || c.includes(':') || c.startsWith('[')) return c; + if (!classMap[c]) { + classMap[c] = `c${idx++}`; + } + modified = true; + return classMap[c]; + }); + + if (modified) { + const newClasses = newArr.join(' '); + if (newClasses !== orig) { + html = html.replace(m, `class="${newClasses}"`); + } + } + }); + + if (modified) { + fs.writeFileSync(filePath, html); + } +} + +function walkDir(dir) { + if (!fs.existsSync(dir)) return; + fs.readdirSync(dir).forEach(name => { + const full = path.join(dir, name); + const stat = fs.statSync(full); + if (stat.isDirectory()) walkDir(full); + else if (name.endsWith('.html')) processFile(full); + }); +} + +walkDir('_site'); + +console.log(`Minified ${Object.keys(classMap).length} classes`); \ No newline at end of file -- 2.51.2