Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
2bccc146
Commit
2bccc146
authored
Apr 30, 2016
by
Tobias Weingartner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixup and address most of the feedback.
parent
a3af232d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
116 additions
and
99 deletions
+116
-99
middleware/markdown/markdown.go
middleware/markdown/markdown.go
+50
-48
middleware/markdown/markdown_test.go
middleware/markdown/markdown_test.go
+11
-0
middleware/markdown/process.go
middleware/markdown/process.go
+14
-11
middleware/markdown/summary/render.go
middleware/markdown/summary/render.go
+39
-30
middleware/markdown/summary/summary.go
middleware/markdown/summary/summary.go
+2
-0
middleware/markdown/template.go
middleware/markdown/template.go
+0
-10
No files found.
middleware/markdown/markdown.go
View file @
2bccc146
...
...
@@ -3,10 +3,10 @@
package
markdown
import
(
"io/ioutil"
"net/http"
"os"
"path"
"strings"
"text/template"
"time"
...
...
@@ -83,17 +83,22 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
// URL points to, and pass that in to any possible template invocations,
// so that templates can customize the look and feel of a directory.
fdp
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
if
os
.
IsPermission
(
err
)
{
return
http
.
StatusForbidden
,
err
}
switch
{
case
err
==
nil
:
// nop
case
os
.
IsPermission
(
err
)
:
return
http
.
StatusForbidden
,
err
case
os
.
IsExist
(
err
)
:
return
http
.
StatusNotFound
,
nil
default
:
// did we run out of FD?
return
http
.
StatusInternalServerError
,
err
}
defer
fdp
.
Close
()
// Grab a possible set of directory entries. Note, we do not check
// for errors here (unreadable directory, for example). It may
// still be useful to have a directory template file, without the
// directory contents being present.
// directory contents being present. Note, the directory's last
// modification is also present here (entry ".").
dirents
,
_
=
fdp
.
Readdir
(
-
1
)
for
_
,
d
:=
range
dirents
{
lastModTime
=
latest
(
lastModTime
,
d
.
ModTime
())
...
...
@@ -103,53 +108,45 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
fpath
=
idx
}
// If supported extension, process it
if
_
,
ok
:=
cfg
.
Extensions
[
path
.
Ext
(
fpath
)];
ok
{
f
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
if
os
.
IsPermission
(
err
)
{
return
http
.
StatusForbidden
,
err
}
return
http
.
StatusNotFound
,
nil
}
fs
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
return
http
.
StatusNotFound
,
nil
}
lastModTime
=
latest
(
lastModTime
,
fs
.
ModTime
())
body
,
err
:=
ioutil
.
ReadAll
(
f
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
// If not supported extension, pass on it
if
_
,
ok
:=
cfg
.
Extensions
[
path
.
Ext
(
fpath
)];
!
ok
{
return
md
.
Next
.
ServeHTTP
(
w
,
r
)
}
ctx
:=
middleware
.
Context
{
Root
:
md
.
FileSys
,
Req
:
r
,
URL
:
r
.
URL
,
}
html
,
err
:=
cfg
.
Markdown
(
fpath
,
body
,
dirents
,
ctx
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
// At this point we have a supported extension/markdown
f
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
switch
{
case
err
==
nil
:
// nop
case
os
.
IsPermission
(
err
)
:
return
http
.
StatusForbidden
,
err
case
os
.
IsExist
(
err
)
:
return
http
.
StatusNotFound
,
nil
default
:
// did we run out of FD?
return
http
.
StatusInternalServerError
,
err
}
defer
f
.
Close
()
// TODO(weingart): move template execution here, something like:
//
// html, err = md.execTemplate(cfg, html, ctx)
// if err != nil {
// return http.StatusInternalServerError, err
// }
if
fs
,
err
:=
f
.
Stat
();
err
!=
nil
{
return
http
.
StatusGone
,
nil
}
else
{
lastModTime
=
latest
(
lastModTime
,
fs
.
ModTime
())
}
middleware
.
SetLastModifiedHeader
(
w
,
lastModTime
)
if
r
.
Method
==
http
.
MethodGet
{
w
.
Write
(
html
)
}
return
http
.
StatusOK
,
nil
ctx
:=
middleware
.
Context
{
Root
:
md
.
FileSys
,
Req
:
r
,
URL
:
r
.
URL
,
}
html
,
err
:=
cfg
.
Markdown
(
title
(
fpath
),
f
,
dirents
,
ctx
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
// Didn't qualify to serve as markdown; pass-thru
return
md
.
Next
.
ServeHTTP
(
w
,
r
)
middleware
.
SetLastModifiedHeader
(
w
,
lastModTime
)
if
r
.
Method
==
http
.
MethodGet
{
w
.
Write
(
html
)
}
return
http
.
StatusOK
,
nil
}
// latest returns the latest time.Time
...
...
@@ -164,3 +161,8 @@ func latest(t ...time.Time) time.Time {
return
last
}
// title gives a backup generated title for a page
func
title
(
p
string
)
string
{
return
strings
.
TrimRight
(
path
.
Base
(
p
),
path
.
Ext
(
p
))
}
middleware/markdown/markdown_test.go
View file @
2bccc146
...
...
@@ -2,12 +2,14 @@ package markdown
import
(
"bufio"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"text/template"
"time"
"github.com/mholt/caddy/middleware"
...
...
@@ -217,3 +219,12 @@ func equalStrings(s1, s2 string) bool {
}
return
true
}
func
setDefaultTemplate
(
filename
string
)
*
template
.
Template
{
buf
,
err
:=
ioutil
.
ReadFile
(
filename
)
if
err
!=
nil
{
return
nil
}
return
template
.
Must
(
GetDefaultTemplate
()
.
Parse
(
string
(
buf
)))
}
middleware/markdown/process.go
View file @
2bccc146
package
markdown
import
(
"io"
"io/ioutil"
"os"
"path/filepath"
//
"path/filepath"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/markdown/metadata"
...
...
@@ -33,8 +34,13 @@ func (f FileInfo) Summarize(wordcount int) (string, error) {
// 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
)
{
parser
:=
metadata
.
GetParser
(
b
)
func
(
c
*
Config
)
Markdown
(
title
string
,
r
io
.
Reader
,
dirents
[]
os
.
FileInfo
,
ctx
middleware
.
Context
)
([]
byte
,
error
)
{
body
,
err
:=
ioutil
.
ReadAll
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
parser
:=
metadata
.
GetParser
(
body
)
markdown
:=
parser
.
Markdown
()
mdata
:=
parser
.
Metadata
()
...
...
@@ -44,19 +50,16 @@ func (c *Config) Markdown(requestPath string, b []byte, dirents []os.FileInfo, c
extns
|=
blackfriday
.
EXTENSION_FENCED_CODE
extns
|=
blackfriday
.
EXTENSION_STRIKETHROUGH
extns
|=
blackfriday
.
EXTENSION_DEFINITION_LISTS
markdown
=
blackfriday
.
Markdown
(
markdown
,
c
.
Renderer
,
extns
)
html
:
=
blackfriday
.
Markdown
(
markdown
,
c
.
Renderer
,
extns
)
// set it as body for template
mdata
.
Variables
[
"body"
]
=
string
(
markdown
)
mdata
.
Variables
[
"body"
]
=
string
(
html
)
// fixup title
title
:=
mdata
.
Title
if
title
==
""
{
title
=
filepath
.
Base
(
requestPath
)
var
extension
=
filepath
.
Ext
(
requestPath
)
title
=
title
[
0
:
len
(
title
)
-
len
(
extension
)]
mdata
.
Variables
[
"title"
]
=
mdata
.
Title
if
mdata
.
Variables
[
"title"
]
==
""
{
mdata
.
Variables
[
"title"
]
=
title
}
mdata
.
Variables
[
"title"
]
=
title
// massage possible files
files
:=
[]
FileInfo
{}
...
...
middleware/markdown/summary/render.go
View file @
2bccc146
...
...
@@ -9,23 +9,26 @@ import (
// Ensure we implement the Blackfriday Markdown Renderer interface
var
_
blackfriday
.
Renderer
=
(
*
Renderer
)(
nil
)
// Renderer is a plain-text Markdown renderer that implements the
// blackfriday.Renderer interface. Many of the required methods are
// stubs with no output.
type
Renderer
struct
{}
// Blocklevel callbacks
// BlockCode is the code tag callback.
//
Stub
BlockCode is the code tag callback.
func
(
r
Renderer
)
BlockCode
(
out
*
bytes
.
Buffer
,
text
[]
byte
,
land
string
)
{}
// BlockQuote is teh quote tag callback.
//
Stub
BlockQuote is teh quote tag callback.
func
(
r
Renderer
)
BlockQuote
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{}
// BlockHtml is the HTML tag callback.
//
Stub
BlockHtml is the HTML tag callback.
func
(
r
Renderer
)
BlockHtml
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{}
// Header is the header tag callback.
//
Stub
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.
//
Stub
HRule is the horizontal rule tag callback.
func
(
r
Renderer
)
HRule
(
out
*
bytes
.
Buffer
)
{}
// List is the list tag callback.
...
...
@@ -39,10 +42,11 @@ func (r Renderer) List(out *bytes.Buffer, text func() bool, flags int) {
out
.
Write
([]
byte
{
' '
})
}
// ListItem is the list item tag callback.
//
Stub
ListItem is the list item tag callback.
func
(
r
Renderer
)
ListItem
(
out
*
bytes
.
Buffer
,
text
[]
byte
,
flags
int
)
{}
// Paragraph is the paragraph tag callback.
// Paragraph is the paragraph tag callback. This renders simple paragraph text
// into plain text, such that summaries can be easily generated.
func
(
r
Renderer
)
Paragraph
(
out
*
bytes
.
Buffer
,
text
func
()
bool
)
{
marker
:=
out
.
Len
()
if
!
text
()
{
...
...
@@ -51,93 +55,98 @@ func (r Renderer) Paragraph(out *bytes.Buffer, text func() bool) {
out
.
Write
([]
byte
{
' '
})
}
// Table is the table tag callback.
//
Stub
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.
//
Stub
TableRow is the table row tag callback.
func
(
r
Renderer
)
TableRow
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{}
// TableHeaderCell is the table header cell tag callback.
//
Stub
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.
//
Stub
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.
//
Stub
Footnotes is the foot notes tag callback.
func
(
r
Renderer
)
Footnotes
(
out
*
bytes
.
Buffer
,
text
func
()
bool
)
{}
// FootnoteItem is the footnote item tag callback.
//
Stub
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.
//
Stub
TitleBlock is the title tag callback.
func
(
r
Renderer
)
TitleBlock
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{}
// Spanlevel callbacks
// AutoLink is the autolink tag callback.
//
Stub
AutoLink is the autolink tag callback.
func
(
r
Renderer
)
AutoLink
(
out
*
bytes
.
Buffer
,
link
[]
byte
,
kind
int
)
{}
// CodeSpan is the code span tag callback.
// CodeSpan is the code span tag callback. Outputs a simple Markdown version
// of the code span.
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.
// DoubleEmphasis is the double emphasis tag callback. Outputs a simple
// plain-text version of the input.
func
(
r
Renderer
)
DoubleEmphasis
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{
out
.
Write
(
text
)
}
// Emphasis is the emphasis tag callback.
// Emphasis is the emphasis tag callback. Outputs a simple plain-text
// version of the input.
func
(
r
Renderer
)
Emphasis
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{
out
.
Write
(
text
)
}
// Image is the image tag callback.
//
Stub
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.
//
Stub
LineBreak is the line break tag callback.
func
(
r
Renderer
)
LineBreak
(
out
*
bytes
.
Buffer
)
{}
// Link is the link tag callback.
// Link is the link tag callback. Outputs a sipmle plain-text version
// of the input.
func
(
r
Renderer
)
Link
(
out
*
bytes
.
Buffer
,
link
[]
byte
,
title
[]
byte
,
content
[]
byte
)
{
out
.
Write
(
content
)
}
// RawHtmlTag is the raw HTML tag callback.
//
Stub
RawHtmlTag is the raw HTML tag callback.
func
(
r
Renderer
)
RawHtmlTag
(
out
*
bytes
.
Buffer
,
tag
[]
byte
)
{}
// TripleEmphasis is the triple emphasis tag callback.
// TripleEmphasis is the triple emphasis tag callback. Outputs a simple plain-text
// version of the input.
func
(
r
Renderer
)
TripleEmphasis
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{
out
.
Write
(
text
)
}
// StrikeThrough is the strikethrough tag callback.
// St
ub St
rikeThrough is the strikethrough tag callback.
func
(
r
Renderer
)
StrikeThrough
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{}
// FootnoteRef is the footnote ref tag callback.
//
Stub
FootnoteRef is the footnote ref tag callback.
func
(
r
Renderer
)
FootnoteRef
(
out
*
bytes
.
Buffer
,
ref
[]
byte
,
id
int
)
{}
// Lowlevel callbacks
// Entity callback.
// Entity callback.
Outputs a simple plain-text version of the input.
func
(
r
Renderer
)
Entity
(
out
*
bytes
.
Buffer
,
entity
[]
byte
)
{
out
.
Write
(
entity
)
}
// NormalText callback.
// NormalText callback.
Outputs a simple plain-text version of the input.
func
(
r
Renderer
)
NormalText
(
out
*
bytes
.
Buffer
,
text
[]
byte
)
{
out
.
Write
(
text
)
}
// Header and footer
// DocumentHeader callback.
//
Stub
DocumentHeader callback.
func
(
r
Renderer
)
DocumentHeader
(
out
*
bytes
.
Buffer
)
{}
// DocumentFooter callback.
//
Stub
DocumentFooter callback.
func
(
r
Renderer
)
DocumentFooter
(
out
*
bytes
.
Buffer
)
{}
// GetFlags returns zero.
//
Stub
GetFlags returns zero.
func
(
r
Renderer
)
GetFlags
()
int
{
return
0
}
middleware/markdown/summary/summary.go
View file @
2bccc146
...
...
@@ -6,6 +6,8 @@ import (
"github.com/russross/blackfriday"
)
// Markdown formats input using a plain-text renderer, and
// then returns up to the first `wordcount` words as a summary.
func
Markdown
(
input
[]
byte
,
wordcount
int
)
[]
byte
{
words
:=
bytes
.
Fields
(
blackfriday
.
Markdown
(
input
,
Renderer
{},
0
))
if
wordcount
>
len
(
words
)
{
...
...
middleware/markdown/template.go
View file @
2bccc146
...
...
@@ -3,7 +3,6 @@ package markdown
import
(
"bytes"
"io/ioutil"
// "os"
"text/template"
"github.com/mholt/caddy/middleware"
...
...
@@ -46,15 +45,6 @@ func execTemplate(c *Config, mdata metadata.Metadata, files []FileInfo, ctx midd
return
b
.
Bytes
(),
nil
}
func
setDefaultTemplate
(
filename
string
)
*
template
.
Template
{
buf
,
err
:=
ioutil
.
ReadFile
(
filename
)
if
err
!=
nil
{
return
nil
}
return
template
.
Must
(
GetDefaultTemplate
()
.
Parse
(
string
(
buf
)))
}
func
SetTemplate
(
t
*
template
.
Template
,
name
,
filename
string
)
error
{
// Read template
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment