diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..968e914 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +vendor/ +bin/ diff --git a/.gitignore b/.gitignore index 5c8536c..9e0a57b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,5 @@ _testmain.go .DS_Store -# getgb.io bin/ -pkg/ +vendor/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bd153d9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM golang:1.6.2-alpine + +ENV APP $GOPATH/src/github.com/agonzalezro/polo +RUN mkdir -p $APP +WORKDIR $APP + +ADD glide.yaml $APP/glide.yaml +ADD glide.lock $APP/glide.lock +RUN apk add --no-cache git \ + && go get -u github.com/Masterminds/glide/... \ + && go get -u github.com/jteeuwen/go-bindata/... \ + && glide install \ + && apk del git + +ADD . $APP +RUN apk add --no-cache make \ + && make \ + && apk del make + +ENTRYPOINT ["bin/polo"] +CMD ["--help"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..775ae95 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: polo + +deps: + mkdir -p bin + +polo: deps + cd cmd/polo&&go generate&&go build&&mv polo ../../bin diff --git a/README.md b/README.md index 51f5ebe..d3d9d9d 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,13 @@ polo [![circleci](https://circleci.com/gh/agonzalezro/polo.svg?style=shield)](https://circleci.com/gh/agonzalezro/polo) -polo is a static blog generator created with [Go](https://golang.org/). It's +polo is a static site generator created with [Go](https://golang.org/). It's compatible with your current Jekyll and Pelican markdowns, so your migration should be straightforward. I'm happily using it on my blog: http://agonzalezro.github.io and you can use -it in yours! +it in yours! There are other places with completely different templates using +it as well: http://k8s.uk/ Yes, I know that there a lot of them out there but I just want mine to learn a little bit of Go coding. @@ -18,7 +19,7 @@ Here are some features: - Jekyll and Pelican compatible. - Can watch files for changes and in that case regenerate the site. - Pretty quick! But new versions will be faster. -- Deploy it to `gh-pages` or create your own blog on github. +- Deploy it to `gh-pages` or create your own site on github. - You can easily auto deploy it: [example for CircleCI](http://agonzalezro.github.io/how-to-automagically-generate-your-polo-blo g-with-circleci.html). - It supports templating, check [my personal blog @@ -28,43 +29,59 @@ Here are some features: Install ------- +### From binary + Find your version here: https://github.com/agonzalezro/polo/releases -If you want to build it yourself, I am using [gb](http://getgb.io): +### Docker + +The latest master is always available as a Docker image: + + docker run agonzalezro/polo + +Remember that you will need to mount volumes and so on. + +### DIY - $ gb build +If you want to build it yourself, I am using [glide](https://github.com/Masterminds/glide) for the dependencies. This means that you will need to use Go 1.5 at least: + + $ glide install How to use it? -------------- If you call the binary without any argument you will get the help: - $ polo - Usage: - polo [OPTIONS] sourcedir outputdir + $ polo -h + usage: polo [] + + Static site generator "compatible" with Jekyll & Pelican content. - Application Options: - -d, --daemon start a simple HTTP server watching for markdown changes. - -c, --config= the settings file. (config.json) - -p, --port= port where to run the server. (8080) + Flags: + -h, --help Show context-sensitive help (also try --help-long and --help-man). + -d, --start-daemon Start a simple HTTP server watching for markdown changes. + -p, --port=8080 Port where to run the server. + -c, --config="config.json" The settings file. + --templates-base-path=. Where the 'templates/' folder resides (in case it exists). + -v, --verbose Verbose logging. - Help Options: - -h, --help Show this help message + Args: + Folder where the content resides. + Where to store the published files. The basic usage mode is: - $ polo sourcedir outputdir + $ polo If you want a server that watches for you changes, meaning that if you change something in `sourcedir` the site will be regenerated: - $ polo -d sourcedir outputdir - ... - 2015/06/23 23:36:57 Static server running on http://localhost:8080 + $ polo -d + INFO[0000] Static server running on :8080 There is an [example project here](https://github.com/agonzalezro/polo/tree/master/example), you can use it -as `sourcedir`. +as ``. Configuration file ------------------ @@ -78,7 +95,7 @@ This is what you can configure: - **author**: if it's not override with the Metadata it's the name that is going to be shown on the articles. -- **title**: title of the blog, for the `` element and the header. +- **title**: title of the site, for the `<title>` element and the header. - **url**: sometimes the full url is needed. - **show{Archive,Categories,Tags}**: if it's true the pages are going to be created and the links are going to be added. @@ -87,7 +104,7 @@ This is what you can configure: ### 3rd party -- **disqusSitename**: if you want comments on your blog. +- **disqusSitename**: if you want comments on your site. - **googleAnalyticsId**: the Google Analytics ID. - **shareThisPublisher**: the ShareThis publisher ID. If provided, there will be some social buttons on the article view. @@ -164,7 +181,7 @@ bootstrap theme: 1. Wherever you want (but it needs to be the same place where you run polo from) you create the folder `templates/base`. -2. Then you edit `templates/base/header.html`, adding the following content: +2. Then you edit `templates/head/header.html`, adding the following content: ````html {{define "header"}} @@ -181,17 +198,11 @@ bootstrap theme: ### Modifying the one that is going to be included on the binary If you want to do changes on the default theme, you need to remember that you -MUST recreate the binary data, you should do it this way: - - $ cd src - $ go-bindata -o src/templates/bindata.go -pkg=templates -ignore=bindata.go src/templates/... - $ cd - - -It's quite important that you `cd` to `src` before doing it, if not the paths -will not match. +MUST recreate the binary data. Use the `go:generate` provided on `cmd/polo` for +that purpose: -There is a [issue open](https://github.com/agonzalezro/polo/issues/35) to -automate this. + $ cd cmd/polo + $ go generate Auto deploy ----------- diff --git a/build-release.sh b/build-release.sh index ab66f30..64ccd76 100755 --- a/build-release.sh +++ b/build-release.sh @@ -3,12 +3,16 @@ OSS=(darwin freebsd linux) ARCHS=(386 amd64) -rm bin/polo* +mkdir -p bin +rm -f bin/polo* for os in "${OSS[@]}"; do for arch in "${ARCHS[@]}"; do - GOOS=$os GOARCH=$arch gb build + echo "Building for $os($arch)" + GOOS=$os GOARCH=$arch make + mv bin/polo bin/polo-$os-$arch done done -mv bin/polo bin/polo-darwin-amd64 +# Link darwin amd64 to bin/polo +ln -s bin/polo-darwin-amd64 bin/polo diff --git a/circle.yml b/circle.yml index dc89c85..6d1aa68 100644 --- a/circle.yml +++ b/circle.yml @@ -1,7 +1,12 @@ +machine: + services: + - docker + dependencies: override: - - go get github.com/constabulary/gb/... + - docker info + - docker build -t agonzalezro/polo . test: override: - - gb test + - docker run --entrypoint go agonzalezro/polo test $(docker run --entrypoint glide agonzalezro/polo novendor) diff --git a/cmd/polo/main.go b/cmd/polo/main.go new file mode 100644 index 0000000..3416028 --- /dev/null +++ b/cmd/polo/main.go @@ -0,0 +1,91 @@ +package main + +//go:generate go-bindata -o ../../templates/assets.go -pkg=assets -ignore=.DS_Store -ignore=assets.go -prefix=../.. ../../templates/... + +import ( + "fmt" + "net/http" + "os" + + log "github.com/Sirupsen/logrus" + config "github.com/agonzalezro/polo/config" + "github.com/agonzalezro/polo/site" + kingpin "gopkg.in/alecthomas/kingpin.v2" + fsnotify "gopkg.in/fsnotify.v1" +) + +var ( + app = kingpin.New("polo", `Static site generator "compatible" with Jekyll & Pelican content.`) + + startDaemon = app.Flag("start-daemon", "Start a simple HTTP server watching for markdown changes.").Short('d').Bool() + port = app.Flag("port", "Port where to run the server.").Default("8080").Short('p').Int() + configPath = app.Flag("config", "The settings file.").Short('c').Default("config.json").String() + + templatesBasePath = app.Flag("templates-base-path", fmt.Sprintf("Where the '%s/' folder resides (in case it exists).", site.TemplatesRelativePath)).Default(".").ExistingDir() + + verbose = app.Flag("verbose", "Verbose logging.").Short('v').Bool() + + source = app.Arg("source", "Folder where the content resides.").Required().ExistingDir() + output = app.Arg("output", "Where to store the published files.").Required().String() +) + +func main() { + app.HelpFlag.Short('h') + kingpin.MustParse(app.Parse(os.Args[1:])) + + if *verbose { + log.SetLevel(log.DebugLevel) + } + + if !dirExists(*output) { + if err := os.Mkdir(*output, os.ModePerm); err != nil { + app.FatalUsage("The output folder couldn't be created!") + } + } + + s, err := site.New(*source, *output, *configPath, *templatesBasePath) + if err != nil { + switch err.(type) { + case config.ErrorParsingConfigFile: + app.FatalUsage("Malformed JSON config file: ", err) + default: + log.Fatal(err) + } + } + + if err := s.Write(); err != nil { + log.Fatal(err) + } + + if *startDaemon { + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + go func() { + for { + select { + case event := <-watcher.Events: + if event.Op != fsnotify.Chmod { + log.Info("Rewriting the site") + if err := s.Write(); err != nil { + log.Fatal(err) + } + } + case err := <-watcher.Errors: + log.Fatal(err) // TODO: perhaps return err + } + } + }() + + for path := range subdirectories(*source) { + watcher.Add(path) + } + + addr := fmt.Sprintf(":%d", *port) + log.Info("Static server running on ", addr) + log.Fatal(http.ListenAndServe(addr, http.FileServer(http.Dir(*output)))) + } +} diff --git a/cmd/polo/utils.go b/cmd/polo/utils.go new file mode 100644 index 0000000..e94ced4 --- /dev/null +++ b/cmd/polo/utils.go @@ -0,0 +1,36 @@ +package main + +import ( + "os" + "path/filepath" + + log "github.com/Sirupsen/logrus" +) + +func subdirectories(parentPath string) chan string { + paths := make(chan string, 1) + + walkFn := func(path string, info os.FileInfo, err error) error { + if err != nil { + log.Warning(err) + } + if info.IsDir() { + paths <- path + } + return nil + } + + go func() { + filepath.Walk(parentPath, walkFn) + close(paths) + }() + + return paths +} + +func dirExists(p string) bool { + if fi, err := os.Stat(p); err == nil { + return fi.IsDir() + } + return false +} diff --git a/src/config/types.go b/config/main.go similarity index 100% rename from src/config/types.go rename to config/main.go diff --git a/context/filters.go b/context/filters.go new file mode 100644 index 0000000..5efc3d0 --- /dev/null +++ b/context/filters.go @@ -0,0 +1,53 @@ +package context + +import "github.com/agonzalezro/polo/file" + +// FilterByPage returns the articles of the site paginated. +func (c Context) FilterByPage(page int) []file.ParsedFile { + var start, end int + + paginationSize := c.Config.PaginationSize + start = (page - 1) * paginationSize + + if start > len(c.Articles) || start < 0 { + return []file.ParsedFile{} + } + + if start+paginationSize <= len(c.Articles) { + end = start + paginationSize + } else { + end = len(c.Articles) - 1 + } + + return c.Articles[start:end] +} + +// FilterByTag returns all the articles belonging to the given tag. +func (c Context) FilterByTag(tag string) []file.ParsedFile { + var files []file.ParsedFile + +LOOP: + for _, f := range c.Articles { + for _, t := range f.Tags { + if tag == t { + files = append(files, f) + continue LOOP + } + } + } + + return files +} + +// FilterByCategory returns all the articles belonging to the give category. +func (c Context) FilterByCategory(category string) []file.ParsedFile { + var files []file.ParsedFile + + for _, f := range c.Articles { + if f.Category == category { + files = append(files, f) + } + } + + return files +} diff --git a/context/main.go b/context/main.go new file mode 100644 index 0000000..ece47d9 --- /dev/null +++ b/context/main.go @@ -0,0 +1,136 @@ +package context + +import ( + "fmt" + "math" + "sync" + "time" + + "github.com/agonzalezro/polo/config" + "github.com/agonzalezro/polo/file" +) + +type Context struct { + Pages []file.ParsedFile + Articles []file.ParsedFile + + Tags, Categories []string + + Config config.Config + Updated string + + // Temporal stuff for template rendering + Article file.ParsedFile + Page file.ParsedFile + Tag string + Category string + CurrentPage int + + tagUniquenessMux, categoryUniquenessMux, numberOfPagesMux *sync.Mutex +} + +func New(config config.Config) *Context { + return &Context{ + Config: config, + Updated: time.Now().Format(time.RFC3339), + tagUniquenessMux: &sync.Mutex{}, + categoryUniquenessMux: &sync.Mutex{}, + numberOfPagesMux: &sync.Mutex{}, + } +} + +func (c *Context) Copy() *Context { + return &Context{ + Config: c.Config, + Pages: c.Pages, + Articles: c.Articles, + Tags: c.Tags, + Categories: c.Categories, + } +} + +// TODO: fix this; we need a number of pages that doesn't fluctuate with the number of articles in the current context +var numberOfPages int + +func (c Context) NumberOfPages() int { + if numberOfPages != 0 { + return numberOfPages + } + + // TODO: we can't use a pointer to context so I doubt that this mutex does anything at all + c.numberOfPagesMux.Lock() + defer c.numberOfPagesMux.Unlock() + + numberOfPages = int( + math.Ceil( + float64(len(c.Articles)) / float64(c.Config.PaginationSize))) + return numberOfPages +} + +// PreviousSlug "calculates" the previous index slug given the page number. +func (c Context) PreviousSlug(page int) (slug string) { + switch page { + case 1: + slug = "#" + case 2: + slug = "/index.html" + default: + slug = fmt.Sprintf("/index%d.html", page-1) + + } + return slug +} + +// NextSlug "calculates" the next index slug given the page number. +func (c Context) NextSlug(page int) string { + if page == c.NumberOfPages() { + return "#" + } + + return fmt.Sprintf("/index%d.html", page+1) +} + +// AppendUniqueTags will append the tag only if it's not already on the context. +func (c *Context) AppendUniqueTags(newTags []string) { + c.tagUniquenessMux.Lock() + defer c.tagUniquenessMux.Unlock() + +LOOP: + for _, newTag := range newTags { + for _, oldTag := range c.Tags { + if newTag == oldTag { + continue LOOP + } + } + c.Tags = append(c.Tags, newTag) + } +} + +// AppendUniqueCategory will append the category just in case that doesn't +// belong to the Context yet. +func (c *Context) AppendUniqueCategory(newCategory string) { + c.categoryUniquenessMux.Lock() + defer c.categoryUniquenessMux.Unlock() + + for _, category := range c.Categories { + if category == newCategory { + return + } + } + c.Categories = append(c.Categories, newCategory) +} + +// Len is needed to implement the sorting interface. +func (c Context) Len() int { + return len(c.Articles) +} + +// Less is a comparator to help us to sort the context Articles by date DESC. +func (c Context) Less(i, j int) bool { + return c.Articles[i].Date.After(c.Articles[j].Date) +} + +// Swap is needed to implement the sorting interface. +func (c Context) Swap(i, j int) { + c.Articles[i], c.Articles[j] = c.Articles[j], c.Articles[i] +} diff --git a/context/main_test.go b/context/main_test.go new file mode 100644 index 0000000..ba63039 --- /dev/null +++ b/context/main_test.go @@ -0,0 +1,36 @@ +package context + +import ( + "sync" + "testing" + + "github.com/agonzalezro/polo/config" + "github.com/agonzalezro/polo/file" + "github.com/stretchr/testify/assert" +) + +func TestNumberOfPages(t *testing.T) { + assert := assert.New(t) + + config := config.Config{ + PaginationSize: 1, + } + c := Context{ + Config: config, + numberOfPagesMux: &sync.Mutex{}, + Articles: []file.ParsedFile{file.ParsedFile{}, file.ParsedFile{}}, + } + assert.Equal(2, c.NumberOfPages()) + + // Same context, old value + c.Articles = []file.ParsedFile{file.ParsedFile{}} + assert.Equal(2, c.NumberOfPages()) + + // New context, old value + c = Context{ + Config: config, + numberOfPagesMux: &sync.Mutex{}, + Articles: []file.ParsedFile{}, + } + assert.Equal(2, c.NumberOfPages()) +} diff --git a/context/template_funcs.go b/context/template_funcs.go new file mode 100644 index 0000000..1b753e6 --- /dev/null +++ b/context/template_funcs.go @@ -0,0 +1,27 @@ +package context + +import "time" + +func (c Context) ShowHeader() bool { + return (c.Config.ShowTags && len(c.Tags) > 0) || (c.Config.ShowCategories && len(c.Categories) > 0) || (c.Config.ShowArchive && len(c.Articles) > 0) +} + +// HumanizeDatetime returns a date or datetime depending of the datetime +// received. +// For example, if the datetime received doesn't have any hour/minutes, the +// hours/minutes part doesn't need to be shown. +func (c Context) HumanizeDatetime(datetime time.Time) string { + if datetime.Hour()+datetime.Minute() == 0 { + return datetime.Format("2006-01-02") + } + return datetime.Format("2006-01-02 15:04") +} + +// ArrayOfPages is a dirty hack because we can not (or I don't know how) do a +// range from X to Y on the template +func (c Context) ArrayOfPages() (pages []int) { + for i := 1; i < c.NumberOfPages()+1; i++ { + pages = append(pages, i) + } + return pages +} diff --git a/example/content/section2.md/example2.md b/example/content/section2/example2.md similarity index 100% rename from example/content/section2.md/example2.md rename to example/content/section2/example2.md diff --git a/file/main.go b/file/main.go new file mode 100644 index 0000000..5073417 --- /dev/null +++ b/file/main.go @@ -0,0 +1,76 @@ +package file + +import ( + "bufio" + "html/template" + "os" + "strings" + "time" +) + +// ParsedFile holds the struct of a file after we parsed the metadata and its +// content. +type ParsedFile struct { + Author string + Title string + Slug string + Content template.HTML + Summary template.HTML + + IsPage bool + Category string + Tags []string + Date time.Time + + // Not to be used by the template + rawContent string + summary string + status string // To keep track of the drafts + + file *os.File + scanner *bufio.Scanner +} + +// New return a new ParsedFile after load it from disk. +func New(path string) (*ParsedFile, error) { + pf := ParsedFile{ + IsPage: IsPage(path), + Category: CategoryFromPath(path), + } + file, err := os.Open(path) + if err != nil { + return nil, err + } + + pf.file = file + pf.scanner = bufio.NewScanner(file) // We need this to seek after parsing metadata + + if err := pf.parse(); err != nil { + return nil, err + } + + pf.Summary = HTML(pf.summaryOrFirstParagraph()) + pf.Content = HTML(pf.rawContent) + return &pf, nil +} + +// summaryOrFirstParagraph will use the summary from the markdown or generate a new one from the 1st paragraph. +func (f ParsedFile) summaryOrFirstParagraph() string { + summary := f.summary + + if summary == "" { + // Get the first paragraph + for _, summary := range strings.Split(f.rawContent, "\n\n") { + if summary != "" { + return summary + } + } + } + + return summary +} + +// IsPublished will return true if the file doesn't specify any other status. +func (f ParsedFile) IsPublished() bool { + return f.status == "" +} diff --git a/src/file/parser.go b/file/parser.go similarity index 62% rename from src/file/parser.go rename to file/parser.go index 23b3287..9971461 100644 --- a/src/file/parser.go +++ b/file/parser.go @@ -2,16 +2,16 @@ package file import ( "bufio" + "errors" "fmt" - "os" "regexp" "strings" "time" - "utils" + "github.com/agonzalezro/polo/utils" ) -func parseData(value string) (t time.Time, err error) { +func parseDate(value string) (t time.Time, err error) { acceptedFormats := []string{ "2006-01-02 15:04", "2006-1-2 15:04", @@ -26,10 +26,15 @@ func parseData(value string) (t time.Time, err error) { return t, fmt.Errorf("Accepted date/time formats are: %v", acceptedFormats) } +var NoMetadataFound = errors.New("No metadata found!") + // parseMetadata sets the metadata on the ParsedFile. // If no metadata is found no error is going to be raised. -func (pf *ParsedFile) parseMetadata() (hasMetadata bool, err error) { +func (pf *ParsedFile) parseMetadata() (err error) { + var count int + for pf.scanner.Scan() { + count++ line := pf.scanner.Text() // In case that the metadata starts like :date: @@ -44,10 +49,9 @@ func (pf *ParsedFile) parseMetadata() (hasMetadata bool, err error) { case "---": // If the metadata is enclosed between lines like this: '---' // (Jekyll style) we need to return after process it. - if hasMetadata == true { - return true, nil + if count > 1 { + goto END } - hasMetadata = true case "tags": // Remove all the spaces between comma and tag and // add one comma at the beginning and other at the end, this will @@ -55,13 +59,11 @@ func (pf *ParsedFile) parseMetadata() (hasMetadata bool, err error) { for _, tag := range strings.Split(value, ",") { pf.Tags = append(pf.Tags, strings.Replace(tag, " ", "", -1)) } - hasMetadata = true case "date": - pf.Date, err = parseData(value) + pf.Date, err = parseDate(value) if err != nil { - return true, err + return err } - hasMetadata = true case "slug": prefix := "/" if strings.HasPrefix(value, "/") { @@ -72,43 +74,43 @@ func (pf *ParsedFile) parseMetadata() (hasMetadata bool, err error) { suffix = "" // And don't duplicate the html either } pf.Slug = fmt.Sprintf("%s%s%s", prefix, value, suffix) - hasMetadata = true - case "title": - pf.Title = value - hasMetadata = true case "status": pf.status = value - hasMetadata = true case "summary": pf.summary = value - hasMetadata = true case "author": pf.Author = value - hasMetadata = true + case "title": + pf.Title = value default: - return hasMetadata, nil + goto END } } - return hasMetadata, nil -} - -// Loads the content of the file object from the given filename. -func (pf *ParsedFile) load(filePath string) error { - file, err := os.Open(filePath) - if err != nil { - return err +END: + // TODO: not the best way to check this. Find a cleaner way. + allUnset := func() bool { + return (pf.Tags == nil && pf.Date.IsZero() && pf.Slug == "" && pf.status == "" && pf.Summary == "" && pf.Author == "" && pf.Title == "") } - - pf.scanner = bufio.NewScanner(file) - hasMetadata, err := pf.parseMetadata() - if err != nil { - return err + if count <= 2 && allUnset() { + return NoMetadataFound } - if !hasMetadata { - // Rewind the file and reset the scanner - file.Seek(0, 0) - pf.scanner = bufio.NewScanner(file) + return nil +} + +// parse parses the content and metadata storing the on private fields of the struct +func (pf *ParsedFile) parse() error { + var err error + if err = pf.parseMetadata(); err != nil { + switch err { + case NoMetadataFound: + // We have already read part of the file but we didn't found metadata. + // Rewind the file and reset the scanner + pf.file.Seek(0, 0) + pf.scanner = bufio.NewScanner(pf.file) + default: + return err + } } isFirstLine := true @@ -116,35 +118,27 @@ func (pf *ParsedFile) load(filePath string) error { line := pf.scanner.Text() if isFirstLine == true { if line == "" { - // Do not read empty lines at the beginning + // Ignore empty lines at the beginning of the file continue } if pf.Title == "" { - // Needed to remove markdown syntax before storing values on the structs + // This is needed to remove markdown syntax before storing values on the structs re := regexp.MustCompile("^#+\\s*") pf.Title = re.ReplaceAllString(line, "") } + if pf.Slug == "" { - prefix := "" - if pf.IsPage { - prefix = "/pages" - } - pf.Slug = fmt.Sprintf("%s/%s.html", prefix, utils.Slugify(pf.Title)) + pf.Slug = fmt.Sprintf("/%s.html", utils.Slugify(pf.Title)) } + pf.scanner.Scan() // We don't want the title underlining isFirstLine = false - } else { - pf.Content += line + "\n" + continue } - } - // Set the category from the filePath - splittedPath := strings.Split(filePath, "/") - length := len(splittedPath) - if length > 1 { - pf.Category = splittedPath[len(splittedPath)-2] + pf.rawContent += line + "\n" } return nil diff --git a/file/parser_test.go b/file/parser_test.go new file mode 100644 index 0000000..8efaf40 --- /dev/null +++ b/file/parser_test.go @@ -0,0 +1,92 @@ +package file + +import ( + "bufio" + "fmt" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func newTestParsedFile(s string) *ParsedFile { + return &ParsedFile{ + scanner: bufio.NewScanner(strings.NewReader(s)), + } +} + +// TestNoMetadata will test that an error NoMetadataFound is raised when +// parseMetadata is called without metadata. +func TestNoMetadata(t *testing.T) { + assert := assert.New(t) + + for _, input := range []string{ + "", + "---\n---\n", + "This is my awesome title\n===\nAnd this is some content", + } { + pf := newTestParsedFile(input) + assert.Equal(NoMetadataFound, pf.parseMetadata()) + } +} + +// Test that the metadata is parsed properly following the Pelican standards +// for it, that means. Check the examples/ folder for more info about them. +func TestPelicanMetadataParsing(t *testing.T) { + assert := assert.New(t) + + timeLayout := "2006-01-02 15:04" + + expectedTitle := "My super title" + expectedDate, _ := time.Parse(timeLayout, "2010-12-03 10:20") + expectedSlug := "/my-super-post.html" + expectedText := "This is the content of my super blog post." + expectedTags := []string{"thats", "awesome"} + + content := fmt.Sprintf( + "Title: %s\nDate: %s\nTags: thats, awesome\nSlug: %s\n\n%s", + expectedTitle, expectedDate.Format(timeLayout), expectedSlug, expectedText) + + pf := newTestParsedFile(content) + err := pf.parse() + assert.NoError(err) + + assert.Equal(expectedTitle, pf.Title) + assert.Equal(expectedDate, pf.Date) + assert.Equal(expectedTags, pf.Tags) + assert.Equal(expectedSlug, pf.Slug) +} + +// Test that the metadata is parsed properly when the standard used for it is +// the Jekyll standard (enclosed between '---' lines). +func TestJekyllMetadataParsing(t *testing.T) { + assert := assert.New(t) + expectedTitle := "jekyll test" + + content := fmt.Sprintf("---\nTitle:%s\n---\nThis is the content", expectedTitle) + pf := newTestParsedFile(content) + + err := pf.parseMetadata() + assert.NoError(err) + + assert.Equal(expectedTitle, pf.Title) +} + +// Test that defining only one piece of metadata (ex date) the title & slug are +// generated properly. +func TestOnlyOneMetadata(t *testing.T) { + assert := assert.New(t) + expectedTitle := "Generated title" + expectedDate := "1984-04-04 16:16" + + content := fmt.Sprintf("Date: %s\n\n%s\n---\nAnd some content", expectedDate, expectedTitle) + pf := newTestParsedFile(content) + + err := pf.parseMetadata() + assert.NoError(err) + + date, err := parseDate(expectedDate) + assert.NoError(err) + assert.Equal(date, pf.Date) +} diff --git a/src/file/template_funcs.go b/file/utils.go similarity index 58% rename from src/file/template_funcs.go rename to file/utils.go index a12fe0d..3190f90 100644 --- a/src/file/template_funcs.go +++ b/file/utils.go @@ -7,8 +7,15 @@ import ( "github.com/russross/blackfriday" ) -// HTML return a template.HTML with the original content rendered as markdown. -func (file ParsedFile) HTML(content string) template.HTML { +func IsMarkdown(path string) bool { + return strings.HasSuffix(path, ".md") || strings.HasSuffix(path, ".markdown") +} + +func IsPage(path string) bool { + return strings.HasPrefix(path, "pages/") || strings.Index(path, "/pages/") > 0 +} + +func HTML(content string) template.HTML { // set up the HTML renderer htmlFlags := 0 htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS @@ -27,17 +34,11 @@ func (file ParsedFile) HTML(content string) template.HTML { return template.HTML(html) } -// Summary returns the document summary in case that it was defined on the -// metadata, or it creates a small summary (1st paragraph) if not. -func (file ParsedFile) Summary() string { - if file.summary != "" { - return file.summary - } - // Avoid empty lines - for _, content := range strings.Split(file.Content, "\n\n") { - if content != "" { - return content - } +func CategoryFromPath(path string) string { + splittedPath := strings.Split(path, "/") + length := len(splittedPath) + if length > 1 { + return splittedPath[length-2] } return "" } diff --git a/glide.lock b/glide.lock new file mode 100644 index 0000000..d39a9e6 --- /dev/null +++ b/glide.lock @@ -0,0 +1,38 @@ +hash: 983ed1ffb63d870540f78a6f2e0174c0fb7784589092d0d41345f33615fe40e0 +updated: 2016-05-02T12:59:00.391068039+02:00 +imports: +- name: github.com/alecthomas/template + version: a0175ee3bccc567396460bf5acd36800cb10c49c +- name: github.com/alecthomas/units + version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a +- name: github.com/davecgh/go-spew + version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d + subpackages: + - spew +- name: github.com/getsentry/raven-go + version: e39495fea085e98d1281fac0ff4d6eb8dc56f86d +- name: github.com/jessevdk/go-flags + version: 6b9493b3cb60367edd942144879646604089e3f7 +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/russross/blackfriday + version: 77efab57b2f74dd3f9051c79752b2e8995c8b789 +- name: github.com/shurcooL/sanitized_anchor_name + version: 10ef21a441db47d8b13ebcc5fd2310f636973c77 +- name: github.com/Sirupsen/logrus + version: 51fe59aca108dc5680109e7b2051cbdcfa5a253c +- name: github.com/stretchr/objx + version: cbeaeb16a013161a98496fad62933b1d21786672 +- name: github.com/stretchr/testify + version: c5d7a69bf8a2c9c374798160849c071093e41dd1 +- name: github.com/tobi/airbrake-go + version: a3cdd910a3ffef88a20fbecc10363a520ad61a0a +- name: golang.org/x/sys + version: b776ec39b3e54652e09028aaaaac9757f4f8211a +- name: gopkg.in/alecthomas/kingpin.v2 + version: 8cccfa8eb2e3183254457fb1749b2667fbc364c7 +- name: gopkg.in/fsnotify.v1 + version: 30411dbcefb7a1da7e84f75530ad3abe4011b4f8 +devImports: [] diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 0000000..8de7167 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,8 @@ +package: main +import: +- package: github.com/Sirupsen/logrus +- package: gopkg.in/fsnotify.v1 +- package: github.com/jessevdk/go-flags +- package: github.com/russross/blackfriday +- package: gopkg.in/alecthomas/kingpin.v2 +- package: github.com/stretchr/testify diff --git a/site/main.go b/site/main.go new file mode 100644 index 0000000..eaebb96 --- /dev/null +++ b/site/main.go @@ -0,0 +1,318 @@ +package site + +import ( + "fmt" + "os" + "path" + "path/filepath" + "sort" + "sync" + + "github.com/agonzalezro/polo/config" + "github.com/agonzalezro/polo/context" + "github.com/agonzalezro/polo/file" +) + +const ( + atomPath = "feeds/all.atom.xml" + archivePath = "archive.html" + articlesPrefixPath = "" // TODO: perhaps allow configuration for this? + pagesPrefixPath = "pages/" + + categoryPathFormater = "category/%s.html" + tagPathFormater = "tag/%s.html" + + indexTemplate = "index" + atomTemplate = "atom" + articleTemplate = "article" + pageTemplate = "page" + archiveTemplate = "archive" + categoryTemplate = "category" + tagTemplate = "tag" +) + +type Siteable interface { + Load() error + Write() error +} + +type Site struct { + port int + source, output string + templatesBasePath string + + slugs map[string]bool + mux *sync.Mutex + + Config config.Config + Context *context.Context +} + +func New(source, output, configPath, templatesBasePath string) (*Site, error) { + config, err := config.New(configPath) + if err != nil { + return nil, err + } + + s := Site{ + source: source, + output: output, + templatesBasePath: templatesBasePath, + Config: *config, + Context: context.New(*config), + mux: &sync.Mutex{}, + } + + return &s, s.Load() +} + +func (s *Site) AddSlug(slug string) { + s.mux.Lock() + defer s.mux.Unlock() + if s.slugs == nil { + s.slugs = make(map[string]bool) + } + s.slugs[slug] = true +} + +// parse is a filepath.WalkFunc that will load all the pages and articles into a context object. +func (s *Site) parse(path string, fileInfo os.FileInfo, err error) error { + if err != nil { + return err + } + + if fileInfo.Mode().IsDir() || !file.IsMarkdown(path) { + return nil + } + + file, err := file.New(path) + if err != nil { + return err + } + + if _, present := s.slugs[file.Slug]; present { + return fmt.Errorf("The slug '%s' already exists!", file.Slug) + } + s.AddSlug(file.Slug) + + // Add the pages or articles to the proper array on the site + if file.IsPage { + s.Context.Pages = append(s.Context.Pages, *file) + return nil + } + + // If it's not a page, it's an article + s.Context.Articles = append(s.Context.Articles, *file) + + // Just supported on Articles + if len(file.Tags) > 0 { + s.Context.AppendUniqueTags(file.Tags) + } + s.Context.AppendUniqueCategory(file.Category) + return nil +} + +func (s *Site) Load() error { + if err := filepath.Walk(s.source, s.parse); err != nil { + return err + } + // Sort the articles after we got them + sort.Sort(s.Context) + return nil +} + +func (s Site) Write() error { + var wg sync.WaitGroup + + errCh := make(chan error, 1024) // TODO: 1024 should be more than enough for the errors + + s.writeIndexes(&wg, errCh) + s.writeFeeds(&wg, errCh) + s.writeArticles(&wg, errCh) + s.writePages(&wg, errCh) + + if s.Config.ShowArchive { + s.writeArchive(&wg, errCh) + } + if s.Config.ShowCategories { + s.writeCategories(&wg, errCh) + } + if s.Config.ShowTags { + s.writeTags(&wg, errCh) + } + + wg.Wait() + + for { + select { + case err := <-errCh: + // I could append errors here but it isn't worthy + return err + default: + return nil + } + } +} + +func (s Site) writef(relativePath string, templateName string, c context.Context) error { + tpl, err := s.getTemplate(templateName) + if err != nil { + return err + } + + // Ensure absolute path exists + err = s.mkdirP(relativePath) + if err != nil { + return err + } + + f, err := os.Create(path.Join(s.output, relativePath)) + if err != nil { + return err + } + + return tpl.ExecuteTemplate(f, "base", c) +} + +func (s Site) writeIndexes(wg *sync.WaitGroup, errCh chan<- error) { + for i := 1; i <= s.Context.NumberOfPages(); i++ { + wg.Add(1) + go func(page int) { + defer wg.Done() + + indexFile := "index.html" + if page > 1 { + indexFile = fmt.Sprintf("index%d.html", page) + } + + c := s.Context.Copy() + c.Articles = c.FilterByPage(page) + + c.CurrentPage = page + + if err := s.writef(indexFile, indexTemplate, *c); err != nil { + errCh <- err + } + }(i) + } +} + +func (s Site) writeFeeds(wg *sync.WaitGroup, errCh chan<- error) { + wg.Add(1) + go func() { + defer wg.Done() + + limit := len(s.Context.Articles) + if limit > 10 { + limit = 10 + } + + c := s.Context.Copy() + c.Articles = c.Articles[0:limit] + + // TODO: just ATOM feeds, not RSS unless somebody needs it and he/she is willing to implement it :) + if err := s.writef(atomPath, atomTemplate, *c); err != nil { + errCh <- err + } + }() +} + +func (s Site) writeArticles(wg *sync.WaitGroup, errCh chan<- error) { + for _, article := range s.Context.Articles { + wg.Add(1) + go func(article file.ParsedFile) { + defer wg.Done() + + c := s.Context.Copy() + c.Article = article + + p := path.Join(articlesPrefixPath, article.Slug) + if err := s.writef(p, articleTemplate, *c); err != nil { + errCh <- err + } + }(article) + } +} + +func (s Site) writePages(wg *sync.WaitGroup, errCh chan<- error) { + for _, page := range s.Context.Pages { + wg.Add(1) + go func(page file.ParsedFile) { + defer wg.Done() + + c := s.Context.Copy() + c.Page = page + + p := path.Join(pagesPrefixPath, page.Slug) + if err := s.writef(p, pageTemplate, *c); err != nil { + errCh <- err + } + }(page) + } +} + +func (s Site) writeArchive(wg *sync.WaitGroup, errCh chan<- error) { + wg.Add(1) + defer wg.Done() + + if err := s.writef(archivePath, archiveTemplate, *s.Context); err != nil { + errCh <- err + } +} + +func (s Site) writeCategories(wg *sync.WaitGroup, errCh chan<- error) { + for _, category := range s.Context.Categories { + wg.Add(1) + go func(category string) { + defer wg.Done() + + c := s.Context.Copy() + c.Articles = c.FilterByCategory(category) + c.Category = category + + p := fmt.Sprintf(categoryPathFormater, category) + if err := s.writef(p, categoryTemplate, *c); err != nil { + errCh <- err + } + }(category) + } +} + +func (s Site) writeTags(wg *sync.WaitGroup, errCh chan<- error) { + for _, tag := range s.Context.Tags { + wg.Add(1) + go func(tag string) { + defer wg.Done() + + c := s.Context.Copy() + c.Articles = c.FilterByTag(tag) + c.Tag = tag + + p := fmt.Sprintf(tagPathFormater, tag) + if err := s.writef(p, tagTemplate, *c); err != nil { + errCh <- err + } + }(tag) + } +} + +// mkdirP assures that the full path exists. It mimics `mkdir -p` +func (s *Site) mkdirP(elem ...string) error { + s.mux.Lock() + defer s.mux.Unlock() + + // TODO: I am not pretty sure that this is the best way to do this, but it works (TM) + toJoin := make([]string, 1, 1) + toJoin[0] = s.output + elem = append(toJoin, elem...) + absolutePath := path.Join(elem...) + + dir := filepath.Dir(absolutePath) + if _, err := os.Stat(dir); os.IsNotExist(err) { + if err := os.Mkdir(dir, 0777); err != nil { + return err + } + } + + return nil +} diff --git a/site/templates.go b/site/templates.go new file mode 100644 index 0000000..4e32b46 --- /dev/null +++ b/site/templates.go @@ -0,0 +1,124 @@ +package site + +import ( + "fmt" + "os" + "path" + "text/template" + + log "github.com/Sirupsen/logrus" + assets "github.com/agonzalezro/polo/templates" +) + +// TODO: probably to be override from the cmd +const TemplatesRelativePath = "templates" + +var templates map[string]*template.Template + +// TODO: this could be our own type based on template.Template +func parseFileOrAsset(t *template.Template, p string) (*template.Template, error) { + if _, err := os.Stat(p); err == nil { + log.Debug("Loading template from disk: ", p) + return t.ParseFiles(p) + } + + b, err := assets.Asset(p) + if err != nil { + return nil, err + } + log.Debug("Loading template from asset: ", p) + return t.Parse(string(b)) +} + +// mustParseCommonTemplates will parse common templates and fatal if it can. +// Common templates are those templates shared. +func mustParseCommonTemplates() *template.Template { + // We can't just walk a dir to find them because GOPATH will not be available + // on a binary installation. + // TODO: it would be cool to use go-bindata list but _bindata is private. + commonTemplatePaths := []string{ + "templates/base.tmpl", + "templates/body/analytics.tmpl", + "templates/body/footer.tmpl", + "templates/body/footer_scripts.tmpl", + "templates/body/navbar.tmpl", + "templates/head/header.tmpl", + "templates/head/header_scripts.tmpl", + "templates/head/share_this.tmpl", + } + + tpl := template.New("common") + var err error + for _, p := range commonTemplatePaths { + tpl, err = parseFileOrAsset(tpl, p) + if err != nil { + log.Fatal(err) + } + } + return tpl +} + +func mustParseContentTemplates(commonTpl *template.Template, templatesPath string) map[string]*template.Template { + // Content templates are those templates that are willing to change depending + // on what we are rending at that moment. + contentTemplatePaths := make(map[string][]string) + for templateName, paths := range map[string][]string{ + articleTemplate: []string{"article/article.tmpl", "article/disqus.tmpl", "article/share_icons.tmpl"}, + archiveTemplate: []string{"archive.tmpl"}, + categoryTemplate: []string{"category.tmpl"}, + indexTemplate: []string{"index.tmpl"}, + pageTemplate: []string{"page.tmpl"}, + tagTemplate: []string{"tag.tmpl"}, + } { + contentTemplatePaths[templateName] = paths + } + + templates = make(map[string]*template.Template) // WARNING package level var + for name, paths := range contentTemplatePaths { + tpl, err := commonTpl.Clone() + if err != nil { + log.Fatal(err) + } + + for _, p := range paths { + p = path.Join(templatesPath, "body", "content", p) + tpl, err = parseFileOrAsset(tpl, p) + if err != nil { + log.Fatal(err) + } + } + templates[name] = tpl + } + + // Atom template doesn't inherit from any shared template + tpl := template.New("atom") + tpl, err := parseFileOrAsset(tpl, "templates/atom.tmpl") + if err != nil { + log.Fatal(err) + } + templates[atomTemplate] = tpl + + return templates +} + +func (s *Site) getTemplates() map[string]*template.Template { + s.mux.Lock() + defer s.mux.Unlock() + + if templates != nil { + return templates + } + + templatesPath := path.Join(s.templatesBasePath, TemplatesRelativePath) + log.Debug("Templates path: ", templatesPath) + + commonTpl := mustParseCommonTemplates() + return mustParseContentTemplates(commonTpl, templatesPath) +} + +func (s *Site) getTemplate(name string) (*template.Template, error) { + if v, ok := s.getTemplates()[name]; ok { + return v, nil + } + return nil, fmt.Errorf("Template '%s' not found!", name) +} diff --git a/src/cmd/polo/polo.go b/src/cmd/polo/polo.go deleted file mode 100644 index 88c1a39..0000000 --- a/src/cmd/polo/polo.go +++ /dev/null @@ -1,129 +0,0 @@ -package main - -import ( - "fmt" - "log" - "net/http" - "os" - "path/filepath" - "time" - - "config" - "site" - - flags "github.com/jessevdk/go-flags" - fsnotify "gopkg.in/fsnotify.v1" -) - -var opts struct { - StartDaemon bool `short:"d" long:"daemon" description:"start a simple HTTP server watching for markdown changes."` - Config string `short:"c" long:"config" default:"config.json" description:"the settings file."` - ServerPort int `short:"p" long:"port" default:"8080" description:"port where to run the server."` -} - -func getAllSubdirectories(parentPath string) (paths []string, err error) { - walkFn := func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - paths = append(paths, path) - } - return nil - } - err = filepath.Walk(parentPath, walkFn) - return paths, err -} - -func writeSite(config config.Config, sourcedir string, outdir string) error { - s := site.New(config, outdir) - if err := s.Populate(sourcedir); err != nil { - return err - } - if err := s.Write(); err != nil { - return err - } - return nil -} - -func main() { - parser := flags.NewParser(&opts, flags.Default) - parser.Usage = "[OPTIONS] sourcedir outputdir" + parser.Usage - - args, err := parser.Parse() - if err != nil { - panic(err) - } - - if len(args) != 2 { - parser.WriteHelp(os.Stderr) - os.Exit(1) - } - - // TODO: this need to be clean up - directoryExists := func(dir string) bool { - if fi, err := os.Stat(dir); err == nil { - return fi.IsDir() - } - return false - } - sourcedir := args[0] - if !directoryExists(sourcedir) { - fmt.Fprintf(os.Stderr, "The sourcedir must be an existent directory!") - os.Exit(1) - } - outdir := args[1] - if !directoryExists(outdir) { - if err := os.Mkdir(outdir, os.ModePerm); err != nil { - fmt.Fprintf(os.Stderr, "The outdir didn't exists and couldn't be created!") - } - time.Sleep(1 * time.Second) // Ugliest thing ever but it doesn't create the dir at time? - } - - config, err := config.New(opts.Config) - if err != nil { - log.Println(err) - log.Println("This usually happens because the JSON file is not well formed.") - os.Exit(1) - } - if err := writeSite(*config, sourcedir, outdir); err != nil { - log.Fatal(err) - } - - if opts.StartDaemon { - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - defer watcher.Close() - - go func() { - for { - select { - case event := <-watcher.Events: - if event.Op != fsnotify.Chmod { - log.Println("Rewriting the site") - if err := writeSite(*config, sourcedir, outdir); err != nil { - log.Fatal(err) - } - } - case err := <-watcher.Errors: - log.Fatal(err) - } - } - }() - - paths, err := getAllSubdirectories(sourcedir) - if err != nil { - log.Fatal(err) - } - for _, path := range paths { - watcher.Add(path) - } - - addr := fmt.Sprintf("localhost:%d", opts.ServerPort) - log.Printf("Static server running on http://%s\n", addr) - log.Fatal( - http.ListenAndServe(addr, http.FileServer(http.Dir(outdir)))) - } -} diff --git a/src/context/template_funcs.go b/src/context/template_funcs.go deleted file mode 100644 index da5ff1b..0000000 --- a/src/context/template_funcs.go +++ /dev/null @@ -1,98 +0,0 @@ -package context - -import ( - "fmt" - "time" - - "file" -) - -// ArticlesByPage returns the articles of the site paginated. -func (c Context) ArticlesByPage(page int) []*file.ParsedFile { - var start, end int - - paginationSize := c.Site.Config.PaginationSize - - start = (page - 1) * paginationSize - - if start+paginationSize <= len(c.Site.Articles) { - end = start + paginationSize - } else { - end = len(c.Site.Articles) - } - - return c.Site.Articles[start:end] -} - -// ArticlesByTag returns all the articles belonging to the given tag. -func (c Context) ArticlesByTag(tag string) []*file.ParsedFile { - var files []*file.ParsedFile - -LOOP: - for _, f := range c.Site.Articles { - for _, t := range f.Tags { - if tag == t { - files = append(files, f) - continue LOOP - } - } - } - - return files -} - -// ArticlesByCategory returns all the articles belonging to the give category. -func (c Context) ArticlesByCategory(category string) []*file.ParsedFile { - var files []*file.ParsedFile - - for _, f := range c.Site.Articles { - if f.Category == category { - files = append(files, f) - } - } - - return files -} - -// PreviousSlug "calculates" the previous index slug given the page number. -func (c Context) PreviousSlug(page int) (slug string) { - switch page { - case 1: - slug = "#" - case 2: - slug = "/index.html" - default: - slug = fmt.Sprintf("/index%d.html", page-1) - - } - return slug -} - -// NextSlug "calculates" the next index slug given the page number. -func (c Context) NextSlug(page int) string { - if page == c.Site.NumberOfPages { - return "#" - } - - return fmt.Sprintf("/index%d.html", page+1) -} - -// ArrayOfPages is a dirty hack because we can not (or I don't know how) do a -// range from X to Y on the template -func (c Context) ArrayOfPages() (pages []int) { - for i := 1; i < c.Site.NumberOfPages+1; i++ { - pages = append(pages, i) - } - return pages -} - -// HumanizeDatetime returns a date or datetime depending of the datetime -// received. -// For example, if the datetime received doesn't have any hour/minutes, the -// hours/minutes part doesn't need to be shown. -func (c Context) HumanizeDatetime(datetime time.Time) string { - if datetime.Hour()+datetime.Minute() == 0 { - return datetime.Format("2006-01-02") - } - return datetime.Format("2006-01-02 15:04") -} diff --git a/src/context/types.go b/src/context/types.go deleted file mode 100644 index a4bdb8b..0000000 --- a/src/context/types.go +++ /dev/null @@ -1,32 +0,0 @@ -package context - -import ( - "config" - "file" -) - -// Context stores the temporal context needed to render a page. -type Context struct { - Article, Page file.ParsedFile - Articles, Pages []*file.ParsedFile - - Tags []string - Tag, Category string - PageNumber int - - Updated string - - Site SiteContext -} - -// SiteContext is a subcontext where we store the Site globals and the -// configuration. -type SiteContext struct { - Articles, Pages []*file.ParsedFile - Tags []string - Categories []string - - NumberOfPages int - - Config config.Config -} diff --git a/src/file/file_test.go b/src/file/file_test.go deleted file mode 100644 index 36171d4..0000000 --- a/src/file/file_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package file - -import ( - "bufio" - "fmt" - "strings" - "testing" - "time" -) - -func fail(t *testing.T, name string, got interface{}, expected interface{}) { - t.Error(name, "was not the expected.\n\tgot:", got, "\n\texpected:", expected) -} - -// Test that the metadata is parsed properly following the Pelican standards -// for it, that means. Check the examples/ folder for more info about them. -func TestPelicanMetadataParsing(t *testing.T) { - timeLayout := "2006-01-02 15:04" - - expectedTitle := "My super title" - expectedDate, _ := time.Parse(timeLayout, "2010-12-03 10:20") - expectedSlug := "/my-super-post.html" - expectedText := "This is the content of my super blog post." - expectedTags := []string{"thats", "awesome"} - - content := fmt.Sprintf( - "Title: %s\nDate: %s\nTags: thats, awesome\nSlug: %s\n\n%s", - expectedTitle, expectedDate.Format(timeLayout), expectedSlug, expectedText) - - pf := ParsedFile{} - pf.scanner = bufio.NewScanner(strings.NewReader(content)) - - pf.parseMetadata() - if pf.Title != expectedTitle { - fail(t, "Title", pf.Title, expectedTitle) - } - - if pf.Date != expectedDate { - fail(t, "Date", pf.Date, expectedDate) - } - if pf.Tags[0] != expectedTags[0] || pf.Tags[1] != expectedTags[1] { - fail(t, "Tags", pf.Tags, expectedTags) - } - if pf.Slug != expectedSlug { - fail(t, "Slug", pf.Slug, expectedSlug) - } - - // Check that doesn't read too much - pf.scanner.Scan() - if pf.scanner.Text() != expectedText { - t.Errorf("This line should be here!") - } -} - -// Test that the metadata is parsed properly when the standard used for it is -// the Jekyll standard (enclosed between '---' lines). -func TestJekyllMetadataParsing(t *testing.T) { - expectedTitle := "jekyll test" - - content := fmt.Sprintf( - "---\nTitle:%s\n---This is the content", expectedTitle) - - pf := ParsedFile{ - scanner: bufio.NewScanner(strings.NewReader(content)), - } - pf.parseMetadata() - - if pf.Title != expectedTitle { - fail(t, "Title", pf.Title, expectedTitle) - } -} diff --git a/src/file/types.go b/src/file/types.go deleted file mode 100644 index 55696f8..0000000 --- a/src/file/types.go +++ /dev/null @@ -1,38 +0,0 @@ -package file - -import ( - "bufio" - "strings" - "time" -) - -// ParsedFile holds the struct of a file after we parsed the metadata and its -// content. -type ParsedFile struct { - Metadata map[string]string - - Author string - Title string - Slug string - Content string - status string // To keep track of the drafts - summary string - - IsPage bool - - Category string - Tags []string - Date time.Time - - scanner *bufio.Scanner -} - -// New return a new ParsedFile after load it from disk. -func New(path string) (*ParsedFile, error) { - pf := ParsedFile{} - pf.IsPage = strings.HasPrefix(path, "pages/") || strings.Index(path, "/pages/") > 0 - if err := pf.load(path); err != nil { - return nil, err - } - return &pf, nil -} diff --git a/src/site/comparator.go b/src/site/comparator.go deleted file mode 100644 index 778104d..0000000 --- a/src/site/comparator.go +++ /dev/null @@ -1,16 +0,0 @@ -package site - -// Len is needed to implement the sorting interface. -func (s Site) Len() int { - return len(s.Articles) -} - -// Less is a comparator to help us to sort the site by date DESC. -func (s Site) Less(i, j int) bool { - return s.Articles[i].Date.After(s.Articles[j].Date) -} - -// Swap is needed to implement the sorting interface. -func (s Site) Swap(i, j int) { - s.Articles[i], s.Articles[j] = s.Articles[j], s.Articles[i] -} diff --git a/src/site/context.go b/src/site/context.go deleted file mode 100644 index 4706a8a..0000000 --- a/src/site/context.go +++ /dev/null @@ -1,72 +0,0 @@ -package site - -import ( - "time" - - "context" - "file" -) - -func (s Site) newSiteContext() context.SiteContext { - return context.SiteContext{ - s.Articles, s.Pages, - s.Tags, - s.Categories, - s.getNumberOfPages(), - s.Config, - } -} - -// NewContext will create a common Context object to be used by other contexts. -func (s Site) NewContext() *context.Context { - contextSite := s.newSiteContext() - return &context.Context{ - Site: contextSite, - } -} - -// NewArticleContext return the context needed to render an Article document. -func (s Site) NewArticleContext(f file.ParsedFile) *context.Context { - c := s.NewContext() - c.Article = f - return c -} - -// NewPageContext returns the context needed to render a Page document. -func (s Site) NewPageContext(f file.ParsedFile) *context.Context { - c := s.NewContext() - c.Page = f - return c -} - -// NewAtomFeedContext returns the context needed to render the Atom feed. -func (s Site) NewAtomFeedContext(limit int) *context.Context { - c := s.NewContext() - c.Updated = time.Now().Format(time.RFC3339) - c.Articles = s.Articles[:limit] - return c -} - -// NewTagContext returns the context needed to render a tag page. -func (s Site) NewTagContext(tag string) *context.Context { - c := s.NewContext() - c.Tag = tag - c.Articles = c.ArticlesByTag(tag) - return c -} - -// NewCategoryContext returns the context needed to render a Category page. -func (s Site) NewCategoryContext(category string) *context.Context { - c := s.NewContext() - c.Category = category - c.Articles = c.ArticlesByCategory(category) - return c -} - -// NewPaginatedContext returns the context needed to render an Index page. -func (s Site) NewPaginatedContext(page int) *context.Context { - c := s.NewContext() - c.PageNumber = page - c.Articles = c.ArticlesByPage(page) - return c -} diff --git a/src/site/types.go b/src/site/types.go deleted file mode 100644 index a6f8cc6..0000000 --- a/src/site/types.go +++ /dev/null @@ -1,109 +0,0 @@ -package site - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "sort" - "strings" - "sync" - - "config" - "file" -) - -// Site is the struct that we will during the execution of the program. It will -// be our storage, config... -type Site struct { - Config config.Config - outputPath string - - Articles, Pages []*file.ParsedFile - Categories []string - Tags []string - - mux sync.Mutex -} - -// New returns a new Site object. -func New(config config.Config, outputPath string) *Site { - site := &Site{Config: config, outputPath: outputPath} - return site -} - -func newUniqueSlugError(slug string) error { - errorMessage := fmt.Sprintf("The slug '%s' already exists!", slug) - return errors.New(errorMessage) -} - -// AppendUniqueTags will append the tag only if it's not already on the site -// tags. -func (site *Site) AppendUniqueTags(newTags []string) { -LOOP: - for _, newTag := range newTags { - for _, oldTag := range site.Tags { - if newTag == oldTag { - continue LOOP - } - } - site.Tags = append(site.Tags, newTag) - } -} - -// AppendUniqueCategory will append the category just in case that doesn't -// belong to the Site yet. -func (site *Site) AppendUniqueCategory(newCategory string) { - for _, category := range site.Categories { - if category == newCategory { - return - } - } - site.Categories = append(site.Categories, newCategory) -} - -// Populate will read the file system searching for markdown and store those on -// the Site object. -func (site *Site) Populate(root string) error { - if err := filepath.Walk(root, site.parseAndStore); err != nil { - return err - } - // Sort the articles after we got them - sort.Sort(site) - return nil -} - -// Append the paths to an array in case that they are markdown files. -func (site *Site) parseAndStore(path string, fileInfo os.FileInfo, inputErr error) (err error) { - if inputErr != nil { - return inputErr - } - - slugsPresence := make(map[string]bool) - - if !fileInfo.Mode().IsDir() && strings.HasSuffix(path, ".md") { - file, err := file.New(path) - if err != nil { - return err - } - - if _, present := slugsPresence[file.Slug]; present { - return newUniqueSlugError(file.Slug) - } - slugsPresence[file.Slug] = true - - // Add the pages or articles to the proper array on the site - if file.IsPage { - site.Pages = append(site.Pages, file) - } else { - site.Articles = append(site.Articles, file) - - // Just supported on Articles - if len(file.Tags) > 0 { - site.AppendUniqueTags(file.Tags) - } - site.AppendUniqueCategory(file.Category) - } - } - return -} diff --git a/src/site/writers.go b/src/site/writers.go deleted file mode 100644 index 06d62e0..0000000 --- a/src/site/writers.go +++ /dev/null @@ -1,397 +0,0 @@ -package site - -import ( - "fmt" - "html/template" - "io/ioutil" - "log" - "math" - "os" - "path" - "path/filepath" - "strings" - "sync" - - "context" - "file" - - // TODO: Perhaps it worth moving the template rendering to the template - // package - assets "templates" -) - -var templates map[string]*template.Template - -// parseFiles is a wrapper similar to template.ParseFiles that is going to -// load the templates from the disk, and if they can not be found from the -// go-bindata file. -func parseFiles(filenames ...string) (*template.Template, error) { - tpl := template.New(filenames[0]) - for _, filename := range filenames { - b, err := ioutil.ReadFile(filename) - if err != nil { - b, err = assets.Asset(filename) - if err != nil { - log.Printf("Template: %s not found. Not in HD neihter in bindata!", filename) - return nil, err - } - } - tpl.Parse(string(b)) - } - return tpl, nil -} - -// loadTemplates is an ugly function but I need it to run the test without the -// template files. If I don't call .Write() I don't need the template files. -func loadTemplates() { - templates = make(map[string]*template.Template) - toRender := make(map[string][]string) - - toRender["atom"] = []string{"templates/atom.xml"} - - getAllTemplateInheritance := func(templates []string) []string { - return append([]string{ - "templates/base/base.html", - "templates/base/header.html", - "templates/base/footer.html", - "templates/base/analytics.html"}, templates...) - } - - toRender["archives"] = getAllTemplateInheritance([]string{"templates/archives.html"}) - toRender["article"] = getAllTemplateInheritance([]string{"templates/article/article.html", "templates/article/disqus.html", "templates/article/sharethis.html"}) - toRender["category"] = getAllTemplateInheritance([]string{"templates/category.html"}) - toRender["index"] = getAllTemplateInheritance([]string{"templates/index.html"}) - toRender["page"] = getAllTemplateInheritance([]string{"templates/page.html"}) - toRender["tag"] = getAllTemplateInheritance([]string{"templates/tag.html"}) - - for name, values := range toRender { - templates[name] = template.Must(parseFiles(values...)) - } -} - -// createAbsolutePath assures that the full dir tree exists and return the -// point to the file -func (site Site) createAbsolutePath(elem ...string) (file *os.File, err error) { - site.mux.Lock() - defer site.mux.Unlock() - - // TODO: I am not pretty sure that this is the best way to do this - s := make([]string, 1, 1) - s[0] = site.outputPath - elem = append(s, elem...) - absolutePath := path.Join(elem...) - - dir := filepath.Dir(absolutePath) - if _, err := os.Stat(dir); os.IsNotExist(err) { - if err := os.Mkdir(dir, 0777); err != nil { - return nil, err - } - } - - file, err = os.Create(absolutePath) - if err != nil { - return nil, err - } - - return file, nil -} - -// Auxiliar function to quickly log the quantity of items created -func logCreation(noun string, quantity int) string { - var pluralize string - if quantity > 1 { - pluralize = "s" - } - return fmt.Sprintf("%5d %s%s created", quantity, strings.Title(noun), pluralize) -} - -// Dump all the site content to the disk -func (site Site) Write() (err error) { - loadTemplates() - - var wg sync.WaitGroup - chErrors := make(chan error, 12) // Enough buffer for all the subroutines - - wg.Add(4) // The following 4 subroutines are mandatory - - go func() { - defer wg.Done() - i, err := site.writeIndexes() - fmt.Println(logCreation("index page", i)) - if err != nil { - log.Panic(err) - } - chErrors <- err - }() - - go func() { - defer wg.Done() - i, err := site.writeFeeds() - fmt.Println(logCreation("feed", i)) - chErrors <- err - }() - - go func() { - defer wg.Done() - i, err := site.writeArticles() - fmt.Println(logCreation("article", i)) - chErrors <- err - }() - - go func() { - defer wg.Done() - i, err := site.writePages() - fmt.Println(logCreation("page", i)) - chErrors <- err - }() - - if site.Config.ShowArchive { - wg.Add(1) - go func() { - defer wg.Done() - err := site.writeArchive() - fmt.Println(logCreation("archive", 1)) // If error it will not be 1, but we don't care - chErrors <- err - }() - } - if site.Config.ShowCategories { - wg.Add(1) - go func() { - defer wg.Done() - i, err := site.writeCategories() - fmt.Println(logCreation("category page", i)) - chErrors <- err - }() - } - if site.Config.ShowTags { - wg.Add(1) - go func() { - defer wg.Done() - i, err := site.writeTags() - fmt.Println(logCreation("tag page", i)) - chErrors <- err - }() - } - - wg.Wait() - -LOOP: - for { - select { - case err := <-chErrors: - if err != nil { - return err - } - default: - break LOOP - } - } - - return nil -} - -func (site Site) getNumberOfPages() int { - return int( - math.Ceil( - float64(len(site.Articles)) / float64(site.Config.PaginationSize))) -} - -func (site Site) writeIndexes() (int, error) { - var pageNumber int - - for pageNumber = 1; pageNumber <= site.getNumberOfPages(); pageNumber++ { - indexFile := "index.html" - if pageNumber > 1 { - indexFile = fmt.Sprintf("index%d.html", pageNumber) - } - - file, err := site.createAbsolutePath(indexFile) - if err != nil { - return pageNumber, err - } - - if err := templates["index"].ExecuteTemplate(file, "base", site.NewPaginatedContext(pageNumber)); err != nil { - return pageNumber, err - } - } - - return pageNumber, nil -} - -type contextCreator func(f file.ParsedFile) *context.Context - -func (site Site) writeparsedFiles( - files []*file.ParsedFile, template *template.Template, newContext contextCreator) (int, error) { - - var ( - parsedFile *file.ParsedFile - wg sync.WaitGroup - ) - errChan := make(chan error, len(files)) - - for _, parsedFile = range files { - wg.Add(1) - go func(parsedFile *file.ParsedFile) { - defer wg.Done() - - file, err := site.createAbsolutePath(parsedFile.Slug) - if err != nil { - errChan <- err - return - } - - context := newContext(*parsedFile) - if err := template.ExecuteTemplate(file, "base", context); err != nil { - errChan <- err - } - }(parsedFile) - } - - wg.Wait() - - select { - case err := <-errChan: - if err != nil { - return -1, err - } - default: - break - } - - return len(files), nil -} - -func (site Site) writeArticles() (int, error) { - return site.writeparsedFiles(site.Articles, templates["article"], site.NewArticleContext) -} - -func (site Site) writePages() (int, error) { - return site.writeparsedFiles(site.Pages, templates["page"], site.NewPageContext) -} - -func (site Site) writeArchive() error { - file, err := site.createAbsolutePath("archives.html") - if err != nil { - return err - } - - if err := templates["archives"].ExecuteTemplate(file, "base", site.NewContext()); err != nil { - return err - } - - return nil -} - -func (site Site) writeCategories() (int, error) { - var wg sync.WaitGroup - errChan := make(chan error, len(site.Categories)) - - for _, category := range site.Categories { - wg.Add(1) - go func(category string) { - defer wg.Done() - - categoryFile := fmt.Sprintf("category/%s.html", category) - file, err := site.createAbsolutePath(categoryFile) - if err != nil { - errChan <- err - return - } - - if err := templates["category"].ExecuteTemplate(file, "base", site.NewCategoryContext(category)); err != nil { - errChan <- err - } - - errChan <- nil - }(category) - } - - wg.Wait() - - select { - case err := <-errChan: - if err != nil { - return -1, err - } - default: - break - } - - return len(site.Categories), nil -} - -func (site Site) writeTags() (int, error) { - var wg sync.WaitGroup - errChan := make(chan error, len(site.Tags)) - - for _, tag := range site.Tags { - wg.Add(1) - go func(tag string) { - defer wg.Done() - - tagFile := fmt.Sprintf("tag/%s.html", tag) - file, err := site.createAbsolutePath(tagFile) - if err != nil { - errChan <- err - return - } - - if err := templates["tag"].ExecuteTemplate(file, "base", site.NewTagContext(tag)); err != nil { - errChan <- err - } - - errChan <- nil - }(tag) - } - - wg.Wait() - - select { - case err := <-errChan: - if err != nil { - return -1, err - } - default: - break - } - - return len(site.Tags), nil -} - -func (site Site) writeFeeds() (int, error) { - var i int - - if err := site.writeAtomFeed(); err != nil { - return i + 1, err - } - - if err := site.writeRSSFeed(); err != nil { - return i + 1, err - } - - i++ // Not implemented yet, fake it - return i, nil -} - -func (site Site) writeAtomFeed() error { - file, err := site.createAbsolutePath("feeds/all.atom.xml") - if err != nil { - return err - } - - limit := len(site.Articles) - if limit > 10 { // TODO: Move feed limit of news to the config - limit = 10 - } - - if err := templates["atom"].Execute(file, site.NewAtomFeedContext(limit)); err != nil { - return err - } - - return nil -} - -func (site Site) writeRSSFeed() error { - // TODO (agonzalezro): to be implemented if somebody needs it - return nil -} diff --git a/src/templates/archives.html b/src/templates/archives.html deleted file mode 100644 index 6a65f59..0000000 --- a/src/templates/archives.html +++ /dev/null @@ -1,13 +0,0 @@ -{{define "title"}} -Archives | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -<h1>Archives</h1> -<dl class="dl-horizontal"> - {{range $_, $article := .Site.Articles}} - <dt>{{$.HumanizeDatetime $article.Date}}</dt> - <dd><a href="{{$article.Slug}}">{{$article.Title}}</a></dd> - {{end}} -</dl> -{{end}} diff --git a/src/templates/article/article.html b/src/templates/article/article.html deleted file mode 100644 index 9048385..0000000 --- a/src/templates/article/article.html +++ /dev/null @@ -1,37 +0,0 @@ -{{define "title"}} -{{.Article.Title}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -<h1>{{.Article.Title}}</h1> - -<p> -{{if .Site.Config.Author }} -<span class="label label-default">by {{.Site.Config.Author}}</span> -{{end}} - -{{if .Article.Date}} -<span class="label label-default">{{.HumanizeDatetime .Article.Date}}</span> -{{end}} - -{{if .Article.Category}} -<a class="label label-success" href="/category/{{.Article.Category}}.html">{{.Article.Category}}</a> -{{end}} - -{{if .Article.Tags}} -{{range $_, $tag := .Article.Tags}} -<a class="label label-info" href="/tag/{{$tag}}.html">{{$tag}}</a> -{{end}} -{{end}} -</p> - -{{.Article.HTML .Article.Content}} - -{{if .Site.Config.ShareThisPublisher}} -{{template "sharethis" .}} -{{end}} - -{{if .Site.Config.DisqusSitename}} -{{template "disqus" .}} -{{end}} -{{end}} diff --git a/src/templates/article/sharethis.html b/src/templates/article/sharethis.html deleted file mode 100644 index c144a6d..0000000 --- a/src/templates/article/sharethis.html +++ /dev/null @@ -1,10 +0,0 @@ -{{define "sharethis"}} -<br> -<span class='st_sharethis_large' displayText='ShareThis'></span> -<span class='st_facebook_large' displayText='Facebook'></span> -<span class='st_twitter_large' displayText='Tweet'></span> -<span class='st_linkedin_large' displayText='LinkedIn'></span> -<span class='st_googleplus_large' displayText='Google +'></span> -<span class='st_reddit_large' displayText='Reddit'></span> -<span class='st_email_large' displayText='Email'></span> -{{end}} diff --git a/src/templates/atom.xml b/src/templates/atom.xml deleted file mode 100644 index d0ec88d..0000000 --- a/src/templates/atom.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<feed xmlns="http://www.w3.org/2005/Atom"> - <title>{{.Site.Config.Title}} - - {{.Updated}} - - {{if .Articles}} - {{range $_, $article := .Articles}} - - {{$article.Title}} - - {{if $article.Date}} - {{$article.Date}} - {{end}} - - {{$article.HTML $article.Summary}} - - - {{$.Site.Config.Author}} - - - {{end}} - {{end}} - diff --git a/src/templates/base/base.html b/src/templates/base/base.html deleted file mode 100644 index bb85da1..0000000 --- a/src/templates/base/base.html +++ /dev/null @@ -1,93 +0,0 @@ -{{define "base"}} - - - - - - - - {{template "title" .}} - - - {{if .Site.Config.Favicon}} - - {{end}} - - {{template "header" .}} - - {{if .Site.Config.ShareThisPublisher}} - - - - {{end}} - - - - - -
- {{template "content" .}} -
- {{template "footer" .}} - {{template "analytics" .}} - - -{{end}} diff --git a/src/templates/base/footer.html b/src/templates/base/footer.html deleted file mode 100644 index 73b5f52..0000000 --- a/src/templates/base/footer.html +++ /dev/null @@ -1,14 +0,0 @@ -{{define "footer"}} - {{/* This should be split on new releases */}} -
-
-

- polo is made with - by - @agonzalezro -

-
-
- - -{{end}} diff --git a/src/templates/base/header.html b/src/templates/base/header.html deleted file mode 100644 index c2f5ac5..0000000 --- a/src/templates/base/header.html +++ /dev/null @@ -1,4 +0,0 @@ -{{define "header"}} - - -{{end}} diff --git a/src/templates/bindata.go b/src/templates/bindata.go deleted file mode 100644 index 6230260..0000000 --- a/src/templates/bindata.go +++ /dev/null @@ -1,849 +0,0 @@ -// Code generated by go-bindata. -// sources: -// templates/archives.html -// templates/article/article.html -// templates/article/disqus.html -// templates/article/sharethis.html -// templates/atom.xml -// templates/base/analytics.html -// templates/base/base.html -// templates/base/footer.html -// templates/base/header.html -// templates/category.html -// templates/index.html -// templates/page.html -// templates/tag.html -// templates/templates/archives.html -// templates/templates/article/article.html -// templates/templates/article/disqus.html -// templates/templates/article/sharethis.html -// templates/templates/atom.xml -// templates/templates/base/analytics.html -// templates/templates/base/base.html -// templates/templates/base/footer.html -// templates/templates/base/header.html -// templates/templates/category.html -// templates/templates/index.html -// templates/templates/page.html -// templates/templates/tag.html -// DO NOT EDIT! - -package templates - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "strings" - "os" - "time" - "io/ioutil" - "path" - "path/filepath" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindataFileInfo) Name() string { - return fi.name -} -func (fi bindataFileInfo) Size() int64 { - return fi.size -} -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} -func (fi bindataFileInfo) IsDir() bool { - return false -} -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _templatesArchivesHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x8f\xb1\x4e\xc4\x30\x0c\x86\xf7\x3e\x85\x15\x75\x84\x54\xac\x28\x8d\x74\x82\x81\xfd\xd8\x51\xd4\xb8\xad\xa5\x5c\x2a\xa5\x3e\x86\x33\x79\x77\x5c\xca\x15\xa6\xc8\xbf\xbe\xcf\xce\x2f\x12\x71\xa4\x8c\x60\x98\x38\xa1\xa9\xb5\x39\x95\x61\xa6\x4f\x5c\xe1\x0b\x44\xec\x99\x18\xed\xcb\x92\x47\x9a\xec\xfb\x86\x28\x21\x82\x39\xea\xdb\xfc\xd9\xc3\x92\x19\x33\x6f\xbe\x9b\x9f\xfc\x7d\x87\xeb\x74\x68\x5c\x4c\x30\xa4\xb0\xae\xbd\x89\xe9\x71\x5e\x0a\xdd\x14\x0f\xc9\xf8\x06\xf4\x46\x09\x79\x42\x68\x3f\x1e\xa0\x0d\x85\x69\x48\x08\xcf\x3d\xec\x97\x4f\x7b\xb0\xea\x5e\x00\x17\xd9\x8b\xb4\xf6\xed\x7a\x09\x99\x6e\xf8\x1a\x18\x99\x2e\x78\x78\x76\x4b\x6a\x75\x9d\x82\x3f\x7c\xf4\x2e\xc0\x5c\x70\xec\x8d\x8a\x77\xea\x9c\xae\x53\xad\xc6\xff\x8b\x7e\xab\xb9\x2e\x78\xb5\xe3\xfe\xb1\xbd\xa5\xce\xc9\x1f\x9d\xbf\x03\x00\x00\xff\xff\x3f\x64\x0b\x14\x31\x01\x00\x00") - -func templatesArchivesHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesArchivesHtml, - "templates/archives.html", - ) -} - -func templatesArchivesHtml() (*asset, error) { - bytes, err := templatesArchivesHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/archives.html", size: 305, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesArticleArticleHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x92\x41\x6f\xa3\x30\x10\x85\xef\xfc\x0a\xcb\xca\x71\x17\xb4\xd7\x15\x41\x8a\x92\x43\x0e\xbb\x52\xa5\x70\xaf\x26\x64\xc0\x96\x8c\x49\xed\xe1\x90\x52\xfe\x7b\xc7\xa4\x34\x40\x52\xb5\x97\x58\x19\xcf\xfb\xde\xc3\x33\x5d\x77\xc2\x52\x5b\x14\x92\x34\x19\x94\x7d\x1f\x75\x5d\xbc\x71\xa4\x0b\x83\x71\x1e\x6a\x7d\x2f\xde\x04\x17\x0f\x9a\x30\xde\x36\xb6\xd4\xd5\x78\xc1\xbd\x68\x4f\x7c\x46\x37\x4e\xd1\x58\x42\x4b\x81\x94\xaa\x3f\xd9\x3d\x2d\x4d\xb8\x1c\x45\xe9\x39\x63\x95\x2e\xc5\x0c\xbc\x69\x49\x35\x4e\x04\xb1\x3f\x83\x15\x85\x01\xef\xd7\xd2\xc0\x11\x8d\x18\x7e\x7f\xb3\x11\xb4\x86\x64\x76\xbc\x2c\x63\x5d\xd5\xc1\x22\x88\xb3\x69\xbc\x60\x34\x06\xd9\x01\xe1\x8f\x1c\x18\xbf\x6f\x6b\xb0\xfa\x15\x83\x86\x74\x8d\x4b\xca\x37\x56\x5b\x6e\xaa\x1a\x77\x09\x76\xf0\xc8\xcb\xb7\x45\x81\xde\x4b\xa1\x1c\x96\x6b\x99\x14\x1f\x82\x64\xf2\x70\x37\x48\xac\xa8\x36\x32\x7b\x78\x97\x26\xf0\x65\x8c\x1c\x2a\x3f\x8c\xcb\x81\xad\x50\xac\x9e\x7f\x89\x15\x41\x25\xfe\xae\xef\x7a\x1e\xc7\xd4\xb6\x6c\x3e\x33\xb2\x92\xe3\x05\xc0\x24\xd1\xf5\xef\x2c\xc4\x78\xa6\x09\xcf\x7a\xba\x57\xfb\xfc\xff\xbf\xc9\x1b\x5d\x37\xe6\x96\x7a\x3a\xd2\x83\x02\x87\xb9\xd2\xfe\xa9\x3d\x1a\xed\x15\xba\x01\x4c\x58\x9f\x0d\x7f\xba\x90\x3e\x34\x10\x37\x48\x11\xcf\x37\x72\x89\xda\x69\xff\xd2\xfa\x50\xb1\x50\xe3\x02\x73\x1a\x2e\xe7\x8c\xf1\x7c\x0f\x00\x00\xff\xff\x48\x15\x1f\x37\x25\x03\x00\x00") - -func templatesArticleArticleHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesArticleArticleHtml, - "templates/article/article.html", - ) -} - -func templatesArticleArticleHtml() (*asset, error) { - bytes, err := templatesArticleArticleHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/article/article.html", size: 805, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesArticleDisqusHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x53\x4f\x6f\x9c\x3e\x10\xbd\xef\xa7\x18\x71\x31\x28\x0a\xfe\xe9\x77\xcc\xb2\x54\xed\xa6\x87\xf6\xd0\x54\xda\xdc\xaa\x2a\x32\x78\x00\x67\x8d\xcd\xda\x66\xb7\x84\xec\x77\xef\xb0\x90\xa8\x7f\xd5\x13\x78\xe6\xcd\xcc\x9b\xe7\xe7\x71\x94\x58\x29\x83\x10\x49\xe5\x0f\xbd\x8f\xce\xe7\x55\xd6\xfc\x9f\x6f\x6d\xdb\xa2\x09\x3e\xe3\x74\x58\x65\x52\x1d\x41\xc9\xcd\x02\x7a\x08\x8d\x43\x21\xa3\x3c\xe3\x94\xa0\xb4\x2f\x9d\xea\x02\x84\xa1\xc3\x4d\x14\xf0\x5b\xe0\x8f\xe2\x28\xe6\x68\x94\xaf\x00\x8e\xc2\xc1\x52\xeb\x1b\xeb\x82\x11\x2d\xc2\x06\xd8\x38\xa6\x3b\x15\x30\xdd\x5a\x53\xa9\x3a\xbd\xbd\x40\xa6\xc8\x04\x38\x9f\xd9\x9a\x6a\x39\x87\xfb\xbb\xdb\x3b\x88\x45\x6d\xcd\x93\xd0\xf8\xe4\x6c\x72\x03\xc4\xb0\x13\x41\x15\x4a\xab\x30\xc0\x49\x85\x06\xda\x01\xac\x96\x50\x68\x5b\x83\x70\x41\x95\x1a\xfd\xdc\xe0\x03\x48\x6b\x58\x80\xbd\xb1\x27\x50\x15\xa8\x40\x15\x5a\xc3\xc9\xba\x3d\x54\xd6\x81\x0d\x0d\x3a\xe8\x3d\x3a\xff\x33\x5d\x25\x49\x06\x55\x29\xca\xce\x7c\xdf\xce\x8d\xd3\x9d\xee\xeb\x0b\x43\xc2\xc7\x55\x6f\xca\xa0\xac\x89\x13\x18\xe9\xbc\x74\xf0\x07\xaa\x91\xb6\xec\x27\x29\xd3\x92\x34\x0b\xf8\x5e\xe3\x74\x8a\xd9\xac\x0e\x4b\xd6\x13\x2e\x9d\xa4\x9b\x06\xfc\x22\x1e\x9b\xb3\xc2\x0f\xa6\xa4\x74\x70\x3d\xae\x2f\xfd\xa7\xa8\x77\x53\x8c\x71\xce\xe0\xea\x77\x75\xaf\x80\xa5\x73\x30\x2d\x6d\xcb\xb1\x2d\x50\xa6\x8f\x9e\xcd\xf5\xf1\x2b\xad\x1a\xc3\xc2\xc9\xbf\x1b\xee\x45\xfd\x89\x8a\x63\xd6\xd0\xfd\xb2\xe4\xcb\x7f\x5f\xe1\xf9\x19\xfe\x81\x2d\xac\x1c\x2e\xd8\x24\x15\x5d\x87\x46\x6e\x1b\xa5\x65\x4c\x14\x93\x69\xd8\x39\x89\xe9\x9b\xf1\x79\x23\x72\x8b\xb1\xcb\xef\x67\x8d\xc2\x23\xd0\x65\x17\x1a\xe1\x23\x6d\xbd\x5b\x8c\x64\xe1\xa8\xf0\x04\x74\x29\x90\x09\x20\xb7\x55\x9b\xa8\x09\xa1\xbb\xe1\xfc\x87\x9d\xde\x50\xfc\xe1\xa5\x5b\x94\x97\x8b\x67\xa1\xb3\x27\x74\x48\x46\x18\x60\x76\x54\x9a\x71\x41\x66\x7d\x1d\xbc\xfa\x7b\xd3\x08\x4a\x2d\xbc\x27\xab\xfb\xc3\x75\xe1\xb4\x32\xfb\x3f\x77\xce\x7c\x27\xcc\x0b\x98\x1c\x67\xaf\x97\x17\x94\xcf\x33\x69\x61\x02\xe4\xd3\xe4\xd5\x38\x92\x2a\xf4\xb2\xbe\x07\x00\x00\xff\xff\x43\x45\x7a\xc4\x6e\x03\x00\x00") - -func templatesArticleDisqusHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesArticleDisqusHtml, - "templates/article/disqus.html", - ) -} - -func templatesArticleDisqusHtml() (*asset, error) { - bytes, err := templatesArticleDisqusHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/article/disqus.html", size: 878, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesArticleSharethisHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\xd1\xb1\x0e\x82\x30\x10\xc6\xf1\x9d\xa7\x68\x58\x3a\x38\xf8\x02\xc0\xa6\xc6\xc4\x49\xd9\x49\xa1\x07\x5c\xa8\x2d\x69\xcf\xa0\x69\x78\x77\x81\x18\x1d\x6c\xe7\x7f\x7f\x5f\xd2\x9c\xf7\x12\x5a\xd4\xc0\x52\xd7\x0b\x0b\xd4\xa3\x4b\xe7\x39\xc9\x6a\x5b\x24\x99\x1b\x85\x66\x8d\x12\xce\xe5\xdc\x51\xf5\x7d\x51\x29\x61\x3b\xe0\x4c\xa2\x1b\x95\x78\x95\xf0\xa4\x9c\xdf\xd6\x5a\x2e\x95\x17\xd9\x7e\x95\xff\x03\xad\x68\xa0\x36\x66\x08\xfa\xe3\x27\xc6\x39\x4d\x48\x04\x36\xa8\xcb\x09\x80\xe2\x54\xa1\x1e\x40\xa2\x0e\xda\xcb\x16\xcf\x3a\xce\x3b\x63\x3a\x05\xa3\x7a\x84\xbf\x7e\xda\x32\xdb\xc5\x07\x2c\x48\x89\x14\xc4\xd7\x2d\xc5\x29\xdc\x05\xaa\xa0\x3c\xac\xe5\x07\xbd\x07\x2d\x97\xdb\xbd\x03\x00\x00\xff\xff\xb6\x22\x45\x39\xd3\x01\x00\x00") - -func templatesArticleSharethisHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesArticleSharethisHtml, - "templates/article/sharethis.html", - ) -} - -func templatesArticleSharethisHtml() (*asset, error) { - bytes, err := templatesArticleSharethisHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/article/sharethis.html", size: 467, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesAtomXml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x92\x4d\x4f\xc3\x20\x18\xc7\xef\xfd\x14\x84\xec\xa8\x30\x35\x26\x66\xa1\x5d\x16\x3d\x78\x98\x17\xb7\x9d\x0d\x59\x9f\x76\xc4\x16\x16\x4a\xad\xa6\xe1\xbb\x3b\xe8\xe8\x9b\xde\xc8\xf3\x7f\xe1\xf7\x10\xd8\xfa\xbb\x2c\xd0\x17\xe8\x4a\x28\x19\xe3\x3b\xb2\xc4\x08\xe4\x51\xa5\x42\xe6\x31\xae\x4d\x76\xfb\x84\xd7\x49\x14\xb1\x0c\x20\x45\x17\xaf\xac\x62\x7c\x32\xe6\xbc\xa2\xb4\x69\x1a\xd2\x3c\x10\xa5\x73\x7a\xbf\x5c\x3e\xd2\x8d\x51\x25\x4e\x22\x84\x98\x11\xa6\x80\xa4\x6d\xc9\x4e\x18\x20\xcf\x4a\x66\x22\x27\x7b\x37\xb4\x96\xd1\x4e\x75\xbe\x42\xc8\x4f\x74\xd2\x90\xc5\x78\x66\x3e\xbc\x6f\xad\xc5\x88\x7a\x5b\x7d\x4e\xb9\x81\xd4\x15\x1e\xba\xa3\xab\x09\xd3\xe8\x62\x69\x5b\x91\x21\xb2\xd1\x46\x1c\x0b\xa8\xac\xf5\x23\xcd\x65\x0e\x68\xf1\x71\x83\x16\xbc\x53\xd0\x2a\x9e\xb9\x18\x48\xa3\x7f\xdc\x2d\x23\xec\x60\xff\x07\x79\x0e\xbd\xf8\x4b\x3d\xca\xef\x8a\x3a\xef\xd7\xb8\x52\xf6\xe2\xcb\x85\xde\x33\x4c\x36\x9c\xc9\xa3\x35\xbb\x06\x90\x69\x08\x55\x75\x59\xf2\x00\xef\xb4\x3e\xfb\xba\x7f\xdb\x0e\x17\xed\x3a\x5f\x88\xd1\x49\x8e\xf1\xda\x9c\x94\x0e\x25\x4c\xf2\xd2\x3f\xc1\x64\xaf\x8d\xf7\x38\x1a\x2f\x5f\x7b\x86\x24\xa3\xfd\x33\x0e\x84\xe1\xc4\xa8\xfb\x3b\x49\xf4\x1b\x00\x00\xff\xff\x41\x57\x24\xb9\x6b\x02\x00\x00") - -func templatesAtomXmlBytes() ([]byte, error) { - return bindataRead( - _templatesAtomXml, - "templates/atom.xml", - ) -} - -func templatesAtomXml() (*asset, error) { - bytes, err := templatesAtomXmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/atom.xml", size: 619, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesBaseAnalyticsHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x92\x51\x8f\xd3\x30\x0c\xc7\xdf\xf9\x14\x56\x5f\xd2\x8a\x53\xca\xf3\xf5\x76\xe8\x0e\x10\xe2\xe5\x84\x04\x6f\xd3\x34\x99\xd4\xcd\xb2\x75\x49\x49\xdc\x41\xd5\xed\xbb\x93\xa6\x9d\x98\x10\xd2\x3d\xc5\xfe\xfb\x57\xdb\xff\xca\xe3\x58\x53\x63\x2c\x41\x86\x16\xdb\x81\x8d\x0a\xd9\xe5\xf2\x06\x60\x1c\x4d\x03\xf2\x9b\x61\x92\x1f\x9c\x6d\x8c\x96\x9f\x9d\xd3\x2d\x3d\x5d\xb1\x2f\x1f\x13\xf7\x10\x94\x37\x1d\x03\x0f\x1d\xad\x32\xa6\xdf\x5c\xee\xf1\x84\xb3\x9a\x3d\x46\x02\xe0\x84\x1e\xb6\x1a\x7f\xc2\x6a\x7e\xce\x67\x58\x6f\xaa\x54\x9a\x72\xd9\xf5\x61\x97\xaf\xc5\x36\x10\x3f\x29\xe5\x7a\xcb\xe2\x0e\xc4\x38\xbe\x36\x5e\x6c\x8a\xff\x74\x61\x8f\xea\xf0\x15\x35\x9d\x0c\xfd\x4a\x48\x62\xf2\xa6\xb7\x8a\x8d\xb3\x79\x01\x63\x52\xe6\xc5\x34\xc6\xb5\x6a\xa7\xfa\x23\x59\x96\xca\x13\x32\x7d\x6a\x69\xca\x72\x31\xdb\x10\x45\x15\x31\x39\x59\x8c\xac\xf8\xc7\xa4\x48\x45\x0c\x83\x55\xb1\xca\xbe\xa7\x6a\x69\x1f\xe5\xe0\x27\x31\x17\x3b\xe6\x2e\xdc\x0b\x58\xdd\xcc\x6a\x9d\xc2\x69\x21\xd9\x79\xc7\x4e\xb9\x16\xde\xc3\x02\x96\xa5\x80\xfb\x39\x99\xe2\x02\xde\x82\x08\x8c\x1c\xa4\x96\xb5\xeb\x7f\xb4\xa4\x5a\xa3\x0e\xd2\x12\x97\xb5\x92\xfb\x20\xaa\x1b\x4b\xe1\xd6\x91\x26\x5e\xec\x84\xe7\xe1\x3b\xea\x17\x3c\xd2\x5f\x63\xeb\x77\x9b\x0a\x82\xec\xd0\x47\xe0\xc5\xd5\x24\x8d\x0d\xe4\xf9\x99\x1a\xe7\x29\xd7\x78\x07\x61\xf9\xc9\x97\x22\x4f\xd1\x43\x39\x7f\xfc\x98\xae\x84\x6c\x1d\xef\xe0\xfa\xfe\x09\x00\x00\xff\xff\xea\xed\x60\x78\x4f\x02\x00\x00") - -func templatesBaseAnalyticsHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesBaseAnalyticsHtml, - "templates/base/analytics.html", - ) -} - -func templatesBaseAnalyticsHtml() (*asset, error) { - bytes, err := templatesBaseAnalyticsHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/base/analytics.html", size: 591, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesBaseBaseHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x57\x5b\x6f\xe4\x34\x14\x7e\xdf\x5f\x61\x4c\x1f\xb6\xa2\x49\xb6\x48\x48\xab\xee\x24\x52\x77\xd8\x15\x48\xc0\x56\xea\x20\xc1\x13\xf2\x24\x9e\xc4\x8b\x13\x07\xdb\x99\xe9\x28\x9a\xff\xce\xb1\x63\xe7\x36\x69\x69\x85\x16\x89\xa7\xc4\xe7\x7e\xf9\xce\x89\xd3\xb6\x19\xdd\xb1\x8a\x22\xbc\x25\x8a\xe2\xd3\xe9\xd5\xea\xab\xef\x3f\xad\x37\xbf\xdf\x7d\x40\x85\x2e\x79\xf2\x6a\xd5\x3d\x10\x5a\x15\x94\x64\xe6\x05\x5e\x4b\xaa\x09\x4a\x0b\x22\x15\xd5\x31\x6e\xf4\x2e\x78\x8b\xc7\xac\x42\xeb\x3a\xa0\x7f\x35\x6c\x1f\xe3\xdf\x82\x5f\x6f\x83\xb5\x28\x6b\xa2\xd9\x96\x53\x8c\x52\x51\x69\x5a\x81\xde\x8f\x1f\x62\x9a\xe5\x74\xa2\x59\x91\x92\xc6\x78\xcf\xe8\xa1\x16\x52\x8f\x84\x0f\x2c\xd3\x45\x9c\xd1\x3d\x4b\x69\x60\x0f\x57\x88\x55\x4c\x33\xc2\x03\x95\x12\x4e\xe3\xeb\xf0\x0d\x98\xea\x6c\x69\xa6\x39\x4d\xda\x56\xd3\xb2\xe6\x44\x43\x7e\x96\x82\x51\x78\x3a\xad\xa2\x8e\xeb\x44\x39\xab\xfe\x44\x85\xa4\xbb\x18\x47\x3b\x4a\x33\x15\x11\xce\x43\xa2\x45\x19\x3e\x94\x1c\x23\x7d\xac\x21\x22\x52\xd7\x9c\xa5\x90\x82\xa8\x22\xc3\xfb\xc6\xf2\x24\xe5\xc0\xe2\x9a\xca\x0a\x9c\x80\xac\x31\x1c\xe3\x7b\xa6\x29\x84\x48\xd1\xed\xe6\xd3\xcf\xe8\x23\x18\x75\x39\xb6\x2d\xdb\xa1\xd0\xb0\xc3\xb5\xa8\x76\x2c\x0f\x3f\x12\x48\x48\x54\x50\xf8\x21\x18\x6b\x55\x15\x90\x7f\xda\x68\x64\xd8\xd8\x05\xd8\xb6\xcb\xca\x18\x45\xde\x01\xad\x32\x30\xe6\x0e\x43\xfa\xa6\x79\x54\xda\xfc\x5f\x3d\x12\xca\x3d\xf4\x93\x6e\x0a\xa6\xee\x9a\x2d\x67\xaa\xa0\xd2\x47\xa5\x52\xc9\x6a\xed\x2a\xa1\xe9\x83\x8e\x3e\x93\x3d\xe9\xa8\x38\xd9\x13\x89\xd4\x81\xe9\xb4\xd8\x88\xef\x1e\x62\x2d\x1b\xfa\x6e\x15\x75\xdc\xe4\x19\x06\x90\x92\x29\xd4\x3e\x3a\x84\xca\x44\xa0\x21\x82\x30\x15\x65\xb4\x6d\xb4\x86\x6a\x77\x0f\x15\x7e\x56\x38\x79\x89\xd9\x4e\x06\x21\xa5\x7f\x62\x79\xa1\x43\x51\x9b\xe6\xa9\xd7\x6d\xed\xd3\xbb\x41\xf3\x82\x2e\x95\x00\x5f\xa1\x4c\xfc\x22\xf4\x0f\x44\x15\x37\x68\x47\xb8\xa2\x8e\xb2\x16\xf5\xb1\xa7\x14\xc0\xbe\xcd\x32\x49\x95\x7a\x4f\xa4\x23\x9f\x2e\xdf\x75\x91\x4e\xe2\xf6\x4d\x32\xf4\x6e\xa8\xcc\xeb\x56\x64\x47\x97\x57\xc6\xf6\x28\xe5\x44\xa9\x18\x57\x64\xbf\x85\xfa\x76\x8f\x00\x86\x95\x34\x5c\xfb\xa3\xd2\x00\xc8\x34\xd0\xa2\x06\x28\x0a\x83\x3c\x60\xb0\xdc\xa2\xb4\xcf\x7f\x6c\xcd\x4c\x13\x81\x71\x97\x3d\x77\xc9\x5b\xe0\xc0\x32\xc8\x98\xf0\x6c\x1b\x5c\xad\xbb\x03\x9e\xa9\x69\x91\xe7\x66\xc6\x32\xa2\x89\x3b\x18\x97\x9c\x93\x5a\xf5\x64\x22\x73\xb3\x33\x42\xa7\xd3\xb3\xc7\xce\x4c\x6b\x6b\x52\x79\xf3\x4a\x06\xa2\xe2\x47\x9c\x6c\xac\x4d\x34\x24\x09\x75\x05\xb9\x27\x54\xcd\x78\x04\xe0\xc7\x42\xe7\x3f\x11\x5d\x39\xc0\x4e\x68\x64\x56\xa9\xad\x24\x55\xe6\x87\x3a\xc2\xc9\x0c\x86\x1b\xb3\x46\xcc\xa2\x22\xa3\x36\x45\xd0\xa7\xe1\x68\xc7\x57\x48\x37\xc1\x77\x24\xa7\x0a\xbd\x06\xa3\x8e\xb0\x21\xb9\x9a\x4f\xb7\x38\x18\xea\xe5\x58\x6c\x0d\xbb\x21\x17\x92\xd1\x05\xe1\x81\x37\x51\xb9\x95\x00\x39\xbe\xa4\x70\x2b\xd3\x82\xed\xe9\xa5\xdb\x1a\x8f\x60\xcb\x37\x1c\x2d\x76\xfe\x1f\xd2\x7a\x91\x73\x70\xdf\xf0\x91\x77\x3f\x35\xf0\x98\xa1\x6d\x69\x17\xf6\x26\x27\x16\xed\x8a\x4e\xa0\x9f\xae\x75\xa4\x93\x51\xa1\xf9\x4a\xe2\xc4\xa9\x28\xd3\xb9\x55\x04\x92\x33\x37\x7e\xee\xc7\x34\x80\x42\x4e\xd1\xc5\x1f\x57\xe8\xa2\x86\x7c\xd1\x4d\x3c\xce\xfe\x29\xef\x6d\x6b\x35\xc2\x7b\xde\xe4\xb0\xa7\x12\x7f\x1e\xc1\xe7\x39\x41\xac\xa2\x86\x4f\x7b\x80\x40\x04\x4d\x64\x7c\x5f\xfe\x1d\x76\x9e\x40\xe5\xf3\xfa\xe6\x5f\xa5\xd9\xe8\x4b\x4d\x7c\x69\x78\xe7\xe5\xf5\x8e\x33\x29\xea\x4c\x1c\xaa\xf9\x62\xf2\xc5\xff\x7a\xb6\xe7\x06\xf9\x91\xe7\xd5\xb6\xdf\xbc\xe6\xcb\x66\xf6\xc5\x36\x99\x8c\xf5\x2c\x5d\x6f\x25\x28\x69\xd5\xcc\x5c\xcf\xc0\x92\x76\x6e\x8e\x03\x60\x1e\x4d\xcb\x68\x5e\x10\x3f\x3b\x20\x7f\xd1\x4f\xd2\xfb\xe3\xda\xdb\xe9\x2d\x9e\x69\xaf\xe6\x20\x1a\xd5\x21\xf2\x5a\x11\xf8\x18\x2c\xb8\x81\x98\xd0\xa6\x4b\x74\x4b\xe0\xee\x87\xea\x86\x73\xdf\xce\xb6\xe5\xb4\x42\x7d\xa0\x06\xc1\x76\xbb\x9e\x15\xcc\x60\xf6\x3c\xa4\xa5\xf1\x9a\x63\x7b\x49\x73\x79\x2c\x27\x60\x7a\x1c\xb8\x5f\x02\x40\xd6\xdb\x97\x84\x8e\x26\xf9\x80\x9a\x85\x2c\x9e\xc4\x0b\xc8\x5b\x0b\x2f\x43\x09\x28\x18\x80\x58\xbd\x01\x1b\xf6\xf8\xbf\x81\xc5\xf9\xa2\x9c\x4a\x9c\x7d\xa2\xc7\xec\x11\xd3\xbd\x9e\xdd\xf5\xfa\xdb\x99\xf9\x36\x06\x65\x16\x5c\xbf\xf1\x6f\x62\xb7\x83\x5f\xad\xe0\xda\x9e\x79\x1e\xbc\xf5\x2f\x8e\xf1\x6d\xdf\xf0\xf1\xa5\xdf\xfd\x3c\x75\xb7\xfe\x59\x10\x63\xb9\x9d\x10\xda\xff\x1c\xcc\x79\xa4\x22\xfc\x08\x95\x57\x9e\x0d\x38\xb4\x37\x55\xb8\xbb\xda\x3f\x43\x9f\xe6\xdf\x01\x00\x00\xff\xff\x5b\x40\x77\x1c\x4b\x0e\x00\x00") - -func templatesBaseBaseHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesBaseBaseHtml, - "templates/base/base.html", - ) -} - -func templatesBaseBaseHtml() (*asset, error) { - bytes, err := templatesBaseBaseHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/base/base.html", size: 3659, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesBaseFooterHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\x92\xdd\x8e\xa3\x30\x0c\x85\xef\xf7\x29\xac\x5c\x56\x82\x94\xbd\x5a\xad\x28\xda\x87\xd8\x17\x08\x60\x20\x28\x24\xd9\xd8\xdd\xfe\xa0\xbe\xfb\x18\x5a\xa6\x33\x53\xcd\x0d\x3a\x8e\xc3\xe7\x73\xc0\xf3\xdc\x62\x67\x3d\x82\xea\x42\x60\x4c\xea\x76\xfb\x01\x30\xcf\x7a\x07\x7f\x07\x4b\x40\x43\x38\xba\x16\x6a\x04\x8a\xce\x32\x04\x0f\x1e\x4f\x90\xd0\xa1\x21\x24\xd8\xe9\xf5\x85\xb2\xb5\xff\xa1\x71\x86\xe8\xa0\x9a\xe0\xd9\x08\x32\x41\x13\x5c\x36\xb5\x59\xb1\xdf\x54\xe8\x3a\x42\xce\x8a\xb5\x76\x7d\xf6\x6b\x13\x8f\xc6\x4f\x55\x09\xec\x33\x8e\xf1\xcc\x59\x83\x7e\x31\x77\xef\x4a\x3f\x6e\x4a\xb4\x81\x21\x61\x77\x50\x03\x73\xfc\xad\x75\x6f\x79\x38\xd6\x79\x13\x26\x6d\xfa\xe0\xaf\xc6\xe1\x35\x05\x1d\x83\x0b\xaa\x5a\x9e\xa5\x36\x15\x48\xb4\xc9\xb4\x08\x27\xb9\xfd\x44\x51\x34\x7e\x9b\xdb\xbb\x4b\x1c\xac\x84\x81\x77\x95\x0d\x68\x12\xab\xaa\xd4\xcb\xc5\x0a\xea\xcb\xb7\x2e\x58\xc0\xe2\xf8\xab\x0d\x55\xfd\xf9\x50\x2d\x4e\xb6\x44\xfa\x11\xa9\xd4\x92\x7d\x91\x4f\x41\x4d\xb2\x91\x81\x52\x73\xc7\x93\xf0\xcd\x68\xce\x79\x1f\x42\x2f\xff\x21\x5a\xba\xcf\x91\x33\xed\x6c\x4d\x7a\xfc\x77\xc4\x74\xd1\x45\x5e\x14\xf9\xfe\x51\xe5\x93\xf5\xf9\x48\xab\xfb\x15\xf8\xc2\x96\x6f\x87\x5c\xcb\x1a\x10\x27\x13\x57\x64\x6b\x89\xf5\x48\xfa\x79\xfa\x4a\x99\x67\xf4\xad\x6c\xc1\x5b\x00\x00\x00\xff\xff\xa9\xef\x18\x09\x4b\x02\x00\x00") - -func templatesBaseFooterHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesBaseFooterHtml, - "templates/base/footer.html", - ) -} - -func templatesBaseFooterHtml() (*asset, error) { - bytes, err := templatesBaseFooterHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/base/footer.html", size: 587, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesBaseHeaderHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\xcf\x31\x0e\x02\x21\x10\x85\xe1\xde\x53\x90\xe9\x05\x93\x6d\x5d\xef\x82\xcc\xdb\x40\x84\xc1\x30\xd3\x18\xb2\x77\x77\x2b\xf5\x02\xb6\x7f\x5e\xf2\xe5\xcd\xc9\xd8\x8a\xc0\x51\x46\x64\x0c\xda\xf7\x93\x73\xd7\x5a\xe4\xe1\x06\xea\x4a\x6a\xaf\x0a\xcd\x80\x91\xcb\x03\xdb\x4a\x21\x08\x8c\x25\xfa\x7b\xef\xa6\x36\xe2\x33\xb1\xf8\xd4\x5b\xf8\x84\xb0\xf8\x8b\x5f\x42\x52\xfd\x36\xdf\xca\xb1\x52\xa5\xdb\x9f\x80\xb3\x65\x34\xfc\x30\x73\x42\xf8\xf8\xf3\x0e\x00\x00\xff\xff\x6a\x24\xeb\x71\xe4\x00\x00\x00") - -func templatesBaseHeaderHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesBaseHeaderHtml, - "templates/base/header.html", - ) -} - -func templatesBaseHeaderHtml() (*asset, error) { - bytes, err := templatesBaseHeaderHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/base/header.html", size: 228, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesCategoryHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x54\x8e\x41\xab\xc3\x20\x10\x84\xef\xfe\x8a\x45\x72\x7c\x28\xef\xfa\xd8\x08\x8f\xfc\x84\xf4\x5e\x24\xd9\x18\x41\x0c\xd8\xcd\xa1\x58\xff\x7b\x4d\xd2\xd0\xf6\xa4\x33\xcc\x7e\x33\x39\x8f\x34\xf9\x48\x20\xd9\x73\x20\x59\x8a\xc8\x59\x75\x96\xc9\x2d\xe9\x5e\x0a\x3c\xa0\xea\xde\x33\xa9\x6e\x89\x93\x77\xea\xb2\xe5\xf6\x18\xc5\xb1\xbe\xe2\x8d\x18\x96\xc8\x14\x79\x83\xe0\xfc\x6b\xbe\x40\xa8\xab\x23\x70\x0d\x46\x40\x45\x26\x1b\x1d\x41\x73\xfd\x81\xc6\x26\xf6\x43\x20\xf8\x6b\x41\xfd\x1f\xff\x5b\x25\x00\x60\xf0\x06\x2d\xcc\x89\xa6\x56\xe6\x7c\x06\x55\x1f\x56\x57\x8a\x34\x1f\xd6\x6b\x14\x6a\x6b\x50\xd7\xb3\xbd\xe3\xd8\x87\x7a\xeb\x3c\xd5\x33\x00\x00\xff\xff\x03\x42\x6c\xbd\xf0\x00\x00\x00") - -func templatesCategoryHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesCategoryHtml, - "templates/category.html", - ) -} - -func templatesCategoryHtml() (*asset, error) { - bytes, err := templatesCategoryHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/category.html", size: 240, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x55\x4f\x6f\xa3\x3e\x10\xbd\xf3\x29\x5c\x7e\xd1\xef\x50\x6d\x41\xbd\xee\x12\xa4\xaa\x7b\xe8\xa1\x9b\xad\xd4\xdc\x2b\x07\x06\xb0\x64\x4c\x62\x9b\xa8\x59\x94\xef\xbe\xe3\x3f\x04\x9c\xa5\xda\x6a\x23\x25\x86\x19\xcf\xbc\x37\x33\xcf\xce\x30\x94\x50\x31\x01\x24\xd6\x4c\x73\x88\xcf\xe7\x68\x18\x92\x57\xa6\x21\x79\xec\x44\xc5\xea\x64\x6b\xec\xd6\x0c\xa2\xc4\x35\x9a\x42\x8a\x4e\x68\x10\xda\x05\xb1\x8a\x24\x0f\x52\xb3\x82\x83\x72\xdb\x24\x15\x35\x90\xd5\xdb\x17\xb2\xa2\xce\x41\xbe\xae\x83\x4d\x99\xb7\xe7\x51\xd6\xdc\xe7\x19\x25\x8d\x84\x6a\x1d\x0f\xc3\x18\x90\xbc\xf2\xbe\x3e\x9f\xe3\x7c\x66\xf2\x84\xb2\x94\xe6\x59\x8a\x61\x51\x94\xed\x73\x47\xa0\x93\x64\x15\x90\x7f\xe8\x75\x63\x8c\x63\xac\x7b\x37\xc8\x6a\x4f\x05\x29\x38\x55\x6a\x1d\x73\xba\x03\x4e\xec\xef\x1d\xd6\x46\x7b\xae\xe3\x7c\x77\x22\x36\xe7\x1f\xb1\x33\x2a\x93\x09\xb8\x02\xeb\x5a\x80\xb7\x7e\xd3\xbb\x2c\x35\xa8\xf9\xbc\x95\x73\x80\xef\x54\xc3\xa7\xa8\x19\x98\xa7\xbe\xa5\x82\xfd\x02\x13\xa4\x59\x0b\xd7\x69\xfe\x82\xf5\x88\x9b\xea\x4e\x9e\xec\x10\x96\xc0\x54\x5f\x14\xa0\x54\xec\x47\x92\x16\x3e\x20\x9d\x95\x3f\x25\x49\x1a\xdd\xf2\x60\x4a\x93\xcf\x0c\xea\x23\x1a\x5b\x5a\x2b\xab\x9e\x99\x56\x34\xad\x8d\x4e\xae\xf7\x2c\xd3\x64\xa2\xea\x2e\x1c\x31\xd2\xd0\xc3\x65\xce\xc8\xbe\x06\x24\xc6\x35\x4b\x51\x38\xd1\x8c\xf4\xd3\xf6\xc7\xf3\xac\x47\x4e\xde\x66\xe3\x7e\xc4\xd6\xf0\xae\xef\x24\xab\x1b\x1c\xc3\xc4\x68\xa7\x05\xc1\xef\x65\x42\x1f\xe9\xf8\xbf\x92\xa9\x43\xaf\xde\x34\xfa\x69\x19\xe7\xcf\x40\x8f\x40\x30\x4d\xd7\xb6\x88\x74\xe3\x34\x8d\xa4\xf0\x61\x3a\x19\x32\x68\x9f\x53\x9a\x3d\x30\x9b\x4e\x37\x4c\xd4\x44\x77\x44\x01\x90\x06\x24\xdc\xb8\x23\x71\x1d\x84\x3d\xaf\x35\x71\xda\xdc\xf4\xed\x0e\xe4\xcf\xea\x85\xd6\xa0\xc8\xbd\xc9\x55\xb2\x63\x50\x60\x81\x64\x40\x62\x85\x3d\x1f\xed\x7b\x5a\x33\x41\x35\xeb\x44\x8c\x3d\x23\xf8\xc9\x38\x1b\x9d\xf6\xdd\xa2\xc0\x01\x4f\xa0\xc9\xec\x50\x6c\x7a\xe3\xc4\xc2\xe9\x8e\x43\xe9\x77\x3a\x62\xe6\x19\xb3\xd9\x64\xb3\xb3\x9f\xbc\x48\x38\xb2\xae\x57\xa6\x69\x41\x3a\x73\x13\xfc\xcf\xe9\xa1\xef\xbe\xd9\x81\xda\xc8\x94\x33\xcf\x28\x90\x11\x12\x1e\xef\x1b\x49\x4f\xbe\x5c\x0f\x6a\xa8\x5f\xe8\xda\x8d\x21\x8a\x2f\x8b\x16\x9a\x1d\x21\xf6\x74\xaf\x88\xa6\x4c\x94\xf0\x6e\xb3\xe0\x5d\xe8\xb2\xdc\xdb\x2b\xc0\x3c\x5e\xce\xbc\xd7\xa1\x8d\x35\x0c\xbd\xd7\x53\x0f\x6a\x98\xb5\x06\xd7\xf4\x96\xb8\x6a\x6e\x53\x33\xc3\x4f\x77\x7c\xb5\x30\xe5\x7f\x19\xc2\x06\x85\xb0\x3c\x00\xb9\x38\x80\x2c\xed\x39\x8a\x17\xa5\x74\x51\x9e\xab\x02\x39\xda\x12\x02\xa3\xff\xeb\x70\x9e\xdf\x01\x00\x00\xff\xff\x15\x8b\x41\x60\x85\x06\x00\x00") - -func templatesIndexHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesIndexHtml, - "templates/index.html", - ) -} - -func templatesIndexHtml() (*asset, error) { - bytes, err := templatesIndexHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/index.html", size: 1669, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesPageHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xaa\xae\x4e\x49\x4d\xcb\xcc\x4b\x55\x50\x2a\xc9\x2c\xc9\x49\x55\xaa\xad\xe5\xaa\xae\xd6\x0b\x48\x4c\x4f\xd5\x0b\x01\x09\xd4\xd6\x2a\xd4\x28\x00\x45\x82\x33\x4b\x52\xf5\x9c\xf3\xf3\xd2\x32\xd3\x61\x12\x40\x85\xa9\x79\x29\x40\x9a\x0b\x61\x48\x72\x7e\x5e\x49\x6a\x5e\x09\xc8\x18\x9b\x0c\x43\x3b\x34\xa3\x6c\xf4\x81\x62\x70\xf3\x3d\x42\x7c\x7d\x14\x20\x4c\x67\x88\x36\x24\x33\x01\x01\x00\x00\xff\xff\x27\x7a\x43\x12\x98\x00\x00\x00") - -func templatesPageHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesPageHtml, - "templates/page.html", - ) -} - -func templatesPageHtml() (*asset, error) { - bytes, err := templatesPageHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/page.html", size: 152, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTagHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x8e\xc1\x0a\x83\x30\x10\x44\xef\xf9\x8a\x25\x78\x2c\x09\xbd\x96\x35\x50\xfa\x09\x7a\x2f\x41\x57\x0d\x84\x08\x36\x9e\xb6\xf9\xf7\xae\x5a\x69\x4f\xd9\x09\xf3\x66\x86\xb9\xa7\x21\x24\x02\x9d\x43\x8e\xa4\x4b\x51\xcc\xa6\xf5\x63\x29\xf0\x06\x39\x9b\x90\xc9\x3c\xe6\x34\x84\xd1\xb4\x9b\x65\x77\x50\xea\xe5\x55\x3f\xba\x9b\x53\xa6\x94\x37\x1e\xa7\xab\x3b\x33\xd0\x8a\x50\xb8\x46\xa7\x40\xd2\x16\x9f\x46\x82\xea\x79\x81\xca\x2f\x39\x74\x91\xe0\x56\x83\xb9\x1f\xf7\x4b\x60\x00\x8c\xc1\xa1\x87\x69\xa1\xa1\xd6\xcc\xa7\xd1\x34\x71\x95\x40\xed\xfe\xbe\xbe\x7b\xd0\x7a\x87\x56\xb0\xbd\xe3\x98\x86\x76\xeb\x3c\xd5\x27\x00\x00\xff\xff\xd0\xa4\x2a\x22\xe6\x00\x00\x00") - -func templatesTagHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTagHtml, - "templates/tag.html", - ) -} - -func templatesTagHtml() (*asset, error) { - bytes, err := templatesTagHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/tag.html", size: 230, mode: os.FileMode(420), modTime: time.Unix(1435084316, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesArchivesHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x8f\xb1\x4e\xc4\x30\x0c\x86\xf7\x3e\x85\x15\x75\x84\x54\xac\x28\x8d\x74\x82\x81\xfd\xd8\x51\xd4\xb8\xad\xa5\x5c\x2a\xa5\x3e\x86\x33\x79\x77\x5c\xca\x15\xa6\xc8\xbf\xbe\xcf\xce\x2f\x12\x71\xa4\x8c\x60\x98\x38\xa1\xa9\xb5\x39\x95\x61\xa6\x4f\x5c\xe1\x0b\x44\xec\x99\x18\xed\xcb\x92\x47\x9a\xec\xfb\x86\x28\x21\x82\x39\xea\xdb\xfc\xd9\xc3\x92\x19\x33\x6f\xbe\x9b\x9f\xfc\x7d\x87\xeb\x74\x68\x5c\x4c\x30\xa4\xb0\xae\xbd\x89\xe9\x71\x5e\x0a\xdd\x14\x0f\xc9\xf8\x06\xf4\x46\x09\x79\x42\x68\x3f\x1e\xa0\x0d\x85\x69\x48\x08\xcf\x3d\xec\x97\x4f\x7b\xb0\xea\x5e\x00\x17\xd9\x8b\xb4\xf6\xed\x7a\x09\x99\x6e\xf8\x1a\x18\x99\x2e\x78\x78\x76\x4b\x6a\x75\x9d\x82\x3f\x7c\xf4\x2e\xc0\x5c\x70\xec\x8d\x8a\x77\xea\x9c\xae\x53\xad\xc6\xff\x8b\x7e\xab\xb9\x2e\x78\xb5\xe3\xfe\xb1\xbd\xa5\xce\xc9\x1f\x9d\xbf\x03\x00\x00\xff\xff\x3f\x64\x0b\x14\x31\x01\x00\x00") - -func templatesTemplatesArchivesHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesArchivesHtml, - "templates/templates/archives.html", - ) -} - -func templatesTemplatesArchivesHtml() (*asset, error) { - bytes, err := templatesTemplatesArchivesHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/archives.html", size: 305, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesArticleArticleHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x92\x41\x6f\xa3\x30\x10\x85\xef\xfc\x0a\xcb\xca\x71\x17\xb4\xd7\x15\x41\x8a\x92\x43\x0e\xbb\x52\xa5\x70\xaf\x26\x64\xc0\x96\x8c\x49\xed\xe1\x90\x52\xfe\x7b\xc7\xa4\x34\x40\x52\xb5\x97\x58\x19\xcf\xfb\xde\xc3\x33\x5d\x77\xc2\x52\x5b\x14\x92\x34\x19\x94\x7d\x1f\x75\x5d\xbc\x71\xa4\x0b\x83\x71\x1e\x6a\x7d\x2f\xde\x04\x17\x0f\x9a\x30\xde\x36\xb6\xd4\xd5\x78\xc1\xbd\x68\x4f\x7c\x46\x37\x4e\xd1\x58\x42\x4b\x81\x94\xaa\x3f\xd9\x3d\x2d\x4d\xb8\x1c\x45\xe9\x39\x63\x95\x2e\xc5\x0c\xbc\x69\x49\x35\x4e\x04\xb1\x3f\x83\x15\x85\x01\xef\xd7\xd2\xc0\x11\x8d\x18\x7e\x7f\xb3\x11\xb4\x86\x64\x76\xbc\x2c\x63\x5d\xd5\xc1\x22\x88\xb3\x69\xbc\x60\x34\x06\xd9\x01\xe1\x8f\x1c\x18\xbf\x6f\x6b\xb0\xfa\x15\x83\x86\x74\x8d\x4b\xca\x37\x56\x5b\x6e\xaa\x1a\x77\x09\x76\xf0\xc8\xcb\xb7\x45\x81\xde\x4b\xa1\x1c\x96\x6b\x99\x14\x1f\x82\x64\xf2\x70\x37\x48\xac\xa8\x36\x32\x7b\x78\x97\x26\xf0\x65\x8c\x1c\x2a\x3f\x8c\xcb\x81\xad\x50\xac\x9e\x7f\x89\x15\x41\x25\xfe\xae\xef\x7a\x1e\xc7\xd4\xb6\x6c\x3e\x33\xb2\x92\xe3\x05\xc0\x24\xd1\xf5\xef\x2c\xc4\x78\xa6\x09\xcf\x7a\xba\x57\xfb\xfc\xff\xbf\xc9\x1b\x5d\x37\xe6\x96\x7a\x3a\xd2\x83\x02\x87\xb9\xd2\xfe\xa9\x3d\x1a\xed\x15\xba\x01\x4c\x58\x9f\x0d\x7f\xba\x90\x3e\x34\x10\x37\x48\x11\xcf\x37\x72\x89\xda\x69\xff\xd2\xfa\x50\xb1\x50\xe3\x02\x73\x1a\x2e\xe7\x8c\xf1\x7c\x0f\x00\x00\xff\xff\x48\x15\x1f\x37\x25\x03\x00\x00") - -func templatesTemplatesArticleArticleHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesArticleArticleHtml, - "templates/templates/article/article.html", - ) -} - -func templatesTemplatesArticleArticleHtml() (*asset, error) { - bytes, err := templatesTemplatesArticleArticleHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/article/article.html", size: 805, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesArticleDisqusHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x53\x4f\x6f\x9c\x3e\x10\xbd\xef\xa7\x18\x71\x31\x28\x0a\xfe\xe9\x77\xcc\xb2\x54\xed\xa6\x87\xf6\xd0\x54\xda\xdc\xaa\x2a\x32\x78\x00\x67\x8d\xcd\xda\x66\xb7\x84\xec\x77\xef\xb0\x90\xa8\x7f\xd5\x13\x78\xe6\xcd\xcc\x9b\xe7\xe7\x71\x94\x58\x29\x83\x10\x49\xe5\x0f\xbd\x8f\xce\xe7\x55\xd6\xfc\x9f\x6f\x6d\xdb\xa2\x09\x3e\xe3\x74\x58\x65\x52\x1d\x41\xc9\xcd\x02\x7a\x08\x8d\x43\x21\xa3\x3c\xe3\x94\xa0\xb4\x2f\x9d\xea\x02\x84\xa1\xc3\x4d\x14\xf0\x5b\xe0\x8f\xe2\x28\xe6\x68\x94\xaf\x00\x8e\xc2\xc1\x52\xeb\x1b\xeb\x82\x11\x2d\xc2\x06\xd8\x38\xa6\x3b\x15\x30\xdd\x5a\x53\xa9\x3a\xbd\xbd\x40\xa6\xc8\x04\x38\x9f\xd9\x9a\x6a\x39\x87\xfb\xbb\xdb\x3b\x88\x45\x6d\xcd\x93\xd0\xf8\xe4\x6c\x72\x03\xc4\xb0\x13\x41\x15\x4a\xab\x30\xc0\x49\x85\x06\xda\x01\xac\x96\x50\x68\x5b\x83\x70\x41\x95\x1a\xfd\xdc\xe0\x03\x48\x6b\x58\x80\xbd\xb1\x27\x50\x15\xa8\x40\x15\x5a\xc3\xc9\xba\x3d\x54\xd6\x81\x0d\x0d\x3a\xe8\x3d\x3a\xff\x33\x5d\x25\x49\x06\x55\x29\xca\xce\x7c\xdf\xce\x8d\xd3\x9d\xee\xeb\x0b\x43\xc2\xc7\x55\x6f\xca\xa0\xac\x89\x13\x18\xe9\xbc\x74\xf0\x07\xaa\x91\xb6\xec\x27\x29\xd3\x92\x34\x0b\xf8\x5e\xe3\x74\x8a\xd9\xac\x0e\x4b\xd6\x13\x2e\x9d\xa4\x9b\x06\xfc\x22\x1e\x9b\xb3\xc2\x0f\xa6\xa4\x74\x70\x3d\xae\x2f\xfd\xa7\xa8\x77\x53\x8c\x71\xce\xe0\xea\x77\x75\xaf\x80\xa5\x73\x30\x2d\x6d\xcb\xb1\x2d\x50\xa6\x8f\x9e\xcd\xf5\xf1\x2b\xad\x1a\xc3\xc2\xc9\xbf\x1b\xee\x45\xfd\x89\x8a\x63\xd6\xd0\xfd\xb2\xe4\xcb\x7f\x5f\xe1\xf9\x19\xfe\x81\x2d\xac\x1c\x2e\xd8\x24\x15\x5d\x87\x46\x6e\x1b\xa5\x65\x4c\x14\x93\x69\xd8\x39\x89\xe9\x9b\xf1\x79\x23\x72\x8b\xb1\xcb\xef\x67\x8d\xc2\x23\xd0\x65\x17\x1a\xe1\x23\x6d\xbd\x5b\x8c\x64\xe1\xa8\xf0\x04\x74\x29\x90\x09\x20\xb7\x55\x9b\xa8\x09\xa1\xbb\xe1\xfc\x87\x9d\xde\x50\xfc\xe1\xa5\x5b\x94\x97\x8b\x67\xa1\xb3\x27\x74\x48\x46\x18\x60\x76\x54\x9a\x71\x41\x66\x7d\x1d\xbc\xfa\x7b\xd3\x08\x4a\x2d\xbc\x27\xab\xfb\xc3\x75\xe1\xb4\x32\xfb\x3f\x77\xce\x7c\x27\xcc\x0b\x98\x1c\x67\xaf\x97\x17\x94\xcf\x33\x69\x61\x02\xe4\xd3\xe4\xd5\x38\x92\x2a\xf4\xb2\xbe\x07\x00\x00\xff\xff\x43\x45\x7a\xc4\x6e\x03\x00\x00") - -func templatesTemplatesArticleDisqusHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesArticleDisqusHtml, - "templates/templates/article/disqus.html", - ) -} - -func templatesTemplatesArticleDisqusHtml() (*asset, error) { - bytes, err := templatesTemplatesArticleDisqusHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/article/disqus.html", size: 878, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesArticleSharethisHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\xd1\xb1\x0e\x82\x30\x10\xc6\xf1\x9d\xa7\x68\x58\x3a\x38\xf8\x02\xc0\xa6\xc6\xc4\x49\xd9\x49\xa1\x07\x5c\xa8\x2d\x69\xcf\xa0\x69\x78\x77\x81\x18\x1d\x6c\xe7\x7f\x7f\x5f\xd2\x9c\xf7\x12\x5a\xd4\xc0\x52\xd7\x0b\x0b\xd4\xa3\x4b\xe7\x39\xc9\x6a\x5b\x24\x99\x1b\x85\x66\x8d\x12\xce\xe5\xdc\x51\xf5\x7d\x51\x29\x61\x3b\xe0\x4c\xa2\x1b\x95\x78\x95\xf0\xa4\x9c\xdf\xd6\x5a\x2e\x95\x17\xd9\x7e\x95\xff\x03\xad\x68\xa0\x36\x66\x08\xfa\xe3\x27\xc6\x39\x4d\x48\x04\x36\xa8\xcb\x09\x80\xe2\x54\xa1\x1e\x40\xa2\x0e\xda\xcb\x16\xcf\x3a\xce\x3b\x63\x3a\x05\xa3\x7a\x84\xbf\x7e\xda\x32\xdb\xc5\x07\x2c\x48\x89\x14\xc4\xd7\x2d\xc5\x29\xdc\x05\xaa\xa0\x3c\xac\xe5\x07\xbd\x07\x2d\x97\xdb\xbd\x03\x00\x00\xff\xff\xb6\x22\x45\x39\xd3\x01\x00\x00") - -func templatesTemplatesArticleSharethisHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesArticleSharethisHtml, - "templates/templates/article/sharethis.html", - ) -} - -func templatesTemplatesArticleSharethisHtml() (*asset, error) { - bytes, err := templatesTemplatesArticleSharethisHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/article/sharethis.html", size: 467, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesAtomXml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x92\x4d\x4f\xc3\x20\x18\xc7\xef\xfd\x14\x84\xec\xa8\x30\x35\x26\x66\xa1\x5d\x16\x3d\x78\x98\x17\xb7\x9d\x0d\x59\x9f\x76\xc4\x16\x16\x4a\xad\xa6\xe1\xbb\x3b\xe8\xe8\x9b\xde\xc8\xf3\x7f\xe1\xf7\x10\xd8\xfa\xbb\x2c\xd0\x17\xe8\x4a\x28\x19\xe3\x3b\xb2\xc4\x08\xe4\x51\xa5\x42\xe6\x31\xae\x4d\x76\xfb\x84\xd7\x49\x14\xb1\x0c\x20\x45\x17\xaf\xac\x62\x7c\x32\xe6\xbc\xa2\xb4\x69\x1a\xd2\x3c\x10\xa5\x73\x7a\xbf\x5c\x3e\xd2\x8d\x51\x25\x4e\x22\x84\x98\x11\xa6\x80\xa4\x6d\xc9\x4e\x18\x20\xcf\x4a\x66\x22\x27\x7b\x37\xb4\x96\xd1\x4e\x75\xbe\x42\xc8\x4f\x74\xd2\x90\xc5\x78\x66\x3e\xbc\x6f\xad\xc5\x88\x7a\x5b\x7d\x4e\xb9\x81\xd4\x15\x1e\xba\xa3\xab\x09\xd3\xe8\x62\x69\x5b\x91\x21\xb2\xd1\x46\x1c\x0b\xa8\xac\xf5\x23\xcd\x65\x0e\x68\xf1\x71\x83\x16\xbc\x53\xd0\x2a\x9e\xb9\x18\x48\xa3\x7f\xdc\x2d\x23\xec\x60\xff\x07\x79\x0e\xbd\xf8\x4b\x3d\xca\xef\x8a\x3a\xef\xd7\xb8\x52\xf6\xe2\xcb\x85\xde\x33\x4c\x36\x9c\xc9\xa3\x35\xbb\x06\x90\x69\x08\x55\x75\x59\xf2\x00\xef\xb4\x3e\xfb\xba\x7f\xdb\x0e\x17\xed\x3a\x5f\x88\xd1\x49\x8e\xf1\xda\x9c\x94\x0e\x25\x4c\xf2\xd2\x3f\xc1\x64\xaf\x8d\xf7\x38\x1a\x2f\x5f\x7b\x86\x24\xa3\xfd\x33\x0e\x84\xe1\xc4\xa8\xfb\x3b\x49\xf4\x1b\x00\x00\xff\xff\x41\x57\x24\xb9\x6b\x02\x00\x00") - -func templatesTemplatesAtomXmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesAtomXml, - "templates/templates/atom.xml", - ) -} - -func templatesTemplatesAtomXml() (*asset, error) { - bytes, err := templatesTemplatesAtomXmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/atom.xml", size: 619, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesBaseAnalyticsHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x92\x51\x8f\xd3\x30\x0c\xc7\xdf\xf9\x14\x56\x5f\xd2\x8a\x53\xca\xf3\xf5\x76\xe8\x0e\x10\xe2\xe5\x84\x04\x6f\xd3\x34\x99\xd4\xcd\xb2\x75\x49\x49\xdc\x41\xd5\xed\xbb\x93\xa6\x9d\x98\x10\xd2\x3d\xc5\xfe\xfb\x57\xdb\xff\xca\xe3\x58\x53\x63\x2c\x41\x86\x16\xdb\x81\x8d\x0a\xd9\xe5\xf2\x06\x60\x1c\x4d\x03\xf2\x9b\x61\x92\x1f\x9c\x6d\x8c\x96\x9f\x9d\xd3\x2d\x3d\x5d\xb1\x2f\x1f\x13\xf7\x10\x94\x37\x1d\x03\x0f\x1d\xad\x32\xa6\xdf\x5c\xee\xf1\x84\xb3\x9a\x3d\x46\x02\xe0\x84\x1e\xb6\x1a\x7f\xc2\x6a\x7e\xce\x67\x58\x6f\xaa\x54\x9a\x72\xd9\xf5\x61\x97\xaf\xc5\x36\x10\x3f\x29\xe5\x7a\xcb\xe2\x0e\xc4\x38\xbe\x36\x5e\x6c\x8a\xff\x74\x61\x8f\xea\xf0\x15\x35\x9d\x0c\xfd\x4a\x48\x62\xf2\xa6\xb7\x8a\x8d\xb3\x79\x01\x63\x52\xe6\xc5\x34\xc6\xb5\x6a\xa7\xfa\x23\x59\x96\xca\x13\x32\x7d\x6a\x69\xca\x72\x31\xdb\x10\x45\x15\x31\x39\x59\x8c\xac\xf8\xc7\xa4\x48\x45\x0c\x83\x55\xb1\xca\xbe\xa7\x6a\x69\x1f\xe5\xe0\x27\x31\x17\x3b\xe6\x2e\xdc\x0b\x58\xdd\xcc\x6a\x9d\xc2\x69\x21\xd9\x79\xc7\x4e\xb9\x16\xde\xc3\x02\x96\xa5\x80\xfb\x39\x99\xe2\x02\xde\x82\x08\x8c\x1c\xa4\x96\xb5\xeb\x7f\xb4\xa4\x5a\xa3\x0e\xd2\x12\x97\xb5\x92\xfb\x20\xaa\x1b\x4b\xe1\xd6\x91\x26\x5e\xec\x84\xe7\xe1\x3b\xea\x17\x3c\xd2\x5f\x63\xeb\x77\x9b\x0a\x82\xec\xd0\x47\xe0\xc5\xd5\x24\x8d\x0d\xe4\xf9\x99\x1a\xe7\x29\xd7\x78\x07\x61\xf9\xc9\x97\x22\x4f\xd1\x43\x39\x7f\xfc\x98\xae\x84\x6c\x1d\xef\xe0\xfa\xfe\x09\x00\x00\xff\xff\xea\xed\x60\x78\x4f\x02\x00\x00") - -func templatesTemplatesBaseAnalyticsHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesBaseAnalyticsHtml, - "templates/templates/base/analytics.html", - ) -} - -func templatesTemplatesBaseAnalyticsHtml() (*asset, error) { - bytes, err := templatesTemplatesBaseAnalyticsHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/base/analytics.html", size: 591, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesBaseBaseHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x57\x5b\x6f\xe4\x34\x14\x7e\xdf\x5f\x61\x4c\x1f\xb6\xa2\x49\xb6\x48\x48\xab\xee\x24\x52\x77\xd8\x15\x48\xc0\x56\xea\x20\xc1\x13\xf2\x24\x9e\xc4\x8b\x13\x07\xdb\x99\xe9\x28\x9a\xff\xce\xb1\x63\xe7\x36\x69\x69\x85\x16\x89\xa7\xc4\xe7\x7e\xf9\xce\x89\xd3\xb6\x19\xdd\xb1\x8a\x22\xbc\x25\x8a\xe2\xd3\xe9\xd5\xea\xab\xef\x3f\xad\x37\xbf\xdf\x7d\x40\x85\x2e\x79\xf2\x6a\xd5\x3d\x10\x5a\x15\x94\x64\xe6\x05\x5e\x4b\xaa\x09\x4a\x0b\x22\x15\xd5\x31\x6e\xf4\x2e\x78\x8b\xc7\xac\x42\xeb\x3a\xa0\x7f\x35\x6c\x1f\xe3\xdf\x82\x5f\x6f\x83\xb5\x28\x6b\xa2\xd9\x96\x53\x8c\x52\x51\x69\x5a\x81\xde\x8f\x1f\x62\x9a\xe5\x74\xa2\x59\x91\x92\xc6\x78\xcf\xe8\xa1\x16\x52\x8f\x84\x0f\x2c\xd3\x45\x9c\xd1\x3d\x4b\x69\x60\x0f\x57\x88\x55\x4c\x33\xc2\x03\x95\x12\x4e\xe3\xeb\xf0\x0d\x98\xea\x6c\x69\xa6\x39\x4d\xda\x56\xd3\xb2\xe6\x44\x43\x7e\x96\x82\x51\x78\x3a\xad\xa2\x8e\xeb\x44\x39\xab\xfe\x44\x85\xa4\xbb\x18\x47\x3b\x4a\x33\x15\x11\xce\x43\xa2\x45\x19\x3e\x94\x1c\x23\x7d\xac\x21\x22\x52\xd7\x9c\xa5\x90\x82\xa8\x22\xc3\xfb\xc6\xf2\x24\xe5\xc0\xe2\x9a\xca\x0a\x9c\x80\xac\x31\x1c\xe3\x7b\xa6\x29\x84\x48\xd1\xed\xe6\xd3\xcf\xe8\x23\x18\x75\x39\xb6\x2d\xdb\xa1\xd0\xb0\xc3\xb5\xa8\x76\x2c\x0f\x3f\x12\x48\x48\x54\x50\xf8\x21\x18\x6b\x55\x15\x90\x7f\xda\x68\x64\xd8\xd8\x05\xd8\xb6\xcb\xca\x18\x45\xde\x01\xad\x32\x30\xe6\x0e\x43\xfa\xa6\x79\x54\xda\xfc\x5f\x3d\x12\xca\x3d\xf4\x93\x6e\x0a\xa6\xee\x9a\x2d\x67\xaa\xa0\xd2\x47\xa5\x52\xc9\x6a\xed\x2a\xa1\xe9\x83\x8e\x3e\x93\x3d\xe9\xa8\x38\xd9\x13\x89\xd4\x81\xe9\xb4\xd8\x88\xef\x1e\x62\x2d\x1b\xfa\x6e\x15\x75\xdc\xe4\x19\x06\x90\x92\x29\xd4\x3e\x3a\x84\xca\x44\xa0\x21\x82\x30\x15\x65\xb4\x6d\xb4\x86\x6a\x77\x0f\x15\x7e\x56\x38\x79\x89\xd9\x4e\x06\x21\xa5\x7f\x62\x79\xa1\x43\x51\x9b\xe6\xa9\xd7\x6d\xed\xd3\xbb\x41\xf3\x82\x2e\x95\x00\x5f\xa1\x4c\xfc\x22\xf4\x0f\x44\x15\x37\x68\x47\xb8\xa2\x8e\xb2\x16\xf5\xb1\xa7\x14\xc0\xbe\xcd\x32\x49\x95\x7a\x4f\xa4\x23\x9f\x2e\xdf\x75\x91\x4e\xe2\xf6\x4d\x32\xf4\x6e\xa8\xcc\xeb\x56\x64\x47\x97\x57\xc6\xf6\x28\xe5\x44\xa9\x18\x57\x64\xbf\x85\xfa\x76\x8f\x00\x86\x95\x34\x5c\xfb\xa3\xd2\x00\xc8\x34\xd0\xa2\x06\x28\x0a\x83\x3c\x60\xb0\xdc\xa2\xb4\xcf\x7f\x6c\xcd\x4c\x13\x81\x71\x97\x3d\x77\xc9\x5b\xe0\xc0\x32\xc8\x98\xf0\x6c\x1b\x5c\xad\xbb\x03\x9e\xa9\x69\x91\xe7\x66\xc6\x32\xa2\x89\x3b\x18\x97\x9c\x93\x5a\xf5\x64\x22\x73\xb3\x33\x42\xa7\xd3\xb3\xc7\xce\x4c\x6b\x6b\x52\x79\xf3\x4a\x06\xa2\xe2\x47\x9c\x6c\xac\x4d\x34\x24\x09\x75\x05\xb9\x27\x54\xcd\x78\x04\xe0\xc7\x42\xe7\x3f\x11\x5d\x39\xc0\x4e\x68\x64\x56\xa9\xad\x24\x55\xe6\x87\x3a\xc2\xc9\x0c\x86\x1b\xb3\x46\xcc\xa2\x22\xa3\x36\x45\xd0\xa7\xe1\x68\xc7\x57\x48\x37\xc1\x77\x24\xa7\x0a\xbd\x06\xa3\x8e\xb0\x21\xb9\x9a\x4f\xb7\x38\x18\xea\xe5\x58\x6c\x0d\xbb\x21\x17\x92\xd1\x05\xe1\x81\x37\x51\xb9\x95\x00\x39\xbe\xa4\x70\x2b\xd3\x82\xed\xe9\xa5\xdb\x1a\x8f\x60\xcb\x37\x1c\x2d\x76\xfe\x1f\xd2\x7a\x91\x73\x70\xdf\xf0\x91\x77\x3f\x35\xf0\x98\xa1\x6d\x69\x17\xf6\x26\x27\x16\xed\x8a\x4e\xa0\x9f\xae\x75\xa4\x93\x51\xa1\xf9\x4a\xe2\xc4\xa9\x28\xd3\xb9\x55\x04\x92\x33\x37\x7e\xee\xc7\x34\x80\x42\x4e\xd1\xc5\x1f\x57\xe8\xa2\x86\x7c\xd1\x4d\x3c\xce\xfe\x29\xef\x6d\x6b\x35\xc2\x7b\xde\xe4\xb0\xa7\x12\x7f\x1e\xc1\xe7\x39\x41\xac\xa2\x86\x4f\x7b\x80\x40\x04\x4d\x64\x7c\x5f\xfe\x1d\x76\x9e\x40\xe5\xf3\xfa\xe6\x5f\xa5\xd9\xe8\x4b\x4d\x7c\x69\x78\xe7\xe5\xf5\x8e\x33\x29\xea\x4c\x1c\xaa\xf9\x62\xf2\xc5\xff\x7a\xb6\xe7\x06\xf9\x91\xe7\xd5\xb6\xdf\xbc\xe6\xcb\x66\xf6\xc5\x36\x99\x8c\xf5\x2c\x5d\x6f\x25\x28\x69\xd5\xcc\x5c\xcf\xc0\x92\x76\x6e\x8e\x03\x60\x1e\x4d\xcb\x68\x5e\x10\x3f\x3b\x20\x7f\xd1\x4f\xd2\xfb\xe3\xda\xdb\xe9\x2d\x9e\x69\xaf\xe6\x20\x1a\xd5\x21\xf2\x5a\x11\xf8\x18\x2c\xb8\x81\x98\xd0\xa6\x4b\x74\x4b\xe0\xee\x87\xea\x86\x73\xdf\xce\xb6\xe5\xb4\x42\x7d\xa0\x06\xc1\x76\xbb\x9e\x15\xcc\x60\xf6\x3c\xa4\xa5\xf1\x9a\x63\x7b\x49\x73\x79\x2c\x27\x60\x7a\x1c\xb8\x5f\x02\x40\xd6\xdb\x97\x84\x8e\x26\xf9\x80\x9a\x85\x2c\x9e\xc4\x0b\xc8\x5b\x0b\x2f\x43\x09\x28\x18\x80\x58\xbd\x01\x1b\xf6\xf8\xbf\x81\xc5\xf9\xa2\x9c\x4a\x9c\x7d\xa2\xc7\xec\x11\xd3\xbd\x9e\xdd\xf5\xfa\xdb\x99\xf9\x36\x06\x65\x16\x5c\xbf\xf1\x6f\x62\xb7\x83\x5f\xad\xe0\xda\x9e\x79\x1e\xbc\xf5\x2f\x8e\xf1\x6d\xdf\xf0\xf1\xa5\xdf\xfd\x3c\x75\xb7\xfe\x59\x10\x63\xb9\x9d\x10\xda\xff\x1c\xcc\x79\xa4\x22\xfc\x08\x95\x57\x9e\x0d\x38\xb4\x37\x55\xb8\xbb\xda\x3f\x43\x9f\xe6\xdf\x01\x00\x00\xff\xff\x5b\x40\x77\x1c\x4b\x0e\x00\x00") - -func templatesTemplatesBaseBaseHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesBaseBaseHtml, - "templates/templates/base/base.html", - ) -} - -func templatesTemplatesBaseBaseHtml() (*asset, error) { - bytes, err := templatesTemplatesBaseBaseHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/base/base.html", size: 3659, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesBaseFooterHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\x92\xdd\x8e\xa3\x30\x0c\x85\xef\xf7\x29\xac\x5c\x56\x82\x94\xbd\x5a\xad\x28\xda\x87\xd8\x17\x08\x60\x20\x28\x24\xd9\xd8\xdd\xfe\xa0\xbe\xfb\x18\x5a\xa6\x33\x53\xcd\x0d\x3a\x8e\xc3\xe7\x73\xc0\xf3\xdc\x62\x67\x3d\x82\xea\x42\x60\x4c\xea\x76\xfb\x01\x30\xcf\x7a\x07\x7f\x07\x4b\x40\x43\x38\xba\x16\x6a\x04\x8a\xce\x32\x04\x0f\x1e\x4f\x90\xd0\xa1\x21\x24\xd8\xe9\xf5\x85\xb2\xb5\xff\xa1\x71\x86\xe8\xa0\x9a\xe0\xd9\x08\x32\x41\x13\x5c\x36\xb5\x59\xb1\xdf\x54\xe8\x3a\x42\xce\x8a\xb5\x76\x7d\xf6\x6b\x13\x8f\xc6\x4f\x55\x09\xec\x33\x8e\xf1\xcc\x59\x83\x7e\x31\x77\xef\x4a\x3f\x6e\x4a\xb4\x81\x21\x61\x77\x50\x03\x73\xfc\xad\x75\x6f\x79\x38\xd6\x79\x13\x26\x6d\xfa\xe0\xaf\xc6\xe1\x35\x05\x1d\x83\x0b\xaa\x5a\x9e\xa5\x36\x15\x48\xb4\xc9\xb4\x08\x27\xb9\xfd\x44\x51\x34\x7e\x9b\xdb\xbb\x4b\x1c\xac\x84\x81\x77\x95\x0d\x68\x12\xab\xaa\xd4\xcb\xc5\x0a\xea\xcb\xb7\x2e\x58\xc0\xe2\xf8\xab\x0d\x55\xfd\xf9\x50\x2d\x4e\xb6\x44\xfa\x11\xa9\xd4\x92\x7d\x91\x4f\x41\x4d\xb2\x91\x81\x52\x73\xc7\x93\xf0\xcd\x68\xce\x79\x1f\x42\x2f\xff\x21\x5a\xba\xcf\x91\x33\xed\x6c\x4d\x7a\xfc\x77\xc4\x74\xd1\x45\x5e\x14\xf9\xfe\x51\xe5\x93\xf5\xf9\x48\xab\xfb\x15\xf8\xc2\x96\x6f\x87\x5c\xcb\x1a\x10\x27\x13\x57\x64\x6b\x89\xf5\x48\xfa\x79\xfa\x4a\x99\x67\xf4\xad\x6c\xc1\x5b\x00\x00\x00\xff\xff\xa9\xef\x18\x09\x4b\x02\x00\x00") - -func templatesTemplatesBaseFooterHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesBaseFooterHtml, - "templates/templates/base/footer.html", - ) -} - -func templatesTemplatesBaseFooterHtml() (*asset, error) { - bytes, err := templatesTemplatesBaseFooterHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/base/footer.html", size: 587, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesBaseHeaderHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\xcf\x31\x0e\x02\x21\x10\x85\xe1\xde\x53\x90\xe9\x05\x93\x6d\x5d\xef\x82\xcc\xdb\x40\x84\xc1\x30\xd3\x18\xb2\x77\x77\x2b\xf5\x02\xb6\x7f\x5e\xf2\xe5\xcd\xc9\xd8\x8a\xc0\x51\x46\x64\x0c\xda\xf7\x93\x73\xd7\x5a\xe4\xe1\x06\xea\x4a\x6a\xaf\x0a\xcd\x80\x91\xcb\x03\xdb\x4a\x21\x08\x8c\x25\xfa\x7b\xef\xa6\x36\xe2\x33\xb1\xf8\xd4\x5b\xf8\x84\xb0\xf8\x8b\x5f\x42\x52\xfd\x36\xdf\xca\xb1\x52\xa5\xdb\x9f\x80\xb3\x65\x34\xfc\x30\x73\x42\xf8\xf8\xf3\x0e\x00\x00\xff\xff\x6a\x24\xeb\x71\xe4\x00\x00\x00") - -func templatesTemplatesBaseHeaderHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesBaseHeaderHtml, - "templates/templates/base/header.html", - ) -} - -func templatesTemplatesBaseHeaderHtml() (*asset, error) { - bytes, err := templatesTemplatesBaseHeaderHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/base/header.html", size: 228, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesCategoryHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x54\x8e\x41\xab\xc3\x20\x10\x84\xef\xfe\x8a\x45\x72\x7c\x28\xef\xfa\xd8\x08\x8f\xfc\x84\xf4\x5e\x24\xd9\x18\x41\x0c\xd8\xcd\xa1\x58\xff\x7b\x4d\xd2\xd0\xf6\xa4\x33\xcc\x7e\x33\x39\x8f\x34\xf9\x48\x20\xd9\x73\x20\x59\x8a\xc8\x59\x75\x96\xc9\x2d\xe9\x5e\x0a\x3c\xa0\xea\xde\x33\xa9\x6e\x89\x93\x77\xea\xb2\xe5\xf6\x18\xc5\xb1\xbe\xe2\x8d\x18\x96\xc8\x14\x79\x83\xe0\xfc\x6b\xbe\x40\xa8\xab\x23\x70\x0d\x46\x40\x45\x26\x1b\x1d\x41\x73\xfd\x81\xc6\x26\xf6\x43\x20\xf8\x6b\x41\xfd\x1f\xff\x5b\x25\x00\x60\xf0\x06\x2d\xcc\x89\xa6\x56\xe6\x7c\x06\x55\x1f\x56\x57\x8a\x34\x1f\xd6\x6b\x14\x6a\x6b\x50\xd7\xb3\xbd\xe3\xd8\x87\x7a\xeb\x3c\xd5\x33\x00\x00\xff\xff\x03\x42\x6c\xbd\xf0\x00\x00\x00") - -func templatesTemplatesCategoryHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesCategoryHtml, - "templates/templates/category.html", - ) -} - -func templatesTemplatesCategoryHtml() (*asset, error) { - bytes, err := templatesTemplatesCategoryHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/category.html", size: 240, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x55\x4f\x6f\xa3\x3e\x10\xbd\xf3\x29\x5c\x7e\xd1\xef\x50\x6d\x41\xbd\xee\x12\xa4\xaa\x7b\xe8\xa1\x9b\xad\xd4\xdc\x2b\x07\x06\xb0\x64\x4c\x62\x9b\xa8\x59\x94\xef\xbe\xe3\x3f\x04\x9c\xa5\xda\x6a\x23\x25\x86\x19\xcf\xbc\x37\x33\xcf\xce\x30\x94\x50\x31\x01\x24\xd6\x4c\x73\x88\xcf\xe7\x68\x18\x92\x57\xa6\x21\x79\xec\x44\xc5\xea\x64\x6b\xec\xd6\x0c\xa2\xc4\x35\x9a\x42\x8a\x4e\x68\x10\xda\x05\xb1\x8a\x24\x0f\x52\xb3\x82\x83\x72\xdb\x24\x15\x35\x90\xd5\xdb\x17\xb2\xa2\xce\x41\xbe\xae\x83\x4d\x99\xb7\xe7\x51\xd6\xdc\xe7\x19\x25\x8d\x84\x6a\x1d\x0f\xc3\x18\x90\xbc\xf2\xbe\x3e\x9f\xe3\x7c\x66\xf2\x84\xb2\x94\xe6\x59\x8a\x61\x51\x94\xed\x73\x47\xa0\x93\x64\x15\x90\x7f\xe8\x75\x63\x8c\x63\xac\x7b\x37\xc8\x6a\x4f\x05\x29\x38\x55\x6a\x1d\x73\xba\x03\x4e\xec\xef\x1d\xd6\x46\x7b\xae\xe3\x7c\x77\x22\x36\xe7\x1f\xb1\x33\x2a\x93\x09\xb8\x02\xeb\x5a\x80\xb7\x7e\xd3\xbb\x2c\x35\xa8\xf9\xbc\x95\x73\x80\xef\x54\xc3\xa7\xa8\x19\x98\xa7\xbe\xa5\x82\xfd\x02\x13\xa4\x59\x0b\xd7\x69\xfe\x82\xf5\x88\x9b\xea\x4e\x9e\xec\x10\x96\xc0\x54\x5f\x14\xa0\x54\xec\x47\x92\x16\x3e\x20\x9d\x95\x3f\x25\x49\x1a\xdd\xf2\x60\x4a\x93\xcf\x0c\xea\x23\x1a\x5b\x5a\x2b\xab\x9e\x99\x56\x34\xad\x8d\x4e\xae\xf7\x2c\xd3\x64\xa2\xea\x2e\x1c\x31\xd2\xd0\xc3\x65\xce\xc8\xbe\x06\x24\xc6\x35\x4b\x51\x38\xd1\x8c\xf4\xd3\xf6\xc7\xf3\xac\x47\x4e\xde\x66\xe3\x7e\xc4\xd6\xf0\xae\xef\x24\xab\x1b\x1c\xc3\xc4\x68\xa7\x05\xc1\xef\x65\x42\x1f\xe9\xf8\xbf\x92\xa9\x43\xaf\xde\x34\xfa\x69\x19\xe7\xcf\x40\x8f\x40\x30\x4d\xd7\xb6\x88\x74\xe3\x34\x8d\xa4\xf0\x61\x3a\x19\x32\x68\x9f\x53\x9a\x3d\x30\x9b\x4e\x37\x4c\xd4\x44\x77\x44\x01\x90\x06\x24\xdc\xb8\x23\x71\x1d\x84\x3d\xaf\x35\x71\xda\xdc\xf4\xed\x0e\xe4\xcf\xea\x85\xd6\xa0\xc8\xbd\xc9\x55\xb2\x63\x50\x60\x81\x64\x40\x62\x85\x3d\x1f\xed\x7b\x5a\x33\x41\x35\xeb\x44\x8c\x3d\x23\xf8\xc9\x38\x1b\x9d\xf6\xdd\xa2\xc0\x01\x4f\xa0\xc9\xec\x50\x6c\x7a\xe3\xc4\xc2\xe9\x8e\x43\xe9\x77\x3a\x62\xe6\x19\xb3\xd9\x64\xb3\xb3\x9f\xbc\x48\x38\xb2\xae\x57\xa6\x69\x41\x3a\x73\x13\xfc\xcf\xe9\xa1\xef\xbe\xd9\x81\xda\xc8\x94\x33\xcf\x28\x90\x11\x12\x1e\xef\x1b\x49\x4f\xbe\x5c\x0f\x6a\xa8\x5f\xe8\xda\x8d\x21\x8a\x2f\x8b\x16\x9a\x1d\x21\xf6\x74\xaf\x88\xa6\x4c\x94\xf0\x6e\xb3\xe0\x5d\xe8\xb2\xdc\xdb\x2b\xc0\x3c\x5e\xce\xbc\xd7\xa1\x8d\x35\x0c\xbd\xd7\x53\x0f\x6a\x98\xb5\x06\xd7\xf4\x96\xb8\x6a\x6e\x53\x33\xc3\x4f\x77\x7c\xb5\x30\xe5\x7f\x19\xc2\x06\x85\xb0\x3c\x00\xb9\x38\x80\x2c\xed\x39\x8a\x17\xa5\x74\x51\x9e\xab\x02\x39\xda\x12\x02\xa3\xff\xeb\x70\x9e\xdf\x01\x00\x00\xff\xff\x15\x8b\x41\x60\x85\x06\x00\x00") - -func templatesTemplatesIndexHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesIndexHtml, - "templates/templates/index.html", - ) -} - -func templatesTemplatesIndexHtml() (*asset, error) { - bytes, err := templatesTemplatesIndexHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/index.html", size: 1669, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesPageHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xaa\xae\x4e\x49\x4d\xcb\xcc\x4b\x55\x50\x2a\xc9\x2c\xc9\x49\x55\xaa\xad\xe5\xaa\xae\xd6\x0b\x48\x4c\x4f\xd5\x0b\x01\x09\xd4\xd6\x2a\xd4\x28\x00\x45\x82\x33\x4b\x52\xf5\x9c\xf3\xf3\xd2\x32\xd3\x61\x12\x40\x85\xa9\x79\x29\x40\x9a\x0b\x61\x48\x72\x7e\x5e\x49\x6a\x5e\x09\xc8\x18\x9b\x0c\x43\x3b\x34\xa3\x6c\xf4\x81\x62\x70\xf3\x3d\x42\x7c\x7d\x14\x20\x4c\x67\x88\x36\x24\x33\x01\x01\x00\x00\xff\xff\x27\x7a\x43\x12\x98\x00\x00\x00") - -func templatesTemplatesPageHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesPageHtml, - "templates/templates/page.html", - ) -} - -func templatesTemplatesPageHtml() (*asset, error) { - bytes, err := templatesTemplatesPageHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/page.html", size: 152, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templatesTemplatesTagHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x8e\xc1\x0a\x83\x30\x10\x44\xef\xf9\x8a\x25\x78\x2c\x09\xbd\x96\x35\x50\xfa\x09\x7a\x2f\x41\x57\x0d\x84\x08\x36\x9e\xb6\xf9\xf7\xae\x5a\x69\x4f\xd9\x09\xf3\x66\x86\xb9\xa7\x21\x24\x02\x9d\x43\x8e\xa4\x4b\x51\xcc\xa6\xf5\x63\x29\xf0\x06\x39\x9b\x90\xc9\x3c\xe6\x34\x84\xd1\xb4\x9b\x65\x77\x50\xea\xe5\x55\x3f\xba\x9b\x53\xa6\x94\x37\x1e\xa7\xab\x3b\x33\xd0\x8a\x50\xb8\x46\xa7\x40\xd2\x16\x9f\x46\x82\xea\x79\x81\xca\x2f\x39\x74\x91\xe0\x56\x83\xb9\x1f\xf7\x4b\x60\x00\x8c\xc1\xa1\x87\x69\xa1\xa1\xd6\xcc\xa7\xd1\x34\x71\x95\x40\xed\xfe\xbe\xbe\x7b\xd0\x7a\x87\x56\xb0\xbd\xe3\x98\x86\x76\xeb\x3c\xd5\x27\x00\x00\xff\xff\xd0\xa4\x2a\x22\xe6\x00\x00\x00") - -func templatesTemplatesTagHtmlBytes() ([]byte, error) { - return bindataRead( - _templatesTemplatesTagHtml, - "templates/templates/tag.html", - ) -} - -func templatesTemplatesTagHtml() (*asset, error) { - bytes, err := templatesTemplatesTagHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/templates/tag.html", size: 230, mode: os.FileMode(420), modTime: time.Unix(1435105280, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if (err != nil) { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "templates/archives.html": templatesArchivesHtml, - "templates/article/article.html": templatesArticleArticleHtml, - "templates/article/disqus.html": templatesArticleDisqusHtml, - "templates/article/sharethis.html": templatesArticleSharethisHtml, - "templates/atom.xml": templatesAtomXml, - "templates/base/analytics.html": templatesBaseAnalyticsHtml, - "templates/base/base.html": templatesBaseBaseHtml, - "templates/base/footer.html": templatesBaseFooterHtml, - "templates/base/header.html": templatesBaseHeaderHtml, - "templates/category.html": templatesCategoryHtml, - "templates/index.html": templatesIndexHtml, - "templates/page.html": templatesPageHtml, - "templates/tag.html": templatesTagHtml, - "templates/templates/archives.html": templatesTemplatesArchivesHtml, - "templates/templates/article/article.html": templatesTemplatesArticleArticleHtml, - "templates/templates/article/disqus.html": templatesTemplatesArticleDisqusHtml, - "templates/templates/article/sharethis.html": templatesTemplatesArticleSharethisHtml, - "templates/templates/atom.xml": templatesTemplatesAtomXml, - "templates/templates/base/analytics.html": templatesTemplatesBaseAnalyticsHtml, - "templates/templates/base/base.html": templatesTemplatesBaseBaseHtml, - "templates/templates/base/footer.html": templatesTemplatesBaseFooterHtml, - "templates/templates/base/header.html": templatesTemplatesBaseHeaderHtml, - "templates/templates/category.html": templatesTemplatesCategoryHtml, - "templates/templates/index.html": templatesTemplatesIndexHtml, - "templates/templates/page.html": templatesTemplatesPageHtml, - "templates/templates/tag.html": templatesTemplatesTagHtml, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} -var _bintree = &bintree{nil, map[string]*bintree{ - "templates": &bintree{nil, map[string]*bintree{ - "archives.html": &bintree{templatesArchivesHtml, map[string]*bintree{ - }}, - "article": &bintree{nil, map[string]*bintree{ - "article.html": &bintree{templatesArticleArticleHtml, map[string]*bintree{ - }}, - "disqus.html": &bintree{templatesArticleDisqusHtml, map[string]*bintree{ - }}, - "sharethis.html": &bintree{templatesArticleSharethisHtml, map[string]*bintree{ - }}, - }}, - "atom.xml": &bintree{templatesAtomXml, map[string]*bintree{ - }}, - "base": &bintree{nil, map[string]*bintree{ - "analytics.html": &bintree{templatesBaseAnalyticsHtml, map[string]*bintree{ - }}, - "base.html": &bintree{templatesBaseBaseHtml, map[string]*bintree{ - }}, - "footer.html": &bintree{templatesBaseFooterHtml, map[string]*bintree{ - }}, - "header.html": &bintree{templatesBaseHeaderHtml, map[string]*bintree{ - }}, - }}, - "category.html": &bintree{templatesCategoryHtml, map[string]*bintree{ - }}, - "index.html": &bintree{templatesIndexHtml, map[string]*bintree{ - }}, - "page.html": &bintree{templatesPageHtml, map[string]*bintree{ - }}, - "tag.html": &bintree{templatesTagHtml, map[string]*bintree{ - }}, - "templates": &bintree{nil, map[string]*bintree{ - "archives.html": &bintree{templatesTemplatesArchivesHtml, map[string]*bintree{ - }}, - "article": &bintree{nil, map[string]*bintree{ - "article.html": &bintree{templatesTemplatesArticleArticleHtml, map[string]*bintree{ - }}, - "disqus.html": &bintree{templatesTemplatesArticleDisqusHtml, map[string]*bintree{ - }}, - "sharethis.html": &bintree{templatesTemplatesArticleSharethisHtml, map[string]*bintree{ - }}, - }}, - "atom.xml": &bintree{templatesTemplatesAtomXml, map[string]*bintree{ - }}, - "base": &bintree{nil, map[string]*bintree{ - "analytics.html": &bintree{templatesTemplatesBaseAnalyticsHtml, map[string]*bintree{ - }}, - "base.html": &bintree{templatesTemplatesBaseBaseHtml, map[string]*bintree{ - }}, - "footer.html": &bintree{templatesTemplatesBaseFooterHtml, map[string]*bintree{ - }}, - "header.html": &bintree{templatesTemplatesBaseHeaderHtml, map[string]*bintree{ - }}, - }}, - "category.html": &bintree{templatesTemplatesCategoryHtml, map[string]*bintree{ - }}, - "index.html": &bintree{templatesTemplatesIndexHtml, map[string]*bintree{ - }}, - "page.html": &bintree{templatesTemplatesPageHtml, map[string]*bintree{ - }}, - "tag.html": &bintree{templatesTemplatesTagHtml, map[string]*bintree{ - }}, - }}, - }}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, path.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, path.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} - diff --git a/src/templates/category.html b/src/templates/category.html deleted file mode 100644 index 85d30c1..0000000 --- a/src/templates/category.html +++ /dev/null @@ -1,12 +0,0 @@ -{{define "title"}} -{{.Category}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Category}}

- -{{end}} diff --git a/src/templates/index.html b/src/templates/index.html deleted file mode 100644 index 1007d86..0000000 --- a/src/templates/index.html +++ /dev/null @@ -1,72 +0,0 @@ -{{define "title"}} -{{.Site.Config.Title}} -{{end}} - -{{define "content"}} -{{if .Articles}} - -{{range $_, $article := .Articles}} -
-

{{$article.Title}}

- -

-{{if or $.Site.Config.Author $article.Author}} -by {{if $article.Author}}{{$article.Author}}{{else}}{{$.Site.Config.Author}}{{end}} -{{end}} - -{{if $article.Date}} -{{$.HumanizeDatetime $article.Date}} -{{end}} - -{{if $article.Category}} -{{$article.Category}} -{{end}} - -{{if $article.Tags}} -{{range $_, $tag := $article.Tags}} -{{$tag}} -{{end}} -{{end}} -

- -{{$article.HTML $article.Content}} -

Leave a comment!

-
-
-{{end}} - -{{else}} -

Nothing to see here!

-
-{{end}} - -{{if gt .Site.NumberOfPages 1}} -
    - -
  • - « -
  • - - {{range $_, $page := .ArrayOfPages}} -
  • - - {{$page}} - -
  • - {{end}} {{/* range */}} - -
  • - » -
  • - -
-{{end}} {{/* if */}} -{{end}} {{/* content */}} diff --git a/src/templates/page.html b/src/templates/page.html deleted file mode 100644 index 3ca144e..0000000 --- a/src/templates/page.html +++ /dev/null @@ -1,8 +0,0 @@ -{{define "title"}} -{{.Page.Title}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Page.Title}}

-{{.Page.HTML .Page.Content}} -{{end}} diff --git a/src/templates/tag.html b/src/templates/tag.html deleted file mode 100644 index fe6fe04..0000000 --- a/src/templates/tag.html +++ /dev/null @@ -1,12 +0,0 @@ -{{define "title"}} -{{.Tag}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Tag}}

- -{{end}} diff --git a/src/templates/templates/archives.html b/src/templates/templates/archives.html deleted file mode 100644 index 6a65f59..0000000 --- a/src/templates/templates/archives.html +++ /dev/null @@ -1,13 +0,0 @@ -{{define "title"}} -Archives | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

Archives

-
- {{range $_, $article := .Site.Articles}} -
{{$.HumanizeDatetime $article.Date}}
-
{{$article.Title}}
- {{end}} -
-{{end}} diff --git a/src/templates/templates/article/article.html b/src/templates/templates/article/article.html deleted file mode 100644 index 9048385..0000000 --- a/src/templates/templates/article/article.html +++ /dev/null @@ -1,37 +0,0 @@ -{{define "title"}} -{{.Article.Title}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Article.Title}}

- -

-{{if .Site.Config.Author }} -by {{.Site.Config.Author}} -{{end}} - -{{if .Article.Date}} -{{.HumanizeDatetime .Article.Date}} -{{end}} - -{{if .Article.Category}} -{{.Article.Category}} -{{end}} - -{{if .Article.Tags}} -{{range $_, $tag := .Article.Tags}} -{{$tag}} -{{end}} -{{end}} -

- -{{.Article.HTML .Article.Content}} - -{{if .Site.Config.ShareThisPublisher}} -{{template "sharethis" .}} -{{end}} - -{{if .Site.Config.DisqusSitename}} -{{template "disqus" .}} -{{end}} -{{end}} diff --git a/src/templates/templates/article/disqus.html b/src/templates/templates/article/disqus.html deleted file mode 100644 index e160848..0000000 --- a/src/templates/templates/article/disqus.html +++ /dev/null @@ -1,18 +0,0 @@ -{{define "disqus"}} -

Comments

-
- - -comments powered by Disqus -{{end}} diff --git a/src/templates/templates/base/analytics.html b/src/templates/templates/base/analytics.html deleted file mode 100644 index 06c2895..0000000 --- a/src/templates/templates/base/analytics.html +++ /dev/null @@ -1,15 +0,0 @@ -{{define "analytics"}} - {{if .Site.Config.GoogleAnalyticsID}} - - {{end}} -{{end}} diff --git a/src/templates/templates/base/base.html b/src/templates/templates/base/base.html deleted file mode 100644 index bb85da1..0000000 --- a/src/templates/templates/base/base.html +++ /dev/null @@ -1,93 +0,0 @@ -{{define "base"}} - - - - - - - - {{template "title" .}} - - - {{if .Site.Config.Favicon}} - - {{end}} - - {{template "header" .}} - - {{if .Site.Config.ShareThisPublisher}} - - - - {{end}} - - - - - -
- {{template "content" .}} -
- {{template "footer" .}} - {{template "analytics" .}} - - -{{end}} diff --git a/src/templates/templates/base/footer.html b/src/templates/templates/base/footer.html deleted file mode 100644 index 73b5f52..0000000 --- a/src/templates/templates/base/footer.html +++ /dev/null @@ -1,14 +0,0 @@ -{{define "footer"}} - {{/* This should be split on new releases */}} -
-
-

- polo is made with - by - @agonzalezro -

-
-
- - -{{end}} diff --git a/src/templates/templates/base/header.html b/src/templates/templates/base/header.html deleted file mode 100644 index c2f5ac5..0000000 --- a/src/templates/templates/base/header.html +++ /dev/null @@ -1,4 +0,0 @@ -{{define "header"}} - - -{{end}} diff --git a/src/templates/templates/bindata.go b/src/templates/templates/bindata.go deleted file mode 100644 index 6be158e..0000000 --- a/src/templates/templates/bindata.go +++ /dev/null @@ -1,499 +0,0 @@ -package templates - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "strings" - "os" - "time" - "io/ioutil" - "path" - "path/filepath" -) - -func bindata_read(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindata_file_info struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindata_file_info) Name() string { - return fi.name -} -func (fi bindata_file_info) Size() int64 { - return fi.size -} -func (fi bindata_file_info) Mode() os.FileMode { - return fi.mode -} -func (fi bindata_file_info) ModTime() time.Time { - return fi.modTime -} -func (fi bindata_file_info) IsDir() bool { - return false -} -func (fi bindata_file_info) Sys() interface{} { - return nil -} - -var _templates_archives_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x8f\xb1\x4e\xc4\x30\x0c\x86\xf7\x3e\x85\x15\x75\x84\x54\xac\x28\x8d\x74\x82\x81\xfd\xd8\x51\xd4\xb8\xad\xa5\x5c\x2a\xa5\x3e\x86\x33\x79\x77\x5c\xca\x15\xa6\xc8\xbf\xbe\xcf\xce\x2f\x12\x71\xa4\x8c\x60\x98\x38\xa1\xa9\xb5\x39\x95\x61\xa6\x4f\x5c\xe1\x0b\x44\xec\x99\x18\xed\xcb\x92\x47\x9a\xec\xfb\x86\x28\x21\x82\x39\xea\xdb\xfc\xd9\xc3\x92\x19\x33\x6f\xbe\x9b\x9f\xfc\x7d\x87\xeb\x74\x68\x5c\x4c\x30\xa4\xb0\xae\xbd\x89\xe9\x71\x5e\x0a\xdd\x14\x0f\xc9\xf8\x06\xf4\x46\x09\x79\x42\x68\x3f\x1e\xa0\x0d\x85\x69\x48\x08\xcf\x3d\xec\x97\x4f\x7b\xb0\xea\x5e\x00\x17\xd9\x8b\xb4\xf6\xed\x7a\x09\x99\x6e\xf8\x1a\x18\x99\x2e\x78\x78\x76\x4b\x6a\x75\x9d\x82\x3f\x7c\xf4\x2e\xc0\x5c\x70\xec\x8d\x8a\x77\xea\x9c\xae\x53\xad\xc6\xff\x8b\x7e\xab\xb9\x2e\x78\xb5\xe3\xfe\xb1\xbd\xa5\xce\xc9\x1f\x9d\xbf\x03\x00\x00\xff\xff\x3f\x64\x0b\x14\x31\x01\x00\x00") - -func templates_archives_html_bytes() ([]byte, error) { - return bindata_read( - _templates_archives_html, - "templates/archives.html", - ) -} - -func templates_archives_html() (*asset, error) { - bytes, err := templates_archives_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/archives.html", size: 305, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_article_article_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x92\x41\x6f\xa3\x30\x10\x85\xef\xfc\x0a\xcb\xca\x71\x17\xb4\xd7\x15\x41\x8a\x92\x43\x0e\xbb\x52\xa5\x70\xaf\x26\x64\xc0\x96\x8c\x49\xed\xe1\x90\x52\xfe\x7b\xc7\xa4\x34\x40\x52\xb5\x97\x58\x19\xcf\xfb\xde\xc3\x33\x5d\x77\xc2\x52\x5b\x14\x92\x34\x19\x94\x7d\x1f\x75\x5d\xbc\x71\xa4\x0b\x83\x71\x1e\x6a\x7d\x2f\xde\x04\x17\x0f\x9a\x30\xde\x36\xb6\xd4\xd5\x78\xc1\xbd\x68\x4f\x7c\x46\x37\x4e\xd1\x58\x42\x4b\x81\x94\xaa\x3f\xd9\x3d\x2d\x4d\xb8\x1c\x45\xe9\x39\x63\x95\x2e\xc5\x0c\xbc\x69\x49\x35\x4e\x04\xb1\x3f\x83\x15\x85\x01\xef\xd7\xd2\xc0\x11\x8d\x18\x7e\x7f\xb3\x11\xb4\x86\x64\x76\xbc\x2c\x63\x5d\xd5\xc1\x22\x88\xb3\x69\xbc\x60\x34\x06\xd9\x01\xe1\x8f\x1c\x18\xbf\x6f\x6b\xb0\xfa\x15\x83\x86\x74\x8d\x4b\xca\x37\x56\x5b\x6e\xaa\x1a\x77\x09\x76\xf0\xc8\xcb\xb7\x45\x81\xde\x4b\xa1\x1c\x96\x6b\x99\x14\x1f\x82\x64\xf2\x70\x37\x48\xac\xa8\x36\x32\x7b\x78\x97\x26\xf0\x65\x8c\x1c\x2a\x3f\x8c\xcb\x81\xad\x50\xac\x9e\x7f\x89\x15\x41\x25\xfe\xae\xef\x7a\x1e\xc7\xd4\xb6\x6c\x3e\x33\xb2\x92\xe3\x05\xc0\x24\xd1\xf5\xef\x2c\xc4\x78\xa6\x09\xcf\x7a\xba\x57\xfb\xfc\xff\xbf\xc9\x1b\x5d\x37\xe6\x96\x7a\x3a\xd2\x83\x02\x87\xb9\xd2\xfe\xa9\x3d\x1a\xed\x15\xba\x01\x4c\x58\x9f\x0d\x7f\xba\x90\x3e\x34\x10\x37\x48\x11\xcf\x37\x72\x89\xda\x69\xff\xd2\xfa\x50\xb1\x50\xe3\x02\x73\x1a\x2e\xe7\x8c\xf1\x7c\x0f\x00\x00\xff\xff\x48\x15\x1f\x37\x25\x03\x00\x00") - -func templates_article_article_html_bytes() ([]byte, error) { - return bindata_read( - _templates_article_article_html, - "templates/article/article.html", - ) -} - -func templates_article_article_html() (*asset, error) { - bytes, err := templates_article_article_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/article/article.html", size: 805, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_article_disqus_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x53\x4f\x6f\x9c\x3e\x10\xbd\xef\xa7\x18\x71\x31\x28\x0a\xfe\xe9\x77\xcc\xb2\x54\xed\xa6\x87\xf6\xd0\x54\xda\xdc\xaa\x2a\x32\x78\x00\x67\x8d\xcd\xda\x66\xb7\x84\xec\x77\xef\xb0\x90\xa8\x7f\xd5\x13\x78\xe6\xcd\xcc\x9b\xe7\xe7\x71\x94\x58\x29\x83\x10\x49\xe5\x0f\xbd\x8f\xce\xe7\x55\xd6\xfc\x9f\x6f\x6d\xdb\xa2\x09\x3e\xe3\x74\x58\x65\x52\x1d\x41\xc9\xcd\x02\x7a\x08\x8d\x43\x21\xa3\x3c\xe3\x94\xa0\xb4\x2f\x9d\xea\x02\x84\xa1\xc3\x4d\x14\xf0\x5b\xe0\x8f\xe2\x28\xe6\x68\x94\xaf\x00\x8e\xc2\xc1\x52\xeb\x1b\xeb\x82\x11\x2d\xc2\x06\xd8\x38\xa6\x3b\x15\x30\xdd\x5a\x53\xa9\x3a\xbd\xbd\x40\xa6\xc8\x04\x38\x9f\xd9\x9a\x6a\x39\x87\xfb\xbb\xdb\x3b\x88\x45\x6d\xcd\x93\xd0\xf8\xe4\x6c\x72\x03\xc4\xb0\x13\x41\x15\x4a\xab\x30\xc0\x49\x85\x06\xda\x01\xac\x96\x50\x68\x5b\x83\x70\x41\x95\x1a\xfd\xdc\xe0\x03\x48\x6b\x58\x80\xbd\xb1\x27\x50\x15\xa8\x40\x15\x5a\xc3\xc9\xba\x3d\x54\xd6\x81\x0d\x0d\x3a\xe8\x3d\x3a\xff\x33\x5d\x25\x49\x06\x55\x29\xca\xce\x7c\xdf\xce\x8d\xd3\x9d\xee\xeb\x0b\x43\xc2\xc7\x55\x6f\xca\xa0\xac\x89\x13\x18\xe9\xbc\x74\xf0\x07\xaa\x91\xb6\xec\x27\x29\xd3\x92\x34\x0b\xf8\x5e\xe3\x74\x8a\xd9\xac\x0e\x4b\xd6\x13\x2e\x9d\xa4\x9b\x06\xfc\x22\x1e\x9b\xb3\xc2\x0f\xa6\xa4\x74\x70\x3d\xae\x2f\xfd\xa7\xa8\x77\x53\x8c\x71\xce\xe0\xea\x77\x75\xaf\x80\xa5\x73\x30\x2d\x6d\xcb\xb1\x2d\x50\xa6\x8f\x9e\xcd\xf5\xf1\x2b\xad\x1a\xc3\xc2\xc9\xbf\x1b\xee\x45\xfd\x89\x8a\x63\xd6\xd0\xfd\xb2\xe4\xcb\x7f\x5f\xe1\xf9\x19\xfe\x81\x2d\xac\x1c\x2e\xd8\x24\x15\x5d\x87\x46\x6e\x1b\xa5\x65\x4c\x14\x93\x69\xd8\x39\x89\xe9\x9b\xf1\x79\x23\x72\x8b\xb1\xcb\xef\x67\x8d\xc2\x23\xd0\x65\x17\x1a\xe1\x23\x6d\xbd\x5b\x8c\x64\xe1\xa8\xf0\x04\x74\x29\x90\x09\x20\xb7\x55\x9b\xa8\x09\xa1\xbb\xe1\xfc\x87\x9d\xde\x50\xfc\xe1\xa5\x5b\x94\x97\x8b\x67\xa1\xb3\x27\x74\x48\x46\x18\x60\x76\x54\x9a\x71\x41\x66\x7d\x1d\xbc\xfa\x7b\xd3\x08\x4a\x2d\xbc\x27\xab\xfb\xc3\x75\xe1\xb4\x32\xfb\x3f\x77\xce\x7c\x27\xcc\x0b\x98\x1c\x67\xaf\x97\x17\x94\xcf\x33\x69\x61\x02\xe4\xd3\xe4\xd5\x38\x92\x2a\xf4\xb2\xbe\x07\x00\x00\xff\xff\x43\x45\x7a\xc4\x6e\x03\x00\x00") - -func templates_article_disqus_html_bytes() ([]byte, error) { - return bindata_read( - _templates_article_disqus_html, - "templates/article/disqus.html", - ) -} - -func templates_article_disqus_html() (*asset, error) { - bytes, err := templates_article_disqus_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/article/disqus.html", size: 878, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_article_sharethis_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\xd1\xb1\x0e\x82\x30\x10\xc6\xf1\x9d\xa7\x68\x58\x3a\x38\xf8\x02\xc0\xa6\xc6\xc4\x49\xd9\x49\xa1\x07\x5c\xa8\x2d\x69\xcf\xa0\x69\x78\x77\x81\x18\x1d\x6c\xe7\x7f\x7f\x5f\xd2\x9c\xf7\x12\x5a\xd4\xc0\x52\xd7\x0b\x0b\xd4\xa3\x4b\xe7\x39\xc9\x6a\x5b\x24\x99\x1b\x85\x66\x8d\x12\xce\xe5\xdc\x51\xf5\x7d\x51\x29\x61\x3b\xe0\x4c\xa2\x1b\x95\x78\x95\xf0\xa4\x9c\xdf\xd6\x5a\x2e\x95\x17\xd9\x7e\x95\xff\x03\xad\x68\xa0\x36\x66\x08\xfa\xe3\x27\xc6\x39\x4d\x48\x04\x36\xa8\xcb\x09\x80\xe2\x54\xa1\x1e\x40\xa2\x0e\xda\xcb\x16\xcf\x3a\xce\x3b\x63\x3a\x05\xa3\x7a\x84\xbf\x7e\xda\x32\xdb\xc5\x07\x2c\x48\x89\x14\xc4\xd7\x2d\xc5\x29\xdc\x05\xaa\xa0\x3c\xac\xe5\x07\xbd\x07\x2d\x97\xdb\xbd\x03\x00\x00\xff\xff\xb6\x22\x45\x39\xd3\x01\x00\x00") - -func templates_article_sharethis_html_bytes() ([]byte, error) { - return bindata_read( - _templates_article_sharethis_html, - "templates/article/sharethis.html", - ) -} - -func templates_article_sharethis_html() (*asset, error) { - bytes, err := templates_article_sharethis_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/article/sharethis.html", size: 467, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_atom_xml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x92\x4d\x4f\xc3\x20\x18\xc7\xef\xfd\x14\x84\xec\xa8\x30\x35\x26\x66\xa1\x5d\x16\x3d\x78\x98\x17\xb7\x9d\x0d\x59\x9f\x76\xc4\x16\x16\x4a\xad\xa6\xe1\xbb\x3b\xe8\xe8\x9b\xde\xc8\xf3\x7f\xe1\xf7\x10\xd8\xfa\xbb\x2c\xd0\x17\xe8\x4a\x28\x19\xe3\x3b\xb2\xc4\x08\xe4\x51\xa5\x42\xe6\x31\xae\x4d\x76\xfb\x84\xd7\x49\x14\xb1\x0c\x20\x45\x17\xaf\xac\x62\x7c\x32\xe6\xbc\xa2\xb4\x69\x1a\xd2\x3c\x10\xa5\x73\x7a\xbf\x5c\x3e\xd2\x8d\x51\x25\x4e\x22\x84\x98\x11\xa6\x80\xa4\x6d\xc9\x4e\x18\x20\xcf\x4a\x66\x22\x27\x7b\x37\xb4\x96\xd1\x4e\x75\xbe\x42\xc8\x4f\x74\xd2\x90\xc5\x78\x66\x3e\xbc\x6f\xad\xc5\x88\x7a\x5b\x7d\x4e\xb9\x81\xd4\x15\x1e\xba\xa3\xab\x09\xd3\xe8\x62\x69\x5b\x91\x21\xb2\xd1\x46\x1c\x0b\xa8\xac\xf5\x23\xcd\x65\x0e\x68\xf1\x71\x83\x16\xbc\x53\xd0\x2a\x9e\xb9\x18\x48\xa3\x7f\xdc\x2d\x23\xec\x60\xff\x07\x79\x0e\xbd\xf8\x4b\x3d\xca\xef\x8a\x3a\xef\xd7\xb8\x52\xf6\xe2\xcb\x85\xde\x33\x4c\x36\x9c\xc9\xa3\x35\xbb\x06\x90\x69\x08\x55\x75\x59\xf2\x00\xef\xb4\x3e\xfb\xba\x7f\xdb\x0e\x17\xed\x3a\x5f\x88\xd1\x49\x8e\xf1\xda\x9c\x94\x0e\x25\x4c\xf2\xd2\x3f\xc1\x64\xaf\x8d\xf7\x38\x1a\x2f\x5f\x7b\x86\x24\xa3\xfd\x33\x0e\x84\xe1\xc4\xa8\xfb\x3b\x49\xf4\x1b\x00\x00\xff\xff\x41\x57\x24\xb9\x6b\x02\x00\x00") - -func templates_atom_xml_bytes() ([]byte, error) { - return bindata_read( - _templates_atom_xml, - "templates/atom.xml", - ) -} - -func templates_atom_xml() (*asset, error) { - bytes, err := templates_atom_xml_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/atom.xml", size: 619, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_base_analytics_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x92\x51\x8f\xd3\x30\x0c\xc7\xdf\xf9\x14\x56\x5f\xd2\x8a\x53\xca\xf3\xf5\x76\xe8\x0e\x10\xe2\xe5\x84\x04\x6f\xd3\x34\x99\xd4\xcd\xb2\x75\x49\x49\xdc\x41\xd5\xed\xbb\x93\xa6\x9d\x98\x10\xd2\x3d\xc5\xfe\xfb\x57\xdb\xff\xca\xe3\x58\x53\x63\x2c\x41\x86\x16\xdb\x81\x8d\x0a\xd9\xe5\xf2\x06\x60\x1c\x4d\x03\xf2\x9b\x61\x92\x1f\x9c\x6d\x8c\x96\x9f\x9d\xd3\x2d\x3d\x5d\xb1\x2f\x1f\x13\xf7\x10\x94\x37\x1d\x03\x0f\x1d\xad\x32\xa6\xdf\x5c\xee\xf1\x84\xb3\x9a\x3d\x46\x02\xe0\x84\x1e\xb6\x1a\x7f\xc2\x6a\x7e\xce\x67\x58\x6f\xaa\x54\x9a\x72\xd9\xf5\x61\x97\xaf\xc5\x36\x10\x3f\x29\xe5\x7a\xcb\xe2\x0e\xc4\x38\xbe\x36\x5e\x6c\x8a\xff\x74\x61\x8f\xea\xf0\x15\x35\x9d\x0c\xfd\x4a\x48\x62\xf2\xa6\xb7\x8a\x8d\xb3\x79\x01\x63\x52\xe6\xc5\x34\xc6\xb5\x6a\xa7\xfa\x23\x59\x96\xca\x13\x32\x7d\x6a\x69\xca\x72\x31\xdb\x10\x45\x15\x31\x39\x59\x8c\xac\xf8\xc7\xa4\x48\x45\x0c\x83\x55\xb1\xca\xbe\xa7\x6a\x69\x1f\xe5\xe0\x27\x31\x17\x3b\xe6\x2e\xdc\x0b\x58\xdd\xcc\x6a\x9d\xc2\x69\x21\xd9\x79\xc7\x4e\xb9\x16\xde\xc3\x02\x96\xa5\x80\xfb\x39\x99\xe2\x02\xde\x82\x08\x8c\x1c\xa4\x96\xb5\xeb\x7f\xb4\xa4\x5a\xa3\x0e\xd2\x12\x97\xb5\x92\xfb\x20\xaa\x1b\x4b\xe1\xd6\x91\x26\x5e\xec\x84\xe7\xe1\x3b\xea\x17\x3c\xd2\x5f\x63\xeb\x77\x9b\x0a\x82\xec\xd0\x47\xe0\xc5\xd5\x24\x8d\x0d\xe4\xf9\x99\x1a\xe7\x29\xd7\x78\x07\x61\xf9\xc9\x97\x22\x4f\xd1\x43\x39\x7f\xfc\x98\xae\x84\x6c\x1d\xef\xe0\xfa\xfe\x09\x00\x00\xff\xff\xea\xed\x60\x78\x4f\x02\x00\x00") - -func templates_base_analytics_html_bytes() ([]byte, error) { - return bindata_read( - _templates_base_analytics_html, - "templates/base/analytics.html", - ) -} - -func templates_base_analytics_html() (*asset, error) { - bytes, err := templates_base_analytics_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/base/analytics.html", size: 591, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_base_base_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x57\x5b\x6f\xe4\x34\x14\x7e\xdf\x5f\x61\x4c\x1f\xb6\xa2\x49\xb6\x48\x48\xab\xee\x24\x52\x77\xd8\x15\x48\xc0\x56\xea\x20\xc1\x13\xf2\x24\x9e\xc4\x8b\x13\x07\xdb\x99\xe9\x28\x9a\xff\xce\xb1\x63\xe7\x36\x69\x69\x85\x16\x89\xa7\xc4\xe7\x7e\xf9\xce\x89\xd3\xb6\x19\xdd\xb1\x8a\x22\xbc\x25\x8a\xe2\xd3\xe9\xd5\xea\xab\xef\x3f\xad\x37\xbf\xdf\x7d\x40\x85\x2e\x79\xf2\x6a\xd5\x3d\x10\x5a\x15\x94\x64\xe6\x05\x5e\x4b\xaa\x09\x4a\x0b\x22\x15\xd5\x31\x6e\xf4\x2e\x78\x8b\xc7\xac\x42\xeb\x3a\xa0\x7f\x35\x6c\x1f\xe3\xdf\x82\x5f\x6f\x83\xb5\x28\x6b\xa2\xd9\x96\x53\x8c\x52\x51\x69\x5a\x81\xde\x8f\x1f\x62\x9a\xe5\x74\xa2\x59\x91\x92\xc6\x78\xcf\xe8\xa1\x16\x52\x8f\x84\x0f\x2c\xd3\x45\x9c\xd1\x3d\x4b\x69\x60\x0f\x57\x88\x55\x4c\x33\xc2\x03\x95\x12\x4e\xe3\xeb\xf0\x0d\x98\xea\x6c\x69\xa6\x39\x4d\xda\x56\xd3\xb2\xe6\x44\x43\x7e\x96\x82\x51\x78\x3a\xad\xa2\x8e\xeb\x44\x39\xab\xfe\x44\x85\xa4\xbb\x18\x47\x3b\x4a\x33\x15\x11\xce\x43\xa2\x45\x19\x3e\x94\x1c\x23\x7d\xac\x21\x22\x52\xd7\x9c\xa5\x90\x82\xa8\x22\xc3\xfb\xc6\xf2\x24\xe5\xc0\xe2\x9a\xca\x0a\x9c\x80\xac\x31\x1c\xe3\x7b\xa6\x29\x84\x48\xd1\xed\xe6\xd3\xcf\xe8\x23\x18\x75\x39\xb6\x2d\xdb\xa1\xd0\xb0\xc3\xb5\xa8\x76\x2c\x0f\x3f\x12\x48\x48\x54\x50\xf8\x21\x18\x6b\x55\x15\x90\x7f\xda\x68\x64\xd8\xd8\x05\xd8\xb6\xcb\xca\x18\x45\xde\x01\xad\x32\x30\xe6\x0e\x43\xfa\xa6\x79\x54\xda\xfc\x5f\x3d\x12\xca\x3d\xf4\x93\x6e\x0a\xa6\xee\x9a\x2d\x67\xaa\xa0\xd2\x47\xa5\x52\xc9\x6a\xed\x2a\xa1\xe9\x83\x8e\x3e\x93\x3d\xe9\xa8\x38\xd9\x13\x89\xd4\x81\xe9\xb4\xd8\x88\xef\x1e\x62\x2d\x1b\xfa\x6e\x15\x75\xdc\xe4\x19\x06\x90\x92\x29\xd4\x3e\x3a\x84\xca\x44\xa0\x21\x82\x30\x15\x65\xb4\x6d\xb4\x86\x6a\x77\x0f\x15\x7e\x56\x38\x79\x89\xd9\x4e\x06\x21\xa5\x7f\x62\x79\xa1\x43\x51\x9b\xe6\xa9\xd7\x6d\xed\xd3\xbb\x41\xf3\x82\x2e\x95\x00\x5f\xa1\x4c\xfc\x22\xf4\x0f\x44\x15\x37\x68\x47\xb8\xa2\x8e\xb2\x16\xf5\xb1\xa7\x14\xc0\xbe\xcd\x32\x49\x95\x7a\x4f\xa4\x23\x9f\x2e\xdf\x75\x91\x4e\xe2\xf6\x4d\x32\xf4\x6e\xa8\xcc\xeb\x56\x64\x47\x97\x57\xc6\xf6\x28\xe5\x44\xa9\x18\x57\x64\xbf\x85\xfa\x76\x8f\x00\x86\x95\x34\x5c\xfb\xa3\xd2\x00\xc8\x34\xd0\xa2\x06\x28\x0a\x83\x3c\x60\xb0\xdc\xa2\xb4\xcf\x7f\x6c\xcd\x4c\x13\x81\x71\x97\x3d\x77\xc9\x5b\xe0\xc0\x32\xc8\x98\xf0\x6c\x1b\x5c\xad\xbb\x03\x9e\xa9\x69\x91\xe7\x66\xc6\x32\xa2\x89\x3b\x18\x97\x9c\x93\x5a\xf5\x64\x22\x73\xb3\x33\x42\xa7\xd3\xb3\xc7\xce\x4c\x6b\x6b\x52\x79\xf3\x4a\x06\xa2\xe2\x47\x9c\x6c\xac\x4d\x34\x24\x09\x75\x05\xb9\x27\x54\xcd\x78\x04\xe0\xc7\x42\xe7\x3f\x11\x5d\x39\xc0\x4e\x68\x64\x56\xa9\xad\x24\x55\xe6\x87\x3a\xc2\xc9\x0c\x86\x1b\xb3\x46\xcc\xa2\x22\xa3\x36\x45\xd0\xa7\xe1\x68\xc7\x57\x48\x37\xc1\x77\x24\xa7\x0a\xbd\x06\xa3\x8e\xb0\x21\xb9\x9a\x4f\xb7\x38\x18\xea\xe5\x58\x6c\x0d\xbb\x21\x17\x92\xd1\x05\xe1\x81\x37\x51\xb9\x95\x00\x39\xbe\xa4\x70\x2b\xd3\x82\xed\xe9\xa5\xdb\x1a\x8f\x60\xcb\x37\x1c\x2d\x76\xfe\x1f\xd2\x7a\x91\x73\x70\xdf\xf0\x91\x77\x3f\x35\xf0\x98\xa1\x6d\x69\x17\xf6\x26\x27\x16\xed\x8a\x4e\xa0\x9f\xae\x75\xa4\x93\x51\xa1\xf9\x4a\xe2\xc4\xa9\x28\xd3\xb9\x55\x04\x92\x33\x37\x7e\xee\xc7\x34\x80\x42\x4e\xd1\xc5\x1f\x57\xe8\xa2\x86\x7c\xd1\x4d\x3c\xce\xfe\x29\xef\x6d\x6b\x35\xc2\x7b\xde\xe4\xb0\xa7\x12\x7f\x1e\xc1\xe7\x39\x41\xac\xa2\x86\x4f\x7b\x80\x40\x04\x4d\x64\x7c\x5f\xfe\x1d\x76\x9e\x40\xe5\xf3\xfa\xe6\x5f\xa5\xd9\xe8\x4b\x4d\x7c\x69\x78\xe7\xe5\xf5\x8e\x33\x29\xea\x4c\x1c\xaa\xf9\x62\xf2\xc5\xff\x7a\xb6\xe7\x06\xf9\x91\xe7\xd5\xb6\xdf\xbc\xe6\xcb\x66\xf6\xc5\x36\x99\x8c\xf5\x2c\x5d\x6f\x25\x28\x69\xd5\xcc\x5c\xcf\xc0\x92\x76\x6e\x8e\x03\x60\x1e\x4d\xcb\x68\x5e\x10\x3f\x3b\x20\x7f\xd1\x4f\xd2\xfb\xe3\xda\xdb\xe9\x2d\x9e\x69\xaf\xe6\x20\x1a\xd5\x21\xf2\x5a\x11\xf8\x18\x2c\xb8\x81\x98\xd0\xa6\x4b\x74\x4b\xe0\xee\x87\xea\x86\x73\xdf\xce\xb6\xe5\xb4\x42\x7d\xa0\x06\xc1\x76\xbb\x9e\x15\xcc\x60\xf6\x3c\xa4\xa5\xf1\x9a\x63\x7b\x49\x73\x79\x2c\x27\x60\x7a\x1c\xb8\x5f\x02\x40\xd6\xdb\x97\x84\x8e\x26\xf9\x80\x9a\x85\x2c\x9e\xc4\x0b\xc8\x5b\x0b\x2f\x43\x09\x28\x18\x80\x58\xbd\x01\x1b\xf6\xf8\xbf\x81\xc5\xf9\xa2\x9c\x4a\x9c\x7d\xa2\xc7\xec\x11\xd3\xbd\x9e\xdd\xf5\xfa\xdb\x99\xf9\x36\x06\x65\x16\x5c\xbf\xf1\x6f\x62\xb7\x83\x5f\xad\xe0\xda\x9e\x79\x1e\xbc\xf5\x2f\x8e\xf1\x6d\xdf\xf0\xf1\xa5\xdf\xfd\x3c\x75\xb7\xfe\x59\x10\x63\xb9\x9d\x10\xda\xff\x1c\xcc\x79\xa4\x22\xfc\x08\x95\x57\x9e\x0d\x38\xb4\x37\x55\xb8\xbb\xda\x3f\x43\x9f\xe6\xdf\x01\x00\x00\xff\xff\x5b\x40\x77\x1c\x4b\x0e\x00\x00") - -func templates_base_base_html_bytes() ([]byte, error) { - return bindata_read( - _templates_base_base_html, - "templates/base/base.html", - ) -} - -func templates_base_base_html() (*asset, error) { - bytes, err := templates_base_base_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/base/base.html", size: 3659, mode: os.FileMode(420), modTime: time.Unix(1426674262, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_base_footer_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\x92\xdd\x8e\xa3\x30\x0c\x85\xef\xf7\x29\xac\x5c\x56\x82\x94\xbd\x5a\xad\x28\xda\x87\xd8\x17\x08\x60\x20\x28\x24\xd9\xd8\xdd\xfe\xa0\xbe\xfb\x18\x5a\xa6\x33\x53\xcd\x0d\x3a\x8e\xc3\xe7\x73\xc0\xf3\xdc\x62\x67\x3d\x82\xea\x42\x60\x4c\xea\x76\xfb\x01\x30\xcf\x7a\x07\x7f\x07\x4b\x40\x43\x38\xba\x16\x6a\x04\x8a\xce\x32\x04\x0f\x1e\x4f\x90\xd0\xa1\x21\x24\xd8\xe9\xf5\x85\xb2\xb5\xff\xa1\x71\x86\xe8\xa0\x9a\xe0\xd9\x08\x32\x41\x13\x5c\x36\xb5\x59\xb1\xdf\x54\xe8\x3a\x42\xce\x8a\xb5\x76\x7d\xf6\x6b\x13\x8f\xc6\x4f\x55\x09\xec\x33\x8e\xf1\xcc\x59\x83\x7e\x31\x77\xef\x4a\x3f\x6e\x4a\xb4\x81\x21\x61\x77\x50\x03\x73\xfc\xad\x75\x6f\x79\x38\xd6\x79\x13\x26\x6d\xfa\xe0\xaf\xc6\xe1\x35\x05\x1d\x83\x0b\xaa\x5a\x9e\xa5\x36\x15\x48\xb4\xc9\xb4\x08\x27\xb9\xfd\x44\x51\x34\x7e\x9b\xdb\xbb\x4b\x1c\xac\x84\x81\x77\x95\x0d\x68\x12\xab\xaa\xd4\xcb\xc5\x0a\xea\xcb\xb7\x2e\x58\xc0\xe2\xf8\xab\x0d\x55\xfd\xf9\x50\x2d\x4e\xb6\x44\xfa\x11\xa9\xd4\x92\x7d\x91\x4f\x41\x4d\xb2\x91\x81\x52\x73\xc7\x93\xf0\xcd\x68\xce\x79\x1f\x42\x2f\xff\x21\x5a\xba\xcf\x91\x33\xed\x6c\x4d\x7a\xfc\x77\xc4\x74\xd1\x45\x5e\x14\xf9\xfe\x51\xe5\x93\xf5\xf9\x48\xab\xfb\x15\xf8\xc2\x96\x6f\x87\x5c\xcb\x1a\x10\x27\x13\x57\x64\x6b\x89\xf5\x48\xfa\x79\xfa\x4a\x99\x67\xf4\xad\x6c\xc1\x5b\x00\x00\x00\xff\xff\xa9\xef\x18\x09\x4b\x02\x00\x00") - -func templates_base_footer_html_bytes() ([]byte, error) { - return bindata_read( - _templates_base_footer_html, - "templates/base/footer.html", - ) -} - -func templates_base_footer_html() (*asset, error) { - bytes, err := templates_base_footer_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/base/footer.html", size: 587, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_base_header_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\xcf\x31\x0e\x02\x21\x10\x85\xe1\xde\x53\x90\xe9\x05\x93\x6d\x5d\xef\x82\xcc\xdb\x40\x84\xc1\x30\xd3\x18\xb2\x77\x77\x2b\xf5\x02\xb6\x7f\x5e\xf2\xe5\xcd\xc9\xd8\x8a\xc0\x51\x46\x64\x0c\xda\xf7\x93\x73\xd7\x5a\xe4\xe1\x06\xea\x4a\x6a\xaf\x0a\xcd\x80\x91\xcb\x03\xdb\x4a\x21\x08\x8c\x25\xfa\x7b\xef\xa6\x36\xe2\x33\xb1\xf8\xd4\x5b\xf8\x84\xb0\xf8\x8b\x5f\x42\x52\xfd\x36\xdf\xca\xb1\x52\xa5\xdb\x9f\x80\xb3\x65\x34\xfc\x30\x73\x42\xf8\xf8\xf3\x0e\x00\x00\xff\xff\x6a\x24\xeb\x71\xe4\x00\x00\x00") - -func templates_base_header_html_bytes() ([]byte, error) { - return bindata_read( - _templates_base_header_html, - "templates/base/header.html", - ) -} - -func templates_base_header_html() (*asset, error) { - bytes, err := templates_base_header_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/base/header.html", size: 228, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_category_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x54\x8e\x41\xab\xc3\x20\x10\x84\xef\xfe\x8a\x45\x72\x7c\x28\xef\xfa\xd8\x08\x8f\xfc\x84\xf4\x5e\x24\xd9\x18\x41\x0c\xd8\xcd\xa1\x58\xff\x7b\x4d\xd2\xd0\xf6\xa4\x33\xcc\x7e\x33\x39\x8f\x34\xf9\x48\x20\xd9\x73\x20\x59\x8a\xc8\x59\x75\x96\xc9\x2d\xe9\x5e\x0a\x3c\xa0\xea\xde\x33\xa9\x6e\x89\x93\x77\xea\xb2\xe5\xf6\x18\xc5\xb1\xbe\xe2\x8d\x18\x96\xc8\x14\x79\x83\xe0\xfc\x6b\xbe\x40\xa8\xab\x23\x70\x0d\x46\x40\x45\x26\x1b\x1d\x41\x73\xfd\x81\xc6\x26\xf6\x43\x20\xf8\x6b\x41\xfd\x1f\xff\x5b\x25\x00\x60\xf0\x06\x2d\xcc\x89\xa6\x56\xe6\x7c\x06\x55\x1f\x56\x57\x8a\x34\x1f\xd6\x6b\x14\x6a\x6b\x50\xd7\xb3\xbd\xe3\xd8\x87\x7a\xeb\x3c\xd5\x33\x00\x00\xff\xff\x03\x42\x6c\xbd\xf0\x00\x00\x00") - -func templates_category_html_bytes() ([]byte, error) { - return bindata_read( - _templates_category_html, - "templates/category.html", - ) -} - -func templates_category_html() (*asset, error) { - bytes, err := templates_category_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/category.html", size: 240, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_index_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x55\x4f\x6f\xa3\x3e\x10\xbd\xf3\x29\x5c\x7e\xd1\xef\x50\x6d\x41\xbd\xee\x12\xa4\xaa\x7b\xe8\xa1\x9b\xad\xd4\xdc\x2b\x07\x06\xb0\x64\x4c\x62\x9b\xa8\x59\x94\xef\xbe\xe3\x3f\x04\x9c\xa5\xda\x6a\x23\x25\x86\x19\xcf\xbc\x37\x33\xcf\xce\x30\x94\x50\x31\x01\x24\xd6\x4c\x73\x88\xcf\xe7\x68\x18\x92\x57\xa6\x21\x79\xec\x44\xc5\xea\x64\x6b\xec\xd6\x0c\xa2\xc4\x35\x9a\x42\x8a\x4e\x68\x10\xda\x05\xb1\x8a\x24\x0f\x52\xb3\x82\x83\x72\xdb\x24\x15\x35\x90\xd5\xdb\x17\xb2\xa2\xce\x41\xbe\xae\x83\x4d\x99\xb7\xe7\x51\xd6\xdc\xe7\x19\x25\x8d\x84\x6a\x1d\x0f\xc3\x18\x90\xbc\xf2\xbe\x3e\x9f\xe3\x7c\x66\xf2\x84\xb2\x94\xe6\x59\x8a\x61\x51\x94\xed\x73\x47\xa0\x93\x64\x15\x90\x7f\xe8\x75\x63\x8c\x63\xac\x7b\x37\xc8\x6a\x4f\x05\x29\x38\x55\x6a\x1d\x73\xba\x03\x4e\xec\xef\x1d\xd6\x46\x7b\xae\xe3\x7c\x77\x22\x36\xe7\x1f\xb1\x33\x2a\x93\x09\xb8\x02\xeb\x5a\x80\xb7\x7e\xd3\xbb\x2c\x35\xa8\xf9\xbc\x95\x73\x80\xef\x54\xc3\xa7\xa8\x19\x98\xa7\xbe\xa5\x82\xfd\x02\x13\xa4\x59\x0b\xd7\x69\xfe\x82\xf5\x88\x9b\xea\x4e\x9e\xec\x10\x96\xc0\x54\x5f\x14\xa0\x54\xec\x47\x92\x16\x3e\x20\x9d\x95\x3f\x25\x49\x1a\xdd\xf2\x60\x4a\x93\xcf\x0c\xea\x23\x1a\x5b\x5a\x2b\xab\x9e\x99\x56\x34\xad\x8d\x4e\xae\xf7\x2c\xd3\x64\xa2\xea\x2e\x1c\x31\xd2\xd0\xc3\x65\xce\xc8\xbe\x06\x24\xc6\x35\x4b\x51\x38\xd1\x8c\xf4\xd3\xf6\xc7\xf3\xac\x47\x4e\xde\x66\xe3\x7e\xc4\xd6\xf0\xae\xef\x24\xab\x1b\x1c\xc3\xc4\x68\xa7\x05\xc1\xef\x65\x42\x1f\xe9\xf8\xbf\x92\xa9\x43\xaf\xde\x34\xfa\x69\x19\xe7\xcf\x40\x8f\x40\x30\x4d\xd7\xb6\x88\x74\xe3\x34\x8d\xa4\xf0\x61\x3a\x19\x32\x68\x9f\x53\x9a\x3d\x30\x9b\x4e\x37\x4c\xd4\x44\x77\x44\x01\x90\x06\x24\xdc\xb8\x23\x71\x1d\x84\x3d\xaf\x35\x71\xda\xdc\xf4\xed\x0e\xe4\xcf\xea\x85\xd6\xa0\xc8\xbd\xc9\x55\xb2\x63\x50\x60\x81\x64\x40\x62\x85\x3d\x1f\xed\x7b\x5a\x33\x41\x35\xeb\x44\x8c\x3d\x23\xf8\xc9\x38\x1b\x9d\xf6\xdd\xa2\xc0\x01\x4f\xa0\xc9\xec\x50\x6c\x7a\xe3\xc4\xc2\xe9\x8e\x43\xe9\x77\x3a\x62\xe6\x19\xb3\xd9\x64\xb3\xb3\x9f\xbc\x48\x38\xb2\xae\x57\xa6\x69\x41\x3a\x73\x13\xfc\xcf\xe9\xa1\xef\xbe\xd9\x81\xda\xc8\x94\x33\xcf\x28\x90\x11\x12\x1e\xef\x1b\x49\x4f\xbe\x5c\x0f\x6a\xa8\x5f\xe8\xda\x8d\x21\x8a\x2f\x8b\x16\x9a\x1d\x21\xf6\x74\xaf\x88\xa6\x4c\x94\xf0\x6e\xb3\xe0\x5d\xe8\xb2\xdc\xdb\x2b\xc0\x3c\x5e\xce\xbc\xd7\xa1\x8d\x35\x0c\xbd\xd7\x53\x0f\x6a\x98\xb5\x06\xd7\xf4\x96\xb8\x6a\x6e\x53\x33\xc3\x4f\x77\x7c\xb5\x30\xe5\x7f\x19\xc2\x06\x85\xb0\x3c\x00\xb9\x38\x80\x2c\xed\x39\x8a\x17\xa5\x74\x51\x9e\xab\x02\x39\xda\x12\x02\xa3\xff\xeb\x70\x9e\xdf\x01\x00\x00\xff\xff\x15\x8b\x41\x60\x85\x06\x00\x00") - -func templates_index_html_bytes() ([]byte, error) { - return bindata_read( - _templates_index_html, - "templates/index.html", - ) -} - -func templates_index_html() (*asset, error) { - bytes, err := templates_index_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/index.html", size: 1669, mode: os.FileMode(420), modTime: time.Unix(1422915149, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_page_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xaa\xae\x4e\x49\x4d\xcb\xcc\x4b\x55\x50\x2a\xc9\x2c\xc9\x49\x55\xaa\xad\xe5\xaa\xae\xd6\x0b\x48\x4c\x4f\xd5\x0b\x01\x09\xd4\xd6\x2a\xd4\x28\x00\x45\x82\x33\x4b\x52\xf5\x9c\xf3\xf3\xd2\x32\xd3\x61\x12\x40\x85\xa9\x79\x29\x40\x9a\x0b\x61\x48\x72\x7e\x5e\x49\x6a\x5e\x09\xc8\x18\x9b\x0c\x43\x3b\x34\xa3\x6c\xf4\x81\x62\x70\xf3\x3d\x42\x7c\x7d\x14\x20\x4c\x67\x88\x36\x24\x33\x01\x01\x00\x00\xff\xff\x27\x7a\x43\x12\x98\x00\x00\x00") - -func templates_page_html_bytes() ([]byte, error) { - return bindata_read( - _templates_page_html, - "templates/page.html", - ) -} - -func templates_page_html() (*asset, error) { - bytes, err := templates_page_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/page.html", size: 152, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _templates_tag_html = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x8e\xc1\x0a\x83\x30\x10\x44\xef\xf9\x8a\x25\x78\x2c\x09\xbd\x96\x35\x50\xfa\x09\x7a\x2f\x41\x57\x0d\x84\x08\x36\x9e\xb6\xf9\xf7\xae\x5a\x69\x4f\xd9\x09\xf3\x66\x86\xb9\xa7\x21\x24\x02\x9d\x43\x8e\xa4\x4b\x51\xcc\xa6\xf5\x63\x29\xf0\x06\x39\x9b\x90\xc9\x3c\xe6\x34\x84\xd1\xb4\x9b\x65\x77\x50\xea\xe5\x55\x3f\xba\x9b\x53\xa6\x94\x37\x1e\xa7\xab\x3b\x33\xd0\x8a\x50\xb8\x46\xa7\x40\xd2\x16\x9f\x46\x82\xea\x79\x81\xca\x2f\x39\x74\x91\xe0\x56\x83\xb9\x1f\xf7\x4b\x60\x00\x8c\xc1\xa1\x87\x69\xa1\xa1\xd6\xcc\xa7\xd1\x34\x71\x95\x40\xed\xfe\xbe\xbe\x7b\xd0\x7a\x87\x56\xb0\xbd\xe3\x98\x86\x76\xeb\x3c\xd5\x27\x00\x00\xff\xff\xd0\xa4\x2a\x22\xe6\x00\x00\x00") - -func templates_tag_html_bytes() ([]byte, error) { - return bindata_read( - _templates_tag_html, - "templates/tag.html", - ) -} - -func templates_tag_html() (*asset, error) { - bytes, err := templates_tag_html_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "templates/tag.html", size: 230, mode: os.FileMode(420), modTime: time.Unix(1415354637, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "templates/archives.html": templates_archives_html, - "templates/article/article.html": templates_article_article_html, - "templates/article/disqus.html": templates_article_disqus_html, - "templates/article/sharethis.html": templates_article_sharethis_html, - "templates/atom.xml": templates_atom_xml, - "templates/base/analytics.html": templates_base_analytics_html, - "templates/base/base.html": templates_base_base_html, - "templates/base/footer.html": templates_base_footer_html, - "templates/base/header.html": templates_base_header_html, - "templates/category.html": templates_category_html, - "templates/index.html": templates_index_html, - "templates/page.html": templates_page_html, - "templates/tag.html": templates_tag_html, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for name := range node.Children { - rv = append(rv, name) - } - return rv, nil -} - -type _bintree_t struct { - Func func() (*asset, error) - Children map[string]*_bintree_t -} -var _bintree = &_bintree_t{nil, map[string]*_bintree_t{ - "templates": &_bintree_t{nil, map[string]*_bintree_t{ - "archives.html": &_bintree_t{templates_archives_html, map[string]*_bintree_t{ - }}, - "article": &_bintree_t{nil, map[string]*_bintree_t{ - "article.html": &_bintree_t{templates_article_article_html, map[string]*_bintree_t{ - }}, - "disqus.html": &_bintree_t{templates_article_disqus_html, map[string]*_bintree_t{ - }}, - "sharethis.html": &_bintree_t{templates_article_sharethis_html, map[string]*_bintree_t{ - }}, - }}, - "atom.xml": &_bintree_t{templates_atom_xml, map[string]*_bintree_t{ - }}, - "base": &_bintree_t{nil, map[string]*_bintree_t{ - "analytics.html": &_bintree_t{templates_base_analytics_html, map[string]*_bintree_t{ - }}, - "base.html": &_bintree_t{templates_base_base_html, map[string]*_bintree_t{ - }}, - "footer.html": &_bintree_t{templates_base_footer_html, map[string]*_bintree_t{ - }}, - "header.html": &_bintree_t{templates_base_header_html, map[string]*_bintree_t{ - }}, - }}, - "category.html": &_bintree_t{templates_category_html, map[string]*_bintree_t{ - }}, - "index.html": &_bintree_t{templates_index_html, map[string]*_bintree_t{ - }}, - "page.html": &_bintree_t{templates_page_html, map[string]*_bintree_t{ - }}, - "tag.html": &_bintree_t{templates_tag_html, map[string]*_bintree_t{ - }}, - }}, -}} - -// Restore an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, path.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// Restore assets under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - if err != nil { // File - return RestoreAsset(dir, name) - } else { // Dir - for _, child := range children { - err = RestoreAssets(dir, path.Join(name, child)) - if err != nil { - return err - } - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} - diff --git a/src/templates/templates/category.html b/src/templates/templates/category.html deleted file mode 100644 index 85d30c1..0000000 --- a/src/templates/templates/category.html +++ /dev/null @@ -1,12 +0,0 @@ -{{define "title"}} -{{.Category}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Category}}

- -{{end}} diff --git a/src/templates/templates/index.html b/src/templates/templates/index.html deleted file mode 100644 index 1007d86..0000000 --- a/src/templates/templates/index.html +++ /dev/null @@ -1,72 +0,0 @@ -{{define "title"}} -{{.Site.Config.Title}} -{{end}} - -{{define "content"}} -{{if .Articles}} - -{{range $_, $article := .Articles}} -
-

{{$article.Title}}

- -

-{{if or $.Site.Config.Author $article.Author}} -by {{if $article.Author}}{{$article.Author}}{{else}}{{$.Site.Config.Author}}{{end}} -{{end}} - -{{if $article.Date}} -{{$.HumanizeDatetime $article.Date}} -{{end}} - -{{if $article.Category}} -{{$article.Category}} -{{end}} - -{{if $article.Tags}} -{{range $_, $tag := $article.Tags}} -{{$tag}} -{{end}} -{{end}} -

- -{{$article.HTML $article.Content}} -

Leave a comment!

-
-
-{{end}} - -{{else}} -

Nothing to see here!

-
-{{end}} - -{{if gt .Site.NumberOfPages 1}} -
    - -
  • - « -
  • - - {{range $_, $page := .ArrayOfPages}} -
  • - - {{$page}} - -
  • - {{end}} {{/* range */}} - -
  • - » -
  • - -
-{{end}} {{/* if */}} -{{end}} {{/* content */}} diff --git a/src/templates/templates/page.html b/src/templates/templates/page.html deleted file mode 100644 index 3ca144e..0000000 --- a/src/templates/templates/page.html +++ /dev/null @@ -1,8 +0,0 @@ -{{define "title"}} -{{.Page.Title}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Page.Title}}

-{{.Page.HTML .Page.Content}} -{{end}} diff --git a/src/templates/templates/tag.html b/src/templates/templates/tag.html deleted file mode 100644 index fe6fe04..0000000 --- a/src/templates/templates/tag.html +++ /dev/null @@ -1,12 +0,0 @@ -{{define "title"}} -{{.Tag}} | {{.Site.Config.Title}} -{{end}} - -{{define "content"}} -

{{.Tag}}

- -{{end}} diff --git a/templates/assets.go b/templates/assets.go new file mode 100644 index 0000000..5a6029c --- /dev/null +++ b/templates/assets.go @@ -0,0 +1,613 @@ +// Code generated by go-bindata. +// sources: +// ../../templates/atom.tmpl +// ../../templates/base.tmpl +// ../../templates/body/analytics.tmpl +// ../../templates/body/content/archive.tmpl +// ../../templates/body/content/article/article.tmpl +// ../../templates/body/content/article/disqus.tmpl +// ../../templates/body/content/article/share_icons.tmpl +// ../../templates/body/content/category.tmpl +// ../../templates/body/content/index.tmpl +// ../../templates/body/content/page.tmpl +// ../../templates/body/content/tag.tmpl +// ../../templates/body/footer.tmpl +// ../../templates/body/footer_scripts.tmpl +// ../../templates/body/navbar.tmpl +// ../../templates/head/header.tmpl +// ../../templates/head/header_scripts.tmpl +// ../../templates/head/share_this.tmpl +// DO NOT EDIT! + +package assets + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _templatesAtomTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x92\xc1\x4e\xf3\x30\x10\x84\xef\x79\x8a\x95\xd5\xe3\xff\xc7\x05\x84\x84\x2a\x27\x55\x05\x47\x4e\x40\xcf\xc8\xd4\xeb\xd4\x22\xb1\x2b\xc7\x21\x20\xcb\xef\x4e\x9c\xd4\x4d\x5b\x71\xb3\x3d\xdf\xee\xcc\x44\xf1\x5e\xa0\x54\x1a\x81\x7c\xf0\x16\x49\x08\x19\x5b\x7f\x37\x35\x7c\xa1\x6d\x95\xd1\x05\xb9\xc9\x97\x04\x50\xef\x8c\x50\xba\x2a\x48\xe7\xe4\xff\x07\xb2\x2e\xb3\x8c\x49\x44\x01\x03\xab\xdb\x82\xec\x9d\x3b\xac\x28\xed\xfb\x3e\xef\xef\x72\x63\x2b\x7a\xbb\x5c\xde\xd3\x8d\x33\x0d\x29\x33\x00\xe6\x94\xab\xb1\xf4\x3e\x7f\x34\x5a\xaa\x2a\x7f\x8b\xf7\x10\x18\x9d\x84\x88\xd4\x4a\x7f\xc2\xde\xa2\x2c\xc8\xcc\x6d\x5f\x9e\x43\x20\x40\x47\xa2\x3b\x08\xee\x50\xc4\x35\xdb\xe9\x18\x37\xa4\xd7\x6c\x40\xbc\x57\x12\xf2\x8d\x75\x6a\x57\x63\x3b\xb4\x89\x4f\x96\xeb\x0a\x61\xf1\xfe\x0f\x16\x7c\x52\x60\x55\x5c\x51\x0c\xb5\xb3\x3f\xd1\xe5\x2c\x6c\xc2\xff\x48\x7b\x9d\x77\x71\x11\xf8\x6c\xf4\xb5\xee\xaa\x53\x83\x63\xc0\x93\xf8\x34\x04\x1f\xed\x2f\xca\x5d\xc9\x67\x0d\xa7\x0d\xa8\x45\x1a\x6a\xbb\xa6\xe1\x29\x77\xd4\x66\xdf\x49\x49\x20\xbd\x20\x19\xef\xdc\xde\xd8\x34\xc6\x34\x6f\xc6\xbe\xa9\xc4\x66\x94\xa3\xf5\xa8\x1c\x57\xcc\x43\x8c\x9e\x3e\xd7\x1c\x27\x9d\x18\x8d\x7f\x46\x99\xa5\xfb\x6f\x00\x00\x00\xff\xff\x3c\xc3\x3c\x5e\x63\x02\x00\x00") + +func templatesAtomTmplBytes() ([]byte, error) { + return bindataRead( + _templatesAtomTmpl, + "templates/atom.tmpl", + ) +} + +func templatesAtomTmpl() (*asset, error) { + bytes, err := templatesAtomTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/atom.tmpl", size: 611, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBaseTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x52\xc1\x6e\xd4\x30\x10\xbd\xf7\x2b\x06\x5f\x21\x09\xdc\x38\xc4\x2b\x55\x4b\x2b\x71\x40\x45\xa2\x48\x70\xaa\x26\xce\xa4\x19\xd5\xb1\x43\x3c\xbb\x65\x65\xed\xbf\xe3\x38\x5b\x29\x0b\xb4\x3d\x79\xac\xf7\xe6\x79\xde\x1b\xc7\xd8\x52\xc7\x8e\x40\x35\x18\x48\x1d\x8f\x17\xf5\x9b\x4f\x37\xdb\xdb\x9f\x5f\xaf\xa0\x97\xc1\x6e\x2e\xea\xe5\x00\xa8\x7b\xc2\x76\x2e\x52\x39\x90\x20\x98\x1e\xa7\x40\xa2\xd5\x4e\xba\xe2\xa3\x5a\x43\xbd\xc8\x58\xd0\xaf\x1d\xef\xb5\xfa\x51\x7c\xbf\x2c\xb6\x7e\x18\x51\xb8\xb1\xa4\xc0\x78\x27\xe4\x52\xdf\xe7\x2b\x4d\xed\x3d\x9d\x75\x3a\x1c\x48\xab\x3d\xd3\xe3\xe8\x27\x59\x91\x1f\xb9\x95\x5e\xb7\xb4\x67\x43\x45\xbe\xbc\x03\x76\x2c\x8c\xb6\x08\x06\x2d\xe9\x0f\xe5\xfb\x24\x95\xb5\x62\xe4\x0e\xca\xad\x77\x1d\xdf\x97\xd7\x98\x7a\xbc\x4b\xde\xf2\x33\x96\xdd\x03\x4c\x64\xb5\x0a\x7d\x7a\xc2\xec\x04\x66\x58\x41\x3f\x51\xa7\x55\x8c\xff\xf4\x29\xa8\x36\x27\x59\x72\x6d\xd2\x59\x84\x84\xc5\xd2\x26\xc6\xc6\x7a\xf3\x00\x2a\x5f\x15\x94\xc7\xe3\x89\x56\x57\x0b\xe3\x69\xa4\x13\x6f\x8e\x91\xa6\x35\xf1\x7f\xf8\x5d\x30\x13\x8f\x12\x9e\xe7\x85\x14\x3f\xdd\x49\xcf\xe7\x9c\x95\xc9\xc5\x50\xd5\x11\xb5\xa1\x42\x6b\x4b\x14\x3f\x94\xbf\x07\xab\x40\x0e\x63\x8a\x19\xc7\xd1\xb2\x49\x7b\xf1\xae\x9a\xb1\xb7\x19\xcb\xd9\xa0\x15\x9a\x1c\x4a\x72\x94\x5d\x68\xf5\x8d\x85\x52\xee\x04\x97\xb7\x37\x5f\xe0\x3a\x89\xe6\xc5\xd5\xd5\xf2\x2f\xe6\xb2\xf1\xed\x61\x73\x3e\xa5\xc3\x7d\x83\x2f\xb8\x3d\xed\xf7\x79\x42\xe7\xbd\xbc\x14\xd7\x82\xbf\x1e\x17\x3a\xb4\x07\x61\xf3\x37\xa5\xae\x96\xa9\x93\x8f\xfc\xd1\x9f\x90\x3f\x01\x00\x00\xff\xff\xdf\x8f\xf3\x43\x1a\x03\x00\x00") + +func templatesBaseTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBaseTmpl, + "templates/base.tmpl", + ) +} + +func templatesBaseTmpl() (*asset, error) { + bytes, err := templatesBaseTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/base.tmpl", size: 794, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyAnalyticsTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x7c\x92\xcd\xae\xd3\x30\x10\x85\xf7\x3c\xc5\x28\x1b\x27\xe2\xca\x61\x7d\x73\x0b\x6a\x01\x21\x36\x15\x0b\x76\x55\x55\x0d\xce\xc4\x75\x9b\xda\xc1\x9e\x14\x22\xb7\xef\x8e\xf3\x83\xa8\x10\x62\x65\xcf\x39\x5f\x66\xe6\x24\x89\xb1\xa6\xc6\x58\x82\x0c\x2d\xb6\x03\x1b\x15\xb2\xfb\xfd\x55\x8c\xa6\x01\xf9\xde\xd9\xc6\x68\xf9\xc9\x39\xdd\xd2\xfa\xb7\xff\xf9\x43\x02\x00\x5e\x82\xf2\xa6\x63\xe0\xa1\xa3\x55\xc6\xf4\x93\xcb\x13\x5e\x71\x56\xb3\xb7\x89\x00\xb8\xa2\x87\x83\xc6\xef\xb0\x9a\x8f\xdb\x0d\x76\xfb\x6a\xb2\xc6\x5a\x76\x7d\x38\xe6\x3b\x71\x08\xc4\x6b\xa5\x5c\x6f\x59\x3c\x81\x88\xf1\x3f\x93\xc5\xbe\xf8\x47\x03\xf6\xa8\xce\x5f\x50\xd3\xd5\xd0\x8f\x09\x99\x98\xbc\xe9\xad\x62\xe3\x6c\x5e\x40\x9c\x94\x79\x27\x8d\x69\xa3\xda\xa9\xfe\x42\x96\xa5\xf2\x84\x4c\x1f\x5b\x1a\xab\x5c\xcc\x09\x44\x51\x25\x4c\x8e\xe9\x12\x2b\xfe\xca\x27\x26\x13\xc3\x60\x55\x72\xd9\xf7\x54\x2d\xed\x93\x1c\xfc\x28\xe6\xe2\xc8\xdc\x85\x67\x01\xab\x87\x59\xad\x53\x38\x2e\x24\x3b\xef\xd8\x29\xd7\xc2\x3b\x58\xc0\xb2\x14\xf0\x3c\x17\xe3\xbd\x80\xd7\x20\x02\x23\x07\xa9\x65\xed\xfa\x6f\x2d\xa9\xd6\xa8\xb3\xb4\xc4\x65\xad\xe4\x29\x88\xea\x21\x52\x78\x4c\xa4\x89\x97\x38\x61\x33\x7c\x45\xbd\xc5\x0b\xfd\x09\xb6\x7b\xb3\xaf\x20\xc8\x0e\x7d\x02\xb6\xae\x26\x69\x6c\x20\xcf\x1b\x6a\x9c\xa7\x5c\xe3\x13\x84\xe5\x25\xdf\x8b\x7c\xba\xbd\x94\xf3\xc3\xe3\x67\x8d\x91\x6c\x3d\xfd\x23\xf3\xf9\x2b\x00\x00\xff\xff\x5a\x78\x7e\x8d\x43\x02\x00\x00") + +func templatesBodyAnalyticsTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyAnalyticsTmpl, + "templates/body/analytics.tmpl", + ) +} + +func templatesBodyAnalyticsTmpl() (*asset, error) { + bytes, err := templatesBodyAnalyticsTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/analytics.tmpl", size: 579, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentArchiveTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x50\xb1\x6e\xac\x30\x10\xec\xf9\x8a\x15\xa2\x7c\xc0\x23\x55\x14\x19\x4b\xa7\xa4\x48\x9f\xf4\x91\x85\x17\xb0\xb4\x18\xc9\xf8\x28\xce\xf1\xbf\x67\xcd\xe1\x4b\x1a\x7b\x3c\x3b\xb3\x1e\x4d\x08\x1a\x47\x63\x11\x4a\x6f\x3c\x61\x19\x63\x71\x71\xc3\x6c\x76\xdc\xe0\x1b\x42\x68\x5e\x57\x3b\x9a\xa9\xf9\x4c\x53\x1e\x86\x80\x56\xf3\x5d\xfc\x1a\x87\xd5\x7a\xb4\x3e\x59\x85\x36\x3b\x0c\xa4\xb6\xad\x3f\x68\xc5\x02\x07\xc3\x4a\xf5\xa2\xeb\xee\x7f\x46\xeb\x38\x6e\xe8\xeb\xee\x78\xd3\x54\x3f\x67\x70\x0e\x9e\x4a\x59\x00\x88\xb9\x93\x67\x16\xd1\x32\x4e\x94\xa6\xbc\x5e\x53\x3d\xaf\xce\xdc\xd2\x2f\x74\xe8\x81\xe3\x3a\x65\x27\x84\xea\xeb\x1f\x54\xca\x79\x33\x10\xc2\x4b\x0f\xcd\xe5\x8e\x37\x8e\x98\x74\x42\x7b\x19\x42\xd5\xbc\x5f\x17\x65\xcd\x0d\xdf\x94\x47\x6f\x16\x7c\x98\x9a\xc4\xc4\x28\x5a\x16\x9e\x0e\x2d\x85\x82\xd9\xe1\xd8\x97\x6c\xcd\xba\x0f\xba\x4e\x31\x96\xf2\x0f\x75\x36\x25\x5a\x25\xd9\xaf\x73\xb2\x7b\x6d\xbc\xa9\xd5\x24\x0b\x3e\xcd\x2e\x1f\x6d\xfe\x04\x00\x00\xff\xff\xe0\x96\xd1\xf4\x86\x01\x00\x00") + +func templatesBodyContentArchiveTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentArchiveTmpl, + "templates/body/content/archive.tmpl", + ) +} + +func templatesBodyContentArchiveTmpl() (*asset, error) { + bytes, err := templatesBodyContentArchiveTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/archive.tmpl", size: 390, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentArticleArticleTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x93\x4f\xef\x9b\x20\x18\xc7\xef\xbe\x8a\x27\xa4\xc7\xa9\xeb\x4e\xcb\x42\x4d\x9a\xee\xb0\x17\xd0\x7b\x43\xf1\x51\xc9\x10\x3a\xc1\x25\x1d\xf3\xbd\x0f\x54\x5a\x5b\x4d\xf6\xbb\x28\xcf\xbf\xef\xf7\x23\x88\x73\x25\x56\x42\x21\x10\x2b\xac\x44\x32\x0c\x89\x73\xd9\xb1\xb3\x82\x4b\xcc\xce\x21\x37\x0c\xf0\x17\x7c\xf2\xa4\x55\x25\xea\x98\xf3\x6d\xa8\x4a\xff\x4e\x9e\x12\x5c\x2b\x8b\xca\x06\x11\x5a\x8a\xdf\xc0\x25\x33\xe6\x30\xa6\x99\x6f\xe8\x80\x6b\x99\xb6\x65\xba\xff\x1c\x57\xba\xaa\x0c\xda\x74\x3f\xc6\xb2\x4e\xbf\xc6\xc5\x5c\xf8\x42\x8a\x04\x80\x36\xfb\x62\x4d\x45\x73\x9f\x4e\x42\xf9\x16\x9a\xc0\x33\x8a\x0a\x74\x07\x91\xf4\xd8\xdb\x26\x84\x71\x6e\x8a\x3d\x5c\x68\xa6\xe6\xc6\x54\x24\x94\xec\x8a\x12\xc6\x67\xea\x3f\x86\xf5\xd2\x92\xe2\x7a\x9f\x14\x57\xf3\x0b\x94\x67\x0a\xa5\xc1\xb1\xf4\x62\x3e\x56\xc2\x36\xd1\x3c\xf8\x8d\xb8\xf0\x26\xfb\x9d\x59\xfc\x30\x94\x37\xf8\xd1\xb7\x4c\x89\x3f\x18\xe6\xac\x68\xf1\x5d\x29\x5a\x4d\x4e\xf3\x21\xad\x6d\x4f\xbe\xb9\xd6\xdd\x3d\x5a\xb3\x2d\x5f\xd3\x73\x8e\xc6\x10\x68\x3a\xac\x0e\x24\xe7\xf3\x50\xbe\xd8\x83\xa7\x50\xd6\xd8\x56\x92\x62\xb3\x46\x73\xf6\x5f\xa4\x33\xab\xcd\x8c\xe3\x5c\xc7\x54\x8d\xb0\xbb\x7c\x82\x9d\x65\x35\x7c\x3b\x6c\xf6\x6d\x63\x0b\x55\xe9\x07\xb3\x9f\xf6\xb8\x41\x64\x41\x38\x85\x2b\xa8\xd7\x35\xcd\x6f\xe3\x89\x2d\x3f\x68\xfa\xc5\x27\x7e\xe7\xae\x52\xf3\x9f\x40\x4c\xc3\x3a\xb4\x8d\x30\x17\xe1\x7f\x76\xbf\x5d\xd9\xe3\xe0\x97\x6d\xa5\x30\xbf\xfa\xd7\x2a\xcd\xfd\x45\x29\x1e\x97\x29\xbe\xff\x05\x00\x00\xff\xff\x76\x29\x2e\xb1\x97\x03\x00\x00") + +func templatesBodyContentArticleArticleTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentArticleArticleTmpl, + "templates/body/content/article/article.tmpl", + ) +} + +func templatesBodyContentArticleArticleTmpl() (*asset, error) { + bytes, err := templatesBodyContentArticleArticleTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/article/article.tmpl", size: 919, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentArticleDisqusTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x53\x4d\x6f\x9c\x30\x10\xbd\xef\xaf\x18\x71\x31\x28\x0a\xae\x7a\x4c\x58\xaa\x36\xe9\xa1\x3d\x34\x95\x92\x5b\x55\x45\x06\x0f\xe0\xc4\x6b\xb3\xb6\xd9\x2d\x21\xfb\xdf\x3b\xac\xd9\xa8\x5f\x51\x4f\xe0\xf9\x78\xf3\xe6\xf9\x79\x9a\x24\x36\xca\x20\x24\xb5\xdd\x6c\xd0\x04\x9f\x1c\x0e\xab\x69\x52\x0d\xe4\x57\xd6\x34\xaa\xcd\xaf\x95\xdf\x0e\xfe\x56\x05\x34\x62\x83\x94\x2d\xba\xb7\xe5\xd5\x52\x5d\x70\x3a\xac\x0a\xa9\x76\xa0\xe4\x3a\x91\xc7\xda\xfb\xd0\x39\x14\x32\x29\x0b\x4e\x09\x4a\xfb\xda\xa9\x3e\x40\x18\x7b\x5c\x27\x01\x7f\x04\xfe\x20\x76\x22\x46\x93\x72\x05\xb0\x13\x0e\x96\x5e\xdf\x59\x17\xe6\x49\xb0\x06\x36\x4d\xaf\xb1\x60\x97\xd4\xc6\x39\xdc\xdd\x5c\xdf\x40\x2a\x5a\x6b\x9e\x84\xc6\x27\x67\xb3\x0b\x20\x72\xbd\x08\xaa\x52\x5a\x85\x11\xf6\x2a\x74\xb0\x19\xc1\x6a\x09\x95\xb6\x2d\x08\x17\x54\xad\xd1\x47\x80\x4f\x20\xad\x61\x01\x1e\x8d\xdd\x03\xad\xad\x02\x75\x68\x0d\x7b\xeb\x1e\xa1\xb1\x0e\x6c\xe8\xd0\xc1\xe0\xd1\xf9\xdf\x99\x2a\x49\x0a\xa8\x46\x51\x36\x52\x7d\x1f\x81\xf3\x5b\x3d\xb4\x47\x86\x54\x9f\x36\x83\xa9\x83\xb2\x26\xcd\x60\xa2\xf3\x82\xe0\xb7\xd4\x23\x6d\x3d\xcc\x2a\xe6\x35\xc9\x15\xf0\xa3\xc6\xf9\x94\xb2\x28\x0c\xcb\x2e\xe7\xba\x7c\x56\x6d\x1e\xf0\x87\x6e\x2c\x66\x85\x1f\x4d\x4d\xe9\xe0\x06\xbc\x3c\xe2\xcf\x51\xef\xe6\x18\xe3\x9c\xc1\xd9\xdf\xc2\x9e\x01\xcb\x63\x30\xa7\x5b\xe7\xb8\xa9\x50\xe6\x0f\x9e\xc5\xfe\xf4\x85\x56\x8b\x61\xe1\xe4\x3f\x8c\x77\xa2\xfd\x42\xcd\x29\xeb\xe8\x6a\x59\xf6\xed\xcd\x77\x78\x7e\x86\xff\xd4\x56\x56\x8e\xc7\xda\x2c\x17\x7d\x8f\x46\x5e\x75\x4a\xcb\x94\x28\x66\xf3\xb0\x43\x96\xd2\xb7\xe0\x71\x23\x32\x8a\xb1\xcb\xef\x57\x8d\xc2\x23\xd0\x65\x57\x1a\xe1\x33\x6d\x7d\xbb\x78\xc8\xc2\x4e\xe1\x1e\xe8\x52\xa0\x10\x40\x46\x6b\xd6\x49\x17\x42\x7f\xc1\xf9\x2f\x3b\xbd\xa3\xf8\xfd\x09\x2d\x29\x4f\xe6\x86\xde\xee\xd1\x21\x19\x61\x84\xe8\xa8\xbc\xe0\x82\x7c\xfa\x32\x78\xf5\x3a\x68\x02\xb5\x16\xde\x93\xcb\xfd\xf6\xbc\x72\x5a\x99\xc7\x7f\x23\x17\xbe\x17\xe6\x54\x4c\x8e\xb3\xe7\x11\x24\x29\xe3\x4c\x5a\x98\x0a\xca\x79\x32\x3d\x35\x52\xe5\xf8\xe4\xe2\xf7\x67\x00\x00\x00\xff\xff\x2e\x72\x91\x27\x91\x03\x00\x00") + +func templatesBodyContentArticleDisqusTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentArticleDisqusTmpl, + "templates/body/content/article/disqus.tmpl", + ) +} + +func templatesBodyContentArticleDisqusTmpl() (*asset, error) { + bytes, err := templatesBodyContentArticleDisqusTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/article/disqus.tmpl", size: 913, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentArticleShare_iconsTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\xd1\xb1\x4e\xc3\x30\x10\xc6\xf1\xbd\x4f\x61\x75\xc9\x80\x54\x5e\x20\xed\x82\x00\x21\x31\x20\xc8\x1e\x39\xf1\xc5\x39\xf5\x38\x47\xbe\xab\x0a\xb2\xfa\xee\x34\x06\xc1\x80\x3d\x65\xf8\xdf\xef\x93\x22\xa7\xe4\x60\x42\x06\xb3\x95\xd9\x46\xe8\x71\x0c\x2c\xdb\xcb\x65\x93\x12\x4e\x66\x77\x17\x78\x42\xbf\x7b\x5b\x5b\x37\xa3\xbc\x9c\x06\x42\x99\x21\x5e\x2f\xda\x21\x1e\x36\xad\x2c\x96\xcd\x48\x56\x64\xdf\x88\xf6\x79\x45\xaf\x97\x3d\xd9\xe8\xa1\x31\x0e\x65\x21\xfb\xd9\xc1\x87\xee\x9b\xdf\x9d\xe6\xd0\xde\xae\xf2\xff\xc0\x64\x47\x18\x42\x38\x16\xfd\xc3\x4f\xac\x73\x3d\xa3\x2a\xc4\xa2\xee\xce\x00\x5a\xa7\x84\x7c\x04\x87\x5c\xb4\xcf\x39\x3e\x71\x9d\xfb\x10\x3c\xc1\x42\xa7\xf2\xaf\x3f\xe6\x6c\x6e\xea\x03\x11\x9c\x43\x2d\xe2\xd7\x9c\xea\x14\xde\x2d\x52\x51\xde\xaf\xe5\x0f\xa6\x04\xec\xf2\xeb\x7e\x7f\xbf\x02\x00\x00\xff\xff\x44\xcc\xeb\xfc\xff\x01\x00\x00") + +func templatesBodyContentArticleShare_iconsTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentArticleShare_iconsTmpl, + "templates/body/content/article/share_icons.tmpl", + ) +} + +func templatesBodyContentArticleShare_iconsTmpl() (*asset, error) { + bytes, err := templatesBodyContentArticleShare_iconsTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/article/share_icons.tmpl", size: 511, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentCategoryTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x54\x50\xc1\x4e\xc4\x20\x10\xbd\xf7\x2b\x26\x64\x8f\xb6\x58\x4f\xc6\x50\x12\xe3\x27\xe8\xdd\x90\x76\x60\x49\x46\x48\x28\x6b\x62\x90\x7f\x77\xe8\xb6\xea\x9e\x66\xe6\xcd\x7b\xcc\x7b\x94\xb2\xa0\xf5\x01\x41\x64\x9f\x09\x45\xad\x5d\x29\xc3\x8b\xc9\xe8\x62\xfa\xaa\x15\xbe\xa1\xcd\x31\x58\xef\x86\xb7\x46\xd9\x18\x18\x16\xae\xdd\x9f\x7a\x8e\x21\x63\xc8\x4d\xaf\x16\xff\x09\x33\x99\x75\x9d\x36\xd8\x30\x21\xc1\x1c\xa9\xff\x58\xfa\xf1\xfe\xe8\xa2\xb5\x2b\xe6\x7e\xdc\x66\x72\xfd\xe3\xd1\xec\x8b\x07\xa1\x3b\x00\x75\x1e\xf5\x8d\x21\x25\x19\x69\x8b\x0b\xb5\x02\x6c\x2f\x99\xe0\x10\x4e\xef\x77\x70\x32\x29\xfb\x99\x10\x9e\x26\x18\x9e\xaf\xfd\xca\x96\x1a\x4f\x91\xd7\xca\xc0\x39\xa1\x9d\x44\x29\x07\x75\x78\xa5\x8b\xab\x55\xe8\x7f\xd0\x9e\x53\x49\xa3\x95\x64\xd9\x7e\xe7\x1a\x9a\x5f\x92\xed\xb6\x92\x9c\x53\xff\xfe\xc5\x4f\x00\x00\x00\xff\xff\x5e\xcf\x66\xec\x49\x01\x00\x00") + +func templatesBodyContentCategoryTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentCategoryTmpl, + "templates/body/content/category.tmpl", + ) +} + +func templatesBodyContentCategoryTmpl() (*asset, error) { + bytes, err := templatesBodyContentCategoryTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/category.tmpl", size: 329, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentIndexTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xa4\x56\x41\x4f\xdc\x3c\x10\xbd\xef\xaf\x30\xf9\x56\xdf\x01\x75\x13\xb6\xa7\xaa\x0d\x91\x10\x1c\x7a\xa8\x28\x12\xdc\x91\x37\x99\x24\x56\x1d\x27\xd8\xce\x0a\x1a\xed\x7f\xef\xd8\x71\xb2\xf6\x12\x54\x50\x0f\x90\xd8\x33\xf3\xfc\x66\xde\x8b\x61\x18\x0a\x28\x99\x00\x12\x69\xa6\x39\x44\x87\xc3\x6a\x18\xe2\xeb\x56\x94\xac\x8a\x1f\xcc\x96\xdd\x01\x51\xe0\x73\x75\xcc\xce\x5b\xa1\x41\x68\x93\x9f\x16\x6c\x4f\x72\x4e\x95\xba\xb4\xdb\x14\x13\x24\xc9\x5b\xbe\x69\x8a\xcd\xf6\x62\x7a\x6b\xcb\x52\x81\xde\x6c\xed\x9a\x57\x9b\x2f\xd3\x8b\x0b\x7c\x8e\xb2\x15\x21\xc3\xc0\x4a\x12\x5f\x49\xcd\x72\x0e\x0a\xd1\x09\x31\x9b\x92\x8a\x0a\xc8\xfa\xf1\x13\x59\xd3\x31\x46\xbe\x5e\xbe\xca\x4b\x5d\x2c\xb3\x2b\x5c\xd7\xdb\x2c\xa5\xa4\x96\x50\x5e\x46\xc3\x30\x95\xc6\xf7\xbc\xaf\x0e\x87\x28\xf3\xb6\x5c\xab\x69\x42\xb3\x34\xc1\xb2\xd5\x04\xd1\x4d\x60\x8e\x5b\x2b\xc9\x7a\x9a\xcf\x55\xaf\x6b\xb3\x9e\x40\xc6\xb5\x23\x63\xab\x55\x47\xc5\x34\x1b\x4e\x77\xc0\x89\xfd\xbd\xc1\x31\xd2\x9e\xeb\x28\xdb\xbd\x8c\xb0\xaf\x30\x3c\x6e\xc7\x2d\xe0\x0a\x6c\x28\x64\x60\x43\x46\xa1\x34\x31\x07\xfa\x8c\x9d\x70\x41\x0b\x33\xf0\x0d\xd5\xf0\x21\xb6\xe6\xe4\xef\x7d\x43\x05\xfb\x0d\xa6\x58\xb3\x06\x4e\xe1\x3e\xc8\xe1\x1a\x8b\xaa\x56\xbe\xf8\x3c\xe8\x12\x09\xd5\xe7\x39\x28\x15\x39\x39\x93\xdc\x15\x26\xde\xa4\x8e\x60\x71\xad\x1b\x1e\x28\x7c\x8c\x19\x91\xdf\x4b\xef\x81\x56\xca\xa3\x16\x38\x51\xd3\xca\xb8\xf0\xad\xdc\xe5\x36\x98\x28\xdb\xb9\x07\x44\x30\xf4\xf1\xe1\x33\xb6\xcb\x45\x92\xcb\xeb\x34\xe9\x66\xbf\xfa\x0d\x8f\x9f\xe8\xb1\xb7\xb4\x9b\x08\x69\x78\xd6\x1b\xc9\xaa\x5a\x47\xd9\x02\xdf\x9d\x16\x04\x7f\x66\xdd\xe7\x94\x69\x3a\x93\xfd\x6e\x98\x7a\xea\xd5\x3d\xc3\x73\x68\xe3\x5b\x89\xbc\xfd\xd1\xdd\x81\x6c\x28\x67\xe2\x57\x80\x3a\x3a\xfb\xef\xf5\xff\x15\xf6\xc8\x47\x8d\x71\x5a\x44\xd9\x0f\xa0\x7b\x20\xc8\xbc\x6d\x1a\x6c\xf6\x2c\x04\x0d\x86\xe6\x4d\xd4\x4e\xcc\xed\xf9\x57\x46\x5a\xcb\x6c\x75\xe2\x8a\x80\x9b\xb9\x51\x6e\x5b\x5d\x33\x51\x11\xdd\x12\x05\x40\x6a\x90\x70\x36\xde\x19\x1e\x44\x00\x80\x23\xab\x34\x89\x6f\xfb\x66\x07\xf2\x67\x79\x47\x2b\x50\xe4\xc2\x42\xfa\x97\xa7\x55\x25\xc7\x2e\x40\x3a\x59\xd2\x9e\x4f\xc1\x8e\x56\x4c\x50\xcd\x5a\x31\x4b\x96\x72\x36\x45\x43\xf7\xc2\x93\x91\xa8\x97\x12\xb1\xcc\x61\x64\x1b\x8c\x16\x47\x48\x77\x1c\x8a\x53\x3b\x85\x5e\x98\x05\x88\xef\x24\xec\x59\x8b\x3a\xa3\x02\x21\xb0\xa9\xf9\x9f\xd3\xa7\xbe\xfd\x16\x4c\x97\x33\xcf\x90\xde\x17\xd3\x19\x32\xe3\xc5\x2d\xe9\x8b\x9b\xc4\xd1\xc7\xd8\xcf\xcc\xdf\xa6\x9e\x1c\xe6\x9a\xa5\xb9\x66\x7b\x88\x1c\xeb\x05\xd2\x09\x13\x05\x3c\x5b\x28\xfc\x5b\x35\x42\x6d\xed\xbd\xd9\x59\x1c\x57\xe9\xbe\xb8\xc0\x32\x2e\x63\xd9\x34\xa6\xad\x60\x62\xf8\x4c\xce\xc9\xd8\xe0\x79\xe2\x7d\x69\xef\x56\x66\x1d\xba\xe2\x9f\x74\xba\x45\xff\xbc\xa1\x91\x5c\xd6\x68\x7c\xeb\xb9\x79\x4b\x13\xb4\xa2\x67\xdd\xb1\x37\xe4\x6c\x1b\x73\xd1\x20\xe6\xfe\x07\x18\x13\xfe\x04\x00\x00\xff\xff\xd4\x5b\x1b\x6a\x49\x08\x00\x00") + +func templatesBodyContentIndexTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentIndexTmpl, + "templates/body/content/index.tmpl", + ) +} + +func templatesBodyContentIndexTmpl() (*asset, error) { + bytes, err := templatesBodyContentIndexTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/index.tmpl", size: 2121, mode: os.FileMode(420), modTime: time.Unix(1462145951, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentPageTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x8e\x31\xce\x02\x21\x14\x84\xfb\x3d\xc5\xcb\xf6\xec\xfe\xfc\x95\x05\xd2\xec\x05\x2c\xbc\x00\x81\x07\x92\x20\x24\x42\x6c\x90\xbb\xfb\x58\x45\x13\x2b\x86\x6f\x06\x66\x6a\x35\x68\x7d\x44\x98\x8b\x2f\x01\xe7\xd6\xa6\x5a\x97\x93\x72\xb8\x9c\x3b\x68\x0d\x1e\x40\x64\x4b\xd1\x7a\x37\x18\x65\x30\x1a\x3a\xa7\xef\x7b\x9d\x62\xc1\x58\xfa\x0f\xc2\xf8\x3b\xe8\xa0\x72\x3e\xee\x58\x51\xe0\x06\x3a\x05\x76\x35\x8c\xff\x0d\x95\xac\xcd\x58\x18\xdf\xef\xc1\xb1\xc3\x10\x6f\xe3\x7f\x96\x13\x80\xb8\x70\xf9\x33\x49\xac\xc4\xc8\x1a\x78\x7b\x55\xf7\xe6\x95\xaa\xe5\x67\xde\x33\x00\x00\xff\xff\x21\x09\x94\x3e\xde\x00\x00\x00") + +func templatesBodyContentPageTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentPageTmpl, + "templates/body/content/page.tmpl", + ) +} + +func templatesBodyContentPageTmpl() (*asset, error) { + bytes, err := templatesBodyContentPageTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/page.tmpl", size: 222, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyContentTagTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x50\x41\x4e\xc4\x30\x0c\xbc\xf7\x15\x56\xb4\x47\xda\x50\x4e\x08\xb9\x91\x10\x4f\x60\xef\x28\x6a\x9d\x6e\x24\x93\x4a\x6d\x96\x4b\xc8\xdf\x71\xda\x06\x38\x65\x6c\xcf\xd8\x33\x49\x69\x22\xe7\x03\x81\x8a\x3e\x32\xa9\x9c\x9b\x94\xba\xab\x9d\x73\x86\x6f\x10\xf8\xb6\x04\xe7\xe7\xee\x5a\xa6\xfb\x90\xc2\x24\x6f\xf3\x27\x1c\x97\x10\x29\xc4\x22\xc5\xc9\x7f\xc1\xc8\x76\xdb\x86\xbd\x6d\x85\xb0\xc2\xb8\x70\xfb\x39\xb5\xfd\x63\x45\x8b\x73\x1b\xc5\xb6\xdf\x6b\x9e\xdb\xe7\x0a\xce\xc1\x93\x32\x0d\x00\xde\x7a\x53\xbd\xa0\x96\xa2\xf4\xee\x5c\x1e\x10\x67\xab\x0d\x33\xc1\xe5\xe3\x01\x2e\x76\x8d\x7e\x64\x82\x97\x01\xba\xd7\x03\x6f\xe2\xa6\xf0\x90\xbd\x41\x0b\xb7\x95\xdc\xa0\x52\xaa\xd4\xee\x9d\xef\xb2\x56\x99\x7f\xad\x33\x22\x6a\x6b\x50\x8b\xec\xbc\x73\xe4\x95\x4d\xba\xdc\x46\x2d\x11\xcd\xef\x37\xfc\x04\x00\x00\xff\xff\xb2\x22\x85\x22\x3f\x01\x00\x00") + +func templatesBodyContentTagTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyContentTagTmpl, + "templates/body/content/tag.tmpl", + ) +} + +func templatesBodyContentTagTmpl() (*asset, error) { + bytes, err := templatesBodyContentTagTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/content/tag.tmpl", size: 319, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyFooterTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\x50\xdb\x6a\x03\x21\x10\x7d\xcf\x57\x0c\xbe\x5b\x9b\x3e\x95\xb2\x91\xfe\x8a\xd1\x71\x15\x5c\x47\x74\x7a\x49\x96\xfc\x7b\x35\xc9\x96\x50\xe8\x8b\x73\x86\x33\x9c\x8b\xeb\xea\xd0\xc7\x8c\x20\x3c\x11\x63\x15\x97\xcb\x6e\x72\xf1\x13\x6c\x32\xad\x1d\x84\xa5\xcc\xa6\xf3\x15\x2c\x25\xb9\x38\xb9\x7f\xde\x10\x79\xdf\x90\xe5\xfe\xba\xa7\x59\xbe\x6e\xe0\x4e\xbc\x08\xbd\x03\x78\x14\x63\xfc\x66\x69\x31\x0f\x9f\xc1\x75\xb6\xdc\x66\x47\x06\x42\x45\x7f\x10\x81\xb9\xbc\x29\x35\x47\x0e\x1f\xc7\x27\x4b\x8b\x32\x33\xe5\xb3\x49\x78\xae\xa4\x0a\x25\x12\x7a\xbc\x93\x32\x1a\x62\x83\xc5\x38\x84\xaf\x7e\xbd\x09\xb5\x62\xf2\xe6\x38\xa7\x53\x09\xb1\x97\x80\x5f\x24\x03\x9a\xca\x42\x4f\x6a\x1c\x6a\x38\x9e\xfe\x49\xc0\x5d\xb4\x27\xfd\x1b\x41\xe8\xf7\x87\x6d\xa4\xb8\x35\x51\xd7\x2a\x93\xea\x7d\xf5\xee\x3e\xd6\x15\xb3\xeb\x3f\xfa\x13\x00\x00\xff\xff\x9c\x43\xc2\x70\x66\x01\x00\x00") + +func templatesBodyFooterTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyFooterTmpl, + "templates/body/footer.tmpl", + ) +} + +func templatesBodyFooterTmpl() (*asset, error) { + bytes, err := templatesBodyFooterTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/footer.tmpl", size: 358, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyFooter_scriptsTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x64\xce\x51\xce\x82\x30\x0c\xc0\xf1\xf7\xef\x14\x64\x07\x68\x3f\x5e\x0d\x72\x15\x33\x58\x99\x5d\x60\x9b\x6b\x4d\x34\x0b\x77\x97\x80\x89\x31\xbe\xb5\xff\x87\x5f\x5b\xab\xa3\x89\x23\x35\x66\x4a\x49\xa9\x5c\x64\x2c\x9c\x55\xcc\xba\xfe\x75\xc7\xdc\x48\x19\xcf\xe6\xaa\x9a\xe5\x84\x68\x83\x7d\x80\x4f\xc9\xcf\x64\x33\x0b\x8c\x69\xd9\x1b\xce\x3c\x08\x86\xdb\x9d\xca\x13\x5b\x68\x5b\xf8\x7f\x6f\xb0\x70\x84\x20\xa6\xef\xf0\x00\xfb\x6f\x19\xd1\x93\x0e\xdb\x75\xd1\x62\xf3\x0e\x3a\x16\xc5\x20\xf8\xa9\xbf\x46\xad\x14\xdd\xf6\xe5\x2b\x00\x00\xff\xff\xe1\xf1\x56\x06\xc2\x00\x00\x00") + +func templatesBodyFooter_scriptsTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyFooter_scriptsTmpl, + "templates/body/footer_scripts.tmpl", + ) +} + +func templatesBodyFooter_scriptsTmpl() (*asset, error) { + bytes, err := templatesBodyFooter_scriptsTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/footer_scripts.tmpl", size: 194, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesBodyNavbarTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xcc\x55\x41\x8b\xdb\x3c\x10\xbd\xef\xaf\x10\xfa\x72\xf8\x16\x1a\xfb\x5e\x1c\xc3\x76\xa1\xf4\x58\xd8\xbd\x97\x71\xac\xc8\x02\xad\x64\x64\x79\x97\x60\xfc\xdf\x3b\x92\x25\x5b\x76\x92\x92\x43\x17\x7a\x72\x34\x7a\x33\x6f\xe6\xbd\xb1\x33\x0c\x35\x3b\x09\xc5\x08\x55\xf0\x5e\x81\xa1\xe3\xf8\x50\xd4\xe2\x9d\x1c\x25\x74\xdd\x21\x44\xc9\xf4\xd8\x23\x16\x7a\x69\xe3\xb1\xb3\x60\xc5\x71\x6f\x75\x4b\x89\xd1\x92\x79\xb8\xe0\x18\xd4\x8a\x96\x0f\x84\xa4\x95\x8e\x5a\x59\x40\x26\xe3\x6f\xd6\x77\xa1\x5e\xc3\xa0\x9e\xef\x11\x51\xf5\xd6\x6a\x45\xec\xb9\xc5\xd2\xd3\x81\x6e\x52\xac\xe6\x5c\x32\x4a\x6a\xb0\x10\x0e\x8e\x4a\x4a\x68\xbb\x39\x0c\x86\x33\x7b\xa0\x59\xc8\x99\xaf\x23\x11\x52\x75\x2d\xa8\x58\xba\x33\x7b\xad\xe4\x99\x96\xaf\xbe\x1e\x59\x86\x2a\x72\x87\xbb\x91\x26\x70\xc2\xbd\x93\xb0\xfc\x4c\x58\x91\x4f\x42\xcc\x67\xd8\x28\x52\x19\x50\x35\x25\x8d\x61\xa7\x03\xcd\x69\x39\x0c\xd9\xb3\x56\x27\xc1\xb3\x57\x61\x25\x1b\xc7\x22\x87\xe0\x40\x8e\x16\x4c\x3f\x87\x41\x9c\x48\xf6\xd2\xe8\x8f\x1f\xde\x03\xdc\x82\x1b\x1e\x45\xf1\xc8\x85\x8a\xbe\x86\x36\x24\xfb\x09\x9c\x75\xe4\x7f\x6c\x83\x64\x4f\x06\x37\x44\xe2\x31\x36\xe1\x38\x9e\xcc\xb1\x11\xef\xec\x31\xb0\x20\x4f\x2f\x13\x9a\xb8\x5e\xf8\x48\x2c\x9a\x5a\xbc\xac\x32\x17\xc1\x32\x52\x94\xa8\x47\x18\x1d\xa6\xfb\xac\xb1\x6f\x92\x96\x01\xdd\xb9\xe9\x8b\x1c\x81\x49\x61\xa6\x6a\xac\x92\x04\x50\x42\xce\xc8\xee\xd7\x17\xb2\x6b\x71\x18\xf2\xf5\x10\xa6\xba\x49\xe6\x60\x5d\x3e\x0c\x1e\x9f\xbd\xc8\x9e\x8f\xa3\xd3\x7e\x3a\x27\xca\x5f\xe7\x8e\xde\xf6\x72\x51\x93\xe0\x15\x59\xfa\x8a\xf2\x4e\xba\x3e\x83\x65\x5c\x1b\xb1\x51\x76\x09\x3f\x06\xe0\x2b\xf0\x35\xc4\x05\xee\x50\x3e\xfe\x34\x82\x37\x76\x6b\xc3\x7d\x2d\xac\xc5\x8a\x34\xb5\xd1\x6d\xad\x3f\x54\xfa\xf6\x45\x19\xff\xdb\xbc\xc8\x0b\x36\x21\x2b\xaa\xf9\x93\x02\x86\x59\xf7\x82\x54\xe5\xbc\xd4\x9b\xa1\x62\x85\xfd\x1b\x53\x7d\x42\xb9\x71\xf9\x38\x95\x3f\x7b\xa7\xaf\x4e\xe0\x12\x76\x10\xb7\x19\x61\xbb\xec\xbb\x90\x96\x99\x6f\xe7\xe7\x98\x3c\x97\x59\xe5\x15\xa9\xe1\xc9\xb0\x79\x44\xbb\xb5\x59\x32\xc3\xbe\xae\x62\xeb\x4f\x43\x05\x35\xf6\xdd\xf6\x52\x46\x77\x86\x41\x32\x45\xe6\xf6\xdc\xa6\xf9\x6f\xc6\x4a\x15\xb7\x5f\xeb\x56\xd6\xdb\xb7\xde\xbf\x2d\xfa\xca\x5b\x12\x17\xe1\xea\x8a\xfd\x4d\xf3\x3d\xc1\x67\xd8\x6e\x81\x7b\xc7\x37\x0d\xff\xc1\x6b\x44\xfa\xb4\xfb\x1c\x46\xa0\x33\xd7\xe3\x17\x5f\xfd\xf1\x1f\xb2\xf4\x12\x99\xde\xac\xfe\x25\x62\x38\x04\xc3\x23\xc6\x7f\x07\x00\x00\xff\xff\x72\xd5\x84\x3f\x4d\x08\x00\x00") + +func templatesBodyNavbarTmplBytes() ([]byte, error) { + return bindataRead( + _templatesBodyNavbarTmpl, + "templates/body/navbar.tmpl", + ) +} + +func templatesBodyNavbarTmpl() (*asset, error) { + bytes, err := templatesBodyNavbarTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/body/navbar.tmpl", size: 2125, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesHeadHeaderTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\xcf\xb1\x0e\x02\x21\x10\x04\xd0\xde\xaf\x20\xdb\x0b\x26\xd7\x7a\xfe\x0b\xb2\x73\x81\x08\x8b\x61\xb7\x31\xe4\xfe\xdd\xab\xd4\x1f\xb0\x7d\x99\xcc\x64\xe6\x64\x6c\x45\xe0\x28\x23\x32\x06\xed\xfb\xe9\x5a\x8b\x3c\xdc\x40\x5d\x49\xed\x55\xa1\x19\x30\x72\x79\x60\x5b\x29\x04\x81\xb1\x44\x7f\xef\xdd\xd4\x46\x7c\x26\x16\x9f\x7a\x0b\x1f\x08\x8b\xbf\xf8\x25\x24\xd5\xaf\xf9\x56\x8e\x94\x2a\xdd\xfe\x52\x7f\xb6\x8c\x86\x9f\x91\x39\x21\x7c\x7c\x79\x07\x00\x00\xff\xff\xe8\x1b\x48\x83\xe0\x00\x00\x00") + +func templatesHeadHeaderTmplBytes() ([]byte, error) { + return bindataRead( + _templatesHeadHeaderTmpl, + "templates/head/header.tmpl", + ) +} + +func templatesHeadHeaderTmpl() (*asset, error) { + bytes, err := templatesHeadHeaderTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/head/header.tmpl", size: 224, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesHeadHeader_scriptsTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xaa\xae\x4e\x49\x4d\xcb\xcc\x4b\x55\x50\xca\x48\x4d\x4c\x49\x2d\x8a\x2f\x4e\x2e\xca\x2c\x28\x29\x56\xaa\xad\xe5\xaa\xae\xd6\xd7\x52\xf0\x2a\x2d\x2e\x51\x48\x54\x28\xc8\x49\x4c\x4e\xcd\xc8\xcf\x01\x2a\x51\xd0\xd2\x07\x4b\xa6\xe6\xa5\x00\x69\x40\x00\x00\x00\xff\xff\x9f\x23\x5e\xcf\x41\x00\x00\x00") + +func templatesHeadHeader_scriptsTmplBytes() ([]byte, error) { + return bindataRead( + _templatesHeadHeader_scriptsTmpl, + "templates/head/header_scripts.tmpl", + ) +} + +func templatesHeadHeader_scriptsTmpl() (*asset, error) { + bytes, err := templatesHeadHeader_scriptsTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/head/header_scripts.tmpl", size: 65, mode: os.FileMode(420), modTime: time.Unix(1461591613, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesHeadShare_thisTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x90\x3d\x4f\xc3\x30\x10\x86\x77\x7e\xc5\xc9\x13\x48\xc8\x9e\x58\xda\x26\x12\x74\x61\x40\x08\x89\xee\xc8\x8d\x2f\xb5\xab\x12\x5b\xbe\x4b\x3f\x74\xca\x7f\x27\x69\x42\x46\xe8\x74\xd2\xfb\x9c\x4f\xcf\x6b\x11\x87\x75\x68\x10\x14\x79\x9b\xf1\x8b\x7d\x20\xd5\x75\x77\x22\xa1\x06\xbd\x8e\x4d\x1d\x76\xfa\x73\x40\x9b\x9e\x7c\xb4\xdb\x43\x20\x8f\xb9\xdf\x00\x58\x51\x95\x43\x62\xe0\x4b\xc2\x42\x31\x9e\xd9\xec\xed\xd1\x8e\xa9\x2a\x8f\x36\x03\x9d\x02\x57\x7e\x13\x9f\xce\x05\xe7\x16\x97\x2b\x33\xd2\xf2\xdf\xe7\x40\xb9\x2a\x94\x31\x27\x7d\x15\x1b\xbc\x74\x15\xbf\xcd\xb6\x65\x8e\xcd\x34\x48\xef\x49\x95\xb7\x1f\x1d\x36\x00\x88\xdf\xc2\xce\xb3\x8e\x89\x43\x7f\xe3\x5e\xd2\x6f\xad\x05\x28\x91\xbf\x5a\xab\x47\x70\xf1\x3d\xf2\xab\x25\xbf\x80\xda\x1e\x08\xa7\x64\x1d\xd3\x65\x4e\x7c\x8f\x9f\x9d\xcb\x48\xf4\x62\xf3\x14\x77\x0f\xcb\x41\x70\x96\x15\xc1\xc6\x5d\xbf\x7a\x9c\x3f\x01\x00\x00\xff\xff\xc1\x4a\xda\x05\x8b\x01\x00\x00") + +func templatesHeadShare_thisTmplBytes() ([]byte, error) { + return bindataRead( + _templatesHeadShare_thisTmpl, + "templates/head/share_this.tmpl", + ) +} + +func templatesHeadShare_thisTmpl() (*asset, error) { + bytes, err := templatesHeadShare_thisTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/head/share_this.tmpl", size: 395, mode: os.FileMode(420), modTime: time.Unix(1461591614, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "templates/atom.tmpl": templatesAtomTmpl, + "templates/base.tmpl": templatesBaseTmpl, + "templates/body/analytics.tmpl": templatesBodyAnalyticsTmpl, + "templates/body/content/archive.tmpl": templatesBodyContentArchiveTmpl, + "templates/body/content/article/article.tmpl": templatesBodyContentArticleArticleTmpl, + "templates/body/content/article/disqus.tmpl": templatesBodyContentArticleDisqusTmpl, + "templates/body/content/article/share_icons.tmpl": templatesBodyContentArticleShare_iconsTmpl, + "templates/body/content/category.tmpl": templatesBodyContentCategoryTmpl, + "templates/body/content/index.tmpl": templatesBodyContentIndexTmpl, + "templates/body/content/page.tmpl": templatesBodyContentPageTmpl, + "templates/body/content/tag.tmpl": templatesBodyContentTagTmpl, + "templates/body/footer.tmpl": templatesBodyFooterTmpl, + "templates/body/footer_scripts.tmpl": templatesBodyFooter_scriptsTmpl, + "templates/body/navbar.tmpl": templatesBodyNavbarTmpl, + "templates/head/header.tmpl": templatesHeadHeaderTmpl, + "templates/head/header_scripts.tmpl": templatesHeadHeader_scriptsTmpl, + "templates/head/share_this.tmpl": templatesHeadShare_thisTmpl, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} +var _bintree = &bintree{nil, map[string]*bintree{ + "templates": &bintree{nil, map[string]*bintree{ + "atom.tmpl": &bintree{templatesAtomTmpl, map[string]*bintree{}}, + "base.tmpl": &bintree{templatesBaseTmpl, map[string]*bintree{}}, + "body": &bintree{nil, map[string]*bintree{ + "analytics.tmpl": &bintree{templatesBodyAnalyticsTmpl, map[string]*bintree{}}, + "content": &bintree{nil, map[string]*bintree{ + "archive.tmpl": &bintree{templatesBodyContentArchiveTmpl, map[string]*bintree{}}, + "article": &bintree{nil, map[string]*bintree{ + "article.tmpl": &bintree{templatesBodyContentArticleArticleTmpl, map[string]*bintree{}}, + "disqus.tmpl": &bintree{templatesBodyContentArticleDisqusTmpl, map[string]*bintree{}}, + "share_icons.tmpl": &bintree{templatesBodyContentArticleShare_iconsTmpl, map[string]*bintree{}}, + }}, + "category.tmpl": &bintree{templatesBodyContentCategoryTmpl, map[string]*bintree{}}, + "index.tmpl": &bintree{templatesBodyContentIndexTmpl, map[string]*bintree{}}, + "page.tmpl": &bintree{templatesBodyContentPageTmpl, map[string]*bintree{}}, + "tag.tmpl": &bintree{templatesBodyContentTagTmpl, map[string]*bintree{}}, + }}, + "footer.tmpl": &bintree{templatesBodyFooterTmpl, map[string]*bintree{}}, + "footer_scripts.tmpl": &bintree{templatesBodyFooter_scriptsTmpl, map[string]*bintree{}}, + "navbar.tmpl": &bintree{templatesBodyNavbarTmpl, map[string]*bintree{}}, + }}, + "head": &bintree{nil, map[string]*bintree{ + "header.tmpl": &bintree{templatesHeadHeaderTmpl, map[string]*bintree{}}, + "header_scripts.tmpl": &bintree{templatesHeadHeader_scriptsTmpl, map[string]*bintree{}}, + "share_this.tmpl": &bintree{templatesHeadShare_thisTmpl, map[string]*bintree{}}, + }}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} + diff --git a/src/templates/templates/atom.xml b/templates/atom.tmpl similarity index 63% rename from src/templates/templates/atom.xml rename to templates/atom.tmpl index d0ec88d..27cd333 100644 --- a/src/templates/templates/atom.xml +++ b/templates/atom.tmpl @@ -1,25 +1,27 @@ +{{define "base"}} - {{.Site.Config.Title}} - + {{.Config.Title}} + {{.Updated}} {{if .Articles}} {{range $_, $article := .Articles}} {{$article.Title}} - + {{if $article.Date}} {{$article.Date}} {{end}} - {{$article.HTML $article.Summary}} + {{$article.Summary}} - {{$.Site.Config.Author}} + {{$.Config.Author}} {{end}} {{end}} +{{end}} diff --git a/templates/base.tmpl b/templates/base.tmpl new file mode 100644 index 0000000..12fa1a4 --- /dev/null +++ b/templates/base.tmpl @@ -0,0 +1,30 @@ +{{define "base"}} + + + + + + + + {{if .Config.Favicon}} + + {{end}} + + {{block "title" .}}{{end}} + + {{block "header" .}}{{end}} + {{block "header_scripts" .}}{{end}} + {{block "share_this" .}}{{end}} + + + + + + {{block "navbar" .}}{{end}} + {{block "content" .}}{{end}} + {{block "footer" .}}{{end}} + {{block "footer_scripts" .}}{{end}} + {{block "analytics" .}}{{end}} + + +{{end}} diff --git a/src/templates/base/analytics.html b/templates/body/analytics.tmpl similarity index 81% rename from src/templates/base/analytics.html rename to templates/body/analytics.tmpl index 06c2895..b5ccbd7 100644 --- a/src/templates/base/analytics.html +++ b/templates/body/analytics.tmpl @@ -1,8 +1,8 @@ {{define "analytics"}} - {{if .Site.Config.GoogleAnalyticsID}} +{{if .Config.GoogleAnalyticsID}} + +{{end}} diff --git a/templates/body/navbar.tmpl b/templates/body/navbar.tmpl new file mode 100644 index 0000000..2bdddb3 --- /dev/null +++ b/templates/body/navbar.tmpl @@ -0,0 +1,62 @@ +{{define "navbar"}} + +{{end}} diff --git a/templates/head/header.tmpl b/templates/head/header.tmpl new file mode 100644 index 0000000..5da70ef --- /dev/null +++ b/templates/head/header.tmpl @@ -0,0 +1,4 @@ +{{define "header"}} + + +{{end}} diff --git a/templates/head/header_scripts.tmpl b/templates/head/header_scripts.tmpl new file mode 100644 index 0000000..55b768d --- /dev/null +++ b/templates/head/header_scripts.tmpl @@ -0,0 +1,3 @@ +{{define "header_scripts"}} +{{/* Just a placeholder */}} +{{end}} diff --git a/templates/head/share_this.tmpl b/templates/head/share_this.tmpl new file mode 100644 index 0000000..699dea8 --- /dev/null +++ b/templates/head/share_this.tmpl @@ -0,0 +1,9 @@ +{{define "share_this"}} +{{if .Config.ShareThisPublisher}} + + + +{{end}} +{{end}} diff --git a/src/utils/utils.go b/utils/utils.go similarity index 100% rename from src/utils/utils.go rename to utils/utils.go diff --git a/src/utils/utils_test.go b/utils/utils_test.go similarity index 100% rename from src/utils/utils_test.go rename to utils/utils_test.go diff --git a/vendor/manifest b/vendor/manifest deleted file mode 100644 index e7a70be..0000000 --- a/vendor/manifest +++ /dev/null @@ -1,29 +0,0 @@ -{ - "version": 0, - "dependencies": [ - { - "importpath": "github.com/jessevdk/go-flags", - "repository": "https://github.com/jessevdk/go-flags", - "revision": "1acbbaff2f347c412a0c7884873bd72cc9c1f5b4", - "branch": "master" - }, - { - "importpath": "github.com/russross/blackfriday", - "repository": "https://github.com/russross/blackfriday", - "revision": "8cec3a854e68dba10faabbe31c089abf4a3e57a6", - "branch": "master" - }, - { - "importpath": "github.com/shurcooL/sanitized_anchor_name", - "repository": "https://github.com/shurcooL/sanitized_anchor_name", - "revision": "244f5ac324cb97e1987ef901a0081a77bfd8e845", - "branch": "master" - }, - { - "importpath": "gopkg.in/fsnotify.v1", - "repository": "https://gopkg.in/fsnotify.v1", - "revision": "96c060f6a6b7e0d6f75fddd10efeaca3e5d1bcb0", - "branch": "master" - } - ] -} \ No newline at end of file diff --git a/vendor/src/github.com/jessevdk/go-flags/LICENSE b/vendor/src/github.com/jessevdk/go-flags/LICENSE deleted file mode 100644 index bcca0d5..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2012 Jesse van den Kieboom. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/src/github.com/jessevdk/go-flags/README.md b/vendor/src/github.com/jessevdk/go-flags/README.md deleted file mode 100644 index b6faef6..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/README.md +++ /dev/null @@ -1,131 +0,0 @@ -go-flags: a go library for parsing command line arguments -========================================================= - -[![GoDoc](https://godoc.org/github.com/jessevdk/go-flags?status.png)](https://godoc.org/github.com/jessevdk/go-flags) [![Build Status](https://travis-ci.org/jessevdk/go-flags.svg?branch=master)](https://travis-ci.org/jessevdk/go-flags) [![Coverage Status](https://img.shields.io/coveralls/jessevdk/go-flags.svg)](https://coveralls.io/r/jessevdk/go-flags?branch=master) - -This library provides similar functionality to the builtin flag library of -go, but provides much more functionality and nicer formatting. From the -documentation: - -Package flags provides an extensive command line option parser. -The flags package is similar in functionality to the go builtin flag package -but provides more options and uses reflection to provide a convenient and -succinct way of specifying command line options. - -Supported features: -* Options with short names (-v) -* Options with long names (--verbose) -* Options with and without arguments (bool v.s. other type) -* Options with optional arguments and default values -* Multiple option groups each containing a set of options -* Generate and print well-formatted help message -* Passing remaining command line arguments after -- (optional) -* Ignoring unknown command line options (optional) -* Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification -* Supports multiple short options -aux -* Supports all primitive go types (string, int{8..64}, uint{8..64}, float) -* Supports same option multiple times (can store in slice or last option counts) -* Supports maps -* Supports function callbacks -* Supports namespaces for (nested) option groups - -The flags package uses structs, reflection and struct field tags -to allow users to specify command line options. This results in very simple -and concise specification of your application options. For example: - - type Options struct { - Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` - } - -This specifies one option with a short name -v and a long name --verbose. -When either -v or --verbose is found on the command line, a 'true' value -will be appended to the Verbose field. e.g. when specifying -vvv, the -resulting value of Verbose will be {[true, true, true]}. - -Example: --------- - var opts struct { - // Slice of bool will append 'true' each time the option - // is encountered (can be set multiple times, like -vvv) - Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` - - // Example of automatic marshalling to desired type (uint) - Offset uint `long:"offset" description:"Offset"` - - // Example of a callback, called each time the option is found. - Call func(string) `short:"c" description:"Call phone number"` - - // Example of a required flag - Name string `short:"n" long:"name" description:"A name" required:"true"` - - // Example of a value name - File string `short:"f" long:"file" description:"A file" value-name:"FILE"` - - // Example of a pointer - Ptr *int `short:"p" description:"A pointer to an integer"` - - // Example of a slice of strings - StringSlice []string `short:"s" description:"A slice of strings"` - - // Example of a slice of pointers - PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` - - // Example of a map - IntMap map[string]int `long:"intmap" description:"A map from string to int"` - } - - // Callback which will invoke callto: to call a number. - // Note that this works just on OS X (and probably only with - // Skype) but it shows the idea. - opts.Call = func(num string) { - cmd := exec.Command("open", "callto:"+num) - cmd.Start() - cmd.Process.Release() - } - - // Make some fake arguments to parse. - args := []string{ - "-vv", - "--offset=5", - "-n", "Me", - "-p", "3", - "-s", "hello", - "-s", "world", - "--ptrslice", "hello", - "--ptrslice", "world", - "--intmap", "a:1", - "--intmap", "b:5", - "arg1", - "arg2", - "arg3", - } - - // Parse flags from `args'. Note that here we use flags.ParseArgs for - // the sake of making a working example. Normally, you would simply use - // flags.Parse(&opts) which uses os.Args - args, err := flags.ParseArgs(&opts, args) - - if err != nil { - panic(err) - os.Exit(1) - } - - fmt.Printf("Verbosity: %v\n", opts.Verbose) - fmt.Printf("Offset: %d\n", opts.Offset) - fmt.Printf("Name: %s\n", opts.Name) - fmt.Printf("Ptr: %d\n", *opts.Ptr) - fmt.Printf("StringSlice: %v\n", opts.StringSlice) - fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1]) - fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"]) - fmt.Printf("Remaining args: %s\n", strings.Join(args, " ")) - - // Output: Verbosity: [true true] - // Offset: 5 - // Name: Me - // Ptr: 3 - // StringSlice: [hello world] - // PtrSlice: [hello world] - // IntMap: [a:1 b:5] - // Remaining args: arg1 arg2 arg3 - -More information can be found in the godocs: diff --git a/vendor/src/github.com/jessevdk/go-flags/arg.go b/vendor/src/github.com/jessevdk/go-flags/arg.go deleted file mode 100644 index fd8db9c..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/arg.go +++ /dev/null @@ -1,21 +0,0 @@ -package flags - -import ( - "reflect" -) - -// Arg represents a positional argument on the command line. -type Arg struct { - // The name of the positional argument (used in the help) - Name string - - // A description of the positional argument (used in the help) - Description string - - value reflect.Value - tag multiTag -} - -func (a *Arg) isRemaining() bool { - return a.value.Type().Kind() == reflect.Slice -} diff --git a/vendor/src/github.com/jessevdk/go-flags/arg_test.go b/vendor/src/github.com/jessevdk/go-flags/arg_test.go deleted file mode 100644 index faea280..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/arg_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestPositional(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Positional struct { - Command int - Filename string - Rest []string - } `positional-args:"yes" required:"yes"` - }{} - - p := NewParser(&opts, Default) - ret, err := p.ParseArgs([]string{"10", "arg_test.go", "a", "b"}) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - if opts.Positional.Command != 10 { - t.Fatalf("Expected opts.Positional.Command to be 10, but got %v", opts.Positional.Command) - } - - if opts.Positional.Filename != "arg_test.go" { - t.Fatalf("Expected opts.Positional.Filename to be \"arg_test.go\", but got %v", opts.Positional.Filename) - } - - assertStringArray(t, opts.Positional.Rest, []string{"a", "b"}) - assertStringArray(t, ret, []string{}) -} - -func TestPositionalRequired(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Positional struct { - Command int - Filename string - Rest []string - } `positional-args:"yes" required:"yes"` - }{} - - p := NewParser(&opts, None) - _, err := p.ParseArgs([]string{"10"}) - - assertError(t, err, ErrRequired, "the required argument `Filename` was not provided") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/assert_test.go b/vendor/src/github.com/jessevdk/go-flags/assert_test.go deleted file mode 100644 index 8e06636..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/assert_test.go +++ /dev/null @@ -1,177 +0,0 @@ -package flags - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path" - "runtime" - "testing" -) - -func assertCallerInfo() (string, int) { - ptr := make([]uintptr, 15) - n := runtime.Callers(1, ptr) - - if n == 0 { - return "", 0 - } - - mef := runtime.FuncForPC(ptr[0]) - mefile, meline := mef.FileLine(ptr[0]) - - for i := 2; i < n; i++ { - f := runtime.FuncForPC(ptr[i]) - file, line := f.FileLine(ptr[i]) - - if file != mefile { - return file, line - } - } - - return mefile, meline -} - -func assertErrorf(t *testing.T, format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - - file, line := assertCallerInfo() - - t.Errorf("%s:%d: %s", path.Base(file), line, msg) -} - -func assertFatalf(t *testing.T, format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - - file, line := assertCallerInfo() - - t.Fatalf("%s:%d: %s", path.Base(file), line, msg) -} - -func assertString(t *testing.T, a string, b string) { - if a != b { - assertErrorf(t, "Expected %#v, but got %#v", b, a) - } -} - -func assertStringArray(t *testing.T, a []string, b []string) { - if len(a) != len(b) { - assertErrorf(t, "Expected %#v, but got %#v", b, a) - return - } - - for i, v := range a { - if b[i] != v { - assertErrorf(t, "Expected %#v, but got %#v", b, a) - return - } - } -} - -func assertBoolArray(t *testing.T, a []bool, b []bool) { - if len(a) != len(b) { - assertErrorf(t, "Expected %#v, but got %#v", b, a) - return - } - - for i, v := range a { - if b[i] != v { - assertErrorf(t, "Expected %#v, but got %#v", b, a) - return - } - } -} - -func assertParserSuccess(t *testing.T, data interface{}, args ...string) (*Parser, []string) { - parser := NewParser(data, Default&^PrintErrors) - ret, err := parser.ParseArgs(args) - - if err != nil { - t.Fatalf("Unexpected parse error: %s", err) - return nil, nil - } - - return parser, ret -} - -func assertParseSuccess(t *testing.T, data interface{}, args ...string) []string { - _, ret := assertParserSuccess(t, data, args...) - return ret -} - -func assertError(t *testing.T, err error, typ ErrorType, msg string) { - if err == nil { - assertFatalf(t, "Expected error: %s", msg) - return - } - - if e, ok := err.(*Error); !ok { - assertFatalf(t, "Expected Error type, but got %#v", err) - } else { - if e.Type != typ { - assertErrorf(t, "Expected error type {%s}, but got {%s}", typ, e.Type) - } - - if e.Message != msg { - assertErrorf(t, "Expected error message %#v, but got %#v", msg, e.Message) - } - } -} - -func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{}, args ...string) []string { - parser := NewParser(data, Default&^PrintErrors) - ret, err := parser.ParseArgs(args) - - assertError(t, err, typ, msg) - return ret -} - -func diff(a, b string) (string, error) { - atmp, err := ioutil.TempFile("", "help-diff") - - if err != nil { - return "", err - } - - btmp, err := ioutil.TempFile("", "help-diff") - - if err != nil { - return "", err - } - - if _, err := io.WriteString(atmp, a); err != nil { - return "", err - } - - if _, err := io.WriteString(btmp, b); err != nil { - return "", err - } - - ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output() - - os.Remove(atmp.Name()) - os.Remove(btmp.Name()) - - if err.Error() == "exit status 1" { - return string(ret), nil - } - - return string(ret), err -} - -func assertDiff(t *testing.T, actual, expected, msg string) { - if actual == expected { - return - } - - ret, err := diff(actual, expected) - - if err != nil { - assertErrorf(t, "Unexpected diff error: %s", err) - assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual) - } else { - assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret) - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/check_crosscompile.sh b/vendor/src/github.com/jessevdk/go-flags/check_crosscompile.sh deleted file mode 100644 index c494f61..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/check_crosscompile.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -e - -echo '# linux arm7' -GOARM=7 GOARCH=arm GOOS=linux go build -echo '# linux arm5' -GOARM=5 GOARCH=arm GOOS=linux go build -echo '# windows 386' -GOARCH=386 GOOS=windows go build -echo '# windows amd64' -GOARCH=amd64 GOOS=windows go build -echo '# darwin' -GOARCH=amd64 GOOS=darwin go build -echo '# freebsd' -GOARCH=amd64 GOOS=freebsd go build diff --git a/vendor/src/github.com/jessevdk/go-flags/closest.go b/vendor/src/github.com/jessevdk/go-flags/closest.go deleted file mode 100644 index 3b51875..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/closest.go +++ /dev/null @@ -1,59 +0,0 @@ -package flags - -func levenshtein(s string, t string) int { - if len(s) == 0 { - return len(t) - } - - if len(t) == 0 { - return len(s) - } - - dists := make([][]int, len(s)+1) - for i := range dists { - dists[i] = make([]int, len(t)+1) - dists[i][0] = i - } - - for j := range t { - dists[0][j] = j - } - - for i, sc := range s { - for j, tc := range t { - if sc == tc { - dists[i+1][j+1] = dists[i][j] - } else { - dists[i+1][j+1] = dists[i][j] + 1 - if dists[i+1][j] < dists[i+1][j+1] { - dists[i+1][j+1] = dists[i+1][j] + 1 - } - if dists[i][j+1] < dists[i+1][j+1] { - dists[i+1][j+1] = dists[i][j+1] + 1 - } - } - } - } - - return dists[len(s)][len(t)] -} - -func closestChoice(cmd string, choices []string) (string, int) { - if len(choices) == 0 { - return "", 0 - } - - mincmd := -1 - mindist := -1 - - for i, c := range choices { - l := levenshtein(cmd, c) - - if mincmd < 0 || l < mindist { - mindist = l - mincmd = i - } - } - - return choices[mincmd], mindist -} diff --git a/vendor/src/github.com/jessevdk/go-flags/command.go b/vendor/src/github.com/jessevdk/go-flags/command.go deleted file mode 100644 index 13332ae..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/command.go +++ /dev/null @@ -1,106 +0,0 @@ -package flags - -// Command represents an application command. Commands can be added to the -// parser (which itself is a command) and are selected/executed when its name -// is specified on the command line. The Command type embeds a Group and -// therefore also carries a set of command specific options. -type Command struct { - // Embedded, see Group for more information - *Group - - // The name by which the command can be invoked - Name string - - // The active sub command (set by parsing) or nil - Active *Command - - // Whether subcommands are optional - SubcommandsOptional bool - - // Aliases for the command - Aliases []string - - // Whether positional arguments are required - ArgsRequired bool - - commands []*Command - hasBuiltinHelpGroup bool - args []*Arg -} - -// Commander is an interface which can be implemented by any command added in -// the options. When implemented, the Execute method will be called for the last -// specified (sub)command providing the remaining command line arguments. -type Commander interface { - // Execute will be called for the last active (sub)command. The - // args argument contains the remaining command line arguments. The - // error that Execute returns will be eventually passed out of the - // Parse method of the Parser. - Execute(args []string) error -} - -// Usage is an interface which can be implemented to show a custom usage string -// in the help message shown for a command. -type Usage interface { - // Usage is called for commands to allow customized printing of command - // usage in the generated help message. - Usage() string -} - -// AddCommand adds a new command to the parser with the given name and data. The -// data needs to be a pointer to a struct from which the fields indicate which -// options are in the command. The provided data can implement the Command and -// Usage interfaces. -func (c *Command) AddCommand(command string, shortDescription string, longDescription string, data interface{}) (*Command, error) { - cmd := newCommand(command, shortDescription, longDescription, data) - - cmd.parent = c - - if err := cmd.scan(); err != nil { - return nil, err - } - - c.commands = append(c.commands, cmd) - return cmd, nil -} - -// AddGroup adds a new group to the command with the given name and data. The -// data needs to be a pointer to a struct from which the fields indicate which -// options are in the group. -func (c *Command) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) { - group := newGroup(shortDescription, longDescription, data) - - group.parent = c - - if err := group.scanType(c.scanSubcommandHandler(group)); err != nil { - return nil, err - } - - c.groups = append(c.groups, group) - return group, nil -} - -// Commands returns a list of subcommands of this command. -func (c *Command) Commands() []*Command { - return c.commands -} - -// Find locates the subcommand with the given name and returns it. If no such -// command can be found Find will return nil. -func (c *Command) Find(name string) *Command { - for _, cc := range c.commands { - if cc.match(name) { - return cc - } - } - - return nil -} - -// Args returns a list of positional arguments associated with this command. -func (c *Command) Args() []*Arg { - ret := make([]*Arg, len(c.args)) - copy(ret, c.args) - - return ret -} diff --git a/vendor/src/github.com/jessevdk/go-flags/command_private.go b/vendor/src/github.com/jessevdk/go-flags/command_private.go deleted file mode 100644 index 82ce793..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/command_private.go +++ /dev/null @@ -1,271 +0,0 @@ -package flags - -import ( - "reflect" - "sort" - "strings" - "unsafe" -) - -type lookup struct { - shortNames map[string]*Option - longNames map[string]*Option - - commands map[string]*Command -} - -func newCommand(name string, shortDescription string, longDescription string, data interface{}) *Command { - return &Command{ - Group: newGroup(shortDescription, longDescription, data), - Name: name, - } -} - -func (c *Command) scanSubcommandHandler(parentg *Group) scanHandler { - f := func(realval reflect.Value, sfield *reflect.StructField) (bool, error) { - mtag := newMultiTag(string(sfield.Tag)) - - if err := mtag.Parse(); err != nil { - return true, err - } - - positional := mtag.Get("positional-args") - - if len(positional) != 0 { - stype := realval.Type() - - for i := 0; i < stype.NumField(); i++ { - field := stype.Field(i) - - m := newMultiTag((string(field.Tag))) - - if err := m.Parse(); err != nil { - return true, err - } - - name := m.Get("positional-arg-name") - - if len(name) == 0 { - name = field.Name - } - - arg := &Arg{ - Name: name, - Description: m.Get("description"), - - value: realval.Field(i), - tag: m, - } - - c.args = append(c.args, arg) - - if len(mtag.Get("required")) != 0 { - c.ArgsRequired = true - } - } - - return true, nil - } - - subcommand := mtag.Get("command") - - if len(subcommand) != 0 { - ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr())) - - shortDescription := mtag.Get("description") - longDescription := mtag.Get("long-description") - subcommandsOptional := mtag.Get("subcommands-optional") - aliases := mtag.GetMany("alias") - - subc, err := c.AddCommand(subcommand, shortDescription, longDescription, ptrval.Interface()) - - if err != nil { - return true, err - } - - if len(subcommandsOptional) > 0 { - subc.SubcommandsOptional = true - } - - if len(aliases) > 0 { - subc.Aliases = aliases - } - - return true, nil - } - - return parentg.scanSubGroupHandler(realval, sfield) - } - - return f -} - -func (c *Command) scan() error { - return c.scanType(c.scanSubcommandHandler(c.Group)) -} - -func (c *Command) eachCommand(f func(*Command), recurse bool) { - f(c) - - for _, cc := range c.commands { - if recurse { - cc.eachCommand(f, true) - } else { - f(cc) - } - } -} - -func (c *Command) eachActiveGroup(f func(cc *Command, g *Group)) { - c.eachGroup(func(g *Group) { - f(c, g) - }) - - if c.Active != nil { - c.Active.eachActiveGroup(f) - } -} - -func (c *Command) addHelpGroups(showHelp func() error) { - if !c.hasBuiltinHelpGroup { - c.addHelpGroup(showHelp) - c.hasBuiltinHelpGroup = true - } - - for _, cc := range c.commands { - cc.addHelpGroups(showHelp) - } -} - -func (c *Command) makeLookup() lookup { - ret := lookup{ - shortNames: make(map[string]*Option), - longNames: make(map[string]*Option), - commands: make(map[string]*Command), - } - - parent := c.parent - - for parent != nil { - if cmd, ok := parent.(*Command); ok { - cmd.fillLookup(&ret, true) - } - - if grp, ok := parent.(*Group); ok { - parent = grp - } else { - parent = nil - } - } - - c.fillLookup(&ret, false) - return ret -} - -func (c *Command) fillLookup(ret *lookup, onlyOptions bool) { - c.eachGroup(func(g *Group) { - for _, option := range g.options { - if option.ShortName != 0 { - ret.shortNames[string(option.ShortName)] = option - } - - if len(option.LongName) > 0 { - ret.longNames[option.LongNameWithNamespace()] = option - } - } - }) - - if onlyOptions { - return - } - - for _, subcommand := range c.commands { - ret.commands[subcommand.Name] = subcommand - - for _, a := range subcommand.Aliases { - ret.commands[a] = subcommand - } - } -} - -func (c *Command) groupByName(name string) *Group { - if grp := c.Group.groupByName(name); grp != nil { - return grp - } - - for _, subc := range c.commands { - prefix := subc.Name + "." - - if strings.HasPrefix(name, prefix) { - if grp := subc.groupByName(name[len(prefix):]); grp != nil { - return grp - } - } else if name == subc.Name { - return subc.Group - } - } - - return nil -} - -type commandList []*Command - -func (c commandList) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -func (c commandList) Len() int { - return len(c) -} - -func (c commandList) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -func (c *Command) sortedCommands() []*Command { - ret := make(commandList, len(c.commands)) - copy(ret, c.commands) - - sort.Sort(ret) - return []*Command(ret) -} - -func (c *Command) match(name string) bool { - if c.Name == name { - return true - } - - for _, v := range c.Aliases { - if v == name { - return true - } - } - - return false -} - -func (c *Command) hasCliOptions() bool { - ret := false - - c.eachGroup(func(g *Group) { - if g.isBuiltinHelp { - return - } - - for _, opt := range g.options { - if opt.canCli() { - ret = true - } - } - }) - - return ret -} - -func (c *Command) fillParseState(s *parseState) { - s.positional = make([]*Arg, len(c.args)) - copy(s.positional, c.args) - - s.lookup = c.makeLookup() - s.command = c -} diff --git a/vendor/src/github.com/jessevdk/go-flags/command_test.go b/vendor/src/github.com/jessevdk/go-flags/command_test.go deleted file mode 100644 index 1d904ae..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/command_test.go +++ /dev/null @@ -1,402 +0,0 @@ -package flags - -import ( - "fmt" - "testing" -) - -func TestCommandInline(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command struct { - G bool `short:"g"` - } `command:"cmd"` - }{} - - p, ret := assertParserSuccess(t, &opts, "-v", "cmd", "-g") - - assertStringArray(t, ret, []string{}) - - if p.Active == nil { - t.Errorf("Expected active command") - } - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.Command.G { - t.Errorf("Expected Command.G to be true") - } - - if p.Command.Find("cmd") != p.Active { - t.Errorf("Expected to find command `cmd' to be active") - } -} - -func TestCommandInlineMulti(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - C1 struct { - } `command:"c1"` - - C2 struct { - G bool `short:"g"` - } `command:"c2"` - }{} - - p, ret := assertParserSuccess(t, &opts, "-v", "c2", "-g") - - assertStringArray(t, ret, []string{}) - - if p.Active == nil { - t.Errorf("Expected active command") - } - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.C2.G { - t.Errorf("Expected C2.G to be true") - } - - if p.Command.Find("c1") == nil { - t.Errorf("Expected to find command `c1'") - } - - if c2 := p.Command.Find("c2"); c2 == nil { - t.Errorf("Expected to find command `c2'") - } else if c2 != p.Active { - t.Errorf("Expected to find command `c2' to be active") - } -} - -func TestCommandFlagOrder1(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command struct { - G bool `short:"g"` - } `command:"cmd"` - }{} - - assertParseFail(t, ErrUnknownFlag, "unknown flag `g'", &opts, "-v", "-g", "cmd") -} - -func TestCommandFlagOrder2(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command struct { - G bool `short:"g"` - } `command:"cmd"` - }{} - - assertParseSuccess(t, &opts, "cmd", "-v", "-g") - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.Command.G { - t.Errorf("Expected Command.G to be true") - } -} - -func TestCommandFlagOverride1(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command struct { - Value bool `short:"v"` - } `command:"cmd"` - }{} - - assertParseSuccess(t, &opts, "-v", "cmd") - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if opts.Command.Value { - t.Errorf("Expected Command.Value to be false") - } -} - -func TestCommandFlagOverride2(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command struct { - Value bool `short:"v"` - } `command:"cmd"` - }{} - - assertParseSuccess(t, &opts, "cmd", "-v") - - if opts.Value { - t.Errorf("Expected Value to be false") - } - - if !opts.Command.Value { - t.Errorf("Expected Command.Value to be true") - } -} - -func TestCommandEstimate(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Cmd1 struct { - } `command:"remove"` - - Cmd2 struct { - } `command:"add"` - }{} - - p := NewParser(&opts, None) - _, err := p.ParseArgs([]string{}) - - assertError(t, err, ErrCommandRequired, "Please specify one command of: add or remove") -} - -func TestCommandEstimate2(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Cmd1 struct { - } `command:"remove"` - - Cmd2 struct { - } `command:"add"` - }{} - - p := NewParser(&opts, None) - _, err := p.ParseArgs([]string{"rmive"}) - - assertError(t, err, ErrUnknownCommand, "Unknown command `rmive', did you mean `remove'?") -} - -type testCommand struct { - G bool `short:"g"` - Executed bool - EArgs []string -} - -func (c *testCommand) Execute(args []string) error { - c.Executed = true - c.EArgs = args - - return nil -} - -func TestCommandExecute(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command testCommand `command:"cmd"` - }{} - - assertParseSuccess(t, &opts, "-v", "cmd", "-g", "a", "b") - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.Command.Executed { - t.Errorf("Did not execute command") - } - - if !opts.Command.G { - t.Errorf("Expected Command.C to be true") - } - - assertStringArray(t, opts.Command.EArgs, []string{"a", "b"}) -} - -func TestCommandClosest(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Cmd1 struct { - } `command:"remove"` - - Cmd2 struct { - } `command:"add"` - }{} - - args := assertParseFail(t, ErrUnknownCommand, "Unknown command `addd', did you mean `add'?", &opts, "-v", "addd") - - assertStringArray(t, args, []string{"addd"}) -} - -func TestCommandAdd(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - }{} - - var cmd = struct { - G bool `short:"g"` - }{} - - p := NewParser(&opts, Default) - c, err := p.AddCommand("cmd", "", "", &cmd) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - ret, err := p.ParseArgs([]string{"-v", "cmd", "-g", "rest"}) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - assertStringArray(t, ret, []string{"rest"}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !cmd.G { - t.Errorf("Expected Command.G to be true") - } - - if p.Command.Find("cmd") != c { - t.Errorf("Expected to find command `cmd'") - } - - if p.Commands()[0] != c { - t.Errorf("Expected command %#v, but got %#v", c, p.Commands()[0]) - } - - if c.Options()[0].ShortName != 'g' { - t.Errorf("Expected short name `g' but got %v", c.Options()[0].ShortName) - } -} - -func TestCommandNestedInline(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Command struct { - G bool `short:"g"` - - Nested struct { - N string `long:"n"` - } `command:"nested"` - } `command:"cmd"` - }{} - - p, ret := assertParserSuccess(t, &opts, "-v", "cmd", "-g", "nested", "--n", "n", "rest") - - assertStringArray(t, ret, []string{"rest"}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.Command.G { - t.Errorf("Expected Command.G to be true") - } - - assertString(t, opts.Command.Nested.N, "n") - - if c := p.Command.Find("cmd"); c == nil { - t.Errorf("Expected to find command `cmd'") - } else { - if c != p.Active { - t.Errorf("Expected `cmd' to be the active parser command") - } - - if nested := c.Find("nested"); nested == nil { - t.Errorf("Expected to find command `nested'") - } else if nested != c.Active { - t.Errorf("Expected to find command `nested' to be the active `cmd' command") - } - } -} - -func TestRequiredOnCommand(t *testing.T) { - var opts = struct { - Value bool `short:"v" required:"true"` - - Command struct { - G bool `short:"g"` - } `command:"cmd"` - }{} - - assertParseFail(t, ErrRequired, fmt.Sprintf("the required flag `%cv' was not specified", defaultShortOptDelimiter), &opts, "cmd") -} - -func TestRequiredAllOnCommand(t *testing.T) { - var opts = struct { - Value bool `short:"v" required:"true"` - Missing bool `long:"missing" required:"true"` - - Command struct { - G bool `short:"g"` - } `command:"cmd"` - }{} - - assertParseFail(t, ErrRequired, fmt.Sprintf("the required flags `%smissing' and `%cv' were not specified", defaultLongOptDelimiter, defaultShortOptDelimiter), &opts, "cmd") -} - -func TestDefaultOnCommand(t *testing.T) { - var opts = struct { - Command struct { - G bool `short:"g" default:"true"` - } `command:"cmd"` - }{} - - assertParseSuccess(t, &opts, "cmd") - - if !opts.Command.G { - t.Errorf("Expected G to be true") - } -} - -func TestSubcommandsOptional(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Cmd1 struct { - } `command:"remove"` - - Cmd2 struct { - } `command:"add"` - }{} - - p := NewParser(&opts, None) - p.SubcommandsOptional = true - - _, err := p.ParseArgs([]string{"-v"}) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - if !opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestCommandAlias(t *testing.T) { - var opts = struct { - Command struct { - G bool `short:"g" default:"true"` - } `command:"cmd" alias:"cm"` - }{} - - assertParseSuccess(t, &opts, "cm") - - if !opts.Command.G { - t.Errorf("Expected G to be true") - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/completion.go b/vendor/src/github.com/jessevdk/go-flags/completion.go deleted file mode 100644 index d0adfe0..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/completion.go +++ /dev/null @@ -1,304 +0,0 @@ -package flags - -import ( - "fmt" - "path/filepath" - "reflect" - "sort" - "strings" - "unicode/utf8" -) - -// Completion is a type containing information of a completion. -type Completion struct { - // The completed item - Item string - - // A description of the completed item (optional) - Description string -} - -type completions []Completion - -func (c completions) Len() int { - return len(c) -} - -func (c completions) Less(i, j int) bool { - return c[i].Item < c[j].Item -} - -func (c completions) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -// Completer is an interface which can be implemented by types -// to provide custom command line argument completion. -type Completer interface { - // Complete receives a prefix representing a (partial) value - // for its type and should provide a list of possible valid - // completions. - Complete(match string) []Completion -} - -type completion struct { - parser *Parser - - ShowDescriptions bool -} - -// Filename is a string alias which provides filename completion. -type Filename string - -func completionsWithoutDescriptions(items []string) []Completion { - ret := make([]Completion, len(items)) - - for i, v := range items { - ret[i].Item = v - } - - return ret -} - -// Complete returns a list of existing files with the given -// prefix. -func (f *Filename) Complete(match string) []Completion { - ret, _ := filepath.Glob(match + "*") - return completionsWithoutDescriptions(ret) -} - -func (c *completion) skipPositional(s *parseState, n int) { - if n >= len(s.positional) { - s.positional = nil - } else { - s.positional = s.positional[n:] - } -} - -func (c *completion) completeOptionNames(names map[string]*Option, prefix string, match string) []Completion { - n := make([]Completion, 0, len(names)) - - for k, opt := range names { - if strings.HasPrefix(k, match) { - n = append(n, Completion{ - Item: prefix + k, - Description: opt.Description, - }) - } - } - - return n -} - -func (c *completion) completeLongNames(s *parseState, prefix string, match string) []Completion { - return c.completeOptionNames(s.lookup.longNames, prefix, match) -} - -func (c *completion) completeShortNames(s *parseState, prefix string, match string) []Completion { - if len(match) != 0 { - return []Completion{ - Completion{ - Item: prefix + match, - }, - } - } - - return c.completeOptionNames(s.lookup.shortNames, prefix, match) -} - -func (c *completion) completeCommands(s *parseState, match string) []Completion { - n := make([]Completion, 0, len(s.command.commands)) - - for _, cmd := range s.command.commands { - if cmd.data != c && strings.HasPrefix(cmd.Name, match) { - n = append(n, Completion{ - Item: cmd.Name, - Description: cmd.ShortDescription, - }) - } - } - - return n -} - -func (c *completion) completeValue(value reflect.Value, prefix string, match string) []Completion { - i := value.Interface() - - var ret []Completion - - if cmp, ok := i.(Completer); ok { - ret = cmp.Complete(match) - } else if value.CanAddr() { - if cmp, ok = value.Addr().Interface().(Completer); ok { - ret = cmp.Complete(match) - } - } - - for i, v := range ret { - ret[i].Item = prefix + v.Item - } - - return ret -} - -func (c *completion) completeArg(arg *Arg, prefix string, match string) []Completion { - if arg.isRemaining() { - // For remaining positional args (that are parsed into a slice), complete - // based on the element type. - return c.completeValue(reflect.New(arg.value.Type().Elem()), prefix, match) - } - - return c.completeValue(arg.value, prefix, match) -} - -func (c *completion) complete(args []string) []Completion { - if len(args) == 0 { - args = []string{""} - } - - s := &parseState{ - args: args, - } - - c.parser.fillParseState(s) - - var opt *Option - - for len(s.args) > 1 { - arg := s.pop() - - if (c.parser.Options&PassDoubleDash) != None && arg == "--" { - opt = nil - c.skipPositional(s, len(s.args)-1) - - break - } - - if argumentIsOption(arg) { - prefix, optname, islong := stripOptionPrefix(arg) - optname, _, argument := splitOption(prefix, optname, islong) - - if argument == nil { - var o *Option - canarg := true - - if islong { - o = s.lookup.longNames[optname] - } else { - for i, r := range optname { - sname := string(r) - o = s.lookup.shortNames[sname] - - if o == nil { - break - } - - if i == 0 && o.canArgument() && len(optname) != len(sname) { - canarg = false - break - } - } - } - - if o == nil && (c.parser.Options&PassAfterNonOption) != None { - opt = nil - c.skipPositional(s, len(s.args)-1) - - break - } else if o != nil && o.canArgument() && !o.OptionalArgument && canarg { - if len(s.args) > 1 { - s.pop() - } else { - opt = o - } - } - } - } else { - if len(s.positional) > 0 { - if !s.positional[0].isRemaining() { - // Don't advance beyond a remaining positional arg (because - // it consumes all subsequent args). - s.positional = s.positional[1:] - } - } else if cmd, ok := s.lookup.commands[arg]; ok { - cmd.fillParseState(s) - } - - opt = nil - } - } - - lastarg := s.args[len(s.args)-1] - var ret []Completion - - if opt != nil { - // Completion for the argument of 'opt' - ret = c.completeValue(opt.value, "", lastarg) - } else if argumentStartsOption(lastarg) { - // Complete the option - prefix, optname, islong := stripOptionPrefix(lastarg) - optname, split, argument := splitOption(prefix, optname, islong) - - if argument == nil && !islong { - rname, n := utf8.DecodeRuneInString(optname) - sname := string(rname) - - if opt := s.lookup.shortNames[sname]; opt != nil && opt.canArgument() { - ret = c.completeValue(opt.value, prefix+sname, optname[n:]) - } else { - ret = c.completeShortNames(s, prefix, optname) - } - } else if argument != nil { - if islong { - opt = s.lookup.longNames[optname] - } else { - opt = s.lookup.shortNames[optname] - } - - if opt != nil { - ret = c.completeValue(opt.value, prefix+optname+split, *argument) - } - } else if islong { - ret = c.completeLongNames(s, prefix, optname) - } else { - ret = c.completeShortNames(s, prefix, optname) - } - } else if len(s.positional) > 0 { - // Complete for positional argument - ret = c.completeArg(s.positional[0], "", lastarg) - } else if len(s.command.commands) > 0 { - // Complete for command - ret = c.completeCommands(s, lastarg) - } - - sort.Sort(completions(ret)) - return ret -} - -func (c *completion) execute(args []string) { - ret := c.complete(args) - - if c.ShowDescriptions && len(ret) > 1 { - maxl := 0 - - for _, v := range ret { - if len(v.Item) > maxl { - maxl = len(v.Item) - } - } - - for _, v := range ret { - fmt.Printf("%s", v.Item) - - if len(v.Description) > 0 { - fmt.Printf("%s # %s", strings.Repeat(" ", maxl-len(v.Item)), v.Description) - } - - fmt.Printf("\n") - } - } else { - for _, v := range ret { - fmt.Println(v.Item) - } - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/completion_test.go b/vendor/src/github.com/jessevdk/go-flags/completion_test.go deleted file mode 100644 index 2d5a97f..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/completion_test.go +++ /dev/null @@ -1,289 +0,0 @@ -package flags - -import ( - "bytes" - "io" - "os" - "path" - "path/filepath" - "reflect" - "runtime" - "strings" - "testing" -) - -type TestComplete struct { -} - -func (t *TestComplete) Complete(match string) []Completion { - options := []string{ - "hello world", - "hello universe", - "hello multiverse", - } - - ret := make([]Completion, 0, len(options)) - - for _, o := range options { - if strings.HasPrefix(o, match) { - ret = append(ret, Completion{ - Item: o, - }) - } - } - - return ret -} - -var completionTestOptions struct { - Verbose bool `short:"v" long:"verbose" description:"Verbose messages"` - Debug bool `short:"d" long:"debug" description:"Enable debug"` - Version bool `long:"version" description:"Show version"` - Required bool `long:"required" required:"true" description:"This is required"` - - AddCommand struct { - Positional struct { - Filename Filename - } `positional-args:"yes"` - } `command:"add" description:"add an item"` - - AddMultiCommand struct { - Positional struct { - Filename []Filename - } `positional-args:"yes"` - } `command:"add-multi" description:"add multiple items"` - - RemoveCommand struct { - Other bool `short:"o"` - File Filename `short:"f" long:"filename"` - } `command:"rm" description:"remove an item"` - - RenameCommand struct { - Completed TestComplete `short:"c" long:"completed"` - } `command:"rename" description:"rename an item"` -} - -type completionTest struct { - Args []string - Completed []string - ShowDescriptions bool -} - -var completionTests []completionTest - -func init() { - _, sourcefile, _, _ := runtime.Caller(0) - completionTestSourcedir := filepath.Join(filepath.SplitList(path.Dir(sourcefile))...) - - completionTestFilename := []string{filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion_test.go")} - - completionTests = []completionTest{ - { - // Short names - []string{"-"}, - []string{"-d", "-v"}, - false, - }, - - { - // Short names concatenated - []string{"-dv"}, - []string{"-dv"}, - false, - }, - - { - // Long names - []string{"--"}, - []string{"--debug", "--required", "--verbose", "--version"}, - false, - }, - - { - // Long names with descriptions - []string{"--"}, - []string{ - "--debug # Enable debug", - "--required # This is required", - "--verbose # Verbose messages", - "--version # Show version", - }, - true, - }, - - { - // Long names partial - []string{"--ver"}, - []string{"--verbose", "--version"}, - false, - }, - - { - // Commands - []string{""}, - []string{"add", "add-multi", "rename", "rm"}, - false, - }, - - { - // Commands with descriptions - []string{""}, - []string{ - "add # add an item", - "add-multi # add multiple items", - "rename # rename an item", - "rm # remove an item", - }, - true, - }, - - { - // Commands partial - []string{"r"}, - []string{"rename", "rm"}, - false, - }, - - { - // Positional filename - []string{"add", filepath.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - - { - // Multiple positional filename (1 arg) - []string{"add-multi", filepath.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - { - // Multiple positional filename (2 args) - []string{"add-multi", filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - { - // Multiple positional filename (3 args) - []string{"add-multi", filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - - { - // Flag filename - []string{"rm", "-f", path.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - - { - // Flag short concat last filename - []string{"rm", "-of", path.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - - { - // Flag concat filename - []string{"rm", "-f" + path.Join(completionTestSourcedir, "completion")}, - []string{"-f" + completionTestFilename[0], "-f" + completionTestFilename[1]}, - false, - }, - - { - // Flag equal concat filename - []string{"rm", "-f=" + path.Join(completionTestSourcedir, "completion")}, - []string{"-f=" + completionTestFilename[0], "-f=" + completionTestFilename[1]}, - false, - }, - - { - // Flag concat long filename - []string{"rm", "--filename=" + path.Join(completionTestSourcedir, "completion")}, - []string{"--filename=" + completionTestFilename[0], "--filename=" + completionTestFilename[1]}, - false, - }, - - { - // Flag long filename - []string{"rm", "--filename", path.Join(completionTestSourcedir, "completion")}, - completionTestFilename, - false, - }, - - { - // Custom completed - []string{"rename", "-c", "hello un"}, - []string{"hello universe"}, - false, - }, - } -} - -func TestCompletion(t *testing.T) { - p := NewParser(&completionTestOptions, Default) - c := &completion{parser: p} - - for _, test := range completionTests { - if test.ShowDescriptions { - continue - } - - ret := c.complete(test.Args) - items := make([]string, len(ret)) - - for i, v := range ret { - items[i] = v.Item - } - - if !reflect.DeepEqual(items, test.Completed) { - t.Errorf("Args: %#v, %#v\n Expected: %#v\n Got: %#v", test.Args, test.ShowDescriptions, test.Completed, items) - } - } -} - -func TestParserCompletion(t *testing.T) { - for _, test := range completionTests { - if test.ShowDescriptions { - os.Setenv("GO_FLAGS_COMPLETION", "verbose") - } else { - os.Setenv("GO_FLAGS_COMPLETION", "1") - } - - tmp := os.Stdout - - r, w, _ := os.Pipe() - os.Stdout = w - - out := make(chan string) - - go func() { - var buf bytes.Buffer - - io.Copy(&buf, r) - - out <- buf.String() - }() - - p := NewParser(&completionTestOptions, None) - - _, err := p.ParseArgs(test.Args) - - w.Close() - - os.Stdout = tmp - - if err != nil { - t.Fatalf("Unexpected error: %s", err) - } - - got := strings.Split(strings.Trim(<-out, "\n"), "\n") - - if !reflect.DeepEqual(got, test.Completed) { - t.Errorf("Expected: %#v\nGot: %#v", test.Completed, got) - } - } - - os.Setenv("GO_FLAGS_COMPLETION", "") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/convert.go b/vendor/src/github.com/jessevdk/go-flags/convert.go deleted file mode 100644 index 1185737..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/convert.go +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright 2012 Jesse van den Kieboom. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flags - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "time" -) - -// Marshaler is the interface implemented by types that can marshal themselves -// to a string representation of the flag. -type Marshaler interface { - // MarshalFlag marshals a flag value to its string representation. - MarshalFlag() (string, error) -} - -// Unmarshaler is the interface implemented by types that can unmarshal a flag -// argument to themselves. The provided value is directly passed from the -// command line. -type Unmarshaler interface { - // UnmarshalFlag unmarshals a string value representation to the flag - // value (which therefore needs to be a pointer receiver). - UnmarshalFlag(value string) error -} - -func getBase(options multiTag, base int) (int, error) { - sbase := options.Get("base") - - var err error - var ivbase int64 - - if sbase != "" { - ivbase, err = strconv.ParseInt(sbase, 10, 32) - base = int(ivbase) - } - - return base, err -} - -func convertMarshal(val reflect.Value) (bool, string, error) { - // Check first for the Marshaler interface - if val.Type().NumMethod() > 0 && val.CanInterface() { - if marshaler, ok := val.Interface().(Marshaler); ok { - ret, err := marshaler.MarshalFlag() - return true, ret, err - } - } - - return false, "", nil -} - -func convertToString(val reflect.Value, options multiTag) (string, error) { - if ok, ret, err := convertMarshal(val); ok { - return ret, err - } - - tp := val.Type() - - // Support for time.Duration - if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() { - stringer := val.Interface().(fmt.Stringer) - return stringer.String(), nil - } - - switch tp.Kind() { - case reflect.String: - return val.String(), nil - case reflect.Bool: - if val.Bool() { - return "true", nil - } - - return "false", nil - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - base, err := getBase(options, 10) - - if err != nil { - return "", err - } - - return strconv.FormatInt(val.Int(), base), nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - base, err := getBase(options, 10) - - if err != nil { - return "", err - } - - return strconv.FormatUint(val.Uint(), base), nil - case reflect.Float32, reflect.Float64: - return strconv.FormatFloat(val.Float(), 'g', -1, tp.Bits()), nil - case reflect.Slice: - if val.Len() == 0 { - return "", nil - } - - ret := "[" - - for i := 0; i < val.Len(); i++ { - if i != 0 { - ret += ", " - } - - item, err := convertToString(val.Index(i), options) - - if err != nil { - return "", err - } - - ret += item - } - - return ret + "]", nil - case reflect.Map: - ret := "{" - - for i, key := range val.MapKeys() { - if i != 0 { - ret += ", " - } - - keyitem, err := convertToString(key, options) - - if err != nil { - return "", err - } - - item, err := convertToString(val.MapIndex(key), options) - - if err != nil { - return "", err - } - - ret += keyitem + ":" + item - } - - return ret + "}", nil - case reflect.Ptr: - return convertToString(reflect.Indirect(val), options) - case reflect.Interface: - if !val.IsNil() { - return convertToString(val.Elem(), options) - } - } - - return "", nil -} - -func convertUnmarshal(val string, retval reflect.Value) (bool, error) { - if retval.Type().NumMethod() > 0 && retval.CanInterface() { - if unmarshaler, ok := retval.Interface().(Unmarshaler); ok { - return true, unmarshaler.UnmarshalFlag(val) - } - } - - if retval.Type().Kind() != reflect.Ptr && retval.CanAddr() { - return convertUnmarshal(val, retval.Addr()) - } - - if retval.Type().Kind() == reflect.Interface && !retval.IsNil() { - return convertUnmarshal(val, retval.Elem()) - } - - return false, nil -} - -func convert(val string, retval reflect.Value, options multiTag) error { - if ok, err := convertUnmarshal(val, retval); ok { - return err - } - - tp := retval.Type() - - // Support for time.Duration - if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() { - parsed, err := time.ParseDuration(val) - - if err != nil { - return err - } - - retval.SetInt(int64(parsed)) - return nil - } - - switch tp.Kind() { - case reflect.String: - retval.SetString(val) - case reflect.Bool: - if val == "" { - retval.SetBool(true) - } else { - b, err := strconv.ParseBool(val) - - if err != nil { - return err - } - - retval.SetBool(b) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - base, err := getBase(options, 10) - - if err != nil { - return err - } - - parsed, err := strconv.ParseInt(val, base, tp.Bits()) - - if err != nil { - return err - } - - retval.SetInt(parsed) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - base, err := getBase(options, 10) - - if err != nil { - return err - } - - parsed, err := strconv.ParseUint(val, base, tp.Bits()) - - if err != nil { - return err - } - - retval.SetUint(parsed) - case reflect.Float32, reflect.Float64: - parsed, err := strconv.ParseFloat(val, tp.Bits()) - - if err != nil { - return err - } - - retval.SetFloat(parsed) - case reflect.Slice: - elemtp := tp.Elem() - - elemvalptr := reflect.New(elemtp) - elemval := reflect.Indirect(elemvalptr) - - if err := convert(val, elemval, options); err != nil { - return err - } - - retval.Set(reflect.Append(retval, elemval)) - case reflect.Map: - parts := strings.SplitN(val, ":", 2) - - key := parts[0] - var value string - - if len(parts) == 2 { - value = parts[1] - } - - keytp := tp.Key() - keyval := reflect.New(keytp) - - if err := convert(key, keyval, options); err != nil { - return err - } - - valuetp := tp.Elem() - valueval := reflect.New(valuetp) - - if err := convert(value, valueval, options); err != nil { - return err - } - - if retval.IsNil() { - retval.Set(reflect.MakeMap(tp)) - } - - retval.SetMapIndex(reflect.Indirect(keyval), reflect.Indirect(valueval)) - case reflect.Ptr: - if retval.IsNil() { - retval.Set(reflect.New(retval.Type().Elem())) - } - - return convert(val, reflect.Indirect(retval), options) - case reflect.Interface: - if !retval.IsNil() { - return convert(val, retval.Elem(), options) - } - } - - return nil -} - -func isPrint(s string) bool { - for _, c := range s { - if !strconv.IsPrint(c) { - return false - } - } - - return true -} - -func quoteIfNeeded(s string) string { - if !isPrint(s) { - return strconv.Quote(s) - } - - return s -} - -func quoteIfNeededV(s []string) []string { - ret := make([]string, len(s)) - - for i, v := range s { - ret[i] = quoteIfNeeded(v) - } - - return ret -} - -func quoteV(s []string) []string { - ret := make([]string, len(s)) - - for i, v := range s { - ret[i] = strconv.Quote(v) - } - - return ret -} - -func unquoteIfPossible(s string) (string, error) { - if len(s) == 0 || s[0] != '"' { - return s, nil - } - - return strconv.Unquote(s) -} - -func wrapText(s string, l int, prefix string) string { - // Basic text wrapping of s at spaces to fit in l - var ret string - - s = strings.TrimSpace(s) - - for len(s) > l { - // Try to split on space - suffix := "" - - pos := strings.LastIndex(s[:l], " ") - - if pos < 0 { - pos = l - 1 - suffix = "-\n" - } - - if len(ret) != 0 { - ret += "\n" + prefix - } - - ret += strings.TrimSpace(s[:pos]) + suffix - s = strings.TrimSpace(s[pos:]) - } - - if len(s) > 0 { - if len(ret) != 0 { - ret += "\n" + prefix - } - - return ret + s - } - - return ret -} diff --git a/vendor/src/github.com/jessevdk/go-flags/convert_test.go b/vendor/src/github.com/jessevdk/go-flags/convert_test.go deleted file mode 100644 index 0de0eea..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/convert_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package flags - -import ( - "testing" - "time" -) - -func expectConvert(t *testing.T, o *Option, expected string) { - s, err := convertToString(o.value, o.tag) - - if err != nil { - t.Errorf("Unexpected error: %v", err) - return - } - - assertString(t, s, expected) -} - -func TestConvertToString(t *testing.T) { - d, _ := time.ParseDuration("1h2m4s") - - var opts = struct { - String string `long:"string"` - - Int int `long:"int"` - Int8 int8 `long:"int8"` - Int16 int16 `long:"int16"` - Int32 int32 `long:"int32"` - Int64 int64 `long:"int64"` - - Uint uint `long:"uint"` - Uint8 uint8 `long:"uint8"` - Uint16 uint16 `long:"uint16"` - Uint32 uint32 `long:"uint32"` - Uint64 uint64 `long:"uint64"` - - Float32 float32 `long:"float32"` - Float64 float64 `long:"float64"` - - Duration time.Duration `long:"duration"` - - Bool bool `long:"bool"` - - IntSlice []int `long:"int-slice"` - IntFloatMap map[int]float64 `long:"int-float-map"` - - PtrBool *bool `long:"ptr-bool"` - Interface interface{} `long:"interface"` - - Int32Base int32 `long:"int32-base" base:"16"` - Uint32Base uint32 `long:"uint32-base" base:"16"` - }{ - "string", - - -2, - -1, - 0, - 1, - 2, - - 1, - 2, - 3, - 4, - 5, - - 1.2, - -3.4, - - d, - true, - - []int{-3, 4, -2}, - map[int]float64{-2: 4.5}, - - new(bool), - float32(5.2), - - -5823, - 4232, - } - - p := NewNamedParser("test", Default) - grp, _ := p.AddGroup("test group", "", &opts) - - expects := []string{ - "string", - "-2", - "-1", - "0", - "1", - "2", - - "1", - "2", - "3", - "4", - "5", - - "1.2", - "-3.4", - - "1h2m4s", - "true", - - "[-3, 4, -2]", - "{-2:4.5}", - - "false", - "5.2", - - "-16bf", - "1088", - } - - for i, v := range grp.Options() { - expectConvert(t, v, expects[i]) - } -} - -func TestConvertToStringInvalidIntBase(t *testing.T) { - var opts = struct { - Int int `long:"int" base:"no"` - }{ - 2, - } - - p := NewNamedParser("test", Default) - grp, _ := p.AddGroup("test group", "", &opts) - o := grp.Options()[0] - - _, err := convertToString(o.value, o.tag) - - if err != nil { - err = newErrorf(ErrMarshal, "%v", err) - } - - assertError(t, err, ErrMarshal, "strconv.ParseInt: parsing \"no\": invalid syntax") -} - -func TestConvertToStringInvalidUintBase(t *testing.T) { - var opts = struct { - Uint uint `long:"uint" base:"no"` - }{ - 2, - } - - p := NewNamedParser("test", Default) - grp, _ := p.AddGroup("test group", "", &opts) - o := grp.Options()[0] - - _, err := convertToString(o.value, o.tag) - - if err != nil { - err = newErrorf(ErrMarshal, "%v", err) - } - - assertError(t, err, ErrMarshal, "strconv.ParseInt: parsing \"no\": invalid syntax") -} - -func TestWrapText(t *testing.T) { - s := "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - - got := wrapText(s, 60, " ") - expected := `Lorem ipsum dolor sit amet, consectetur adipisicing elit, - sed do eiusmod tempor incididunt ut labore et dolore magna - aliqua. Ut enim ad minim veniam, quis nostrud exercitation - ullamco laboris nisi ut aliquip ex ea commodo consequat. - Duis aute irure dolor in reprehenderit in voluptate velit - esse cillum dolore eu fugiat nulla pariatur. Excepteur sint - occaecat cupidatat non proident, sunt in culpa qui officia - deserunt mollit anim id est laborum.` - - assertDiff(t, got, expected, "wrapped text") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/error.go b/vendor/src/github.com/jessevdk/go-flags/error.go deleted file mode 100644 index fce9d31..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/error.go +++ /dev/null @@ -1,123 +0,0 @@ -package flags - -import ( - "fmt" -) - -// ErrorType represents the type of error. -type ErrorType uint - -const ( - // ErrUnknown indicates a generic error. - ErrUnknown ErrorType = iota - - // ErrExpectedArgument indicates that an argument was expected. - ErrExpectedArgument - - // ErrUnknownFlag indicates an unknown flag. - ErrUnknownFlag - - // ErrUnknownGroup indicates an unknown group. - ErrUnknownGroup - - // ErrMarshal indicates a marshalling error while converting values. - ErrMarshal - - // ErrHelp indicates that the built-in help was shown (the error - // contains the help message). - ErrHelp - - // ErrNoArgumentForBool indicates that an argument was given for a - // boolean flag (which don't not take any arguments). - ErrNoArgumentForBool - - // ErrRequired indicates that a required flag was not provided. - ErrRequired - - // ErrShortNameTooLong indicates that a short flag name was specified, - // longer than one character. - ErrShortNameTooLong - - // ErrDuplicatedFlag indicates that a short or long flag has been - // defined more than once - ErrDuplicatedFlag - - // ErrTag indicates an error while parsing flag tags. - ErrTag - - // ErrCommandRequired indicates that a command was required but not - // specified - ErrCommandRequired - - // ErrUnknownCommand indicates that an unknown command was specified. - ErrUnknownCommand -) - -func (e ErrorType) String() string { - switch e { - case ErrUnknown: - return "unknown" - case ErrExpectedArgument: - return "expected argument" - case ErrUnknownFlag: - return "unknown flag" - case ErrUnknownGroup: - return "unknown group" - case ErrMarshal: - return "marshal" - case ErrHelp: - return "help" - case ErrNoArgumentForBool: - return "no argument for bool" - case ErrRequired: - return "required" - case ErrShortNameTooLong: - return "short name too long" - case ErrDuplicatedFlag: - return "duplicated flag" - case ErrTag: - return "tag" - case ErrCommandRequired: - return "command required" - case ErrUnknownCommand: - return "unknown command" - } - - return "unrecognized error type" -} - -// Error represents a parser error. The error returned from Parse is of this -// type. The error contains both a Type and Message. -type Error struct { - // The type of error - Type ErrorType - - // The error message - Message string -} - -// Error returns the error's message -func (e *Error) Error() string { - return e.Message -} - -func newError(tp ErrorType, message string) *Error { - return &Error{ - Type: tp, - Message: message, - } -} - -func newErrorf(tp ErrorType, format string, args ...interface{}) *Error { - return newError(tp, fmt.Sprintf(format, args...)) -} - -func wrapError(err error) *Error { - ret, ok := err.(*Error) - - if !ok { - return newError(ErrUnknown, err.Error()) - } - - return ret -} diff --git a/vendor/src/github.com/jessevdk/go-flags/example_test.go b/vendor/src/github.com/jessevdk/go-flags/example_test.go deleted file mode 100644 index f7be2bb..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/example_test.go +++ /dev/null @@ -1,110 +0,0 @@ -// Example of use of the flags package. -package flags - -import ( - "fmt" - "os/exec" -) - -func Example() { - var opts struct { - // Slice of bool will append 'true' each time the option - // is encountered (can be set multiple times, like -vvv) - Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` - - // Example of automatic marshalling to desired type (uint) - Offset uint `long:"offset" description:"Offset"` - - // Example of a callback, called each time the option is found. - Call func(string) `short:"c" description:"Call phone number"` - - // Example of a required flag - Name string `short:"n" long:"name" description:"A name" required:"true"` - - // Example of a value name - File string `short:"f" long:"file" description:"A file" value-name:"FILE"` - - // Example of a pointer - Ptr *int `short:"p" description:"A pointer to an integer"` - - // Example of a slice of strings - StringSlice []string `short:"s" description:"A slice of strings"` - - // Example of a slice of pointers - PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` - - // Example of a map - IntMap map[string]int `long:"intmap" description:"A map from string to int"` - - // Example of a filename (useful for completion) - Filename Filename `long:"filename" description:"A filename"` - - // Example of positional arguments - Args struct { - Id string - Num int - Rest []string - } `positional-args:"yes" required:"yes"` - } - - // Callback which will invoke callto: to call a number. - // Note that this works just on OS X (and probably only with - // Skype) but it shows the idea. - opts.Call = func(num string) { - cmd := exec.Command("open", "callto:"+num) - cmd.Start() - cmd.Process.Release() - } - - // Make some fake arguments to parse. - args := []string{ - "-vv", - "--offset=5", - "-n", "Me", - "-p", "3", - "-s", "hello", - "-s", "world", - "--ptrslice", "hello", - "--ptrslice", "world", - "--intmap", "a:1", - "--intmap", "b:5", - "--filename", "hello.go", - "id", - "10", - "remaining1", - "remaining2", - } - - // Parse flags from `args'. Note that here we use flags.ParseArgs for - // the sake of making a working example. Normally, you would simply use - // flags.Parse(&opts) which uses os.Args - _, err := ParseArgs(&opts, args) - - if err != nil { - panic(err) - } - - fmt.Printf("Verbosity: %v\n", opts.Verbose) - fmt.Printf("Offset: %d\n", opts.Offset) - fmt.Printf("Name: %s\n", opts.Name) - fmt.Printf("Ptr: %d\n", *opts.Ptr) - fmt.Printf("StringSlice: %v\n", opts.StringSlice) - fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1]) - fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"]) - fmt.Printf("Filename: %v\n", opts.Filename) - fmt.Printf("Args.Id: %s\n", opts.Args.Id) - fmt.Printf("Args.Num: %d\n", opts.Args.Num) - fmt.Printf("Args.Rest: %v\n", opts.Args.Rest) - - // Output: Verbosity: [true true] - // Offset: 5 - // Name: Me - // Ptr: 3 - // StringSlice: [hello world] - // PtrSlice: [hello world] - // IntMap: [a:1 b:5] - // Filename: hello.go - // Args.Id: id - // Args.Num: 10 - // Args.Rest: [remaining1 remaining2] -} diff --git a/vendor/src/github.com/jessevdk/go-flags/examples/add.go b/vendor/src/github.com/jessevdk/go-flags/examples/add.go deleted file mode 100644 index 57d8f23..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/examples/add.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "fmt" -) - -type AddCommand struct { - All bool `short:"a" long:"all" description:"Add all files"` -} - -var addCommand AddCommand - -func (x *AddCommand) Execute(args []string) error { - fmt.Printf("Adding (all=%v): %#v\n", x.All, args) - return nil -} - -func init() { - parser.AddCommand("add", - "Add a file", - "The add command adds a file to the repository. Use -a to add all files.", - &addCommand) -} diff --git a/vendor/src/github.com/jessevdk/go-flags/examples/bash-completion b/vendor/src/github.com/jessevdk/go-flags/examples/bash-completion deleted file mode 100644 index 974f52a..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/examples/bash-completion +++ /dev/null @@ -1,9 +0,0 @@ -_examples() { - args=("${COMP_WORDS[@]:1:$COMP_CWORD}") - - local IFS=$'\n' - COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}")) - return 1 -} - -complete -F _examples examples diff --git a/vendor/src/github.com/jessevdk/go-flags/examples/main.go b/vendor/src/github.com/jessevdk/go-flags/examples/main.go deleted file mode 100644 index 4a22be6..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/examples/main.go +++ /dev/null @@ -1,75 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "github.com/jessevdk/go-flags" - "os" - "strconv" - "strings" -) - -type EditorOptions struct { - Input flags.Filename `short:"i" long:"input" description:"Input file" default:"-"` - Output flags.Filename `short:"o" long:"output" description:"Output file" default:"-"` -} - -type Point struct { - X, Y int -} - -func (p *Point) UnmarshalFlag(value string) error { - parts := strings.Split(value, ",") - - if len(parts) != 2 { - return errors.New("expected two numbers separated by a ,") - } - - x, err := strconv.ParseInt(parts[0], 10, 32) - - if err != nil { - return err - } - - y, err := strconv.ParseInt(parts[1], 10, 32) - - if err != nil { - return err - } - - p.X = int(x) - p.Y = int(y) - - return nil -} - -func (p Point) MarshalFlag() (string, error) { - return fmt.Sprintf("%d,%d", p.X, p.Y), nil -} - -type Options struct { - // Example of verbosity with level - Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` - - // Example of optional value - User string `short:"u" long:"user" description:"User name" optional:"yes" optional-value:"pancake"` - - // Example of map with multiple default values - Users map[string]string `long:"users" description:"User e-mail map" default:"system:system@example.org" default:"admin:admin@example.org"` - - // Example of option group - Editor EditorOptions `group:"Editor Options"` - - // Example of custom type Marshal/Unmarshal - Point Point `long:"point" description:"A x,y point" default:"1,2"` -} - -var options Options - -var parser = flags.NewParser(&options, flags.Default) - -func main() { - if _, err := parser.Parse(); err != nil { - os.Exit(1) - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/examples/rm.go b/vendor/src/github.com/jessevdk/go-flags/examples/rm.go deleted file mode 100644 index c9c1dd0..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/examples/rm.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "fmt" -) - -type RmCommand struct { - Force bool `short:"f" long:"force" description:"Force removal of files"` -} - -var rmCommand RmCommand - -func (x *RmCommand) Execute(args []string) error { - fmt.Printf("Removing (force=%v): %#v\n", x.Force, args) - return nil -} - -func init() { - parser.AddCommand("rm", - "Remove a file", - "The rm command removes a file to the repository. Use -f to force removal of files.", - &rmCommand) -} diff --git a/vendor/src/github.com/jessevdk/go-flags/flags.go b/vendor/src/github.com/jessevdk/go-flags/flags.go deleted file mode 100644 index 4ac6793..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/flags.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2012 Jesse van den Kieboom. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package flags provides an extensive command line option parser. -The flags package is similar in functionality to the go built-in flag package -but provides more options and uses reflection to provide a convenient and -succinct way of specifying command line options. - - -Supported features - -The following features are supported in go-flags: - - Options with short names (-v) - Options with long names (--verbose) - Options with and without arguments (bool v.s. other type) - Options with optional arguments and default values - Option default values from ENVIRONMENT_VARIABLES, including slice and map values - Multiple option groups each containing a set of options - Generate and print well-formatted help message - Passing remaining command line arguments after -- (optional) - Ignoring unknown command line options (optional) - Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification - Supports multiple short options -aux - Supports all primitive go types (string, int{8..64}, uint{8..64}, float) - Supports same option multiple times (can store in slice or last option counts) - Supports maps - Supports function callbacks - Supports namespaces for (nested) option groups - -Additional features specific to Windows: - Options with short names (/v) - Options with long names (/verbose) - Windows-style options with arguments use a colon as the delimiter - Modify generated help message with Windows-style / options - - -Basic usage - -The flags package uses structs, reflection and struct field tags -to allow users to specify command line options. This results in very simple -and concise specification of your application options. For example: - - type Options struct { - Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` - } - -This specifies one option with a short name -v and a long name --verbose. -When either -v or --verbose is found on the command line, a 'true' value -will be appended to the Verbose field. e.g. when specifying -vvv, the -resulting value of Verbose will be {[true, true, true]}. - -Slice options work exactly the same as primitive type options, except that -whenever the option is encountered, a value is appended to the slice. - -Map options from string to primitive type are also supported. On the command -line, you specify the value for such an option as key:value. For example - - type Options struct { - AuthorInfo string[string] `short:"a"` - } - -Then, the AuthorInfo map can be filled with something like --a name:Jesse -a "surname:van den Kieboom". - -Finally, for full control over the conversion between command line argument -values and options, user defined types can choose to implement the Marshaler -and Unmarshaler interfaces. - - -Available field tags - -The following is a list of tags for struct fields supported by go-flags: - - short: the short name of the option (single character) - long: the long name of the option - required: whether an option is required to appear on the command - line. If a required option is not present, the parser will - return ErrRequired (optional) - description: the description of the option (optional) - long-description: the long description of the option. Currently only - displayed in generated man pages (optional) - no-flag: if non-empty this field is ignored as an option (optional) - - optional: whether an argument of the option is optional (optional) - optional-value: the value of an optional option when the option occurs - without an argument. This tag can be specified multiple - times in the case of maps or slices (optional) - default: the default value of an option. This tag can be specified - multiple times in the case of slices or maps (optional) - default-mask: when specified, this value will be displayed in the help - instead of the actual default value. This is useful - mostly for hiding otherwise sensitive information from - showing up in the help. If default-mask takes the special - value "-", then no default value will be shown at all - (optional) - env: the default value of the option is overridden from the - specified environment variable, if one has been defined. - (optional) - env-delim: the 'env' default value from environment is split into - multiple values with the given delimiter string, use with - slices and maps (optional) - value-name: the name of the argument value (to be shown in the help) - (optional) - - base: a base (radix) used to convert strings to integer values, the - default base is 10 (i.e. decimal) (optional) - - ini-name: the explicit ini option name (optional) - no-ini: if non-empty this field is ignored as an ini option - (optional) - - group: when specified on a struct field, makes the struct - field a separate group with the given name (optional) - namespace: when specified on a group struct field, the namespace - gets prepended to every option's long name and - subgroup's namespace of this group, separated by - the parser's namespace delimiter (optional) - command: when specified on a struct field, makes the struct - field a (sub)command with the given name (optional) - subcommands-optional: when specified on a command struct field, makes - any subcommands of that command optional (optional) - alias: when specified on a command struct field, adds the - specified name as an alias for the command. Can be - be specified multiple times to add more than one - alias (optional) - positional-args: when specified on a field with a struct type, - uses the fields of that struct to parse remaining - positional command line arguments into (in order - of the fields). If a field has a slice type, - then all remaining arguments will be added to it. - Positional arguments are optional by default, - unless the "required" tag is specified together - with the "positional-args" tag (optional) - positional-arg-name: used on a field in a positional argument struct; name - of the positional argument placeholder to be shown in - the help (optional) - - -Either the `short:` tag or the `long:` must be specified to make the field eligible as an -option. - - -Option groups - -Option groups are a simple way to semantically separate your options. All -options in a particular group are shown together in the help under the name -of the group. Namespaces can be used to specify option long names more -precisely and emphasize the options affiliation to their group. - -There are currently three ways to specify option groups. - - 1. Use NewNamedParser specifying the various option groups. - 2. Use AddGroup to add a group to an existing parser. - 3. Add a struct field to the top-level options annotated with the - group:"group-name" tag. - - - -Commands - -The flags package also has basic support for commands. Commands are often -used in monolithic applications that support various commands or actions. -Take git for example, all of the add, commit, checkout, etc. are called -commands. Using commands you can easily separate multiple functions of your -application. - -There are currently two ways to specify a command. - - 1. Use AddCommand on an existing parser. - 2. Add a struct field to your options struct annotated with the - command:"command-name" tag. - -The most common, idiomatic way to implement commands is to define a global -parser instance and implement each command in a separate file. These -command files should define a go init function which calls AddCommand on -the global parser. - -When parsing ends and there is an active command and that command implements -the Commander interface, then its Execute method will be run with the -remaining command line arguments. - -Command structs can have options which become valid to parse after the -command has been specified on the command line, in addition to the options -of all the parent commands. I.e. considering a -v flag on the parser and an -add command, the following are equivalent: - - ./app -v add - ./app add -v - -However, if the -v flag is defined on the add command, then the first of -the two examples above would fail since the -v flag is not defined before -the add command. - - -Completion - -go-flags has builtin support to provide bash completion of flags, commands -and argument values. To use completion, the binary which uses go-flags -can be invoked in a special environment to list completion of the current -command line argument. It should be noted that this `executes` your application, -and it is up to the user to make sure there are no negative side effects (for -example from init functions). - -Setting the environment variable `GO_FLAGS_COMPLETION=1` enables completion -by replacing the argument parsing routine with the completion routine which -outputs completions for the passed arguments. The basic invocation to -complete a set of arguments is therefore: - - GO_FLAGS_COMPLETION=1 ./completion-example arg1 arg2 arg3 - -where `completion-example` is the binary, `arg1` and `arg2` are -the current arguments, and `arg3` (the last argument) is the argument -to be completed. If the GO_FLAGS_COMPLETION is set to "verbose", then -descriptions of possible completion items will also be shown, if there -are more than 1 completion items. - -To use this with bash completion, a simple file can be written which -calls the binary which supports go-flags completion: - - _completion_example() { - # All arguments except the first one - args=("${COMP_WORDS[@]:1:$COMP_CWORD}") - - # Only split on newlines - local IFS=$'\n' - - # Call completion (note that the first element of COMP_WORDS is - # the executable itself) - COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}")) - return 0 - } - - complete -F _completion_example completion-example - -Completion requires the parser option PassDoubleDash and is therefore enforced if the environment variable GO_FLAGS_COMPLETION is set. - -Customized completion for argument values is supported by implementing -the flags.Completer interface for the argument value type. An example -of a type which does so is the flags.Filename type, an alias of string -allowing simple filename completion. A slice or array argument value -whose element type implements flags.Completer will also be completed. -*/ -package flags diff --git a/vendor/src/github.com/jessevdk/go-flags/group.go b/vendor/src/github.com/jessevdk/go-flags/group.go deleted file mode 100644 index 8b609a3..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/group.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2012 Jesse van den Kieboom. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flags - -import ( - "errors" - "strings" -) - -// ErrNotPointerToStruct indicates that a provided data container is not -// a pointer to a struct. Only pointers to structs are valid data containers -// for options. -var ErrNotPointerToStruct = errors.New("provided data is not a pointer to struct") - -// Group represents an option group. Option groups can be used to logically -// group options together under a description. Groups are only used to provide -// more structure to options both for the user (as displayed in the help message) -// and for you, since groups can be nested. -type Group struct { - // A short description of the group. The - // short description is primarily used in the built-in generated help - // message - ShortDescription string - - // A long description of the group. The long - // description is primarily used to present information on commands - // (Command embeds Group) in the built-in generated help and man pages. - LongDescription string - - // The namespace of the group - Namespace string - - // The parent of the group or nil if it has no parent - parent interface{} - - // All the options in the group - options []*Option - - // All the subgroups - groups []*Group - - // Whether the group represents the built-in help group - isBuiltinHelp bool - - data interface{} -} - -// AddGroup adds a new group to the command with the given name and data. The -// data needs to be a pointer to a struct from which the fields indicate which -// options are in the group. -func (g *Group) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) { - group := newGroup(shortDescription, longDescription, data) - - group.parent = g - - if err := group.scan(); err != nil { - return nil, err - } - - g.groups = append(g.groups, group) - return group, nil -} - -// Groups returns the list of groups embedded in this group. -func (g *Group) Groups() []*Group { - return g.groups -} - -// Options returns the list of options in this group. -func (g *Group) Options() []*Option { - return g.options -} - -// Find locates the subgroup with the given short description and returns it. -// If no such group can be found Find will return nil. Note that the description -// is matched case insensitively. -func (g *Group) Find(shortDescription string) *Group { - lshortDescription := strings.ToLower(shortDescription) - - var ret *Group - - g.eachGroup(func(gg *Group) { - if gg != g && strings.ToLower(gg.ShortDescription) == lshortDescription { - ret = gg - } - }) - - return ret -} diff --git a/vendor/src/github.com/jessevdk/go-flags/group_private.go b/vendor/src/github.com/jessevdk/go-flags/group_private.go deleted file mode 100644 index 15251ce..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/group_private.go +++ /dev/null @@ -1,254 +0,0 @@ -package flags - -import ( - "reflect" - "unicode/utf8" - "unsafe" -) - -type scanHandler func(reflect.Value, *reflect.StructField) (bool, error) - -func newGroup(shortDescription string, longDescription string, data interface{}) *Group { - return &Group{ - ShortDescription: shortDescription, - LongDescription: longDescription, - - data: data, - } -} - -func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option { - prio := 0 - var retopt *Option - - for _, opt := range g.options { - if namematch != nil && namematch(opt, name) && prio < 4 { - retopt = opt - prio = 4 - } - - if name == opt.field.Name && prio < 3 { - retopt = opt - prio = 3 - } - - if name == opt.LongNameWithNamespace() && prio < 2 { - retopt = opt - prio = 2 - } - - if opt.ShortName != 0 && name == string(opt.ShortName) && prio < 1 { - retopt = opt - prio = 1 - } - } - - return retopt -} - -func (g *Group) eachGroup(f func(*Group)) { - f(g) - - for _, gg := range g.groups { - gg.eachGroup(f) - } -} - -func (g *Group) scanStruct(realval reflect.Value, sfield *reflect.StructField, handler scanHandler) error { - stype := realval.Type() - - if sfield != nil { - if ok, err := handler(realval, sfield); err != nil { - return err - } else if ok { - return nil - } - } - - for i := 0; i < stype.NumField(); i++ { - field := stype.Field(i) - - // PkgName is set only for non-exported fields, which we ignore - if field.PkgPath != "" { - continue - } - - mtag := newMultiTag(string(field.Tag)) - - if err := mtag.Parse(); err != nil { - return err - } - - // Skip fields with the no-flag tag - if mtag.Get("no-flag") != "" { - continue - } - - // Dive deep into structs or pointers to structs - kind := field.Type.Kind() - fld := realval.Field(i) - - if kind == reflect.Struct { - if err := g.scanStruct(fld, &field, handler); err != nil { - return err - } - } else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct { - if fld.IsNil() { - fld.Set(reflect.New(fld.Type().Elem())) - } - - if err := g.scanStruct(reflect.Indirect(fld), &field, handler); err != nil { - return err - } - } - - longname := mtag.Get("long") - shortname := mtag.Get("short") - - // Need at least either a short or long name - if longname == "" && shortname == "" && mtag.Get("ini-name") == "" { - continue - } - - short := rune(0) - rc := utf8.RuneCountInString(shortname) - - if rc > 1 { - return newErrorf(ErrShortNameTooLong, - "short names can only be 1 character long, not `%s'", - shortname) - - } else if rc == 1 { - short, _ = utf8.DecodeRuneInString(shortname) - } - - description := mtag.Get("description") - def := mtag.GetMany("default") - - optionalValue := mtag.GetMany("optional-value") - valueName := mtag.Get("value-name") - defaultMask := mtag.Get("default-mask") - - optional := (mtag.Get("optional") != "") - required := (mtag.Get("required") != "") - - option := &Option{ - Description: description, - ShortName: short, - LongName: longname, - Default: def, - EnvDefaultKey: mtag.Get("env"), - EnvDefaultDelim: mtag.Get("env-delim"), - OptionalArgument: optional, - OptionalValue: optionalValue, - Required: required, - ValueName: valueName, - DefaultMask: defaultMask, - - group: g, - - field: field, - value: realval.Field(i), - tag: mtag, - } - - g.options = append(g.options, option) - } - - return nil -} - -func (g *Group) checkForDuplicateFlags() *Error { - shortNames := make(map[rune]*Option) - longNames := make(map[string]*Option) - - var duplicateError *Error - - g.eachGroup(func(g *Group) { - for _, option := range g.options { - if option.LongName != "" { - longName := option.LongNameWithNamespace() - - if otherOption, ok := longNames[longName]; ok { - duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same long name as option `%s'", option, otherOption) - return - } - longNames[longName] = option - } - if option.ShortName != 0 { - if otherOption, ok := shortNames[option.ShortName]; ok { - duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same short name as option `%s'", option, otherOption) - return - } - shortNames[option.ShortName] = option - } - } - }) - - return duplicateError -} - -func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) { - mtag := newMultiTag(string(sfield.Tag)) - - if err := mtag.Parse(); err != nil { - return true, err - } - - subgroup := mtag.Get("group") - - if len(subgroup) != 0 { - ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr())) - description := mtag.Get("description") - - group, err := g.AddGroup(subgroup, description, ptrval.Interface()) - if err != nil { - return true, err - } - - group.Namespace = mtag.Get("namespace") - - return true, nil - } - - return false, nil -} - -func (g *Group) scanType(handler scanHandler) error { - // Get all the public fields in the data struct - ptrval := reflect.ValueOf(g.data) - - if ptrval.Type().Kind() != reflect.Ptr { - panic(ErrNotPointerToStruct) - } - - stype := ptrval.Type().Elem() - - if stype.Kind() != reflect.Struct { - panic(ErrNotPointerToStruct) - } - - realval := reflect.Indirect(ptrval) - - if err := g.scanStruct(realval, nil, handler); err != nil { - return err - } - - if err := g.checkForDuplicateFlags(); err != nil { - return err - } - - return nil -} - -func (g *Group) scan() error { - return g.scanType(g.scanSubGroupHandler) -} - -func (g *Group) groupByName(name string) *Group { - if len(name) == 0 { - return g - } - - return g.Find(name) -} diff --git a/vendor/src/github.com/jessevdk/go-flags/group_test.go b/vendor/src/github.com/jessevdk/go-flags/group_test.go deleted file mode 100644 index b5ed9d4..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/group_test.go +++ /dev/null @@ -1,187 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestGroupInline(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Group struct { - G bool `short:"g"` - } `group:"Grouped Options"` - }{} - - p, ret := assertParserSuccess(t, &opts, "-v", "-g") - - assertStringArray(t, ret, []string{}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.Group.G { - t.Errorf("Expected Group.G to be true") - } - - if p.Command.Group.Find("Grouped Options") == nil { - t.Errorf("Expected to find group `Grouped Options'") - } -} - -func TestGroupAdd(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - }{} - - var grp = struct { - G bool `short:"g"` - }{} - - p := NewParser(&opts, Default) - g, err := p.AddGroup("Grouped Options", "", &grp) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - ret, err := p.ParseArgs([]string{"-v", "-g", "rest"}) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - assertStringArray(t, ret, []string{"rest"}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !grp.G { - t.Errorf("Expected Group.G to be true") - } - - if p.Command.Group.Find("Grouped Options") != g { - t.Errorf("Expected to find group `Grouped Options'") - } - - if p.Groups()[1] != g { - t.Errorf("Expected group %#v, but got %#v", g, p.Groups()[0]) - } - - if g.Options()[0].ShortName != 'g' { - t.Errorf("Expected short name `g' but got %v", g.Options()[0].ShortName) - } -} - -func TestGroupNestedInline(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - - Group struct { - G bool `short:"g"` - - Nested struct { - N string `long:"n"` - } `group:"Nested Options"` - } `group:"Grouped Options"` - }{} - - p, ret := assertParserSuccess(t, &opts, "-v", "-g", "--n", "n", "rest") - - assertStringArray(t, ret, []string{"rest"}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - if !opts.Group.G { - t.Errorf("Expected Group.G to be true") - } - - assertString(t, opts.Group.Nested.N, "n") - - if p.Command.Group.Find("Grouped Options") == nil { - t.Errorf("Expected to find group `Grouped Options'") - } - - if p.Command.Group.Find("Nested Options") == nil { - t.Errorf("Expected to find group `Nested Options'") - } -} - -func TestGroupNestedInlineNamespace(t *testing.T) { - var opts = struct { - Opt string `long:"opt"` - - Group struct { - Opt string `long:"opt"` - Group struct { - Opt string `long:"opt"` - } `group:"Subsubgroup" namespace:"sap"` - } `group:"Subgroup" namespace:"sip"` - }{} - - p, ret := assertParserSuccess(t, &opts, "--opt", "a", "--sip.opt", "b", "--sip.sap.opt", "c", "rest") - - assertStringArray(t, ret, []string{"rest"}) - - assertString(t, opts.Opt, "a") - assertString(t, opts.Group.Opt, "b") - assertString(t, opts.Group.Group.Opt, "c") - - for _, name := range []string{"Subgroup", "Subsubgroup"} { - if p.Command.Group.Find(name) == nil { - t.Errorf("Expected to find group '%s'", name) - } - } -} - -func TestDuplicateShortFlags(t *testing.T) { - var opts struct { - Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` - Variables []string `short:"v" long:"variable" description:"Set a variable value."` - } - - args := []string{ - "--verbose", - "-v", "123", - "-v", "456", - } - - _, err := ParseArgs(&opts, args) - - if err == nil { - t.Errorf("Expected an error with type ErrDuplicatedFlag") - } else { - err2 := err.(*Error) - if err2.Type != ErrDuplicatedFlag { - t.Errorf("Expected an error with type ErrDuplicatedFlag") - } - } -} - -func TestDuplicateLongFlags(t *testing.T) { - var opts struct { - Test1 []bool `short:"a" long:"testing" description:"Test 1"` - Test2 []string `short:"b" long:"testing" description:"Test 2."` - } - - args := []string{ - "--testing", - } - - _, err := ParseArgs(&opts, args) - - if err == nil { - t.Errorf("Expected an error with type ErrDuplicatedFlag") - } else { - err2 := err.(*Error) - if err2.Type != ErrDuplicatedFlag { - t.Errorf("Expected an error with type ErrDuplicatedFlag") - } - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/help.go b/vendor/src/github.com/jessevdk/go-flags/help.go deleted file mode 100644 index e26fcd0..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/help.go +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright 2012 Jesse van den Kieboom. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flags - -import ( - "bufio" - "bytes" - "fmt" - "io" - "reflect" - "runtime" - "strings" - "unicode/utf8" -) - -type alignmentInfo struct { - maxLongLen int - hasShort bool - hasValueName bool - terminalColumns int - indent bool -} - -const ( - paddingBeforeOption = 2 - distanceBetweenOptionAndDescription = 2 -) - -func (a *alignmentInfo) descriptionStart() int { - ret := a.maxLongLen + distanceBetweenOptionAndDescription - - if a.hasShort { - ret += 2 - } - - if a.maxLongLen > 0 { - ret += 4 - } - - if a.hasValueName { - ret += 3 - } - - return ret -} - -func (a *alignmentInfo) updateLen(name string, indent bool) { - l := utf8.RuneCountInString(name) - - if indent { - l = l + 4 - } - - if l > a.maxLongLen { - a.maxLongLen = l - } -} - -func (p *Parser) getAlignmentInfo() alignmentInfo { - ret := alignmentInfo{ - maxLongLen: 0, - hasShort: false, - hasValueName: false, - terminalColumns: getTerminalColumns(), - } - - if ret.terminalColumns <= 0 { - ret.terminalColumns = 80 - } - - var prevcmd *Command - - p.eachActiveGroup(func(c *Command, grp *Group) { - if c != prevcmd { - for _, arg := range c.args { - ret.updateLen(arg.Name, c != p.Command) - } - } - - for _, info := range grp.options { - if !info.canCli() { - continue - } - - if info.ShortName != 0 { - ret.hasShort = true - } - - if len(info.ValueName) > 0 { - ret.hasValueName = true - } - - ret.updateLen(info.LongNameWithNamespace()+info.ValueName, c != p.Command) - } - }) - - return ret -} - -func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) { - line := &bytes.Buffer{} - - prefix := paddingBeforeOption - - if info.indent { - prefix += 4 - } - - line.WriteString(strings.Repeat(" ", prefix)) - - if option.ShortName != 0 { - line.WriteRune(defaultShortOptDelimiter) - line.WriteRune(option.ShortName) - } else if info.hasShort { - line.WriteString(" ") - } - - descstart := info.descriptionStart() + paddingBeforeOption - - if len(option.LongName) > 0 { - if option.ShortName != 0 { - line.WriteString(", ") - } else if info.hasShort { - line.WriteString(" ") - } - - line.WriteString(defaultLongOptDelimiter) - line.WriteString(option.LongNameWithNamespace()) - } - - if option.canArgument() { - line.WriteRune(defaultNameArgDelimiter) - - if len(option.ValueName) > 0 { - line.WriteString(option.ValueName) - } - } - - written := line.Len() - line.WriteTo(writer) - - if option.Description != "" { - dw := descstart - written - writer.WriteString(strings.Repeat(" ", dw)) - - def := "" - defs := option.Default - - if len(option.DefaultMask) != 0 { - if option.DefaultMask != "-" { - def = option.DefaultMask - } - } else if len(defs) == 0 && option.canArgument() { - var showdef bool - - switch option.field.Type.Kind() { - case reflect.Func, reflect.Ptr: - showdef = !option.value.IsNil() - case reflect.Slice, reflect.String, reflect.Array: - showdef = option.value.Len() > 0 - case reflect.Map: - showdef = !option.value.IsNil() && option.value.Len() > 0 - default: - zeroval := reflect.Zero(option.field.Type) - showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface()) - } - - if showdef { - def, _ = convertToString(option.value, option.tag) - } - } else if len(defs) != 0 { - l := len(defs) - 1 - - for i := 0; i < l; i++ { - def += quoteIfNeeded(defs[i]) + ", " - } - - def += quoteIfNeeded(defs[l]) - } - - var envDef string - if option.EnvDefaultKey != "" { - var envPrintable string - if runtime.GOOS == "windows" { - envPrintable = "%" + option.EnvDefaultKey + "%" - } else { - envPrintable = "$" + option.EnvDefaultKey - } - envDef = fmt.Sprintf(" [%s]", envPrintable) - } - - var desc string - - if def != "" { - desc = fmt.Sprintf("%s (%v)%s", option.Description, def, envDef) - } else { - desc = option.Description + envDef - } - - writer.WriteString(wrapText(desc, - info.terminalColumns-descstart, - strings.Repeat(" ", descstart))) - } - - writer.WriteString("\n") -} - -func maxCommandLength(s []*Command) int { - if len(s) == 0 { - return 0 - } - - ret := len(s[0].Name) - - for _, v := range s[1:] { - l := len(v.Name) - - if l > ret { - ret = l - } - } - - return ret -} - -// WriteHelp writes a help message containing all the possible options and -// their descriptions to the provided writer. Note that the HelpFlag parser -// option provides a convenient way to add a -h/--help option group to the -// command line parser which will automatically show the help messages using -// this method. -func (p *Parser) WriteHelp(writer io.Writer) { - if writer == nil { - return - } - - wr := bufio.NewWriter(writer) - aligninfo := p.getAlignmentInfo() - - cmd := p.Command - - for cmd.Active != nil { - cmd = cmd.Active - } - - if p.Name != "" { - wr.WriteString("Usage:\n") - wr.WriteString(" ") - - allcmd := p.Command - - for allcmd != nil { - var usage string - - if allcmd == p.Command { - if len(p.Usage) != 0 { - usage = p.Usage - } else if p.Options&HelpFlag != 0 { - usage = "[OPTIONS]" - } - } else if us, ok := allcmd.data.(Usage); ok { - usage = us.Usage() - } else if allcmd.hasCliOptions() { - usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name) - } - - if len(usage) != 0 { - fmt.Fprintf(wr, " %s %s", allcmd.Name, usage) - } else { - fmt.Fprintf(wr, " %s", allcmd.Name) - } - - if len(allcmd.args) > 0 { - fmt.Fprintf(wr, " ") - } - - for i, arg := range allcmd.args { - if i != 0 { - fmt.Fprintf(wr, " ") - } - - name := arg.Name - - if arg.isRemaining() { - name = name + "..." - } - - if !allcmd.ArgsRequired { - fmt.Fprintf(wr, "[%s]", name) - } else { - fmt.Fprintf(wr, "%s", name) - } - } - - if allcmd.Active == nil && len(allcmd.commands) > 0 { - var co, cc string - - if allcmd.SubcommandsOptional { - co, cc = "[", "]" - } else { - co, cc = "<", ">" - } - - if len(allcmd.commands) > 3 { - fmt.Fprintf(wr, " %scommand%s", co, cc) - } else { - subcommands := allcmd.sortedCommands() - names := make([]string, len(subcommands)) - - for i, subc := range subcommands { - names[i] = subc.Name - } - - fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc) - } - } - - allcmd = allcmd.Active - } - - fmt.Fprintln(wr) - - if len(cmd.LongDescription) != 0 { - fmt.Fprintln(wr) - - t := wrapText(cmd.LongDescription, - aligninfo.terminalColumns, - "") - - fmt.Fprintln(wr, t) - } - } - - c := p.Command - - for c != nil { - printcmd := c != p.Command - - c.eachGroup(func(grp *Group) { - first := true - - // Skip built-in help group for all commands except the top-level - // parser - if grp.isBuiltinHelp && c != p.Command { - return - } - - for _, info := range grp.options { - if !info.canCli() { - continue - } - - if printcmd { - fmt.Fprintf(wr, "\n[%s command options]\n", c.Name) - aligninfo.indent = true - printcmd = false - } - - if first && cmd.Group != grp { - fmt.Fprintln(wr) - - if aligninfo.indent { - wr.WriteString(" ") - } - - fmt.Fprintf(wr, "%s:\n", grp.ShortDescription) - first = false - } - - p.writeHelpOption(wr, info, aligninfo) - } - }) - - if len(c.args) > 0 { - if c == p.Command { - fmt.Fprintf(wr, "\nArguments:\n") - } else { - fmt.Fprintf(wr, "\n[%s command arguments]\n", c.Name) - } - - maxlen := aligninfo.descriptionStart() - - for _, arg := range c.args { - prefix := strings.Repeat(" ", paddingBeforeOption) - fmt.Fprintf(wr, "%s%s", prefix, arg.Name) - - if len(arg.Description) > 0 { - align := strings.Repeat(" ", maxlen-len(arg.Name)-1) - fmt.Fprintf(wr, ":%s%s", align, arg.Description) - } - - fmt.Fprintln(wr) - } - } - - c = c.Active - } - - scommands := cmd.sortedCommands() - - if len(scommands) > 0 { - maxnamelen := maxCommandLength(scommands) - - fmt.Fprintln(wr) - fmt.Fprintln(wr, "Available commands:") - - for _, c := range scommands { - fmt.Fprintf(wr, " %s", c.Name) - - if len(c.ShortDescription) > 0 { - pad := strings.Repeat(" ", maxnamelen-len(c.Name)) - fmt.Fprintf(wr, "%s %s", pad, c.ShortDescription) - - if len(c.Aliases) > 0 { - fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", ")) - } - - } - - fmt.Fprintln(wr) - } - } - - wr.Flush() -} diff --git a/vendor/src/github.com/jessevdk/go-flags/help_test.go b/vendor/src/github.com/jessevdk/go-flags/help_test.go deleted file mode 100644 index e10f4b6..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/help_test.go +++ /dev/null @@ -1,300 +0,0 @@ -package flags - -import ( - "bytes" - "fmt" - "os" - "runtime" - "testing" - "time" -) - -type helpOptions struct { - Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information" ini-name:"verbose"` - Call func(string) `short:"c" description:"Call phone number" ini-name:"call"` - PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` - EmptyDescription bool `long:"empty-description"` - - Default string `long:"default" default:"Some\nvalue" description:"Test default value"` - DefaultArray []string `long:"default-array" default:"Some value" default:"Other\tvalue" description:"Test default array value"` - DefaultMap map[string]string `long:"default-map" default:"some:value" default:"another:value" description:"Testdefault map value"` - EnvDefault1 string `long:"env-default1" default:"Some value" env:"ENV_DEFAULT" description:"Test env-default1 value"` - EnvDefault2 string `long:"env-default2" env:"ENV_DEFAULT" description:"Test env-default2 value"` - OptionWithArgName string `long:"opt-with-arg-name" value-name:"something" description:"Option with named argument"` - - OnlyIni string `ini-name:"only-ini" description:"Option only available in ini"` - - Other struct { - StringSlice []string `short:"s" default:"some" default:"value" description:"A slice of strings"` - IntMap map[string]int `long:"intmap" default:"a:1" description:"A map from string to int" ini-name:"int-map"` - } `group:"Other Options"` - - Group struct { - Opt string `long:"opt" description:"This is a subgroup option"` - - Group struct { - Opt string `long:"opt" description:"This is a subsubgroup option"` - } `group:"Subsubgroup" namespace:"sap"` - } `group:"Subgroup" namespace:"sip"` - - Command struct { - ExtraVerbose []bool `long:"extra-verbose" description:"Use for extra verbosity"` - } `command:"command" alias:"cm" alias:"cmd" description:"A command"` - - Args struct { - Filename string `positional-arg-name:"filename" description:"A filename"` - Number int `positional-arg-name:"num" description:"A number"` - } `positional-args:"yes"` -} - -func TestHelp(t *testing.T) { - oldEnv := EnvSnapshot() - defer oldEnv.Restore() - os.Setenv("ENV_DEFAULT", "env-def") - - var opts helpOptions - p := NewNamedParser("TestHelp", HelpFlag) - p.AddGroup("Application Options", "The application options", &opts) - - _, err := p.ParseArgs([]string{"--help"}) - - if err == nil { - t.Fatalf("Expected help error") - } - - if e, ok := err.(*Error); !ok { - t.Fatalf("Expected flags.Error, but got %T", err) - } else { - if e.Type != ErrHelp { - t.Errorf("Expected flags.ErrHelp type, but got %s", e.Type) - } - - var expected string - - if runtime.GOOS == "windows" { - expected = `Usage: - TestHelp [OPTIONS] [filename] [num] - -Application Options: - /v, /verbose Show verbose debug information - /c: Call phone number - /ptrslice: A slice of pointers to string - /empty-description - /default: Test default value ("Some\nvalue") - /default-array: Test default array value (Some value, "Other\tvalue") - /default-map: Testdefault map value (some:value, another:value) - /env-default1: Test env-default1 value (Some value) [%ENV_DEFAULT%] - /env-default2: Test env-default2 value [%ENV_DEFAULT%] - /opt-with-arg-name:something Option with named argument - -Other Options: - /s: A slice of strings (some, value) - /intmap: A map from string to int (a:1) - -Subgroup: - /sip.opt: This is a subgroup option - -Subsubgroup: - /sip.sap.opt: This is a subsubgroup option - -Help Options: - /? Show this help message - /h, /help Show this help message - -Arguments: - filename: A filename - num: A number - -Available commands: - command A command (aliases: cm, cmd) -` - } else { - expected = `Usage: - TestHelp [OPTIONS] [filename] [num] - -Application Options: - -v, --verbose Show verbose debug information - -c= Call phone number - --ptrslice= A slice of pointers to string - --empty-description - --default= Test default value ("Some\nvalue") - --default-array= Test default array value (Some value, - "Other\tvalue") - --default-map= Testdefault map value (some:value, - another:value) - --env-default1= Test env-default1 value (Some value) - [$ENV_DEFAULT] - --env-default2= Test env-default2 value [$ENV_DEFAULT] - --opt-with-arg-name=something Option with named argument - -Other Options: - -s= A slice of strings (some, value) - --intmap= A map from string to int (a:1) - -Subgroup: - --sip.opt= This is a subgroup option - -Subsubgroup: - --sip.sap.opt= This is a subsubgroup option - -Help Options: - -h, --help Show this help message - -Arguments: - filename: A filename - num: A number - -Available commands: - command A command (aliases: cm, cmd) -` - } - - assertDiff(t, e.Message, expected, "help message") - } -} - -func TestMan(t *testing.T) { - oldEnv := EnvSnapshot() - defer oldEnv.Restore() - os.Setenv("ENV_DEFAULT", "env-def") - - var opts helpOptions - p := NewNamedParser("TestMan", HelpFlag) - p.ShortDescription = "Test manpage generation" - p.LongDescription = "This is a somewhat `longer' description of what this does" - p.AddGroup("Application Options", "The application options", &opts) - - p.Commands()[0].LongDescription = "Longer `command' description" - - var buf bytes.Buffer - p.WriteManPage(&buf) - - got := buf.String() - - tt := time.Now() - - var envDefaultName string - - if runtime.GOOS == "windows" { - envDefaultName = "%ENV_DEFAULT%" - } else { - envDefaultName = "$ENV_DEFAULT" - } - - expected := fmt.Sprintf(`.TH TestMan 1 "%s" -.SH NAME -TestMan \- Test manpage generation -.SH SYNOPSIS -\fBTestMan\fP [OPTIONS] -.SH DESCRIPTION -This is a somewhat \fBlonger\fP description of what this does -.SH OPTIONS -.TP -\fB\fB\-v\fR, \fB\-\-verbose\fR\fP -Show verbose debug information -.TP -\fB\fB\-c\fR\fP -Call phone number -.TP -\fB\fB\-\-ptrslice\fR\fP -A slice of pointers to string -.TP -\fB\fB\-\-empty-description\fR\fP -.TP -\fB\fB\-\-default\fR \fP -Test default value -.TP -\fB\fB\-\-default-array\fR \fP -Test default array value -.TP -\fB\fB\-\-default-map\fR \fP -Testdefault map value -.TP -\fB\fB\-\-env-default1\fR \fP -Test env-default1 value -.TP -\fB\fB\-\-env-default2\fR \fP -Test env-default2 value -.TP -\fB\fB\-\-opt-with-arg-name\fR \fIsomething\fR\fP -Option with named argument -.TP -\fB\fB\-s\fR \fP -A slice of strings -.TP -\fB\fB\-\-intmap\fR \fP -A map from string to int -.TP -\fB\fB\-\-sip.opt\fR\fP -This is a subgroup option -.TP -\fB\fB\-\-sip.sap.opt\fR\fP -This is a subsubgroup option -.SH COMMANDS -.SS command -A command - -Longer \fBcommand\fP description - -\fBUsage\fP: TestMan [OPTIONS] command [command-OPTIONS] - - -\fBAliases\fP: cm, cmd - -.TP -\fB\fB\-\-extra-verbose\fR\fP -Use for extra verbosity -`, tt.Format("2 January 2006"), envDefaultName) - - assertDiff(t, got, expected, "man page") -} - -type helpCommandNoOptions struct { - Command struct { - } `command:"command" description:"A command"` -} - -func TestHelpCommand(t *testing.T) { - oldEnv := EnvSnapshot() - defer oldEnv.Restore() - os.Setenv("ENV_DEFAULT", "env-def") - - var opts helpCommandNoOptions - p := NewNamedParser("TestHelpCommand", HelpFlag) - p.AddGroup("Application Options", "The application options", &opts) - - _, err := p.ParseArgs([]string{"command", "--help"}) - - if err == nil { - t.Fatalf("Expected help error") - } - - if e, ok := err.(*Error); !ok { - t.Fatalf("Expected flags.Error, but got %T", err) - } else { - if e.Type != ErrHelp { - t.Errorf("Expected flags.ErrHelp type, but got %s", e.Type) - } - - var expected string - - if runtime.GOOS == "windows" { - expected = `Usage: - TestHelpCommand [OPTIONS] command - -Help Options: - /? Show this help message - /h, /help Show this help message -` - } else { - expected = `Usage: - TestHelpCommand [OPTIONS] command - -Help Options: - -h, --help Show this help message -` - } - - assertDiff(t, e.Message, expected, "help message") - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/ini.go b/vendor/src/github.com/jessevdk/go-flags/ini.go deleted file mode 100644 index 7225052..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/ini.go +++ /dev/null @@ -1,140 +0,0 @@ -package flags - -import ( - "fmt" - "io" -) - -// IniError contains location information on where an error occured. -type IniError struct { - // The error message. - Message string - - // The filename of the file in which the error occurred. - File string - - // The line number at which the error occurred. - LineNumber uint -} - -// Error provides a "file:line: message" formatted message of the ini error. -func (x *IniError) Error() string { - return fmt.Sprintf( - "%s:%d: %s", - x.File, - x.LineNumber, - x.Message, - ) -} - -// IniOptions for writing -type IniOptions uint - -const ( - // IniNone indicates no options. - IniNone IniOptions = 0 - - // IniIncludeDefaults indicates that default values should be written. - IniIncludeDefaults = 1 << iota - - // IniCommentDefaults indicates that if IniIncludeDefaults is used - // options with default values are written but commented out. - IniCommentDefaults - - // IniIncludeComments indicates that comments containing the description - // of an option should be written. - IniIncludeComments - - // IniDefault provides a default set of options. - IniDefault = IniIncludeComments -) - -// IniParser is a utility to read and write flags options from and to ini -// formatted strings. -type IniParser struct { - parser *Parser -} - -// NewIniParser creates a new ini parser for a given Parser. -func NewIniParser(p *Parser) *IniParser { - return &IniParser{ - parser: p, - } -} - -// IniParse is a convenience function to parse command line options with default -// settings from an ini formatted file. The provided data is a pointer to a struct -// representing the default option group (named "Application Options"). For -// more control, use flags.NewParser. -func IniParse(filename string, data interface{}) error { - p := NewParser(data, Default) - - return NewIniParser(p).ParseFile(filename) -} - -// ParseFile parses flags from an ini formatted file. See Parse for more -// information on the ini file format. The returned errors can be of the type -// flags.Error or flags.IniError. -func (i *IniParser) ParseFile(filename string) error { - i.parser.clearIsSet() - - ini, err := readIniFromFile(filename) - - if err != nil { - return err - } - - return i.parse(ini) -} - -// Parse parses flags from an ini format. You can use ParseFile as a -// convenience function to parse from a filename instead of a general -// io.Reader. -// -// The format of the ini file is as follows: -// -// [Option group name] -// option = value -// -// Each section in the ini file represents an option group or command in the -// flags parser. The default flags parser option group (i.e. when using -// flags.Parse) is named 'Application Options'. The ini option name is matched -// in the following order: -// -// 1. Compared to the ini-name tag on the option struct field (if present) -// 2. Compared to the struct field name -// 3. Compared to the option long name (if present) -// 4. Compared to the option short name (if present) -// -// Sections for nested groups and commands can be addressed using a dot `.' -// namespacing notation (i.e [subcommand.Options]). Group section names are -// matched case insensitive. -// -// The returned errors can be of the type flags.Error or flags.IniError. -func (i *IniParser) Parse(reader io.Reader) error { - i.parser.clearIsSet() - - ini, err := readIni(reader, "") - - if err != nil { - return err - } - - return i.parse(ini) -} - -// WriteFile writes the flags as ini format into a file. See WriteIni -// for more information. The returned error occurs when the specified file -// could not be opened for writing. -func (i *IniParser) WriteFile(filename string, options IniOptions) error { - return writeIniToFile(i, filename, options) -} - -// Write writes the current values of all the flags to an ini format. -// See Parse for more information on the ini file format. You typically -// call this only after settings have been parsed since the default values of each -// option are stored just before parsing the flags (this is only relevant when -// IniIncludeDefaults is _not_ set in options). -func (i *IniParser) Write(writer io.Writer, options IniOptions) { - writeIni(i, writer, options) -} diff --git a/vendor/src/github.com/jessevdk/go-flags/ini_private.go b/vendor/src/github.com/jessevdk/go-flags/ini_private.go deleted file mode 100644 index 887aa76..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/ini_private.go +++ /dev/null @@ -1,452 +0,0 @@ -package flags - -import ( - "bufio" - "fmt" - "io" - "os" - "reflect" - "sort" - "strconv" - "strings" -) - -type iniValue struct { - Name string - Value string - Quoted bool - LineNumber uint -} - -type iniSection []iniValue -type ini struct { - File string - Sections map[string]iniSection -} - -func readFullLine(reader *bufio.Reader) (string, error) { - var line []byte - - for { - l, more, err := reader.ReadLine() - - if err != nil { - return "", err - } - - if line == nil && !more { - return string(l), nil - } - - line = append(line, l...) - - if !more { - break - } - } - - return string(line), nil -} - -func optionIniName(option *Option) string { - name := option.tag.Get("_read-ini-name") - - if len(name) != 0 { - return name - } - - name = option.tag.Get("ini-name") - - if len(name) != 0 { - return name - } - - return option.field.Name -} - -func writeGroupIni(cmd *Command, group *Group, namespace string, writer io.Writer, options IniOptions) { - var sname string - - if len(namespace) != 0 { - sname = namespace - } - - if cmd.Group != group && len(group.ShortDescription) != 0 { - if len(sname) != 0 { - sname += "." - } - - sname += group.ShortDescription - } - - sectionwritten := false - comments := (options & IniIncludeComments) != IniNone - - for _, option := range group.options { - if option.isFunc() { - continue - } - - if len(option.tag.Get("no-ini")) != 0 { - continue - } - - val := option.value - - if (options&IniIncludeDefaults) == IniNone && option.valueIsDefault() { - continue - } - - if !sectionwritten { - fmt.Fprintf(writer, "[%s]\n", sname) - sectionwritten = true - } - - if comments && len(option.Description) != 0 { - fmt.Fprintf(writer, "; %s\n", option.Description) - } - - oname := optionIniName(option) - - commentOption := (options&(IniIncludeDefaults|IniCommentDefaults)) == IniIncludeDefaults|IniCommentDefaults && option.valueIsDefault() - - kind := val.Type().Kind() - switch kind { - case reflect.Slice: - kind = val.Type().Elem().Kind() - - if val.Len() == 0 { - writeOption(writer, oname, kind, "", "", true, option.iniQuote) - } else { - for idx := 0; idx < val.Len(); idx++ { - v, _ := convertToString(val.Index(idx), option.tag) - - writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote) - } - } - case reflect.Map: - kind = val.Type().Elem().Kind() - - if val.Len() == 0 { - writeOption(writer, oname, kind, "", "", true, option.iniQuote) - } else { - mkeys := val.MapKeys() - keys := make([]string, len(val.MapKeys())) - kkmap := make(map[string]reflect.Value) - - for i, k := range mkeys { - keys[i], _ = convertToString(k, option.tag) - kkmap[keys[i]] = k - } - - sort.Strings(keys) - - for _, k := range keys { - v, _ := convertToString(val.MapIndex(kkmap[k]), option.tag) - - writeOption(writer, oname, kind, k, v, commentOption, option.iniQuote) - } - } - default: - v, _ := convertToString(val, option.tag) - - writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote) - } - - if comments { - fmt.Fprintln(writer) - } - } - - if sectionwritten && !comments { - fmt.Fprintln(writer) - } -} - -func writeOption(writer io.Writer, optionName string, optionType reflect.Kind, optionKey string, optionValue string, commentOption bool, forceQuote bool) { - if forceQuote || (optionType == reflect.String && !isPrint(optionValue)) { - optionValue = strconv.Quote(optionValue) - } - - comment := "" - if commentOption { - comment = "; " - } - - fmt.Fprintf(writer, "%s%s =", comment, optionName) - - if optionKey != "" { - fmt.Fprintf(writer, " %s:%s", optionKey, optionValue) - } else if optionValue != "" { - fmt.Fprintf(writer, " %s", optionValue) - } - - fmt.Fprintln(writer) -} - -func writeCommandIni(command *Command, namespace string, writer io.Writer, options IniOptions) { - command.eachGroup(func(group *Group) { - writeGroupIni(command, group, namespace, writer, options) - }) - - for _, c := range command.commands { - var nns string - - if len(namespace) != 0 { - nns = c.Name + "." + nns - } else { - nns = c.Name - } - - writeCommandIni(c, nns, writer, options) - } -} - -func writeIni(parser *IniParser, writer io.Writer, options IniOptions) { - writeCommandIni(parser.parser.Command, "", writer, options) -} - -func writeIniToFile(parser *IniParser, filename string, options IniOptions) error { - file, err := os.Create(filename) - - if err != nil { - return err - } - - defer file.Close() - - writeIni(parser, file, options) - - return nil -} - -func readIniFromFile(filename string) (*ini, error) { - file, err := os.Open(filename) - - if err != nil { - return nil, err - } - - defer file.Close() - - return readIni(file, filename) -} - -func readIni(contents io.Reader, filename string) (*ini, error) { - ret := &ini{ - File: filename, - Sections: make(map[string]iniSection), - } - - reader := bufio.NewReader(contents) - - // Empty global section - section := make(iniSection, 0, 10) - sectionname := "" - - ret.Sections[sectionname] = section - - var lineno uint - - for { - line, err := readFullLine(reader) - - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - - lineno++ - line = strings.TrimSpace(line) - - // Skip empty lines and lines starting with ; (comments) - if len(line) == 0 || line[0] == ';' || line[0] == '#' { - continue - } - - if line[0] == '[' { - if line[0] != '[' || line[len(line)-1] != ']' { - return nil, &IniError{ - Message: "malformed section header", - File: filename, - LineNumber: lineno, - } - } - - name := strings.TrimSpace(line[1 : len(line)-1]) - - if len(name) == 0 { - return nil, &IniError{ - Message: "empty section name", - File: filename, - LineNumber: lineno, - } - } - - sectionname = name - section = ret.Sections[name] - - if section == nil { - section = make(iniSection, 0, 10) - ret.Sections[name] = section - } - - continue - } - - // Parse option here - keyval := strings.SplitN(line, "=", 2) - - if len(keyval) != 2 { - return nil, &IniError{ - Message: fmt.Sprintf("malformed key=value (%s)", line), - File: filename, - LineNumber: lineno, - } - } - - name := strings.TrimSpace(keyval[0]) - value := strings.TrimSpace(keyval[1]) - quoted := false - - if len(value) != 0 && value[0] == '"' { - if v, err := strconv.Unquote(value); err == nil { - value = v - - quoted = true - } else { - return nil, &IniError{ - Message: err.Error(), - File: filename, - LineNumber: lineno, - } - } - } - - section = append(section, iniValue{ - Name: name, - Value: value, - Quoted: quoted, - LineNumber: lineno, - }) - - ret.Sections[sectionname] = section - } - - return ret, nil -} - -func (i *IniParser) matchingGroups(name string) []*Group { - if len(name) == 0 { - var ret []*Group - - i.parser.eachGroup(func(g *Group) { - ret = append(ret, g) - }) - - return ret - } - - g := i.parser.groupByName(name) - - if g != nil { - return []*Group{g} - } - - return nil -} - -func (i *IniParser) parse(ini *ini) error { - p := i.parser - - var quotesLookup = make(map[*Option]bool) - - for name, section := range ini.Sections { - groups := i.matchingGroups(name) - - if len(groups) == 0 { - return newErrorf(ErrUnknownGroup, "could not find option group `%s'", name) - } - - for _, inival := range section { - var opt *Option - - for _, group := range groups { - opt = group.optionByName(inival.Name, func(o *Option, n string) bool { - return strings.ToLower(o.tag.Get("ini-name")) == strings.ToLower(n) - }) - - if opt != nil && len(opt.tag.Get("no-ini")) != 0 { - opt = nil - } - - if opt != nil { - break - } - } - - if opt == nil { - if (p.Options & IgnoreUnknown) == None { - return &IniError{ - Message: fmt.Sprintf("unknown option: %s", inival.Name), - File: ini.File, - LineNumber: inival.LineNumber, - } - } - - continue - } - - pval := &inival.Value - - if !opt.canArgument() && len(inival.Value) == 0 { - pval = nil - } else { - if opt.value.Type().Kind() == reflect.Map { - parts := strings.SplitN(inival.Value, ":", 2) - - // only handle unquoting - if len(parts) == 2 && parts[1][0] == '"' { - if v, err := strconv.Unquote(parts[1]); err == nil { - parts[1] = v - - inival.Quoted = true - } else { - return &IniError{ - Message: err.Error(), - File: ini.File, - LineNumber: inival.LineNumber, - } - } - - s := parts[0] + ":" + parts[1] - - pval = &s - } - } - } - - if err := opt.set(pval); err != nil { - return &IniError{ - Message: err.Error(), - File: ini.File, - LineNumber: inival.LineNumber, - } - } - - // either all INI values are quoted or only values who need quoting - if _, ok := quotesLookup[opt]; !inival.Quoted || !ok { - quotesLookup[opt] = inival.Quoted - } - - opt.tag.Set("_read-ini-name", inival.Name) - } - } - - for opt, quoted := range quotesLookup { - opt.iniQuote = quoted - } - - return nil -} diff --git a/vendor/src/github.com/jessevdk/go-flags/ini_test.go b/vendor/src/github.com/jessevdk/go-flags/ini_test.go deleted file mode 100644 index 215b757..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/ini_test.go +++ /dev/null @@ -1,767 +0,0 @@ -package flags - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "reflect" - "strings" - "testing" -) - -func TestWriteIni(t *testing.T) { - oldEnv := EnvSnapshot() - defer oldEnv.Restore() - os.Setenv("ENV_DEFAULT", "env-def") - - var tests = []struct { - args []string - options IniOptions - expected string - }{ - { - []string{"-vv", "--intmap=a:2", "--intmap", "b:3", "filename", "0", "command"}, - IniDefault, - `[Application Options] -; Show verbose debug information -verbose = true -verbose = true - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -[Other Options] -; A map from string to int -int-map = a:2 -int-map = b:3 - -`, - }, - { - []string{"-vv", "--intmap=a:2", "--intmap", "b:3", "filename", "0", "command"}, - IniDefault | IniIncludeDefaults, - `[Application Options] -; Show verbose debug information -verbose = true -verbose = true - -; A slice of pointers to string -; PtrSlice = - -EmptyDescription = false - -; Test default value -Default = "Some\nvalue" - -; Test default array value -DefaultArray = Some value -DefaultArray = "Other\tvalue" - -; Testdefault map value -DefaultMap = another:value -DefaultMap = some:value - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -; Option with named argument -OptionWithArgName = - -; Option only available in ini -only-ini = - -[Other Options] -; A slice of strings -StringSlice = some -StringSlice = value - -; A map from string to int -int-map = a:2 -int-map = b:3 - -[Subgroup] -; This is a subgroup option -Opt = - -[Subsubgroup] -; This is a subsubgroup option -Opt = - -[command] -; Use for extra verbosity -; ExtraVerbose = - -`, - }, - { - []string{"filename", "0", "command"}, - IniDefault | IniIncludeDefaults | IniCommentDefaults, - `[Application Options] -; Show verbose debug information -; verbose = - -; A slice of pointers to string -; PtrSlice = - -; EmptyDescription = false - -; Test default value -; Default = "Some\nvalue" - -; Test default array value -; DefaultArray = Some value -; DefaultArray = "Other\tvalue" - -; Testdefault map value -; DefaultMap = another:value -; DefaultMap = some:value - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -; Option with named argument -; OptionWithArgName = - -; Option only available in ini -; only-ini = - -[Other Options] -; A slice of strings -; StringSlice = some -; StringSlice = value - -; A map from string to int -; int-map = a:1 - -[Subgroup] -; This is a subgroup option -; Opt = - -[Subsubgroup] -; This is a subsubgroup option -; Opt = - -[command] -; Use for extra verbosity -; ExtraVerbose = - -`, - }, - { - []string{"--default=New value", "--default-array=New value", "--default-map=new:value", "filename", "0", "command"}, - IniDefault | IniIncludeDefaults | IniCommentDefaults, - `[Application Options] -; Show verbose debug information -; verbose = - -; A slice of pointers to string -; PtrSlice = - -; EmptyDescription = false - -; Test default value -Default = New value - -; Test default array value -DefaultArray = New value - -; Testdefault map value -DefaultMap = new:value - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -; Option with named argument -; OptionWithArgName = - -; Option only available in ini -; only-ini = - -[Other Options] -; A slice of strings -; StringSlice = some -; StringSlice = value - -; A map from string to int -; int-map = a:1 - -[Subgroup] -; This is a subgroup option -; Opt = - -[Subsubgroup] -; This is a subsubgroup option -; Opt = - -[command] -; Use for extra verbosity -; ExtraVerbose = - -`, - }, - } - - for _, test := range tests { - var opts helpOptions - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - _, err := p.ParseArgs(test.args) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - inip := NewIniParser(p) - - var b bytes.Buffer - inip.Write(&b, test.options) - - got := b.String() - expected := test.expected - - msg := fmt.Sprintf("with arguments %+v and ini options %b", test.args, test.options) - assertDiff(t, got, expected, msg) - } -} - -func TestReadIni(t *testing.T) { - var opts helpOptions - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - inic := ` -; Show verbose debug information -verbose = true -verbose = true - -DefaultMap = another:"value\n1" -DefaultMap = some:value 2 - -[Application Options] -; A slice of pointers to string -; PtrSlice = - -; Test default value -Default = "New\nvalue" - -; Test env-default1 value -EnvDefault1 = New value - -[Other Options] -# A slice of strings -StringSlice = "some\nvalue" -StringSlice = another value - -; A map from string to int -int-map = a:2 -int-map = b:3 - -` - - b := strings.NewReader(inic) - err := inip.Parse(b) - - if err != nil { - t.Fatalf("Unexpected error: %s", err) - } - - assertBoolArray(t, opts.Verbose, []bool{true, true}) - - if v := map[string]string{"another": "value\n1", "some": "value 2"}; !reflect.DeepEqual(opts.DefaultMap, v) { - t.Fatalf("Expected %#v for DefaultMap but got %#v", v, opts.DefaultMap) - } - - assertString(t, opts.Default, "New\nvalue") - - assertString(t, opts.EnvDefault1, "New value") - - assertStringArray(t, opts.Other.StringSlice, []string{"some\nvalue", "another value"}) - - if v, ok := opts.Other.IntMap["a"]; !ok { - t.Errorf("Expected \"a\" in Other.IntMap") - } else if v != 2 { - t.Errorf("Expected Other.IntMap[\"a\"] = 2, but got %v", v) - } - - if v, ok := opts.Other.IntMap["b"]; !ok { - t.Errorf("Expected \"b\" in Other.IntMap") - } else if v != 3 { - t.Errorf("Expected Other.IntMap[\"b\"] = 3, but got %v", v) - } -} - -func TestReadAndWriteIni(t *testing.T) { - var tests = []struct { - options IniOptions - read string - write string - }{ - { - IniIncludeComments, - `[Application Options] -; Show verbose debug information -verbose = true -verbose = true - -; Test default value -Default = "quote me" - -; Test default array value -DefaultArray = 1 -DefaultArray = "2" -DefaultArray = 3 - -; Testdefault map value -; DefaultMap = - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -[Other Options] -; A slice of strings -; StringSlice = - -; A map from string to int -int-map = a:2 -int-map = b:"3" - -`, - `[Application Options] -; Show verbose debug information -verbose = true -verbose = true - -; Test default value -Default = "quote me" - -; Test default array value -DefaultArray = 1 -DefaultArray = 2 -DefaultArray = 3 - -; Testdefault map value -; DefaultMap = - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -[Other Options] -; A slice of strings -; StringSlice = - -; A map from string to int -int-map = a:2 -int-map = b:3 - -`, - }, - { - IniIncludeComments, - `[Application Options] -; Show verbose debug information -verbose = true -verbose = true - -; Test default value -Default = "quote me" - -; Test default array value -DefaultArray = "1" -DefaultArray = "2" -DefaultArray = "3" - -; Testdefault map value -; DefaultMap = - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -[Other Options] -; A slice of strings -; StringSlice = - -; A map from string to int -int-map = a:"2" -int-map = b:"3" - -`, - `[Application Options] -; Show verbose debug information -verbose = true -verbose = true - -; Test default value -Default = "quote me" - -; Test default array value -DefaultArray = "1" -DefaultArray = "2" -DefaultArray = "3" - -; Testdefault map value -; DefaultMap = - -; Test env-default1 value -EnvDefault1 = env-def - -; Test env-default2 value -EnvDefault2 = env-def - -[Other Options] -; A slice of strings -; StringSlice = - -; A map from string to int -int-map = a:"2" -int-map = b:"3" - -`, - }, - } - - for _, test := range tests { - var opts helpOptions - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - read := strings.NewReader(test.read) - err := inip.Parse(read) - if err != nil { - t.Fatalf("Unexpected error: %s", err) - } - - var write bytes.Buffer - inip.Write(&write, test.options) - - got := write.String() - - msg := fmt.Sprintf("with ini options %b", test.options) - assertDiff(t, got, test.write, msg) - } -} - -func TestReadIniWrongQuoting(t *testing.T) { - var tests = []struct { - iniFile string - lineNumber uint - }{ - { - iniFile: `Default = "New\nvalue`, - lineNumber: 1, - }, - { - iniFile: `StringSlice = "New\nvalue`, - lineNumber: 1, - }, - { - iniFile: `StringSlice = "New\nvalue" - StringSlice = "Second\nvalue`, - lineNumber: 2, - }, - { - iniFile: `DefaultMap = some:"value`, - lineNumber: 1, - }, - { - iniFile: `DefaultMap = some:value - DefaultMap = another:"value`, - lineNumber: 2, - }, - } - - for _, test := range tests { - var opts helpOptions - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - inic := test.iniFile - - b := strings.NewReader(inic) - err := inip.Parse(b) - - if err == nil { - t.Fatalf("Expect error") - } - - iniError := err.(*IniError) - - if iniError.LineNumber != test.lineNumber { - t.Fatalf("Expect error on line %d", test.lineNumber) - } - } -} - -func TestIniCommands(t *testing.T) { - var opts struct { - Value string `short:"v" long:"value"` - - Add struct { - Name int `short:"n" long:"name" ini-name:"AliasName"` - - Other struct { - O string `short:"o" long:"other"` - } `group:"Other Options"` - } `command:"add"` - } - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - inic := `[Application Options] -value = some value - -[add] -AliasName = 5 - -[add.Other Options] -other = subgroup - -` - - b := strings.NewReader(inic) - err := inip.Parse(b) - - if err != nil { - t.Fatalf("Unexpected error: %s", err) - } - - assertString(t, opts.Value, "some value") - - if opts.Add.Name != 5 { - t.Errorf("Expected opts.Add.Name to be 5, but got %v", opts.Add.Name) - } - - assertString(t, opts.Add.Other.O, "subgroup") - - // Test writing it back - buf := &bytes.Buffer{} - - inip.Write(buf, IniDefault) - - assertDiff(t, buf.String(), inic, "ini contents") -} - -func TestIniNoIni(t *testing.T) { - var opts struct { - NoValue string `short:"n" long:"novalue" no-ini:"yes"` - Value string `short:"v" long:"value"` - } - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - // read INI - inic := `[Application Options] -novalue = some value -value = some other value -` - - b := strings.NewReader(inic) - err := inip.Parse(b) - - if err == nil { - t.Fatalf("Expected error") - } - - iniError := err.(*IniError) - - if v := uint(2); iniError.LineNumber != v { - t.Errorf("Expected opts.Add.Name to be %d, but got %d", v, iniError.LineNumber) - } - - if v := "unknown option: novalue"; iniError.Message != v { - t.Errorf("Expected opts.Add.Name to be %s, but got %s", v, iniError.Message) - } - - // write INI - opts.NoValue = "some value" - opts.Value = "some other value" - - file, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("Cannot create temporary file: %s", err) - } - defer os.Remove(file.Name()) - - err = inip.WriteFile(file.Name(), IniIncludeDefaults) - if err != nil { - t.Fatalf("Could not write ini file: %s", err) - } - - found, err := ioutil.ReadFile(file.Name()) - if err != nil { - t.Fatalf("Could not read written ini file: %s", err) - } - - expected := "[Application Options]\nValue = some other value\n\n" - - assertDiff(t, string(found), expected, "ini content") -} - -func TestIniParse(t *testing.T) { - file, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("Cannot create temporary file: %s", err) - } - defer os.Remove(file.Name()) - - _, err = file.WriteString("value = 123") - if err != nil { - t.Fatalf("Cannot write to temporary file: %s", err) - } - - file.Close() - - var opts struct { - Value int `long:"value"` - } - - err = IniParse(file.Name(), &opts) - if err != nil { - t.Fatalf("Could not parse ini: %s", err) - } - - if opts.Value != 123 { - t.Fatalf("Expected Value to be \"123\" but was \"%d\"", opts.Value) - } -} - -func TestWriteFile(t *testing.T) { - file, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("Cannot create temporary file: %s", err) - } - defer os.Remove(file.Name()) - - var opts struct { - Value int `long:"value"` - } - - opts.Value = 123 - - p := NewParser(&opts, Default) - ini := NewIniParser(p) - - err = ini.WriteFile(file.Name(), IniIncludeDefaults) - if err != nil { - t.Fatalf("Could not write ini file: %s", err) - } - - found, err := ioutil.ReadFile(file.Name()) - if err != nil { - t.Fatalf("Could not read written ini file: %s", err) - } - - expected := "[Application Options]\nValue = 123\n\n" - - assertDiff(t, string(found), expected, "ini content") -} - -func TestOverwriteRequiredOptions(t *testing.T) { - var tests = []struct { - args []string - expected []string - }{ - { - args: []string{"--value", "from CLI"}, - expected: []string{ - "from CLI", - "from default", - }, - }, - { - args: []string{"--value", "from CLI", "--default", "from CLI"}, - expected: []string{ - "from CLI", - "from CLI", - }, - }, - { - args: []string{"--config", "no file name"}, - expected: []string{ - "from INI", - "from INI", - }, - }, - { - args: []string{"--value", "from CLI before", "--default", "from CLI before", "--config", "no file name"}, - expected: []string{ - "from INI", - "from INI", - }, - }, - { - args: []string{"--value", "from CLI before", "--default", "from CLI before", "--config", "no file name", "--value", "from CLI after", "--default", "from CLI after"}, - expected: []string{ - "from CLI after", - "from CLI after", - }, - }, - } - - for _, test := range tests { - var opts struct { - Config func(s string) error `long:"config" no-ini:"true"` - Value string `long:"value" required:"true"` - Default string `long:"default" required:"true" default:"from default"` - } - - p := NewParser(&opts, Default) - - opts.Config = func(s string) error { - ini := NewIniParser(p) - - return ini.Parse(bytes.NewBufferString("value = from INI\ndefault = from INI")) - } - - _, err := p.ParseArgs(test.args) - if err != nil { - t.Fatalf("Unexpected error %s with args %+v", err, test.args) - } - - if opts.Value != test.expected[0] { - t.Fatalf("Expected Value to be \"%s\" but was \"%s\" with args %+v", test.expected[0], opts.Value, test.args) - } - - if opts.Default != test.expected[1] { - t.Fatalf("Expected Default to be \"%s\" but was \"%s\" with args %+v", test.expected[1], opts.Default, test.args) - } - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/long_test.go b/vendor/src/github.com/jessevdk/go-flags/long_test.go deleted file mode 100644 index 02fc8c7..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/long_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestLong(t *testing.T) { - var opts = struct { - Value bool `long:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "--value") - - assertStringArray(t, ret, []string{}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestLongArg(t *testing.T) { - var opts = struct { - Value string `long:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "--value", "value") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestLongArgEqual(t *testing.T) { - var opts = struct { - Value string `long:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "--value=value") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestLongDefault(t *testing.T) { - var opts = struct { - Value string `long:"value" default:"value"` - }{} - - ret := assertParseSuccess(t, &opts) - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestLongOptional(t *testing.T) { - var opts = struct { - Value string `long:"value" optional:"yes" optional-value:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "--value") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestLongOptionalArg(t *testing.T) { - var opts = struct { - Value string `long:"value" optional:"yes" optional-value:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "--value", "no") - - assertStringArray(t, ret, []string{"no"}) - assertString(t, opts.Value, "value") -} - -func TestLongOptionalArgEqual(t *testing.T) { - var opts = struct { - Value string `long:"value" optional:"yes" optional-value:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "--value=value", "no") - - assertStringArray(t, ret, []string{"no"}) - assertString(t, opts.Value, "value") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/man.go b/vendor/src/github.com/jessevdk/go-flags/man.go deleted file mode 100644 index 95347d0..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/man.go +++ /dev/null @@ -1,186 +0,0 @@ -package flags - -import ( - "fmt" - "io" - "runtime" - "strings" - "time" -) - -func manQuote(s string) string { - return strings.Replace(s, "\\", "\\\\", -1) -} - -func formatForMan(wr io.Writer, s string) { - for { - idx := strings.IndexRune(s, '`') - - if idx < 0 { - fmt.Fprintf(wr, "%s", manQuote(s)) - break - } - - fmt.Fprintf(wr, "%s", manQuote(s[:idx])) - - s = s[idx+1:] - idx = strings.IndexRune(s, '\'') - - if idx < 0 { - fmt.Fprintf(wr, "%s", manQuote(s)) - break - } - - fmt.Fprintf(wr, "\\fB%s\\fP", manQuote(s[:idx])) - s = s[idx+1:] - } -} - -func writeManPageOptions(wr io.Writer, grp *Group) { - grp.eachGroup(func(group *Group) { - for _, opt := range group.options { - if !opt.canCli() { - continue - } - - fmt.Fprintln(wr, ".TP") - fmt.Fprintf(wr, "\\fB") - - if opt.ShortName != 0 { - fmt.Fprintf(wr, "\\fB\\-%c\\fR", opt.ShortName) - } - - if len(opt.LongName) != 0 { - if opt.ShortName != 0 { - fmt.Fprintf(wr, ", ") - } - - fmt.Fprintf(wr, "\\fB\\-\\-%s\\fR", manQuote(opt.LongNameWithNamespace())) - } - - if len(opt.ValueName) != 0 || opt.OptionalArgument { - if opt.OptionalArgument { - fmt.Fprintf(wr, " [\\fI%s=%s\\fR]", manQuote(opt.ValueName), manQuote(strings.Join(quoteV(opt.OptionalValue), ", "))) - } else { - fmt.Fprintf(wr, " \\fI%s\\fR", manQuote(opt.ValueName)) - } - } - - if len(opt.Default) != 0 { - fmt.Fprintf(wr, " ", manQuote(strings.Join(quoteV(opt.Default), ", "))) - } else if len(opt.EnvDefaultKey) != 0 { - if runtime.GOOS == "windows" { - fmt.Fprintf(wr, " ", manQuote(opt.EnvDefaultKey)) - } else { - fmt.Fprintf(wr, " ", manQuote(opt.EnvDefaultKey)) - } - } - - if opt.Required { - fmt.Fprintf(wr, " (\\fIrequired\\fR)") - } - - fmt.Fprintln(wr, "\\fP") - - if len(opt.Description) != 0 { - formatForMan(wr, opt.Description) - fmt.Fprintln(wr, "") - } - } - }) -} - -func writeManPageSubcommands(wr io.Writer, name string, root *Command) { - commands := root.sortedCommands() - - for _, c := range commands { - var nn string - - if len(name) != 0 { - nn = name + " " + c.Name - } else { - nn = c.Name - } - - writeManPageCommand(wr, nn, root, c) - } -} - -func writeManPageCommand(wr io.Writer, name string, root *Command, command *Command) { - fmt.Fprintf(wr, ".SS %s\n", name) - fmt.Fprintln(wr, command.ShortDescription) - - if len(command.LongDescription) > 0 { - fmt.Fprintln(wr, "") - - cmdstart := fmt.Sprintf("The %s command", manQuote(command.Name)) - - if strings.HasPrefix(command.LongDescription, cmdstart) { - fmt.Fprintf(wr, "The \\fI%s\\fP command", manQuote(command.Name)) - - formatForMan(wr, command.LongDescription[len(cmdstart):]) - fmt.Fprintln(wr, "") - } else { - formatForMan(wr, command.LongDescription) - fmt.Fprintln(wr, "") - } - } - - var usage string - if us, ok := command.data.(Usage); ok { - usage = us.Usage() - } else if command.hasCliOptions() { - usage = fmt.Sprintf("[%s-OPTIONS]", command.Name) - } - - var pre string - if root.hasCliOptions() { - pre = fmt.Sprintf("%s [OPTIONS] %s", root.Name, command.Name) - } else { - pre = fmt.Sprintf("%s %s", root.Name, command.Name) - } - - if len(usage) > 0 { - fmt.Fprintf(wr, "\n\\fBUsage\\fP: %s %s\n\n", manQuote(pre), manQuote(usage)) - } - - if len(command.Aliases) > 0 { - fmt.Fprintf(wr, "\n\\fBAliases\\fP: %s\n\n", manQuote(strings.Join(command.Aliases, ", "))) - } - - writeManPageOptions(wr, command.Group) - writeManPageSubcommands(wr, name, command) -} - -// WriteManPage writes a basic man page in groff format to the specified -// writer. -func (p *Parser) WriteManPage(wr io.Writer) { - t := time.Now() - - fmt.Fprintf(wr, ".TH %s 1 \"%s\"\n", manQuote(p.Name), t.Format("2 January 2006")) - fmt.Fprintln(wr, ".SH NAME") - fmt.Fprintf(wr, "%s \\- %s\n", manQuote(p.Name), manQuote(p.ShortDescription)) - fmt.Fprintln(wr, ".SH SYNOPSIS") - - usage := p.Usage - - if len(usage) == 0 { - usage = "[OPTIONS]" - } - - fmt.Fprintf(wr, "\\fB%s\\fP %s\n", manQuote(p.Name), manQuote(usage)) - fmt.Fprintln(wr, ".SH DESCRIPTION") - - formatForMan(wr, p.LongDescription) - fmt.Fprintln(wr, "") - - fmt.Fprintln(wr, ".SH OPTIONS") - - writeManPageOptions(wr, p.Command.Group) - - if len(p.commands) > 0 { - fmt.Fprintln(wr, ".SH COMMANDS") - - writeManPageSubcommands(wr, "", p.Command) - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/marshal_test.go b/vendor/src/github.com/jessevdk/go-flags/marshal_test.go deleted file mode 100644 index 59c9cce..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/marshal_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package flags - -import ( - "fmt" - "testing" -) - -type marshalled bool - -func (m *marshalled) UnmarshalFlag(value string) error { - if value == "yes" { - *m = true - } else if value == "no" { - *m = false - } else { - return fmt.Errorf("`%s' is not a valid value, please specify `yes' or `no'", value) - } - - return nil -} - -func (m marshalled) MarshalFlag() (string, error) { - if m { - return "yes", nil - } - - return "no", nil -} - -type marshalledError bool - -func (m marshalledError) MarshalFlag() (string, error) { - return "", newErrorf(ErrMarshal, "Failed to marshal") -} - -func TestUnmarshal(t *testing.T) { - var opts = struct { - Value marshalled `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v=yes") - - assertStringArray(t, ret, []string{}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestUnmarshalDefault(t *testing.T) { - var opts = struct { - Value marshalled `short:"v" default:"yes"` - }{} - - ret := assertParseSuccess(t, &opts) - - assertStringArray(t, ret, []string{}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestUnmarshalOptional(t *testing.T) { - var opts = struct { - Value marshalled `short:"v" optional:"yes" optional-value:"yes"` - }{} - - ret := assertParseSuccess(t, &opts, "-v") - - assertStringArray(t, ret, []string{}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestUnmarshalError(t *testing.T) { - var opts = struct { - Value marshalled `short:"v"` - }{} - - assertParseFail(t, ErrMarshal, fmt.Sprintf("invalid argument for flag `%cv' (expected flags.marshalled): `invalid' is not a valid value, please specify `yes' or `no'", defaultShortOptDelimiter), &opts, "-vinvalid") -} - -func TestMarshalError(t *testing.T) { - var opts = struct { - Value marshalledError `short:"v"` - }{} - - p := NewParser(&opts, Default) - o := p.Command.Groups()[0].Options()[0] - - _, err := convertToString(o.value, o.tag) - - assertError(t, err, ErrMarshal, "Failed to marshal") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/multitag.go b/vendor/src/github.com/jessevdk/go-flags/multitag.go deleted file mode 100644 index 96bb1a3..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/multitag.go +++ /dev/null @@ -1,140 +0,0 @@ -package flags - -import ( - "strconv" -) - -type multiTag struct { - value string - cache map[string][]string -} - -func newMultiTag(v string) multiTag { - return multiTag{ - value: v, - } -} - -func (x *multiTag) scan() (map[string][]string, error) { - v := x.value - - ret := make(map[string][]string) - - // This is mostly copied from reflect.StructTag.Get - for v != "" { - i := 0 - - // Skip whitespace - for i < len(v) && v[i] == ' ' { - i++ - } - - v = v[i:] - - if v == "" { - break - } - - // Scan to colon to find key - i = 0 - - for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' { - i++ - } - - if i >= len(v) { - return nil, newErrorf(ErrTag, "expected `:' after key name, but got end of tag (in `%v`)", x.value) - } - - if v[i] != ':' { - return nil, newErrorf(ErrTag, "expected `:' after key name, but got `%v' (in `%v`)", v[i], x.value) - } - - if i+1 >= len(v) { - return nil, newErrorf(ErrTag, "expected `\"' to start tag value at end of tag (in `%v`)", x.value) - } - - if v[i+1] != '"' { - return nil, newErrorf(ErrTag, "expected `\"' to start tag value, but got `%v' (in `%v`)", v[i+1], x.value) - } - - name := v[:i] - v = v[i+1:] - - // Scan quoted string to find value - i = 1 - - for i < len(v) && v[i] != '"' { - if v[i] == '\n' { - return nil, newErrorf(ErrTag, "unexpected newline in tag value `%v' (in `%v`)", name, x.value) - } - - if v[i] == '\\' { - i++ - } - i++ - } - - if i >= len(v) { - return nil, newErrorf(ErrTag, "expected end of tag value `\"' at end of tag (in `%v`)", x.value) - } - - val, err := strconv.Unquote(v[:i+1]) - - if err != nil { - return nil, newErrorf(ErrTag, "Malformed value of tag `%v:%v` => %v (in `%v`)", name, v[:i+1], err, x.value) - } - - v = v[i+1:] - - ret[name] = append(ret[name], val) - } - - return ret, nil -} - -func (x *multiTag) Parse() error { - vals, err := x.scan() - x.cache = vals - - return err -} - -func (x *multiTag) cached() map[string][]string { - if x.cache == nil { - cache, _ := x.scan() - - if cache == nil { - cache = make(map[string][]string) - } - - x.cache = cache - } - - return x.cache -} - -func (x *multiTag) Get(key string) string { - c := x.cached() - - if v, ok := c[key]; ok { - return v[len(v)-1] - } - - return "" -} - -func (x *multiTag) GetMany(key string) []string { - c := x.cached() - return c[key] -} - -func (x *multiTag) Set(key string, value string) { - c := x.cached() - c[key] = []string{value} -} - -func (x *multiTag) SetMany(key string, value []string) { - c := x.cached() - c[key] = value -} diff --git a/vendor/src/github.com/jessevdk/go-flags/option.go b/vendor/src/github.com/jessevdk/go-flags/option.go deleted file mode 100644 index 42c1059..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/option.go +++ /dev/null @@ -1,162 +0,0 @@ -package flags - -import ( - "fmt" - "reflect" - "unicode/utf8" -) - -// Option flag information. Contains a description of the option, short and -// long name as well as a default value and whether an argument for this -// flag is optional. -type Option struct { - // The description of the option flag. This description is shown - // automatically in the built-in help. - Description string - - // The short name of the option (a single character). If not 0, the - // option flag can be 'activated' using -. Either ShortName - // or LongName needs to be non-empty. - ShortName rune - - // The long name of the option. If not "", the option flag can be - // activated using --. Either ShortName or LongName needs - // to be non-empty. - LongName string - - // The default value of the option. - Default []string - - // The optional environment default value key name. - EnvDefaultKey string - - // The optional delimiter string for EnvDefaultKey values. - EnvDefaultDelim string - - // If true, specifies that the argument to an option flag is optional. - // When no argument to the flag is specified on the command line, the - // value of OptionalValue will be set in the field this option represents. - // This is only valid for non-boolean options. - OptionalArgument bool - - // The optional value of the option. The optional value is used when - // the option flag is marked as having an OptionalArgument. This means - // that when the flag is specified, but no option argument is given, - // the value of the field this option represents will be set to - // OptionalValue. This is only valid for non-boolean options. - OptionalValue []string - - // If true, the option _must_ be specified on the command line. If the - // option is not specified, the parser will generate an ErrRequired type - // error. - Required bool - - // A name for the value of an option shown in the Help as --flag [ValueName] - ValueName string - - // A mask value to show in the help instead of the default value. This - // is useful for hiding sensitive information in the help, such as - // passwords. - DefaultMask string - - // The group which the option belongs to - group *Group - - // The struct field which the option represents. - field reflect.StructField - - // The struct field value which the option represents. - value reflect.Value - - // Determines if the option will be always quoted in the INI output - iniQuote bool - - tag multiTag - isSet bool -} - -// LongNameWithNamespace returns the option's long name with the group namespaces -// prepended by walking up the option's group tree. Namespaces and the long name -// itself are separated by the parser's namespace delimiter. If the long name is -// empty an empty string is returned. -func (option *Option) LongNameWithNamespace() string { - if len(option.LongName) == 0 { - return "" - } - - // fetch the namespace delimiter from the parser which is always at the - // end of the group hierarchy - namespaceDelimiter := "" - g := option.group - - for { - if p, ok := g.parent.(*Parser); ok { - namespaceDelimiter = p.NamespaceDelimiter - - break - } - - switch i := g.parent.(type) { - case *Command: - g = i.Group - case *Group: - g = i - } - } - - // concatenate long name with namespace - longName := option.LongName - g = option.group - - for g != nil { - if g.Namespace != "" { - longName = g.Namespace + namespaceDelimiter + longName - } - - switch i := g.parent.(type) { - case *Command: - g = i.Group - case *Group: - g = i - case *Parser: - g = nil - } - } - - return longName -} - -// String converts an option to a human friendly readable string describing the -// option. -func (option *Option) String() string { - var s string - var short string - - if option.ShortName != 0 { - data := make([]byte, utf8.RuneLen(option.ShortName)) - utf8.EncodeRune(data, option.ShortName) - short = string(data) - - if len(option.LongName) != 0 { - s = fmt.Sprintf("%s%s, %s%s", - string(defaultShortOptDelimiter), short, - defaultLongOptDelimiter, option.LongNameWithNamespace()) - } else { - s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short) - } - } else if len(option.LongName) != 0 { - s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace()) - } - - return s -} - -// Value returns the option value as an interface{}. -func (option *Option) Value() interface{} { - return option.value.Interface() -} - -// IsSet returns true if option has been set -func (option *Option) IsSet() bool { - return option.isSet -} diff --git a/vendor/src/github.com/jessevdk/go-flags/option_private.go b/vendor/src/github.com/jessevdk/go-flags/option_private.go deleted file mode 100644 index d36c841..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/option_private.go +++ /dev/null @@ -1,182 +0,0 @@ -package flags - -import ( - "reflect" - "strings" - "syscall" -) - -// Set the value of an option to the specified value. An error will be returned -// if the specified value could not be converted to the corresponding option -// value type. -func (option *Option) set(value *string) error { - option.isSet = true - - if option.isFunc() { - return option.call(value) - } else if value != nil { - return convert(*value, option.value, option.tag) - } - - return convert("", option.value, option.tag) -} - -func (option *Option) canCli() bool { - return option.ShortName != 0 || len(option.LongName) != 0 -} - -func (option *Option) canArgument() bool { - if u := option.isUnmarshaler(); u != nil { - return true - } - - return !option.isBool() -} - -func (option *Option) emptyValue() reflect.Value { - tp := option.value.Type() - - if tp.Kind() == reflect.Map { - return reflect.MakeMap(tp) - } - - return reflect.Zero(tp) -} - -func (option *Option) empty() { - if !option.isFunc() { - option.value.Set(option.emptyValue()) - } -} - -func (option *Option) clearDefault() { - usedDefault := option.Default - if envKey := option.EnvDefaultKey; envKey != "" { - // os.Getenv() makes no distinction between undefined and - // empty values, so we use syscall.Getenv() - if value, ok := syscall.Getenv(envKey); ok { - if option.EnvDefaultDelim != "" { - usedDefault = strings.Split(value, - option.EnvDefaultDelim) - } else { - usedDefault = []string{value} - } - } - } - - if len(usedDefault) > 0 { - option.empty() - - for _, d := range usedDefault { - option.set(&d) - } - } else { - tp := option.value.Type() - - switch tp.Kind() { - case reflect.Map: - if option.value.IsNil() { - option.empty() - } - case reflect.Slice: - if option.value.IsNil() { - option.empty() - } - } - } -} - -func (option *Option) valueIsDefault() bool { - // Check if the value of the option corresponds to its - // default value - emptyval := option.emptyValue() - - checkvalptr := reflect.New(emptyval.Type()) - checkval := reflect.Indirect(checkvalptr) - - checkval.Set(emptyval) - - if len(option.Default) != 0 { - for _, v := range option.Default { - convert(v, checkval, option.tag) - } - } - - return reflect.DeepEqual(option.value.Interface(), checkval.Interface()) -} - -func (option *Option) isUnmarshaler() Unmarshaler { - v := option.value - - for { - if !v.CanInterface() { - break - } - - i := v.Interface() - - if u, ok := i.(Unmarshaler); ok { - return u - } - - if !v.CanAddr() { - break - } - - v = v.Addr() - } - - return nil -} - -func (option *Option) isBool() bool { - tp := option.value.Type() - - for { - switch tp.Kind() { - case reflect.Bool: - return true - case reflect.Slice: - return (tp.Elem().Kind() == reflect.Bool) - case reflect.Func: - return tp.NumIn() == 0 - case reflect.Ptr: - tp = tp.Elem() - default: - return false - } - } -} - -func (option *Option) isFunc() bool { - return option.value.Type().Kind() == reflect.Func -} - -func (option *Option) call(value *string) error { - var retval []reflect.Value - - if value == nil { - retval = option.value.Call(nil) - } else { - tp := option.value.Type().In(0) - - val := reflect.New(tp) - val = reflect.Indirect(val) - - if err := convert(*value, val, option.tag); err != nil { - return err - } - - retval = option.value.Call([]reflect.Value{val}) - } - - if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() { - if retval[0].Interface() == nil { - return nil - } - - return retval[0].Interface().(error) - } - - return nil -} diff --git a/vendor/src/github.com/jessevdk/go-flags/options_test.go b/vendor/src/github.com/jessevdk/go-flags/options_test.go deleted file mode 100644 index b0fe9f4..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/options_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestPassDoubleDash(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - }{} - - p := NewParser(&opts, PassDoubleDash) - ret, err := p.ParseArgs([]string{"-v", "--", "-v", "-g"}) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - assertStringArray(t, ret, []string{"-v", "-g"}) -} - -func TestPassAfterNonOption(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - }{} - - p := NewParser(&opts, PassAfterNonOption) - ret, err := p.ParseArgs([]string{"-v", "arg", "-v", "-g"}) - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - return - } - - if !opts.Value { - t.Errorf("Expected Value to be true") - } - - assertStringArray(t, ret, []string{"arg", "-v", "-g"}) -} diff --git a/vendor/src/github.com/jessevdk/go-flags/optstyle_other.go b/vendor/src/github.com/jessevdk/go-flags/optstyle_other.go deleted file mode 100644 index 29ca4b6..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/optstyle_other.go +++ /dev/null @@ -1,67 +0,0 @@ -// +build !windows - -package flags - -import ( - "strings" -) - -const ( - defaultShortOptDelimiter = '-' - defaultLongOptDelimiter = "--" - defaultNameArgDelimiter = '=' -) - -func argumentStartsOption(arg string) bool { - return len(arg) > 0 && arg[0] == '-' -} - -func argumentIsOption(arg string) bool { - if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' { - return true - } - - if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' { - return true - } - - return false -} - -// stripOptionPrefix returns the option without the prefix and whether or -// not the option is a long option or not. -func stripOptionPrefix(optname string) (prefix string, name string, islong bool) { - if strings.HasPrefix(optname, "--") { - return "--", optname[2:], true - } else if strings.HasPrefix(optname, "-") { - return "-", optname[1:], false - } - - return "", optname, false -} - -// splitOption attempts to split the passed option into a name and an argument. -// When there is no argument specified, nil will be returned for it. -func splitOption(prefix string, option string, islong bool) (string, string, *string) { - pos := strings.Index(option, "=") - - if (islong && pos >= 0) || (!islong && pos == 1) { - rest := option[pos+1:] - return option[:pos], "=", &rest - } - - return option, "", nil -} - -// addHelpGroup adds a new group that contains default help parameters. -func (c *Command) addHelpGroup(showHelp func() error) *Group { - var help struct { - ShowHelp func() error `short:"h" long:"help" description:"Show this help message"` - } - - help.ShowHelp = showHelp - ret, _ := c.AddGroup("Help Options", "", &help) - ret.isBuiltinHelp = true - - return ret -} diff --git a/vendor/src/github.com/jessevdk/go-flags/optstyle_windows.go b/vendor/src/github.com/jessevdk/go-flags/optstyle_windows.go deleted file mode 100644 index a51de9c..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/optstyle_windows.go +++ /dev/null @@ -1,106 +0,0 @@ -package flags - -import ( - "strings" -) - -// Windows uses a front slash for both short and long options. Also it uses -// a colon for name/argument delimter. -const ( - defaultShortOptDelimiter = '/' - defaultLongOptDelimiter = "/" - defaultNameArgDelimiter = ':' -) - -func argumentStartsOption(arg string) bool { - return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/') -} - -func argumentIsOption(arg string) bool { - // Windows-style options allow front slash for the option - // delimiter. - if len(arg) > 1 && arg[0] == '/' { - return true - } - - if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' { - return true - } - - if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' { - return true - } - - return false -} - -// stripOptionPrefix returns the option without the prefix and whether or -// not the option is a long option or not. -func stripOptionPrefix(optname string) (prefix string, name string, islong bool) { - // Determine if the argument is a long option or not. Windows - // typically supports both long and short options with a single - // front slash as the option delimiter, so handle this situation - // nicely. - possplit := 0 - - if strings.HasPrefix(optname, "--") { - possplit = 2 - islong = true - } else if strings.HasPrefix(optname, "-") { - possplit = 1 - islong = false - } else if strings.HasPrefix(optname, "/") { - possplit = 1 - islong = len(optname) > 2 - } - - return optname[:possplit], optname[possplit:], islong -} - -// splitOption attempts to split the passed option into a name and an argument. -// When there is no argument specified, nil will be returned for it. -func splitOption(prefix string, option string, islong bool) (string, string, *string) { - if len(option) == 0 { - return option, "", nil - } - - // Windows typically uses a colon for the option name and argument - // delimiter while POSIX typically uses an equals. Support both styles, - // but don't allow the two to be mixed. That is to say /foo:bar and - // --foo=bar are acceptable, but /foo=bar and --foo:bar are not. - var pos int - var sp string - - if prefix == "/" { - sp = ":" - pos = strings.Index(option, sp) - } else if len(prefix) > 0 { - sp = "=" - pos = strings.Index(option, sp) - } - - if (islong && pos >= 0) || (!islong && pos == 1) { - rest := option[pos+1:] - return option[:pos], sp, &rest - } - - return option, "", nil -} - -// addHelpGroup adds a new group that contains default help parameters. -func (c *Command) addHelpGroup(showHelp func() error) *Group { - // Windows CLI applications typically use /? for help, so make both - // that available as well as the POSIX style h and help. - var help struct { - ShowHelpWindows func() error `short:"?" description:"Show this help message"` - ShowHelpPosix func() error `short:"h" long:"help" description:"Show this help message"` - } - - help.ShowHelpWindows = showHelp - help.ShowHelpPosix = showHelp - - ret, _ := c.AddGroup("Help Options", "", &help) - ret.isBuiltinHelp = true - - return ret -} diff --git a/vendor/src/github.com/jessevdk/go-flags/parser.go b/vendor/src/github.com/jessevdk/go-flags/parser.go deleted file mode 100644 index 6f45a03..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/parser.go +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2012 Jesse van den Kieboom. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flags - -import ( - "os" - "path" -) - -// A Parser provides command line option parsing. It can contain several -// option groups each with their own set of options. -type Parser struct { - // Embedded, see Command for more information - *Command - - // A usage string to be displayed in the help message. - Usage string - - // Option flags changing the behavior of the parser. - Options Options - - // NamespaceDelimiter separates group namespaces and option long names - NamespaceDelimiter string - - // UnknownOptionsHandler is a function which gets called when the parser - // encounters an unknown option. The function receives the unknown option - // name, a SplitArgument which specifies its value if set with an argument - // separator, and the remaining command line arguments. - // It should return a new list of remaining arguments to continue parsing, - // or an error to indicate a parse failure. - UnknownOptionHandler func(option string, arg SplitArgument, args []string) ([]string, error) - - internalError error -} - -// SplitArgument represents the argument value of an option that was passed using -// an argument separator. -type SplitArgument interface { - // String returns the option's value as a string, and a boolean indicating - // if the option was present. - Value() (string, bool) -} - -type strArgument struct { - value *string -} - -func (s strArgument) Value() (string, bool) { - if s.value == nil { - return "", false - } - - return *s.value, true -} - -// Options provides parser options that change the behavior of the option -// parser. -type Options uint - -const ( - // None indicates no options. - None Options = 0 - - // HelpFlag adds a default Help Options group to the parser containing - // -h and --help options. When either -h or --help is specified on the - // command line, the parser will return the special error of type - // ErrHelp. When PrintErrors is also specified, then the help message - // will also be automatically printed to os.Stderr. - HelpFlag = 1 << iota - - // PassDoubleDash passes all arguments after a double dash, --, as - // remaining command line arguments (i.e. they will not be parsed for - // flags). - PassDoubleDash - - // IgnoreUnknown ignores any unknown options and passes them as - // remaining command line arguments instead of generating an error. - IgnoreUnknown - - // PrintErrors prints any errors which occurred during parsing to - // os.Stderr. - PrintErrors - - // PassAfterNonOption passes all arguments after the first non option - // as remaining command line arguments. This is equivalent to strict - // POSIX processing. - PassAfterNonOption - - // Default is a convenient default set of options which should cover - // most of the uses of the flags package. - Default = HelpFlag | PrintErrors | PassDoubleDash -) - -// Parse is a convenience function to parse command line options with default -// settings. The provided data is a pointer to a struct representing the -// default option group (named "Application Options"). For more control, use -// flags.NewParser. -func Parse(data interface{}) ([]string, error) { - return NewParser(data, Default).Parse() -} - -// ParseArgs is a convenience function to parse command line options with default -// settings. The provided data is a pointer to a struct representing the -// default option group (named "Application Options"). The args argument is -// the list of command line arguments to parse. If you just want to parse the -// default program command line arguments (i.e. os.Args), then use flags.Parse -// instead. For more control, use flags.NewParser. -func ParseArgs(data interface{}, args []string) ([]string, error) { - return NewParser(data, Default).ParseArgs(args) -} - -// NewParser creates a new parser. It uses os.Args[0] as the application -// name and then calls Parser.NewNamedParser (see Parser.NewNamedParser for -// more details). The provided data is a pointer to a struct representing the -// default option group (named "Application Options"), or nil if the default -// group should not be added. The options parameter specifies a set of options -// for the parser. -func NewParser(data interface{}, options Options) *Parser { - p := NewNamedParser(path.Base(os.Args[0]), options) - - if data != nil { - g, err := p.AddGroup("Application Options", "", data) - - if err == nil { - g.parent = p - } - - p.internalError = err - } - - return p -} - -// NewNamedParser creates a new parser. The appname is used to display the -// executable name in the built-in help message. Option groups and commands can -// be added to this parser by using AddGroup and AddCommand. -func NewNamedParser(appname string, options Options) *Parser { - p := &Parser{ - Command: newCommand(appname, "", "", nil), - Options: options, - NamespaceDelimiter: ".", - } - - p.Command.parent = p - - return p -} - -// Parse parses the command line arguments from os.Args using Parser.ParseArgs. -// For more detailed information see ParseArgs. -func (p *Parser) Parse() ([]string, error) { - return p.ParseArgs(os.Args[1:]) -} - -// ParseArgs parses the command line arguments according to the option groups that -// were added to the parser. On successful parsing of the arguments, the -// remaining, non-option, arguments (if any) are returned. The returned error -// indicates a parsing error and can be used with PrintError to display -// contextual information on where the error occurred exactly. -// -// When the common help group has been added (AddHelp) and either -h or --help -// was specified in the command line arguments, a help message will be -// automatically printed. Furthermore, the special error type ErrHelp is returned. -// It is up to the caller to exit the program if so desired. -func (p *Parser) ParseArgs(args []string) ([]string, error) { - if p.internalError != nil { - return nil, p.internalError - } - - p.clearIsSet() - - // Add built-in help group to all commands if necessary - if (p.Options & HelpFlag) != None { - p.addHelpGroups(p.showBuiltinHelp) - } - - compval := os.Getenv("GO_FLAGS_COMPLETION") - - if len(compval) != 0 { - comp := &completion{parser: p} - - if compval == "verbose" { - comp.ShowDescriptions = true - } - - comp.execute(args) - - return nil, nil - } - - s := &parseState{ - args: args, - retargs: make([]string, 0, len(args)), - } - - p.fillParseState(s) - - for !s.eof() { - arg := s.pop() - - // When PassDoubleDash is set and we encounter a --, then - // simply append all the rest as arguments and break out - if (p.Options&PassDoubleDash) != None && arg == "--" { - s.addArgs(s.args...) - break - } - - if !argumentIsOption(arg) { - // Note: this also sets s.err, so we can just check for - // nil here and use s.err later - if p.parseNonOption(s) != nil { - break - } - - continue - } - - var err error - - prefix, optname, islong := stripOptionPrefix(arg) - optname, _, argument := splitOption(prefix, optname, islong) - - if islong { - err = p.parseLong(s, optname, argument) - } else { - err = p.parseShort(s, optname, argument) - } - - if err != nil { - ignoreUnknown := (p.Options & IgnoreUnknown) != None - parseErr := wrapError(err) - - if parseErr.Type != ErrUnknownFlag || (!ignoreUnknown && p.UnknownOptionHandler == nil) { - s.err = parseErr - break - } - - if ignoreUnknown { - s.addArgs(arg) - } else if p.UnknownOptionHandler != nil { - modifiedArgs, err := p.UnknownOptionHandler(optname, strArgument{argument}, s.args) - - if err != nil { - s.err = err - break - } - - s.args = modifiedArgs - } - } - } - - if s.err == nil { - p.eachCommand(func(c *Command) { - c.eachGroup(func(g *Group) { - for _, option := range g.options { - if option.isSet { - continue - } - - option.clearDefault() - } - }) - }, true) - - s.checkRequired(p) - } - - var reterr error - - if s.err != nil { - reterr = s.err - } else if len(s.command.commands) != 0 && !s.command.SubcommandsOptional { - reterr = s.estimateCommand() - } else if cmd, ok := s.command.data.(Commander); ok { - reterr = cmd.Execute(s.retargs) - } - - if reterr != nil { - return append([]string{s.arg}, s.args...), p.printError(reterr) - } - - return s.retargs, nil -} diff --git a/vendor/src/github.com/jessevdk/go-flags/parser_private.go b/vendor/src/github.com/jessevdk/go-flags/parser_private.go deleted file mode 100644 index 76be4a7..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/parser_private.go +++ /dev/null @@ -1,340 +0,0 @@ -package flags - -import ( - "bytes" - "fmt" - "os" - "sort" - "strings" - "unicode/utf8" -) - -type parseState struct { - arg string - args []string - retargs []string - positional []*Arg - err error - - command *Command - lookup lookup -} - -func (p *parseState) eof() bool { - return len(p.args) == 0 -} - -func (p *parseState) pop() string { - if p.eof() { - return "" - } - - p.arg = p.args[0] - p.args = p.args[1:] - - return p.arg -} - -func (p *parseState) peek() string { - if p.eof() { - return "" - } - - return p.args[0] -} - -func (p *parseState) checkRequired(parser *Parser) error { - c := parser.Command - - var required []*Option - - for c != nil { - c.eachGroup(func(g *Group) { - for _, option := range g.options { - if !option.isSet && option.Required { - required = append(required, option) - } - } - }) - - c = c.Active - } - - if len(required) == 0 { - if len(p.positional) > 0 && p.command.ArgsRequired { - var reqnames []string - - for _, arg := range p.positional { - if arg.isRemaining() { - break - } - - reqnames = append(reqnames, "`"+arg.Name+"`") - } - - if len(reqnames) == 0 { - return nil - } - - var msg string - - if len(reqnames) == 1 { - msg = fmt.Sprintf("the required argument %s was not provided", reqnames[0]) - } else { - msg = fmt.Sprintf("the required arguments %s and %s were not provided", - strings.Join(reqnames[:len(reqnames)-1], ", "), reqnames[len(reqnames)-1]) - } - - p.err = newError(ErrRequired, msg) - return p.err - } - - return nil - } - - names := make([]string, 0, len(required)) - - for _, k := range required { - names = append(names, "`"+k.String()+"'") - } - - sort.Strings(names) - - var msg string - - if len(names) == 1 { - msg = fmt.Sprintf("the required flag %s was not specified", names[0]) - } else { - msg = fmt.Sprintf("the required flags %s and %s were not specified", - strings.Join(names[:len(names)-1], ", "), names[len(names)-1]) - } - - p.err = newError(ErrRequired, msg) - return p.err -} - -func (p *parseState) estimateCommand() error { - commands := p.command.sortedCommands() - cmdnames := make([]string, len(commands)) - - for i, v := range commands { - cmdnames[i] = v.Name - } - - var msg string - var errtype ErrorType - - if len(p.retargs) != 0 { - c, l := closestChoice(p.retargs[0], cmdnames) - msg = fmt.Sprintf("Unknown command `%s'", p.retargs[0]) - errtype = ErrUnknownCommand - - if float32(l)/float32(len(c)) < 0.5 { - msg = fmt.Sprintf("%s, did you mean `%s'?", msg, c) - } else if len(cmdnames) == 1 { - msg = fmt.Sprintf("%s. You should use the %s command", - msg, - cmdnames[0]) - } else { - msg = fmt.Sprintf("%s. Please specify one command of: %s or %s", - msg, - strings.Join(cmdnames[:len(cmdnames)-1], ", "), - cmdnames[len(cmdnames)-1]) - } - } else { - errtype = ErrCommandRequired - - if len(cmdnames) == 1 { - msg = fmt.Sprintf("Please specify the %s command", cmdnames[0]) - } else { - msg = fmt.Sprintf("Please specify one command of: %s or %s", - strings.Join(cmdnames[:len(cmdnames)-1], ", "), - cmdnames[len(cmdnames)-1]) - } - } - - return newError(errtype, msg) -} - -func (p *Parser) parseOption(s *parseState, name string, option *Option, canarg bool, argument *string) (err error) { - if !option.canArgument() { - if argument != nil { - return newErrorf(ErrNoArgumentForBool, "bool flag `%s' cannot have an argument", option) - } - - err = option.set(nil) - } else if argument != nil || (canarg && !s.eof()) { - var arg string - - if argument != nil { - arg = *argument - } else { - arg = s.pop() - - if argumentIsOption(arg) { - return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got option `%s'", option, arg) - } else if p.Options&PassDoubleDash != 0 && arg == "--" { - return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got double dash `--'", option) - } - } - - if option.tag.Get("unquote") != "false" { - arg, err = unquoteIfPossible(arg) - } - - if err == nil { - err = option.set(&arg) - } - } else if option.OptionalArgument { - option.empty() - - for _, v := range option.OptionalValue { - err = option.set(&v) - - if err != nil { - break - } - } - } else { - err = newErrorf(ErrExpectedArgument, "expected argument for flag `%s'", option) - } - - if err != nil { - if _, ok := err.(*Error); !ok { - err = newErrorf(ErrMarshal, "invalid argument for flag `%s' (expected %s): %s", - option, - option.value.Type(), - err.Error()) - } - } - - return err -} - -func (p *Parser) parseLong(s *parseState, name string, argument *string) error { - if option := s.lookup.longNames[name]; option != nil { - // Only long options that are required can consume an argument - // from the argument list - canarg := !option.OptionalArgument - - return p.parseOption(s, name, option, canarg, argument) - } - - return newErrorf(ErrUnknownFlag, "unknown flag `%s'", name) -} - -func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) { - c, n := utf8.DecodeRuneInString(optname) - - if n == len(optname) { - return optname, nil - } - - first := string(c) - - if option := s.lookup.shortNames[first]; option != nil && option.canArgument() { - arg := optname[n:] - return first, &arg - } - - return optname, nil -} - -func (p *Parser) parseShort(s *parseState, optname string, argument *string) error { - if argument == nil { - optname, argument = p.splitShortConcatArg(s, optname) - } - - for i, c := range optname { - shortname := string(c) - - if option := s.lookup.shortNames[shortname]; option != nil { - // Only the last short argument can consume an argument from - // the arguments list, and only if it's non optional - canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument - - if err := p.parseOption(s, shortname, option, canarg, argument); err != nil { - return err - } - } else { - return newErrorf(ErrUnknownFlag, "unknown flag `%s'", shortname) - } - - // Only the first option can have a concatted argument, so just - // clear argument here - argument = nil - } - - return nil -} - -func (p *parseState) addArgs(args ...string) error { - for len(p.positional) > 0 && len(args) > 0 { - arg := p.positional[0] - - if err := convert(args[0], arg.value, arg.tag); err != nil { - return err - } - - if !arg.isRemaining() { - p.positional = p.positional[1:] - } - - args = args[1:] - } - - p.retargs = append(p.retargs, args...) - return nil -} - -func (p *Parser) parseNonOption(s *parseState) error { - if len(s.positional) > 0 { - return s.addArgs(s.arg) - } - - if cmd := s.lookup.commands[s.arg]; cmd != nil { - s.command.Active = cmd - cmd.fillParseState(s) - } else if (p.Options & PassAfterNonOption) != None { - // If PassAfterNonOption is set then all remaining arguments - // are considered positional - if err := s.addArgs(s.arg); err != nil { - return err - } - - if err := s.addArgs(s.args...); err != nil { - return err - } - - s.args = []string{} - } else { - return s.addArgs(s.arg) - } - - return nil -} - -func (p *Parser) showBuiltinHelp() error { - var b bytes.Buffer - - p.WriteHelp(&b) - return newError(ErrHelp, b.String()) -} - -func (p *Parser) printError(err error) error { - if err != nil && (p.Options&PrintErrors) != None { - fmt.Fprintln(os.Stderr, err) - } - - return err -} - -func (p *Parser) clearIsSet() { - p.eachCommand(func(c *Command) { - c.eachGroup(func(g *Group) { - for _, option := range g.options { - option.isSet = false - } - }) - }, true) -} diff --git a/vendor/src/github.com/jessevdk/go-flags/parser_test.go b/vendor/src/github.com/jessevdk/go-flags/parser_test.go deleted file mode 100644 index 51091f1..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/parser_test.go +++ /dev/null @@ -1,463 +0,0 @@ -package flags - -import ( - "fmt" - "os" - "reflect" - "strconv" - "strings" - "testing" - "time" -) - -type defaultOptions struct { - Int int `long:"i"` - IntDefault int `long:"id" default:"1"` - - Float64 float64 `long:"f"` - Float64Default float64 `long:"fd" default:"-3.14"` - - NumericFlag bool `short:"3" default:"false"` - - String string `long:"str"` - StringDefault string `long:"strd" default:"abc"` - StringNotUnquoted string `long:"strnot" unquote:"false"` - - Time time.Duration `long:"t"` - TimeDefault time.Duration `long:"td" default:"1m"` - - Map map[string]int `long:"m"` - MapDefault map[string]int `long:"md" default:"a:1"` - - Slice []int `long:"s"` - SliceDefault []int `long:"sd" default:"1" default:"2"` -} - -func TestDefaults(t *testing.T) { - var tests = []struct { - msg string - args []string - expected defaultOptions - }{ - { - msg: "no arguments, expecting default values", - args: []string{}, - expected: defaultOptions{ - Int: 0, - IntDefault: 1, - - Float64: 0.0, - Float64Default: -3.14, - - NumericFlag: false, - - String: "", - StringDefault: "abc", - - Time: 0, - TimeDefault: time.Minute, - - Map: map[string]int{}, - MapDefault: map[string]int{"a": 1}, - - Slice: []int{}, - SliceDefault: []int{1, 2}, - }, - }, - { - msg: "non-zero value arguments, expecting overwritten arguments", - args: []string{"--i=3", "--id=3", "--f=-2.71", "--fd=2.71", "-3", "--str=def", "--strd=def", "--t=3ms", "--td=3ms", "--m=c:3", "--md=c:3", "--s=3", "--sd=3"}, - expected: defaultOptions{ - Int: 3, - IntDefault: 3, - - Float64: -2.71, - Float64Default: 2.71, - - NumericFlag: true, - - String: "def", - StringDefault: "def", - - Time: 3 * time.Millisecond, - TimeDefault: 3 * time.Millisecond, - - Map: map[string]int{"c": 3}, - MapDefault: map[string]int{"c": 3}, - - Slice: []int{3}, - SliceDefault: []int{3}, - }, - }, - { - msg: "zero value arguments, expecting overwritten arguments", - args: []string{"--i=0", "--id=0", "--f=0", "--fd=0", "--str", "", "--strd=\"\"", "--t=0ms", "--td=0s", "--m=:0", "--md=:0", "--s=0", "--sd=0"}, - expected: defaultOptions{ - Int: 0, - IntDefault: 0, - - Float64: 0, - Float64Default: 0, - - String: "", - StringDefault: "", - - Time: 0, - TimeDefault: 0, - - Map: map[string]int{"": 0}, - MapDefault: map[string]int{"": 0}, - - Slice: []int{0}, - SliceDefault: []int{0}, - }, - }, - } - - for _, test := range tests { - var opts defaultOptions - - _, err := ParseArgs(&opts, test.args) - if err != nil { - t.Fatalf("%s:\nUnexpected error: %v", test.msg, err) - } - - if opts.Slice == nil { - opts.Slice = []int{} - } - - if !reflect.DeepEqual(opts, test.expected) { - t.Errorf("%s:\nUnexpected options with arguments %+v\nexpected\n%+v\nbut got\n%+v\n", test.msg, test.args, test.expected, opts) - } - } -} - -func TestUnquoting(t *testing.T) { - var tests = []struct { - arg string - err error - value string - }{ - { - arg: "\"abc", - err: strconv.ErrSyntax, - value: "", - }, - { - arg: "\"\"abc\"", - err: strconv.ErrSyntax, - value: "", - }, - { - arg: "\"abc\"", - err: nil, - value: "abc", - }, - { - arg: "\"\\\"abc\\\"\"", - err: nil, - value: "\"abc\"", - }, - { - arg: "\"\\\"abc\"", - err: nil, - value: "\"abc", - }, - } - - for _, test := range tests { - var opts defaultOptions - - for _, delimiter := range []bool{false, true} { - p := NewParser(&opts, None) - - var err error - if delimiter { - _, err = p.ParseArgs([]string{"--str=" + test.arg, "--strnot=" + test.arg}) - } else { - _, err = p.ParseArgs([]string{"--str", test.arg, "--strnot", test.arg}) - } - - if test.err == nil { - if err != nil { - t.Fatalf("Expected no error but got: %v", err) - } - - if test.value != opts.String { - t.Fatalf("Expected String to be %q but got %q", test.value, opts.String) - } - if q := strconv.Quote(test.value); q != opts.StringNotUnquoted { - t.Fatalf("Expected StringDefault to be %q but got %q", q, opts.StringNotUnquoted) - } - } else { - if err == nil { - t.Fatalf("Expected error") - } else if e, ok := err.(*Error); ok { - if strings.HasPrefix(e.Message, test.err.Error()) { - t.Fatalf("Expected error message to end with %q but got %v", test.err.Error(), e.Message) - } - } - } - } - } -} - -// envRestorer keeps a copy of a set of env variables and can restore the env from them -type envRestorer struct { - env map[string]string -} - -func (r *envRestorer) Restore() { - os.Clearenv() - for k, v := range r.env { - os.Setenv(k, v) - } -} - -// EnvSnapshot returns a snapshot of the currently set env variables -func EnvSnapshot() *envRestorer { - r := envRestorer{make(map[string]string)} - for _, kv := range os.Environ() { - parts := strings.SplitN(kv, "=", 2) - if len(parts) != 2 { - panic("got a weird env variable: " + kv) - } - r.env[parts[0]] = parts[1] - } - return &r -} - -type envDefaultOptions struct { - Int int `long:"i" default:"1" env:"TEST_I"` - Time time.Duration `long:"t" default:"1m" env:"TEST_T"` - Map map[string]int `long:"m" default:"a:1" env:"TEST_M" env-delim:";"` - Slice []int `long:"s" default:"1" default:"2" env:"TEST_S" env-delim:","` -} - -func TestEnvDefaults(t *testing.T) { - var tests = []struct { - msg string - args []string - expected envDefaultOptions - env map[string]string - }{ - { - msg: "no arguments, no env, expecting default values", - args: []string{}, - expected: envDefaultOptions{ - Int: 1, - Time: time.Minute, - Map: map[string]int{"a": 1}, - Slice: []int{1, 2}, - }, - }, - { - msg: "no arguments, env defaults, expecting env default values", - args: []string{}, - expected: envDefaultOptions{ - Int: 2, - Time: 2 * time.Minute, - Map: map[string]int{"a": 2, "b": 3}, - Slice: []int{4, 5, 6}, - }, - env: map[string]string{ - "TEST_I": "2", - "TEST_T": "2m", - "TEST_M": "a:2;b:3", - "TEST_S": "4,5,6", - }, - }, - { - msg: "non-zero value arguments, expecting overwritten arguments", - args: []string{"--i=3", "--t=3ms", "--m=c:3", "--s=3"}, - expected: envDefaultOptions{ - Int: 3, - Time: 3 * time.Millisecond, - Map: map[string]int{"c": 3}, - Slice: []int{3}, - }, - env: map[string]string{ - "TEST_I": "2", - "TEST_T": "2m", - "TEST_M": "a:2;b:3", - "TEST_S": "4,5,6", - }, - }, - { - msg: "zero value arguments, expecting overwritten arguments", - args: []string{"--i=0", "--t=0ms", "--m=:0", "--s=0"}, - expected: envDefaultOptions{ - Int: 0, - Time: 0, - Map: map[string]int{"": 0}, - Slice: []int{0}, - }, - env: map[string]string{ - "TEST_I": "2", - "TEST_T": "2m", - "TEST_M": "a:2;b:3", - "TEST_S": "4,5,6", - }, - }, - } - - oldEnv := EnvSnapshot() - defer oldEnv.Restore() - - for _, test := range tests { - var opts envDefaultOptions - oldEnv.Restore() - for envKey, envValue := range test.env { - os.Setenv(envKey, envValue) - } - _, err := ParseArgs(&opts, test.args) - if err != nil { - t.Fatalf("%s:\nUnexpected error: %v", test.msg, err) - } - - if opts.Slice == nil { - opts.Slice = []int{} - } - - if !reflect.DeepEqual(opts, test.expected) { - t.Errorf("%s:\nUnexpected options with arguments %+v\nexpected\n%+v\nbut got\n%+v\n", test.msg, test.args, test.expected, opts) - } - } -} - -func TestOptionAsArgument(t *testing.T) { - var tests = []struct { - args []string - expectError bool - errType ErrorType - errMsg string - rest []string - }{ - { - // short option must not be accepted as argument - args: []string{"--string-slice", "foobar", "--string-slice", "-o"}, - expectError: true, - errType: ErrExpectedArgument, - errMsg: "expected argument for flag `--string-slice', but got option `-o'", - }, - { - // long option must not be accepted as argument - args: []string{"--string-slice", "foobar", "--string-slice", "--other-option"}, - expectError: true, - errType: ErrExpectedArgument, - errMsg: "expected argument for flag `--string-slice', but got option `--other-option'", - }, - { - // long option must not be accepted as argument - args: []string{"--string-slice", "--"}, - expectError: true, - errType: ErrExpectedArgument, - errMsg: "expected argument for flag `--string-slice', but got double dash `--'", - }, - { - // quoted and appended option should be accepted as argument (even if it looks like an option) - args: []string{"--string-slice", "foobar", "--string-slice=\"--other-option\""}, - }, - { - // Accept any single character arguments including '-' - args: []string{"--string-slice", "-"}, - }, - { - // Do not accept arguments which start with '-' even if the next character is a digit - args: []string{"--string-slice", "-3.14"}, - expectError: true, - errType: ErrExpectedArgument, - errMsg: "expected argument for flag `--string-slice', but got option `-3.14'", - }, - { - // Do not accept arguments which start with '-' if the next character is not a digit - args: []string{"--string-slice", "-character"}, - expectError: true, - errType: ErrExpectedArgument, - errMsg: "expected argument for flag `--string-slice', but got option `-character'", - }, - { - args: []string{"-o", "-", "-"}, - rest: []string{"-", "-"}, - }, - } - var opts struct { - StringSlice []string `long:"string-slice"` - OtherOption bool `long:"other-option" short:"o"` - } - - for _, test := range tests { - if test.expectError { - assertParseFail(t, test.errType, test.errMsg, &opts, test.args...) - } else { - args := assertParseSuccess(t, &opts, test.args...) - - assertStringArray(t, args, test.rest) - } - } -} - -func TestUnknownFlagHandler(t *testing.T) { - - var opts struct { - Flag1 string `long:"flag1"` - Flag2 string `long:"flag2"` - } - - p := NewParser(&opts, None) - - var unknownFlag1 string - var unknownFlag2 bool - var unknownFlag3 string - - // Set up a callback to intercept unknown options during parsing - p.UnknownOptionHandler = func(option string, arg SplitArgument, args []string) ([]string, error) { - if option == "unknownFlag1" { - if argValue, ok := arg.Value(); ok { - unknownFlag1 = argValue - return args, nil - } - // consume a value from remaining args list - unknownFlag1 = args[0] - return args[1:], nil - } else if option == "unknownFlag2" { - // treat this one as a bool switch, don't consume any args - unknownFlag2 = true - return args, nil - } else if option == "unknownFlag3" { - if argValue, ok := arg.Value(); ok { - unknownFlag3 = argValue - return args, nil - } - // consume a value from remaining args list - unknownFlag3 = args[0] - return args[1:], nil - } - - return args, fmt.Errorf("Unknown flag: %v", option) - } - - // Parse args containing some unknown flags, verify that - // our callback can handle all of them - _, err := p.ParseArgs([]string{"--flag1=stuff", "--unknownFlag1", "blah", "--unknownFlag2", "--unknownFlag3=baz", "--flag2=foo"}) - - if err != nil { - assertErrorf(t, "Parser returned unexpected error %v", err) - } - - assertString(t, opts.Flag1, "stuff") - assertString(t, opts.Flag2, "foo") - assertString(t, unknownFlag1, "blah") - assertString(t, unknownFlag3, "baz") - - if !unknownFlag2 { - assertErrorf(t, "Flag should have been set by unknown handler, but had value: %v", unknownFlag2) - } - - // Parse args with unknown flags that callback doesn't handle, verify it returns error - _, err = p.ParseArgs([]string{"--flag1=stuff", "--unknownFlagX", "blah", "--flag2=foo"}) - - if err == nil { - assertErrorf(t, "Parser should have returned error, but returned nil") - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/pointer_test.go b/vendor/src/github.com/jessevdk/go-flags/pointer_test.go deleted file mode 100644 index e17445f..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/pointer_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestPointerBool(t *testing.T) { - var opts = struct { - Value *bool `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v") - - assertStringArray(t, ret, []string{}) - - if !*opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestPointerString(t *testing.T) { - var opts = struct { - Value *string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v", "value") - - assertStringArray(t, ret, []string{}) - assertString(t, *opts.Value, "value") -} - -func TestPointerSlice(t *testing.T) { - var opts = struct { - Value *[]string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v", "value1", "-v", "value2") - - assertStringArray(t, ret, []string{}) - assertStringArray(t, *opts.Value, []string{"value1", "value2"}) -} - -func TestPointerMap(t *testing.T) { - var opts = struct { - Value *map[string]int `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v", "k1:2", "-v", "k2:-5") - - assertStringArray(t, ret, []string{}) - - if v, ok := (*opts.Value)["k1"]; !ok { - t.Errorf("Expected key \"k1\" to exist") - } else if v != 2 { - t.Errorf("Expected \"k1\" to be 2, but got %#v", v) - } - - if v, ok := (*opts.Value)["k2"]; !ok { - t.Errorf("Expected key \"k2\" to exist") - } else if v != -5 { - t.Errorf("Expected \"k2\" to be -5, but got %#v", v) - } -} - -type PointerGroup struct { - Value bool `short:"v"` -} - -func TestPointerGroup(t *testing.T) { - var opts = struct { - Group *PointerGroup `group:"Group Options"` - }{} - - ret := assertParseSuccess(t, &opts, "-v") - - assertStringArray(t, ret, []string{}) - - if !opts.Group.Value { - t.Errorf("Expected Group.Value to be true") - } -} diff --git a/vendor/src/github.com/jessevdk/go-flags/short_test.go b/vendor/src/github.com/jessevdk/go-flags/short_test.go deleted file mode 100644 index 95712c1..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/short_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package flags - -import ( - "fmt" - "testing" -) - -func TestShort(t *testing.T) { - var opts = struct { - Value bool `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v") - - assertStringArray(t, ret, []string{}) - - if !opts.Value { - t.Errorf("Expected Value to be true") - } -} - -func TestShortTooLong(t *testing.T) { - var opts = struct { - Value bool `short:"vv"` - }{} - - assertParseFail(t, ErrShortNameTooLong, "short names can only be 1 character long, not `vv'", &opts) -} - -func TestShortRequired(t *testing.T) { - var opts = struct { - Value bool `short:"v" required:"true"` - }{} - - assertParseFail(t, ErrRequired, fmt.Sprintf("the required flag `%cv' was not specified", defaultShortOptDelimiter), &opts) -} - -func TestShortMultiConcat(t *testing.T) { - var opts = struct { - V bool `short:"v"` - O bool `short:"o"` - F bool `short:"f"` - }{} - - ret := assertParseSuccess(t, &opts, "-vo", "-f") - - assertStringArray(t, ret, []string{}) - - if !opts.V { - t.Errorf("Expected V to be true") - } - - if !opts.O { - t.Errorf("Expected O to be true") - } - - if !opts.F { - t.Errorf("Expected F to be true") - } -} - -func TestShortMultiRequiredConcat(t *testing.T) { - var opts = struct { - V bool `short:"v" required:"true"` - O bool `short:"o" required:"true"` - F bool `short:"f" required:"true"` - }{} - - ret := assertParseSuccess(t, &opts, "-vo", "-f") - - assertStringArray(t, ret, []string{}) - - if !opts.V { - t.Errorf("Expected V to be true") - } - - if !opts.O { - t.Errorf("Expected O to be true") - } - - if !opts.F { - t.Errorf("Expected F to be true") - } -} - -func TestShortMultiSlice(t *testing.T) { - var opts = struct { - Values []bool `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v", "-v") - - assertStringArray(t, ret, []string{}) - assertBoolArray(t, opts.Values, []bool{true, true}) -} - -func TestShortMultiSliceConcat(t *testing.T) { - var opts = struct { - Values []bool `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-vvv") - - assertStringArray(t, ret, []string{}) - assertBoolArray(t, opts.Values, []bool{true, true, true}) -} - -func TestShortWithEqualArg(t *testing.T) { - var opts = struct { - Value string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v=value") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestShortWithArg(t *testing.T) { - var opts = struct { - Value string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-vvalue") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestShortArg(t *testing.T) { - var opts = struct { - Value string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-v", "value") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "value") -} - -func TestShortMultiWithEqualArg(t *testing.T) { - var opts = struct { - F []bool `short:"f"` - Value string `short:"v"` - }{} - - assertParseFail(t, ErrExpectedArgument, fmt.Sprintf("expected argument for flag `%cv'", defaultShortOptDelimiter), &opts, "-ffv=value") -} - -func TestShortMultiArg(t *testing.T) { - var opts = struct { - F []bool `short:"f"` - Value string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-ffv", "value") - - assertStringArray(t, ret, []string{}) - assertBoolArray(t, opts.F, []bool{true, true}) - assertString(t, opts.Value, "value") -} - -func TestShortMultiArgConcatFail(t *testing.T) { - var opts = struct { - F []bool `short:"f"` - Value string `short:"v"` - }{} - - assertParseFail(t, ErrExpectedArgument, fmt.Sprintf("expected argument for flag `%cv'", defaultShortOptDelimiter), &opts, "-ffvvalue") -} - -func TestShortMultiArgConcat(t *testing.T) { - var opts = struct { - F []bool `short:"f"` - Value string `short:"v"` - }{} - - ret := assertParseSuccess(t, &opts, "-vff") - - assertStringArray(t, ret, []string{}) - assertString(t, opts.Value, "ff") -} - -func TestShortOptional(t *testing.T) { - var opts = struct { - F []bool `short:"f"` - Value string `short:"v" optional:"yes" optional-value:"value"` - }{} - - ret := assertParseSuccess(t, &opts, "-fv", "f") - - assertStringArray(t, ret, []string{"f"}) - assertString(t, opts.Value, "value") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/tag_test.go b/vendor/src/github.com/jessevdk/go-flags/tag_test.go deleted file mode 100644 index 9daa740..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/tag_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestTagMissingColon(t *testing.T) { - var opts = struct { - Value bool `short` - }{} - - assertParseFail(t, ErrTag, "expected `:' after key name, but got end of tag (in `short`)", &opts, "") -} - -func TestTagMissingValue(t *testing.T) { - var opts = struct { - Value bool `short:` - }{} - - assertParseFail(t, ErrTag, "expected `\"' to start tag value at end of tag (in `short:`)", &opts, "") -} - -func TestTagMissingQuote(t *testing.T) { - var opts = struct { - Value bool `short:"v` - }{} - - assertParseFail(t, ErrTag, "expected end of tag value `\"' at end of tag (in `short:\"v`)", &opts, "") -} - -func TestTagNewline(t *testing.T) { - var opts = struct { - Value bool `long:"verbose" description:"verbose -something"` - }{} - - assertParseFail(t, ErrTag, "unexpected newline in tag value `description' (in `long:\"verbose\" description:\"verbose\nsomething\"`)", &opts, "") -} diff --git a/vendor/src/github.com/jessevdk/go-flags/termsize.go b/vendor/src/github.com/jessevdk/go-flags/termsize.go deleted file mode 100644 index df97e7e..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/termsize.go +++ /dev/null @@ -1,28 +0,0 @@ -// +build !windows,!plan9,!solaris - -package flags - -import ( - "syscall" - "unsafe" -) - -type winsize struct { - row, col uint16 - xpixel, ypixel uint16 -} - -func getTerminalColumns() int { - ws := winsize{} - - if tIOCGWINSZ != 0 { - syscall.Syscall(syscall.SYS_IOCTL, - uintptr(0), - uintptr(tIOCGWINSZ), - uintptr(unsafe.Pointer(&ws))) - - return int(ws.col) - } - - return 80 -} diff --git a/vendor/src/github.com/jessevdk/go-flags/termsize_linux.go b/vendor/src/github.com/jessevdk/go-flags/termsize_linux.go deleted file mode 100644 index e3975e2..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/termsize_linux.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build linux - -package flags - -const ( - tIOCGWINSZ = 0x5413 -) diff --git a/vendor/src/github.com/jessevdk/go-flags/termsize_nosysioctl.go b/vendor/src/github.com/jessevdk/go-flags/termsize_nosysioctl.go deleted file mode 100644 index 2a9bbe0..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/termsize_nosysioctl.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build windows plan9 solaris - -package flags - -func getTerminalColumns() int { - return 80 -} diff --git a/vendor/src/github.com/jessevdk/go-flags/termsize_other.go b/vendor/src/github.com/jessevdk/go-flags/termsize_other.go deleted file mode 100644 index 3082151..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/termsize_other.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !darwin,!freebsd,!netbsd,!openbsd,!linux - -package flags - -const ( - tIOCGWINSZ = 0 -) diff --git a/vendor/src/github.com/jessevdk/go-flags/termsize_unix.go b/vendor/src/github.com/jessevdk/go-flags/termsize_unix.go deleted file mode 100644 index fcc1186..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/termsize_unix.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build darwin freebsd netbsd openbsd - -package flags - -const ( - tIOCGWINSZ = 0x40087468 -) diff --git a/vendor/src/github.com/jessevdk/go-flags/unknown_test.go b/vendor/src/github.com/jessevdk/go-flags/unknown_test.go deleted file mode 100644 index 858be45..0000000 --- a/vendor/src/github.com/jessevdk/go-flags/unknown_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestUnknownFlags(t *testing.T) { - var opts = struct { - Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` - }{} - - args := []string{ - "-f", - } - - p := NewParser(&opts, 0) - args, err := p.ParseArgs(args) - - if err == nil { - t.Fatal("Expected error for unknown argument") - } -} - -func TestIgnoreUnknownFlags(t *testing.T) { - var opts = struct { - Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` - }{} - - args := []string{ - "hello", - "world", - "-v", - "--foo=bar", - "--verbose", - "-f", - } - - p := NewParser(&opts, IgnoreUnknown) - args, err := p.ParseArgs(args) - - if err != nil { - t.Fatal(err) - } - - exargs := []string{ - "hello", - "world", - "--foo=bar", - "-f", - } - - issame := (len(args) == len(exargs)) - - if issame { - for i := 0; i < len(args); i++ { - if args[i] != exargs[i] { - issame = false - break - } - } - } - - if !issame { - t.Fatalf("Expected %v but got %v", exargs, args) - } -} diff --git a/vendor/src/github.com/russross/blackfriday/LICENSE.txt b/vendor/src/github.com/russross/blackfriday/LICENSE.txt deleted file mode 100644 index 2885af3..0000000 --- a/vendor/src/github.com/russross/blackfriday/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -Blackfriday is distributed under the Simplified BSD License: - -> Copyright © 2011 Russ Ross -> All rights reserved. -> -> Redistribution and use in source and binary forms, with or without -> modification, are permitted provided that the following conditions -> are met: -> -> 1. Redistributions of source code must retain the above copyright -> notice, this list of conditions and the following disclaimer. -> -> 2. Redistributions in binary form must reproduce the above -> copyright notice, this list of conditions and the following -> disclaimer in the documentation and/or other materials provided with -> the distribution. -> -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -> POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/src/github.com/russross/blackfriday/README.md b/vendor/src/github.com/russross/blackfriday/README.md deleted file mode 100644 index 52e3b25..0000000 --- a/vendor/src/github.com/russross/blackfriday/README.md +++ /dev/null @@ -1,246 +0,0 @@ -Blackfriday [![Build Status](https://travis-ci.org/russross/blackfriday.svg?branch=master)](https://travis-ci.org/russross/blackfriday) -=========== - -Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It -is paranoid about its input (so you can safely feed it user-supplied -data), it is fast, it supports common extensions (tables, smart -punctuation substitutions, etc.), and it is safe for all utf-8 -(unicode) input. - -HTML output is currently supported, along with Smartypants -extensions. An experimental LaTeX output engine is also included. - -It started as a translation from C of [Sundown][3]. - - -Installation ------------- - -Blackfriday is compatible with Go 1. If you are using an older -release of Go, consider using v1.1 of blackfriday, which was based -on the last stable release of Go prior to Go 1. You can find it as a -tagged commit on github. - -With Go 1 and git installed: - - go get github.com/russross/blackfriday - -will download, compile, and install the package into your `$GOPATH` -directory hierarchy. Alternatively, you can achieve the same if you -import it into a project: - - import "github.com/russross/blackfriday" - -and `go get` without parameters. - -Usage ------ - -For basic usage, it is as simple as getting your input into a byte -slice and calling: - - output := blackfriday.MarkdownBasic(input) - -This renders it with no extensions enabled. To get a more useful -feature set, use this instead: - - output := blackfriday.MarkdownCommon(input) - -### Sanitize untrusted content - -Blackfriday itself does nothing to protect against malicious content. If you are -dealing with user-supplied markdown, we recommend running blackfriday's output -through HTML sanitizer such as -[Bluemonday](https://github.com/microcosm-cc/bluemonday). - -Here's an example of simple usage of blackfriday together with bluemonday: - -``` go -import ( - "github.com/microcosm-cc/bluemonday" - "github.com/russross/blackfriday" -) - -// ... -unsafe := blackfriday.MarkdownCommon(input) -html := bluemonday.UGCPolicy().SanitizeBytes(unsafe) -``` - -### Custom options - -If you want to customize the set of options, first get a renderer -(currently either the HTML or LaTeX output engines), then use it to -call the more general `Markdown` function. For examples, see the -implementations of `MarkdownBasic` and `MarkdownCommon` in -`markdown.go`. - -You can also check out `blackfriday-tool` for a more complete example -of how to use it. Download and install it using: - - go get github.com/russross/blackfriday-tool - -This is a simple command-line tool that allows you to process a -markdown file using a standalone program. You can also browse the -source directly on github if you are just looking for some example -code: - -* - -Note that if you have not already done so, installing -`blackfriday-tool` will be sufficient to download and install -blackfriday in addition to the tool itself. The tool binary will be -installed in `$GOPATH/bin`. This is a statically-linked binary that -can be copied to wherever you need it without worrying about -dependencies and library versions. - - -Features --------- - -All features of Sundown are supported, including: - -* **Compatibility**. The Markdown v1.0.3 test suite passes with - the `--tidy` option. Without `--tidy`, the differences are - mostly in whitespace and entity escaping, where blackfriday is - more consistent and cleaner. - -* **Common extensions**, including table support, fenced code - blocks, autolinks, strikethroughs, non-strict emphasis, etc. - -* **Safety**. Blackfriday is paranoid when parsing, making it safe - to feed untrusted user input without fear of bad things - happening. The test suite stress tests this and there are no - known inputs that make it crash. If you find one, please let me - know and send me the input that does it. - - NOTE: "safety" in this context means *runtime safety only*. In order to - protect yourself agains JavaScript injection in untrusted content, see - [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content). - -* **Fast processing**. It is fast enough to render on-demand in - most web applications without having to cache the output. - -* **Thread safety**. You can run multiple parsers in different - goroutines without ill effect. There is no dependence on global - shared state. - -* **Minimal dependencies**. Blackfriday only depends on standard - library packages in Go. The source code is pretty - self-contained, so it is easy to add to any project, including - Google App Engine projects. - -* **Standards compliant**. Output successfully validates using the - W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional. - - -Extensions ----------- - -In addition to the standard markdown syntax, this package -implements the following extensions: - -* **Intra-word emphasis supression**. The `_` character is - commonly used inside words when discussing code, so having - markdown interpret it as an emphasis command is usually the - wrong thing. Blackfriday lets you treat all emphasis markers as - normal characters when they occur inside a word. - -* **Tables**. Tables can be created by drawing them in the input - using a simple syntax: - - ``` - Name | Age - --------|------ - Bob | 27 - Alice | 23 - ``` - -* **Fenced code blocks**. In addition to the normal 4-space - indentation to mark code blocks, you can explicitly mark them - and supply a language (to make syntax highlighting simple). Just - mark it like this: - - ``` go - func getTrue() bool { - return true - } - ``` - - You can use 3 or more backticks to mark the beginning of the - block, and the same number to mark the end of the block. - -* **Autolinking**. Blackfriday can find URLs that have not been - explicitly marked as links and turn them into links. - -* **Strikethrough**. Use two tildes (`~~`) to mark text that - should be crossed out. - -* **Hard line breaks**. With this extension enabled (it is off by - default in the `MarkdownBasic` and `MarkdownCommon` convenience - functions), newlines in the input translate into line breaks in - the output. - -* **Smart quotes**. Smartypants-style punctuation substitution is - supported, turning normal double- and single-quote marks into - curly quotes, etc. - -* **LaTeX-style dash parsing** is an additional option, where `--` - is translated into `–`, and `---` is translated into - `—`. This differs from most smartypants processors, which - turn a single hyphen into an ndash and a double hyphen into an - mdash. - -* **Smart fractions**, where anything that looks like a fraction - is translated into suitable HTML (instead of just a few special - cases like most smartypant processors). For example, `4/5` - becomes `45`, which renders as - 45. - - -Other renderers ---------------- - -Blackfriday is structured to allow alternative rendering engines. Here -are a few of note: - -* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown): - provides a GitHub Flavored Markdown renderer with fenced code block - highlighting, clickable header anchor links. - - It's not customizable, and its goal is to produce HTML output - equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode), - except the rendering is performed locally. - -* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt, - but for markdown. - -* LaTeX output: renders output as LaTeX. This is currently part of the - main Blackfriday repository, but may be split into its own project - in the future. If you are interested in owning and maintaining the - LaTeX output component, please be in touch. - - It renders some basic documents, but is only experimental at this - point. In particular, it does not do any inline escaping, so input - that happens to look like LaTeX code will be passed through without - modification. - - -Todo ----- - -* More unit testing -* Improve unicode support. It does not understand all unicode - rules (about what constitutes a letter, a punctuation symbol, - etc.), so it may fail to detect word boundaries correctly in - some instances. It is safe on all utf-8 input. - - -License -------- - -[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt) - - - [1]: http://daringfireball.net/projects/markdown/ "Markdown" - [2]: http://golang.org/ "Go Language" - [3]: https://github.com/vmg/sundown "Sundown" diff --git a/vendor/src/github.com/russross/blackfriday/block.go b/vendor/src/github.com/russross/blackfriday/block.go deleted file mode 100644 index 1f300b3..0000000 --- a/vendor/src/github.com/russross/blackfriday/block.go +++ /dev/null @@ -1,1389 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// Functions to parse block-level elements. -// - -package blackfriday - -import ( - "bytes" - - "github.com/shurcooL/sanitized_anchor_name" -) - -// Parse block-level data. -// Note: this function and many that it calls assume that -// the input buffer ends with a newline. -func (p *parser) block(out *bytes.Buffer, data []byte) { - if len(data) == 0 || data[len(data)-1] != '\n' { - panic("block input is missing terminating newline") - } - - // this is called recursively: enforce a maximum depth - if p.nesting >= p.maxNesting { - return - } - p.nesting++ - - // parse out one block-level construct at a time - for len(data) > 0 { - // prefixed header: - // - // # Header 1 - // ## Header 2 - // ... - // ###### Header 6 - if p.isPrefixHeader(data) { - data = data[p.prefixHeader(out, data):] - continue - } - - // block of preformatted HTML: - // - //
- // ... - //
- if data[0] == '<' { - if i := p.html(out, data, true); i > 0 { - data = data[i:] - continue - } - } - - // title block - // - // % stuff - // % more stuff - // % even more stuff - if p.flags&EXTENSION_TITLEBLOCK != 0 { - if data[0] == '%' { - if i := p.titleBlock(out, data, true); i > 0 { - data = data[i:] - continue - } - } - } - - // blank lines. note: returns the # of bytes to skip - if i := p.isEmpty(data); i > 0 { - data = data[i:] - continue - } - - // indented code block: - // - // func max(a, b int) int { - // if a > b { - // return a - // } - // return b - // } - if p.codePrefix(data) > 0 { - data = data[p.code(out, data):] - continue - } - - // fenced code block: - // - // ``` go - // func fact(n int) int { - // if n <= 1 { - // return n - // } - // return n * fact(n-1) - // } - // ``` - if p.flags&EXTENSION_FENCED_CODE != 0 { - if i := p.fencedCode(out, data, true); i > 0 { - data = data[i:] - continue - } - } - - // horizontal rule: - // - // ------ - // or - // ****** - // or - // ______ - if p.isHRule(data) { - p.r.HRule(out) - var i int - for i = 0; data[i] != '\n'; i++ { - } - data = data[i:] - continue - } - - // block quote: - // - // > A big quote I found somewhere - // > on the web - if p.quotePrefix(data) > 0 { - data = data[p.quote(out, data):] - continue - } - - // table: - // - // Name | Age | Phone - // ------|-----|--------- - // Bob | 31 | 555-1234 - // Alice | 27 | 555-4321 - if p.flags&EXTENSION_TABLES != 0 { - if i := p.table(out, data); i > 0 { - data = data[i:] - continue - } - } - - // an itemized/unordered list: - // - // * Item 1 - // * Item 2 - // - // also works with + or - - if p.uliPrefix(data) > 0 { - data = data[p.list(out, data, 0):] - continue - } - - // a numbered/ordered list: - // - // 1. Item 1 - // 2. Item 2 - if p.oliPrefix(data) > 0 { - data = data[p.list(out, data, LIST_TYPE_ORDERED):] - continue - } - - // definition lists: - // - // Term 1 - // : Definition a - // : Definition b - // - // Term 2 - // : Definition c - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if p.dliPrefix(data) > 0 { - data = data[p.list(out, data, LIST_TYPE_DEFINITION):] - continue - } - } - - // anything else must look like a normal paragraph - // note: this finds underlined headers, too - data = data[p.paragraph(out, data):] - } - - p.nesting-- -} - -func (p *parser) isPrefixHeader(data []byte) bool { - if data[0] != '#' { - return false - } - - if p.flags&EXTENSION_SPACE_HEADERS != 0 { - level := 0 - for level < 6 && data[level] == '#' { - level++ - } - if data[level] != ' ' { - return false - } - } - return true -} - -func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { - level := 0 - for level < 6 && data[level] == '#' { - level++ - } - i := skipChar(data, level, ' ') - end := skipUntilChar(data, i, '\n') - skip := end - id := "" - if p.flags&EXTENSION_HEADER_IDS != 0 { - j, k := 0, 0 - // find start/end of header id - for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ { - } - for k = j + 1; k < end && data[k] != '}'; k++ { - } - // extract header id iff found - if j < end && k < end { - id = string(data[j+2 : k]) - end = j - skip = k + 1 - for end > 0 && data[end-1] == ' ' { - end-- - } - } - } - for end > 0 && data[end-1] == '#' { - if isBackslashEscaped(data, end-1) { - break - } - end-- - } - for end > 0 && data[end-1] == ' ' { - end-- - } - if end > i { - if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { - id = sanitized_anchor_name.Create(string(data[i:end])) - } - work := func() bool { - p.inline(out, data[i:end]) - return true - } - p.r.Header(out, work, level, id) - } - return skip -} - -func (p *parser) isUnderlinedHeader(data []byte) int { - // test of level 1 header - if data[0] == '=' { - i := skipChar(data, 1, '=') - i = skipChar(data, i, ' ') - if data[i] == '\n' { - return 1 - } else { - return 0 - } - } - - // test of level 2 header - if data[0] == '-' { - i := skipChar(data, 1, '-') - i = skipChar(data, i, ' ') - if data[i] == '\n' { - return 2 - } else { - return 0 - } - } - - return 0 -} - -func (p *parser) titleBlock(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '%' { - return 0 - } - splitData := bytes.Split(data, []byte("\n")) - var i int - for idx, b := range splitData { - if !bytes.HasPrefix(b, []byte("%")) { - i = idx // - 1 - break - } - } - - data = bytes.Join(splitData[0:i], []byte("\n")) - p.r.TitleBlock(out, data) - - return len(data) -} - -func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { - var i, j int - - // identify the opening tag - if data[0] != '<' { - return 0 - } - curtag, tagfound := p.htmlFindTag(data[1:]) - - // handle special cases - if !tagfound { - // check for an HTML comment - if size := p.htmlComment(out, data, doRender); size > 0 { - return size - } - - // check for an
tag - if size := p.htmlHr(out, data, doRender); size > 0 { - return size - } - - // no special case recognized - return 0 - } - - // look for an unindented matching closing tag - // followed by a blank line - found := false - /* - closetag := []byte("\n") - j = len(curtag) + 1 - for !found { - // scan for a closing tag at the beginning of a line - if skip := bytes.Index(data[j:], closetag); skip >= 0 { - j += skip + len(closetag) - } else { - break - } - - // see if it is the only thing on the line - if skip := p.isEmpty(data[j:]); skip > 0 { - // see if it is followed by a blank line/eof - j += skip - if j >= len(data) { - found = true - i = j - } else { - if skip := p.isEmpty(data[j:]); skip > 0 { - j += skip - found = true - i = j - } - } - } - } - */ - - // if not found, try a second pass looking for indented match - // but not if tag is "ins" or "del" (following original Markdown.pl) - if !found && curtag != "ins" && curtag != "del" { - i = 1 - for i < len(data) { - i++ - for i < len(data) && !(data[i-1] == '<' && data[i] == '/') { - i++ - } - - if i+2+len(curtag) >= len(data) { - break - } - - j = p.htmlFindEnd(curtag, data[i-1:]) - - if j > 0 { - i += j - 1 - found = true - break - } - } - } - - if !found { - return 0 - } - - // the end of the block has been found - if doRender { - // trim newlines - end := i - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - - return i -} - -// HTML comment, lax form -func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' { - return 0 - } - - i := 5 - - // scan for an end-of-comment marker, across lines if necessary - for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') { - i++ - } - i++ - - // no end-of-comment marker - if i >= len(data) { - return 0 - } - - // needs to end with a blank line - if j := p.isEmpty(data[i:]); j > 0 { - size := i + j - if doRender { - // trim trailing newlines - end := size - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - return size - } - - return 0 -} - -// HR, which is the only self-closing block tag considered -func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') { - return 0 - } - if data[3] != ' ' && data[3] != '/' && data[3] != '>' { - // not an
tag after all; at least not a valid one - return 0 - } - - i := 3 - for data[i] != '>' && data[i] != '\n' { - i++ - } - - if data[i] == '>' { - i++ - if j := p.isEmpty(data[i:]); j > 0 { - size := i + j - if doRender { - // trim newlines - end := size - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - return size - } - } - - return 0 -} - -func (p *parser) htmlFindTag(data []byte) (string, bool) { - i := 0 - for isalnum(data[i]) { - i++ - } - key := string(data[:i]) - if blockTags[key] { - return key, true - } - return "", false -} - -func (p *parser) htmlFindEnd(tag string, data []byte) int { - // assume data[0] == '<' && data[1] == '/' already tested - - // check if tag is a match - closetag := []byte("") - if !bytes.HasPrefix(data, closetag) { - return 0 - } - i := len(closetag) - - // check that the rest of the line is blank - skip := 0 - if skip = p.isEmpty(data[i:]); skip == 0 { - return 0 - } - i += skip - skip = 0 - - if i >= len(data) { - return i - } - - if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { - return i - } - if skip = p.isEmpty(data[i:]); skip == 0 { - // following line must be blank - return 0 - } - - return i + skip -} - -func (p *parser) isEmpty(data []byte) int { - // it is okay to call isEmpty on an empty buffer - if len(data) == 0 { - return 0 - } - - var i int - for i = 0; i < len(data) && data[i] != '\n'; i++ { - if data[i] != ' ' && data[i] != '\t' { - return 0 - } - } - return i + 1 -} - -func (p *parser) isHRule(data []byte) bool { - i := 0 - - // skip up to three spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // look at the hrule char - if data[i] != '*' && data[i] != '-' && data[i] != '_' { - return false - } - c := data[i] - - // the whole line must be the char or whitespace - n := 0 - for data[i] != '\n' { - switch { - case data[i] == c: - n++ - case data[i] != ' ': - return false - } - i++ - } - - return n >= 3 -} - -func (p *parser) isFencedCode(data []byte, syntax **string, oldmarker string) (skip int, marker string) { - i, size := 0, 0 - skip = 0 - - // skip up to three spaces - for i < len(data) && i < 3 && data[i] == ' ' { - i++ - } - if i >= len(data) { - return - } - - // check for the marker characters: ~ or ` - if data[i] != '~' && data[i] != '`' { - return - } - - c := data[i] - - // the whole line must be the same char or whitespace - for i < len(data) && data[i] == c { - size++ - i++ - } - - if i >= len(data) { - return - } - - // the marker char must occur at least 3 times - if size < 3 { - return - } - marker = string(data[i-size : i]) - - // if this is the end marker, it must match the beginning marker - if oldmarker != "" && marker != oldmarker { - return - } - - if syntax != nil { - syn := 0 - i = skipChar(data, i, ' ') - - if i >= len(data) { - return - } - - syntaxStart := i - - if data[i] == '{' { - i++ - syntaxStart++ - - for i < len(data) && data[i] != '}' && data[i] != '\n' { - syn++ - i++ - } - - if i >= len(data) || data[i] != '}' { - return - } - - // strip all whitespace at the beginning and the end - // of the {} block - for syn > 0 && isspace(data[syntaxStart]) { - syntaxStart++ - syn-- - } - - for syn > 0 && isspace(data[syntaxStart+syn-1]) { - syn-- - } - - i++ - } else { - for i < len(data) && !isspace(data[i]) { - syn++ - i++ - } - } - - language := string(data[syntaxStart : syntaxStart+syn]) - *syntax = &language - } - - i = skipChar(data, i, ' ') - if i >= len(data) || data[i] != '\n' { - return - } - - skip = i + 1 - return -} - -func (p *parser) fencedCode(out *bytes.Buffer, data []byte, doRender bool) int { - var lang *string - beg, marker := p.isFencedCode(data, &lang, "") - if beg == 0 || beg >= len(data) { - return 0 - } - - var work bytes.Buffer - - for { - // safe to assume beg < len(data) - - // check for the end of the code block - fenceEnd, _ := p.isFencedCode(data[beg:], nil, marker) - if fenceEnd != 0 { - beg += fenceEnd - break - } - - // copy the current line - end := skipUntilChar(data, beg, '\n') + 1 - - // did we reach the end of the buffer without a closing marker? - if end >= len(data) { - return 0 - } - - // verbatim copy to the working buffer - if doRender { - work.Write(data[beg:end]) - } - beg = end - } - - syntax := "" - if lang != nil { - syntax = *lang - } - - if doRender { - p.r.BlockCode(out, work.Bytes(), syntax) - } - - return beg -} - -func (p *parser) table(out *bytes.Buffer, data []byte) int { - var header bytes.Buffer - i, columns := p.tableHeader(&header, data) - if i == 0 { - return 0 - } - - var body bytes.Buffer - - for i < len(data) { - pipes, rowStart := 0, i - for ; data[i] != '\n'; i++ { - if data[i] == '|' { - pipes++ - } - } - - if pipes == 0 { - i = rowStart - break - } - - // include the newline in data sent to tableRow - i++ - p.tableRow(&body, data[rowStart:i], columns, false) - } - - p.r.Table(out, header.Bytes(), body.Bytes(), columns) - - return i -} - -// check if the specified position is preceded by an odd number of backslashes -func isBackslashEscaped(data []byte, i int) bool { - backslashes := 0 - for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' { - backslashes++ - } - return backslashes&1 == 1 -} - -func (p *parser) tableHeader(out *bytes.Buffer, data []byte) (size int, columns []int) { - i := 0 - colCount := 1 - for i = 0; data[i] != '\n'; i++ { - if data[i] == '|' && !isBackslashEscaped(data, i) { - colCount++ - } - } - - // doesn't look like a table header - if colCount == 1 { - return - } - - // include the newline in the data sent to tableRow - header := data[:i+1] - - // column count ignores pipes at beginning or end of line - if data[0] == '|' { - colCount-- - } - if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) { - colCount-- - } - - columns = make([]int, colCount) - - // move on to the header underline - i++ - if i >= len(data) { - return - } - - if data[i] == '|' && !isBackslashEscaped(data, i) { - i++ - } - i = skipChar(data, i, ' ') - - // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3 - // and trailing | optional on last column - col := 0 - for data[i] != '\n' { - dashes := 0 - - if data[i] == ':' { - i++ - columns[col] |= TABLE_ALIGNMENT_LEFT - dashes++ - } - for data[i] == '-' { - i++ - dashes++ - } - if data[i] == ':' { - i++ - columns[col] |= TABLE_ALIGNMENT_RIGHT - dashes++ - } - for data[i] == ' ' { - i++ - } - - // end of column test is messy - switch { - case dashes < 3: - // not a valid column - return - - case data[i] == '|' && !isBackslashEscaped(data, i): - // marker found, now skip past trailing whitespace - col++ - i++ - for data[i] == ' ' { - i++ - } - - // trailing junk found after last column - if col >= colCount && data[i] != '\n' { - return - } - - case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount: - // something else found where marker was required - return - - case data[i] == '\n': - // marker is optional for the last column - col++ - - default: - // trailing junk found after last column - return - } - } - if col != colCount { - return - } - - p.tableRow(out, header, columns, true) - size = i + 1 - return -} - -func (p *parser) tableRow(out *bytes.Buffer, data []byte, columns []int, header bool) { - i, col := 0, 0 - var rowWork bytes.Buffer - - if data[i] == '|' && !isBackslashEscaped(data, i) { - i++ - } - - for col = 0; col < len(columns) && i < len(data); col++ { - for data[i] == ' ' { - i++ - } - - cellStart := i - - for (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' { - i++ - } - - cellEnd := i - - // skip the end-of-cell marker, possibly taking us past end of buffer - i++ - - for cellEnd > cellStart && data[cellEnd-1] == ' ' { - cellEnd-- - } - - var cellWork bytes.Buffer - p.inline(&cellWork, data[cellStart:cellEnd]) - - if header { - p.r.TableHeaderCell(&rowWork, cellWork.Bytes(), columns[col]) - } else { - p.r.TableCell(&rowWork, cellWork.Bytes(), columns[col]) - } - } - - // pad it out with empty columns to get the right number - for ; col < len(columns); col++ { - if header { - p.r.TableHeaderCell(&rowWork, nil, columns[col]) - } else { - p.r.TableCell(&rowWork, nil, columns[col]) - } - } - - // silently ignore rows with too many cells - - p.r.TableRow(out, rowWork.Bytes()) -} - -// returns blockquote prefix length -func (p *parser) quotePrefix(data []byte) int { - i := 0 - for i < 3 && data[i] == ' ' { - i++ - } - if data[i] == '>' { - if data[i+1] == ' ' { - return i + 2 - } - return i + 1 - } - return 0 -} - -// parse a blockquote fragment -func (p *parser) quote(out *bytes.Buffer, data []byte) int { - var raw bytes.Buffer - beg, end := 0, 0 - for beg < len(data) { - end = beg - for data[end] != '\n' { - end++ - } - end++ - - if pre := p.quotePrefix(data[beg:]); pre > 0 { - // skip the prefix - beg += pre - } else if p.isEmpty(data[beg:]) > 0 && - (end >= len(data) || - (p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0)) { - // blockquote ends with at least one blank line - // followed by something without a blockquote prefix - break - } - - // this line is part of the blockquote - raw.Write(data[beg:end]) - beg = end - } - - var cooked bytes.Buffer - p.block(&cooked, raw.Bytes()) - p.r.BlockQuote(out, cooked.Bytes()) - return end -} - -// returns prefix length for block code -func (p *parser) codePrefix(data []byte) int { - if data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' { - return 4 - } - return 0 -} - -func (p *parser) code(out *bytes.Buffer, data []byte) int { - var work bytes.Buffer - - i := 0 - for i < len(data) { - beg := i - for data[i] != '\n' { - i++ - } - i++ - - blankline := p.isEmpty(data[beg:i]) > 0 - if pre := p.codePrefix(data[beg:i]); pre > 0 { - beg += pre - } else if !blankline { - // non-empty, non-prefixed line breaks the pre - i = beg - break - } - - // verbatim copy to the working buffeu - if blankline { - work.WriteByte('\n') - } else { - work.Write(data[beg:i]) - } - } - - // trim all the \n off the end of work - workbytes := work.Bytes() - eol := len(workbytes) - for eol > 0 && workbytes[eol-1] == '\n' { - eol-- - } - if eol != len(workbytes) { - work.Truncate(eol) - } - - work.WriteByte('\n') - - p.r.BlockCode(out, work.Bytes(), "") - - return i -} - -// returns unordered list item prefix -func (p *parser) uliPrefix(data []byte) int { - i := 0 - - // start with up to 3 spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // need a *, +, or - followed by a space - if (data[i] != '*' && data[i] != '+' && data[i] != '-') || - data[i+1] != ' ' { - return 0 - } - return i + 2 -} - -// returns ordered list item prefix -func (p *parser) oliPrefix(data []byte) int { - i := 0 - - // start with up to 3 spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // count the digits - start := i - for data[i] >= '0' && data[i] <= '9' { - i++ - } - - // we need >= 1 digits followed by a dot and a space - if start == i || data[i] != '.' || data[i+1] != ' ' { - return 0 - } - return i + 2 -} - -// returns definition list item prefix -func (p *parser) dliPrefix(data []byte) int { - i := 0 - - // need a : followed by a spaces - if data[i] != ':' || data[i+1] != ' ' { - return 0 - } - for data[i] == ' ' { - i++ - } - return i + 2 -} - -// parse ordered or unordered list block -func (p *parser) list(out *bytes.Buffer, data []byte, flags int) int { - i := 0 - flags |= LIST_ITEM_BEGINNING_OF_LIST - work := func() bool { - for i < len(data) { - skip := p.listItem(out, data[i:], &flags) - i += skip - - if skip == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { - break - } - flags &= ^LIST_ITEM_BEGINNING_OF_LIST - } - return true - } - - p.r.List(out, work, flags) - return i -} - -// Parse a single list item. -// Assumes initial prefix is already removed if this is a sublist. -func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int { - // keep track of the indentation of the first line - itemIndent := 0 - for itemIndent < 3 && data[itemIndent] == ' ' { - itemIndent++ - } - - i := p.uliPrefix(data) - if i == 0 { - i = p.oliPrefix(data) - } - if i == 0 { - i = p.dliPrefix(data) - // reset definition term flag - if i > 0 { - *flags &= ^LIST_TYPE_TERM - } - } - if i == 0 { - // if in defnition list, set term flag and continue - if *flags&LIST_TYPE_DEFINITION != 0 { - *flags |= LIST_TYPE_TERM - } else { - return 0 - } - } - - // skip leading whitespace on first line - for data[i] == ' ' { - i++ - } - - // find the end of the line - line := i - for i > 0 && data[i-1] != '\n' { - i++ - } - - // get working buffer - var raw bytes.Buffer - - // put the first line into the working buffer - raw.Write(data[line:i]) - line = i - - // process the following lines - containsBlankLine := false - sublist := 0 - -gatherlines: - for line < len(data) { - i++ - - // find the end of this line - for data[i-1] != '\n' { - i++ - } - - // if it is an empty line, guess that it is part of this item - // and move on to the next line - if p.isEmpty(data[line:i]) > 0 { - containsBlankLine = true - line = i - continue - } - - // calculate the indentation - indent := 0 - for indent < 4 && line+indent < i && data[line+indent] == ' ' { - indent++ - } - - chunk := data[line+indent : i] - - // evaluate how this line fits in - switch { - // is this a nested list item? - case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) || - p.oliPrefix(chunk) > 0 || - p.dliPrefix(chunk) > 0: - - if containsBlankLine { - *flags |= LIST_ITEM_CONTAINS_BLOCK - } - - // to be a nested list, it must be indented more - // if not, it is the next item in the same list - if indent <= itemIndent { - break gatherlines - } - - // is this the first item in the nested list? - if sublist == 0 { - sublist = raw.Len() - } - - // is this a nested prefix header? - case p.isPrefixHeader(chunk): - // if the header is not indented, it is not nested in the list - // and thus ends the list - if containsBlankLine && indent < 4 { - *flags |= LIST_ITEM_END_OF_LIST - break gatherlines - } - *flags |= LIST_ITEM_CONTAINS_BLOCK - - // anything following an empty line is only part - // of this item if it is indented 4 spaces - // (regardless of the indentation of the beginning of the item) - case containsBlankLine && indent < 4: - if *flags&LIST_TYPE_DEFINITION != 0 && i < len(data)-1 { - // is the next item still a part of this list? - next := i - for data[next] != '\n' { - next++ - } - for next < len(data)-1 && data[next] == '\n' { - next++ - } - if i < len(data)-1 && data[i] != ':' && data[next] != ':' { - *flags |= LIST_ITEM_END_OF_LIST - } - } else { - *flags |= LIST_ITEM_END_OF_LIST - } - break gatherlines - - // a blank line means this should be parsed as a block - case containsBlankLine: - raw.WriteByte('\n') - *flags |= LIST_ITEM_CONTAINS_BLOCK - } - - // if this line was preceeded by one or more blanks, - // re-introduce the blank into the buffer - if containsBlankLine { - containsBlankLine = false - raw.WriteByte('\n') - - } - - // add the line into the working buffer without prefix - raw.Write(data[line+indent : i]) - - line = i - } - - rawBytes := raw.Bytes() - - // render the contents of the list item - var cooked bytes.Buffer - if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 && *flags&LIST_TYPE_TERM == 0 { - // intermediate render of block item, except for definition term - if sublist > 0 { - p.block(&cooked, rawBytes[:sublist]) - p.block(&cooked, rawBytes[sublist:]) - } else { - p.block(&cooked, rawBytes) - } - } else { - // intermediate render of inline item - if sublist > 0 { - p.inline(&cooked, rawBytes[:sublist]) - p.block(&cooked, rawBytes[sublist:]) - } else { - p.inline(&cooked, rawBytes) - } - } - - // render the actual list item - cookedBytes := cooked.Bytes() - parsedEnd := len(cookedBytes) - - // strip trailing newlines - for parsedEnd > 0 && cookedBytes[parsedEnd-1] == '\n' { - parsedEnd-- - } - p.r.ListItem(out, cookedBytes[:parsedEnd], *flags) - - return line -} - -// render a single paragraph that has already been parsed out -func (p *parser) renderParagraph(out *bytes.Buffer, data []byte) { - if len(data) == 0 { - return - } - - // trim leading spaces - beg := 0 - for data[beg] == ' ' { - beg++ - } - - // trim trailing newline - end := len(data) - 1 - - // trim trailing spaces - for end > beg && data[end-1] == ' ' { - end-- - } - - work := func() bool { - p.inline(out, data[beg:end]) - return true - } - p.r.Paragraph(out, work) -} - -func (p *parser) paragraph(out *bytes.Buffer, data []byte) int { - // prev: index of 1st char of previous line - // line: index of 1st char of current line - // i: index of cursor/end of current line - var prev, line, i int - - // keep going until we find something to mark the end of the paragraph - for i < len(data) { - // mark the beginning of the current line - prev = line - current := data[i:] - line = i - - // did we find a blank line marking the end of the paragraph? - if n := p.isEmpty(current); n > 0 { - // did this blank line followed by a definition list item? - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if i < len(data)-1 && data[i+1] == ':' { - return p.list(out, data[prev:], LIST_TYPE_DEFINITION) - } - } - - p.renderParagraph(out, data[:i]) - return i + n - } - - // an underline under some text marks a header, so our paragraph ended on prev line - if i > 0 { - if level := p.isUnderlinedHeader(current); level > 0 { - // render the paragraph - p.renderParagraph(out, data[:prev]) - - // ignore leading and trailing whitespace - eol := i - 1 - for prev < eol && data[prev] == ' ' { - prev++ - } - for eol > prev && data[eol-1] == ' ' { - eol-- - } - - // render the header - // this ugly double closure avoids forcing variables onto the heap - work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool { - return func() bool { - pp.inline(o, d) - return true - } - }(out, p, data[prev:eol]) - - id := "" - if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { - id = sanitized_anchor_name.Create(string(data[prev:eol])) - } - - p.r.Header(out, work, level, id) - - // find the end of the underline - for data[i] != '\n' { - i++ - } - return i - } - } - - // if the next line starts a block of HTML, then the paragraph ends here - if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { - if data[i] == '<' && p.html(out, current, false) > 0 { - // rewind to before the HTML block - p.renderParagraph(out, data[:i]) - return i - } - } - - // if there's a prefixed header or a horizontal rule after this, paragraph is over - if p.isPrefixHeader(current) || p.isHRule(current) { - p.renderParagraph(out, data[:i]) - return i - } - - // if there's a definition list item, prev line is a definition term - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if p.dliPrefix(current) != 0 { - return p.list(out, data[prev:], LIST_TYPE_DEFINITION) - } - } - - // if there's a list after this, paragraph is over - if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 { - if p.uliPrefix(current) != 0 || - p.oliPrefix(current) != 0 || - p.quotePrefix(current) != 0 || - p.codePrefix(current) != 0 { - p.renderParagraph(out, data[:i]) - return i - } - } - - // otherwise, scan to the beginning of the next line - for data[i] != '\n' { - i++ - } - i++ - } - - p.renderParagraph(out, data[:i]) - return i -} diff --git a/vendor/src/github.com/russross/blackfriday/block_test.go b/vendor/src/github.com/russross/blackfriday/block_test.go deleted file mode 100644 index f52506f..0000000 --- a/vendor/src/github.com/russross/blackfriday/block_test.go +++ /dev/null @@ -1,1407 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// Unit tests for block parsing -// - -package blackfriday - -import ( - "testing" -) - -func runMarkdownBlockWithRenderer(input string, extensions int, renderer Renderer) string { - return string(Markdown([]byte(input), renderer, extensions)) -} - -func runMarkdownBlock(input string, extensions int) string { - htmlFlags := 0 - htmlFlags |= HTML_USE_XHTML - - renderer := HtmlRenderer(htmlFlags, "", "") - - return runMarkdownBlockWithRenderer(input, extensions, renderer) -} - -func runnerWithRendererParameters(parameters HtmlRendererParameters) func(string, int) string { - return func(input string, extensions int) string { - htmlFlags := 0 - htmlFlags |= HTML_USE_XHTML - - renderer := HtmlRendererWithParameters(htmlFlags, "", "", parameters) - - return runMarkdownBlockWithRenderer(input, extensions, renderer) - } -} - -func doTestsBlock(t *testing.T, tests []string, extensions int) { - doTestsBlockWithRunner(t, tests, extensions, runMarkdownBlock) -} - -func doTestsBlockWithRunner(t *testing.T, tests []string, extensions int, runner func(string, int) string) { - // catch and report panics - var candidate string - defer func() { - if err := recover(); err != nil { - t.Errorf("\npanic while processing [%#v]: %s\n", candidate, err) - } - }() - - for i := 0; i+1 < len(tests); i += 2 { - input := tests[i] - candidate = input - expected := tests[i+1] - actual := runner(candidate, extensions) - if actual != expected { - t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]", - candidate, expected, actual) - } - - // now test every substring to stress test bounds checking - if !testing.Short() { - for start := 0; start < len(input); start++ { - for end := start + 1; end <= len(input); end++ { - candidate = input[start:end] - _ = runMarkdownBlock(candidate, extensions) - } - } - } - } -} - -func TestPrefixHeaderNoExtensions(t *testing.T) { - var tests = []string{ - "# Header 1\n", - "

Header 1

\n", - - "## Header 2\n", - "

Header 2

\n", - - "### Header 3\n", - "

Header 3

\n", - - "#### Header 4\n", - "

Header 4

\n", - - "##### Header 5\n", - "
Header 5
\n", - - "###### Header 6\n", - "
Header 6
\n", - - "####### Header 7\n", - "
# Header 7
\n", - - "#Header 1\n", - "

Header 1

\n", - - "##Header 2\n", - "

Header 2

\n", - - "###Header 3\n", - "

Header 3

\n", - - "####Header 4\n", - "

Header 4

\n", - - "#####Header 5\n", - "
Header 5
\n", - - "######Header 6\n", - "
Header 6
\n", - - "#######Header 7\n", - "
#Header 7
\n", - - "Hello\n# Header 1\nGoodbye\n", - "

Hello

\n\n

Header 1

\n\n

Goodbye

\n", - - "* List\n# Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n#Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n * Nested list\n # Nested header\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list

      \n\n" + - "

      Nested header

    • \n
  • \n
\n", - - "#Header 1 \\#\n", - "

Header 1 #

\n", - - "#Header 1 \\# foo\n", - "

Header 1 # foo

\n", - - "#Header 1 #\\##\n", - "

Header 1 ##

\n", - } - doTestsBlock(t, tests, 0) -} - -func TestPrefixHeaderSpaceExtension(t *testing.T) { - var tests = []string{ - "# Header 1\n", - "

Header 1

\n", - - "## Header 2\n", - "

Header 2

\n", - - "### Header 3\n", - "

Header 3

\n", - - "#### Header 4\n", - "

Header 4

\n", - - "##### Header 5\n", - "
Header 5
\n", - - "###### Header 6\n", - "
Header 6
\n", - - "####### Header 7\n", - "

####### Header 7

\n", - - "#Header 1\n", - "

#Header 1

\n", - - "##Header 2\n", - "

##Header 2

\n", - - "###Header 3\n", - "

###Header 3

\n", - - "####Header 4\n", - "

####Header 4

\n", - - "#####Header 5\n", - "

#####Header 5

\n", - - "######Header 6\n", - "

######Header 6

\n", - - "#######Header 7\n", - "

#######Header 7

\n", - - "Hello\n# Header 1\nGoodbye\n", - "

Hello

\n\n

Header 1

\n\n

Goodbye

\n", - - "* List\n# Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n#Header\n* List\n", - "
    \n
  • List\n#Header
  • \n
  • List
  • \n
\n", - - "* List\n * Nested list\n # Nested header\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list

      \n\n" + - "

      Nested header

    • \n
  • \n
\n", - } - doTestsBlock(t, tests, EXTENSION_SPACE_HEADERS) -} - -func TestPrefixHeaderIdExtension(t *testing.T) { - var tests = []string{ - "# Header 1 {#someid}\n", - "

Header 1

\n", - - "# Header 1 {#someid} \n", - "

Header 1

\n", - - "# Header 1 {#someid}\n", - "

Header 1

\n", - - "# Header 1 {#someid\n", - "

Header 1 {#someid

\n", - - "# Header 1 {#someid\n", - "

Header 1 {#someid

\n", - - "# Header 1 {#someid}}\n", - "

Header 1

\n\n

}

\n", - - "## Header 2 {#someid}\n", - "

Header 2

\n", - - "### Header 3 {#someid}\n", - "

Header 3

\n", - - "#### Header 4 {#someid}\n", - "

Header 4

\n", - - "##### Header 5 {#someid}\n", - "
Header 5
\n", - - "###### Header 6 {#someid}\n", - "
Header 6
\n", - - "####### Header 7 {#someid}\n", - "
# Header 7
\n", - - "# Header 1 # {#someid}\n", - "

Header 1

\n", - - "## Header 2 ## {#someid}\n", - "

Header 2

\n", - - "Hello\n# Header 1\nGoodbye\n", - "

Hello

\n\n

Header 1

\n\n

Goodbye

\n", - - "* List\n# Header {#someid}\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n#Header {#someid}\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n * Nested list\n # Nested header {#someid}\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list

      \n\n" + - "

      Nested header

    • \n
  • \n
\n", - } - doTestsBlock(t, tests, EXTENSION_HEADER_IDS) -} - -func TestPrefixHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) { - var tests = []string{ - "# header 1 {#someid}\n", - "

header 1

\n", - - "## header 2 {#someid}\n", - "

header 2

\n", - - "### header 3 {#someid}\n", - "

header 3

\n", - - "#### header 4 {#someid}\n", - "

header 4

\n", - - "##### header 5 {#someid}\n", - "
header 5
\n", - - "###### header 6 {#someid}\n", - "
header 6
\n", - - "####### header 7 {#someid}\n", - "
# header 7
\n", - - "# header 1 # {#someid}\n", - "

header 1

\n", - - "## header 2 ## {#someid}\n", - "

header 2

\n", - - "* List\n# Header {#someid}\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n#Header {#someid}\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n * Nested list\n # Nested header {#someid}\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list

      \n\n" + - "

      Nested header

    • \n
  • \n
\n", - } - - parameters := HtmlRendererParameters{ - HeaderIDPrefix: "PRE:", - HeaderIDSuffix: ":POST", - } - - doTestsBlockWithRunner(t, tests, EXTENSION_HEADER_IDS, runnerWithRendererParameters(parameters)) -} - -func TestPrefixAutoHeaderIdExtension(t *testing.T) { - var tests = []string{ - "# Header 1\n", - "

Header 1

\n", - - "# Header 1 \n", - "

Header 1

\n", - - "## Header 2\n", - "

Header 2

\n", - - "### Header 3\n", - "

Header 3

\n", - - "#### Header 4\n", - "

Header 4

\n", - - "##### Header 5\n", - "
Header 5
\n", - - "###### Header 6\n", - "
Header 6
\n", - - "####### Header 7\n", - "
# Header 7
\n", - - "Hello\n# Header 1\nGoodbye\n", - "

Hello

\n\n

Header 1

\n\n

Goodbye

\n", - - "* List\n# Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n#Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n * Nested list\n # Nested header\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list

      \n\n" + - "

      Nested header

    • \n
  • \n
\n", - - "# Header\n\n# Header\n", - "

Header

\n\n

Header

\n", - - "# Header 1\n\n# Header 1", - "

Header 1

\n\n

Header 1

\n", - - "# Header\n\n# Header 1\n\n# Header\n\n# Header", - "

Header

\n\n

Header 1

\n\n

Header

\n\n

Header

\n", - } - doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS) -} - -func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) { - var tests = []string{ - "# Header 1\n", - "

Header 1

\n", - - "# Header 1 \n", - "

Header 1

\n", - - "## Header 2\n", - "

Header 2

\n", - - "### Header 3\n", - "

Header 3

\n", - - "#### Header 4\n", - "

Header 4

\n", - - "##### Header 5\n", - "
Header 5
\n", - - "###### Header 6\n", - "
Header 6
\n", - - "####### Header 7\n", - "
# Header 7
\n", - - "Hello\n# Header 1\nGoodbye\n", - "

Hello

\n\n

Header 1

\n\n

Goodbye

\n", - - "* List\n# Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n#Header\n* List\n", - "
    \n
  • List

    \n\n

    Header

  • \n\n
  • List

  • \n
\n", - - "* List\n * Nested list\n # Nested header\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list

      \n\n" + - "

      Nested header

    • \n
  • \n
\n", - - "# Header\n\n# Header\n", - "

Header

\n\n

Header

\n", - - "# Header 1\n\n# Header 1", - "

Header 1

\n\n

Header 1

\n", - - "# Header\n\n# Header 1\n\n# Header\n\n# Header", - "

Header

\n\n

Header 1

\n\n

Header

\n\n

Header

\n", - } - - parameters := HtmlRendererParameters{ - HeaderIDPrefix: "PRE:", - HeaderIDSuffix: ":POST", - } - - doTestsBlockWithRunner(t, tests, EXTENSION_AUTO_HEADER_IDS, runnerWithRendererParameters(parameters)) -} - -func TestPrefixMultipleHeaderExtensions(t *testing.T) { - var tests = []string{ - "# Header\n\n# Header {#header}\n\n# Header 1", - "

Header

\n\n

Header

\n\n

Header 1

\n", - } - doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS|EXTENSION_HEADER_IDS) -} - -func TestUnderlineHeaders(t *testing.T) { - var tests = []string{ - "Header 1\n========\n", - "

Header 1

\n", - - "Header 2\n--------\n", - "

Header 2

\n", - - "A\n=\n", - "

A

\n", - - "B\n-\n", - "

B

\n", - - "Paragraph\nHeader\n=\n", - "

Paragraph

\n\n

Header

\n", - - "Header\n===\nParagraph\n", - "

Header

\n\n

Paragraph

\n", - - "Header\n===\nAnother header\n---\n", - "

Header

\n\n

Another header

\n", - - " Header\n======\n", - "

Header

\n", - - " Code\n========\n", - "
Code\n
\n\n

========

\n", - - "Header with *inline*\n=====\n", - "

Header with inline

\n", - - "* List\n * Sublist\n Not a header\n ------\n", - "
    \n
  • List\n\n
      \n
    • Sublist\nNot a header\n------
    • \n
  • \n
\n", - - "Paragraph\n\n\n\n\nHeader\n===\n", - "

Paragraph

\n\n

Header

\n", - - "Trailing space \n==== \n\n", - "

Trailing space

\n", - - "Trailing spaces\n==== \n\n", - "

Trailing spaces

\n", - - "Double underline\n=====\n=====\n", - "

Double underline

\n\n

=====

\n", - } - doTestsBlock(t, tests, 0) -} - -func TestUnderlineHeadersAutoIDs(t *testing.T) { - var tests = []string{ - "Header 1\n========\n", - "

Header 1

\n", - - "Header 2\n--------\n", - "

Header 2

\n", - - "A\n=\n", - "

A

\n", - - "B\n-\n", - "

B

\n", - - "Paragraph\nHeader\n=\n", - "

Paragraph

\n\n

Header

\n", - - "Header\n===\nParagraph\n", - "

Header

\n\n

Paragraph

\n", - - "Header\n===\nAnother header\n---\n", - "

Header

\n\n

Another header

\n", - - " Header\n======\n", - "

Header

\n", - - "Header with *inline*\n=====\n", - "

Header with inline

\n", - - "Paragraph\n\n\n\n\nHeader\n===\n", - "

Paragraph

\n\n

Header

\n", - - "Trailing space \n==== \n\n", - "

Trailing space

\n", - - "Trailing spaces\n==== \n\n", - "

Trailing spaces

\n", - - "Double underline\n=====\n=====\n", - "

Double underline

\n\n

=====

\n", - - "Header\n======\n\nHeader\n======\n", - "

Header

\n\n

Header

\n", - - "Header 1\n========\n\nHeader 1\n========\n", - "

Header 1

\n\n

Header 1

\n", - } - doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS) -} - -func TestHorizontalRule(t *testing.T) { - var tests = []string{ - "-\n", - "

-

\n", - - "--\n", - "

--

\n", - - "---\n", - "
\n", - - "----\n", - "
\n", - - "*\n", - "

*

\n", - - "**\n", - "

**

\n", - - "***\n", - "
\n", - - "****\n", - "
\n", - - "_\n", - "

_

\n", - - "__\n", - "

__

\n", - - "___\n", - "
\n", - - "____\n", - "
\n", - - "-*-\n", - "

-*-

\n", - - "- - -\n", - "
\n", - - "* * *\n", - "
\n", - - "_ _ _\n", - "
\n", - - "-----*\n", - "

-----*

\n", - - " ------ \n", - "
\n", - - "Hello\n***\n", - "

Hello

\n\n
\n", - - "---\n***\n___\n", - "
\n\n
\n\n
\n", - } - doTestsBlock(t, tests, 0) -} - -func TestUnorderedList(t *testing.T) { - var tests = []string{ - "* Hello\n", - "
    \n
  • Hello
  • \n
\n", - - "* Yin\n* Yang\n", - "
    \n
  • Yin
  • \n
  • Yang
  • \n
\n", - - "* Ting\n* Bong\n* Goo\n", - "
    \n
  • Ting
  • \n
  • Bong
  • \n
  • Goo
  • \n
\n", - - "* Yin\n\n* Yang\n", - "
    \n
  • Yin

  • \n\n
  • Yang

  • \n
\n", - - "* Ting\n\n* Bong\n* Goo\n", - "
    \n
  • Ting

  • \n\n
  • Bong

  • \n\n
  • Goo

  • \n
\n", - - "+ Hello\n", - "
    \n
  • Hello
  • \n
\n", - - "+ Yin\n+ Yang\n", - "
    \n
  • Yin
  • \n
  • Yang
  • \n
\n", - - "+ Ting\n+ Bong\n+ Goo\n", - "
    \n
  • Ting
  • \n
  • Bong
  • \n
  • Goo
  • \n
\n", - - "+ Yin\n\n+ Yang\n", - "
    \n
  • Yin

  • \n\n
  • Yang

  • \n
\n", - - "+ Ting\n\n+ Bong\n+ Goo\n", - "
    \n
  • Ting

  • \n\n
  • Bong

  • \n\n
  • Goo

  • \n
\n", - - "- Hello\n", - "
    \n
  • Hello
  • \n
\n", - - "- Yin\n- Yang\n", - "
    \n
  • Yin
  • \n
  • Yang
  • \n
\n", - - "- Ting\n- Bong\n- Goo\n", - "
    \n
  • Ting
  • \n
  • Bong
  • \n
  • Goo
  • \n
\n", - - "- Yin\n\n- Yang\n", - "
    \n
  • Yin

  • \n\n
  • Yang

  • \n
\n", - - "- Ting\n\n- Bong\n- Goo\n", - "
    \n
  • Ting

  • \n\n
  • Bong

  • \n\n
  • Goo

  • \n
\n", - - "*Hello\n", - "

*Hello

\n", - - "* Hello \n", - "
    \n
  • Hello
  • \n
\n", - - "* Hello \n Next line \n", - "
    \n
  • Hello\nNext line
  • \n
\n", - - "Paragraph\n* No linebreak\n", - "

Paragraph\n* No linebreak

\n", - - "Paragraph\n\n* Linebreak\n", - "

Paragraph

\n\n
    \n
  • Linebreak
  • \n
\n", - - "* List\n * Nested list\n", - "
    \n
  • List\n\n
      \n
    • Nested list
    • \n
  • \n
\n", - - "* List\n\n * Nested list\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list
    • \n
  • \n
\n", - - "* List\n Second line\n\n + Nested\n", - "
    \n
  • List\nSecond line

    \n\n
      \n
    • Nested
    • \n
  • \n
\n", - - "* List\n + Nested\n\n Continued\n", - "
    \n
  • List

    \n\n
      \n
    • Nested
    • \n
    \n\n

    Continued

  • \n
\n", - - "* List\n * shallow indent\n", - "
    \n
  • List\n\n
      \n
    • shallow indent
    • \n
  • \n
\n", - - "* List\n" + - " * shallow indent\n" + - " * part of second list\n" + - " * still second\n" + - " * almost there\n" + - " * third level\n", - "
    \n" + - "
  • List\n\n" + - "
      \n" + - "
    • shallow indent
    • \n" + - "
    • part of second list
    • \n" + - "
    • still second
    • \n" + - "
    • almost there\n\n" + - "
        \n" + - "
      • third level
      • \n" + - "
    • \n" + - "
  • \n" + - "
\n", - - "* List\n extra indent, same paragraph\n", - "
    \n
  • List\n extra indent, same paragraph
  • \n
\n", - - "* List\n\n code block\n", - "
    \n
  • List

    \n\n
    code block\n
  • \n
\n", - - "* List\n\n code block with spaces\n", - "
    \n
  • List

    \n\n
      code block with spaces\n
  • \n
\n", - - "* List\n\n * sublist\n\n normal text\n\n * another sublist\n", - "
    \n
  • List

    \n\n
      \n
    • sublist
    • \n
    \n\n

    normal text

    \n\n
      \n
    • another sublist
    • \n
  • \n
\n", - } - doTestsBlock(t, tests, 0) -} - -func TestOrderedList(t *testing.T) { - var tests = []string{ - "1. Hello\n", - "
    \n
  1. Hello
  2. \n
\n", - - "1. Yin\n2. Yang\n", - "
    \n
  1. Yin
  2. \n
  3. Yang
  4. \n
\n", - - "1. Ting\n2. Bong\n3. Goo\n", - "
    \n
  1. Ting
  2. \n
  3. Bong
  4. \n
  5. Goo
  6. \n
\n", - - "1. Yin\n\n2. Yang\n", - "
    \n
  1. Yin

  2. \n\n
  3. Yang

  4. \n
\n", - - "1. Ting\n\n2. Bong\n3. Goo\n", - "
    \n
  1. Ting

  2. \n\n
  3. Bong

  4. \n\n
  5. Goo

  6. \n
\n", - - "1 Hello\n", - "

1 Hello

\n", - - "1.Hello\n", - "

1.Hello

\n", - - "1. Hello \n", - "
    \n
  1. Hello
  2. \n
\n", - - "1. Hello \n Next line \n", - "
    \n
  1. Hello\nNext line
  2. \n
\n", - - "Paragraph\n1. No linebreak\n", - "

Paragraph\n1. No linebreak

\n", - - "Paragraph\n\n1. Linebreak\n", - "

Paragraph

\n\n
    \n
  1. Linebreak
  2. \n
\n", - - "1. List\n 1. Nested list\n", - "
    \n
  1. List\n\n
      \n
    1. Nested list
    2. \n
  2. \n
\n", - - "1. List\n\n 1. Nested list\n", - "
    \n
  1. List

    \n\n
      \n
    1. Nested list
    2. \n
  2. \n
\n", - - "1. List\n Second line\n\n 1. Nested\n", - "
    \n
  1. List\nSecond line

    \n\n
      \n
    1. Nested
    2. \n
  2. \n
\n", - - "1. List\n 1. Nested\n\n Continued\n", - "
    \n
  1. List

    \n\n
      \n
    1. Nested
    2. \n
    \n\n

    Continued

  2. \n
\n", - - "1. List\n 1. shallow indent\n", - "
    \n
  1. List\n\n
      \n
    1. shallow indent
    2. \n
  2. \n
\n", - - "1. List\n" + - " 1. shallow indent\n" + - " 2. part of second list\n" + - " 3. still second\n" + - " 4. almost there\n" + - " 1. third level\n", - "
    \n" + - "
  1. List\n\n" + - "
      \n" + - "
    1. shallow indent
    2. \n" + - "
    3. part of second list
    4. \n" + - "
    5. still second
    6. \n" + - "
    7. almost there\n\n" + - "
        \n" + - "
      1. third level
      2. \n" + - "
    8. \n" + - "
  2. \n" + - "
\n", - - "1. List\n extra indent, same paragraph\n", - "
    \n
  1. List\n extra indent, same paragraph
  2. \n
\n", - - "1. List\n\n code block\n", - "
    \n
  1. List

    \n\n
    code block\n
  2. \n
\n", - - "1. List\n\n code block with spaces\n", - "
    \n
  1. List

    \n\n
      code block with spaces\n
  2. \n
\n", - - "1. List\n * Mixted list\n", - "
    \n
  1. List\n\n
      \n
    • Mixted list
    • \n
  2. \n
\n", - - "1. List\n * Mixed list\n", - "
    \n
  1. List\n\n
      \n
    • Mixed list
    • \n
  2. \n
\n", - - "* Start with unordered\n 1. Ordered\n", - "
    \n
  • Start with unordered\n\n
      \n
    1. Ordered
    2. \n
  • \n
\n", - - "* Start with unordered\n 1. Ordered\n", - "
    \n
  • Start with unordered\n\n
      \n
    1. Ordered
    2. \n
  • \n
\n", - - "1. numbers\n1. are ignored\n", - "
    \n
  1. numbers
  2. \n
  3. are ignored
  4. \n
\n", - } - doTestsBlock(t, tests, 0) -} - -func TestDefinitionList(t *testing.T) { - var tests = []string{ - "Term 1\n: Definition a\n", - "
\n
Term 1
\n
Definition a
\n
\n", - - "Term 1\n: Definition a \n", - "
\n
Term 1
\n
Definition a
\n
\n", - - "Term 1\n: Definition a\n: Definition b\n", - "
\n
Term 1
\n
Definition a
\n
Definition b
\n
\n", - - "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n", - "
\n" + - "
Term 1
\n" + - "
Definition a
\n" + - "
Term 2
\n" + - "
Definition b
\n" + - "
\n", - - "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n\nTerm 3\n: Definition c\n", - "
\n" + - "
Term 1
\n" + - "
Definition a
\n" + - "
Term 2
\n" + - "
Definition b
\n" + - "
Term 3
\n" + - "
Definition c
\n" + - "
\n", - - "Term 1\n: Definition a\n: Definition b\n\nTerm 2\n: Definition c\n", - "
\n" + - "
Term 1
\n" + - "
Definition a
\n" + - "
Definition b
\n" + - "
Term 2
\n" + - "
Definition c
\n" + - "
\n", - - "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n", - "
\n" + - "
Term 1
\n" + - "

Definition a

\n" + - "
Term 2
\n" + - "

Definition b

\n" + - "
\n", - - "Term 1\n\n: Definition a\n\n: Definition b\n\nTerm 2\n\n: Definition c\n", - "
\n" + - "
Term 1
\n" + - "

Definition a

\n" + - "

Definition b

\n" + - "
Term 2
\n" + - "

Definition c

\n" + - "
\n", - - "Term 1\n: Definition a\nNext line\n", - "
\n
Term 1
\n
Definition a\nNext line
\n
\n", - - "Term 1\n: Definition a\n Next line\n", - "
\n
Term 1
\n
Definition a\nNext line
\n
\n", - - "Term 1\n: Definition a \n Next line \n", - "
\n
Term 1
\n
Definition a\nNext line
\n
\n", - - "Term 1\n: Definition a\nNext line\n\nTerm 2\n: Definition b", - "
\n" + - "
Term 1
\n" + - "
Definition a\nNext line
\n" + - "
Term 2
\n" + - "
Definition b
\n" + - "
\n", - - "Term 1\n: Definition a\n", - "
\n
Term 1
\n
Definition a
\n
\n", - - "Term 1\n:Definition a\n", - "

Term 1\n:Definition a

\n", - - "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n\nText 1", - "
\n" + - "
Term 1
\n" + - "

Definition a

\n" + - "
Term 2
\n" + - "

Definition b

\n" + - "
\n" + - "\n

Text 1

\n", - - "Term 1\n\n: Definition a\n\nText 1\n\nTerm 2\n\n: Definition b\n\nText 2", - "
\n" + - "
Term 1
\n" + - "

Definition a

\n" + - "
\n" + - "\n

Text 1

\n" + - "\n
\n" + - "
Term 2
\n" + - "

Definition b

\n" + - "
\n" + - "\n

Text 2

\n", - } - doTestsBlock(t, tests, EXTENSION_DEFINITION_LISTS) -} - -func TestPreformattedHtml(t *testing.T) { - var tests = []string{ - "
\n", - "
\n", - - "
\n
\n", - "
\n
\n", - - "
\n
\nParagraph\n", - "

\n
\nParagraph

\n", - - "
\n
\n", - "
\n
\n", - - "
\nAnything here\n
\n", - "
\nAnything here\n
\n", - - "
\n Anything here\n
\n", - "
\n Anything here\n
\n", - - "
\nAnything here\n
\n", - "
\nAnything here\n
\n", - - "
\nThis is *not* &proceessed\n
\n", - "
\nThis is *not* &proceessed\n
\n", - - "\n Something\n\n", - "

\n Something\n

\n", - - "
\n Something here\n\n", - "

\n Something here\n

\n", - - "Paragraph\n
\nHere? >&<\n
\n", - "

Paragraph\n

\nHere? >&<\n

\n", - - "Paragraph\n\n
\nHow about here? >&<\n
\n", - "

Paragraph

\n\n
\nHow about here? >&<\n
\n", - - "Paragraph\n
\nHere? >&<\n
\nAnd here?\n", - "

Paragraph\n

\nHere? >&<\n
\nAnd here?

\n", - - "Paragraph\n\n
\nHow about here? >&<\n
\nAnd here?\n", - "

Paragraph

\n\n

\nHow about here? >&<\n
\nAnd here?

\n", - - "Paragraph\n
\nHere? >&<\n
\n\nAnd here?\n", - "

Paragraph\n

\nHere? >&<\n

\n\n

And here?

\n", - - "Paragraph\n\n
\nHow about here? >&<\n
\n\nAnd here?\n", - "

Paragraph

\n\n
\nHow about here? >&<\n
\n\n

And here?

\n", - } - doTestsBlock(t, tests, 0) -} - -func TestPreformattedHtmlLax(t *testing.T) { - var tests = []string{ - "Paragraph\n
\nHere? >&<\n
\n", - "

Paragraph

\n\n
\nHere? >&<\n
\n", - - "Paragraph\n\n
\nHow about here? >&<\n
\n", - "

Paragraph

\n\n
\nHow about here? >&<\n
\n", - - "Paragraph\n
\nHere? >&<\n
\nAnd here?\n", - "

Paragraph

\n\n
\nHere? >&<\n
\n\n

And here?

\n", - - "Paragraph\n\n
\nHow about here? >&<\n
\nAnd here?\n", - "

Paragraph

\n\n
\nHow about here? >&<\n
\n\n

And here?

\n", - - "Paragraph\n
\nHere? >&<\n
\n\nAnd here?\n", - "

Paragraph

\n\n
\nHere? >&<\n
\n\n

And here?

\n", - - "Paragraph\n\n
\nHow about here? >&<\n
\n\nAnd here?\n", - "

Paragraph

\n\n
\nHow about here? >&<\n
\n\n

And here?

\n", - } - doTestsBlock(t, tests, EXTENSION_LAX_HTML_BLOCKS) -} - -func TestFencedCodeBlock(t *testing.T) { - var tests = []string{ - "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n", - "
func foo() bool {\n\treturn true;\n}\n
\n", - - "``` c\n/* special & char < > \" escaping */\n```\n", - "
/* special & char < > " escaping */\n
\n", - - "``` c\nno *inline* processing ~~of text~~\n```\n", - "
no *inline* processing ~~of text~~\n
\n", - - "```\nNo language\n```\n", - "
No language\n
\n", - - "``` {ocaml}\nlanguage in braces\n```\n", - "
language in braces\n
\n", - - "``` {ocaml} \nwith extra whitespace\n```\n", - "
with extra whitespace\n
\n", - - "```{ ocaml }\nwith extra whitespace\n```\n", - "
with extra whitespace\n
\n", - - "~ ~~ java\nWith whitespace\n~~~\n", - "

~ ~~ java\nWith whitespace\n~~~

\n", - - "~~\nonly two\n~~\n", - "

~~\nonly two\n~~

\n", - - "```` python\nextra\n````\n", - "
extra\n
\n", - - "~~~ perl\nthree to start, four to end\n~~~~\n", - "

~~~ perl\nthree to start, four to end\n~~~~

\n", - - "~~~~ perl\nfour to start, three to end\n~~~\n", - "

~~~~ perl\nfour to start, three to end\n~~~

\n", - - "~~~ bash\ntildes\n~~~\n", - "
tildes\n
\n", - - "``` lisp\nno ending\n", - "

``` lisp\nno ending

\n", - - "~~~ lisp\nend with language\n~~~ lisp\n", - "

~~~ lisp\nend with language\n~~~ lisp

\n", - - "```\nmismatched begin and end\n~~~\n", - "

```\nmismatched begin and end\n~~~

\n", - - "~~~\nmismatched begin and end\n```\n", - "

~~~\nmismatched begin and end\n```

\n", - - " ``` oz\nleading spaces\n```\n", - "
leading spaces\n
\n", - - " ``` oz\nleading spaces\n ```\n", - "
leading spaces\n
\n", - - " ``` oz\nleading spaces\n ```\n", - "
leading spaces\n
\n", - - "``` oz\nleading spaces\n ```\n", - "
leading spaces\n
\n", - - " ``` oz\nleading spaces\n ```\n", - "
``` oz\n
\n\n

leading spaces\n ```

\n", - - "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n", - "

Bla bla

\n\n
code blocks breakup paragraphs\n
\n\n

Bla Bla

\n", - - "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nAnd some text after a fenced code block", - "

Some text before a fenced code block

\n\n
code blocks breakup paragraphs\n
\n\n

And some text after a fenced code block

\n", - - "`", - "

`

\n", - - "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n\n``` oz\nmultiple code blocks work okay\n```\n\nBla Bla\n", - "

Bla bla

\n\n
code blocks breakup paragraphs\n
\n\n

Bla Bla

\n\n
multiple code blocks work okay\n
\n\n

Bla Bla

\n", - - "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nSome text in between\n``` oz\nmultiple code blocks work okay\n```\nAnd some text after a fenced code block", - "

Some text before a fenced code block

\n\n
code blocks breakup paragraphs\n
\n\n

Some text in between

\n\n
multiple code blocks work okay\n
\n\n

And some text after a fenced code block

\n", - } - doTestsBlock(t, tests, EXTENSION_FENCED_CODE) -} - -func TestTable(t *testing.T) { - var tests = []string{ - "a | b\n---|---\nc | d\n", - "\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n
ab
cd
\n", - - "a | b\n---|--\nc | d\n", - "

a | b\n---|--\nc | d

\n", - - "|a|b|c|d|\n|----|----|----|---|\n|e|f|g|h|\n", - "\n\n\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n\n\n
abcd
efgh
\n", - - "*a*|__b__|[c](C)|d\n---|---|---|---\ne|f|g|h\n", - "\n\n\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n\n\n
abcd
efgh
\n", - - "a|b|c\n---|---|---\nd|e|f\ng|h\ni|j|k|l|m\nn|o|p\n", - "\n\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n" + - "\n\n\n\n\n\n" + - "\n\n\n\n\n\n
abc
def
gh
ijk
nop
\n", - - "a|b|c\n---|---|---\n*d*|__e__|f\n", - "\n\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n\n
abc
def
\n", - - "a|b|c|d\n:--|--:|:-:|---\ne|f|g|h\n", - "\n\n\n\n\n" + - "\n\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n\n
abcd
efgh
\n", - - "a|b|c\n---|---|---\n", - "\n\n\n\n\n\n\n\n\n\n\n
abc
\n", - - "a| b|c | d | e\n---|---|---|---|---\nf| g|h | i |j\n", - "\n\n\n\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n\n\n\n
abcde
fghij
\n", - - "a|b\\|c|d\n---|---|---\nf|g\\|h|i\n", - "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
ab|cd
fg|hi
\n", - } - doTestsBlock(t, tests, EXTENSION_TABLES) -} - -func TestUnorderedListWith_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) { - var tests = []string{ - "* Hello\n", - "
    \n
  • Hello
  • \n
\n", - - "* Yin\n* Yang\n", - "
    \n
  • Yin
  • \n
  • Yang
  • \n
\n", - - "* Ting\n* Bong\n* Goo\n", - "
    \n
  • Ting
  • \n
  • Bong
  • \n
  • Goo
  • \n
\n", - - "* Yin\n\n* Yang\n", - "
    \n
  • Yin

  • \n\n
  • Yang

  • \n
\n", - - "* Ting\n\n* Bong\n* Goo\n", - "
    \n
  • Ting

  • \n\n
  • Bong

  • \n\n
  • Goo

  • \n
\n", - - "+ Hello\n", - "
    \n
  • Hello
  • \n
\n", - - "+ Yin\n+ Yang\n", - "
    \n
  • Yin
  • \n
  • Yang
  • \n
\n", - - "+ Ting\n+ Bong\n+ Goo\n", - "
    \n
  • Ting
  • \n
  • Bong
  • \n
  • Goo
  • \n
\n", - - "+ Yin\n\n+ Yang\n", - "
    \n
  • Yin

  • \n\n
  • Yang

  • \n
\n", - - "+ Ting\n\n+ Bong\n+ Goo\n", - "
    \n
  • Ting

  • \n\n
  • Bong

  • \n\n
  • Goo

  • \n
\n", - - "- Hello\n", - "
    \n
  • Hello
  • \n
\n", - - "- Yin\n- Yang\n", - "
    \n
  • Yin
  • \n
  • Yang
  • \n
\n", - - "- Ting\n- Bong\n- Goo\n", - "
    \n
  • Ting
  • \n
  • Bong
  • \n
  • Goo
  • \n
\n", - - "- Yin\n\n- Yang\n", - "
    \n
  • Yin

  • \n\n
  • Yang

  • \n
\n", - - "- Ting\n\n- Bong\n- Goo\n", - "
    \n
  • Ting

  • \n\n
  • Bong

  • \n\n
  • Goo

  • \n
\n", - - "*Hello\n", - "

*Hello

\n", - - "* Hello \n", - "
    \n
  • Hello
  • \n
\n", - - "* Hello \n Next line \n", - "
    \n
  • Hello\nNext line
  • \n
\n", - - "Paragraph\n* No linebreak\n", - "

Paragraph

\n\n
    \n
  • No linebreak
  • \n
\n", - - "Paragraph\n\n* Linebreak\n", - "

Paragraph

\n\n
    \n
  • Linebreak
  • \n
\n", - - "* List\n * Nested list\n", - "
    \n
  • List\n\n
      \n
    • Nested list
    • \n
  • \n
\n", - - "* List\n\n * Nested list\n", - "
    \n
  • List

    \n\n
      \n
    • Nested list
    • \n
  • \n
\n", - - "* List\n Second line\n\n + Nested\n", - "
    \n
  • List\nSecond line

    \n\n
      \n
    • Nested
    • \n
  • \n
\n", - - "* List\n + Nested\n\n Continued\n", - "
    \n
  • List

    \n\n
      \n
    • Nested
    • \n
    \n\n

    Continued

  • \n
\n", - - "* List\n * shallow indent\n", - "
    \n
  • List\n\n
      \n
    • shallow indent
    • \n
  • \n
\n", - - "* List\n" + - " * shallow indent\n" + - " * part of second list\n" + - " * still second\n" + - " * almost there\n" + - " * third level\n", - "
    \n" + - "
  • List\n\n" + - "
      \n" + - "
    • shallow indent
    • \n" + - "
    • part of second list
    • \n" + - "
    • still second
    • \n" + - "
    • almost there\n\n" + - "
        \n" + - "
      • third level
      • \n" + - "
    • \n" + - "
  • \n" + - "
\n", - - "* List\n extra indent, same paragraph\n", - "
    \n
  • List\n extra indent, same paragraph
  • \n
\n", - - "* List\n\n code block\n", - "
    \n
  • List

    \n\n
    code block\n
  • \n
\n", - - "* List\n\n code block with spaces\n", - "
    \n
  • List

    \n\n
      code block with spaces\n
  • \n
\n", - - "* List\n\n * sublist\n\n normal text\n\n * another sublist\n", - "
    \n
  • List

    \n\n
      \n
    • sublist
    • \n
    \n\n

    normal text

    \n\n
      \n
    • another sublist
    • \n
  • \n
\n", - } - doTestsBlock(t, tests, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK) -} - -func TestOrderedList_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) { - var tests = []string{ - "1. Hello\n", - "
    \n
  1. Hello
  2. \n
\n", - - "1. Yin\n2. Yang\n", - "
    \n
  1. Yin
  2. \n
  3. Yang
  4. \n
\n", - - "1. Ting\n2. Bong\n3. Goo\n", - "
    \n
  1. Ting
  2. \n
  3. Bong
  4. \n
  5. Goo
  6. \n
\n", - - "1. Yin\n\n2. Yang\n", - "
    \n
  1. Yin

  2. \n\n
  3. Yang

  4. \n
\n", - - "1. Ting\n\n2. Bong\n3. Goo\n", - "
    \n
  1. Ting

  2. \n\n
  3. Bong

  4. \n\n
  5. Goo

  6. \n
\n", - - "1 Hello\n", - "

1 Hello

\n", - - "1.Hello\n", - "

1.Hello

\n", - - "1. Hello \n", - "
    \n
  1. Hello
  2. \n
\n", - - "1. Hello \n Next line \n", - "
    \n
  1. Hello\nNext line
  2. \n
\n", - - "Paragraph\n1. No linebreak\n", - "

Paragraph

\n\n
    \n
  1. No linebreak
  2. \n
\n", - - "Paragraph\n\n1. Linebreak\n", - "

Paragraph

\n\n
    \n
  1. Linebreak
  2. \n
\n", - - "1. List\n 1. Nested list\n", - "
    \n
  1. List\n\n
      \n
    1. Nested list
    2. \n
  2. \n
\n", - - "1. List\n\n 1. Nested list\n", - "
    \n
  1. List

    \n\n
      \n
    1. Nested list
    2. \n
  2. \n
\n", - - "1. List\n Second line\n\n 1. Nested\n", - "
    \n
  1. List\nSecond line

    \n\n
      \n
    1. Nested
    2. \n
  2. \n
\n", - - "1. List\n 1. Nested\n\n Continued\n", - "
    \n
  1. List

    \n\n
      \n
    1. Nested
    2. \n
    \n\n

    Continued

  2. \n
\n", - - "1. List\n 1. shallow indent\n", - "
    \n
  1. List\n\n
      \n
    1. shallow indent
    2. \n
  2. \n
\n", - - "1. List\n" + - " 1. shallow indent\n" + - " 2. part of second list\n" + - " 3. still second\n" + - " 4. almost there\n" + - " 1. third level\n", - "
    \n" + - "
  1. List\n\n" + - "
      \n" + - "
    1. shallow indent
    2. \n" + - "
    3. part of second list
    4. \n" + - "
    5. still second
    6. \n" + - "
    7. almost there\n\n" + - "
        \n" + - "
      1. third level
      2. \n" + - "
    8. \n" + - "
  2. \n" + - "
\n", - - "1. List\n extra indent, same paragraph\n", - "
    \n
  1. List\n extra indent, same paragraph
  2. \n
\n", - - "1. List\n\n code block\n", - "
    \n
  1. List

    \n\n
    code block\n
  2. \n
\n", - - "1. List\n\n code block with spaces\n", - "
    \n
  1. List

    \n\n
      code block with spaces\n
  2. \n
\n", - - "1. List\n * Mixted list\n", - "
    \n
  1. List\n\n
      \n
    • Mixted list
    • \n
  2. \n
\n", - - "1. List\n * Mixed list\n", - "
    \n
  1. List\n\n
      \n
    • Mixed list
    • \n
  2. \n
\n", - - "* Start with unordered\n 1. Ordered\n", - "
    \n
  • Start with unordered\n\n
      \n
    1. Ordered
    2. \n
  • \n
\n", - - "* Start with unordered\n 1. Ordered\n", - "
    \n
  • Start with unordered\n\n
      \n
    1. Ordered
    2. \n
  • \n
\n", - - "1. numbers\n1. are ignored\n", - "
    \n
  1. numbers
  2. \n
  3. are ignored
  4. \n
\n", - } - doTestsBlock(t, tests, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK) -} - -func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) { - var tests = []string{ - "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n", - "
func foo() bool {\n\treturn true;\n}\n
\n", - - "``` c\n/* special & char < > \" escaping */\n```\n", - "
/* special & char < > " escaping */\n
\n", - - "``` c\nno *inline* processing ~~of text~~\n```\n", - "
no *inline* processing ~~of text~~\n
\n", - - "```\nNo language\n```\n", - "
No language\n
\n", - - "``` {ocaml}\nlanguage in braces\n```\n", - "
language in braces\n
\n", - - "``` {ocaml} \nwith extra whitespace\n```\n", - "
with extra whitespace\n
\n", - - "```{ ocaml }\nwith extra whitespace\n```\n", - "
with extra whitespace\n
\n", - - "~ ~~ java\nWith whitespace\n~~~\n", - "

~ ~~ java\nWith whitespace\n~~~

\n", - - "~~\nonly two\n~~\n", - "

~~\nonly two\n~~

\n", - - "```` python\nextra\n````\n", - "
extra\n
\n", - - "~~~ perl\nthree to start, four to end\n~~~~\n", - "

~~~ perl\nthree to start, four to end\n~~~~

\n", - - "~~~~ perl\nfour to start, three to end\n~~~\n", - "

~~~~ perl\nfour to start, three to end\n~~~

\n", - - "~~~ bash\ntildes\n~~~\n", - "
tildes\n
\n", - - "``` lisp\nno ending\n", - "

``` lisp\nno ending

\n", - - "~~~ lisp\nend with language\n~~~ lisp\n", - "

~~~ lisp\nend with language\n~~~ lisp

\n", - - "```\nmismatched begin and end\n~~~\n", - "

```\nmismatched begin and end\n~~~

\n", - - "~~~\nmismatched begin and end\n```\n", - "

~~~\nmismatched begin and end\n```

\n", - - " ``` oz\nleading spaces\n```\n", - "
leading spaces\n
\n", - - " ``` oz\nleading spaces\n ```\n", - "
leading spaces\n
\n", - - " ``` oz\nleading spaces\n ```\n", - "
leading spaces\n
\n", - - "``` oz\nleading spaces\n ```\n", - "
leading spaces\n
\n", - - " ``` oz\nleading spaces\n ```\n", - "
``` oz\n
\n\n

leading spaces

\n\n
```\n
\n", - } - doTestsBlock(t, tests, EXTENSION_FENCED_CODE|EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK) -} - -func TestTitleBlock_EXTENSION_TITLEBLOCK(t *testing.T) { - var tests = []string{ - "% Some title\n" + - "% Another title line\n" + - "% Yep, more here too\n", - "

" + - "Some title\n" + - "Another title line\n" + - "Yep, more here too\n" + - "

", - } - - doTestsBlock(t, tests, EXTENSION_TITLEBLOCK) - -} diff --git a/vendor/src/github.com/russross/blackfriday/html.go b/vendor/src/github.com/russross/blackfriday/html.go deleted file mode 100644 index 264aae5..0000000 --- a/vendor/src/github.com/russross/blackfriday/html.go +++ /dev/null @@ -1,948 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// -// HTML rendering backend -// -// - -package blackfriday - -import ( - "bytes" - "fmt" - "regexp" - "strconv" - "strings" -) - -// Html renderer configuration options. -const ( - HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks - HTML_SKIP_STYLE // skip embedded