From b7382a20ab74de7f84fdebd155802219c738093a Mon Sep 17 00:00:00 2001 From: "N0\\A" Date: Thu, 19 Mar 2026 15:35:14 +0100 Subject: [PATCH] feat: new default style and more --- awk/fenced_code.awk | 24 +++++++-- awk/indented_code.awk | 25 +++++++--- awk/render_template.awk | 14 ++++-- kewt.sh | 23 +++++++-- site/index.md | 8 +++ styles/kewt.css | 106 ++++++++++++++++++++++++++++++---------- 6 files changed, 156 insertions(+), 44 deletions(-) diff --git a/awk/fenced_code.awk b/awk/fenced_code.awk index 6a866ea..0ddd63c 100644 --- a/awk/fenced_code.awk +++ b/awk/fenced_code.awk @@ -1,11 +1,20 @@ -BEGIN { in_fence = 0; first_line = 0 } +BEGIN { in_fence = 0; first_line = 0; code_tag = "" } { if (!in_fence && $0 ~ /^```/) { in_fence = 1 first_line = 1 + lang = $0 + sub(/^```[[:space:]]*/, "", lang) + sub(/[[:space:]]*$/, "", lang) + if (lang != "") { + code_tag = "" + } else { + code_tag = "" + } next } if (in_fence && $0 ~ /^```[[:space:]]*$/) { + if (first_line) printf "%s", "
" code_tag
         print "
" in_fence = 0 next @@ -14,8 +23,12 @@ BEGIN { in_fence = 0; first_line = 0 } gsub(/&/, "\\&"); gsub(//, "\\>") if (first_line) { first_line = 0 - if ($0 == "") next - print "
" $0
+            printf "%s", "
" code_tag
+            if ($0 == "") {
+                print ""
+                next
+            }
+            print $0
         } else {
             print
         }
@@ -24,5 +37,8 @@ BEGIN { in_fence = 0; first_line = 0 }
     }
 }
 END {
-    if (in_fence) print "
" + if (in_fence) { + if (first_line) printf "%s", "
" code_tag
+        print "
" + } } diff --git a/awk/indented_code.awk b/awk/indented_code.awk index c67dd02..285d842 100644 --- a/awk/indented_code.awk +++ b/awk/indented_code.awk @@ -1,9 +1,20 @@ -BEGIN { in_code = 0 } -/^ | / { - if (!in_code) { print "
"; in_code = 1 }
-    sub(/^	|    /, "", $0)
-    gsub(/&/, "\\&"); gsub(//, "\\>")
-    print; next
+BEGIN { in_code = 0; in_html_pre = 0 }
+{
+    if ($0 ~ /
/) in_html_pre = 1
+    if ($0 ~ /<\/pre>/) { in_html_pre = 0; if (in_code) { print "
"; in_code = 0 }; print; next } + + if (!in_html_pre && $0 ~ /^(\t| )/) { + if (!in_code) { printf "%s", "
"; in_code = 1 }
+        sub(/^(\t|    )/, "", $0)
+        gsub(/&/, "\\&"); gsub(//, "\\>")
+        print
+        next
+    }
+    
+    if (in_code) {
+        print "
" + in_code = 0 + } + print } -{ if (in_code) { print "
"; in_code = 0 } print } END { if (in_code) print "
" } diff --git a/awk/render_template.awk b/awk/render_template.awk index 90d3b06..ca103d9 100644 --- a/awk/render_template.awk +++ b/awk/render_template.awk @@ -1,9 +1,17 @@ -function replace_all(text, token, value, pos, token_len) { +function replace_all(text, token, value, pos, token_len, res) { token_len = length(token) + res = "" while ((pos = index(text, token)) > 0) { - text = substr(text, 1, pos - 1) value substr(text, pos + token_len) + res = res substr(text, 1, pos - 1) value + text = substr(text, pos + token_len) + } + return res text +} + +BEGIN { + if (current_url != "") { + nav = replace_all(nav, "href=\"" current_url "\"", "href=\"" current_url "\" class=\"current-page\"") } - return text } { diff --git a/kewt.sh b/kewt.sh index 36103d9..a99a20a 100755 --- a/kewt.sh +++ b/kewt.sh @@ -69,6 +69,7 @@ EOF + {{TITLE}} @@ -207,6 +208,7 @@ CONFEOF + {{TITLE}} @@ -623,6 +625,15 @@ copy_style_with_resolved_vars() { render_markdown() { file="$1" is_home="$2" + url_override="$3" + + if [ -n "$url_override" ]; then + current_url="$url_override" + else + rel_path="${file#"$src"}" + rel_path="${rel_path#/}" + current_url="/${rel_path%.md}.html" + fi content_file="$file" if [ -n "$posts_dir" ] && [ "$file" != "$src/$posts_dir/index.md" ]; then @@ -704,7 +715,7 @@ render_markdown() { fi fi - ENABLE_HEADER_LINKS="$enable_header_links" MARKDOWN_SITE_ROOT="$src" MARKDOWN_FALLBACK_FILE="$script_dir/styles/$style.css" sh "$script_dir/markdown.sh" "$content_file" | awk -v title="$page_title" -v nav="$nav" -v footer="$footer" -v style_path="${style_path}${asset_version}" -v header_brand="$header_brand" -v head_extra="$head_extra" -f "$awk_dir/render_template.awk" "$local_template" + ENABLE_HEADER_LINKS="$enable_header_links" MARKDOWN_SITE_ROOT="$src" MARKDOWN_FALLBACK_FILE="$script_dir/styles/$style.css" sh "$script_dir/markdown.sh" "$content_file" | awk -v current_url="$current_url" -v title="$page_title" -v nav="$nav" -v footer="$footer" -v style_path="${style_path}${asset_version}" -v header_brand="$header_brand" -v head_extra="$head_extra" -f "$awk_dir/render_template.awk" "$local_template" } echo "Building site from '$src' to '$out'..." @@ -734,7 +745,9 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while if [ "$md_count" -eq 1 ]; then md_file=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md") is_home="false"; [ "$dir" = "$src" ] && is_home="true" - render_markdown "$md_file" "$is_home" > "$out_dir/index.html" + target_url="/$rel_dir/index.html" + [ "$rel_dir" = "." ] && target_url="/index.html" + render_markdown "$md_file" "$is_home" "$target_url" > "$out_dir/index.html" continue fi fi @@ -792,7 +805,9 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while fi done is_home="false"; [ "$dir" = "$src" ] && is_home="true" - render_markdown "$temp_index" "$is_home" > "$out_dir/index.html" + target_url="/$rel_dir/index.html" + [ "$rel_dir" = "." ] && target_url="/index.html" + render_markdown "$temp_index" "$is_home" "$target_url" > "$out_dir/index.html" rm "$temp_index" fi done @@ -840,7 +855,7 @@ if [ -n "$error_page" ] && [ ! -f "$out/$error_page" ]; then echo "# 404 - Not Found" > "$temp_404" echo "" >> "$temp_404" echo "The requested page could not be found." >> "$temp_404" - render_markdown "$temp_404" > "$out/$error_page" + render_markdown "$temp_404" "false" "/$error_page" > "$out/$error_page" rm -f "$temp_404" fi diff --git a/site/index.md b/site/index.md index b71cfbf..8e7f448 100644 --- a/site/index.md +++ b/site/index.md @@ -22,6 +22,11 @@ It's meant to be a static site generator, like _[kew](https://github.com/uint23/ - Admonition support (that's what the blocks like the warning block below are called) - RSS/Feed generation and Sitemap support - Post creation via `--post` +- Automatic 404 page generation +- `?v=n` support for cache busting +- Code block classes for use with external libraries like highlight.js or prism.js (both tested) +- Clickable markdown header anchors +- Mobile responsive layout If you want to **force** a file to be inlined, use `\!![]` instead of `\![]` @@ -43,6 +48,7 @@ On Arch Linux, _kewt_ is available on the AUR: ```sh ./kewt.sh --help +./kewt.sh --version ./kewt.sh --new [title] ./kewt.sh --post ./kewt.sh --from --to @@ -79,6 +85,7 @@ base_url = "" generate_feed = false feed_file = "rss.xml" posts_dir = "" +enable_header_links = true ``` - `title` site title @@ -104,6 +111,7 @@ posts_dir = "" - `generate_feed` enable RSS feed generation (requires `base_url`) - `feed_file` filename for the generated RSS feed (default: "rss.xml") - `posts_dir` directory name containing posts (e.g., "posts"). Enables reverse-chronological sorting, title headings in indexes, and automatic backlinks. +- `enable_header_links` turns markdown section headings into clickable anchor links (default: true) ## Ignores diff --git a/styles/kewt.css b/styles/kewt.css index 24fa6fc..e250723 100644 --- a/styles/kewt.css +++ b/styles/kewt.css @@ -1,25 +1,28 @@ :root { - --bg: #646c7f; - --fg: #fffde0; - --fg-link: #fff18f; - --code-bg: #32394a; - --code-border: #8f95a4; - --code-fg: #fffde0; - --code-sel: #fff18f; - --code-prop: #ffd27f; - --code-val: #cde7ff; - --code-var: #b9ffbe; - --code-com: #d0d0d0; - --adm-note-bg: #3f5666; - --adm-note-border: #a8d8ff; - --adm-tip-bg: #3f664c; - --adm-tip-border: #b9ffbe; - --adm-important-bg: #5a4a6c; - --adm-important-border: #e4c7ff; - --adm-warning-bg: #6b5539; - --adm-warning-border: #ffe0a8; - --adm-caution-bg: #6f3f3f; - --adm-caution-border: #ffb4b4; + --bg: #4a3b69; + --bg-deep: #352654; + --fg: #fbf5ff; + --fg-muted: #c8b9df; + --fg-link: #dfaeff; + --fg-heading: #debfff; + --code-bg: #31234c; + --code-border: #8060af; + --code-fg: #fbf5ff; + --code-sel: #ffef99; + --code-prop: #ffdfba; + --code-val: #cae2ff; + --code-var: #caffc2; + --code-com: #b8aac8; + --adm-note-bg: #353866; + --adm-note-border: #b8c5ff; + --adm-tip-bg: #295246; + --adm-tip-border: #aeffda; + --adm-important-bg: #533076; + --adm-important-border: #f4d9ff; + --adm-warning-bg: #634631; + --adm-warning-border: #ffe2bd; + --adm-caution-bg: #662d43; + --adm-caution-border: #ffc4d5; } body { @@ -29,18 +32,22 @@ body { color: var(--fg); font-family: serif; font-size: 16px; - line-height: 1.2; + line-height: 1.5; } header { padding: 20px; + padding-bottom: 0; + border-bottom: 1px solid var(--code-border); + margin-bottom: 20px; } header h1 { margin: 0; font-size: 35px; - font-weight: normal; + font-weight: bold; font-style: italic; + color: var(--fg-heading); } .site-logo { @@ -57,18 +64,26 @@ header a { text-decoration: none; } +header a:hover { + color: var(--bg-deep); + background: var(--fg); +} + #side-bar { position: absolute; top: 80px; left: 0; width: 200px; padding-left: 20px; + margin-right: 14px; + border-right: 1px solid var(--code-border); + padding-right: 7px; } .side-title { font-size: 25px; margin: 20px 0 8px 0; - color: var(--fg); + color: var(--fg-heading); } #side-bar ul { @@ -87,6 +102,14 @@ a { padding: 1px 2px; } +#side-bar a.current-page { + font-weight: bold; + color: var(--fg); + border-left: 3px solid var(--fg-link); + padding-left: 7px; + margin-left: -10px; +} + a:hover { background: var(--fg); color: var(--bg); @@ -100,7 +123,7 @@ article { h3 { margin-top: 30px; font-size: 25px; - color: var(--fg); + color: var(--fg-heading); font-weight: normal; } @@ -197,10 +220,11 @@ pre code { } footer { - padding-top: 80px; + padding-top: 60px; font-style: italic; font-size: 17px; margin-bottom: 20px; + color: var(--fg-muted); } article, @@ -220,3 +244,33 @@ footer img { display: inline-block; vertical-align: top; } + +hr { + height: 0; + margin: 24px 0; + border: 0; + border-top: 1px solid var(--code-border); +} + +@media screen and (max-width: 600px) { + #side-bar { + position: relative; + top: auto; + left: auto; + width: auto; + border-right: none; + border-bottom: 1px solid var(--code-border); + padding: 0 0 20px 0; + margin: 0 20px 20px 20px; + } + + article { + margin: 0 20px 0 20px; + } + + footer { + margin-left: 20px; + margin-right: 20px; + padding-top: 30px; + } +} \ No newline at end of file