*.bak
**.pub
-/zs
+/aya
/dist
/test.md
+++ /dev/null
----
-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/
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
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
-# 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
## 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
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]:
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
``` 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 \
"<item>" \
"<title>$title</title>" \
- "<link>http://zserge.com/$url</link>" \
+ "<link>http://ayaerge.com/$url</link>" \
"<description>$descr</description>" \
"<pubDate>$(date --date @$timestamp -R)</pubDate>" \
- "<guid>http://zserge.com/$url</guid>" \
+ "<guid>http://ayaerge.com/$url</guid>" \
"</item>"
fi
done | sort -r -n | cut -d' ' -f2-
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 <file>` re-builds one file and prints resulting content to stdout.
+`aya build <file>` 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 <filename> [var1 var2...]` prints a list of variables defined in the
+`aya var <filename> [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).
--- /dev/null
+.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 <file>
+.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 <file>
+.Ar <var1> <var2> ...
+.Sh AUTHORS
+.Nm
+is maintained by Izuru Yakumo
+.Aq Lk https://pub.chaotic.ninja/~yakumo_izuru/
+++ /dev/null
-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
-}
"github.com/russross/blackfriday/v2"
"gopkg.in/yaml.v2"
+ "marisa.chaotic.ninja/aya"
)
const (
- ZSDIR = ".zs"
+ AYADIR = ".aya"
PUBDIR = ".pub"
)
}
// 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]
}
}
}
// 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
}
}
-// Render expanding zs plugins and variables
+// Render expanding aya plugins and variables
func render(s string, vars Vars) (string, error) {
delim_open := "{{"
delim_close := "}}"
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
}
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)
}
}
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)
-module git.mills.io/prologic/zs
+module marisa.chaotic.ninja/aya
go 1.17
+++ /dev/null
-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")
- }
-}
+++ /dev/null
-<html>
- <head>
- <title>About myself</title>
- <link href="styles.css" rel="stylesheet" type="text/css" />
- </head>
- <body><h1>About myself</h1>
-
-<p>Hi all. This is a brief description of who I am.</p>
-</body>
-</html>
+++ /dev/null
-<html>
- <head>
- <title>My blog</title>
- <link href="styles.css" rel="stylesheet" type="text/css" />
- </head>
- <body>
- <p>Here goes list of posts</p>
- <ul>
- <li>
- <a href="/posts/hello.html">First post</a>
- </li>
- <li>
- <a href="/posts/update.html">Second post</a>
- </li>
- </ul>
- </body>
-</html>
+++ /dev/null
-<html>
- <head>
- <title>First post</title>
- <link href="styles.css" rel="stylesheet" type="text/css" />
- </head>
- <body><h1>First post</h1>
-
-<p>This is my first post</p>
-</body>
-</html>
+++ /dev/null
-<html>
- <head>
- <title>Second post</title>
- <link href="styles.css" rel="stylesheet" type="text/css" />
- </head>
- <body><h1>Second post</h1>
-
-<p>This is my second post</p>
-</body>
-</html>
+++ /dev/null
-html{margin:0;padding:0;box-sizing:border-box;}body{font-size:16pt;}
\ No newline at end of file
+++ /dev/null
-html
- head
- title #{title}
- link[href="styles.css"][rel="stylesheet"][type="text/css"]
- body
- #{unescaped(content)}
+++ /dev/null
-title: About myself
-date: 28-08-2015
----
-
-# {{title}}
-
-Hi all. This is a brief description of who I am.
+++ /dev/null
-html
- head
- title My blog
- link[href="styles.css"][rel="stylesheet"][type="text/css"]
- body
- p Here goes list of posts
- ul
- li
- a[href="/posts/hello.html"] First post
- li
- a[href="/posts/update.html"] Second post
-
+++ /dev/null
-title: First post
-date: 28-08-2015
----
-
-# {{title}}
-
-This is my first post
-
+++ /dev/null
-title: Second post
-date: 29-08-2015
----
-
-# {{title}}
-
-This is my second post
-
+++ /dev/null
-html
- margin: 0
- padding: 0
- box-sizing: border-box
-
-body
- font-size: 16pt
+++ /dev/null
-<html>
- <body>
- <h1>Hello</h1>
- </body>
-</html>
+++ /dev/null
-<html>
- <body>
- <h1>{{ printf Hello }}</h1>
- </body>
-</html>
+++ /dev/null
-<html>
- <body>
- <p>Hello world</p>
- </body>
-</html>
+++ /dev/null
-body{font:100% Helvetica, sans-serif;color:blue;}
\ No newline at end of file
+++ /dev/null
-html
- body
- p Hello world
+++ /dev/null
-$base-font: Helvetica, sans-serif
-$main-color: blue
-
-body
- font: 100% $base-font
- color: $main-color
+++ /dev/null
-#!/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
-package main
+package aya
import (
"fmt"
+++ /dev/null
-.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 <file>
-.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 <file>
-.Ar <var1> <var2> ...
-.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