mirror of
https://git.sr.ht/~adnano/kiln
synced 2024-10-30 01:13:08 +00:00
Implement support for preprocess command
This commit is contained in:
parent
91d9dc09fa
commit
20efed1e9a
23
config.go
23
config.go
|
@ -1,11 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
@ -25,28 +22,14 @@ type Task struct {
|
||||||
InputExt string `toml:"input_ext"` // input file extension
|
InputExt string `toml:"input_ext"` // input file extension
|
||||||
OutputExt string `toml:"output_ext"` // output file extension
|
OutputExt string `toml:"output_ext"` // output file extension
|
||||||
TemplateExt string `toml:"template_ext"` // template file extension
|
TemplateExt string `toml:"template_ext"` // template file extension
|
||||||
|
PreProcess string `toml:"preprocess"` // preprocess command
|
||||||
PostProcess string `toml:"postprocess"` // postprocess command
|
PostProcess string `toml:"postprocess"` // postprocess command
|
||||||
StaticDir string `toml:"static_dir"` // static file directory
|
StaticDir string `toml:"static_dir"` // static file directory
|
||||||
OutputDir string `toml:"output_dir"` // output directory
|
OutputDir string `toml:"output_dir"` // output directory
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Task) Format(p *Page) (string, []byte) {
|
func (t Task) OutputPath(pagePath string) string {
|
||||||
path := path.Join(p.Path, "index"+t.OutputExt)
|
return path.Join(pagePath, "index"+t.OutputExt)
|
||||||
|
|
||||||
// Run a custom command.
|
|
||||||
if t.PostProcess != "" {
|
|
||||||
split := strings.Split(t.PostProcess, " ")
|
|
||||||
cmd := exec.Command(split[0], split[1:]...)
|
|
||||||
cmd.Stdin = strings.NewReader(p.Content)
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
output, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return path, output
|
|
||||||
}
|
|
||||||
|
|
||||||
return path, []byte(p.Content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfig loads the configuration from the provided path.
|
// LoadConfig loads the configuration from the provided path.
|
||||||
|
|
105
dir.go
105
dir.go
|
@ -2,8 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
pathpkg "path"
|
pathpkg "path"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -19,10 +22,6 @@ type Dir struct {
|
||||||
Dirs []*Dir // Subdirectories.
|
Dirs []*Dir // Subdirectories.
|
||||||
index *Page // The index page.
|
index *Page // The index page.
|
||||||
feed []byte // Atom feed.
|
feed []byte // Atom feed.
|
||||||
|
|
||||||
inputExt string // input file extension
|
|
||||||
outputExt string // output file extension
|
|
||||||
templateExt string // template file extension
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDir returns a new Dir with the given path.
|
// NewDir returns a new Dir with the given path.
|
||||||
|
@ -37,8 +36,12 @@ func NewDir(path string) *Dir {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read reads from a directory and indexes the files and directories within it.
|
// Read reads from a directory and indexes the files and directories within it.
|
||||||
func (d *Dir) read(srcDir string, path string) error {
|
func (d *Dir) Read(srcDir string, task *Task) error {
|
||||||
|
return d.read(srcDir, "", task)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dir) read(srcDir, path string, task *Task) error {
|
||||||
entries, err := ioutil.ReadDir(pathpkg.Join(srcDir, path))
|
entries, err := ioutil.ReadDir(pathpkg.Join(srcDir, path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -53,20 +56,21 @@ func (d *Dir) read(srcDir string, path string) error {
|
||||||
if entry.IsDir() {
|
if entry.IsDir() {
|
||||||
// Gather directory data
|
// Gather directory data
|
||||||
dir := NewDir(path)
|
dir := NewDir(path)
|
||||||
dir.inputExt = d.inputExt
|
if err := dir.read(srcDir, path, task); err != nil {
|
||||||
dir.outputExt = d.outputExt
|
|
||||||
dir.templateExt = d.templateExt
|
|
||||||
if err := dir.read(srcDir, path); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.Dirs = append(d.Dirs, dir)
|
d.Dirs = append(d.Dirs, dir)
|
||||||
} else {
|
} else if ext := pathpkg.Ext(name); ext == task.InputExt {
|
||||||
srcPath := pathpkg.Join(srcDir, path)
|
srcPath := pathpkg.Join(srcDir, path)
|
||||||
content, err := ioutil.ReadFile(srcPath)
|
content, err := ioutil.ReadFile(srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if ext := pathpkg.Ext(name); ext == d.inputExt {
|
|
||||||
|
if cmd := task.PreProcess; cmd != "" {
|
||||||
|
content = RunProcessCmd(cmd, bytes.NewReader(content))
|
||||||
|
}
|
||||||
|
|
||||||
// Gather page data
|
// Gather page data
|
||||||
if strings.TrimSuffix(name, ext) == "index" {
|
if strings.TrimSuffix(name, ext) == "index" {
|
||||||
d.index = NewPage(d.Path, content)
|
d.index = NewPage(d.Path, content)
|
||||||
|
@ -77,27 +81,26 @@ func (d *Dir) read(srcDir string, path string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// manipulate processes and manipulates the directory's contents.
|
// Process processes the directory's contents.
|
||||||
func (d *Dir) manipulate(cfg *Config) error {
|
func (d *Dir) Process(cfg *Config, task *Task) error {
|
||||||
if d.templateExt != "" {
|
if task.TemplateExt != "" {
|
||||||
// Create index
|
// Create index
|
||||||
if d.index != nil {
|
if d.index != nil {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
tmpl := cfg.Templates.FindTemplate(d.Path, "index"+d.templateExt)
|
tmpl := cfg.Templates.FindTemplate(d.Path, "index"+task.TemplateExt)
|
||||||
if err := tmpl.Execute(&b, d); err != nil {
|
if err := tmpl.Execute(&b, d); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.index.Content = b.String()
|
d.index.Content = b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manipulate pages
|
// Process pages
|
||||||
for i := range d.Pages {
|
for i := range d.Pages {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
tmpl := cfg.Templates.FindTemplate(d.Path, "page"+d.templateExt)
|
tmpl := cfg.Templates.FindTemplate(d.Path, "page"+task.TemplateExt)
|
||||||
if err := tmpl.Execute(&b, d.Pages[i]); err != nil {
|
if err := tmpl.Execute(&b, d.Pages[i]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -129,22 +132,17 @@ func (d *Dir) manipulate(cfg *Config) error {
|
||||||
d.feed = b.Bytes()
|
d.feed = b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manipulate subdirectories
|
// Process subdirectories
|
||||||
for _, d := range d.Dirs {
|
for _, d := range d.Dirs {
|
||||||
if err := d.manipulate(cfg); err != nil {
|
if err := d.Process(cfg, task); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format represents an output format.
|
// Write writes the directory's contents to the provided destination path.
|
||||||
type Format interface {
|
func (d *Dir) Write(dstDir string, task *Task) error {
|
||||||
Format(*Page) (path string, content []byte)
|
|
||||||
}
|
|
||||||
|
|
||||||
// write writes the Dir to the provided destination path.
|
|
||||||
func (d *Dir) write(dstDir string, format Format) error {
|
|
||||||
// Create the directory
|
// Create the directory
|
||||||
dirPath := pathpkg.Join(dstDir, d.Path)
|
dirPath := pathpkg.Join(dstDir, d.Path)
|
||||||
if err := os.MkdirAll(dirPath, 0755); err != nil {
|
if err := os.MkdirAll(dirPath, 0755); err != nil {
|
||||||
|
@ -152,31 +150,23 @@ func (d *Dir) write(dstDir string, format Format) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write pages
|
// Write pages
|
||||||
for _, page := range d.Pages {
|
pages := d.Pages
|
||||||
path, content := format.Format(page)
|
if d.index != nil {
|
||||||
dstPath := pathpkg.Join(dstDir, path)
|
pages = append(pages, d.index)
|
||||||
dir := pathpkg.Dir(dstPath)
|
|
||||||
os.MkdirAll(dir, 0755)
|
|
||||||
f, err := os.Create(dstPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := f.Write(content); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
for _, page := range pages {
|
||||||
|
path := task.OutputPath(page.Path)
|
||||||
|
var content []byte
|
||||||
|
if cmd := task.PostProcess; cmd != "" {
|
||||||
|
content = RunProcessCmd(cmd, strings.NewReader(page.Content))
|
||||||
|
} else {
|
||||||
|
content = []byte(page.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the index file
|
|
||||||
if d.index != nil {
|
|
||||||
path, content := format.Format(d.index)
|
|
||||||
dstPath := pathpkg.Join(dstDir, path)
|
dstPath := pathpkg.Join(dstDir, path)
|
||||||
dir := pathpkg.Dir(dstPath)
|
dir := pathpkg.Dir(dstPath)
|
||||||
os.MkdirAll(dir, 0755)
|
os.MkdirAll(dir, 0755)
|
||||||
f, err := os.Create(dstPath)
|
if err := os.WriteFile(dstPath, content, 0644); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := f.Write(content); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,18 +176,14 @@ func (d *Dir) write(dstDir string, format Format) error {
|
||||||
const path = "atom.xml"
|
const path = "atom.xml"
|
||||||
dstPath := pathpkg.Join(dstDir, path)
|
dstPath := pathpkg.Join(dstDir, path)
|
||||||
os.MkdirAll(dstDir, 0755)
|
os.MkdirAll(dstDir, 0755)
|
||||||
f, err := os.Create(dstPath)
|
if err := os.WriteFile(dstPath, d.feed, 0644); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := f.Write(d.feed); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write subdirectories
|
// Write subdirectories
|
||||||
for _, dir := range d.Dirs {
|
for _, dir := range d.Dirs {
|
||||||
dir.write(dstDir, format)
|
dir.Write(dstDir, task)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -212,3 +198,16 @@ func (d *Dir) sort() {
|
||||||
d.sort()
|
d.sort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunProcessCmd runs a process command.
|
||||||
|
func RunProcessCmd(command string, input io.Reader) []byte {
|
||||||
|
split := strings.Split(command, " ")
|
||||||
|
cmd := exec.Command(split[0], split[1:]...)
|
||||||
|
cmd.Stdin = input
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
output, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
13
main.go
13
main.go
|
@ -86,21 +86,18 @@ func runAll(cfg *Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTask(cfg *Config, task *Task) error {
|
func runTask(cfg *Config, task *Task) error {
|
||||||
// Load content
|
// Read content
|
||||||
dir := NewDir("")
|
dir := NewDir("")
|
||||||
dir.inputExt = task.InputExt
|
if err := dir.Read("content", task); err != nil {
|
||||||
dir.outputExt = task.OutputExt
|
|
||||||
dir.templateExt = task.TemplateExt
|
|
||||||
if err := dir.read("content", ""); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dir.sort()
|
dir.sort()
|
||||||
// Manipulate content
|
// Process content
|
||||||
if err := dir.manipulate(cfg); err != nil {
|
if err := dir.Process(cfg, task); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Write content
|
// Write content
|
||||||
if err := dir.write(task.OutputDir, task); err != nil {
|
if err := dir.Write(task.OutputDir, task); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Copy static files
|
// Copy static files
|
||||||
|
|
Loading…
Reference in a new issue