parent
9ba1c7cfeb
commit
e24e892773
6
cache.go
6
cache.go
@ -15,7 +15,7 @@ type cache struct {
|
|||||||
baseDir string
|
baseDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *cache) retrieveFile(context *Context, 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)
|
cachePath, err := self.buildCachePath(context, outputPath, inputFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -33,7 +33,7 @@ func (self *cache) retrieveFile(context *Context, outputPath string, inputFiles
|
|||||||
return outputFile, nil
|
return outputFile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *cache) storeFile(context *Context, outputFile File, inputFiles []File) error {
|
func (self *cache) storeFile(context *Context, outputFile *File, inputFiles []*File) error {
|
||||||
cachePath, err := self.buildCachePath(context, outputFile.Path(), inputFiles)
|
cachePath, err := self.buildCachePath(context, outputFile.Path(), inputFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -69,7 +69,7 @@ func (self *cache) storeFile(context *Context, outputFile File, inputFiles []Fil
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *cache) buildCachePath(context *Context, outputPath string, inputFiles []File) (string, error) {
|
func (self *cache) buildCachePath(context *Context, outputPath string, inputFiles []*File) (string, error) {
|
||||||
hasher := crc32.NewIEEE()
|
hasher := crc32.NewIEEE()
|
||||||
hasher.Write([]byte(outputPath))
|
hasher.Write([]byte(outputPath))
|
||||||
|
|
||||||
|
36
context.go
36
context.go
@ -24,33 +24,31 @@ type Context struct {
|
|||||||
threads int
|
threads int
|
||||||
index int
|
index int
|
||||||
|
|
||||||
filesIn chan File
|
filesIn chan *File
|
||||||
filesOut chan File
|
filesOut chan *File
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFileFrom data creates a new file instance from the provided data buffer.
|
// CreateFileFrom data creates a new file instance from the provided data buffer.
|
||||||
func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (File, error) {
|
func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (*File, error) {
|
||||||
data, err := io.ReadAll(reader)
|
data, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cf := &contextFile{
|
file := &File{
|
||||||
rawFile{
|
|
||||||
relPath: sourcePath,
|
relPath: sourcePath,
|
||||||
props: make(map[string]FileProp),
|
props: make(FileProps),
|
||||||
modTime: time.Now(),
|
modTime: time.Now(),
|
||||||
size: int64(len(data)),
|
size: int64(len(data)),
|
||||||
reader: bytes.NewReader(data),
|
reader: bytes.NewReader(data),
|
||||||
},
|
index: self.index,
|
||||||
self.index,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cf, nil
|
return file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFileFromAsset creates a new file instance from the provided file path.
|
// CreateFileFromAsset creates a new file instance from the provided file path.
|
||||||
func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (File, error) {
|
func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, error) {
|
||||||
if filepath.IsAbs(sourcePath) {
|
if filepath.IsAbs(sourcePath) {
|
||||||
return nil, errors.New("source paths must be relative")
|
return nil, errors.New("source paths must be relative")
|
||||||
}
|
}
|
||||||
@ -67,29 +65,27 @@ func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (File, err
|
|||||||
return nil, errors.New("assets must be files")
|
return nil, errors.New("assets must be files")
|
||||||
}
|
}
|
||||||
|
|
||||||
cf := &contextFile{
|
file := &File{
|
||||||
rawFile{
|
|
||||||
relPath: sourcePath,
|
relPath: sourcePath,
|
||||||
props: make(map[string]FileProp),
|
props: make(FileProps),
|
||||||
modTime: info.ModTime(),
|
modTime: info.ModTime(),
|
||||||
size: info.Size(),
|
size: info.Size(),
|
||||||
dataPath: dataPath,
|
dataPath: dataPath,
|
||||||
},
|
index: self.index,
|
||||||
self.index,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cf, nil
|
return file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DispatchFile causes the file to get passed to the next link in the chain.
|
// DispatchFile causes the file to get passed to the next link in the chain.
|
||||||
func (self *Context) DispatchFile(file File) {
|
func (self *Context) DispatchFile(file *File) {
|
||||||
self.filesOut <- file
|
self.filesOut <- file
|
||||||
}
|
}
|
||||||
|
|
||||||
// DispatchAndCacheFile caches the file data (excluding the metadata), taking
|
// DispatchAndCacheFile caches the file data (excluding the metadata), taking
|
||||||
// dependencies on any input files that are needed to generate it, and then
|
// dependencies on any input files that are needed to generate it, and then
|
||||||
// passes it to the next link in the chain.
|
// passes it to the next link in the chain.
|
||||||
func (self *Context) DispatchAndCacheFile(outputFile File, inputFiles ...File) {
|
func (self *Context) DispatchAndCacheFile(outputFile *File, inputFiles ...*File) {
|
||||||
if self.goldsmith.state.cache != nil {
|
if self.goldsmith.state.cache != nil {
|
||||||
self.goldsmith.state.cache.storeFile(self, outputFile, inputFiles)
|
self.goldsmith.state.cache.storeFile(self, outputFile, inputFiles)
|
||||||
}
|
}
|
||||||
@ -100,8 +96,8 @@ func (self *Context) DispatchAndCacheFile(outputFile File, inputFiles ...File) {
|
|||||||
// RetrieveCachedFile looks up file data (excluding the metadata), given an
|
// RetrieveCachedFile looks up file data (excluding the metadata), given an
|
||||||
// output path and any input files that are needed to generate it. The function
|
// 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.
|
// will return nil if the desired file is not found in the cache.
|
||||||
func (self *Context) RetrieveCachedFile(outputPath string, inputFiles ...File) File {
|
func (self *Context) RetrieveCachedFile(outputPath string, inputFiles ...*File) *File {
|
||||||
var outputFile File
|
var outputFile *File
|
||||||
if self.goldsmith.state.cache != nil {
|
if self.goldsmith.state.cache != nil {
|
||||||
outputFile, _ = self.goldsmith.state.cache.retrieveFile(self, outputPath, inputFiles)
|
outputFile, _ = self.goldsmith.state.cache.retrieveFile(self, outputPath, inputFiles)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ type Initializer interface {
|
|||||||
|
|
||||||
// Processor allows for optional processing of files passing through a plugin.
|
// Processor allows for optional processing of files passing through a plugin.
|
||||||
type Processor interface {
|
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
|
// Finalizer allows for optional finalization of a plugin after all files
|
||||||
@ -26,5 +26,5 @@ type Finalizer interface {
|
|||||||
// Filter is used to determine which files should continue in the chain.
|
// Filter is used to determine which files should continue in the chain.
|
||||||
type Filter interface {
|
type Filter interface {
|
||||||
Name() string
|
Name() string
|
||||||
Accept(file File) bool
|
Accept(file *File) bool
|
||||||
}
|
}
|
||||||
|
159
file.go
159
file.go
@ -1,7 +1,11 @@
|
|||||||
package goldsmith
|
package goldsmith
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -11,26 +15,141 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// File represents in-memory or on-disk files in a chain.
|
// File represents in-memory or on-disk files in a chain.
|
||||||
type File interface {
|
type File struct {
|
||||||
Path() string
|
relPath string
|
||||||
Dir() string
|
props FileProps
|
||||||
Name() string
|
modTime time.Time
|
||||||
Ext() string
|
size int64
|
||||||
Rename(path string) error
|
|
||||||
|
|
||||||
Size() int64
|
dataPath string
|
||||||
ModTime() time.Time
|
reader *bytes.Reader
|
||||||
|
|
||||||
Read(data []byte) (int, error)
|
index int
|
||||||
WriteTo(writer io.Writer) (int64, error)
|
}
|
||||||
Seek(offset int64, whence int) (int64, error)
|
|
||||||
|
// Rename modifies the file path relative to the source directory.
|
||||||
SetProp(name string, value FileProp)
|
func (self *File) Rename(path string) error {
|
||||||
Prop(name string) (FileProp, bool)
|
if filepath.IsAbs(path) {
|
||||||
PropOrDef(name string, valueDef FileProp) FileProp
|
return fmt.Errorf("unexpected absolute path: %s", path)
|
||||||
Props() FileProps
|
}
|
||||||
CopyProps(file File)
|
|
||||||
RemoveProp(name string)
|
self.relPath = path
|
||||||
|
return nil
|
||||||
GoString() string
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func (self *fileExporter) Initialize(context *Context) error {
|
|||||||
return nil
|
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 {
|
slicePath := func(path string) string {
|
||||||
if filepath.IsAbs(path) {
|
if filepath.IsAbs(path) {
|
||||||
var err error
|
var err error
|
||||||
|
@ -7,11 +7,9 @@ type filterEntry struct {
|
|||||||
|
|
||||||
type filterStack []filterEntry
|
type filterStack []filterEntry
|
||||||
|
|
||||||
func (self *filterStack) accept(file File) bool {
|
func (self *filterStack) accept(file *File) bool {
|
||||||
cf := file.(*contextFile)
|
|
||||||
|
|
||||||
for _, entry := range *self {
|
for _, entry := range *self {
|
||||||
if entry.index >= cf.index && !entry.filter.Accept(file) {
|
if entry.index >= file.index && !entry.filter.Accept(file) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ func (*Condition) Name() string {
|
|||||||
return "condition"
|
return "condition"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Condition) Accept(file goldsmith.File) bool {
|
func (self *Condition) Accept(file *goldsmith.File) bool {
|
||||||
return self.accept
|
return self.accept
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func (*operatorAnd) Name() string {
|
|||||||
return "operator"
|
return "operator"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *operatorAnd) Accept(file goldsmith.File) bool {
|
func (self *operatorAnd) Accept(file *goldsmith.File) bool {
|
||||||
for _, filter := range self.filters {
|
for _, filter := range self.filters {
|
||||||
if !filter.Accept(file) {
|
if !filter.Accept(file) {
|
||||||
return false
|
return false
|
||||||
@ -42,7 +42,7 @@ func (*operatorNot) Name() string {
|
|||||||
return "operator"
|
return "operator"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *operatorNot) Accept(file goldsmith.File) bool {
|
func (self *operatorNot) Accept(file *goldsmith.File) bool {
|
||||||
return !self.filter.Accept(file)
|
return !self.filter.Accept(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func (*operatorOr) Name() string {
|
|||||||
return "operator"
|
return "operator"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *operatorOr) Accept(file goldsmith.File) bool {
|
func (self *operatorOr) Accept(file *goldsmith.File) bool {
|
||||||
for _, filter := range self.filters {
|
for _, filter := range self.filters {
|
||||||
if filter.Accept(file) {
|
if filter.Accept(file) {
|
||||||
return true
|
return true
|
||||||
|
@ -25,7 +25,7 @@ func (*Wildcard) Name() string {
|
|||||||
return "wildcard"
|
return "wildcard"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Wildcard) Accept(file goldsmith.File) bool {
|
func (self *Wildcard) Accept(file *goldsmith.File) bool {
|
||||||
filePath := self.adjustCase(file.Path())
|
filePath := self.adjustCase(file.Path())
|
||||||
|
|
||||||
for _, wildcard := range self.wildcards {
|
for _, wildcard := range self.wildcards {
|
||||||
|
@ -49,7 +49,7 @@ func (self *Goldsmith) Chain(plugin Plugin) *Goldsmith {
|
|||||||
plugin: plugin,
|
plugin: plugin,
|
||||||
filtersExt: append(filterStack(nil), self.state.filters...),
|
filtersExt: append(filterStack(nil), self.state.filters...),
|
||||||
index: self.state.index,
|
index: self.state.index,
|
||||||
filesOut: make(chan File),
|
filesOut: make(chan *File),
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(self.state.contexts) > 0 {
|
if len(self.state.contexts) > 0 {
|
||||||
@ -94,7 +94,7 @@ func (self *Goldsmith) End(targetDir string) []error {
|
|||||||
return errors
|
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()
|
self.state.mutex.Lock()
|
||||||
defer self.state.mutex.Unlock()
|
defer self.state.mutex.Unlock()
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ func (*Absolute) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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 {
|
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
|
||||||
outputFile.CopyProps(inputFile)
|
outputFile.CopyProps(inputFile)
|
||||||
context.DispatchFile(outputFile)
|
context.DispatchFile(outputFile)
|
||||||
|
@ -19,7 +19,7 @@ type Crumb struct {
|
|||||||
|
|
||||||
// Node represents information about a specific file in the site's structure.
|
// Node represents information about a specific file in the site's structure.
|
||||||
type Node struct {
|
type Node struct {
|
||||||
File goldsmith.File
|
File *goldsmith.File
|
||||||
Parent *Node
|
Parent *Node
|
||||||
Children []*Node
|
Children []*Node
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ func (*Breadcrumbs) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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
|
var parentNameStr string
|
||||||
if parentName, ok := inputFile.Prop(self.parentKey); ok {
|
if parentName, ok := inputFile.Prop(self.parentKey); ok {
|
||||||
parentNameStr, _ = parentName.(string)
|
parentNameStr, _ = parentName.(string)
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// A Comparer callback function is used to sort files within a collection group.
|
// 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.
|
// Collection chainable plugin context.
|
||||||
type Collection struct {
|
type Collection struct {
|
||||||
@ -23,8 +23,8 @@ type Collection struct {
|
|||||||
groupsKey string
|
groupsKey string
|
||||||
comparer Comparer
|
comparer Comparer
|
||||||
|
|
||||||
groups map[string][]goldsmith.File
|
groups map[string][]*goldsmith.File
|
||||||
files []goldsmith.File
|
files []*goldsmith.File
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ func New() *Collection {
|
|||||||
return &Collection{
|
return &Collection{
|
||||||
collectionKey: "Collection",
|
collectionKey: "Collection",
|
||||||
groupsKey: "Groups",
|
groupsKey: "Groups",
|
||||||
groups: make(map[string][]goldsmith.File),
|
groups: make(map[string][]*goldsmith.File),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ func (*Collection) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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()
|
self.mutex.Lock()
|
||||||
defer func() {
|
defer func() {
|
||||||
inputFile.SetProp(self.groupsKey, self.groups)
|
inputFile.SetProp(self.groupsKey, self.groups)
|
||||||
@ -110,7 +110,7 @@ func (self *Collection) Finalize(context *goldsmith.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type fileSorter struct {
|
type fileSorter struct {
|
||||||
files []goldsmith.File
|
files []*goldsmith.File
|
||||||
comparer Comparer
|
comparer Comparer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,12 +14,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Processor callback function to modify documents.
|
// 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.
|
// Document plugin context.
|
||||||
type Document struct {
|
type Document struct {
|
||||||
callback Processor
|
callback Processor
|
||||||
files []goldsmith.File
|
files []*goldsmith.File
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ func (*Document) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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)
|
doc, err := goquery.NewDocumentFromReader(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/PuerkitoBio/goquery"
|
"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;")
|
doc.Find("h1").SetAttr("style", "color: red;")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func (*FrontMatter) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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)
|
meta, body, err := parse(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -18,7 +18,7 @@ type Entry struct {
|
|||||||
Name string
|
Name string
|
||||||
Path string
|
Path string
|
||||||
IsDir bool
|
IsDir bool
|
||||||
File goldsmith.File
|
File *goldsmith.File
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index chainable plugin context.
|
// Index chainable plugin context.
|
||||||
@ -60,7 +60,7 @@ func (*Index) Name() string {
|
|||||||
return "index"
|
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()
|
self.mutex.Lock()
|
||||||
defer self.mutex.Unlock()
|
defer self.mutex.Unlock()
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ func (self *Index) Finalize(context *goldsmith.Context) error {
|
|||||||
|
|
||||||
type directory struct {
|
type directory struct {
|
||||||
entries entriesByName
|
entries entriesByName
|
||||||
indexFile goldsmith.File
|
indexFile *goldsmith.File
|
||||||
}
|
}
|
||||||
|
|
||||||
type entriesByName []Entry
|
type entriesByName []Entry
|
||||||
|
@ -20,8 +20,8 @@ type Layout struct {
|
|||||||
defaultLayout *string
|
defaultLayout *string
|
||||||
helpers template.FuncMap
|
helpers template.FuncMap
|
||||||
|
|
||||||
inputFiles []goldsmith.File
|
inputFiles []*goldsmith.File
|
||||||
templateFiles []goldsmith.File
|
templateFiles []*goldsmith.File
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
|
|
||||||
template *template.Template
|
template *template.Template
|
||||||
@ -70,7 +70,7 @@ func (self *Layout) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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()
|
self.mutex.Lock()
|
||||||
defer self.mutex.Unlock()
|
defer self.mutex.Unlock()
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ func (self *Layout) Finalize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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 {
|
if name, ok := file.Props()[self.layoutKey].(string); ok {
|
||||||
return name, true
|
return name, true
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ func (self *LiveJs) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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 {
|
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
|
||||||
outputFile.CopyProps(inputFile)
|
outputFile.CopyProps(inputFile)
|
||||||
context.DispatchFile(outputFile)
|
context.DispatchFile(outputFile)
|
||||||
|
@ -47,7 +47,7 @@ func (self *Markdown) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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"
|
outputPath := strings.TrimSuffix(inputFile.Path(), path.Ext(inputFile.Path())) + ".html"
|
||||||
if outputFile := context.RetrieveCachedFile(outputPath, inputFile); outputFile != nil {
|
if outputFile := context.RetrieveCachedFile(outputPath, inputFile); outputFile != nil {
|
||||||
outputFile.CopyProps(inputFile)
|
outputFile.CopyProps(inputFile)
|
||||||
|
@ -37,7 +37,7 @@ func (*Minify) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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 {
|
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
|
||||||
outputFile.CopyProps(inputFile)
|
outputFile.CopyProps(inputFile)
|
||||||
context.DispatchFile(outputFile)
|
context.DispatchFile(outputFile)
|
||||||
|
@ -22,13 +22,13 @@ import (
|
|||||||
type Namer func(path string, index int) string
|
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.
|
// 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.
|
// Page represents information about a given metadata segment.
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Index int
|
Index int
|
||||||
Items interface{}
|
Items interface{}
|
||||||
File goldsmith.File
|
File *goldsmith.File
|
||||||
|
|
||||||
Next *Page
|
Next *Page
|
||||||
Prev *Page
|
Prev *Page
|
||||||
@ -51,7 +51,7 @@ type Pager struct {
|
|||||||
inheritedKeys []string
|
inheritedKeys []string
|
||||||
itemsPerPage int
|
itemsPerPage int
|
||||||
|
|
||||||
files []goldsmith.File
|
files []*goldsmith.File
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ func (*Pager) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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()
|
self.mutex.Lock()
|
||||||
defer self.mutex.Unlock()
|
defer self.mutex.Unlock()
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ func (self *Pager) Finalize(ctx *goldsmith.Context) error {
|
|||||||
return nil
|
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)
|
enableRaw, ok := file.Prop(self.enableKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -11,9 +11,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test(self *testing.T) {
|
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 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 {
|
if group, ok := groups["group"]; ok {
|
||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,14 @@ type rule struct {
|
|||||||
|
|
||||||
type ruleApply struct {
|
type ruleApply struct {
|
||||||
rule
|
rule
|
||||||
Props map[string]goldsmith.FileProp
|
Props goldsmith.FileProps
|
||||||
}
|
}
|
||||||
|
|
||||||
type ruleDrop struct {
|
type ruleDrop struct {
|
||||||
rule
|
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) {
|
if !wildcard.New(filepath.Join(self.baseDir, "**")).Accept(inputFile) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ func (self *rule) accept(inputFile goldsmith.File) bool {
|
|||||||
return operator.Not(wildcard.New(rejectPaths...)).Accept(inputFile)
|
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) {
|
if self.accept(inputFile) {
|
||||||
for name, value := range self.Props {
|
for name, value := range self.Props {
|
||||||
inputFile.SetProp(name, value)
|
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)
|
return self.accept(inputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ type ruleSet struct {
|
|||||||
Drop []*ruleDrop
|
Drop []*ruleDrop
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRuleSet(inputFile goldsmith.File) (*ruleSet, error) {
|
func newRuleSet(inputFile *goldsmith.File) (*ruleSet, error) {
|
||||||
data, err := io.ReadAll(inputFile)
|
data, err := io.ReadAll(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -91,7 +91,7 @@ func newRuleSet(inputFile goldsmith.File) (*ruleSet, error) {
|
|||||||
return &ruleSet, nil
|
return &ruleSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ruleSet) process(inputFile goldsmith.File) bool {
|
func (self *ruleSet) process(inputFile *goldsmith.File) bool {
|
||||||
for _, rule := range self.Apply {
|
for _, rule := range self.Apply {
|
||||||
rule.apply(inputFile)
|
rule.apply(inputFile)
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ type Rule struct {
|
|||||||
filename string
|
filename string
|
||||||
|
|
||||||
ruleSets []*ruleSet
|
ruleSets []*ruleSet
|
||||||
inputFiles []goldsmith.File
|
inputFiles []*goldsmith.File
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ func (*Rule) Name() string {
|
|||||||
return "rule"
|
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 {
|
if inputFile.Name() == self.filename {
|
||||||
ruleSet, err := newRuleSet(inputFile)
|
ruleSet, err := newRuleSet(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,7 +62,7 @@ func (*Summary) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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)
|
doc, err := goquery.NewDocumentFromReader(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -120,7 +120,7 @@ func (self *Syndicate) WithFeed(name string, config FeedConfig) *Syndicate {
|
|||||||
return self
|
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)
|
defer context.DispatchFile(inputFile)
|
||||||
|
|
||||||
getString := func(key string) string {
|
getString := func(key string) string {
|
||||||
|
@ -74,7 +74,7 @@ func (*Syntax) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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 {
|
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
|
||||||
outputFile.CopyProps(inputFile)
|
outputFile.CopyProps(inputFile)
|
||||||
context.DispatchFile(outputFile)
|
context.DispatchFile(outputFile)
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
// TagInfo contains site-wide information about a particular tag.
|
// TagInfo contains site-wide information about a particular tag.
|
||||||
type TagInfo struct {
|
type TagInfo struct {
|
||||||
TaggedFiles filesByPath
|
TaggedFiles filesByPath
|
||||||
IndexFile goldsmith.File
|
IndexFile *goldsmith.File
|
||||||
SafeName string
|
SafeName string
|
||||||
RawName string
|
RawName string
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ type Tags struct {
|
|||||||
infoByName tagInfoByName
|
infoByName tagInfoByName
|
||||||
infoByCount tagInfoByCount
|
infoByCount tagInfoByCount
|
||||||
|
|
||||||
files []goldsmith.File
|
files []*goldsmith.File
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ func (*Tags) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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{
|
tagState := &TagState{
|
||||||
TagsByName: &self.infoByName,
|
TagsByName: &self.infoByName,
|
||||||
TagsByCount: &self.infoByCount,
|
TagsByCount: &self.infoByCount,
|
||||||
@ -185,8 +185,8 @@ func (self *Tags) Finalize(context *goldsmith.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Tags) buildPages(context *goldsmith.Context) ([]goldsmith.File, error) {
|
func (self *Tags) buildPages(context *goldsmith.Context) ([]*goldsmith.File, error) {
|
||||||
var files []goldsmith.File
|
var files []*goldsmith.File
|
||||||
for tag, info := range self.info {
|
for tag, info := range self.info {
|
||||||
var err error
|
var err error
|
||||||
info.IndexFile, err = context.CreateFileFromReader(self.tagPagePath(tag), bytes.NewReader(nil))
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type filesByPath []goldsmith.File
|
type filesByPath []*goldsmith.File
|
||||||
|
|
||||||
func (self filesByPath) Len() int {
|
func (self filesByPath) Len() int {
|
||||||
return len(self)
|
return len(self)
|
||||||
|
@ -81,7 +81,7 @@ func (*Thumbnail) Initialize(context *goldsmith.Context) error {
|
|||||||
return nil
|
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)
|
defer context.DispatchFile(inputFile)
|
||||||
|
|
||||||
thumbPath := self.namer(inputFile.Path(), self.size)
|
thumbPath := self.namer(inputFile.Path(), self.size)
|
||||||
@ -104,7 +104,7 @@ func (self *Thumbnail) Process(context *goldsmith.Context, inputFile goldsmith.F
|
|||||||
return nil
|
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
|
var thumbFormat imaging.Format
|
||||||
switch strings.ToLower(filepath.Ext(thumbPath)) {
|
switch strings.ToLower(filepath.Ext(thumbPath)) {
|
||||||
case ".jpg", ".jpeg":
|
case ".jpg", ".jpeg":
|
||||||
|
Loading…
Reference in New Issue
Block a user