diff --git a/.gitignore b/.gitignore
index ec76799..9bbfc92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,6 @@
*.bak
**.pub
-/zs
+/aya
/dist
/test.md
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index 88ef0c6..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,25 +0,0 @@
----
-builds:
- -
- id: zs
- binary: zs
- main: .
- flags: -tags "static_build"
- ldflags: -w -X main.Version={{.Version}} -X main.Commit={{.Commit}}
- env:
- - CGO_ENABLED=0
- goos:
- - darwin
- - linux
- goarch:
- - amd64
- - arm64
-signs:
- - artifacts: checksum
-release:
- gitea:
- owner: prologic
- name: zs
- draft: true
-gitea_urls:
- api: https://git.mills.io/api/v1/
diff --git a/LICENSE b/LICENSE
index c68b526..04b041b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,7 @@
The MIT License (MIT)
Copyright (c) 2014 zserge
+Copyright (c) 2023 Izuru Yakumo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Makefile b/Makefile
index b1b1fe8..6b90e2d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,17 @@
destdir ?=
+goflags ?= -v -ldflags "-w -X `go list`.Version=$(version) -X `go list`.Commit=$(commit)" -tags "static_build"
prefix ?= /usr/local
+version ?= `git rev-list --count HEAD || echo "$version"`
+commit ?= `git rev-parse --short HEAD || echo "$commit"`
+
build:
- go build -v
+ go build ${goflags} ./cmd/aya
clean:
- rm -f zs
+ rm -f aya
install:
- install -m0755 zs ${destdir}${prefix}/bin/zs
- install -m0644 zs.1 ${destdir}${prefix}/share/man/man1/zs.1
+ install -Dm0755 aya ${destdir}${prefix}/bin/aya
+ install -Dm0644 aya.1 ${destdir}${prefix}/share/man/man1/aya.1
uninstall:
- rm -f ${prefix}/bin/zs
- rm -f ${prefix}/share/man/man1/zs.1
+ rm -f ${prefix}/bin/aya
+ rm -f ${prefix}/share/man/man1/aya.1
diff --git a/README.md b/README.md
index dda5588..0d61b73 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,8 @@
-# zs
+# aya
-zs is an extremely minimal static site generator written in Go.
+aya is an extremely minimal static site generator written in Go.
-It's inspired by `zas` generator, but is even more minimal.
-
-The name stands for 'zen static' as well as it's my initials.
+This crow tengu stands for 'the fastest one in Gensokyo' and yes this is also a Touhou Project reference.
## Features
@@ -17,9 +15,9 @@ The name stands for 'zen static' as well as it's my initials.
## Installation
-Download the binaries from Github or build it manually:
+Build it manually assuming you have Go installed:
- $ go get git.mills.io/prologic/zs
+ $ go install marisa.chaotic.ninja/aya@latest
## Ideology
@@ -27,7 +25,7 @@ Keep your texts in markdown, or HTML format right in the main directory
of your blog/site.
Keep all service files (extensions, layout pages, deployment scripts etc)
-in the `.zs` subdirectory.
+in the `.aya` subdirectory.
Define variables in the header of the content files using [YAML]:
@@ -40,18 +38,18 @@ Define variables in the header of the content files using [YAML]:
Use placeholders for variables and plugins in your markdown or html
files, e.g. `{{ title }}` or `{{ command arg1 arg2 }}.
-Write extensions in any language you like and put them into the `.zs`
+Write extensions in any language you like and put them into the `.aya`
subdiretory.
Everything the extensions prints to stdout becomes the value of the
placeholder.
-Every variable from the content header will be passed via environment variables like `title` becomes `$ZS_TITLE` and so on. There are some special variables:
+Every variable from the content header will be passed via environment variables like `title` becomes `$AYA_TITLE` and so on. There are some special variables:
-* `$ZS` - a path to the `zs` executable
-* `$ZS_OUTDIR` - a path to the directory with generated files
-* `$ZS_FILE` - a path to the currently processed markdown file
-* `$ZS_URL` - a URL for the currently generated page
+* `$AYA` - a path to the `aya` executable
+* `$AYA_OUTDIR` - a path to the directory with generated files
+* `$AYA_FILE` - a path to the currently processed markdown file
+* `$AYA_URL` - a URL for the currently generated page
## Example of RSS generation
@@ -59,19 +57,19 @@ Extensions can be written in any language you know (Bash, Python, Lua, JavaScrip
``` bash
for f in ./blog/*.md ; do
- d=$($ZS var $f date)
+ d=$($AYA var $f date)
if [ ! -z $d ] ; then
timestamp=`date --date "$d" +%s`
- url=`$ZS var $f url`
- title=`$ZS var $f title | tr A-Z a-z`
- descr=`$ZS var $f description`
+ url=`$AYA var $f url`
+ title=`$AYA var $f title | tr A-Z a-z`
+ descr=`$AYA var $f description`
echo $timestamp \
"" \
"$title" \
- "http://zserge.com/$url" \
+ "http://ayaerge.com/$url" \
"$descr" \
"$(date --date @$timestamp -R)" \
- "http://zserge.com/$url" \
+ "http://ayaerge.com/$url" \
""
fi
done | sort -r -n | cut -d' ' -f2-
@@ -83,21 +81,21 @@ There are two special plugin names that are executed every time the build
happens - `prehook` and `posthook`. You can define some global actions here like
content generation, or additional commands, like LESS to CSS conversion:
- # .zs/post
+ # .aya/post
#!/bin/sh
- lessc < $ZS_OUTDIR/styles.less > $ZS_OUTDIR/styles.css
- rm -f $ZS_OUTDIR/styles.css
+ lessc < $AYA_OUTDIR/styles.less > $AYA_OUTDIR/styles.css
+ rm -f $AYA_OUTDIR/styles.css
## Command line usage
-`zs build` re-builds your site.
+`aya build` re-builds your site.
-`zs build ` re-builds one file and prints resulting content to stdout.
+`aya build ` re-builds one file and prints resulting content to stdout.
-`zs watch` rebuilds your site every time you modify any file.
+`aya watch` rebuilds your site every time you modify any file.
-`zs var [var1 var2...]` prints a list of variables defined in the
+`aya var [var1 var2...]` prints a list of variables defined in the
header of a given markdown file, or the values of certain variables (even if
it's an empty string).
diff --git a/aya.1 b/aya.1
new file mode 100644
index 0000000..33e2b08
--- /dev/null
+++ b/aya.1
@@ -0,0 +1,37 @@
+.Dd $Mdocdate$
+.Dt AYA 1
+.Os
+.Sh NAME
+.Nm aya
+.Nd A really fast static site generator
+.Sh DESCRIPTION
+Does it need one?
+.Sh FEATURES
+.Bl -tag -width 11n -compact
+.It Zero configuration (no configuration file needed)
+.It Cross-platform
+.It Highly extensible
+.It Works well for blogs and generic static websites (landing pages etc)
+.It Easy to learn
+.It Fast (of course)
+.El
+.Sh USAGE
+.Ss (Re-)build your site.
+.Nm
+.Cm build
+.Ss (Re-)build one file and prints resulting content to standard output.
+.Nm
+.Cm build
+.Ar
+.Ss (Re-)build your site every time you modify any file.
+.Nm
+.Cm watch
+.Ss Print a list of variables defined in the header of a given markdown file.
+.Nm
+.Cm var
+.Ar
+.Ar ...
+.Sh AUTHORS
+.Nm
+is maintained by Izuru Yakumo
+.Aq Lk https://pub.chaotic.ninja/~yakumo_izuru/
diff --git a/build_test.go b/build_test.go
deleted file mode 100644
index 78076b8..0000000
--- a/build_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package main
-
-import (
- "crypto/md5"
- "encoding/hex"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "testing"
-)
-
-const TESTDIR = ".test"
-
-func TestBuild(t *testing.T) {
- files, _ := ioutil.ReadDir("testdata")
- for _, f := range files {
- if f.IsDir() {
- testBuild(filepath.Join("testdata", f.Name()), t)
- }
- }
-}
-
-func testBuild(path string, t *testing.T) {
- wd, _ := os.Getwd()
- os.Chdir(path)
- args := os.Args[:]
- os.Args = []string{"zs", "build"}
- t.Log("--- BUILD", path)
- main()
-
- compare(PUBDIR, TESTDIR, t)
-
- os.Chdir(wd)
- os.Args = args
-}
-
-func compare(pub, test string, t *testing.T) {
- a := md5dir(pub)
- b := md5dir(test)
- for k, v := range a {
- if s, ok := b[k]; !ok {
- t.Error("Unexpected file:", k, v)
- } else if s != v {
- t.Error("Different file:", k, v, s)
- } else {
- t.Log("Matching file", k, v)
- }
- }
- for k, v := range b {
- if _, ok := a[k]; !ok {
- t.Error("Missing file:", k, v)
- }
- }
-}
-
-func md5dir(path string) map[string]string {
- files := map[string]string{}
- filepath.Walk(path, func(s string, info os.FileInfo, err error) error {
- if err == nil && !info.IsDir() {
- if f, err := os.Open(s); err == nil {
- defer f.Close()
- hash := md5.New()
- io.Copy(hash, f)
- files[strings.TrimPrefix(s, path)] = hex.EncodeToString(hash.Sum(nil))
- }
- }
- return nil
- })
- return files
-}
diff --git a/main.go b/cmd/aya/main.go
similarity index 89%
rename from main.go
rename to cmd/aya/main.go
index f5240d6..4f04b1b 100644
--- a/main.go
+++ b/cmd/aya/main.go
@@ -15,10 +15,11 @@ import (
"github.com/russross/blackfriday/v2"
"gopkg.in/yaml.v2"
+ "marisa.chaotic.ninja/aya"
)
const (
- ZSDIR = ".zs"
+ AYADIR = ".aya"
PUBDIR = ".pub"
)
@@ -38,12 +39,12 @@ func renameExt(path, oldext, newext string) string {
}
// globals returns list of global OS environment variables that start
-// with ZS_ prefix as Vars, so the values can be used inside templates
+// with AYA_ prefix as Vars, so the values can be used inside templates
func globals() Vars {
vars := Vars{}
for _, e := range os.Environ() {
pair := strings.Split(e, "=")
- if strings.HasPrefix(pair[0], "ZS_") {
+ if strings.HasPrefix(pair[0], "AYA_") {
vars[strings.ToLower(pair[0][3:])] = pair[1]
}
}
@@ -51,21 +52,21 @@ func globals() Vars {
}
// run executes a command or a script. Vars define the command environment,
-// each zs var is converted into OS environemnt variable with ZS_ prefix
-// prepended. Additional variable $ZS contains path to the zs binary. Command
-// stderr is printed to zs stderr, command output is returned as a string.
+// each aya var is converted into OS environemnt variable with AYA_ prefix
+// prepended. Additional variable $AYA contains path to the aya binary. Command
+// stderr is printed to aya stderr, command output is returned as a string.
func run(vars Vars, cmd string, args ...string) (string, error) {
// First check if partial exists (.html)
- if b, err := ioutil.ReadFile(filepath.Join(ZSDIR, cmd+".html")); err == nil {
+ if b, err := ioutil.ReadFile(filepath.Join(AYADIR, cmd+".html")); err == nil {
return string(b), nil
}
var errbuf, outbuf bytes.Buffer
c := exec.Command(cmd, args...)
- env := []string{"ZS=" + os.Args[0], "ZS_OUTDIR=" + PUBDIR}
+ env := []string{"AYA=" + os.Args[0], "AYA_OUTDIR=" + PUBDIR}
env = append(env, os.Environ()...)
for k, v := range vars {
- env = append(env, "ZS_"+strings.ToUpper(k)+"="+v)
+ env = append(env, "AYA_"+strings.ToUpper(k)+"="+v)
}
c.Env = env
c.Stdout = &outbuf
@@ -136,7 +137,7 @@ func getVars(path string, globals Vars) (Vars, string, error) {
}
}
-// Render expanding zs plugins and variables
+// Render expanding aya plugins and variables
func render(s string, vars Vars) (string, error) {
delim_open := "{{"
delim_close := "}}"
@@ -193,7 +194,7 @@ func buildMarkdown(path string, w io.Writer, vars Vars) error {
defer out.Close()
w = out
}
- return buildHTML(filepath.Join(ZSDIR, v["layout"]), w, v)
+ return buildHTML(filepath.Join(AYADIR, v["layout"]), w, v)
}
// Renders text file expanding all variable macros inside it
@@ -296,9 +297,9 @@ func buildAll(watch bool) {
}
func init() {
- // prepend .zs to $PATH, so plugins will be found before OS commands
+ // prepend .aya to $PATH, so plugins will be found before OS commands
p := os.Getenv("PATH")
- p = ZSDIR + ":" + p
+ p = AYADIR + ":" + p
os.Setenv("PATH", p)
}
@@ -342,6 +343,9 @@ func main() {
}
fmt.Println(strings.TrimSpace(s))
}
+ case "version":
+ fmt.Printf("%v\n", aya.Version)
+ os.Exit(0)
default:
if s, err := run(globals(), cmd, args...); err != nil {
fmt.Println(err)
diff --git a/go.mod b/go.mod
index 636544d..7475318 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module git.mills.io/prologic/zs
+module marisa.chaotic.ninja/aya
go 1.17
diff --git a/main_test.go b/main_test.go
deleted file mode 100644
index 6470bc5..0000000
--- a/main_test.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package main
-
-import (
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-)
-
-func TestRenameExt(t *testing.T) {
- if s := renameExt("foo.amber", ".amber", ".html"); s != "foo.html" {
- t.Error(s)
- }
- if s := renameExt("foo.amber", "", ".html"); s != "foo.html" {
- t.Error(s)
- }
- if s := renameExt("foo.amber", ".md", ".html"); s != "foo.amber" {
- t.Error(s)
- }
- if s := renameExt("foo", ".amber", ".html"); s != "foo" {
- t.Error(s)
- }
- if s := renameExt("foo", "", ".html"); s != "foo.html" {
- t.Error(s)
- }
-}
-
-func TestRun(t *testing.T) {
- // external command
- if s, err := run(Vars{}, "echo", "hello"); err != nil || s != "hello\n" {
- t.Error(s, err)
- }
- // passing variables to plugins
- if s, err := run(Vars{"foo": "bar"}, "sh", "-c", "echo $ZS_FOO"); err != nil || s != "bar\n" {
- t.Error(s, err)
- }
-
- // custom plugin overriding external command
- os.Mkdir(ZSDIR, 0755)
- script := `#!/bin/sh
-echo foo
-`
- ioutil.WriteFile(filepath.Join(ZSDIR, "echo"), []byte(script), 0755)
- if s, err := run(Vars{}, "echo", "hello"); err != nil || s != "foo\n" {
- t.Error(s, err)
- }
- os.Remove(filepath.Join(ZSDIR, "echo"))
- os.Remove(ZSDIR)
-}
-
-func TestVars(t *testing.T) {
- tests := map[string]Vars{
- `
-foo: bar
-title: Hello, world!
----
-Some content in markdown
-`: {
- "foo": "bar",
- "title": "Hello, world!",
- "url": "test.html",
- "file": "test.md",
- "output": filepath.Join(PUBDIR, "test.html"),
- "__content": "Some content in markdown\n",
- },
- `
-url: "example.com/foo.html"
----
-Hello
-`: {
- "url": "example.com/foo.html",
- "__content": "Hello\n",
- },
- }
-
- for script, vars := range tests {
- ioutil.WriteFile("test.md", []byte(script), 0644)
- if v, s, err := getVars("test.md", Vars{"baz": "123"}); err != nil {
- t.Error(err)
- } else if s != vars["__content"] {
- t.Error(s, vars["__content"])
- } else {
- for key, value := range vars {
- if key != "__content" && v[key] != value {
- t.Error(key, v[key], value)
- }
- }
- }
- }
-}
-
-func TestRender(t *testing.T) {
- vars := map[string]string{"foo": "bar"}
-
- if s, _ := render("foo bar", vars); s != "foo bar" {
- t.Error(s)
- }
- if s, _ := render("a {{printf short}} text", vars); s != "a short text" {
- t.Error(s)
- }
- if s, _ := render("{{printf Hello}} x{{foo}}z", vars); s != "Hello xbarz" {
- t.Error(s)
- }
- // Test error case
- if _, err := render("a {{greet text ", vars); err == nil {
- t.Error("error expected")
- }
-}
diff --git a/testdata/blog/.test/about.html b/testdata/blog/.test/about.html
deleted file mode 100644
index 2ad8b67..0000000
--- a/testdata/blog/.test/about.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- About myself
-
-
-
About myself
-
-
Hi all. This is a brief description of who I am.
-
-
diff --git a/testdata/blog/.test/index.html b/testdata/blog/.test/index.html
deleted file mode 100644
index 30af02e..0000000
--- a/testdata/blog/.test/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- My blog
-
-
-
-
-
-
diff --git a/testdata/sugar/.test/styles.css b/testdata/sugar/.test/styles.css
deleted file mode 100644
index 42f29d4..0000000
--- a/testdata/sugar/.test/styles.css
+++ /dev/null
@@ -1 +0,0 @@
-body{font:100% Helvetica, sans-serif;color:blue;}
\ No newline at end of file
diff --git a/testdata/sugar/index.amber b/testdata/sugar/index.amber
deleted file mode 100644
index ec9948c..0000000
--- a/testdata/sugar/index.amber
+++ /dev/null
@@ -1,3 +0,0 @@
-html
- body
- p Hello world
diff --git a/testdata/sugar/styles.gcss b/testdata/sugar/styles.gcss
deleted file mode 100644
index b2b4a29..0000000
--- a/testdata/sugar/styles.gcss
+++ /dev/null
@@ -1,6 +0,0 @@
-$base-font: Helvetica, sans-serif
-$main-color: blue
-
-body
- font: 100% $base-font
- color: $main-color
diff --git a/tools/release.sh b/tools/release.sh
deleted file mode 100755
index e8ab44e..0000000
--- a/tools/release.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-# Get the highest tag number
-VERSION="$(git describe --abbrev=0 --tags)"
-VERSION=${VERSION:-'0.0.0'}
-
-# Get number parts
-MAJOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
-MINOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
-PATCH="${VERSION%%.*}"; VERSION="${VERSION#*.}"
-
-# Increase version
-PATCH=$((PATCH+1))
-
-TAG="${1}"
-
-if [ "${TAG}" = "" ]; then
- TAG="${MAJOR}.${MINOR}.${PATCH}"
-fi
-
-echo "Releasing ${TAG} ..."
-
-git tag -a -s -m "Release ${TAG}" "${TAG}"
-git push --tags
-goreleaser release --rm-dist
diff --git a/version.go b/version.go
index 3aefaf3..abbbb4a 100644
--- a/version.go
+++ b/version.go
@@ -1,4 +1,4 @@
-package main
+package aya
import (
"fmt"
diff --git a/zs.1 b/zs.1
deleted file mode 100644
index eedf7de..0000000
--- a/zs.1
+++ /dev/null
@@ -1,50 +0,0 @@
-.Dd January 7, 2022
-.Dt ZS 1
-.Os
-.Sh NAME
-.Nm zs
-.Nd Absolutely minimal static site generator written in Go.
-.Sh DESCRIPTION
-.Nm
-is an extremely minimal static site generator written in Go.
-.Pp
-It's inspired by
-.Em zas
-generator, but is even more minimal.
-.Pp
-The name stands for 'zen static'
-.Sh FEATURES
-.Li Zero configuration (no configuration file needed)
-.Pp
-.Li Cross-platform
-.Pp
-.Li Highly extensible
-.Pp
-.Li Works well for blogs and generic static websites (landing pages etc)
-.Pp
-.Li Easy to learn
-.Pp
-.Li Fast
-.Sh USAGE
-.Ss (Re-)build your site.
-.Nm
-.Cm build
-.Ss (Re-)build one file and prints resulting content to standard output.
-.Nm
-.Cm build
-.Ar
-.Ss (Re-)build your site every time you modify any file.
-.Nm
-.Cm watch
-.Ss Print a list of variables defined in the header of a given markdown file.
-.Nm
-.Cm var
-.Ar
-.Ar ...
-.Sh AUTHORS
-.Nm
-is maintained by James Mills
-.Aq Lk https://prologic.shortcircuit.net.au/
-.Pp
-This manual page was written by Nova
-.Aq Lk https://tilde.cafe/~novaburst