add readme

This commit is contained in:
slonkazoid 2024-12-16 22:44:26 +03:00
parent f6a474f64c
commit dc0f499723
Signed by: slonk
SSH key fingerprint: SHA256:tbZfJX4IOvZ0LGWOWu5Ijo8jfMPi78TU7x1VoEeCIjM
2 changed files with 169 additions and 25 deletions

139
README.md Normal file
View file

@ -0,0 +1,139 @@
# blag
blogging in bash
all blag really is can be summed up as 'a collection of functions for
writing markup in bash, alongside
[bingus-blog](https://git.slonk.ing/slonk/bingus-blog) integration',
but that would be doing it injustice. blag is not just a shellscript.
blag is a way of life- no, blag is the _meaning_ of life.
keep on blagging.
## how to blag
first create a file for your blagpost. the name doesn't matter, but i like to
end mine with `.sh` (this is a requirement for bingus-blog integration).
then, render it with blag: `./blag my_epic_post.sh > rendered.html`.
you'll notice that the resulting html is blank. this is because the post you
wrote did not output anything. in blag, we use the inbuild functions (or plain
printf if you're in a pinch) to actually compose our markup. see below for more
information on those.
### functions
functions in blag generally take html from stdin and output html. this makes it
possible to form complex pipes merging and transforming the content, similar to
applicative programming. an example of this composability:
`curl wttr.in/?2n | escape | codeblock`.
#### `escape`
html-escapes text from stdin.
#### `header <LEVEL>`
LEVEL is a number from 1 to 5, representing h1 to h5.
creates a header from stdin.
#### `paragraph`
creates a paragraph from stdin. simple enough.
#### `image <SRC> <ALT>`
creates an image element with the given SRC (source) and ALT (alt text).
no input.
#### `link <HREF>`
formats stdin as a link to HREF.
#### `br`
outputs a line break.
no input.
#### `br_lines`
replaces line feed characters from stdin with html line breaks.
#### `codeblock`
creates a codeblock from stdin.
### sourcing blag from posts
the regular blag workflow has you running the `blag` binary with the
path to your post, but you could very well just source `blag` _from the post_.
doing so will expose the blag functions to your shellscript but not trigger
blag's cli.
### example
`post.sh`:
```sh
header 1 <<< "hello, world!"
{
echo "the time is:"
date
} | paragraph
```
run `blag` on your post:
```sh
./blag post.sh > rendered.html
```
`rendered.html`:
```html
<h1>hello, world!</h1><p>the time is:
Mon Dec 16 22:42:00 +03 2024</p>
```
## bingus-blog integration
set `engine = "blag"` in your configuration file. the naming format is
"(post name).sh" on disk, just like default markdown posts.
the first line your blag outputs MUST be the post metadata. you MUST set the
following variables in your blag:
- `TITLE`
- `DESCRIPTION`
you SHOULD set `AUTHOR`, though it does default to the name of the user running
`blag`.
you MAY set these variables:
- `ICON`
- `ICON_ALT`
- `COLOR`
- `TAGS` (as an array!)
- `DONT_CACHE` (to explicitly not cache the rendered blag)
- `WRITTEN_AT` (if the filesystem/libc doesn't support it)
you SHOULD NOT set `MODIFIED_AT` unless you have a valid reason.
after setting all the variables call the `metadata` function before outputting
anything else.
the environment variable `BLAG_QUERY` is provided to you as the unmatched
query parameters for the request that invoked the rendering, in json. you can
safely use `jq` to parse it.
the rest is normal
### fastblag
:eyes:
## disclaimer
this is very bad and also pre-alpha quality software. dont come crying
to me when you get revshelled.

55
blag
View file

@ -1,13 +1,8 @@
#!/usr/bin/env bash
#shellcheck disable=SC2155
print_help() {
echo "Usage: $0 <SCRIPT>
$0 -h|--help"
}
error() {
echo "Error: $*" >&2
echo "error: $*" >&2
}
escape() {
@ -28,15 +23,15 @@ _json_str_opt() {
#shellcheck disable=SC2153
metadata() {
local title="$(_json_str "${TITLE?}")"
local description="$(_json_str "${DESCRIPTION?}")"
local author="$(_json_str "${AUTHOR?}")"
local icon="$(_json_str_opt "$ICON")"
local icon_alt="$(_json_str_opt "$ICON_ALT")"
local color="$(_json_str_opt "$COLOR")"
local created_at="$(_json_str_opt "$CREATED_AT")"
local modified_at="$(_json_str_opt "$MODIFIED_AT")"
local tags="$(for tag in "${TAGS[@]}"; do printf '%s' "$tag" | jq -Rs .; done | jq -sr @json)"
local title=$(_json_str "${TITLE?}")
local description=$(_json_str "${DESCRIPTION?}")
local author=$(_json_str "${AUTHOR:-$(id -un)}")
local icon=$(_json_str_opt "$ICON")
local icon_alt=$(_json_str_opt "$ICON_ALT")
local color=$(_json_str_opt "$COLOR")
local created_at=$(_json_str_opt "$CREATED_AT")
local modified_at=$(_json_str_opt "$MODIFIED_AT")
local tags=$(for tag in "${TAGS[@]}"; do printf '%s' "$tag" | jq -Rs .; done | jq -sr @json)
local dont_cache=false
[[ "${DONT_CACHE:+x}" == 'x' ]] && dont_cache=true
@ -63,7 +58,7 @@ paragraph() {
image() {
src=${1?need src}
alt=${2?need alt. dickhead.}
alt=${2?need alt}
printf '<img src="%s" alt="%s">' "$(printf '%s' "$src" | escape)" "$(printf '%s' "$alt" | escape)"
}
@ -101,14 +96,24 @@ render() {
( . "$1"; ) # the moment you've all been waiting for
}
script=$1
if [[ "${script:+x}" != 'x' ]]; then
print_help
exit 1
elif [[ "$script" == "--help"
|| "$script" == "-h" ]]; then
print_help
else
render "$script"
print_help() {
echo "Usage: $0 <SCRIPT>
$0 -h|--help"
}
if ! ( return &>/dev/null ); then
script=$1
if [[ "${script:+x}" != 'x' ]]; then
print_help
exit 1
elif [[ "$script" == "--help"
|| "$script" == "-h" ]]; then
print_help
else
render "$script"
fi
fi