ref: 4a2f16f91e213b02f008405938fe289c58820e88
parent: 73f203ad86a71136a1d35e0aa1bba574edb91a51
author: spf13 <[email protected]>
date: Thu Nov 20 07:39:09 EST 2014
refactor handlers to use types instead of structs.
--- /dev/null
+++ b/hugolib/handler_base.go
@@ -1,0 +1,61 @@
+// Copyright © 2014 Steve Francia <[email protected]>.
+//
+// Licensed under the Simple Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://opensource.org/licenses/Simple-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hugolib
+
+import (
+ "github.com/spf13/hugo/source"
+ "github.com/spf13/hugo/tpl"
+)
+
+type Handler interface {
+ FileConvert(*source.File, *Site) HandledResult
+ PageConvert(*Page, tpl.Template) HandledResult
+ Read(*source.File, *Site) HandledResult
+ Extensions() []string
+}
+
+type Handle struct {
+ extensions []string
+}
+
+func (h Handle) Extensions() []string {
+ return h.extensions
+}
+
+type HandledResult struct {
+ page *Page
+ file *source.File
+ err error
+}
+
+// HandledResult is an error
+func (h HandledResult) Error() string {
+ if h.err != nil {
+ if h.page != nil {
+ return "Error:" + h.err.Error() + " for " + h.page.File.LogicalName()
+ }
+ if h.file != nil {
+ return "Error:" + h.err.Error() + " for " + h.file.LogicalName()
+ }
+ }
+ return h.err.Error()
+}
+
+func (h HandledResult) String() string {
+ return h.Error()
+}
+
+func (hr HandledResult) Page() *Page {
+ return hr.page
+}
--- a/hugolib/handler_file.go
+++ b/hugolib/handler_file.go
@@ -17,19 +17,30 @@
"github.com/dchest/cssmin"
"github.com/spf13/hugo/helpers"
"github.com/spf13/hugo/source"
+ "github.com/spf13/hugo/tpl"
)
func init() {
- RegisterHandler(css)
+ RegisterHandler(new(cssHandler))
}
-var css = Handle{
- extensions: []string{"css"},
- read: func(f *source.File, s *Site, results HandleResults) {
- results <- HandledResult{file: f}
- },
- fileConvert: func(f *source.File, s *Site, results HandleResults) {
- x := cssmin.Minify(f.Bytes())
- s.WriteDestFile(f.Path(), helpers.BytesToReader(x))
- },
+type basicFileHandler Handle
+
+func (h basicFileHandler) Read(f *source.File, s *Site) HandledResult {
+ return HandledResult{file: f}
+}
+
+func (h basicFileHandler) PageConvert(*Page, tpl.Template) HandledResult {
+ return HandledResult{}
+}
+
+type cssHandler struct {
+ basicFileHandler
+}
+
+func (h cssHandler) Extensions() []string { return []string{"css"} }
+func (h cssHandler) FileConvert(f *source.File, s *Site) HandledResult {
+ x := cssmin.Minify(f.Bytes())
+ s.WriteDestFile(f.Path(), helpers.BytesToReader(x))
+ return HandledResult{file: f}
}
--- /dev/null
+++ b/hugolib/handler_meta.go
@@ -1,0 +1,106 @@
+// Copyright © 2014 Steve Francia <[email protected]>.
+//
+// Licensed under the Simple Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://opensource.org/licenses/Simple-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hugolib
+
+import (
+ "errors"
+
+ "github.com/spf13/hugo/source"
+)
+
+var handlers []Handler
+
+type MetaHandler interface {
+ // Read the Files in and register
+ Read(*source.File, *Site, HandleResults)
+
+ // Generic Convert Function with coordination
+ Convert(interface{}, *Site, HandleResults)
+
+ Handle() Handler
+}
+
+type HandleResults chan<- HandledResult
+
+func NewMetaHandler(in string) *MetaHandle {
+ x := &MetaHandle{ext: in}
+ x.Handler()
+ return x
+}
+
+type MetaHandle struct {
+ handler Handler
+ ext string
+}
+
+func (mh *MetaHandle) Read(f *source.File, s *Site, results HandleResults) {
+ if h := mh.Handler(); h != nil {
+ results <- h.Read(f, s)
+ return
+ }
+
+ results <- HandledResult{err: errors.New("No handler found"), file: f}
+}
+
+func (mh *MetaHandle) Convert(i interface{}, s *Site, results HandleResults) {
+ h := mh.Handler()
+
+ if f, ok := i.(*source.File); ok {
+ results <- h.FileConvert(f, s)
+ return
+ }
+
+ if p, ok := i.(*Page); ok {
+ if p == nil {
+ results <- HandledResult{err: errors.New("file resulted in a nil page")}
+ return
+ }
+ results <- h.PageConvert(p, s.Tmpl)
+ p.setSummary()
+ p.analyzePage()
+ }
+}
+
+func (mh *MetaHandle) Handler() Handler {
+ if mh.handler == nil {
+ mh.handler = FindHandler(mh.ext)
+ }
+ return mh.handler
+}
+
+func FindHandler(ext string) Handler {
+ for _, h := range Handlers() {
+ if HandlerMatch(h, ext) {
+ return h
+ }
+ }
+ return nil
+}
+
+func HandlerMatch(h Handler, ext string) bool {
+ for _, x := range h.Extensions() {
+ if ext == x {
+ return true
+ }
+ }
+ return false
+}
+
+func RegisterHandler(h Handler) {
+ handlers = append(handlers, h)
+}
+
+func Handlers() []Handler {
+ return handlers
+}
--- a/hugolib/handler_page.go
+++ b/hugolib/handler_page.go
@@ -13,65 +13,89 @@
package hugolib
-import "github.com/spf13/hugo/source"
+import (
+ "github.com/spf13/hugo/helpers"
+ "github.com/spf13/hugo/source"
+ "github.com/spf13/hugo/tpl"
+ jww "github.com/spf13/jwalterweatherman"
+)
func init() {
- RegisterHandler(markdownHandler)
- RegisterHandler(htmlHandler)
+ RegisterHandler(new(markdownHandler))
+ RegisterHandler(new(htmlHandler))
+ RegisterHandler(new(asciidocHandler))
}
-var markdownHandler = Handle{
- extensions: []string{"mdown", "markdown", "md"},
- read: func(f *source.File, s *Site, results HandleResults) {
- page, err := NewPage(f.Path())
- if err != nil {
- results <- HandledResult{file: f, err: err}
- }
+type basicPageHandler Handle
- if err := page.ReadFrom(f.Contents); err != nil {
- results <- HandledResult{file: f, err: err}
- }
+func (b basicPageHandler) Read(f *source.File, s *Site) HandledResult {
+ page, err := NewPage(f.Path())
+ if err != nil {
+ return HandledResult{file: f, err: err}
+ }
- page.Site = &s.Info
- page.Tmpl = s.Tmpl
+ if err := page.ReadFrom(f.Contents); err != nil {
+ return HandledResult{file: f, err: err}
+ }
- results <- HandledResult{file: f, page: page, err: err}
- },
- pageConvert: func(p *Page, s *Site, results HandleResults) {
- p.ProcessShortcodes(s.Tmpl)
- err := p.Convert()
- if err != nil {
- results <- HandledResult{err: err}
- }
+ page.Site = &s.Info
+ page.Tmpl = s.Tmpl
- results <- HandledResult{err: err}
- },
+ return HandledResult{file: f, page: page, err: err}
}
-var htmlHandler = Handle{
- extensions: []string{"html", "htm"},
- read: func(f *source.File, s *Site, results HandleResults) {
- page, err := NewPage(f.Path())
- if err != nil {
- results <- HandledResult{file: f, err: err}
- }
+func (b basicPageHandler) FileConvert(*source.File, *Site) HandledResult {
+ return HandledResult{}
+}
- if err := page.ReadFrom(f.Contents); err != nil {
- results <- HandledResult{file: f, err: err}
- }
+type markdownHandler struct {
+ basicPageHandler
+}
- page.Site = &s.Info
- page.Tmpl = s.Tmpl
+func (h markdownHandler) Extensions() []string { return []string{"mdown", "markdown", "md"} }
+func (h markdownHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
+ p.ProcessShortcodes(t)
- results <- HandledResult{file: f, page: page, err: err}
- },
- pageConvert: func(p *Page, s *Site, results HandleResults) {
- p.ProcessShortcodes(s.Tmpl)
- err := p.Convert()
+ tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
+
+ if len(p.contentShortCodes) > 0 {
+ tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, -1, true, p.contentShortCodes)
+
if err != nil {
- results <- HandledResult{err: err}
+ jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
+ return HandledResult{err: err}
+ } else {
+ tmpContent = tmpContentWithTokensReplaced
}
+ }
- results <- HandledResult{err: err}
- },
+ p.Content = helpers.BytesToHTML(tmpContent)
+ p.TableOfContents = helpers.BytesToHTML(tmpTableOfContents)
+
+ return HandledResult{err: nil}
+}
+
+type htmlHandler struct {
+ basicPageHandler
+}
+
+func (h htmlHandler) Extensions() []string { return []string{"html", "htm"} }
+func (h htmlHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
+ p.ProcessShortcodes(t)
+ p.Content = helpers.BytesToHTML(p.rawContent)
+ return HandledResult{err: nil}
+}
+
+type asciidocHandler struct {
+ basicPageHandler
+}
+
+func (h asciidocHandler) Extensions() []string { return []string{"asciidoc", "ad"} }
+func (h asciidocHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
+ p.ProcessShortcodes(t)
+
+ // TODO(spf13) Add Ascii Doc Logic here
+
+ //err := p.Convert()
+ return HandledResult{page: p, err: nil}
}
--- a/hugolib/handlers.go
+++ /dev/null
@@ -1,91 +1,0 @@
-// Copyright © 2014 Steve Francia <[email protected]>.
-//
-// Licensed under the Simple Public License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://opensource.org/licenses/Simple-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hugolib
-
-import "github.com/spf13/hugo/source"
-
-type Handler interface {
- // Read the Files in and register
- Read(*source.File, *Site, HandleResults)
-
- // Convert Pages to prepare for templatizing
- // Convert Files to their final destination
- Convert(interface{}, *Site, HandleResults)
-
- // Extensions to register the handle for
- Extensions() []string
-}
-
-type HandledResult struct {
- page *Page
- file *source.File
- err error
-}
-
-type HandleResults chan<- HandledResult
-
-type ReadFunc func(*source.File, *Site, HandleResults)
-type PageConvertFunc func(*Page, *Site, HandleResults)
-type FileConvertFunc ReadFunc
-
-type Handle struct {
- extensions []string
- read ReadFunc
- pageConvert PageConvertFunc
- fileConvert FileConvertFunc
-}
-
-var handlers []Handler
-
-func (h Handle) Extensions() []string {
- return h.extensions
-}
-
-func (h Handle) Read(f *source.File, s *Site, results HandleResults) {
- h.read(f, s, results)
-}
-
-func (h Handle) Convert(i interface{}, s *Site, results HandleResults) {
- if h.pageConvert != nil {
- h.pageConvert(i.(*Page), s, results)
- } else {
- h.fileConvert(i.(*source.File), s, results)
- }
-}
-
-func RegisterHandler(h Handler) {
- handlers = append(handlers, h)
-}
-
-func Handlers() []Handler {
- return handlers
-}
-
-func FindHandler(ext string) Handler {
- for _, h := range Handlers() {
- if HandlerMatch(h, ext) {
- return h
- }
- }
- return nil
-}
-
-func HandlerMatch(h Handler, ext string) bool {
- for _, x := range h.Extensions() {
- if ext == x {
- return true
- }
- }
- return false
-}
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -640,32 +640,20 @@
}
+// TODO(spf13): Remove this entirely
+// Here for backwards compatibility & testing. Only works in isolation
func (page *Page) Convert() error {
- markupType := page.guessMarkupType()
- switch markupType {
- case "markdown", "rst":
-
- tmpContent, tmpTableOfContents := helpers.ExtractTOC(page.renderContent(helpers.RemoveSummaryDivider(page.rawContent)))
-
- if len(page.contentShortCodes) > 0 {
- tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, -1, true, page.contentShortCodes)
-
- if err != nil {
- jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", page.BaseFileName(), err.Error())
- } else {
- tmpContent = tmpContentWithTokensReplaced
- }
- }
-
- page.Content = helpers.BytesToHTML(tmpContent)
- page.TableOfContents = helpers.BytesToHTML(tmpTableOfContents)
- case "html":
- page.Content = helpers.BytesToHTML(page.rawContent)
- default:
- return fmt.Errorf("Error converting unsupported file type '%s' for page '%s'", markupType, page.Source.Path())
+ var h Handler
+ if page.Markup != "" {
+ h = FindHandler(page.Markup)
+ } else {
+ h = FindHandler(page.File.Extension())
}
+ if h != nil {
+ h.PageConvert(page, tpl.T())
+ }
- // now we know enough to create a summary of the page and count some words
+ //// now we know enough to create a summary of the page and count some words
page.setSummary()
//analyze for raw stats
page.analyzePage()
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -342,7 +342,6 @@
if err != nil {
t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
}
- p.ProcessShortcodes(s.Tmpl)
p.Convert()
checkPageTitle(t, p, "Simple")
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -417,7 +417,7 @@
func sourceReader(s *Site, files <-chan *source.File, results chan<- HandledResult, wg *sync.WaitGroup) {
defer wg.Done()
for file := range files {
- h := FindHandler(file.Extension())
+ h := NewMetaHandler(file.Extension())
if h != nil {
h.Read(file, s, results)
} else {
@@ -429,11 +429,11 @@
func pageConverter(s *Site, pages <-chan *Page, results HandleResults, wg *sync.WaitGroup) {
defer wg.Done()
for page := range pages {
- var h Handler
+ var h *MetaHandle
if page.Markup != "" {
- h = FindHandler(page.Markup)
+ h = NewMetaHandler(page.Markup)
} else {
- h = FindHandler(page.File.Extension())
+ h = NewMetaHandler(page.File.Extension())
}
if h != nil {
h.Convert(page, s, results)
@@ -444,7 +444,7 @@
func fileConverter(s *Site, files <-chan *source.File, results HandleResults, wg *sync.WaitGroup) {
defer wg.Done()
for file := range files {
- h := FindHandler(file.Extension())
+ h := NewMetaHandler(file.Extension())
if h != nil {
h.Convert(file, s, results)
}
@@ -470,7 +470,7 @@
errMsgs := []string{}
for r := range results {
if r.err != nil {
- errMsgs = append(errMsgs, r.err.Error())
+ errMsgs = append(errMsgs, r.Error())
continue
}