mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-21 01:45:45 +03:00
Initial re-add of markdown summary functionality.
This commit is contained in:
parent
bd2a33dd14
commit
e0bc426050
5 changed files with 196 additions and 13 deletions
|
@ -3,7 +3,6 @@ package metadata
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -32,9 +31,6 @@ type Metadata struct {
|
|||
|
||||
// Flags to be used with Template
|
||||
Flags map[string]bool
|
||||
|
||||
// Directory entries present, if a directory
|
||||
Dirents []os.FileInfo
|
||||
}
|
||||
|
||||
// NewMetadata() returns a new Metadata struct, loaded with the given map
|
||||
|
|
|
@ -1,14 +1,36 @@
|
|||
package markdown
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/mholt/caddy/middleware"
|
||||
"github.com/mholt/caddy/middleware/markdown/metadata"
|
||||
"github.com/mholt/caddy/middleware/markdown/summary"
|
||||
"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
|
||||
// (if any) and uses the template (if found).
|
||||
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
|
|||
|
||||
// set it as body for template
|
||||
mdata.Variables["body"] = string(markdown)
|
||||
|
||||
// fixup title
|
||||
title := mdata.Title
|
||||
if title == "" {
|
||||
title = filepath.Base(requestPath)
|
||||
|
@ -34,12 +58,15 @@ func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, c
|
|||
}
|
||||
mdata.Variables["title"] = title
|
||||
|
||||
if len(dirents) > 0 {
|
||||
mdata.Flags["dirents"] = true
|
||||
mdata.Dirents = dirents
|
||||
} else {
|
||||
mdata.Flags["dirents"] = false
|
||||
// massage possible files
|
||||
files := []FileInfo{}
|
||||
for _, ent := range dirents {
|
||||
file := FileInfo{
|
||||
FileInfo: ent,
|
||||
ctx: ctx,
|
||||
}
|
||||
files = append(files, file)
|
||||
}
|
||||
|
||||
return execTemplate(c, mdata, ctx)
|
||||
return execTemplate(c, mdata, files, ctx)
|
||||
}
|
||||
|
|
143
middleware/markdown/summary/render.go
Normal file
143
middleware/markdown/summary/render.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
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 }
|
16
middleware/markdown/summary/summary.go
Normal file
16
middleware/markdown/summary/summary.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
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
|
|||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
// "os"
|
||||
"text/template"
|
||||
|
||||
"github.com/mholt/caddy/middleware"
|
||||
|
@ -17,7 +17,7 @@ type Data struct {
|
|||
DocFlags map[string]bool
|
||||
Styles []string
|
||||
Scripts []string
|
||||
Files []os.FileInfo
|
||||
Files []FileInfo
|
||||
}
|
||||
|
||||
// Include "overrides" the embedded middleware.Context's Include()
|
||||
|
@ -28,13 +28,14 @@ func (d Data) Include(filename string) (string, error) {
|
|||
}
|
||||
|
||||
// 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{
|
||||
Context: ctx,
|
||||
Doc: mdata.Variables,
|
||||
DocFlags: mdata.Flags,
|
||||
Styles: c.Styles,
|
||||
Scripts: c.Scripts,
|
||||
Files: files,
|
||||
}
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
|
|
Loading…
Reference in a new issue