Commit e0bc4260 authored by Tobias Weingartner's avatar Tobias Weingartner

Initial re-add of markdown summary functionality.

parent bd2a33dd
...@@ -3,7 +3,6 @@ package metadata ...@@ -3,7 +3,6 @@ package metadata
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"os"
"time" "time"
) )
...@@ -32,9 +31,6 @@ type Metadata struct { ...@@ -32,9 +31,6 @@ type Metadata struct {
// Flags to be used with Template // Flags to be used with Template
Flags map[string]bool Flags map[string]bool
// Directory entries present, if a directory
Dirents []os.FileInfo
} }
// NewMetadata() returns a new Metadata struct, loaded with the given map // NewMetadata() returns a new Metadata struct, loaded with the given map
......
package markdown package markdown
import ( import (
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"github.com/mholt/caddy/middleware" "github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/markdown/metadata" "github.com/mholt/caddy/middleware/markdown/metadata"
"github.com/mholt/caddy/middleware/markdown/summary"
"github.com/russross/blackfriday" "github.com/russross/blackfriday"
) )
type FileInfo struct {
os.FileInfo
ctx middleware.Context
}
func (f FileInfo) Summarize(wordcount int) string {
fp, err := f.ctx.Root.Open(f.Name())
if err != nil {
return ""
}
defer fp.Close()
buf, err := ioutil.ReadAll(fp)
if err != nil {
return ""
}
return string(summary.Markdown(buf, wordcount))
}
// Markdown processes the contents of a page in b. It parses the metadata // Markdown processes the contents of a page in b. It parses the metadata
// (if any) and uses the template (if found). // (if any) and uses the template (if found).
func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, ctx middleware.Context) ([]byte, error) { func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, ctx middleware.Context) ([]byte, error) {
...@@ -26,6 +48,8 @@ func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, c ...@@ -26,6 +48,8 @@ func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, c
// set it as body for template // set it as body for template
mdata.Variables["body"] = string(markdown) mdata.Variables["body"] = string(markdown)
// fixup title
title := mdata.Title title := mdata.Title
if title == "" { if title == "" {
title = filepath.Base(requestPath) title = filepath.Base(requestPath)
...@@ -34,12 +58,15 @@ func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, c ...@@ -34,12 +58,15 @@ func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, c
} }
mdata.Variables["title"] = title mdata.Variables["title"] = title
if len(dirents) > 0 { // massage possible files
mdata.Flags["dirents"] = true files := []FileInfo{}
mdata.Dirents = dirents for _, ent := range dirents {
} else { file := FileInfo{
mdata.Flags["dirents"] = false FileInfo: ent,
ctx: ctx,
}
files = append(files, file)
} }
return execTemplate(c, mdata, ctx) return execTemplate(c, mdata, files, ctx)
} }
package summary
import (
"bytes"
"github.com/russross/blackfriday"
)
// Ensure we implement the Blackfriday Markdown Renderer interface
var _ blackfriday.Renderer = (*Renderer)(nil)
type Renderer struct{}
// Blocklevel callbacks
// BlockCode is the code tag callback.
func (r Renderer) BlockCode(out *bytes.Buffer, text []byte, land string) {}
// BlockQuote is teh quote tag callback.
func (r Renderer) BlockQuote(out *bytes.Buffer, text []byte) {}
// BlockHtml is the HTML tag callback.
func (r Renderer) BlockHtml(out *bytes.Buffer, text []byte) {}
// Header is the header tag callback.
func (r Renderer) Header(out *bytes.Buffer, text func() bool, level int, id string) {}
// HRule is the horizontal rule tag callback.
func (r Renderer) HRule(out *bytes.Buffer) {}
// List is the list tag callback.
func (r Renderer) List(out *bytes.Buffer, text func() bool, flags int) {
// TODO: This is not desired (we'd rather not write lists as part of summary),
// but see this issue: https://github.com/russross/blackfriday/issues/189
marker := out.Len()
if !text() {
out.Truncate(marker)
}
out.Write([]byte{' '})
}
// ListItem is the list item tag callback.
func (r Renderer) ListItem(out *bytes.Buffer, text []byte, flags int) {}
// Paragraph is the paragraph tag callback.
func (r Renderer) Paragraph(out *bytes.Buffer, text func() bool) {
marker := out.Len()
if !text() {
out.Truncate(marker)
}
out.Write([]byte{' '})
}
// Table is the table tag callback.
func (r Renderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {}
// TableRow is the table row tag callback.
func (r Renderer) TableRow(out *bytes.Buffer, text []byte) {}
// TableHeaderCell is the table header cell tag callback.
func (r Renderer) TableHeaderCell(out *bytes.Buffer, text []byte, flags int) {}
// TableCell is the table cell tag callback.
func (r Renderer) TableCell(out *bytes.Buffer, text []byte, flags int) {}
// Footnotes is the foot notes tag callback.
func (r Renderer) Footnotes(out *bytes.Buffer, text func() bool) {}
// FootnoteItem is the footnote item tag callback.
func (r Renderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {}
// TitleBlock is the title tag callback.
func (r Renderer) TitleBlock(out *bytes.Buffer, text []byte) {}
// Spanlevel callbacks
// AutoLink is the autolink tag callback.
func (r Renderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {}
// CodeSpan is the code span tag callback.
func (r Renderer) CodeSpan(out *bytes.Buffer, text []byte) {
out.Write([]byte("`"))
out.Write(text)
out.Write([]byte("`"))
}
// DoubleEmphasis is the double emphasis tag callback.
func (r Renderer) DoubleEmphasis(out *bytes.Buffer, text []byte) {
out.Write(text)
}
// Emphasis is the emphasis tag callback.
func (r Renderer) Emphasis(out *bytes.Buffer, text []byte) {
out.Write(text)
}
// Image is the image tag callback.
func (r Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {}
// LineBreak is the line break tag callback.
func (r Renderer) LineBreak(out *bytes.Buffer) {}
// Link is the link tag callback.
func (r Renderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
out.Write(content)
}
// RawHtmlTag is the raw HTML tag callback.
func (r Renderer) RawHtmlTag(out *bytes.Buffer, tag []byte) {}
// TripleEmphasis is the triple emphasis tag callback.
func (r Renderer) TripleEmphasis(out *bytes.Buffer, text []byte) {
out.Write(text)
}
// StrikeThrough is the strikethrough tag callback.
func (r Renderer) StrikeThrough(out *bytes.Buffer, text []byte) {}
// FootnoteRef is the footnote ref tag callback.
func (r Renderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {}
// Lowlevel callbacks
// Entity callback.
func (r Renderer) Entity(out *bytes.Buffer, entity []byte) {
out.Write(entity)
}
// NormalText callback.
func (r Renderer) NormalText(out *bytes.Buffer, text []byte) {
out.Write(text)
}
// Header and footer
// DocumentHeader callback.
func (r Renderer) DocumentHeader(out *bytes.Buffer) {}
// DocumentFooter callback.
func (r Renderer) DocumentFooter(out *bytes.Buffer) {}
// GetFlags returns zero.
func (r Renderer) GetFlags() int { return 0 }
package summary
import (
"bytes"
"github.com/russross/blackfriday"
)
func Markdown(input []byte, wordcount int) []byte {
words := bytes.Fields(blackfriday.Markdown(input, Renderer{}, 0))
if wordcount > len(words) {
wordcount = len(words)
}
return bytes.Join(words[0:wordcount], []byte{' '})
}
...@@ -3,7 +3,7 @@ package markdown ...@@ -3,7 +3,7 @@ package markdown
import ( import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" // "os"
"text/template" "text/template"
"github.com/mholt/caddy/middleware" "github.com/mholt/caddy/middleware"
...@@ -17,7 +17,7 @@ type Data struct { ...@@ -17,7 +17,7 @@ type Data struct {
DocFlags map[string]bool DocFlags map[string]bool
Styles []string Styles []string
Scripts []string Scripts []string
Files []os.FileInfo Files []FileInfo
} }
// Include "overrides" the embedded middleware.Context's Include() // Include "overrides" the embedded middleware.Context's Include()
...@@ -28,13 +28,14 @@ func (d Data) Include(filename string) (string, error) { ...@@ -28,13 +28,14 @@ func (d Data) Include(filename string) (string, error) {
} }
// execTemplate executes a template given a requestPath, template, and metadata // execTemplate executes a template given a requestPath, template, and metadata
func execTemplate(c *Config, mdata metadata.Metadata, ctx middleware.Context) ([]byte, error) { func execTemplate(c *Config, mdata metadata.Metadata, files []FileInfo, ctx middleware.Context) ([]byte, error) {
mdData := Data{ mdData := Data{
Context: ctx, Context: ctx,
Doc: mdata.Variables, Doc: mdata.Variables,
DocFlags: mdata.Flags, DocFlags: mdata.Flags,
Styles: c.Styles, Styles: c.Styles,
Scripts: c.Scripts, Scripts: c.Scripts,
Files: files,
} }
b := new(bytes.Buffer) b := new(bytes.Buffer)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment