Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 78eac182dc | |||
| b7382a20ab | |||
| d8cf07ee2a | |||
| 76e2ae0117 | |||
| 2e331b5d9a | |||
| 9f5d1089a2 | |||
| 9ccba8fd4e | |||
| 95679abd85 | |||
| 8b1e793510 | |||
| 19f96553d9 | |||
| 1a7525a857 | |||
| e7d90d18e8 | |||
| 4019d2721d | |||
| b58604a4cf | |||
| 99e805b180 | |||
| 62075dea4a | |||
| 7afd041e53 |
@@ -32,12 +32,24 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
TAG="${GITHUB_REF#refs/tags/}"
|
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
|
# Create the release on GitHub
|
||||||
curl -sL -X POST \
|
curl -sL -X POST \
|
||||||
-H "Authorization: token ${{ secrets.GH_RELEASE_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.GH_RELEASE_TOKEN }}" \
|
||||||
-H "Accept: application/vnd.github+json" \
|
-H "Accept: application/vnd.github+json" \
|
||||||
"https://api.github.com/repos/n0va-bot/kewt/releases" \
|
"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
|
# Get the release ID
|
||||||
RELEASE_ID=$(curl -sL \
|
RELEASE_ID=$(curl -sL \
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
|||||||
out/
|
out/
|
||||||
kewt
|
kewt
|
||||||
|
site.conf
|
||||||
|
template.html
|
||||||
|
|||||||
35
LICENSE
Normal file
35
LICENSE
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright 2026 N0\A
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||||
|
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||||
|
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||||
|
OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
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
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
93
README.md
93
README.md
@@ -1,30 +1,19 @@
|
|||||||
# _kewt_
|
# _kewt_
|
||||||
### Pronounced "cute"
|
### Pronounced "cute"
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
# [Go to the website](https://kewt.krzak.org)
|
# [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)_
|
_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
|
## Quick Install
|
||||||
|
|
||||||
- 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)
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -L -o kewt https://git.krzak.org/N0VA/kewt/releases/latest/download/kewt
|
curl -L -o kewt https://git.krzak.org/N0VA/kewt/releases/download/latest/kewt
|
||||||
chmod +x kewt
|
chmod +x kewt
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -33,74 +22,6 @@ 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-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
|
- [kewt-git](https://aur.archlinux.org/packages/kewt-git) — built from the latest git source
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./kewt.sh --help
|
|
||||||
./kewt.sh --new [title]
|
|
||||||
./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`.
|
|
||||||
|
|
||||||
## 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 = ""
|
|
||||||
```
|
|
||||||
|
|
||||||
- `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)
|
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
## Credits
|
## 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...
|
|
||||||
@@ -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 ~ /^```/) {
|
if (!in_fence && $0 ~ /^```/) {
|
||||||
in_fence = 1
|
in_fence = 1
|
||||||
first_line = 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
|
next
|
||||||
}
|
}
|
||||||
if (in_fence && $0 ~ /^```[[:space:]]*$/) {
|
if (in_fence && $0 ~ /^```[[:space:]]*$/) {
|
||||||
|
if (first_line) printf "%s", "<pre>" code_tag
|
||||||
print "</code></pre>"
|
print "</code></pre>"
|
||||||
in_fence = 0
|
in_fence = 0
|
||||||
next
|
next
|
||||||
@@ -14,8 +23,12 @@ BEGIN { in_fence = 0; first_line = 0 }
|
|||||||
gsub(/&/, "\\&"); gsub(/</, "\\<"); gsub(/>/, "\\>")
|
gsub(/&/, "\\&"); gsub(/</, "\\<"); gsub(/>/, "\\>")
|
||||||
if (first_line) {
|
if (first_line) {
|
||||||
first_line = 0
|
first_line = 0
|
||||||
if ($0 == "") next
|
printf "%s", "<pre>" code_tag
|
||||||
print "<pre><code>" $0
|
if ($0 == "") {
|
||||||
|
print ""
|
||||||
|
next
|
||||||
|
}
|
||||||
|
print $0
|
||||||
} else {
|
} else {
|
||||||
print
|
print
|
||||||
}
|
}
|
||||||
@@ -24,5 +37,8 @@ BEGIN { in_fence = 0; first_line = 0 }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
END {
|
END {
|
||||||
if (in_fence) print "</code></pre>"
|
if (in_fence) {
|
||||||
|
if (first_line) printf "%s", "<pre>" code_tag
|
||||||
|
print "</code></pre>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,18 +8,21 @@ function strip_markdown(s) {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
function print_header(line) {
|
function print_header(line) {
|
||||||
if (line ~ /^# /) {
|
tag = ""
|
||||||
sub(/^# /, "", line); print "<h1 id=\"" strip_markdown(line) "\">" line "</h1>"
|
if (line ~ /^# /) { tag = "h1"; sub(/^# /, "", line) }
|
||||||
} else if (line ~ /^## /) {
|
else if (line ~ /^## /) { tag = "h2"; sub(/^## /, "", line) }
|
||||||
sub(/^## /, "", line); print "<h2 id=\"" strip_markdown(line) "\">" line "</h2>"
|
else if (line ~ /^### /) { tag = "h3"; sub(/^### /, "", line) }
|
||||||
} else if (line ~ /^### /) {
|
else if (line ~ /^#### /) { tag = "h4"; sub(/^#### /, "", line) }
|
||||||
sub(/^### /, "", line); print "<h3 id=\"" strip_markdown(line) "\">" line "</h3>"
|
else if (line ~ /^##### /) { tag = "h5"; sub(/^##### /, "", line) }
|
||||||
} else if (line ~ /^#### /) {
|
else if (line ~ /^###### /) { tag = "h6"; sub(/^###### /, "", line) }
|
||||||
sub(/^#### /, "", line); print "<h4 id=\"" strip_markdown(line) "\">" line "</h4>"
|
|
||||||
} else if (line ~ /^##### /) {
|
if (tag != "") {
|
||||||
sub(/^##### /, "", line); print "<h5 id=\"" strip_markdown(line) "\">" line "</h5>"
|
id = strip_markdown(line)
|
||||||
} else if (line ~ /^###### /) {
|
if (enable_header_links == "true") {
|
||||||
sub(/^###### /, "", line); print "<h6 id=\"" strip_markdown(line) "\">" line "</h6>"
|
print "<" tag " id=\"" id "\"><a href=\"#" id "\" class=\"header-anchor\">" line "</a></" tag ">"
|
||||||
|
} else {
|
||||||
|
print "<" tag " id=\"" id "\">" line "</" tag ">"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
print line
|
print line
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
BEGIN { in_code = 0 }
|
BEGIN { in_code = 0; in_html_pre = 0 }
|
||||||
/^ | / {
|
{
|
||||||
if (!in_code) { print "<pre><code>"; in_code = 1 }
|
if ($0 ~ /<pre>/) in_html_pre = 1
|
||||||
sub(/^ | /, "", $0)
|
if ($0 ~ /<\/pre>/) { in_html_pre = 0; if (in_code) { print "</code></pre>"; in_code = 0 }; print; next }
|
||||||
gsub(/&/, "\\&"); gsub(/</, "\\<"); gsub(/>/, "\\>")
|
|
||||||
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>" }
|
END { if (in_code) print "</code></pre>" }
|
||||||
|
|||||||
@@ -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)
|
token_len = length(token)
|
||||||
|
res = ""
|
||||||
while ((pos = index(text, token)) > 0) {
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
425
kewt.sh
425
kewt.sh
@@ -11,13 +11,19 @@ usage() {
|
|||||||
Usage: $invoked_as [--from <src>] [--to <out>]
|
Usage: $invoked_as [--from <src>] [--to <out>]
|
||||||
$invoked_as [src] [out]
|
$invoked_as [src] [out]
|
||||||
$invoked_as --new [title]
|
$invoked_as --new [title]
|
||||||
|
$invoked_as --update [dir]
|
||||||
|
$invoked_as --post
|
||||||
|
$invoked_as --version
|
||||||
$invoked_as --help
|
$invoked_as --help
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--help Show this help message.
|
--help Show this help message.
|
||||||
--new [title] Create a new site directory (default: site)
|
--new [title] Create a new site directory (default: site)
|
||||||
--from <src> Source directory (default: site)
|
--update [dir] Update site.conf and template.html with latest defaults (defaults to current directory)
|
||||||
--to <out> Output directory (default: out)
|
--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
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,12 +46,20 @@ home_name = "Home"
|
|||||||
show_home_in_nav = true
|
show_home_in_nav = true
|
||||||
nav_links = ""
|
nav_links = ""
|
||||||
nav_extra = ""
|
nav_extra = ""
|
||||||
footer = "made with <a href="https://kewt.krzak.org">kewt</a>"
|
footer = "made with <a href=\"https://kewt.krzak.org\">kewt</a>"
|
||||||
logo = ""
|
logo = ""
|
||||||
display_logo = false
|
display_logo = false
|
||||||
display_title = true
|
display_title = true
|
||||||
logo_as_favicon = true
|
logo_as_favicon = true
|
||||||
favicon = ""
|
favicon = ""
|
||||||
|
generate_page_title = true
|
||||||
|
error_page = "not_found.html"
|
||||||
|
versioning = false
|
||||||
|
enable_header_links = true
|
||||||
|
base_url = ""
|
||||||
|
generate_feed = false
|
||||||
|
feed_file = "rss.xml"
|
||||||
|
posts_dir = ""
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -55,6 +69,7 @@ EOF
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>{{TITLE}}</title>
|
<title>{{TITLE}}</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{CSS}}" type="text/css" />
|
<link rel="stylesheet" href="{{CSS}}" type="text/css" />
|
||||||
@@ -97,12 +112,142 @@ create_new_site() {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_new_post() {
|
||||||
|
post_src_dir="$1"
|
||||||
|
|
||||||
|
target_dir="$post_src_dir"
|
||||||
|
if [ -n "$posts_dir" ]; then
|
||||||
|
target_dir="$post_src_dir/$posts_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$target_dir"
|
||||||
|
|
||||||
|
base_filename="$(date +%Y-%m-%d-%H-%M)"
|
||||||
|
filename="${base_filename}.md"
|
||||||
|
file_path="$target_dir/$filename"
|
||||||
|
|
||||||
|
counter=1
|
||||||
|
while [ -e "$file_path" ]; do
|
||||||
|
filename="${base_filename}_${counter}.md"
|
||||||
|
file_path="$target_dir/$filename"
|
||||||
|
counter=$((counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
touch "$file_path"
|
||||||
|
|
||||||
|
echo "Created new post at '$file_path'."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
update_site() {
|
||||||
|
update_dir="${1:-.}"
|
||||||
|
[ -d "$update_dir" ] || die "Directory '$update_dir' does not exist."
|
||||||
|
|
||||||
|
target_conf="$update_dir/site.conf"
|
||||||
|
target_tmpl="$update_dir/template.html"
|
||||||
|
|
||||||
|
# Generate default site.conf
|
||||||
|
default_conf="$KEWT_TMPDIR/default_site.conf"
|
||||||
|
cat > "$default_conf" <<'CONFEOF'
|
||||||
|
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
|
||||||
|
enable_header_links = true
|
||||||
|
base_url = ""
|
||||||
|
generate_feed = false
|
||||||
|
feed_file = "rss.xml"
|
||||||
|
posts_dir = ""
|
||||||
|
CONFEOF
|
||||||
|
|
||||||
|
# Update site.conf
|
||||||
|
if [ ! -f "$target_conf" ]; then
|
||||||
|
echo "No site.conf found in '$update_dir'; nothing to update."
|
||||||
|
else
|
||||||
|
added=0
|
||||||
|
while IFS= read -r line; do
|
||||||
|
case "$line" in
|
||||||
|
''|'#'*) continue ;;
|
||||||
|
*=*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
key=$(printf '%s' "${line%%=*}" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
|
if ! grep -q "^[[:space:]]*${key}[[:space:]]*=" "$target_conf"; then
|
||||||
|
printf '%s\n' "$line" >> "$target_conf"
|
||||||
|
echo " Added: $key"
|
||||||
|
added=$((added + 1))
|
||||||
|
fi
|
||||||
|
done < "$default_conf"
|
||||||
|
if [ "$added" -eq 0 ]; then
|
||||||
|
echo "site.conf is already up to date."
|
||||||
|
else
|
||||||
|
echo "Added $added new key(s) to '$target_conf'."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update template.html
|
||||||
|
if [ -f "$target_tmpl" ]; then
|
||||||
|
default_tmpl="$KEWT_TMPDIR/default_template.html"
|
||||||
|
cat > "$default_tmpl" <<'TMPLEOF'
|
||||||
|
<!doctype html>
|
||||||
|
<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" />
|
||||||
|
{{HEAD_EXTRA}}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>{{HEADER_BRAND}}</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav id="side-bar">{{NAV}}</nav>
|
||||||
|
|
||||||
|
<article>{{CONTENT}}</article>
|
||||||
|
<footer>{{FOOTER}}</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
TMPLEOF
|
||||||
|
if cmp -s "$default_tmpl" "$target_tmpl" 2>/dev/null; then
|
||||||
|
echo "template.html is already up to date."
|
||||||
|
else
|
||||||
|
cp "$default_tmpl" "${target_tmpl}.default"
|
||||||
|
echo "template.html has local changes; saved latest default as '${target_tmpl}.default'."
|
||||||
|
echo ""
|
||||||
|
diff "$target_tmpl" "${target_tmpl}.default" || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
src=""
|
src=""
|
||||||
out=""
|
out=""
|
||||||
new_mode="false"
|
new_mode="false"
|
||||||
new_title=""
|
new_title=""
|
||||||
|
post_mode="false"
|
||||||
|
post_title=""
|
||||||
positional_count=0
|
positional_count=0
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
@@ -118,6 +263,21 @@ while [ $# -gt 0 ]; do
|
|||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
--version|-v)
|
||||||
|
echo "kewt version git"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--post)
|
||||||
|
post_mode="true"
|
||||||
|
;;
|
||||||
|
--update)
|
||||||
|
update_dir="."
|
||||||
|
if [ $# -gt 1 ] && [ "${2#-}" = "$2" ]; then
|
||||||
|
update_dir="$2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
update_site "$update_dir"
|
||||||
|
;;
|
||||||
--from)
|
--from)
|
||||||
[ $# -lt 2 ] && die "--from requires a value."
|
[ $# -lt 2 ] && die "--from requires a value."
|
||||||
src="$2"
|
src="$2"
|
||||||
@@ -149,7 +309,13 @@ done
|
|||||||
|
|
||||||
ensure_root_defaults
|
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"
|
[ -z "$out" ] && out="out"
|
||||||
|
|
||||||
src="${src%/}"
|
src="${src%/}"
|
||||||
@@ -256,7 +422,11 @@ rm -f "$KEWT_TMPDIR/kewt_preserve"
|
|||||||
|
|
||||||
generate_nav() {
|
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 -v src="$1" -f "$awk_dir/collect_dir_info.awk")
|
||||||
eval "find \"$1\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print" | sort | 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"
|
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"
|
||||||
}
|
}
|
||||||
|
|
||||||
title="kewt"
|
title="kewt"
|
||||||
@@ -276,6 +446,14 @@ display_logo="false"
|
|||||||
display_title="true"
|
display_title="true"
|
||||||
logo_as_favicon="true"
|
logo_as_favicon="true"
|
||||||
favicon=""
|
favicon=""
|
||||||
|
generate_page_title="true"
|
||||||
|
error_page="not_found.html"
|
||||||
|
versioning="false"
|
||||||
|
enable_header_links="true"
|
||||||
|
base_url=""
|
||||||
|
generate_feed="false"
|
||||||
|
feed_file="rss.xml"
|
||||||
|
posts_dir=""
|
||||||
|
|
||||||
load_config() {
|
load_config() {
|
||||||
[ -f "$1" ] || return
|
[ -f "$1" ] || return
|
||||||
@@ -292,8 +470,14 @@ load_config() {
|
|||||||
key=$(printf '%s' "$key" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
key=$(printf '%s' "$key" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
val=$(printf '%s' "$val" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
val=$(printf '%s' "$val" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
case "$val" in
|
case "$val" in
|
||||||
\"*\") val=${val#\"}; val=${val%\"} ;;
|
\"*\")
|
||||||
\'*\') val=${val#\'}; val=${val%\'} ;;
|
val=${val#\"}; val=${val%\"}
|
||||||
|
val=$(printf '%s' "$val" | sed 's/\\"/\"/g; s/\\\\/\\/g')
|
||||||
|
;;
|
||||||
|
\'*\')
|
||||||
|
val=${val#\'}; val=${val%\'}
|
||||||
|
val=$(printf '%s' "$val" | sed "s/\\\\'/'/g; s/\\\\/\\/g")
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "$key" in
|
case "$key" in
|
||||||
@@ -313,6 +497,14 @@ load_config() {
|
|||||||
display_title) display_title="$val" ;;
|
display_title) display_title="$val" ;;
|
||||||
logo_as_favicon) logo_as_favicon="$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" ;;
|
||||||
|
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" ;;
|
||||||
esac
|
esac
|
||||||
done < "$1"
|
done < "$1"
|
||||||
}
|
}
|
||||||
@@ -320,6 +512,17 @@ load_config() {
|
|||||||
load_config "./site.conf"
|
load_config "./site.conf"
|
||||||
load_config "$src/site.conf"
|
load_config "$src/site.conf"
|
||||||
|
|
||||||
|
if [ -n "$posts_dir" ]; then
|
||||||
|
HIDE_ARGS="$HIDE_ARGS -o -path '$src/$posts_dir/*'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "$post_mode" = "true" ] && create_new_post "$src"
|
||||||
|
|
||||||
|
asset_version=""
|
||||||
|
if [ "$versioning" = "true" ]; then
|
||||||
|
asset_version="?v=$(date +%s)"
|
||||||
|
fi
|
||||||
|
|
||||||
escape_html_text() {
|
escape_html_text() {
|
||||||
printf '%s' "$1" | sed \
|
printf '%s' "$1" | sed \
|
||||||
-e 's/&/\&/g' \
|
-e 's/&/\&/g' \
|
||||||
@@ -421,6 +624,30 @@ copy_style_with_resolved_vars() {
|
|||||||
|
|
||||||
render_markdown() {
|
render_markdown() {
|
||||||
file="$1"
|
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
|
||||||
|
dir_of_file=$(dirname "$file")
|
||||||
|
rel_dir_of_file="${dir_of_file#"$src"}"
|
||||||
|
rel_dir_of_file="${rel_dir_of_file#/}"
|
||||||
|
if [ "$rel_dir_of_file" = "$posts_dir" ]; then
|
||||||
|
temp_post_with_backlink="$KEWT_TMPDIR/post_with_backlink.md"
|
||||||
|
printf "[< Back](index.html)\n\n" > "$temp_post_with_backlink"
|
||||||
|
cat "$file" >> "$temp_post_with_backlink"
|
||||||
|
content_file="$temp_post_with_backlink"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
local_template=$(find_closest "template.html" "$(dirname "$file")")
|
local_template=$(find_closest "template.html" "$(dirname "$file")")
|
||||||
[ -z "$local_template" ] && local_template="$template"
|
[ -z "$local_template" ] && local_template="$template"
|
||||||
|
|
||||||
@@ -469,7 +696,26 @@ render_markdown() {
|
|||||||
head_extra="<link rel=\"icon\" href=\"$favicon_src\" />"
|
head_extra="<link rel=\"icon\" href=\"$favicon_src\" />"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MARKDOWN_SITE_ROOT="$src" MARKDOWN_FALLBACK_FILE="$script_dir/styles/$style.css" sh "$script_dir/markdown.sh" "$file" | awk -v title="$title" -v nav="$nav" -v footer="$footer" -v style_path="$style_path" -v header_brand="$header_brand" -v head_extra="$head_extra" -f "$awk_dir/render_template.awk" "$local_template"
|
page_title="$title"
|
||||||
|
if [ "$generate_page_title" = "true" ] && [ -n "$file" ] && [ -f "$file" ]; then
|
||||||
|
if [ "$is_home" = "true" ] && [ -n "$home_name" ]; then
|
||||||
|
page_title="$home_name - $title"
|
||||||
|
else
|
||||||
|
first_heading=$(grep -m 1 '^# ' "$file" | sed 's/^# *//; s/ *$//')
|
||||||
|
if [ -n "$first_heading" ]; then
|
||||||
|
first_heading=$(echo "$first_heading" | sed -e 's/\[//g' -e 's/\]//g' -e 's/!//g' -e 's/\*//g' -e 's/_//g' -e 's/`//g' -e 's/([^)]*)//g' | sed 's/\\//g')
|
||||||
|
page_title="$first_heading - $title"
|
||||||
|
else
|
||||||
|
basename_no_ext=$(basename "$file" .md)
|
||||||
|
if [ "$basename_no_ext" != "index" ] && [ "$basename_no_ext" != "404_gen" ]; then
|
||||||
|
cap_basename=$(echo "$basename_no_ext" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')
|
||||||
|
page_title="$cap_basename - $title"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
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 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'..."
|
echo "Building site from '$src' to '$out'..."
|
||||||
@@ -490,11 +736,18 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
|||||||
[ "$dir_indexes" != "true" ] && continue
|
[ "$dir_indexes" != "true" ] && continue
|
||||||
|
|
||||||
if [ ! -f "$dir/index.md" ]; then
|
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)
|
md_count=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md" | wc -l)
|
||||||
if [ "$md_count" -eq 1 ]; then
|
if [ "$md_count" -eq 1 ]; then
|
||||||
md_file=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md")
|
md_file=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md")
|
||||||
render_markdown "$md_file" > "$out_dir/index.html"
|
is_home="false"; [ "$dir" = "$src" ] && is_home="true"
|
||||||
|
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
|
continue
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -504,7 +757,14 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
|||||||
[ -z "$display_dir" ] && display_dir="/"
|
[ -z "$display_dir" ] && display_dir="/"
|
||||||
echo "# Index of $display_dir" > "$temp_index"
|
echo "# Index of $display_dir" > "$temp_index"
|
||||||
echo "" >> "$temp_index"
|
echo "" >> "$temp_index"
|
||||||
find "$dir" ! -name "$(basename "$dir")" -prune ! -name ".*" -print | sort | while read -r entry; do
|
|
||||||
|
sort_args=""
|
||||||
|
# If this is the posts dir reverse
|
||||||
|
if [ "$rel_dir" = "$posts_dir" ] || [ "./$rel_dir" = "$posts_dir" ]; then
|
||||||
|
sort_args="-r"
|
||||||
|
fi
|
||||||
|
|
||||||
|
find "$dir" ! -name "$(basename "$dir")" -prune ! -name ".*" -print | LC_ALL=C sort $sort_args | while read -r entry; do
|
||||||
name="${entry##*/}"
|
name="${entry##*/}"
|
||||||
case "$name" in
|
case "$name" in
|
||||||
template.html|site.conf|style.css|index.md) continue ;;
|
template.html|site.conf|style.css|index.md) continue ;;
|
||||||
@@ -512,12 +772,42 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
|||||||
if [ -d "$entry" ]; then
|
if [ -d "$entry" ]; then
|
||||||
echo "- [${name}/](${name}/index.html)" >> "$temp_index"
|
echo "- [${name}/](${name}/index.html)" >> "$temp_index"
|
||||||
elif [ "${entry%.md}" != "$entry" ]; then
|
elif [ "${entry%.md}" != "$entry" ]; then
|
||||||
echo "- [${name%.md}](${name%.md}.html)" >> "$temp_index"
|
label="${name%.md}"
|
||||||
|
|
||||||
|
# Try to get first heading
|
||||||
|
post_h=$(grep -m 1 '^# ' "$entry" | sed 's/^# *//')
|
||||||
|
if [ -n "$post_h" ]; then
|
||||||
|
post_h=$(echo "$post_h" | sed -e 's/\[//g' -e 's/\]//g' -e 's/!//g' -e 's/\*//g' -e 's/_//g' -e 's/`//g' -e 's/([^)]*)//g' | sed 's/\\//g')
|
||||||
|
|
||||||
|
if [ "$rel_dir" = "$posts_dir" ] || [ "./$rel_dir" = "$posts_dir" ]; then
|
||||||
|
# For posts add date and time
|
||||||
|
p_date=$(echo "${name%.md}" | sed 's/^\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/')
|
||||||
|
p_time="00:00"
|
||||||
|
if echo "${name%.md}" | grep -q '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}'; then
|
||||||
|
p_time=$(echo "${name%.md}" | sed 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-\([0-9]\{2\}[:\-][0-9]\{2\}\).*/\1/' | tr '-' ':')
|
||||||
|
fi
|
||||||
|
label="$post_h - $p_date $p_time"
|
||||||
|
else
|
||||||
|
label="$post_h"
|
||||||
|
fi
|
||||||
|
elif [ "$rel_dir" = "$posts_dir" ] || [ "./$rel_dir" = "$posts_dir" ]; then
|
||||||
|
# No heading and date and time for posts
|
||||||
|
p_date=$(echo "${name%.md}" | sed 's/^\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/')
|
||||||
|
p_time="00:00"
|
||||||
|
if echo "${name%.md}" | grep -q '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}'; then
|
||||||
|
p_time=$(echo "${name%.md}" | sed 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-\([0-9]\{2\}[:\-][0-9]\{2\}\).*/\1/' | tr '-' ':')
|
||||||
|
fi
|
||||||
|
label="$p_date $p_time"
|
||||||
|
fi
|
||||||
|
echo "- [$label](${name%.md}.html)" >> "$temp_index"
|
||||||
else
|
else
|
||||||
echo "- [$name]($name)" >> "$temp_index"
|
echo "- [$name]($name)" >> "$temp_index"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
render_markdown "$temp_index" > "$out_dir/index.html"
|
is_home="false"; [ "$dir" = "$src" ] && is_home="true"
|
||||||
|
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"
|
rm "$temp_index"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -541,18 +831,119 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type f -print" | sort | while
|
|||||||
is_preserved=1
|
is_preserved=1
|
||||||
fi
|
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=$(find "$(dirname "$file")" ! -name "$(basename "$(dirname "$file")")" -prune -name "*.md" | wc -l)
|
||||||
[ "$md_count" -eq 1 ] && continue
|
[ "$md_count" -eq 1 ] && continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ]; then
|
if [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ]; then
|
||||||
|
is_home="false"; [ "$file" = "$src/index.md" ] && is_home="true"
|
||||||
out_file="$out/${rel_path%.md}.html"
|
out_file="$out/${rel_path%.md}.html"
|
||||||
render_markdown "$file" > "$out_file"
|
render_markdown "$file" "$is_home" > "$out_file"
|
||||||
else
|
else
|
||||||
cp "$file" "$out/$rel_path"
|
cp "$file" "$out/$rel_path"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -n "$error_page" ] && [ ! -f "$out/$error_page" ]; then
|
||||||
|
temp_404="$KEWT_TMPDIR/404_gen.md"
|
||||||
|
echo "# 404 - Not Found" > "$temp_404"
|
||||||
|
echo "" >> "$temp_404"
|
||||||
|
echo "The requested page could not be found." >> "$temp_404"
|
||||||
|
render_markdown "$temp_404" "false" "/$error_page" > "$out/$error_page"
|
||||||
|
rm -f "$temp_404"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$base_url" ]; then
|
||||||
|
sitemap_file="$out/sitemap.xml"
|
||||||
|
base_url="${base_url%/}"
|
||||||
|
today=$(date +%Y-%m-%d)
|
||||||
|
|
||||||
|
printf '<?xml version="1.0" encoding="UTF-8"?>\n' > "$sitemap_file"
|
||||||
|
printf '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n' >> "$sitemap_file"
|
||||||
|
|
||||||
|
find "$out" -type f -name "*.html" -print | sort | while IFS= read -r html_file; do
|
||||||
|
rel_url="${html_file#"$out"}"
|
||||||
|
|
||||||
|
# Don't include 404 in the sitemap (duh)
|
||||||
|
[ "${rel_url#/}" = "$error_page" ] && continue
|
||||||
|
|
||||||
|
printf ' <url>\n' >> "$sitemap_file"
|
||||||
|
printf ' <loc>%s%s</loc>\n' "$base_url" "$rel_url" >> "$sitemap_file"
|
||||||
|
printf ' <lastmod>%s</lastmod>\n' "$today" >> "$sitemap_file"
|
||||||
|
printf ' </url>\n' >> "$sitemap_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '</urlset>\n' >> "$sitemap_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$generate_feed" = "true" ] && [ -n "$base_url" ]; then
|
||||||
|
feed_path="$out/$feed_file"
|
||||||
|
base_url_feed="${base_url%/}"
|
||||||
|
build_date=$(date -u '+%a, %d %b %Y %H:%M:%S +0000')
|
||||||
|
|
||||||
|
printf '<?xml version="1.0" encoding="UTF-8"?>\n' > "$feed_path"
|
||||||
|
printf '<rss version="2.0">\n' >> "$feed_path"
|
||||||
|
printf ' <channel>\n' >> "$feed_path"
|
||||||
|
printf ' <title>%s</title>\n' "$title" >> "$feed_path"
|
||||||
|
printf ' <link>%s</link>\n' "$base_url_feed" >> "$feed_path"
|
||||||
|
printf ' <description>%s</description>\n' "$title" >> "$feed_path"
|
||||||
|
printf ' <lastBuildDate>%s</lastBuildDate>\n' "$build_date" >> "$feed_path"
|
||||||
|
|
||||||
|
find "$src" -type f -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*.md' -print | LC_ALL=C sort -r | while IFS= read -r post_file; do
|
||||||
|
post_basename=$(basename "$post_file" .md)
|
||||||
|
# Extract YYYY-MM-DD
|
||||||
|
post_date=$(echo "$post_basename" | sed 's/^\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/')
|
||||||
|
|
||||||
|
# Extract HH:MM if present (e.g., 2026-03-17-10:30 or 2026-03-17-10:30_1)
|
||||||
|
post_time="00:00"
|
||||||
|
if echo "$post_basename" | grep -q '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}'; then
|
||||||
|
post_time=$(echo "$post_basename" | sed 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-\([0-9]\{2\}[:\-][0-9]\{2\}\).*/\1/' | tr '-' ':')
|
||||||
|
fi
|
||||||
|
|
||||||
|
post_slug=$(echo "$post_basename" | sed -e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}//' -e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}//' -e 's/^[_\-]//')
|
||||||
|
|
||||||
|
post_heading=$(grep -m 1 '^# ' "$post_file" | sed 's/^# *//')
|
||||||
|
if [ -z "$post_heading" ]; then
|
||||||
|
if [ -n "$post_slug" ] && ! echo "$post_slug" | grep -q '^[0-9]\+$'; then
|
||||||
|
post_heading=$(echo "$post_slug" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1')
|
||||||
|
else
|
||||||
|
post_heading="Post"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
post_heading=$(echo "$post_heading" | sed -e 's/\[//g' -e 's/\]//g' -e 's/!//g' -e 's/\*//g' -e 's/_//g' -e 's/`//g' -e 's/([^)]*)//g' | sed 's/\\//g')
|
||||||
|
post_title="$post_heading - $post_date $post_time"
|
||||||
|
|
||||||
|
rel_path="${post_file#"$src"}"
|
||||||
|
rel_path="${rel_path#/}"
|
||||||
|
post_url="$base_url_feed/${rel_path%.md}.html"
|
||||||
|
|
||||||
|
pub_year=$(echo "$post_date" | cut -d- -f1)
|
||||||
|
pub_month=$(echo "$post_date" | cut -d- -f2)
|
||||||
|
pub_day=$(echo "$post_date" | cut -d- -f3)
|
||||||
|
case "$pub_month" in
|
||||||
|
01) pub_mon="Jan" ;; 02) pub_mon="Feb" ;; 03) pub_mon="Mar" ;;
|
||||||
|
04) pub_mon="Apr" ;; 05) pub_mon="May" ;; 06) pub_mon="Jun" ;;
|
||||||
|
07) pub_mon="Jul" ;; 08) pub_mon="Aug" ;; 09) pub_mon="Sep" ;;
|
||||||
|
10) pub_mon="Oct" ;; 11) pub_mon="Nov" ;; 12) pub_mon="Dec" ;;
|
||||||
|
esac
|
||||||
|
pub_date="${pub_day} ${pub_mon} ${pub_year} ${post_time}:00 +0000"
|
||||||
|
|
||||||
|
printf ' <item>\n' >> "$feed_path"
|
||||||
|
printf ' <title>%s</title>\n' "$post_title" >> "$feed_path"
|
||||||
|
printf ' <link>%s</link>\n' "$post_url" >> "$feed_path"
|
||||||
|
printf ' <guid>%s</guid>\n' "$post_url" >> "$feed_path"
|
||||||
|
printf ' <pubDate>%s</pubDate>\n' "$pub_date" >> "$feed_path"
|
||||||
|
printf ' </item>\n' >> "$feed_path"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf ' </channel>\n' >> "$feed_path"
|
||||||
|
printf '</rss>\n' >> "$feed_path"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Build complete."
|
echo "Build complete."
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ awk -f "$awk_dir/blockquote_to_admonition.awk" "$temp_file" > "$temp_file.tmp" &
|
|||||||
awk -f "$awk_dir/fenced_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/fenced_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/indented_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/indented_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/pipe_tables.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/pipe_tables.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/headers.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -v enable_header_links="$ENABLE_HEADER_LINKS" -f "$awk_dir/headers.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/lists.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/lists.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
|
|
||||||
# Spacing
|
# Spacing
|
||||||
|
|||||||
16
site.conf
16
site.conf
@@ -1,16 +0,0 @@
|
|||||||
title = "kewt"
|
|
||||||
style = "kewt"
|
|
||||||
dir_indexes = true
|
|
||||||
single_file_index = true
|
|
||||||
flatten = false
|
|
||||||
footer = "made with <a href="https://kewt.krzak.org">kewt</a>"
|
|
||||||
logo = ""
|
|
||||||
display_logo = false
|
|
||||||
display_title = true
|
|
||||||
logo_as_favicon = true
|
|
||||||
favicon = ""
|
|
||||||
order = ""
|
|
||||||
home_name = "Home"
|
|
||||||
show_home_in_nav = true
|
|
||||||
nav_links = ""
|
|
||||||
nav_extra = ""
|
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
# _kewt_
|
# _kewt_
|
||||||
### Pronounced "cute"
|
### Pronounced "cute"
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
# [Go to the repo](https://git.krzak.org/N0VA/kewt)
|
# [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)_
|
_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)_)
|
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)_)
|
||||||
@@ -16,6 +20,13 @@ It's meant to be a static site generator, like _[kew](https://github.com/uint23/
|
|||||||
- Inline html support
|
- Inline html support
|
||||||
- MFM `$font` and `\<plain>` tags
|
- MFM `$font` and `\<plain>` tags
|
||||||
- Admonition support (that's what the blocks like the warning block below are called)
|
- 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 `\![]`
|
If you want to **force** a file to be inlined, use `\!![]` instead of `\![]`
|
||||||
|
|
||||||
@@ -24,7 +35,7 @@ If you want to **force** a file to be inlined, use `\!![]` instead of `\![]`
|
|||||||
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:
|
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:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -L -o kewt https://git.krzak.org/N0VA/kewt/releases/latest/download/kewt
|
curl -L -o kewt https://git.krzak.org/N0VA/kewt/releases/download/latest/kewt
|
||||||
chmod +x kewt
|
chmod +x kewt
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -37,13 +48,17 @@ On Arch Linux, _kewt_ is available on the AUR:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
./kewt.sh --help
|
./kewt.sh --help
|
||||||
|
./kewt.sh --version
|
||||||
./kewt.sh --new [title]
|
./kewt.sh --new [title]
|
||||||
|
./kewt.sh --post
|
||||||
./kewt.sh --from <src> --to <out>
|
./kewt.sh --from <src> --to <out>
|
||||||
./kewt.sh [src] [out]
|
./kewt.sh [src] [out]
|
||||||
```
|
```
|
||||||
|
|
||||||
`--new [title]` creates a new site directory with a copied `site.conf` and a default `index.md`.
|
`--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
|
## site.conf
|
||||||
|
|
||||||
```conf
|
```conf
|
||||||
@@ -57,12 +72,20 @@ home_name = "Home"
|
|||||||
show_home_in_nav = true
|
show_home_in_nav = true
|
||||||
nav_links = ""
|
nav_links = ""
|
||||||
nav_extra = ""
|
nav_extra = ""
|
||||||
footer = "made with <a href="https://kewt.krzak.org">kewt</a>"
|
footer = "made with <a href=\"https://kewt.krzak.org\">kewt</a>"
|
||||||
logo = ""
|
logo = ""
|
||||||
display_logo = false
|
display_logo = false
|
||||||
display_title = true
|
display_title = true
|
||||||
logo_as_favicon = true
|
logo_as_favicon = true
|
||||||
favicon = ""
|
favicon = ""
|
||||||
|
generate_page_title = true
|
||||||
|
error_page = "not_found.html"
|
||||||
|
versioning = false
|
||||||
|
base_url = ""
|
||||||
|
generate_feed = false
|
||||||
|
feed_file = "rss.xml"
|
||||||
|
posts_dir = ""
|
||||||
|
enable_header_links = true
|
||||||
```
|
```
|
||||||
|
|
||||||
- `title` site title
|
- `title` site title
|
||||||
@@ -81,6 +104,14 @@ favicon = ""
|
|||||||
- `display_title` show title text in header
|
- `display_title` show title text in header
|
||||||
- `logo_as_favicon` use `logo` as favicon
|
- `logo_as_favicon` use `logo` as favicon
|
||||||
- `favicon` explicit favicon path (used when `logo_as_favicon` is false or no logo is set)
|
- `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.
|
||||||
|
- `enable_header_links` turns markdown section headings into clickable anchor links (default: true)
|
||||||
|
|
||||||
## Ignores
|
## Ignores
|
||||||
|
|
||||||
@@ -100,7 +131,7 @@ favicon = ""
|
|||||||
|
|
||||||
## Credits
|
## 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]
|
>[!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...
|
||||||
|
|||||||
@@ -3,10 +3,19 @@ style = "kewt"
|
|||||||
dir_indexes = true
|
dir_indexes = true
|
||||||
single_file_index = true
|
single_file_index = true
|
||||||
flatten = false
|
flatten = false
|
||||||
footer = "<a href="https://kewt.krzak.org"><img src="/button.gif" /></a>"
|
footer = "<a href=\"https://kewt.krzak.org\"><img src=\"/button.gif\" /></a>"
|
||||||
logo = ""
|
logo = ""
|
||||||
display_logo = false
|
display_logo = false
|
||||||
display_title = true
|
display_title = true
|
||||||
logo_as_favicon = true
|
logo_as_favicon = true
|
||||||
favicon = ""
|
favicon = ""
|
||||||
order = ""
|
order = ""
|
||||||
|
home_name = "Home"
|
||||||
|
show_home_in_nav = true
|
||||||
|
nav_links = ""
|
||||||
|
nav_extra = ""
|
||||||
|
generate_page_title = true
|
||||||
|
error_page = "not_found.html"
|
||||||
|
versioning = false
|
||||||
|
enable_header_links = true
|
||||||
|
base_url = "https://kewt.krzak.org"
|
||||||
|
|||||||
106
styles/kewt.css
106
styles/kewt.css
@@ -1,25 +1,28 @@
|
|||||||
:root {
|
:root {
|
||||||
--bg: #646c7f;
|
--bg: #4a3b69;
|
||||||
--fg: #fffde0;
|
--bg-deep: #352654;
|
||||||
--fg-link: #fff18f;
|
--fg: #fbf5ff;
|
||||||
--code-bg: #32394a;
|
--fg-muted: #c8b9df;
|
||||||
--code-border: #8f95a4;
|
--fg-link: #dfaeff;
|
||||||
--code-fg: #fffde0;
|
--fg-heading: #debfff;
|
||||||
--code-sel: #fff18f;
|
--code-bg: #31234c;
|
||||||
--code-prop: #ffd27f;
|
--code-border: #8060af;
|
||||||
--code-val: #cde7ff;
|
--code-fg: #fbf5ff;
|
||||||
--code-var: #b9ffbe;
|
--code-sel: #ffef99;
|
||||||
--code-com: #d0d0d0;
|
--code-prop: #ffdfba;
|
||||||
--adm-note-bg: #3f5666;
|
--code-val: #cae2ff;
|
||||||
--adm-note-border: #a8d8ff;
|
--code-var: #caffc2;
|
||||||
--adm-tip-bg: #3f664c;
|
--code-com: #b8aac8;
|
||||||
--adm-tip-border: #b9ffbe;
|
--adm-note-bg: #353866;
|
||||||
--adm-important-bg: #5a4a6c;
|
--adm-note-border: #b8c5ff;
|
||||||
--adm-important-border: #e4c7ff;
|
--adm-tip-bg: #295246;
|
||||||
--adm-warning-bg: #6b5539;
|
--adm-tip-border: #aeffda;
|
||||||
--adm-warning-border: #ffe0a8;
|
--adm-important-bg: #533076;
|
||||||
--adm-caution-bg: #6f3f3f;
|
--adm-important-border: #f4d9ff;
|
||||||
--adm-caution-border: #ffb4b4;
|
--adm-warning-bg: #634631;
|
||||||
|
--adm-warning-border: #ffe2bd;
|
||||||
|
--adm-caution-bg: #662d43;
|
||||||
|
--adm-caution-border: #ffc4d5;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -29,18 +32,22 @@ body {
|
|||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
font-family: serif;
|
font-family: serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.2;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
border-bottom: 1px solid var(--code-border);
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
header h1 {
|
header h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 35px;
|
font-size: 35px;
|
||||||
font-weight: normal;
|
font-weight: bold;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
color: var(--fg-heading);
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-logo {
|
.site-logo {
|
||||||
@@ -57,18 +64,26 @@ header a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header a:hover {
|
||||||
|
color: var(--bg-deep);
|
||||||
|
background: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
#side-bar {
|
#side-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 80px;
|
top: 80px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
margin-right: 14px;
|
||||||
|
border-right: 1px solid var(--code-border);
|
||||||
|
padding-right: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-title {
|
.side-title {
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
margin: 20px 0 8px 0;
|
margin: 20px 0 8px 0;
|
||||||
color: var(--fg);
|
color: var(--fg-heading);
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-bar ul {
|
#side-bar ul {
|
||||||
@@ -87,6 +102,14 @@ a {
|
|||||||
padding: 1px 2px;
|
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 {
|
a:hover {
|
||||||
background: var(--fg);
|
background: var(--fg);
|
||||||
color: var(--bg);
|
color: var(--bg);
|
||||||
@@ -100,7 +123,7 @@ article {
|
|||||||
h3 {
|
h3 {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
color: var(--fg);
|
color: var(--fg-heading);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,10 +220,11 @@ pre code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
padding-top: 80px;
|
padding-top: 60px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
color: var(--fg-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
article,
|
article,
|
||||||
@@ -220,3 +244,33 @@ footer img {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: top;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>{{TITLE}}</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{CSS}}" type="text/css" />
|
|
||||||
{{HEAD_EXTRA}}
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<h1>{{HEADER_BRAND}}</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<nav id="side-bar">{{NAV}}</nav>
|
|
||||||
|
|
||||||
<article>{{CONTENT}}</article>
|
|
||||||
<footer>{{FOOTER}}</footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -26,7 +26,13 @@ exit $?
|
|||||||
#==PAYLOAD==
|
#==PAYLOAD==
|
||||||
EOF
|
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"
|
chmod +x "$OUT_FILE"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user