Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
tantalic committed Jan 31, 2017
2 parents c838953 + 1f87d33 commit a4c865d
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 97 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ Usage: `servemd [OPTIONS] [DIR]`
| `HOST` | `-a, --host` | Host/IP address to listen on | All addresses |
| `PORT` | `-p, --port` | TCP port to listen on | `3000` |
| `BASIC_AUTH` | `-u, --auth` | Username and password for HTTP basic authentication. In the form of `user1:pass1,user2:pass2` | None |
| `X_ROBOTS_TAG` | `-r --x-robots-tag` | Sets a `X-Robots-Tag` header. Example: `"noindex, nofollow"` | None |
| `DOCUMENT_EXTENSION` | `-e, --extension` | Extension used for markdown files | `.md` |
| `DIRECTORY_INDEX` | `-i, --index` | Filename (without extension) to use for directory indexes | `index` |
| `MARKDOWN_THEME` | `-m, --markdown-theme` | Theme to use for styling markdown. Values: *clean*, *github*, *developer* | `clean` |
| `MARKDOWN_THEME` | `-m, --markdown-theme` | Theme to use for styling markdown. Can be one of the following built-in themes: *clean*, *github*, *developer* or the path to a custom CSS file to include. | `clean` |
| `CODE_THEME` | `-c, --code-theme` | Syntax highlighting theme (powered by [highlight.js][highlightjs]) | None |


Expand Down
2 changes: 1 addition & 1 deletion assets/templates/document.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

{{if .MarkdownTheme}}
<!-- Markdown Theme -->
<link rel="stylesheet" type="text/css" href="/assets/themes/{{.MarkdownTheme}}.css">
<link rel="stylesheet" type="text/css" href="{{.MarkdownTheme}}">
{{end}}

{{if .CodeTheme}}
Expand Down
175 changes: 89 additions & 86 deletions bindata_assetfs.go

Large diffs are not rendered by default.

26 changes: 20 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import (
)

const (
Version = "0.4.0"
Version = "0.5.0"
DefaultTheme = "clean"
)

type httpHandleFunc func(w http.ResponseWriter, r *http.Request)

func main() {
app := cli.App("servemd", "a simple http server for markdown content")
app.Version("v version", Version)
Expand All @@ -38,6 +37,12 @@ func main() {
Desc: "Username and password for basic authentication in the form of user:pass",
EnvVar: "BASIC_AUTH",
})
robotsTag = app.String(cli.StringOpt{
Name: "r x-robots-tag",
Desc: "Sets a X-Robots-Tag header",
EnvVar: "X_ROBOTS_TAG",
Value: "",
})

// Content
dir = app.String(cli.StringArg{
Expand All @@ -63,7 +68,7 @@ func main() {
markdownTheme = app.String(cli.StringOpt{
Name: "m markdown-theme",
Desc: "Theme to use for styling markdown html",
Value: "clean",
Value: DefaultTheme,
EnvVar: "MARKDOWN_THEME",
})
codeTheme = app.String(cli.StringOpt{
Expand All @@ -82,15 +87,24 @@ func main() {
}
http.HandleFunc("/assets/", headerMiddleware(staticAssetHandlerFunc))

// Setup the markdown theme (may be custom or bundled)
themePath, themeHandler := theme(*markdownTheme)
if themeHandler != nil {
http.HandleFunc(themePath, themeHandler)
}

// Markdown File Handler
markdownHandlerFunc := markdownHandleFunc(MarkdownHandlerOptions{
DocRoot: *dir,
DocExtension: *extension,
DirIndex: *index,
MarkdownTheme: *markdownTheme,
MarkdownTheme: themePath,
CodeTheme: *codeTheme,
})
http.HandleFunc("/", basicAuthMiddleware(headerMiddleware(markdownHandlerFunc), *users))
markdownHandlerFunc = headerMiddleware(markdownHandlerFunc)
markdownHandlerFunc = basicAuthMiddleware(markdownHandlerFunc, *users)
markdownHandlerFunc = robotsTagMiddleware(markdownHandlerFunc, *robotsTag)
http.HandleFunc("/", markdownHandlerFunc)

// Start HTTP server
addr := fmt.Sprintf("%s:%d", *host, *port)
Expand Down
2 changes: 1 addition & 1 deletion markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type MarkdownHandlerOptions struct {
CodeTheme string
}

func markdownHandleFunc(opts MarkdownHandlerOptions) httpHandleFunc {
func markdownHandleFunc(opts MarkdownHandlerOptions) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

path, err := filepath.Abs(filepath.Join(opts.DocRoot, r.URL.Path))
Expand Down
16 changes: 14 additions & 2 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import (
"strings"
)

func headerMiddleware(handler httpHandleFunc) httpHandleFunc {
func headerMiddleware(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Powered-By", "github.com/tantalic/servemd")
w.Header().Set("X-Servemd-Version", Version)
handler(w, r)
}
}

func basicAuthMiddleware(handler httpHandleFunc, users []string) httpHandleFunc {
func basicAuthMiddleware(handler http.HandlerFunc, users []string) http.HandlerFunc {
// If no users are defined don't add the middleware
if len(users) == 0 {
return handler
Expand All @@ -38,3 +38,15 @@ func basicAuthMiddleware(handler httpHandleFunc, users []string) httpHandleFunc
http.Error(w, "Unauthorized", http.StatusUnauthorized)
}
}

func robotsTagMiddleware(handler http.HandlerFunc, value string) http.HandlerFunc {
// If the value is an empty string don't add the middleware
if value == "" {
return handler
}

return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Robots-Tag", value)
handler(w, r)
}
}
49 changes: 49 additions & 0 deletions theme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"fmt"
"log"
"net/http"
"os"
"path/filepath"
)

func theme(value string) (string, http.HandlerFunc) {
// Check if the value is a path to a CSS file
if filepath.Ext(value) == ".css" {
cssPath, err := filepath.Abs(value)
if err != nil {
log.Printf("Error finding custom theme: %s: %s. Falling back to: %s.", value, err.Error(), DefaultTheme)
return themePath(DefaultTheme), nil
}

if stat, err := os.Stat(cssPath); err == nil && !stat.IsDir() {
// Add handler to serve content
handler := func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, cssPath)
}
return themePath("custom"), handler
}

log.Printf("Error finding custom theme: %s. Falling back to: %s.", value, DefaultTheme)
return themePath(DefaultTheme), nil
}

// If the value is not a path, check that it is a valid bundled theme
localPath := themeAssetPath(value)
_, err := Asset(localPath)
if err != nil {
log.Printf("Invalid theme selected: %s. Falling back to: %s.", value, DefaultTheme)
return themePath(DefaultTheme), nil
}

return themePath(value), nil
}

func themePath(value string) string {
return fmt.Sprintf("/assets/themes/%s.css", value)
}

func themeAssetPath(value string) string {
return fmt.Sprintf("assets/themes/%s.css", value)
}

0 comments on commit a4c865d

Please sign in to comment.