Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fc3d6fc6f | |||
| c5a9355871 | |||
| b8cd129c47 | |||
| 5e033a65e7 | |||
| 5bf2e2abe5 | |||
| 3a2056ff8f | |||
| fd829a3f22 | |||
| bad02decba | |||
| 2aef6ec4a1 | |||
| 78eac182dc | |||
| b7382a20ab | |||
| d8cf07ee2a | |||
| 76e2ae0117 | |||
| 2e331b5d9a | |||
| 9f5d1089a2 |
35
.gitea/workflows/publish-aur-git.yml
Normal file
35
.gitea/workflows/publish-aur-git.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Publish kewt-git to AUR
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'packaging/AUR/PKGBUILD.git'
|
||||
- 'packaging/AUR/.SRCINFO.git'
|
||||
|
||||
jobs:
|
||||
publish-aur-git:
|
||||
runs-on: local
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Arch Linux environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y pacman-package-manager curl jq || true
|
||||
|
||||
- name: Prepare AUR files
|
||||
run: |
|
||||
mkdir -p aur-work
|
||||
cp packaging/AUR/PKGBUILD.git aur-work/PKGBUILD
|
||||
cp packaging/AUR/.SRCINFO.git aur-work/.SRCINFO
|
||||
|
||||
- name: Publish to AUR
|
||||
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
|
||||
with:
|
||||
pkgname: kewt-git
|
||||
pkgbuild: ./aur-work/PKGBUILD
|
||||
commit_username: ${{ github.actor }}
|
||||
commit_email: ${{ github.actor }}@users.noreply.github.com
|
||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
commit_message: "Update kewt-git to ${{ github.sha }}"
|
||||
@@ -32,12 +32,24 @@ jobs:
|
||||
run: |
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
|
||||
# Fetch release body from Gitea
|
||||
RELEASE_BODY=$(curl -sL \
|
||||
"https://git.krzak.org/api/v1/repos/N0VA/kewt/releases/tags/${TAG}" \
|
||||
| jq -r '.body // ""')
|
||||
|
||||
# Build JSON payload
|
||||
PAYLOAD=$(jq -n \
|
||||
--arg tag "$TAG" \
|
||||
--arg name "Release $TAG" \
|
||||
--arg body "$RELEASE_BODY" \
|
||||
'{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}')
|
||||
|
||||
# Create the release on GitHub
|
||||
curl -sL -X POST \
|
||||
-H "Authorization: token ${{ secrets.GH_RELEASE_TOKEN }}" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/n0va-bot/kewt/releases" \
|
||||
-d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\",\"draft\":false,\"prerelease\":false}" || true
|
||||
-d "$PAYLOAD" || true
|
||||
|
||||
# Get the release ID
|
||||
RELEASE_ID=$(curl -sL \
|
||||
@@ -78,25 +90,9 @@ jobs:
|
||||
-e "s/SHA256SUM_PLACEHOLDER/${CHECKSUM}/g" \
|
||||
packaging/AUR/PKGBUILD.template > aur-work/PKGBUILD
|
||||
|
||||
cat > aur-work/.SRCINFO << SRCEOF
|
||||
pkgbase = kewt-bin
|
||||
pkgdesc = A minimalist, 100% POSIX, static site generator inspired by werc and kew
|
||||
pkgver = ${VERSION}
|
||||
pkgrel = 1
|
||||
url = https://git.krzak.org/N0VA/kewt
|
||||
arch = any
|
||||
license = MIT
|
||||
depends = sh
|
||||
provides = kewt
|
||||
conflicts = kewt
|
||||
conflicts = kewt-git
|
||||
source = kewt-bin-${VERSION}.sh::https://git.krzak.org/N0VA/kewt/releases/download/v${VERSION}/kewt
|
||||
sha256sums = ${CHECKSUM}
|
||||
|
||||
pkgname = kewt-bin
|
||||
SRCEOF
|
||||
# Remove leading whitespace from heredoc
|
||||
sed -i 's/^ //' aur-work/.SRCINFO
|
||||
sed -e "s/VERSION_PLACEHOLDER/${VERSION}/g" \
|
||||
-e "s/SHA256SUM_PLACEHOLDER/${CHECKSUM}/g" \
|
||||
packaging/AUR/.SRCINFO.template > aur-work/.SRCINFO
|
||||
|
||||
- name: Publish to AUR
|
||||
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
|
||||
|
||||
5
LICENSE
5
LICENSE
@@ -18,9 +18,8 @@ PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
This project incorporates code (CSS style) from the 'kew' project, which is also licensed under the ISC License:
|
||||
|
||||
Copyright (c) 2023 uint23
|
||||
This project incorporates code (CSS style) from the 'kew' project,
|
||||
which is also licensed under the ISC License: Copyright (c) 2026 uint23
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
112
README.md
112
README.md
@@ -1,29 +1,16 @@
|
||||
# _kewt_
|
||||
# 
|
||||
### Pronounced "cute"
|
||||
|
||||
***
|
||||
|
||||
# [Go to the website](https://kewt.krzak.org)
|
||||
|
||||
***
|
||||
|
||||
_kewt_ is a minimalist ssg inspired by _[werc](http://werc.cat-v.org/)_ and _[kew](https://github.com/uint23/kew)_
|
||||
|
||||
It's meant to be a static site generator, like _[kew](https://github.com/uint23/kew)_ but use only default (POSIX) tooling, like _[werc](http://werc.cat-v.org/)_ (and definitely unlike _[kew](https://github.com/uint23/kew)_)
|
||||
|
||||
## Features
|
||||
|
||||
- No dependencies
|
||||
- Supports many embed types
|
||||
- Automatic css variable replacement for older browsers
|
||||
- Automatic inlining and embedding of many filetypes with `\![link]` or `\`
|
||||
- Inline html support
|
||||
- MFM `$font` and `\<plain>` tags
|
||||
- Admonition support (that's what the blocks like the warning block below are called)
|
||||
- RSS/Feed generation and Sitemap support
|
||||
- Post creation via `--post`
|
||||
|
||||
If you want to **force** a file to be inlined, use `\!![]` instead of `\![]`
|
||||
|
||||
## Installation
|
||||
|
||||
You can clone the repository to use `kewt.sh` directly, or you can download the standalone executable, which bundles all dependencies into a single file:
|
||||
## Quick Install
|
||||
|
||||
```sh
|
||||
curl -L -o kewt https://git.krzak.org/N0VA/kewt/releases/download/latest/kewt
|
||||
@@ -35,91 +22,10 @@ On Arch Linux, _kewt_ is available on the AUR:
|
||||
- [kewt-bin](https://aur.archlinux.org/packages/kewt-bin) — prebuilt standalone binary from the latest release
|
||||
- [kewt-git](https://aur.archlinux.org/packages/kewt-git) — built from the latest git source
|
||||
|
||||
## Usage
|
||||
## Contributing
|
||||
|
||||
```sh
|
||||
./kewt.sh --help
|
||||
./kewt.sh --new [title]
|
||||
./kewt.sh --post
|
||||
./kewt.sh --from <src> --to <out>
|
||||
./kewt.sh [src] [out]
|
||||
```
|
||||
|
||||
`--new [title]` creates a new site directory with a copied `site.conf` and a default `index.md`.
|
||||
|
||||
`--post` creates a new empty markdown file in the configured `posts_dir` with the current date and time as the name.
|
||||
|
||||
## site.conf
|
||||
|
||||
```conf
|
||||
title = "kewt"
|
||||
style = "kewt"
|
||||
dir_indexes = true
|
||||
single_file_index = true
|
||||
flatten = false
|
||||
order = ""
|
||||
home_name = "Home"
|
||||
show_home_in_nav = true
|
||||
nav_links = ""
|
||||
nav_extra = ""
|
||||
footer = "made with <a href=\"https://kewt.krzak.org\">kewt</a>"
|
||||
logo = ""
|
||||
display_logo = false
|
||||
display_title = true
|
||||
logo_as_favicon = true
|
||||
favicon = ""
|
||||
generate_page_title = true
|
||||
error_page = "not_found.html"
|
||||
versioning = false
|
||||
base_url = ""
|
||||
generate_feed = false
|
||||
feed_file = "rss.xml"
|
||||
posts_dir = ""
|
||||
```
|
||||
|
||||
- `title` site title
|
||||
- `style` style file name from `./styles` (without `.css`)
|
||||
- `dir_indexes` generate directory index pages when missing `index.md`
|
||||
- `single_file_index` if a directory has one markdown file and no `index.md`, use that file as `index.html`
|
||||
- `flatten` flatten sidebar directory levels
|
||||
- `order` comma separated file/directory name list to order the sidebar (alphabetical by default)
|
||||
- `home_name` text for the home link in navigation (default: "Home")
|
||||
- `show_home_in_nav` show home link in navigation (default: true)
|
||||
- `nav_links` comma separated extra nav links, as bare URLs or Markdown links like `[Label](https://example.com)`
|
||||
- `nav_extra` raw HTML appended inside the `<nav>` after the generated link list
|
||||
- `footer` footer html/text shown at the bottom of pages
|
||||
- `logo` logo image path (used in header if enabled)
|
||||
- `display_logo` show logo in header
|
||||
- `display_title` show title text in header
|
||||
- `logo_as_favicon` use `logo` as favicon
|
||||
- `favicon` explicit favicon path (used when `logo_as_favicon` is false or no logo is set)
|
||||
- `generate_page_title` automatically generate title text from the first markdown heading or filename (default: true)
|
||||
- `error_page` filename for the generated 404 error page (default: "not_found.html", empty to disable)
|
||||
- `versioning` append a version query parameter (`?v=timestamp`) to css asset urls to bypass cache (default: false)
|
||||
- `base_url` absolute URL of the site, used for sitemap and RSS feed generation
|
||||
- `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.
|
||||
|
||||
## Ignores
|
||||
|
||||
- `.kewtignore`: Files/directories to ignore. If empty, the whole directory gets ignored
|
||||
- `.kewthide`: Files/directories to hide from navigation but still process. Same empty rules as with ignore
|
||||
- `.kewtpreserve`: Files/directories to copy but not convert markdown to html. Same empty rules again
|
||||
|
||||
## Embeds
|
||||
|
||||
- `\![link]`:
|
||||
- local image/audio/video files are embedded as media tags
|
||||
- local text/code files are inlined directly
|
||||
- global image/audio/video links are embedded as media tags
|
||||
- other global links are embedded as `<iframe>`
|
||||
- `\` works the same, with `alt` used for images
|
||||
- `\!![]` and `\!` force inline local file contents
|
||||
Either through a pull request to the **home** repository ([N0VA/kewt](https://git.krzak.org/N0VA/kewt)) or by sending a patch to my email address ([n0va@krzak.org](mailto:n0va@krzak.org))
|
||||
|
||||
## Credits
|
||||
|
||||
- Default css style and html template based on _[kew](https://github.com/uint23/kew)_ by [uint23](https://github.com/uint23)
|
||||
|
||||
>[!WARNING]
|
||||
>Most of this was coded at night, while sleepy and a bit sick, and after walking for about 4 hours around a forest, so...
|
||||
- _kew_ css style adapted from _[kew](https://github.com/uint23/kew)_ by [uint23](https://github.com/uint23)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
BEGIN {
|
||||
src = ENVIRON["AWK_SRC"]
|
||||
slen = length(src)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
BEGIN { in_fence = 0; first_line = 0 }
|
||||
BEGIN { in_fence = 0; first_line = 0; code_tag = "<code>" }
|
||||
{
|
||||
if (!in_fence && $0 ~ /^```/) {
|
||||
in_fence = 1
|
||||
first_line = 1
|
||||
lang = $0
|
||||
sub(/^```[[:space:]]*/, "", lang)
|
||||
sub(/[[:space:]]*$/, "", lang)
|
||||
if (lang != "") {
|
||||
code_tag = "<code class=\"language-" lang "\">"
|
||||
} else {
|
||||
code_tag = "<code>"
|
||||
}
|
||||
next
|
||||
}
|
||||
if (in_fence && $0 ~ /^```[[:space:]]*$/) {
|
||||
if (first_line) printf "%s", "<pre>" code_tag
|
||||
print "</code></pre>"
|
||||
in_fence = 0
|
||||
next
|
||||
@@ -14,8 +23,12 @@ BEGIN { in_fence = 0; first_line = 0 }
|
||||
gsub(/&/, "\\&"); gsub(/</, "\\<"); gsub(/>/, "\\>")
|
||||
if (first_line) {
|
||||
first_line = 0
|
||||
if ($0 == "") next
|
||||
print "<pre><code>" $0
|
||||
printf "%s", "<pre>" 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 "</code></pre>"
|
||||
if (in_fence) {
|
||||
if (first_line) printf "%s", "<pre>" code_tag
|
||||
print "</code></pre>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,13 @@ function compare_paths(p1, p2, parts1, parts2, n1, n2, i, name1, name2, lname
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
src = ENVIRON["AWK_SRC"]
|
||||
single_file_index = ENVIRON["AWK_SINGLE_FILE_INDEX"]
|
||||
flatten = ENVIRON["AWK_FLATTEN"]
|
||||
order = ENVIRON["AWK_ORDER"]
|
||||
home_name = ENVIRON["AWK_HOME_NAME"]
|
||||
show_home_in_nav = ENVIRON["AWK_SHOW_HOME_IN_NAV"]
|
||||
dinfo = ENVIRON["AWK_DINFO"]
|
||||
n_dlines = split(dinfo, dlines, "\n")
|
||||
for (i = 1; i <= n_dlines; i++) {
|
||||
if (split(dlines[i], dparts, "|") == 3) {
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
BEGIN { in_code = 0 }
|
||||
/^ | / {
|
||||
if (!in_code) { print "<pre><code>"; in_code = 1 }
|
||||
sub(/^ | /, "", $0)
|
||||
gsub(/&/, "\\&"); gsub(/</, "\\<"); gsub(/>/, "\\>")
|
||||
print; next
|
||||
BEGIN { in_code = 0; in_html_pre = 0 }
|
||||
{
|
||||
if ($0 ~ /<pre>/) in_html_pre = 1
|
||||
if ($0 ~ /<\/pre>/) { in_html_pre = 0; if (in_code) { print "</code></pre>"; in_code = 0 }; print; next }
|
||||
|
||||
if (!in_html_pre && $0 ~ /^(\t| )/) {
|
||||
if (!in_code) { printf "%s", "<pre><code>"; in_code = 1 }
|
||||
sub(/^(\t| )/, "", $0)
|
||||
gsub(/&/, "\\&"); gsub(/</, "\\<"); gsub(/>/, "\\>")
|
||||
print
|
||||
next
|
||||
}
|
||||
|
||||
if (in_code) {
|
||||
print "</code></pre>"
|
||||
in_code = 0
|
||||
}
|
||||
print
|
||||
}
|
||||
{ if (in_code) { print "</code></pre>"; in_code = 0 } print }
|
||||
END { if (in_code) print "</code></pre>" }
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
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 {
|
||||
current_url = ENVIRON["AWK_CURRENT_URL"]
|
||||
nav = ENVIRON["AWK_NAV"]
|
||||
title = ENVIRON["AWK_TITLE"]
|
||||
footer = ENVIRON["AWK_FOOTER"]
|
||||
style_path = ENVIRON["AWK_STYLE_PATH"]
|
||||
head_extra = ENVIRON["AWK_HEAD_EXTRA"]
|
||||
header_brand = ENVIRON["AWK_HEADER_BRAND"]
|
||||
if (current_url != "") {
|
||||
nav = replace_all(nav, "href=\"" current_url "\"", "href=\"" current_url "\" class=\"current-page\"")
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
BEGIN { done = 0 }
|
||||
BEGIN {
|
||||
new_title = ENVIRON["AWK_NEW_TITLE"]
|
||||
done = 0
|
||||
}
|
||||
/^title[[:space:]]*=/ {
|
||||
print "title = \"" new_title "\""
|
||||
done = 1
|
||||
|
||||
21
icon.svg
Normal file
21
icon.svg
Normal file
@@ -0,0 +1,21 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="bg-grad" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#4a3b69"/>
|
||||
<stop offset="100%" stop-color="#352654"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="512" height="512" rx="80" ry="80" fill="url(#bg-grad)"/>
|
||||
<text
|
||||
x="256"
|
||||
y="296"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="central"
|
||||
font-family="Georgia, 'Times New Roman', Times, serif"
|
||||
font-size="220"
|
||||
font-weight="bold"
|
||||
font-style="italic"
|
||||
fill="#debfff"
|
||||
letter-spacing="-8"
|
||||
>kewt</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 639 B |
70
kewt.sh
70
kewt.sh
@@ -13,6 +13,7 @@ Usage: $invoked_as [--from <src>] [--to <out>]
|
||||
$invoked_as --new [title]
|
||||
$invoked_as --update [dir]
|
||||
$invoked_as --post
|
||||
$invoked_as --version
|
||||
$invoked_as --help
|
||||
|
||||
Options:
|
||||
@@ -20,6 +21,7 @@ Options:
|
||||
--new [title] Create a new site directory (default: site)
|
||||
--update [dir] Update site.conf and template.html with latest defaults (defaults to current directory)
|
||||
--post Create a new empty post file in the configured posts_dir with current date and time as name
|
||||
--version Show version information.
|
||||
--from <src> Source directory (default: site)
|
||||
--to <out> Output directory (default: out)
|
||||
EOF
|
||||
@@ -67,6 +69,7 @@ EOF
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{{TITLE}}</title>
|
||||
|
||||
<link rel="stylesheet" href="{{CSS}}" type="text/css" />
|
||||
@@ -102,7 +105,7 @@ create_new_site() {
|
||||
printf "# _kewt_ website\n" > "$new_dir/index.md"
|
||||
|
||||
if [ -n "$new_title" ]; then
|
||||
awk -v new_title="$new_title" -f "$awk_dir/update_site_conf.awk" "$new_dir/site.conf" > "$new_dir/site.conf.tmp" && mv "$new_dir/site.conf.tmp" "$new_dir/site.conf"
|
||||
AWK_NEW_TITLE="$new_title" awk -f "$awk_dir/update_site_conf.awk" "$new_dir/site.conf" > "$new_dir/site.conf.tmp" && mv "$new_dir/site.conf.tmp" "$new_dir/site.conf"
|
||||
fi
|
||||
|
||||
echo "Created new site at '$new_dir'."
|
||||
@@ -119,7 +122,7 @@ create_new_post() {
|
||||
|
||||
mkdir -p "$target_dir"
|
||||
|
||||
base_filename="$(date +%Y-%m-%d-%H:%M)"
|
||||
base_filename="$(date +%Y-%m-%d-%H-%M)"
|
||||
filename="${base_filename}.md"
|
||||
file_path="$target_dir/$filename"
|
||||
|
||||
@@ -205,6 +208,7 @@ CONFEOF
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{{TITLE}}</title>
|
||||
|
||||
<link rel="stylesheet" href="{{CSS}}" type="text/css" />
|
||||
@@ -259,6 +263,10 @@ while [ $# -gt 0 ]; do
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--version|-v)
|
||||
echo "kewt version git"
|
||||
exit 0
|
||||
;;
|
||||
--post)
|
||||
post_mode="true"
|
||||
;;
|
||||
@@ -301,7 +309,13 @@ done
|
||||
|
||||
ensure_root_defaults
|
||||
|
||||
[ -z "$src" ] && src="site"
|
||||
if [ -z "$src" ]; then
|
||||
if [ "$post_mode" = "true" ] && [ -f "./site.conf" ]; then
|
||||
src="."
|
||||
else
|
||||
src="site"
|
||||
fi
|
||||
fi
|
||||
[ -z "$out" ] && out="out"
|
||||
|
||||
src="${src%/}"
|
||||
@@ -407,12 +421,12 @@ done < "$KEWT_TMPDIR/kewt_preserve"
|
||||
rm -f "$KEWT_TMPDIR/kewt_preserve"
|
||||
|
||||
generate_nav() {
|
||||
dinfo=$(eval "find \"$1\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -print" | sort | awk -v src="$1" -f "$awk_dir/collect_dir_info.awk")
|
||||
dinfo=$(eval "find \"$1\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -print" | sort | AWK_SRC="$1" awk -f "$awk_dir/collect_dir_info.awk")
|
||||
find_cmd="find \"$1\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print"
|
||||
if [ -n "$posts_dir" ] && [ -d "$1/$posts_dir" ]; then
|
||||
find_cmd="$find_cmd && echo \"$1/$posts_dir/index.md\""
|
||||
fi
|
||||
eval "$find_cmd" | sort -u | awk -v src="$1" -v single_file_index="$single_file_index" -v flatten="$flatten" -v order="$order" -v home_name="$home_name" -v show_home_in_nav="$show_home_in_nav" -v dinfo="$dinfo" -f "$awk_dir/generate_sidebar.awk"
|
||||
eval "$find_cmd" | sort -u | AWK_SRC="$1" AWK_SINGLE_FILE_INDEX="$single_file_index" AWK_FLATTEN="$flatten" AWK_ORDER="$order" AWK_HOME_NAME="$home_name" AWK_SHOW_HOME_IN_NAV="$show_home_in_nav" AWK_DINFO="$dinfo" awk -f "$awk_dir/generate_sidebar.awk"
|
||||
}
|
||||
|
||||
title="kewt"
|
||||
@@ -468,7 +482,7 @@ load_config() {
|
||||
|
||||
case "$key" in
|
||||
title) title="$val" ;;
|
||||
style) style="$val" ;;
|
||||
style) style="${val#/}" ;;
|
||||
dir_indexes) dir_indexes="$val" ;;
|
||||
single_file_index) single_file_index="$val" ;;
|
||||
flatten) flatten="$val" ;;
|
||||
@@ -478,19 +492,19 @@ load_config() {
|
||||
nav_links) nav_links="$val" ;;
|
||||
nav_extra) nav_extra="$val" ;;
|
||||
footer) footer="$val" ;;
|
||||
logo) logo="$val" ;;
|
||||
logo) logo="${val#/}" ;;
|
||||
display_logo) display_logo="$val" ;;
|
||||
display_title) display_title="$val" ;;
|
||||
logo_as_favicon) logo_as_favicon="$val" ;;
|
||||
favicon) favicon="$val" ;;
|
||||
favicon) favicon="${val#/}" ;;
|
||||
generate_page_title) generate_page_title="$val" ;;
|
||||
error_page) error_page="$val" ;;
|
||||
error_page) error_page="${val#/}" ;;
|
||||
versioning) versioning="$val" ;;
|
||||
enable_header_links) enable_header_links="$val" ;;
|
||||
base_url) base_url="$val" ;;
|
||||
generate_feed) generate_feed="$val" ;;
|
||||
feed_file) feed_file="$val" ;;
|
||||
posts_dir) posts_dir="$val" ;;
|
||||
feed_file) feed_file="${val#/}" ;;
|
||||
posts_dir) posts_dir="${val#/}" ;;
|
||||
esac
|
||||
done < "$1"
|
||||
}
|
||||
@@ -611,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
|
||||
@@ -692,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_CURRENT_URL="$current_url" AWK_TITLE="$page_title" AWK_NAV="$nav" AWK_FOOTER="$footer" AWK_STYLE_PATH="${style_path}${asset_version}" AWK_HEADER_BRAND="$header_brand" AWK_HEAD_EXTRA="$head_extra" awk -f "$awk_dir/render_template.awk" "$local_template"
|
||||
}
|
||||
|
||||
echo "Building site from '$src' to '$out'..."
|
||||
@@ -713,12 +736,18 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
||||
[ "$dir_indexes" != "true" ] && continue
|
||||
|
||||
if [ ! -f "$dir/index.md" ]; then
|
||||
if [ "$single_file_index" = "true" ]; then
|
||||
is_posts_dir="false"
|
||||
if [ -n "$posts_dir" ] && { [ "$rel_dir" = "$posts_dir" ] || [ "./$rel_dir" = "$posts_dir" ]; }; then
|
||||
is_posts_dir="true"
|
||||
fi
|
||||
if [ "$single_file_index" = "true" ] && [ "$is_posts_dir" = "false" ]; then
|
||||
md_count=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md" | wc -l)
|
||||
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
|
||||
@@ -776,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
|
||||
@@ -800,7 +831,12 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type f -print" | sort | while
|
||||
is_preserved=1
|
||||
fi
|
||||
|
||||
if [ "$single_file_index" = "true" ] && [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ] && [ ! -f "$(dirname "$file")/index.md" ]; then
|
||||
is_posts_dir_2="false"
|
||||
if [ -n "$posts_dir" ] && { [ "$dir_rel" = "$posts_dir" ] || [ "./$dir_rel" = "$posts_dir" ]; }; then
|
||||
is_posts_dir_2="true"
|
||||
fi
|
||||
|
||||
if [ "$single_file_index" = "true" ] && [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ] && [ ! -f "$(dirname "$file")/index.md" ] && [ "$is_posts_dir_2" = "false" ]; then
|
||||
md_count=$(find "$(dirname "$file")" ! -name "$(basename "$(dirname "$file")")" -prune -name "*.md" | wc -l)
|
||||
[ "$md_count" -eq 1 ] && continue
|
||||
fi
|
||||
@@ -819,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
|
||||
|
||||
|
||||
16
packaging/AUR/.SRCINFO.git
Normal file
16
packaging/AUR/.SRCINFO.git
Normal file
@@ -0,0 +1,16 @@
|
||||
pkgbase = kewt-git
|
||||
pkgdesc = A minimalist, 100% POSIX, static site generator inspired by werc and kew
|
||||
pkgver = r0.0000000
|
||||
pkgrel = 3
|
||||
url = https://kewt.krzak.org
|
||||
arch = any
|
||||
license = ISC
|
||||
makedepends = git
|
||||
depends = sh
|
||||
provides = kewt
|
||||
conflicts = kewt
|
||||
conflicts = kewt-bin
|
||||
source = kewt-git::git+https://git.krzak.org/N0VA/kewt.git
|
||||
sha256sums = SKIP
|
||||
|
||||
pkgname = kewt-git
|
||||
15
packaging/AUR/.SRCINFO.template
Normal file
15
packaging/AUR/.SRCINFO.template
Normal file
@@ -0,0 +1,15 @@
|
||||
pkgbase = kewt-bin
|
||||
pkgdesc = A minimalist, 100% POSIX, static site generator inspired by werc and kew
|
||||
pkgver = VERSION_PLACEHOLDER
|
||||
pkgrel = 2
|
||||
url = https://kewt.krzak.org
|
||||
arch = any
|
||||
license = ISC
|
||||
depends = sh
|
||||
provides = kewt
|
||||
conflicts = kewt
|
||||
conflicts = kewt-git
|
||||
source = kewt-bin-VERSION_PLACEHOLDER.sh::https://git.krzak.org/N0VA/kewt/releases/download/vVERSION_PLACEHOLDER/kewt
|
||||
sha256sums = SHA256SUM_PLACEHOLDER
|
||||
|
||||
pkgname = kewt-bin
|
||||
@@ -1,16 +1,16 @@
|
||||
# Maintainer: n0va <n0va@krzak.org>
|
||||
pkgname=kewt-git
|
||||
pkgver=r0.0000000
|
||||
pkgrel=1
|
||||
pkgrel=2
|
||||
pkgdesc="A minimalist, 100% POSIX, static site generator inspired by werc and kew"
|
||||
arch=('any')
|
||||
url="https://git.krzak.org/N0VA/kewt"
|
||||
license=('MIT')
|
||||
url="https://kewt.krzak.org"
|
||||
license=('ISC')
|
||||
makedepends=('git')
|
||||
depends=('sh')
|
||||
provides=('kewt')
|
||||
conflicts=('kewt' 'kewt-bin')
|
||||
source=("${pkgname}::git+${url}.git")
|
||||
source=("${pkgname}::git+https://git.krzak.org/N0VA/kewt.git")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
|
||||
@@ -4,12 +4,12 @@ pkgver=VERSION_PLACEHOLDER
|
||||
pkgrel=1
|
||||
pkgdesc="A minimalist, 100% POSIX, static site generator inspired by werc and kew"
|
||||
arch=('any')
|
||||
url="https://git.krzak.org/N0VA/kewt"
|
||||
license=('MIT')
|
||||
url="https://kewt.krzak.org"
|
||||
license=('ISC')
|
||||
depends=('sh')
|
||||
provides=('kewt')
|
||||
conflicts=('kewt' 'kewt-git')
|
||||
source=("${pkgname}-${pkgver}.sh::${url}/releases/download/v${pkgver}/kewt")
|
||||
source=("${pkgname}-${pkgver}.sh::https://git.krzak.org/N0VA/kewt/releases/download/v${pkgver}/kewt")
|
||||
sha256sums=('SHA256SUM_PLACEHOLDER')
|
||||
|
||||
build() {
|
||||
|
||||
BIN
site/favicon.ico
Normal file
BIN
site/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
@@ -1,8 +1,12 @@
|
||||
# _kewt_
|
||||
### Pronounced "cute"
|
||||
|
||||
***
|
||||
|
||||
# [Go to the repo](https://git.krzak.org/N0VA/kewt)
|
||||
|
||||
***
|
||||
|
||||
_kewt_ is a minimalist ssg inspired by _[werc](http://werc.cat-v.org/)_ and _[kew](https://github.com/uint23/kew)_
|
||||
|
||||
It's meant to be a static site generator, like _[kew](https://github.com/uint23/kew)_ but use only default (POSIX) tooling, like _[werc](http://werc.cat-v.org/)_ (and definitely unlike _[kew](https://github.com/uint23/kew)_)
|
||||
@@ -18,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 `\![]`
|
||||
|
||||
@@ -39,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 <src> --to <out>
|
||||
@@ -75,6 +85,7 @@ base_url = ""
|
||||
generate_feed = false
|
||||
feed_file = "rss.xml"
|
||||
posts_dir = ""
|
||||
enable_header_links = true
|
||||
```
|
||||
|
||||
- `title` site title
|
||||
@@ -100,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
|
||||
|
||||
@@ -119,7 +131,7 @@ posts_dir = ""
|
||||
|
||||
## Credits
|
||||
|
||||
- Default css style and html template based on _[kew](https://github.com/uint23/kew)_ by [uint23](https://github.com/uint23)
|
||||
- _kew_ css style adapted from _[kew](https://github.com/uint23/kew)_ by [uint23](https://github.com/uint23)
|
||||
|
||||
>[!WARNING]
|
||||
>Most of this was coded at night, while sleepy and a bit sick, and after walking for about 4 hours around a forest, so...
|
||||
>The base that all of this is built upon was coded at night, while sleepy and a bit sick, and after walking for about 4 hours around a forest, so...
|
||||
|
||||
@@ -7,8 +7,8 @@ footer = "<a href=\"https://kewt.krzak.org\"><img src=\"/button.gif\" /></a>"
|
||||
logo = ""
|
||||
display_logo = false
|
||||
display_title = true
|
||||
logo_as_favicon = true
|
||||
favicon = ""
|
||||
logo_as_favicon = false
|
||||
favicon = "favicon.ico"
|
||||
order = ""
|
||||
home_name = "Home"
|
||||
show_home_in_nav = true
|
||||
@@ -16,6 +16,6 @@ nav_links = ""
|
||||
nav_extra = ""
|
||||
generate_page_title = true
|
||||
error_page = "not_found.html"
|
||||
versioning = false
|
||||
versioning = true
|
||||
enable_header_links = true
|
||||
base_url = "https://kewt.krzak.org"
|
||||
|
||||
106
styles/kewt.css
106
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;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,13 @@ exit $?
|
||||
#==PAYLOAD==
|
||||
EOF
|
||||
|
||||
tar -cz -C "$REPO_ROOT" kewt.sh markdown.sh awk styles >> "$OUT_FILE"
|
||||
VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "standalone")
|
||||
tmpbuild=$(mktemp -d)
|
||||
cp -r "$REPO_ROOT/kewt.sh" "$REPO_ROOT/markdown.sh" "$REPO_ROOT/awk" "$REPO_ROOT/styles" "$tmpbuild/"
|
||||
sed -e "s/kewt version git/kewt version $VERSION/" "$tmpbuild/kewt.sh" > "$tmpbuild/kewt.sh.tmp" && mv "$tmpbuild/kewt.sh.tmp" "$tmpbuild/kewt.sh"
|
||||
chmod +x "$tmpbuild/kewt.sh" "$tmpbuild/markdown.sh"
|
||||
tar -cz -C "$tmpbuild" kewt.sh markdown.sh awk styles >> "$OUT_FILE"
|
||||
rm -rf "$tmpbuild"
|
||||
|
||||
chmod +x "$OUT_FILE"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user