Compare commits

..

2 Commits

Author SHA1 Message Date
e24e892773 Revert "Change File to interface"
This reverts commit 2f95fdba2d.
2024-03-03 18:09:21 -08:00
9ba1c7cfeb Revert "Make Context be an interface"
This reverts commit ab0c1c53d2.
2024-03-03 17:46:38 -08:00
31 changed files with 264 additions and 178 deletions

View File

@ -15,7 +15,7 @@ type cache struct {
baseDir string
}
func (self *cache) retrieveFile(context *contextImpl, outputPath string, inputFiles []File) (File, error) {
func (self *cache) retrieveFile(context *Context, outputPath string, inputFiles []*File) (*File, error) {
cachePath, err := self.buildCachePath(context, outputPath, inputFiles)
if err != nil {
return nil, err
@ -33,7 +33,7 @@ func (self *cache) retrieveFile(context *contextImpl, outputPath string, inputFi
return outputFile, nil
}
func (self *cache) storeFile(context *contextImpl, outputFile File, inputFiles []File) error {
func (self *cache) storeFile(context *Context, outputFile *File, inputFiles []*File) error {
cachePath, err := self.buildCachePath(context, outputFile.Path(), inputFiles)
if err != nil {
return err
@ -69,7 +69,7 @@ func (self *cache) storeFile(context *contextImpl, outputFile File, inputFiles [
return nil
}
func (self *cache) buildCachePath(context *contextImpl, outputPath string, inputFiles []File) (string, error) {
func (self *cache) buildCachePath(context *Context, outputPath string, inputFiles []*File) (string, error) {
hasher := crc32.NewIEEE()
hasher.Write([]byte(outputPath))

View File

@ -13,34 +13,7 @@ import (
// Context corresponds to the current link in the chain and provides methods
// that enable plugins to inject new files into the chain.
type Context interface {
// CreateFileFrom data creates a new file instance from the provided data buffer.
CreateFileFromReader(sourcePath string, reader io.Reader) (File, error)
// CreateFileFromAsset creates a new file instance from the provided file path.
CreateFileFromAsset(sourcePath, dataPath string) (File, error)
// DispatchFile causes the file to get passed to the next link in the chain.
DispatchFile(file File)
// DispatchAndCacheFile caches the file data (excluding the metadata), taking
// dependencies on any input files that are needed to generate it, and then
// passes it to the next link in the chain.
DispatchAndCacheFile(outputFile File, inputFiles ...File)
// RetrieveCachedFile looks up file data (excluding the metadata), given an
// output path and any input files that are needed to generate it. The function
// will return nil if the desired file is not found in the cache.
RetrieveCachedFile(outputPath string, inputFiles ...File) File
// Specify internal filter(s) that exclude files from being processed.
Filter(filters ...Filter) Context
// Specify the maximum number of threads used for processing.
Threads(threads int) Context
}
type contextImpl struct {
type Context struct {
goldsmith *Goldsmith
plugin Plugin
@ -51,33 +24,31 @@ type contextImpl struct {
threads int
index int
filesIn chan File
filesOut chan File
filesIn chan *File
filesOut chan *File
}
// CreateFileFrom data creates a new file instance from the provided data buffer.
func (self *contextImpl) CreateFileFromReader(sourcePath string, reader io.Reader) (File, error) {
func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (*File, error) {
data, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
cf := &contextFile{
rawFile{
file := &File{
relPath: sourcePath,
props: make(map[string]FileProp),
props: make(FileProps),
modTime: time.Now(),
size: int64(len(data)),
reader: bytes.NewReader(data),
},
self.index,
index: self.index,
}
return cf, nil
return file, nil
}
// CreateFileFromAsset creates a new file instance from the provided file path.
func (self *contextImpl) CreateFileFromAsset(sourcePath, dataPath string) (File, error) {
func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, error) {
if filepath.IsAbs(sourcePath) {
return nil, errors.New("source paths must be relative")
}
@ -94,29 +65,27 @@ func (self *contextImpl) CreateFileFromAsset(sourcePath, dataPath string) (File,
return nil, errors.New("assets must be files")
}
cf := &contextFile{
rawFile{
file := &File{
relPath: sourcePath,
props: make(map[string]FileProp),
props: make(FileProps),
modTime: info.ModTime(),
size: info.Size(),
dataPath: dataPath,
},
self.index,
index: self.index,
}
return cf, nil
return file, nil
}
// DispatchFile causes the file to get passed to the next link in the chain.
func (self *contextImpl) DispatchFile(file File) {
func (self *Context) DispatchFile(file *File) {
self.filesOut <- file
}
// DispatchAndCacheFile caches the file data (excluding the metadata), taking
// dependencies on any input files that are needed to generate it, and then
// passes it to the next link in the chain.
func (self *contextImpl) DispatchAndCacheFile(outputFile File, inputFiles ...File) {
func (self *Context) DispatchAndCacheFile(outputFile *File, inputFiles ...*File) {
if self.goldsmith.state.cache != nil {
self.goldsmith.state.cache.storeFile(self, outputFile, inputFiles)
}
@ -127,8 +96,8 @@ func (self *contextImpl) DispatchAndCacheFile(outputFile File, inputFiles ...Fil
// RetrieveCachedFile looks up file data (excluding the metadata), given an
// output path and any input files that are needed to generate it. The function
// will return nil if the desired file is not found in the cache.
func (self *contextImpl) RetrieveCachedFile(outputPath string, inputFiles ...File) File {
var outputFile File
func (self *Context) RetrieveCachedFile(outputPath string, inputFiles ...*File) *File {
var outputFile *File
if self.goldsmith.state.cache != nil {
outputFile, _ = self.goldsmith.state.cache.retrieveFile(self, outputPath, inputFiles)
}
@ -137,7 +106,7 @@ func (self *contextImpl) RetrieveCachedFile(outputPath string, inputFiles ...Fil
}
// Specify internal filter(s) that exclude files from being processed.
func (self *contextImpl) Filter(filters ...Filter) Context {
func (self *Context) Filter(filters ...Filter) *Context {
for _, filter := range filters {
self.filtersInt.push(filter, self.index)
}
@ -146,12 +115,12 @@ func (self *contextImpl) Filter(filters ...Filter) Context {
}
// Specify the maximum number of threads used for processing.
func (self *contextImpl) Threads(threads int) Context {
func (self *Context) Threads(threads int) *Context {
self.threads = threads
return self
}
func (self *contextImpl) step() {
func (self *Context) step() {
defer close(self.filesOut)
if initializer, ok := self.plugin.(Initializer); ok {

View File

@ -9,22 +9,22 @@ type Plugin interface {
// Initializer is used to optionally initialize a plugin and to specify a
// filter to be used for determining which files will be processed.
type Initializer interface {
Initialize(context Context) error
Initialize(context *Context) error
}
// Processor allows for optional processing of files passing through a plugin.
type Processor interface {
Process(context Context, file File) error
Process(context *Context, file *File) error
}
// Finalizer allows for optional finalization of a plugin after all files
// queued in the chain have passed through it.
type Finalizer interface {
Finalize(context Context) error
Finalize(context *Context) error
}
// Filter is used to determine which files should continue in the chain.
type Filter interface {
Name() string
Accept(file File) bool
Accept(file *File) bool
}

159
file.go
View File

@ -1,7 +1,11 @@
package goldsmith
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"time"
)
@ -11,26 +15,141 @@ type (
)
// File represents in-memory or on-disk files in a chain.
type File interface {
Path() string
Dir() string
Name() string
Ext() string
Rename(path string) error
type File struct {
relPath string
props FileProps
modTime time.Time
size int64
Size() int64
ModTime() time.Time
dataPath string
reader *bytes.Reader
Read(data []byte) (int, error)
WriteTo(writer io.Writer) (int64, error)
Seek(offset int64, whence int) (int64, error)
SetProp(name string, value FileProp)
Prop(name string) (FileProp, bool)
PropOrDef(name string, valueDef FileProp) FileProp
Props() FileProps
CopyProps(file File)
RemoveProp(name string)
GoString() string
index int
}
// Rename modifies the file path relative to the source directory.
func (self *File) Rename(path string) error {
if filepath.IsAbs(path) {
return fmt.Errorf("unexpected absolute path: %s", path)
}
self.relPath = path
return nil
}
// Path returns the file path relative to the source directory.
func (self *File) Path() string {
return filepath.ToSlash(self.relPath)
}
// Dir returns the containing directory of the file.
func (self *File) Dir() string {
return filepath.ToSlash(filepath.Dir(self.relPath))
}
// Name returns the base name of the file.
func (self *File) Name() string {
return filepath.Base(self.relPath)
}
// Ext returns the extension of the file.
func (self *File) Ext() string {
return filepath.Ext(self.relPath)
}
// Size returns the file length in bytes.
func (self *File) Size() int64 {
return self.size
}
// ModTime returns the time of the file's last modification.
func (self *File) ModTime() time.Time {
return self.modTime
}
// Read reads file data into the provided buffer.
func (self *File) Read(data []byte) (int, error) {
if err := self.load(); err != nil {
return 0, err
}
return self.reader.Read(data)
}
// Write writes file data into the provided writer.
func (self *File) WriteTo(writer io.Writer) (int64, error) {
if err := self.load(); err != nil {
return 0, err
}
return self.reader.WriteTo(writer)
}
// Seek updates the file pointer to the desired position.
func (self *File) Seek(offset int64, whence int) (int64, error) {
if self.reader == nil && offset == 0 && (whence == io.SeekStart || whence == io.SeekCurrent) {
return 0, nil
}
if err := self.load(); err != nil {
return 0, err
}
return self.reader.Seek(offset, whence)
}
// GoString returns value for string formatting.
func (self *File) GoString() string {
return self.relPath
}
// RemoveProp deletes the metadata property for the provided name.
func (self *File) RemoveProp(name string) {
delete(self.props, name)
}
// SetProp updates the metadata property for the provided name.
func (self *File) SetProp(name string, value FileProp) {
self.props[name] = value
}
// Prop returns the metadata property for the provided name.
func (self *File) Prop(name string) (FileProp, bool) {
value, ok := self.props[name]
return value, ok
}
// PropOrDef returns the metadata property for the provided name or the default.
func (self *File) PropOrDef(name string, valueDef FileProp) FileProp {
if value, ok := self.Prop(name); ok {
return value
}
return valueDef
}
// Props returns all of the metadata properties.
func (self *File) Props() FileProps {
return self.props
}
// CopyProps copies all metadata properties from the provided file.
func (self *File) CopyProps(file *File) {
for key, value := range file.props {
self.props[key] = value
}
}
func (self *File) load() error {
if self.reader != nil {
return nil
}
data, err := os.ReadFile(self.dataPath)
if err != nil {
return err
}
self.reader = bytes.NewReader(data)
return nil
}

View File

@ -16,13 +16,13 @@ func (*fileExporter) Name() string {
return "exporter"
}
func (self *fileExporter) Initialize(context Context) error {
func (self *fileExporter) Initialize(context *Context) error {
self.tokens = make(map[string]bool)
context.Threads(1)
return nil
}
func (self *fileExporter) Process(context Context, file File) error {
func (self *fileExporter) Process(context *Context, file *File) error {
slicePath := func(path string) string {
if filepath.IsAbs(path) {
var err error
@ -64,7 +64,7 @@ func (self *fileExporter) Process(context Context, file File) error {
return nil
}
func (self *fileExporter) Finalize(context Context) error {
func (self *fileExporter) Finalize(context *Context) error {
if !self.clean {
return nil
}

View File

@ -13,7 +13,7 @@ func (*fileImporter) Name() string {
return "importer"
}
func (self *fileImporter) Initialize(context Context) error {
func (self *fileImporter) Initialize(context *Context) error {
return filepath.Walk(self.sourceDir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil

View File

@ -7,11 +7,9 @@ type filterEntry struct {
type filterStack []filterEntry
func (self *filterStack) accept(file File) bool {
cf := file.(*contextFile)
func (self *filterStack) accept(file *File) bool {
for _, entry := range *self {
if entry.index >= cf.index && !entry.filter.Accept(file) {
if entry.index >= file.index && !entry.filter.Accept(file) {
return false
}
}

View File

@ -16,6 +16,6 @@ func (*Condition) Name() string {
return "condition"
}
func (self *Condition) Accept(file goldsmith.File) bool {
func (self *Condition) Accept(file *goldsmith.File) bool {
return self.accept
}

View File

@ -20,7 +20,7 @@ func (*operatorAnd) Name() string {
return "operator"
}
func (self *operatorAnd) Accept(file goldsmith.File) bool {
func (self *operatorAnd) Accept(file *goldsmith.File) bool {
for _, filter := range self.filters {
if !filter.Accept(file) {
return false
@ -42,7 +42,7 @@ func (*operatorNot) Name() string {
return "operator"
}
func (self *operatorNot) Accept(file goldsmith.File) bool {
func (self *operatorNot) Accept(file *goldsmith.File) bool {
return !self.filter.Accept(file)
}
@ -58,7 +58,7 @@ func (*operatorOr) Name() string {
return "operator"
}
func (self *operatorOr) Accept(file goldsmith.File) bool {
func (self *operatorOr) Accept(file *goldsmith.File) bool {
for _, filter := range self.filters {
if filter.Accept(file) {
return true

View File

@ -25,7 +25,7 @@ func (*Wildcard) Name() string {
return "wildcard"
}
func (self *Wildcard) Accept(file goldsmith.File) bool {
func (self *Wildcard) Accept(file *goldsmith.File) bool {
filePath := self.adjustCase(file.Path())
for _, wildcard := range self.wildcards {

View File

@ -7,7 +7,7 @@ import (
)
type chainState struct {
contexts []*contextImpl
contexts []*Context
cache *cache
filters filterStack
@ -44,12 +44,12 @@ func (self *Goldsmith) Clean(clean bool) *Goldsmith {
// Chain links a plugin instance into the chain.
func (self *Goldsmith) Chain(plugin Plugin) *Goldsmith {
context := &contextImpl{
context := &Context{
goldsmith: self,
plugin: plugin,
filtersExt: append(filterStack(nil), self.state.filters...),
index: self.state.index,
filesOut: make(chan File),
filesOut: make(chan *File),
}
if len(self.state.contexts) > 0 {
@ -94,7 +94,7 @@ func (self *Goldsmith) End(targetDir string) []error {
return errors
}
func (self *Goldsmith) fault(name string, file File, err error) {
func (self *Goldsmith) fault(name string, file *File, err error) {
self.state.mutex.Lock()
defer self.state.mutex.Unlock()

View File

@ -45,12 +45,12 @@ func (*Absolute) Name() string {
return "absolute"
}
func (*Absolute) Initialize(context goldsmith.Context) error {
func (*Absolute) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Absolute) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Absolute) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile)

View File

@ -19,7 +19,7 @@ type Crumb struct {
// Node represents information about a specific file in the site's structure.
type Node struct {
File goldsmith.File
File *goldsmith.File
Parent *Node
Children []*Node
@ -70,12 +70,12 @@ func (*Breadcrumbs) Name() string {
return "breadcrumbs"
}
func (*Breadcrumbs) Initialize(context goldsmith.Context) error {
func (*Breadcrumbs) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Breadcrumbs) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Breadcrumbs) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
var parentNameStr string
if parentName, ok := inputFile.Prop(self.parentKey); ok {
parentNameStr, _ = parentName.(string)
@ -103,7 +103,7 @@ func (self *Breadcrumbs) Process(context goldsmith.Context, inputFile goldsmith.
return nil
}
func (self *Breadcrumbs) Finalize(context goldsmith.Context) error {
func (self *Breadcrumbs) Finalize(context *goldsmith.Context) error {
for _, node := range self.allNodes {
if len(node.parentName) == 0 {
continue

View File

@ -15,7 +15,7 @@ import (
)
// A Comparer callback function is used to sort files within a collection group.
type Comparer func(i, j goldsmith.File) (less bool)
type Comparer func(i, j *goldsmith.File) (less bool)
// Collection chainable plugin context.
type Collection struct {
@ -23,8 +23,8 @@ type Collection struct {
groupsKey string
comparer Comparer
groups map[string][]goldsmith.File
files []goldsmith.File
groups map[string][]*goldsmith.File
files []*goldsmith.File
mutex sync.Mutex
}
@ -33,7 +33,7 @@ func New() *Collection {
return &Collection{
collectionKey: "Collection",
groupsKey: "Groups",
groups: make(map[string][]goldsmith.File),
groups: make(map[string][]*goldsmith.File),
}
}
@ -61,12 +61,12 @@ func (*Collection) Name() string {
return "collection"
}
func (*Collection) Initialize(context goldsmith.Context) error {
func (*Collection) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Collection) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Collection) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
self.mutex.Lock()
defer func() {
inputFile.SetProp(self.groupsKey, self.groups)
@ -96,7 +96,7 @@ func (self *Collection) Process(context goldsmith.Context, inputFile goldsmith.F
return nil
}
func (self *Collection) Finalize(context goldsmith.Context) error {
func (self *Collection) Finalize(context *goldsmith.Context) error {
for _, files := range self.groups {
fg := &fileSorter{files, self.comparer}
sort.Sort(fg)
@ -110,7 +110,7 @@ func (self *Collection) Finalize(context goldsmith.Context) error {
}
type fileSorter struct {
files []goldsmith.File
files []*goldsmith.File
comparer Comparer
}

View File

@ -14,12 +14,12 @@ import (
)
// Processor callback function to modify documents.
type Processor func(goldsmith.File, *goquery.Document) error
type Processor func(*goldsmith.File, *goquery.Document) error
// Document plugin context.
type Document struct {
callback Processor
files []goldsmith.File
files []*goldsmith.File
mutex sync.Mutex
}
@ -32,12 +32,12 @@ func (*Document) Name() string {
return "document"
}
func (*Document) Initialize(context goldsmith.Context) error {
func (*Document) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Document) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Document) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
doc, err := goquery.NewDocumentFromReader(inputFile)
if err != nil {
return err
@ -61,7 +61,7 @@ func (self *Document) Process(context goldsmith.Context, inputFile goldsmith.Fil
return nil
}
func (self *Document) Finalize(context goldsmith.Context) error {
func (self *Document) Finalize(context *goldsmith.Context) error {
for _, file := range self.files {
context.DispatchFile(file)
}

View File

@ -8,7 +8,7 @@ import (
"github.com/PuerkitoBio/goquery"
)
func process(file goldsmith.File, doc *goquery.Document) error {
func process(file *goldsmith.File, doc *goquery.Document) error {
doc.Find("h1").SetAttr("style", "color: red;")
return nil
}

View File

@ -53,7 +53,7 @@ func (*Forward) Name() string {
return "forward"
}
func (self *Forward) Initialize(context goldsmith.Context) error {
func (self *Forward) Initialize(context *goldsmith.Context) error {
for sourcePath, targetPath := range self.pathMap {
sourceFile, err := context.CreateFileFromReader(sourcePath, bytes.NewReader(nil))
if err != nil {

View File

@ -66,12 +66,12 @@ func (*FrontMatter) Name() string {
return "frontmatter"
}
func (*FrontMatter) Initialize(context goldsmith.Context) error {
func (*FrontMatter) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.md", "**/*.markdown", "**/*.rst", "**/*.txt", "**/*.html", "**/*.htm"))
return nil
}
func (*FrontMatter) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (*FrontMatter) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
meta, body, err := parse(inputFile)
if err != nil {
return err

View File

@ -18,7 +18,7 @@ type Entry struct {
Name string
Path string
IsDir bool
File goldsmith.File
File *goldsmith.File
}
// Index chainable plugin context.
@ -60,7 +60,7 @@ func (*Index) Name() string {
return "index"
}
func (self *Index) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Index) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
self.mutex.Lock()
defer self.mutex.Unlock()
@ -105,7 +105,7 @@ func (self *Index) Process(context goldsmith.Context, inputFile goldsmith.File)
return nil
}
func (self *Index) Finalize(context goldsmith.Context) error {
func (self *Index) Finalize(context *goldsmith.Context) error {
for name, list := range self.dirLists {
sort.Sort(list.entries)
@ -131,7 +131,7 @@ func (self *Index) Finalize(context goldsmith.Context) error {
type directory struct {
entries entriesByName
indexFile goldsmith.File
indexFile *goldsmith.File
}
type entriesByName []Entry

View File

@ -20,8 +20,8 @@ type Layout struct {
defaultLayout *string
helpers template.FuncMap
inputFiles []goldsmith.File
templateFiles []goldsmith.File
inputFiles []*goldsmith.File
templateFiles []*goldsmith.File
mutex sync.Mutex
template *template.Template
@ -64,13 +64,13 @@ func (*Layout) Name() string {
return "layout"
}
func (self *Layout) Initialize(context goldsmith.Context) error {
func (self *Layout) Initialize(context *goldsmith.Context) error {
self.template = template.New("").Funcs(self.helpers)
context.Filter(wildcard.New("**/*.html", "**/*.htm", "**/*.tmpl", "**/*.gohtml"))
return nil
}
func (self *Layout) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Layout) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
self.mutex.Lock()
defer self.mutex.Unlock()
@ -94,7 +94,7 @@ func (self *Layout) Process(context goldsmith.Context, inputFile goldsmith.File)
return nil
}
func (self *Layout) Finalize(context goldsmith.Context) error {
func (self *Layout) Finalize(context *goldsmith.Context) error {
for _, templateFile := range self.templateFiles {
var buff bytes.Buffer
if _, err := templateFile.WriteTo(&buff); err != nil {
@ -128,7 +128,7 @@ func (self *Layout) Finalize(context goldsmith.Context) error {
return nil
}
func (self *Layout) getFileLayout(file goldsmith.File) (string, bool) {
func (self *Layout) getFileLayout(file *goldsmith.File) (string, bool) {
if name, ok := file.Props()[self.layoutKey].(string); ok {
return name, true
}

View File

@ -31,13 +31,13 @@ func (*LiveJs) Name() string {
return "livejs"
}
func (self *LiveJs) Initialize(context goldsmith.Context) error {
func (self *LiveJs) Initialize(context *goldsmith.Context) error {
self.html = fmt.Sprintf("\n<!-- begin livejs code -->\n<script>\n%s\n</script>\n<!-- end livejs code -->\n", livejs)
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *LiveJs) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *LiveJs) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile)

View File

@ -42,12 +42,12 @@ func (*Markdown) Name() string {
return "markdown"
}
func (self *Markdown) Initialize(context goldsmith.Context) error {
func (self *Markdown) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.md", "**/*.markdown"))
return nil
}
func (self *Markdown) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Markdown) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
outputPath := strings.TrimSuffix(inputFile.Path(), path.Ext(inputFile.Path())) + ".html"
if outputFile := context.RetrieveCachedFile(outputPath, inputFile); outputFile != nil {
outputFile.CopyProps(inputFile)

View File

@ -32,12 +32,12 @@ func (*Minify) Name() string {
return "minify"
}
func (*Minify) Initialize(context goldsmith.Context) error {
func (*Minify) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.css", "**/*.html", "**/*.htm", "**/*.js", "**/*.svg", "**/*.json", "**/*.xml"))
return nil
}
func (*Minify) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (*Minify) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile)

View File

@ -22,13 +22,13 @@ import (
type Namer func(path string, index int) string
// Lister callback function is used to return a metadata slice which should be paged across several files.
type Lister func(file goldsmith.File) interface{}
type Lister func(file *goldsmith.File) interface{}
// Page represents information about a given metadata segment.
type Page struct {
Index int
Items interface{}
File goldsmith.File
File *goldsmith.File
Next *Page
Prev *Page
@ -51,7 +51,7 @@ type Pager struct {
inheritedKeys []string
itemsPerPage int
files []goldsmith.File
files []*goldsmith.File
mutex sync.Mutex
}
@ -109,12 +109,12 @@ func (*Pager) Name() string {
return "pager"
}
func (*Pager) Initialize(context goldsmith.Context) error {
func (*Pager) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Pager) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Pager) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
self.mutex.Lock()
defer self.mutex.Unlock()
@ -200,7 +200,7 @@ func (self *Pager) Process(context goldsmith.Context, inputFile goldsmith.File)
return nil
}
func (self *Pager) Finalize(ctx goldsmith.Context) error {
func (self *Pager) Finalize(ctx *goldsmith.Context) error {
for _, f := range self.files {
ctx.DispatchFile(f)
}
@ -208,7 +208,7 @@ func (self *Pager) Finalize(ctx goldsmith.Context) error {
return nil
}
func (self *Pager) isEnabledForFile(file goldsmith.File) (bool, error) {
func (self *Pager) isEnabledForFile(file *goldsmith.File) (bool, error) {
enableRaw, ok := file.Prop(self.enableKey)
if !ok {
return false, nil

View File

@ -11,9 +11,9 @@ import (
)
func Test(self *testing.T) {
lister := func(file goldsmith.File) interface{} {
lister := func(file *goldsmith.File) interface{} {
if groupsRaw, ok := file.Prop("Groups"); ok {
if groups, ok := groupsRaw.(map[string][]goldsmith.File); ok {
if groups, ok := groupsRaw.(map[string][]*goldsmith.File); ok {
if group, ok := groups["group"]; ok {
return group
}

View File

@ -19,14 +19,14 @@ type rule struct {
type ruleApply struct {
rule
Props map[string]goldsmith.FileProp
Props goldsmith.FileProps
}
type ruleDrop struct {
rule
}
func (self *rule) accept(inputFile goldsmith.File) bool {
func (self *rule) accept(inputFile *goldsmith.File) bool {
if !wildcard.New(filepath.Join(self.baseDir, "**")).Accept(inputFile) {
return false
}
@ -52,7 +52,7 @@ func (self *rule) accept(inputFile goldsmith.File) bool {
return operator.Not(wildcard.New(rejectPaths...)).Accept(inputFile)
}
func (self *ruleApply) apply(inputFile goldsmith.File) {
func (self *ruleApply) apply(inputFile *goldsmith.File) {
if self.accept(inputFile) {
for name, value := range self.Props {
inputFile.SetProp(name, value)
@ -60,7 +60,7 @@ func (self *ruleApply) apply(inputFile goldsmith.File) {
}
}
func (self *ruleDrop) drop(inputFile goldsmith.File) bool {
func (self *ruleDrop) drop(inputFile *goldsmith.File) bool {
return self.accept(inputFile)
}
@ -69,7 +69,7 @@ type ruleSet struct {
Drop []*ruleDrop
}
func newRuleSet(inputFile goldsmith.File) (*ruleSet, error) {
func newRuleSet(inputFile *goldsmith.File) (*ruleSet, error) {
data, err := io.ReadAll(inputFile)
if err != nil {
return nil, err
@ -91,7 +91,7 @@ func newRuleSet(inputFile goldsmith.File) (*ruleSet, error) {
return &ruleSet, nil
}
func (self *ruleSet) process(inputFile goldsmith.File) bool {
func (self *ruleSet) process(inputFile *goldsmith.File) bool {
for _, rule := range self.Apply {
rule.apply(inputFile)
}
@ -110,7 +110,7 @@ type Rule struct {
filename string
ruleSets []*ruleSet
inputFiles []goldsmith.File
inputFiles []*goldsmith.File
mutex sync.Mutex
}
@ -128,7 +128,7 @@ func (*Rule) Name() string {
return "rule"
}
func (self *Rule) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Rule) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
if inputFile.Name() == self.filename {
ruleSet, err := newRuleSet(inputFile)
if err != nil {
@ -147,7 +147,7 @@ func (self *Rule) Process(context goldsmith.Context, inputFile goldsmith.File) e
return nil
}
func (self *Rule) Finalize(context goldsmith.Context) error {
func (self *Rule) Finalize(context *goldsmith.Context) error {
for _, inputFile := range self.inputFiles {
var block bool
for _, ruleSet := range self.ruleSets {

View File

@ -57,12 +57,12 @@ func (*Summary) Name() string {
return "summary"
}
func (*Summary) Initialize(context goldsmith.Context) error {
func (*Summary) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Summary) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Summary) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
doc, err := goquery.NewDocumentFromReader(inputFile)
if err != nil {
return err

View File

@ -120,7 +120,7 @@ func (self *Syndicate) WithFeed(name string, config FeedConfig) *Syndicate {
return self
}
func (self *Syndicate) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Syndicate) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
defer context.DispatchFile(inputFile)
getString := func(key string) string {
@ -214,7 +214,7 @@ func (self *Syndicate) Process(context goldsmith.Context, inputFile goldsmith.Fi
return nil
}
func (self *feed) output(context goldsmith.Context) error {
func (self *feed) output(context *goldsmith.Context) error {
feed := feeds.Feed{
Title: self.config.Title,
Link: &feeds.Link{Href: self.config.Url},
@ -310,7 +310,7 @@ func (self *feed) output(context goldsmith.Context) error {
return nil
}
func (self *Syndicate) Finalize(context goldsmith.Context) error {
func (self *Syndicate) Finalize(context *goldsmith.Context) error {
for _, feed := range self.feeds {
feed.output(context)
}

View File

@ -69,12 +69,12 @@ func (*Syntax) Name() string {
return "syntax"
}
func (*Syntax) Initialize(context goldsmith.Context) error {
func (*Syntax) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Syntax) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Syntax) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile)

View File

@ -18,7 +18,7 @@ import (
// TagInfo contains site-wide information about a particular tag.
type TagInfo struct {
TaggedFiles filesByPath
IndexFile goldsmith.File
IndexFile *goldsmith.File
SafeName string
RawName string
}
@ -44,7 +44,7 @@ type Tags struct {
infoByName tagInfoByName
infoByCount tagInfoByCount
files []goldsmith.File
files []*goldsmith.File
mutex sync.Mutex
}
@ -93,12 +93,12 @@ func (*Tags) Name() string {
return "tags"
}
func (*Tags) Initialize(context goldsmith.Context) error {
func (*Tags) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
return nil
}
func (self *Tags) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Tags) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
tagState := &TagState{
TagsByName: &self.infoByName,
TagsByCount: &self.infoByCount,
@ -158,7 +158,7 @@ func (self *Tags) Process(context goldsmith.Context, inputFile goldsmith.File) e
return nil
}
func (self *Tags) Finalize(context goldsmith.Context) error {
func (self *Tags) Finalize(context *goldsmith.Context) error {
for _, info := range self.info {
sort.Sort(info.TaggedFiles)
@ -185,8 +185,8 @@ func (self *Tags) Finalize(context goldsmith.Context) error {
return nil
}
func (self *Tags) buildPages(context goldsmith.Context) ([]goldsmith.File, error) {
var files []goldsmith.File
func (self *Tags) buildPages(context *goldsmith.Context) ([]*goldsmith.File, error) {
var files []*goldsmith.File
for tag, info := range self.info {
var err error
info.IndexFile, err = context.CreateFileFromReader(self.tagPagePath(tag), bytes.NewReader(nil))
@ -273,7 +273,7 @@ func (self tagInfoByName) Less(i, j int) bool {
return false
}
type filesByPath []goldsmith.File
type filesByPath []*goldsmith.File
func (self filesByPath) Len() int {
return len(self)

View File

@ -76,12 +76,12 @@ func (*Thumbnail) Name() string {
return "thumbnail"
}
func (*Thumbnail) Initialize(context goldsmith.Context) error {
func (*Thumbnail) Initialize(context *goldsmith.Context) error {
context.Filter(wildcard.New("**/*.jpg", "**/*.jpeg", "**/*.gif", "**/*.png"))
return nil
}
func (self *Thumbnail) Process(context goldsmith.Context, inputFile goldsmith.File) error {
func (self *Thumbnail) Process(context *goldsmith.Context, inputFile *goldsmith.File) error {
defer context.DispatchFile(inputFile)
thumbPath := self.namer(inputFile.Path(), self.size)
@ -104,7 +104,7 @@ func (self *Thumbnail) Process(context goldsmith.Context, inputFile goldsmith.Fi
return nil
}
func (self *Thumbnail) thumbnail(context goldsmith.Context, inputFile goldsmith.File, thumbPath string) (goldsmith.File, error) {
func (self *Thumbnail) thumbnail(context *goldsmith.Context, inputFile *goldsmith.File, thumbPath string) (*goldsmith.File, error) {
var thumbFormat imaging.Format
switch strings.ToLower(filepath.Ext(thumbPath)) {
case ".jpg", ".jpeg":