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
0fccd370
Commit
0fccd370
authored
May 08, 2015
by
Abiola Ibrahim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
markdown: documentation done. awaiting test
parent
2c7de8f3
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
66 deletions
+89
-66
middleware/markdown/markdown.go
middleware/markdown/markdown.go
+2
-2
middleware/markdown/metadata.go
middleware/markdown/metadata.go
+26
-13
middleware/markdown/process.go
middleware/markdown/process.go
+61
-51
No files found.
middleware/markdown/markdown.go
View file @
0fccd370
...
@@ -61,10 +61,10 @@ type Config struct {
...
@@ -61,10 +61,10 @@ type Config struct {
// Map of registered templates
// Map of registered templates
Templates
map
[
string
]
string
Templates
map
[
string
]
string
//
Static files
//
Map of request URL to static files generated
StaticFiles
map
[
string
]
string
StaticFiles
map
[
string
]
string
//
Static files directory
//
Directory to store static files
StaticDir
string
StaticDir
string
}
}
...
...
middleware/markdown/metadata.go
View file @
0fccd370
...
@@ -17,12 +17,17 @@ var (
...
@@ -17,12 +17,17 @@ var (
// Metadata stores a page's metadata
// Metadata stores a page's metadata
type
Metadata
struct
{
type
Metadata
struct
{
// Page title
Title
string
Title
string
// Page template
Template
string
Template
string
// Variables to be used with Template
Variables
map
[
string
]
interface
{}
Variables
map
[
string
]
interface
{}
}
}
//
Load loads parsed metadata into m
//
load loads parsed values in parsedMap into Metadata
func
(
m
*
Metadata
)
load
(
parsedMap
map
[
string
]
interface
{})
{
func
(
m
*
Metadata
)
load
(
parsedMap
map
[
string
]
interface
{})
{
if
template
,
ok
:=
parsedMap
[
"title"
];
ok
{
if
template
,
ok
:=
parsedMap
[
"title"
];
ok
{
m
.
Title
,
_
=
template
.
(
string
)
m
.
Title
,
_
=
template
.
(
string
)
...
@@ -35,14 +40,19 @@ func (m *Metadata) load(parsedMap map[string]interface{}) {
...
@@ -35,14 +40,19 @@ func (m *Metadata) load(parsedMap map[string]interface{}) {
}
}
}
}
// MetadataParser parses the page metadata
// MetadataParser is a an interface that must be satisfied by each parser
// into Metadata
type
MetadataParser
interface
{
type
MetadataParser
interface
{
//
Identifiers
//
Opening identifier
Opening
()
[]
byte
Opening
()
[]
byte
// Closing identifier
Closing
()
[]
byte
Closing
()
[]
byte
// Parse the metadata
Parse
([]
byte
)
error
Parse
([]
byte
)
error
// Parsed metadata.
// Should be called after a call to Parse returns no error
Metadata
()
Metadata
Metadata
()
Metadata
}
}
...
@@ -51,7 +61,7 @@ type JSONMetadataParser struct {
...
@@ -51,7 +61,7 @@ type JSONMetadataParser struct {
metadata
Metadata
metadata
Metadata
}
}
// Parse
parses b into
metadata
// Parse
the
metadata
func
(
j
*
JSONMetadataParser
)
Parse
(
b
[]
byte
)
error
{
func
(
j
*
JSONMetadataParser
)
Parse
(
b
[]
byte
)
error
{
m
:=
make
(
map
[
string
]
interface
{})
m
:=
make
(
map
[
string
]
interface
{})
if
err
:=
json
.
Unmarshal
(
b
,
&
m
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
b
,
&
m
);
err
!=
nil
{
...
@@ -61,7 +71,8 @@ func (j *JSONMetadataParser) Parse(b []byte) error {
...
@@ -61,7 +71,8 @@ func (j *JSONMetadataParser) Parse(b []byte) error {
return
nil
return
nil
}
}
// Metadata returns the metadata parsed by this parser
// Parsed metadata.
// Should be called after a call to Parse returns no error
func
(
j
*
JSONMetadataParser
)
Metadata
()
Metadata
{
func
(
j
*
JSONMetadataParser
)
Metadata
()
Metadata
{
return
j
.
metadata
return
j
.
metadata
}
}
...
@@ -81,7 +92,7 @@ type TOMLMetadataParser struct {
...
@@ -81,7 +92,7 @@ type TOMLMetadataParser struct {
metadata
Metadata
metadata
Metadata
}
}
// Parse
parses b into
metadata
// Parse
the
metadata
func
(
t
*
TOMLMetadataParser
)
Parse
(
b
[]
byte
)
error
{
func
(
t
*
TOMLMetadataParser
)
Parse
(
b
[]
byte
)
error
{
m
:=
make
(
map
[
string
]
interface
{})
m
:=
make
(
map
[
string
]
interface
{})
if
err
:=
toml
.
Unmarshal
(
b
,
&
m
);
err
!=
nil
{
if
err
:=
toml
.
Unmarshal
(
b
,
&
m
);
err
!=
nil
{
...
@@ -91,7 +102,8 @@ func (t *TOMLMetadataParser) Parse(b []byte) error {
...
@@ -91,7 +102,8 @@ func (t *TOMLMetadataParser) Parse(b []byte) error {
return
nil
return
nil
}
}
// Metadata returns the metadata parsed by this parser
// Parsed metadata.
// Should be called after a call to Parse returns no error
func
(
t
*
TOMLMetadataParser
)
Metadata
()
Metadata
{
func
(
t
*
TOMLMetadataParser
)
Metadata
()
Metadata
{
return
t
.
metadata
return
t
.
metadata
}
}
...
@@ -106,12 +118,12 @@ func (t *TOMLMetadataParser) Closing() []byte {
...
@@ -106,12 +118,12 @@ func (t *TOMLMetadataParser) Closing() []byte {
return
[]
byte
(
"+++"
)
return
[]
byte
(
"+++"
)
}
}
// YAMLMetadataParser is the MetdataParser for YAML
// YAMLMetadataParser is the Met
a
dataParser for YAML
type
YAMLMetadataParser
struct
{
type
YAMLMetadataParser
struct
{
metadata
Metadata
metadata
Metadata
}
}
// Parse
parses b into
metadata
// Parse
the
metadata
func
(
y
*
YAMLMetadataParser
)
Parse
(
b
[]
byte
)
error
{
func
(
y
*
YAMLMetadataParser
)
Parse
(
b
[]
byte
)
error
{
m
:=
make
(
map
[
string
]
interface
{})
m
:=
make
(
map
[
string
]
interface
{})
if
err
:=
yaml
.
Unmarshal
(
b
,
&
m
);
err
!=
nil
{
if
err
:=
yaml
.
Unmarshal
(
b
,
&
m
);
err
!=
nil
{
...
@@ -121,7 +133,8 @@ func (y *YAMLMetadataParser) Parse(b []byte) error {
...
@@ -121,7 +133,8 @@ func (y *YAMLMetadataParser) Parse(b []byte) error {
return
nil
return
nil
}
}
// Metadata returns the metadata parsed by this parser
// Parsed metadata.
// Should be called after a call to Parse returns no error
func
(
y
*
YAMLMetadataParser
)
Metadata
()
Metadata
{
func
(
y
*
YAMLMetadataParser
)
Metadata
()
Metadata
{
return
y
.
metadata
return
y
.
metadata
}
}
...
...
middleware/markdown/process.go
View file @
0fccd370
...
@@ -19,9 +19,9 @@ const (
...
@@ -19,9 +19,9 @@ const (
StaticDir
=
".caddy_static"
StaticDir
=
".caddy_static"
)
)
// process the contents of a page.
// process
processes
the contents of a page.
// It parses the metadata
if any and uses the template if found
// It parses the metadata
(if any) and uses the template (if found)
func
(
md
Markdown
)
process
(
c
Config
,
fp
ath
string
,
b
[]
byte
)
([]
byte
,
error
)
{
func
(
md
Markdown
)
process
(
c
Config
,
requestP
ath
string
,
b
[]
byte
)
([]
byte
,
error
)
{
metadata
,
markdown
,
err
:=
extractMetadata
(
b
)
metadata
,
markdown
,
err
:=
extractMetadata
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -46,10 +46,11 @@ func (md Markdown) process(c Config, fpath string, b []byte) ([]byte, error) {
...
@@ -46,10 +46,11 @@ func (md Markdown) process(c Config, fpath string, b []byte) ([]byte, error) {
// process markdown
// process markdown
markdown
=
blackfriday
.
Markdown
(
markdown
,
c
.
Renderer
,
0
)
markdown
=
blackfriday
.
Markdown
(
markdown
,
c
.
Renderer
,
0
)
// set it as body for template
// set it as body for template
metadata
.
Variables
[
"body"
]
=
string
(
markdown
)
metadata
.
Variables
[
"body"
]
=
string
(
markdown
)
return
md
.
processTemplate
(
c
,
fp
ath
,
tmpl
,
metadata
)
return
md
.
processTemplate
(
c
,
requestP
ath
,
tmpl
,
metadata
)
}
}
// extractMetadata extracts metadata content from a page.
// extractMetadata extracts metadata content from a page.
...
@@ -60,12 +61,12 @@ func extractMetadata(b []byte) (metadata Metadata, markdown []byte, err error) {
...
@@ -60,12 +61,12 @@ func extractMetadata(b []byte) (metadata Metadata, markdown []byte, err error) {
reader
:=
bytes
.
NewBuffer
(
b
)
reader
:=
bytes
.
NewBuffer
(
b
)
scanner
:=
bufio
.
NewScanner
(
reader
)
scanner
:=
bufio
.
NewScanner
(
reader
)
var
parser
MetadataParser
var
parser
MetadataParser
// if scanner.Scan() &&
// Read first line
// Read first line
if
scanner
.
Scan
()
{
if
scanner
.
Scan
()
{
line
:=
scanner
.
Bytes
()
line
:=
scanner
.
Bytes
()
parser
=
findParser
(
line
)
parser
=
findParser
(
line
)
// if no parser found
// if no parser found
,
// assume metadata not present
// assume metadata not present
if
parser
==
nil
{
if
parser
==
nil
{
return
metadata
,
b
,
nil
return
metadata
,
b
,
nil
...
@@ -78,7 +79,8 @@ func extractMetadata(b []byte) (metadata Metadata, markdown []byte, err error) {
...
@@ -78,7 +79,8 @@ func extractMetadata(b []byte) (metadata Metadata, markdown []byte, err error) {
// Read remaining lines until closing identifier is found
// Read remaining lines until closing identifier is found
for
scanner
.
Scan
()
{
for
scanner
.
Scan
()
{
line
:=
scanner
.
Bytes
()
line
:=
scanner
.
Bytes
()
// closing identifier found
// if closing identifier found
if
bytes
.
Equal
(
bytes
.
TrimSpace
(
line
),
parser
.
Closing
())
{
if
bytes
.
Equal
(
bytes
.
TrimSpace
(
line
),
parser
.
Closing
())
{
// parse the metadata
// parse the metadata
err
:=
parser
.
Parse
(
buf
.
Bytes
())
err
:=
parser
.
Parse
(
buf
.
Bytes
())
...
@@ -97,10 +99,12 @@ func extractMetadata(b []byte) (metadata Metadata, markdown []byte, err error) {
...
@@ -97,10 +99,12 @@ func extractMetadata(b []byte) (metadata Metadata, markdown []byte, err error) {
buf
.
Write
(
line
)
buf
.
Write
(
line
)
buf
.
WriteString
(
"
\r\n
"
)
buf
.
WriteString
(
"
\r\n
"
)
}
}
// closing identifier not found
return
metadata
,
nil
,
fmt
.
Errorf
(
"Metadata not closed. '%v' not found"
,
string
(
parser
.
Closing
()))
return
metadata
,
nil
,
fmt
.
Errorf
(
"Metadata not closed. '%v' not found"
,
string
(
parser
.
Closing
()))
}
}
// findParser
locates the parser for an
opening identifier
// findParser
finds the parser using line that contains
opening identifier
func
findParser
(
line
[]
byte
)
MetadataParser
{
func
findParser
(
line
[]
byte
)
MetadataParser
{
line
=
bytes
.
TrimSpace
(
line
)
line
=
bytes
.
TrimSpace
(
line
)
for
_
,
parser
:=
range
parsers
{
for
_
,
parser
:=
range
parsers
{
...
@@ -111,13 +115,16 @@ func findParser(line []byte) MetadataParser {
...
@@ -111,13 +115,16 @@ func findParser(line []byte) MetadataParser {
return
nil
return
nil
}
}
func
(
md
Markdown
)
processTemplate
(
c
Config
,
fpath
string
,
tmpl
[]
byte
,
metadata
Metadata
)
([]
byte
,
error
)
{
// processTemplate processes a template given a requestPath,
// if template is specified
// template (tmpl) and metadata
// replace parse the template
func
(
md
Markdown
)
processTemplate
(
c
Config
,
requestPath
string
,
tmpl
[]
byte
,
metadata
Metadata
)
([]
byte
,
error
)
{
if
tmpl
!=
nil
{
// if template is not specified,
tmpl
=
defaultTemplate
(
c
,
metadata
,
fpath
)
// use the default template
if
tmpl
==
nil
{
tmpl
=
defaultTemplate
(
c
,
metadata
,
requestPath
)
}
}
// process the template
b
:=
&
bytes
.
Buffer
{}
b
:=
&
bytes
.
Buffer
{}
t
,
err
:=
template
.
New
(
""
)
.
Parse
(
string
(
tmpl
))
t
,
err
:=
template
.
New
(
""
)
.
Parse
(
string
(
tmpl
))
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -128,7 +135,7 @@ func (md Markdown) processTemplate(c Config, fpath string, tmpl []byte, metadata
...
@@ -128,7 +135,7 @@ func (md Markdown) processTemplate(c Config, fpath string, tmpl []byte, metadata
}
}
// generate static page
// generate static page
if
err
=
md
.
generatePage
(
c
,
fp
ath
,
b
.
Bytes
());
err
!=
nil
{
if
err
=
md
.
generatePage
(
c
,
requestP
ath
,
b
.
Bytes
());
err
!=
nil
{
// if static page generation fails,
// if static page generation fails,
// nothing fatal, only log the error.
// nothing fatal, only log the error.
log
.
Println
(
err
)
log
.
Println
(
err
)
...
@@ -138,40 +145,10 @@ func (md Markdown) processTemplate(c Config, fpath string, tmpl []byte, metadata
...
@@ -138,40 +145,10 @@ func (md Markdown) processTemplate(c Config, fpath string, tmpl []byte, metadata
}
}
func
defaultTemplate
(
c
Config
,
metadata
Metadata
,
fpath
string
)
[]
byte
{
// generatePage generates a static html page from the markdown in content.
// else, use default template
func
(
md
Markdown
)
generatePage
(
c
Config
,
requestPath
string
,
content
[]
byte
)
error
{
var
scripts
,
styles
bytes
.
Buffer
// should not happen,
for
_
,
style
:=
range
c
.
Styles
{
// must be set on Markdown init.
styles
.
WriteString
(
strings
.
Replace
(
cssTemplate
,
"{{url}}"
,
style
,
1
))
styles
.
WriteString
(
"
\r\n
"
)
}
for
_
,
script
:=
range
c
.
Scripts
{
scripts
.
WriteString
(
strings
.
Replace
(
jsTemplate
,
"{{url}}"
,
script
,
1
))
scripts
.
WriteString
(
"
\r\n
"
)
}
// Title is first line (length-limited), otherwise filename
title
:=
metadata
.
Title
if
title
==
""
{
title
=
filepath
.
Base
(
fpath
)
if
body
,
_
:=
metadata
.
Variables
[
"body"
]
.
([]
byte
);
len
(
body
)
>
128
{
title
=
string
(
body
[
:
128
])
}
else
if
len
(
body
)
>
0
{
title
=
string
(
body
)
}
}
html
:=
[]
byte
(
htmlTemplate
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{title}}"
),
[]
byte
(
title
),
1
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{css}}"
),
styles
.
Bytes
(),
1
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{js}}"
),
scripts
.
Bytes
(),
1
)
return
html
}
func
(
md
Markdown
)
generatePage
(
c
Config
,
fpath
string
,
content
[]
byte
)
error
{
// should not happen
// must be set on init
if
c
.
StaticDir
==
""
{
if
c
.
StaticDir
==
""
{
return
fmt
.
Errorf
(
"Static directory not set"
)
return
fmt
.
Errorf
(
"Static directory not set"
)
}
}
...
@@ -184,12 +161,14 @@ func (md Markdown) generatePage(c Config, fpath string, content []byte) error {
...
@@ -184,12 +161,14 @@ func (md Markdown) generatePage(c Config, fpath string, content []byte) error {
}
}
}
}
filePath
:=
filepath
.
Join
(
c
.
StaticDir
,
fp
ath
)
filePath
:=
filepath
.
Join
(
c
.
StaticDir
,
requestP
ath
)
// If it is index file, use the directory instead
// If it is index file, use the directory instead
if
md
.
IsIndexFile
(
filepath
.
Base
(
fp
ath
))
{
if
md
.
IsIndexFile
(
filepath
.
Base
(
requestP
ath
))
{
filePath
,
_
=
filepath
.
Split
(
filePath
)
filePath
,
_
=
filepath
.
Split
(
filePath
)
}
}
// Create the directory in case it is not existing
if
err
:=
os
.
MkdirAll
(
filePath
,
os
.
FileMode
(
0755
));
err
!=
nil
{
if
err
:=
os
.
MkdirAll
(
filePath
,
os
.
FileMode
(
0755
));
err
!=
nil
{
return
err
return
err
}
}
...
@@ -201,10 +180,41 @@ func (md Markdown) generatePage(c Config, fpath string, content []byte) error {
...
@@ -201,10 +180,41 @@ func (md Markdown) generatePage(c Config, fpath string, content []byte) error {
return
err
return
err
}
}
c
.
StaticFiles
[
fp
ath
]
=
filePath
c
.
StaticFiles
[
requestP
ath
]
=
filePath
return
nil
return
nil
}
}
// defaultTemplate constructs a default template.
func
defaultTemplate
(
c
Config
,
metadata
Metadata
,
requestPath
string
)
[]
byte
{
var
scripts
,
styles
bytes
.
Buffer
for
_
,
style
:=
range
c
.
Styles
{
styles
.
WriteString
(
strings
.
Replace
(
cssTemplate
,
"{{url}}"
,
style
,
1
))
styles
.
WriteString
(
"
\r\n
"
)
}
for
_
,
script
:=
range
c
.
Scripts
{
scripts
.
WriteString
(
strings
.
Replace
(
jsTemplate
,
"{{url}}"
,
script
,
1
))
scripts
.
WriteString
(
"
\r\n
"
)
}
// Title is first line (length-limited), otherwise filename
title
:=
metadata
.
Title
if
title
==
""
{
title
=
filepath
.
Base
(
requestPath
)
if
body
,
_
:=
metadata
.
Variables
[
"body"
]
.
([]
byte
);
len
(
body
)
>
128
{
title
=
string
(
body
[
:
128
])
}
else
if
len
(
body
)
>
0
{
title
=
string
(
body
)
}
}
html
:=
[]
byte
(
htmlTemplate
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{title}}"
),
[]
byte
(
title
),
1
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{css}}"
),
styles
.
Bytes
(),
1
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{js}}"
),
scripts
.
Bytes
(),
1
)
return
html
}
const
(
const
(
htmlTemplate
=
`<!DOCTYPE html>
htmlTemplate
=
`<!DOCTYPE html>
<html>
<html>
...
...
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