1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-12-02 16:47:50 +01:00
gojekyll/plugins/plugins.go

131 lines
3.6 KiB
Go
Raw Normal View History

2017-07-01 05:10:58 +02:00
// Package plugins holds emulated Jekyll plugins.
//
// Unlike Jekyll, these are baked into the executable -- both because as of 2017.07 package "plugin' currently
// works only on Linux, but also because the gojekyll implementation is immature and any possible interfaces
// are far from baked.
2017-06-30 18:53:34 +02:00
package plugins
import (
"fmt"
"regexp"
2017-06-30 18:53:34 +02:00
2017-07-09 21:07:14 +02:00
"github.com/kyokomi/emoji"
2017-07-09 03:41:35 +02:00
"github.com/osteele/gojekyll/config"
"github.com/osteele/gojekyll/pages"
2017-07-09 22:17:20 +02:00
"github.com/osteele/gojekyll/utils"
2017-07-01 01:37:31 +02:00
"github.com/osteele/liquid"
2017-07-04 23:13:47 +02:00
"github.com/osteele/liquid/render"
2017-06-30 18:53:34 +02:00
)
2017-07-09 03:41:35 +02:00
// Site is the site interface that is available to a plugin.
type Site interface {
AddDocument(pages.Document, bool)
Config() *config.Config
Pages() []pages.Page
}
// Plugin describes the hooks that a plugin can override.
type Plugin interface {
2017-07-09 04:47:50 +02:00
ConfigureTemplateEngine(liquid.Engine) error
PostRender([]byte) []byte
2017-07-09 04:47:50 +02:00
Initialize(Site) error
2017-07-09 03:41:35 +02:00
PostRead(site Site) error
}
type plugin struct{}
2017-07-09 04:47:50 +02:00
func (p plugin) ConfigureTemplateEngine(liquid.Engine) error { return nil }
func (p plugin) PostRender(b []byte) []byte { return b }
2017-07-09 04:47:50 +02:00
func (p plugin) Initialize(Site) error { return nil }
func (p plugin) PostRead(Site) error { return nil }
2017-07-09 03:41:35 +02:00
2017-07-09 04:47:50 +02:00
// Lookup returns a plugin if it has been registered.
func Lookup(name string) (Plugin, bool) {
p, found := directory[name]
return p, found
2017-07-09 03:41:35 +02:00
}
2017-07-01 05:10:58 +02:00
// Install installs a plugin from the plugin directory.
2017-07-09 04:47:50 +02:00
func Install(names []string, site Site) {
for _, name := range names {
p, found := directory[name]
if found {
if err := p.Initialize(site); err != nil {
panic(err)
}
} else {
fmt.Printf("warning: gojekyll does not emulate the %s plugin.\n", name)
2017-06-30 18:53:34 +02:00
}
}
}
2017-07-09 04:47:50 +02:00
var directory = map[string]Plugin{}
2017-06-30 18:53:34 +02:00
2017-07-09 01:57:41 +02:00
// register installs a plugin in the plugin directory.
2017-07-09 04:47:50 +02:00
func register(name string, p Plugin) {
directory[name] = p
2017-06-30 18:53:34 +02:00
}
func init() {
2017-07-09 21:07:14 +02:00
register("jemoji", jekyllJemojiPlugin{})
register("jekyll-mentions", jekyllMentionsPlugin{})
2017-07-09 04:47:50 +02:00
register("jekyll-seo-tag", jekyllSEOTagPlugin{})
2017-07-05 22:54:48 +02:00
// the following plugins are always active
2017-07-02 05:06:47 +02:00
// no warning but effect; the server runs in this mode anyway
2017-07-09 04:47:50 +02:00
register("jekyll-live-reload", plugin{})
register("jekyll-sass-converter", plugin{})
2017-06-30 18:53:34 +02:00
}
2017-07-01 16:37:11 +02:00
2017-07-09 21:07:14 +02:00
// Some small plugins are below. More involved plugins are in separate files.
// jekyll-jemoji
type jekyllJemojiPlugin struct{ plugin }
func (p jekyllJemojiPlugin) PostRender(b []byte) []byte {
2017-07-09 22:17:20 +02:00
return utils.ApplyToHTMLText(b, func(s string) string {
2017-07-09 21:07:14 +02:00
s = emoji.Sprint(s)
return s
})
}
// jekyll-mentions
type jekyllMentionsPlugin struct{ plugin }
var mentionPattern = regexp.MustCompile(`@(\w+)`)
func (p jekyllMentionsPlugin) PostRender(b []byte) []byte {
2017-07-09 22:17:20 +02:00
return utils.ApplyToHTMLText(b, func(s string) string {
return mentionPattern.ReplaceAllString(s, `<a href="https://github.com/$1" class="user-mention">@$1</a>`)
})
}
2017-07-09 21:07:14 +02:00
// jekyll-seo
2017-07-09 04:47:50 +02:00
type jekyllSEOTagPlugin struct{ plugin }
func (p jekyllSEOTagPlugin) ConfigureTemplateEngine(e liquid.Engine) error {
p.stubbed("jekyll-seo-tag")
e.RegisterTag("seo", p.makeUnimplementedTag("jekyll-seo-tag"))
return nil
2017-07-01 16:37:11 +02:00
}
2017-07-09 21:07:14 +02:00
// helpers
2017-07-09 04:47:50 +02:00
func (p plugin) stubbed(name string) {
fmt.Printf("warning: gojekyll does not emulate the %s plugin. Some tags have been stubbed to prevent errors.\n", name)
2017-07-02 05:06:47 +02:00
}
2017-07-09 04:47:50 +02:00
func (p plugin) makeUnimplementedTag(pluginName string) liquid.Renderer {
2017-07-01 16:37:11 +02:00
warned := false
2017-07-04 23:13:47 +02:00
return func(ctx render.Context) (string, error) {
2017-07-01 16:37:11 +02:00
if !warned {
2017-07-09 04:47:50 +02:00
fmt.Printf("The %q tag in the %q plugin has not been implemented.\n", ctx.TagName(), pluginName)
2017-07-01 16:37:11 +02:00
warned = true
}
2017-07-09 03:41:35 +02:00
return fmt.Sprintf(`<!-- unimplemented tag: %q -->`, ctx.TagName()), nil
2017-07-01 16:37:11 +02:00
}
}