Compare commits
No commits in common. "e24e8927738ff2ef1797cfbb56e34c607095cd0f" and "05f7ee528084960aa807e129d233d94d181427c1" have entirely different histories.
e24e892773
...
05f7ee5280
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 *contextImpl, 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 *contextImpl, 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 []*F
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *cache) buildCachePath(context *Context, outputPath string, inputFiles []*File) (string, error) {
|
func (self *cache) buildCachePath(context *contextImpl, outputPath string, inputFiles []File) (string, error) {
|
||||||
hasher := crc32.NewIEEE()
|
hasher := crc32.NewIEEE()
|
||||||
hasher.Write([]byte(outputPath))
|
hasher.Write([]byte(outputPath))
|
||||||
|
|
||||||
|
71
context.go
71
context.go
@ -13,7 +13,34 @@ import (
|
|||||||
|
|
||||||
// Context corresponds to the current link in the chain and provides methods
|
// Context corresponds to the current link in the chain and provides methods
|
||||||
// that enable plugins to inject new files into the chain.
|
// that enable plugins to inject new files into the chain.
|
||||||
type Context struct {
|
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 {
|
||||||
goldsmith *Goldsmith
|
goldsmith *Goldsmith
|
||||||
|
|
||||||
plugin Plugin
|
plugin Plugin
|
||||||
@ -24,31 +51,33 @@ 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 *contextImpl) 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
|
||||||
}
|
}
|
||||||
|
|
||||||
file := &File{
|
cf := &contextFile{
|
||||||
|
rawFile{
|
||||||
relPath: sourcePath,
|
relPath: sourcePath,
|
||||||
props: make(FileProps),
|
props: make(map[string]FileProp),
|
||||||
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 file, nil
|
return cf, 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 *contextImpl) 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")
|
||||||
}
|
}
|
||||||
@ -65,27 +94,29 @@ func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, er
|
|||||||
return nil, errors.New("assets must be files")
|
return nil, errors.New("assets must be files")
|
||||||
}
|
}
|
||||||
|
|
||||||
file := &File{
|
cf := &contextFile{
|
||||||
|
rawFile{
|
||||||
relPath: sourcePath,
|
relPath: sourcePath,
|
||||||
props: make(FileProps),
|
props: make(map[string]FileProp),
|
||||||
modTime: info.ModTime(),
|
modTime: info.ModTime(),
|
||||||
size: info.Size(),
|
size: info.Size(),
|
||||||
dataPath: dataPath,
|
dataPath: dataPath,
|
||||||
index: self.index,
|
},
|
||||||
|
self.index,
|
||||||
}
|
}
|
||||||
|
|
||||||
return file, nil
|
return cf, 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 *contextImpl) 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 *contextImpl) 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)
|
||||||
}
|
}
|
||||||
@ -96,8 +127,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 *contextImpl) 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)
|
||||||
}
|
}
|
||||||
@ -106,7 +137,7 @@ func (self *Context) RetrieveCachedFile(outputPath string, inputFiles ...*File)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specify internal filter(s) that exclude files from being processed.
|
// Specify internal filter(s) that exclude files from being processed.
|
||||||
func (self *Context) Filter(filters ...Filter) *Context {
|
func (self *contextImpl) Filter(filters ...Filter) Context {
|
||||||
for _, filter := range filters {
|
for _, filter := range filters {
|
||||||
self.filtersInt.push(filter, self.index)
|
self.filtersInt.push(filter, self.index)
|
||||||
}
|
}
|
||||||
@ -115,12 +146,12 @@ func (self *Context) Filter(filters ...Filter) *Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specify the maximum number of threads used for processing.
|
// Specify the maximum number of threads used for processing.
|
||||||
func (self *Context) Threads(threads int) *Context {
|
func (self *contextImpl) Threads(threads int) Context {
|
||||||
self.threads = threads
|
self.threads = threads
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Context) step() {
|
func (self *contextImpl) step() {
|
||||||
defer close(self.filesOut)
|
defer close(self.filesOut)
|
||||||
|
|
||||||
if initializer, ok := self.plugin.(Initializer); ok {
|
if initializer, ok := self.plugin.(Initializer); ok {
|
||||||
|
@ -9,22 +9,22 @@ type Plugin interface {
|
|||||||
// Initializer is used to optionally initialize a plugin and to specify a
|
// Initializer is used to optionally initialize a plugin and to specify a
|
||||||
// filter to be used for determining which files will be processed.
|
// filter to be used for determining which files will be processed.
|
||||||
type Initializer interface {
|
type Initializer interface {
|
||||||
Initialize(context *Context) error
|
Initialize(context Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
// queued in the chain have passed through it.
|
// queued in the chain have passed through it.
|
||||||
type Finalizer interface {
|
type Finalizer interface {
|
||||||
Finalize(context *Context) error
|
Finalize(context Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
155
file.go
155
file.go
@ -1,11 +1,7 @@
|
|||||||
package goldsmith
|
package goldsmith
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,141 +11,26 @@ 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 struct {
|
type File interface {
|
||||||
relPath string
|
Path() string
|
||||||
props FileProps
|
Dir() string
|
||||||
modTime time.Time
|
Name() string
|
||||||
size int64
|
Ext() string
|
||||||
|
Rename(path string) error
|
||||||
|
|
||||||
dataPath string
|
Size() int64
|
||||||
reader *bytes.Reader
|
ModTime() time.Time
|
||||||
|
|
||||||
index int
|
Read(data []byte) (int, error)
|
||||||
}
|
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
|
GoString() string
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,13 @@ func (*fileExporter) Name() string {
|
|||||||
return "exporter"
|
return "exporter"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *fileExporter) Initialize(context *Context) error {
|
func (self *fileExporter) Initialize(context Context) error {
|
||||||
self.tokens = make(map[string]bool)
|
self.tokens = make(map[string]bool)
|
||||||
context.Threads(1)
|
context.Threads(1)
|
||||||
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
|
||||||
@ -64,7 +64,7 @@ func (self *fileExporter) Process(context *Context, file *File) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *fileExporter) Finalize(context *Context) error {
|
func (self *fileExporter) Finalize(context Context) error {
|
||||||
if !self.clean {
|
if !self.clean {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ func (*fileImporter) Name() string {
|
|||||||
return "importer"
|
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 {
|
return filepath.Walk(self.sourceDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
|
@ -7,9 +7,11 @@ 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 >= file.index && !entry.filter.Accept(file) {
|
if entry.index >= cf.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 {
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type chainState struct {
|
type chainState struct {
|
||||||
contexts []*Context
|
contexts []*contextImpl
|
||||||
|
|
||||||
cache *cache
|
cache *cache
|
||||||
filters filterStack
|
filters filterStack
|
||||||
@ -44,12 +44,12 @@ func (self *Goldsmith) Clean(clean bool) *Goldsmith {
|
|||||||
|
|
||||||
// Chain links a plugin instance into the chain.
|
// Chain links a plugin instance into the chain.
|
||||||
func (self *Goldsmith) Chain(plugin Plugin) *Goldsmith {
|
func (self *Goldsmith) Chain(plugin Plugin) *Goldsmith {
|
||||||
context := &Context{
|
context := &contextImpl{
|
||||||
goldsmith: self,
|
goldsmith: self,
|
||||||
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()
|
||||||
|
|
||||||
|
@ -45,12 +45,12 @@ func (*Absolute) Name() string {
|
|||||||
return "absolute"
|
return "absolute"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Absolute) Initialize(context *goldsmith.Context) error {
|
func (*Absolute) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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
|
||||||
|
|
||||||
@ -70,12 +70,12 @@ func (*Breadcrumbs) Name() string {
|
|||||||
return "breadcrumbs"
|
return "breadcrumbs"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Breadcrumbs) Initialize(context *goldsmith.Context) error {
|
func (*Breadcrumbs) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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)
|
||||||
@ -103,7 +103,7 @@ func (self *Breadcrumbs) Process(context *goldsmith.Context, inputFile *goldsmit
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Breadcrumbs) Finalize(context *goldsmith.Context) error {
|
func (self *Breadcrumbs) Finalize(context goldsmith.Context) error {
|
||||||
for _, node := range self.allNodes {
|
for _, node := range self.allNodes {
|
||||||
if len(node.parentName) == 0 {
|
if len(node.parentName) == 0 {
|
||||||
continue
|
continue
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +61,12 @@ func (*Collection) Name() string {
|
|||||||
return "collection"
|
return "collection"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Collection) Initialize(context *goldsmith.Context) error {
|
func (*Collection) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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)
|
||||||
@ -96,7 +96,7 @@ func (self *Collection) Process(context *goldsmith.Context, inputFile *goldsmith
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Collection) Finalize(context *goldsmith.Context) error {
|
func (self *Collection) Finalize(context goldsmith.Context) error {
|
||||||
for _, files := range self.groups {
|
for _, files := range self.groups {
|
||||||
fg := &fileSorter{files, self.comparer}
|
fg := &fileSorter{files, self.comparer}
|
||||||
sort.Sort(fg)
|
sort.Sort(fg)
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,12 +32,12 @@ func (*Document) Name() string {
|
|||||||
return "document"
|
return "document"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Document) Initialize(context *goldsmith.Context) error {
|
func (*Document) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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
|
||||||
@ -61,7 +61,7 @@ func (self *Document) Process(context *goldsmith.Context, inputFile *goldsmith.F
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Document) Finalize(context *goldsmith.Context) error {
|
func (self *Document) Finalize(context goldsmith.Context) error {
|
||||||
for _, file := range self.files {
|
for _, file := range self.files {
|
||||||
context.DispatchFile(file)
|
context.DispatchFile(file)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ func (*Forward) Name() string {
|
|||||||
return "forward"
|
return "forward"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Forward) Initialize(context *goldsmith.Context) error {
|
func (self *Forward) Initialize(context goldsmith.Context) error {
|
||||||
for sourcePath, targetPath := range self.pathMap {
|
for sourcePath, targetPath := range self.pathMap {
|
||||||
sourceFile, err := context.CreateFileFromReader(sourcePath, bytes.NewReader(nil))
|
sourceFile, err := context.CreateFileFromReader(sourcePath, bytes.NewReader(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -66,12 +66,12 @@ func (*FrontMatter) Name() string {
|
|||||||
return "frontmatter"
|
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"))
|
context.Filter(wildcard.New("**/*.md", "**/*.markdown", "**/*.rst", "**/*.txt", "**/*.html", "**/*.htm"))
|
||||||
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()
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ func (self *Index) Process(context *goldsmith.Context, inputFile *goldsmith.File
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Index) Finalize(context *goldsmith.Context) error {
|
func (self *Index) Finalize(context goldsmith.Context) error {
|
||||||
for name, list := range self.dirLists {
|
for name, list := range self.dirLists {
|
||||||
sort.Sort(list.entries)
|
sort.Sort(list.entries)
|
||||||
|
|
||||||
@ -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
|
||||||
@ -64,13 +64,13 @@ func (*Layout) Name() string {
|
|||||||
return "layout"
|
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)
|
self.template = template.New("").Funcs(self.helpers)
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm", "**/*.tmpl", "**/*.gohtml"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm", "**/*.tmpl", "**/*.gohtml"))
|
||||||
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()
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ func (self *Layout) Process(context *goldsmith.Context, inputFile *goldsmith.Fil
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Layout) Finalize(context *goldsmith.Context) error {
|
func (self *Layout) Finalize(context goldsmith.Context) error {
|
||||||
for _, templateFile := range self.templateFiles {
|
for _, templateFile := range self.templateFiles {
|
||||||
var buff bytes.Buffer
|
var buff bytes.Buffer
|
||||||
if _, err := templateFile.WriteTo(&buff); err != nil {
|
if _, err := templateFile.WriteTo(&buff); err != nil {
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,13 @@ func (*LiveJs) Name() string {
|
|||||||
return "livejs"
|
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)
|
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"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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)
|
||||||
|
@ -42,12 +42,12 @@ func (*Markdown) Name() string {
|
|||||||
return "markdown"
|
return "markdown"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Markdown) Initialize(context *goldsmith.Context) error {
|
func (self *Markdown) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.md", "**/*.markdown"))
|
context.Filter(wildcard.New("**/*.md", "**/*.markdown"))
|
||||||
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)
|
||||||
|
@ -32,12 +32,12 @@ func (*Minify) Name() string {
|
|||||||
return "minify"
|
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"))
|
context.Filter(wildcard.New("**/*.css", "**/*.html", "**/*.htm", "**/*.js", "**/*.svg", "**/*.json", "**/*.xml"))
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,12 +109,12 @@ func (*Pager) Name() string {
|
|||||||
return "pager"
|
return "pager"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Pager) Initialize(context *goldsmith.Context) error {
|
func (*Pager) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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()
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ func (self *Pager) Process(context *goldsmith.Context, inputFile *goldsmith.File
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Pager) Finalize(ctx *goldsmith.Context) error {
|
func (self *Pager) Finalize(ctx goldsmith.Context) error {
|
||||||
for _, f := range self.files {
|
for _, f := range self.files {
|
||||||
ctx.DispatchFile(f)
|
ctx.DispatchFile(f)
|
||||||
}
|
}
|
||||||
@ -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 goldsmith.FileProps
|
Props map[string]goldsmith.FileProp
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
@ -147,7 +147,7 @@ func (self *Rule) Process(context *goldsmith.Context, inputFile *goldsmith.File)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Rule) Finalize(context *goldsmith.Context) error {
|
func (self *Rule) Finalize(context goldsmith.Context) error {
|
||||||
for _, inputFile := range self.inputFiles {
|
for _, inputFile := range self.inputFiles {
|
||||||
var block bool
|
var block bool
|
||||||
for _, ruleSet := range self.ruleSets {
|
for _, ruleSet := range self.ruleSets {
|
||||||
|
@ -57,12 +57,12 @@ func (*Summary) Name() string {
|
|||||||
return "summary"
|
return "summary"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Summary) Initialize(context *goldsmith.Context) error {
|
func (*Summary) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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 {
|
||||||
@ -214,7 +214,7 @@ func (self *Syndicate) Process(context *goldsmith.Context, inputFile *goldsmith.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *feed) output(context *goldsmith.Context) error {
|
func (self *feed) output(context goldsmith.Context) error {
|
||||||
feed := feeds.Feed{
|
feed := feeds.Feed{
|
||||||
Title: self.config.Title,
|
Title: self.config.Title,
|
||||||
Link: &feeds.Link{Href: self.config.Url},
|
Link: &feeds.Link{Href: self.config.Url},
|
||||||
@ -310,7 +310,7 @@ func (self *feed) output(context *goldsmith.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Syndicate) Finalize(context *goldsmith.Context) error {
|
func (self *Syndicate) Finalize(context goldsmith.Context) error {
|
||||||
for _, feed := range self.feeds {
|
for _, feed := range self.feeds {
|
||||||
feed.output(context)
|
feed.output(context)
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,12 @@ func (*Syntax) Name() string {
|
|||||||
return "syntax"
|
return "syntax"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Syntax) Initialize(context *goldsmith.Context) error {
|
func (*Syntax) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,12 +93,12 @@ func (*Tags) Name() string {
|
|||||||
return "tags"
|
return "tags"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Tags) Initialize(context *goldsmith.Context) error {
|
func (*Tags) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
context.Filter(wildcard.New("**/*.html", "**/*.htm"))
|
||||||
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,
|
||||||
@ -158,7 +158,7 @@ func (self *Tags) Process(context *goldsmith.Context, inputFile *goldsmith.File)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Tags) Finalize(context *goldsmith.Context) error {
|
func (self *Tags) Finalize(context goldsmith.Context) error {
|
||||||
for _, info := range self.info {
|
for _, info := range self.info {
|
||||||
sort.Sort(info.TaggedFiles)
|
sort.Sort(info.TaggedFiles)
|
||||||
|
|
||||||
@ -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)
|
||||||
|
@ -76,12 +76,12 @@ func (*Thumbnail) Name() string {
|
|||||||
return "thumbnail"
|
return "thumbnail"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Thumbnail) Initialize(context *goldsmith.Context) error {
|
func (*Thumbnail) Initialize(context goldsmith.Context) error {
|
||||||
context.Filter(wildcard.New("**/*.jpg", "**/*.jpeg", "**/*.gif", "**/*.png"))
|
context.Filter(wildcard.New("**/*.jpg", "**/*.jpeg", "**/*.gif", "**/*.png"))
|
||||||
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.
|
|||||||
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