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
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
|
@ -25,28 +22,14 @@ type Task struct {
|
|||
InputExt string `toml:"input_ext"` // input file extension
|
||||
OutputExt string `toml:"output_ext"` // output file extension
|
||||
TemplateExt string `toml:"template_ext"` // template file extension
|
||||
PreProcess string `toml:"preprocess"` // preprocess command
|
||||
PostProcess string `toml:"postprocess"` // postprocess command
|
||||
StaticDir string `toml:"static_dir"` // static file directory
|
||||
OutputDir string `toml:"output_dir"` // output directory
|
||||
}
|
||||
|
||||
func (t Task) Format(p *Page) (string, []byte) {
|
||||
path := path.Join(p.Path, "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)
|
||||
func (t Task) OutputPath(pagePath string) string {
|
||||
return path.Join(pagePath, "index"+t.OutputExt)
|
||||
}
|
||||
|
||||
// LoadConfig loads the configuration from the provided path.
|
||||
|
|
123
dir.go
123
dir.go
|
@ -2,8 +2,11 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
pathpkg "path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
@ -19,10 +22,6 @@ type Dir struct {
|
|||
Dirs []*Dir // Subdirectories.
|
||||
index *Page // The index page.
|
||||
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.
|
||||
|
@ -37,8 +36,12 @@ func NewDir(path string) *Dir {
|
|||
}
|
||||
}
|
||||
|
||||
// read reads from a directory and indexes the files and directories within it.
|
||||
func (d *Dir) read(srcDir string, path string) error {
|
||||
// Read reads from a directory and indexes the files and directories within it.
|
||||
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))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -53,51 +56,51 @@ func (d *Dir) read(srcDir string, path string) error {
|
|||
if entry.IsDir() {
|
||||
// Gather directory data
|
||||
dir := NewDir(path)
|
||||
dir.inputExt = d.inputExt
|
||||
dir.outputExt = d.outputExt
|
||||
dir.templateExt = d.templateExt
|
||||
if err := dir.read(srcDir, path); err != nil {
|
||||
if err := dir.read(srcDir, path, task); err != nil {
|
||||
return err
|
||||
}
|
||||
d.Dirs = append(d.Dirs, dir)
|
||||
} else {
|
||||
} else if ext := pathpkg.Ext(name); ext == task.InputExt {
|
||||
srcPath := pathpkg.Join(srcDir, path)
|
||||
content, err := ioutil.ReadFile(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ext := pathpkg.Ext(name); ext == d.inputExt {
|
||||
// Gather page data
|
||||
if strings.TrimSuffix(name, ext) == "index" {
|
||||
d.index = NewPage(d.Path, content)
|
||||
d.Title = d.index.Title
|
||||
d.Content = d.index.Content
|
||||
} else {
|
||||
d.Pages = append(d.Pages, NewPage(path, content))
|
||||
}
|
||||
|
||||
if cmd := task.PreProcess; cmd != "" {
|
||||
content = RunProcessCmd(cmd, bytes.NewReader(content))
|
||||
}
|
||||
|
||||
// Gather page data
|
||||
if strings.TrimSuffix(name, ext) == "index" {
|
||||
d.index = NewPage(d.Path, content)
|
||||
d.Title = d.index.Title
|
||||
d.Content = d.index.Content
|
||||
} else {
|
||||
d.Pages = append(d.Pages, NewPage(path, content))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// manipulate processes and manipulates the directory's contents.
|
||||
func (d *Dir) manipulate(cfg *Config) error {
|
||||
if d.templateExt != "" {
|
||||
// Process processes the directory's contents.
|
||||
func (d *Dir) Process(cfg *Config, task *Task) error {
|
||||
if task.TemplateExt != "" {
|
||||
// Create index
|
||||
if d.index != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
d.index.Content = b.String()
|
||||
}
|
||||
|
||||
// Manipulate pages
|
||||
// Process pages
|
||||
for i := range d.Pages {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -129,22 +132,17 @@ func (d *Dir) manipulate(cfg *Config) error {
|
|||
d.feed = b.Bytes()
|
||||
}
|
||||
|
||||
// Manipulate subdirectories
|
||||
// Process subdirectories
|
||||
for _, d := range d.Dirs {
|
||||
if err := d.manipulate(cfg); err != nil {
|
||||
if err := d.Process(cfg, task); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Format represents an output format.
|
||||
type Format interface {
|
||||
Format(*Page) (path string, content []byte)
|
||||
}
|
||||
|
||||
// write writes the Dir to the provided destination path.
|
||||
func (d *Dir) write(dstDir string, format Format) error {
|
||||
// Write writes the directory's contents to the provided destination path.
|
||||
func (d *Dir) Write(dstDir string, task *Task) error {
|
||||
// Create the directory
|
||||
dirPath := pathpkg.Join(dstDir, d.Path)
|
||||
if err := os.MkdirAll(dirPath, 0755); err != nil {
|
||||
|
@ -152,31 +150,23 @@ func (d *Dir) write(dstDir string, format Format) error {
|
|||
}
|
||||
|
||||
// Write pages
|
||||
for _, page := range d.Pages {
|
||||
path, content := format.Format(page)
|
||||
dstPath := pathpkg.Join(dstDir, path)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// Write the index file
|
||||
pages := d.Pages
|
||||
if d.index != nil {
|
||||
path, content := format.Format(d.index)
|
||||
pages = append(pages, d.index)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
dstPath := pathpkg.Join(dstDir, path)
|
||||
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 {
|
||||
if err := os.WriteFile(dstPath, content, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -186,18 +176,14 @@ func (d *Dir) write(dstDir string, format Format) error {
|
|||
const path = "atom.xml"
|
||||
dstPath := pathpkg.Join(dstDir, path)
|
||||
os.MkdirAll(dstDir, 0755)
|
||||
f, err := os.Create(dstPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(d.feed); err != nil {
|
||||
if err := os.WriteFile(dstPath, d.feed, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Write subdirectories
|
||||
for _, dir := range d.Dirs {
|
||||
dir.write(dstDir, format)
|
||||
dir.Write(dstDir, task)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -212,3 +198,16 @@ func (d *Dir) 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 {
|
||||
// Load content
|
||||
// Read content
|
||||
dir := NewDir("")
|
||||
dir.inputExt = task.InputExt
|
||||
dir.outputExt = task.OutputExt
|
||||
dir.templateExt = task.TemplateExt
|
||||
if err := dir.read("content", ""); err != nil {
|
||||
if err := dir.Read("content", task); err != nil {
|
||||
return err
|
||||
}
|
||||
dir.sort()
|
||||
// Manipulate content
|
||||
if err := dir.manipulate(cfg); err != nil {
|
||||
// Process content
|
||||
if err := dir.Process(cfg, task); err != nil {
|
||||
return err
|
||||
}
|
||||
// Write content
|
||||
if err := dir.write(task.OutputDir, task); err != nil {
|
||||
if err := dir.Write(task.OutputDir, task); err != nil {
|
||||
return err
|
||||
}
|
||||
// Copy static files
|
||||
|
|
Loading…
Reference in a new issue