func importFromJekyll(cmd *cobra.Command, args []string) error { jww.SetLogThreshold(jww.LevelTrace) jww.SetStdoutThreshold(jww.LevelWarn) if len(args) < 2 { return newUserError(`Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.") } jekyllRoot, err := filepath.Abs(filepath.Clean(args[0])) if err != nil { return newUserError("Path error:", args[0]) } targetDir, err := filepath.Abs(filepath.Clean(args[1])) if err != nil { return newUserError("Path error:", args[1]) } jww.INFO.Println("Import Jekyll from:", jekyllRoot, "to:", targetDir) if strings.HasPrefix(filepath.Dir(targetDir), jekyllRoot) { return newUserError("Target path should not be inside the Jekyll root, aborting.") } forceImport, _ := cmd.Flags().GetBool("force") if err := createSiteFromJekyll(jekyllRoot, targetDir, forceImport); err != nil { return newUserError(err) } fmt.Println("Importing...") fileCount := 0 callback := func(path string, fi os.FileInfo, err error) error { if err != nil { return err } if fi.IsDir() { return nil } relPath, err := filepath.Rel(jekyllRoot, path) if err != nil { return newUserError("Get rel path error:", path) } relPath = filepath.ToSlash(relPath) draft := false switch { case strings.HasPrefix(relPath, "_posts/"): relPath = "content/post" + relPath[len("_posts"):] case strings.HasPrefix(relPath, "_drafts/"): relPath = "content/draft" + relPath[len("_drafts"):] draft = true default: return nil } fileCount++ return convertJekyllPost(path, relPath, targetDir, draft) } err = helpers.SymbolicWalk(hugofs.Os(), jekyllRoot, callback) if err != nil { return err } fmt.Println("Congratulations!", fileCount, "post(s) imported!") fmt.Println("Now, start Hugo by yourself:\n" + "$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove") fmt.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove") return nil }
Use: "man", Short: "Generate man pages for the Hugo CLI", Long: `This command automatically generates up-to-date man pages of Hugo's command-line interface. By default, it creates the man page files in the "man" directory under the current directory.`, RunE: func(cmd *cobra.Command, args []string) error { header := &doc.GenManHeader{ Section: "1", Manual: "Hugo Manual", Source: fmt.Sprintf("Hugo %s", helpers.HugoVersion()), } if !strings.HasSuffix(genmandir, helpers.FilePathSeparator) { genmandir += helpers.FilePathSeparator } if found, _ := helpers.Exists(genmandir, hugofs.Os()); !found { jww.FEEDBACK.Println("Directory", genmandir, "does not exist, creating...") hugofs.Os().MkdirAll(genmandir, 0777) } cmd.Root().DisableAutoGenTag = true jww.FEEDBACK.Println("Generating Hugo man pages in", genmandir, "...") doc.GenManTree(cmd.Root(), header, genmandir) jww.FEEDBACK.Println("Done.") return nil }, } func init() {
// Highlight takes some code and returns highlighted code. func Highlight(code, lang, optsStr string) string { if !HasPygments() { jww.WARN.Println("Highlighting requires Pygments to be installed and in the path") return code } options, err := parsePygmentsOpts(optsStr) if err != nil { jww.ERROR.Print(err.Error()) return code } // Try to read from cache first hash := sha1.New() io.WriteString(hash, code) io.WriteString(hash, lang) io.WriteString(hash, options) fs := hugofs.Os() ignoreCache := viper.GetBool("IgnoreCache") cacheDir := viper.GetString("CacheDir") var cachefile string if !ignoreCache && cacheDir != "" { cachefile = filepath.Join(cacheDir, fmt.Sprintf("pygments-%x", hash.Sum(nil))) exists, err := Exists(cachefile, fs) if err != nil { jww.ERROR.Print(err.Error()) return code } if exists { f, err := fs.Open(cachefile) if err != nil { jww.ERROR.Print(err.Error()) return code } s, err := ioutil.ReadAll(f) if err != nil { jww.ERROR.Print(err.Error()) return code } return string(s) } } // No cache file, render and cache it var out bytes.Buffer var stderr bytes.Buffer var langOpt string if lang == "" { langOpt = "-g" // Try guessing the language } else { langOpt = "-l" + lang } cmd := exec.Command(pygmentsBin, langOpt, "-fhtml", "-O", options) cmd.Stdin = strings.NewReader(code) cmd.Stdout = &out cmd.Stderr = &stderr if err := cmd.Run(); err != nil { jww.ERROR.Print(stderr.String()) return code } str := out.String() // inject code tag into Pygments output if lang != "" && strings.Contains(str, "<pre>") { codeTag := fmt.Sprintf(`<pre><code class="language-%s" data-lang="%s">`, lang, lang) str = strings.Replace(str, "<pre>", codeTag, 1) str = strings.Replace(str, "</pre>", "</code></pre>", 1) } if !ignoreCache && cachefile != "" { // Write cache file if err := WriteToDisk(cachefile, strings.NewReader(str), fs); err != nil { jww.ERROR.Print(stderr.String()) } } return str }
func (t *GoHTMLTemplate) loadTemplates(absPath string, prefix string) { walker := func(path string, fi os.FileInfo, err error) error { if err != nil { return nil } if fi.Mode()&os.ModeSymlink == os.ModeSymlink { link, err := filepath.EvalSymlinks(absPath) if err != nil { jww.ERROR.Printf("Cannot read symbolic link '%s', error was: %s", absPath, err) return nil } linkfi, err := os.Stat(link) if err != nil { jww.ERROR.Printf("Cannot stat '%s', error was: %s", link, err) return nil } if !linkfi.Mode().IsRegular() { jww.ERROR.Printf("Symbolic links for directories not supported, skipping '%s'", absPath) } return nil } if !fi.IsDir() { if isDotFile(path) || isBackupFile(path) || isBaseTemplate(path) { return nil } tplName := t.GenerateTemplateNameFrom(absPath, path) if prefix != "" { tplName = strings.Trim(prefix, "/") + "/" + tplName } var baseTemplatePath string // Ace and Go templates may have both a base and inner template. pathDir := filepath.Dir(path) if filepath.Ext(path) != ".amber" && !strings.HasSuffix(pathDir, "partials") && !strings.HasSuffix(pathDir, "shortcodes") { innerMarkers := goTemplateInnerMarkers baseFileName := fmt.Sprintf("%s.html", baseFileBase) if filepath.Ext(path) == ".ace" { innerMarkers = aceTemplateInnerMarkers baseFileName = fmt.Sprintf("%s.ace", baseFileBase) } // This may be a view that shouldn't have base template // Have to look inside it to make sure needsBase, err := helpers.FileContainsAny(path, innerMarkers, hugofs.Os()) if err != nil { return err } if needsBase { // Look for base template in the follwing order: // 1. <current-path>/<template-name>-baseof.<suffix>, e.g. list-baseof.<suffix>. // 2. <current-path>/baseof.<suffix> // 3. _default/<template-name>-baseof.<suffix>, e.g. list-baseof.<suffix>. // 4. _default/baseof.<suffix> // 5. <themedir>/layouts/_default/<template-name>-baseof.<suffix> // 6. <themedir>/layouts/_default/baseof.<suffix> currBaseFilename := fmt.Sprintf("%s-%s", helpers.Filename(path), baseFileName) templateDir := filepath.Dir(path) themeDir := helpers.GetThemeDir() pathsToCheck := []string{ filepath.Join(templateDir, currBaseFilename), filepath.Join(templateDir, baseFileName), filepath.Join(absPath, "_default", currBaseFilename), filepath.Join(absPath, "_default", baseFileName), filepath.Join(themeDir, "layouts", "_default", currBaseFilename), filepath.Join(themeDir, "layouts", "_default", baseFileName), } for _, pathToCheck := range pathsToCheck { if ok, err := helpers.Exists(pathToCheck, hugofs.Os()); err == nil && ok { baseTemplatePath = pathToCheck break } } } } t.AddTemplateFile(tplName, baseTemplatePath, path) } return nil } filepath.Walk(absPath, walker) }