diff --git a/environment.go b/environment.go index a78cd7f..177bf72 100644 --- a/environment.go +++ b/environment.go @@ -2,8 +2,10 @@ package step import "os" import "io" +import "fmt" import "time" import "io/fs" +import "errors" import "context" import "path/filepath" import "html/template" @@ -107,28 +109,47 @@ func (this *Environment) parse (name string, modTime time.Time, input io.Reader) document.Extends = extends } + // add template functions + funcMap := make(template.FuncMap) + for name, function := range this.funcMap { + funcMap[name] = function + } + for _, provider := range this.FuncProviders { + provider, ok := provider.(FuncProviderFor) + if !ok { continue } + funcMapFor := provider.FuncMapFor(document) + if funcMapFor == nil { continue } + for name, function := range funcMapFor { + funcMap[name] = function + } + } + err = this.addFuncsTo(document, funcMap) + if err != nil { return nil, err } + // parse template from the body - document.template.Funcs(this.funcMap) // TODO catch template errors here and offset their row number by the // number of rows taken up by the front matter _, err = document.template.Parse(body) if err != nil { return nil, err } - // add template functions which need a document pointer for context - for _, provider := range this.FuncProviders { - provider, ok := provider.(FuncProviderFor) - if !ok { continue } - funcMap := provider.FuncMapFor(document) - if funcMap == nil { continue } - for name, function := range funcMap { - this.funcMap[name] = function - } - } - documents[name] = document return document, nil } +func (this *Environment) addFuncsTo (document *Document, funcs template.FuncMap) (err error) { + defer func () { + if r := recover(); r != nil { + if rerr, ok := err.(error); ok { + err = rerr + } else { + err = errors.New(fmt.Sprint(r)) + } + } + } () + document.template.Funcs(funcs) + return err +} + // GetFS returns the effective filesystem that the environment uses. func (this *Environment) GetFS () fs.FS { if this.FS == nil {