mirror of
https://github.com/tiennm99/HugoBlox-kit.git
synced 2026-10-11 12:11:45 +00:00
91 lines
3.7 KiB
HTML
91 lines
3.7 KiB
HTML
{{/* Hugo Blox: Dynamic Tailwind @source generation for Hugo modules */}}
|
|
{{/* Documentation: https://hugoblox.com/docs/ */}}
|
|
{{/* License: https://github.com/HugoBlox/kit/blob/main/LICENSE.md */}}
|
|
|
|
{{/*
|
|
This partial generates Tailwind CSS @source directives that tell Tailwind where to scan for CSS classes.
|
|
|
|
It provides a robust bridge between Hugo's virtual filesystem (which includes module mounts)
|
|
and Tailwind's real filesystem scanner.
|
|
*/}}
|
|
{{ $paths := slice }}
|
|
|
|
{{/* 1. Always scan the site's source files. */}}
|
|
{{ $paths = $paths | append `content/**/*.md` }}
|
|
{{ $paths = $paths | append `layouts/**/*.html` }}
|
|
{{ $paths = $paths | append `assets/js/**/*.js` }}
|
|
{{ $paths = $paths | append `assets/js/**/*.jsx` }}
|
|
{{ $paths = $paths | append `assets/js/**/*.tsx` }}
|
|
{{ $paths = $paths | append `hugo_stats.json` }}
|
|
|
|
{{/*
|
|
2. Crucially, scan Hugo's generated JS output from Preact components.
|
|
These files are built by Hugo's `js.Build` into a predictable location within the
|
|
project's `assets` directory, making them a reliable source for Tailwind to scan.
|
|
This step happens before Tailwind runs, thanks to `templates.Defer` in `site_head.html`.
|
|
*/}}
|
|
{{ $paths = $paths | append `assets/js/preact-built/**/*.js` }}
|
|
|
|
{{/*
|
|
3. Comprehensive class extraction from Preact JSX/TSX source files.
|
|
|
|
Hugo's virtual filesystem mounts block JSX/TSX into assets/js/hbx/blocks/.
|
|
Tailwind's @source file paths only work on the real filesystem, but these
|
|
files exist only in Hugo's virtual FS (or in a module cache for remote modules).
|
|
So we read the file content via resources.Match and extract class candidates inline.
|
|
|
|
Strategy: Extract ALL string literal content — not just class= attributes.
|
|
This catches classes in any pattern:
|
|
- Static attrs: class="gap-8 items-center"
|
|
- JSX expressions: class={"gap-8 items-center"}
|
|
- Template literals: class={`gap-8 ${cond ? "md:grid" : ""}`}
|
|
- Utility fns: cn("gap-8", condition && "md:grid-cols-2")
|
|
|
|
Tailwind's scanner automatically ignores non-class tokens (import paths,
|
|
error messages, etc.), so false positives are harmless.
|
|
*/}}
|
|
{{ $all_jsx := resources.Match "js/hbx/**/*.jsx" }}
|
|
{{ $all_tsx := resources.Match "js/hbx/**/*.tsx" }}
|
|
|
|
{{ $extracted_classes := slice }}
|
|
{{ range $f := $all_jsx | append $all_tsx }}
|
|
{{ $code := $f.Content }}
|
|
|
|
{{/* A) Extract content of all double-quoted strings */}}
|
|
{{ $dq_matches := findRE `"[^"]*"` $code }}
|
|
{{ range $m := $dq_matches }}
|
|
{{ $str := strings.TrimPrefix `"` (strings.TrimSuffix `"` $m) }}
|
|
{{ range split $str " " }}
|
|
{{ $t := strings.TrimSpace . }}
|
|
{{/* Filter out tokens with unsafe characters (braces, quotes, parens) */}}
|
|
{{ if and $t (not (findRE `[\{\}\(\)"';]` $t)) }}
|
|
{{ $extracted_classes = $extracted_classes | append $t }}
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{/* B) Extract static parts of template literals (backtick strings) */}}
|
|
{{/* Removes ${...} interpolations, keeping surrounding text */}}
|
|
{{ $bt_matches := findRE "`[^`]*`" $code }}
|
|
{{ range $m := $bt_matches }}
|
|
{{ $str := strings.TrimPrefix "`" (strings.TrimSuffix "`" $m) }}
|
|
{{ $static := replaceRE `\$\{[^}]*\}` " " $str }}
|
|
{{ range split $static " " }}
|
|
{{ $t := strings.TrimSpace . }}
|
|
{{/* Filter out tokens with unsafe characters (braces, quotes, parens) */}}
|
|
{{ if and $t (not (findRE `[\{\}\(\)"';]` $t)) }}
|
|
{{ $extracted_classes = $extracted_classes | append $t }}
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{ $extracted_classes = $extracted_classes | uniq }}
|
|
{{ range $class := $extracted_classes }}
|
|
@source inline("{{ $class }}");
|
|
{{ end }}
|
|
|
|
{{/* Generate the @source rules */}}
|
|
{{ range $paths }}
|
|
@source "{{ . }}";
|
|
{{ end }} |