Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the shortcode parser to the new pageparser package #5331

Merged
merged 16 commits into from
Oct 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 86 additions & 33 deletions commands/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,27 @@
package commands

import (
"bytes"
"fmt"
"io"
"strings"
"time"

"github.com/gohugoio/hugo/hugofs"

"github.com/gohugoio/hugo/helpers"

"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/parser/metadecoders"
"github.com/gohugoio/hugo/parser/pageparser"

src "github.com/gohugoio/hugo/source"
"github.com/pkg/errors"

"github.com/gohugoio/hugo/hugolib"

"path/filepath"

"github.com/gohugoio/hugo/parser"
"github.com/spf13/cast"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -60,7 +70,7 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.`,
Long: `toJSON converts all front matter in the content directory
to use JSON for the front matter.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cc.convertContents(rune([]byte(parser.JSONLead)[0]))
return cc.convertContents(metadecoders.JSON)
},
},
&cobra.Command{
Expand All @@ -69,7 +79,7 @@ to use JSON for the front matter.`,
Long: `toTOML converts all front matter in the content directory
to use TOML for the front matter.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cc.convertContents(rune([]byte(parser.TOMLLead)[0]))
return cc.convertContents(metadecoders.TOML)
},
},
&cobra.Command{
Expand All @@ -78,7 +88,7 @@ to use TOML for the front matter.`,
Long: `toYAML converts all front matter in the content directory
to use YAML for the front matter.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cc.convertContents(rune([]byte(parser.YAMLLead)[0]))
return cc.convertContents(metadecoders.YAML)
},
},
)
Expand All @@ -91,7 +101,7 @@ to use YAML for the front matter.`,
return cc
}

func (cc *convertCmd) convertContents(mark rune) error {
func (cc *convertCmd) convertContents(format metadecoders.Format) error {
if cc.outputDir == "" && !cc.unsafe {
return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path")
}
Expand All @@ -114,17 +124,17 @@ func (cc *convertCmd) convertContents(mark rune) error {

site.Log.FEEDBACK.Println("processing", len(site.AllPages), "content files")
for _, p := range site.AllPages {
if err := cc.convertAndSavePage(p, site, mark); err != nil {
if err := cc.convertAndSavePage(p, site, format); err != nil {
return err
}
}
return nil
}

func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, mark rune) error {
func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, targetFormat metadecoders.Format) error {
// The resources are not in .Site.AllPages.
for _, r := range p.Resources.ByType("page") {
if err := cc.convertAndSavePage(r.(*hugolib.Page), site, mark); err != nil {
if err := cc.convertAndSavePage(r.(*hugolib.Page), site, targetFormat); err != nil {
return err
}
}
Expand All @@ -134,61 +144,104 @@ func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, ma
return nil
}

errMsg := fmt.Errorf("Error processing file %q", p.Path())

site.Log.INFO.Println("Attempting to convert", p.LogicalName())
newPage, err := site.NewPage(p.LogicalName())
if err != nil {
return err
}

f, _ := p.File.(src.ReadableFile)
file, err := f.Open()
if err != nil {
site.Log.ERROR.Println("Error reading file:", p.Path())
site.Log.ERROR.Println(errMsg)
file.Close()
return nil
}

psr, err := parser.ReadFrom(file)
pf, err := parseContentFile(file)
if err != nil {
site.Log.ERROR.Println("Error processing file:", p.Path())
site.Log.ERROR.Println(errMsg)
file.Close()
return err
}

file.Close()

metadata, err := psr.Metadata()
if err != nil {
site.Log.ERROR.Println("Error processing file:", p.Path())
return err
}

// better handling of dates in formats that don't have support for them
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") || mark == parser.FormatToLeadRune("toml") {
newMetadata := cast.ToStringMap(metadata)
for k, v := range newMetadata {
if pf.frontMatterFormat == metadecoders.JSON || pf.frontMatterFormat == metadecoders.YAML || pf.frontMatterFormat == metadecoders.TOML {
for k, v := range pf.frontMatter {
switch vv := v.(type) {
case time.Time:
newMetadata[k] = vv.Format(time.RFC3339)
pf.frontMatter[k] = vv.Format(time.RFC3339)
}
}
metadata = newMetadata
}

newPage.SetSourceContent(psr.Content())
if err = newPage.SetSourceMetaData(metadata, mark); err != nil {
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/gohugoio/hugo/issues/2458", newPage.FullFilePath(), err)
return nil
var newContent bytes.Buffer
err = parser.InterfaceToFrontMatter(pf.frontMatter, targetFormat, &newContent)
if err != nil {
site.Log.ERROR.Println(errMsg)
return err
}

newContent.Write(pf.content)

newFilename := p.Filename()

if cc.outputDir != "" {
newFilename = filepath.Join(cc.outputDir, p.Dir(), newPage.LogicalName())
contentDir := strings.TrimSuffix(newFilename, p.Path())
contentDir = filepath.Base(contentDir)

newFilename = filepath.Join(cc.outputDir, contentDir, p.Path())
}

if err = newPage.SaveSourceAs(newFilename); err != nil {
fs := hugofs.Os
if err := helpers.WriteToDisk(newFilename, &newContent, fs); err != nil {
return errors.Wrapf(err, "Failed to save file %q:", newFilename)
}

return nil
}

type parsedFile struct {
frontMatterFormat metadecoders.Format
frontMatterSource []byte
frontMatter map[string]interface{}

// Everything after Front Matter
content []byte
}

func parseContentFile(r io.Reader) (parsedFile, error) {
var pf parsedFile

psr, err := pageparser.Parse(r)
if err != nil {
return pf, err
}

iter := psr.Iterator()

walkFn := func(item pageparser.Item) bool {
if pf.frontMatterSource != nil {
// The rest is content.
pf.content = psr.Input()[item.Pos:]
// Done
return false
} else if item.IsFrontMatter() {
pf.frontMatterFormat = metadecoders.FormatFromFrontMatterType(item.Type)
pf.frontMatterSource = item.Val
}
return true

}

iter.PeekWalk(walkFn)

metadata, err := metadecoders.UnmarshalToMap(pf.frontMatterSource, pf.frontMatterFormat)
if err != nil {
return pf, err
}
pf.frontMatter = metadata

return pf, nil

}
11 changes: 7 additions & 4 deletions commands/hugo.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import (

"github.com/gohugoio/hugo/config"

"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/parser/metadecoders"
flag "github.com/spf13/pflag"

"github.com/fsnotify/fsnotify"
Expand Down Expand Up @@ -620,7 +620,9 @@ func (c *commandeer) buildSites() (err error) {

func (c *commandeer) handleBuildErr(err error, msg string) {
c.buildErr = err
c.logger.ERROR.Printf("%s: %s", msg, err)

c.logger.ERROR.Print(msg + ":\n\n")
c.logger.ERROR.Println(helpers.FirstUpper(err.Error()))
if !c.h.quiet && c.h.verbose {
herrors.PrintStackTrace(err)
}
Expand Down Expand Up @@ -660,9 +662,10 @@ func (c *commandeer) fullRebuild() {
c.commandeerHugoState = &commandeerHugoState{}
err := c.loadConfig(true, true)
if err != nil {
c.logger.ERROR.Println("Failed to reload config:", err)
// Set the processing on pause until the state is recovered.
c.paused = true
c.handleBuildErr(err, "Failed to reload config")

} else {
c.paused = false
}
Expand Down Expand Up @@ -1017,7 +1020,7 @@ func (c *commandeer) isThemeVsHugoVersionMismatch(fs afero.Fs) (dir string, mism

b, err := afero.ReadFile(fs, path)

tomlMeta, err := parser.HandleTOMLMetaData(b)
tomlMeta, err := metadecoders.UnmarshalToMap(b, metadecoders.TOML)

if err != nil {
continue
Expand Down
38 changes: 13 additions & 25 deletions commands/import_jekyll.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package commands
import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
Expand All @@ -25,6 +26,8 @@ import (
"strings"
"time"

"github.com/gohugoio/hugo/parser/metadecoders"

"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/hugolib"
Expand Down Expand Up @@ -253,7 +256,7 @@ func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]
return nil
}

c, err := parser.HandleYAMLMetaData(b)
c, err := metadecoders.UnmarshalToMap(b, metadecoders.YAML)

if err != nil {
return nil
Expand All @@ -262,7 +265,7 @@ func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]
return c
}

func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind string, jekyllConfig map[string]interface{}) (err error) {
func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind metadecoders.Format, jekyllConfig map[string]interface{}) (err error) {
title := "My New Hugo Site"
baseURL := "http://example.org/"

Expand All @@ -288,15 +291,14 @@ func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind stri
"languageCode": "en-us",
"disablePathToLower": true,
}
kind = parser.FormatSanitize(kind)

var buf bytes.Buffer
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
err = parser.InterfaceToConfig(in, kind, &buf)
if err != nil {
return err
}

return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs)
return helpers.WriteToDisk(filepath.Join(inpath, "config."+string(kind)), &buf, fs)
}

func copyFile(source string, dest string) error {
Expand Down Expand Up @@ -445,39 +447,25 @@ func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft b
return err
}

psr, err := parser.ReadFrom(bytes.NewReader(contentBytes))
pf, err := parseContentFile(bytes.NewReader(contentBytes))
if err != nil {
jww.ERROR.Println("Parse file error:", path)
return err
}

metadata, err := psr.Metadata()
if err != nil {
jww.ERROR.Println("Processing file error:", path)
return err
}

newmetadata, err := convertJekyllMetaData(metadata, postName, postDate, draft)
newmetadata, err := convertJekyllMetaData(pf.frontMatter, postName, postDate, draft)
if err != nil {
jww.ERROR.Println("Convert metadata error:", path)
return err
}

jww.TRACE.Println(newmetadata)
content := convertJekyllContent(newmetadata, string(psr.Content()))
content := convertJekyllContent(newmetadata, string(pf.content))

page, err := s.NewPage(filename)
if err != nil {
jww.ERROR.Println("New page error", filename)
return err
fs := hugofs.Os
if err := helpers.WriteToDisk(targetFile, strings.NewReader(content), fs); err != nil {
return fmt.Errorf("Failed to save file %q:", filename)
}

page.SetSourceContent([]byte(content))
page.SetSourceMetaData(newmetadata, parser.FormatToLeadRune("yaml"))
page.SaveSourceAs(targetFile)

jww.TRACE.Println("Target file:", targetFile)

return nil
}

Expand Down
5 changes: 3 additions & 2 deletions commands/new_site.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"path/filepath"
"strings"

"github.com/gohugoio/hugo/parser/metadecoders"

_errors "github.com/pkg/errors"

"github.com/gohugoio/hugo/create"
Expand Down Expand Up @@ -131,10 +133,9 @@ func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) {
"title": "My New Hugo Site",
"languageCode": "en-us",
}
kind = parser.FormatSanitize(kind)

var buf bytes.Buffer
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
err = parser.InterfaceToConfig(in, metadecoders.FormatFromString(kind), &buf)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion commands/server_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var buildErrorTemplate = `<!doctype html>
<main>
{{ highlight .Error "apl" "noclasses=true,style=monokai" }}
{{ with .File }}
{{ $params := printf "noclasses=true,style=monokai,linenos=table,hl_lines=%d,linenostart=%d" (add .Pos 1) .LineNumber }}
{{ $params := printf "noclasses=true,style=monokai,linenos=table,hl_lines=%d,linenostart=%d" (add .Pos 1) (sub .LineNumber .Pos) }}
{{ $lexer := .ChromaLexer | default "go-html-template" }}
{{ highlight (delimit .Lines "\n") $lexer $params }}
{{ end }}
Expand Down
Loading