Minimal working prototype

This commit is contained in:
2022-12-26 02:57:25 +01:00
parent 7d22424cf1
commit 38b1017681
20 changed files with 733 additions and 72 deletions
+73
View File
@@ -0,0 +1,73 @@
package operation
import (
"html/template"
"log"
"mime"
"path/filepath"
"strings"
gopath "path"
"github.com/alecthomas/repr"
"github.com/aziis98/cabret"
"github.com/aziis98/cabret/operation/layout"
"github.com/aziis98/cabret/util"
)
var HtmlMimeType = mime.TypeByExtension(".html")
var _ cabret.Operation = Layout{}
type Layout struct {
// TemplateFilesPattern is a comma separated list of unix glob patterns
TemplateFilesPattern string
Options map[string]any
}
func (op Layout) Process(content cabret.Content) (*cabret.Content, error) {
var tmpl layout.Template
patterns := strings.Split(op.TemplateFilesPattern, ",")
tmplFiles := []string{}
for _, pat := range patterns {
files, err := filepath.Glob(strings.TrimSpace(pat))
if err != nil {
return nil, err
}
tmplFiles = append(tmplFiles, files...)
}
log.Printf(`[Layout] template pattern "%s" expanded to %s`, op.TemplateFilesPattern, repr.String(tmplFiles))
if gopath.Ext(tmplFiles[0]) == ".html" {
var err error
if tmpl, err = layout.NewHtmlTemplate(tmplFiles...); err != nil {
return nil, err
}
} else {
var err error
if tmpl, err = layout.NewTextTemplate(tmplFiles...); err != nil {
return nil, err
}
}
ctx := util.CloneMap(content.Metadata)
if content.Type == HtmlMimeType {
ctx["Content"] = template.HTML(content.Data)
} else {
ctx["Content"] = content.Data
}
data, err := tmpl.Render(ctx)
if err != nil {
return nil, err
}
content.Data = data
return &content, nil
}
+31
View File
@@ -0,0 +1,31 @@
package layout
import (
"bytes"
"html/template"
)
var _ Template = HtmlTemplate{}
type HtmlTemplate struct {
*template.Template
}
func NewHtmlTemplate(files ...string) (*HtmlTemplate, error) {
t, err := template.ParseFiles(files...)
if err != nil {
return nil, err
}
return &HtmlTemplate{t}, nil
}
func (t HtmlTemplate) Render(ctx map[string]any) ([]byte, error) {
var b bytes.Buffer
if err := t.Template.Execute(&b, ctx); err != nil {
return nil, err
}
return b.Bytes(), nil
}
+5
View File
@@ -0,0 +1,5 @@
package layout
type Template interface {
Render(ctx map[string]any) ([]byte, error)
}
+31
View File
@@ -0,0 +1,31 @@
package layout
import (
"bytes"
"text/template"
)
var _ Template = TextTemplate{}
type TextTemplate struct {
*template.Template
}
func NewTextTemplate(files ...string) (*TextTemplate, error) {
t, err := template.ParseFiles(files...)
if err != nil {
return nil, err
}
return &TextTemplate{t}, nil
}
func (t TextTemplate) Render(ctx map[string]any) ([]byte, error) {
var b bytes.Buffer
if err := t.Template.Execute(&b, ctx); err != nil {
return nil, err
}
return b.Bytes(), nil
}
+46
View File
@@ -0,0 +1,46 @@
package operation
import (
"bytes"
"github.com/aziis98/cabret"
"github.com/iancoleman/strcase"
"github.com/yuin/goldmark"
meta "github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
)
type Markdown struct {
Options map[string]any
}
func (op Markdown) Process(content cabret.Content) (*cabret.Content, error) {
md := goldmark.New(
goldmark.WithExtensions(
extension.GFM,
meta.Meta,
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
)
var buf bytes.Buffer
context := parser.NewContext()
if err := md.Convert(content.Data, &buf, parser.WithContext(context)); err != nil {
panic(err)
}
frontmatter := meta.Get(context)
for k, v := range frontmatter {
content.Metadata[strcase.ToCamel(k)] = v
}
return &cabret.Content{
Type: HtmlMimeType,
Data: buf.Bytes(),
Metadata: content.Metadata,
}, nil
}
+36
View File
@@ -0,0 +1,36 @@
package operation
import (
"fmt"
"os"
gopath "path"
"github.com/aziis98/cabret"
"github.com/aziis98/cabret/path"
)
var _ cabret.Operation = Target{}
type Target struct {
PathTemplate string
}
func (op Target) Process(c cabret.Content) (*cabret.Content, error) {
mr, ok := c.Metadata[cabret.MatchResult].(map[string]string)
if !ok {
return nil, fmt.Errorf(`invalid match result type %T`, c.Metadata[cabret.MatchResult])
}
target := path.RenderTemplate(op.PathTemplate, mr)
if err := os.MkdirAll(gopath.Dir(target), 0777); err != nil {
return nil, err
}
if err := os.WriteFile(target, c.Data, 0666); err != nil {
return nil, err
}
c.Metadata["Target"] = op.PathTemplate
return &c, nil
}