From d78ecf4682d55fcb5b8a93755f9c5c5af0c8c8c3 Mon Sep 17 00:00:00 2001 From: Sebastian Frank Date: Thu, 28 Feb 2019 12:13:28 +0100 Subject: [PATCH] reorganizes processing code --- config/global.go | 5 + helper/assets.go | 27 +++ helper/content.go | 342 ++++++++++++++++++++++++++++++++ helper/navigation.go | 94 +++++++++ main.go | 450 +------------------------------------------ 5 files changed, 475 insertions(+), 443 deletions(-) create mode 100644 helper/assets.go create mode 100644 helper/content.go create mode 100644 helper/navigation.go diff --git a/config/global.go b/config/global.go index 2a40a94..982f5a1 100644 --- a/config/global.go +++ b/config/global.go @@ -25,6 +25,11 @@ type GlobalConfig struct { OtherFiles struct { Action string `yaml:"Action"` } `yaml:"OtherFiles"` + + Directories struct { + Input string + Output string + } } var Config = new(GlobalConfig) diff --git a/helper/assets.go b/helper/assets.go new file mode 100644 index 0000000..e4220c8 --- /dev/null +++ b/helper/assets.go @@ -0,0 +1,27 @@ +package helper + +import ( + "strings" + + "gitbase.de/apairon/mark2web/config" + cpy "github.com/otiai10/copy" +) + +func ProcessAssets() { + switch config.Config.Assets.Action { + case "copy": + from := config.Config.Assets.FromPath + to := config.Config.Assets.ToPath + if !strings.HasPrefix(from, "/") { + from = config.Config.Directories.Input + "/" + from + } + if !strings.HasPrefix(to, "/") { + to = config.Config.Directories.Output + "/" + to + } + Log.Noticef("copying assets from '%s' to '%s'", from, to) + err := cpy.Copy(from, to) + if err != nil { + Log.Panicf("could not copy assets from '%s' to '%s': %s", from, to, err) + } + } +} diff --git a/helper/content.go b/helper/content.go new file mode 100644 index 0000000..fc6c394 --- /dev/null +++ b/helper/content.go @@ -0,0 +1,342 @@ +package helper + +import ( + "bytes" + "io/ioutil" + "os" + "path" + "regexp" + "strings" + + "gitbase.de/apairon/mark2web/config" + "github.com/Depado/bfchroma" + "github.com/davecgh/go-spew/spew" + "github.com/extemporalgenome/slug" + "github.com/flosch/pongo2" + cpy "github.com/otiai10/copy" + "gopkg.in/russross/blackfriday.v2" + "gopkg.in/yaml.v2" +) + +func fillNodeConfig(node *config.PathConfigTree, inBase, outBase, dir string, conf *config.PathConfig) { + inPath := inBase + if dir != "" { + inPath += "/" + dir + } + + Log.Infof("reading input directory: %s", inPath) + + node.InputPath = inPath + + // read config + newConfig := new(config.PathConfig) + Log.Debug("looking for config.yml ...") + configFile := inPath + "/config.yml" + if _, err := os.Stat(configFile); os.IsNotExist(err) { + Log.Debug("no config.yml found in this directory, using upper configs") + config.Merge(newConfig, conf) + // remove this + newConfig.This = config.ThisPathConfig{} + } else { + Log.Debug("reading config...") + data, err := ioutil.ReadFile(configFile) + if err != nil { + Log.Panicf("could not read file '%s': %s", configFile, err) + } + err = yaml.Unmarshal(data, newConfig) + if err != nil { + Log.Panicf("could not parse YAML file '%s': %s", configFile, err) + } + + Log.Debug("merging config with upper config") + oldThis := newConfig.This + config.Merge(newConfig, conf) + newConfig.This = oldThis + + Log.Debug(spew.Sdump(newConfig)) + } + + node.Config = newConfig + + // calc outDir + stripedDir := dir + var regexStr *string + if newConfig.Path != nil { + regexStr = newConfig.Path.Strip + } + if regexStr != nil && *regexStr != "" { + if regex, err := regexp.Compile(*regexStr); err != nil { + Log.Panicf("error compiling path.strip regex '%s' from '%s': %s", *regexStr, inBase+"/"+dir, err) + } else { + stripedDir = regex.ReplaceAllString(stripedDir, "$1") + } + } + + if node.Config.This.Navname == nil { + navname := strings.Replace(stripedDir, "_", " ", -1) + node.Config.This.Navname = &navname + } + + stripedDir = slug.Slug(stripedDir) + outPath := outBase + "/" + stripedDir + outPath = path.Clean(outPath) + + Log.Infof("calculated output directory: %s", outPath) + node.OutputPath = outPath + +} + +func ReadContentDir(inBase string, outBase string, dir string, conf *config.PathConfig, tree *config.PathConfigTree) { + fillNodeConfig(tree, inBase, outBase, dir, conf) + + files, err := ioutil.ReadDir(tree.InputPath) + if err != nil { + Log.Panic(err) + } + + // first only files + for _, f := range files { + p := tree.InputPath + "/" + f.Name() + if !f.IsDir() && f.Name() != "config.yml" { + switch path.Ext(f.Name()) { + case ".md": + Log.Debugf(".MD %s", p) + if tree.InputFiles == nil { + tree.InputFiles = make([]string, 0) + } + tree.InputFiles = append(tree.InputFiles, f.Name()) + break + default: + Log.Debugf("FIL %s", p) + if tree.OtherFiles == nil { + tree.OtherFiles = make([]string, 0) + } + tree.OtherFiles = append(tree.OtherFiles, f.Name()) + } + } + } + + // only directorys, needed config before + for _, f := range files { + p := tree.InputPath + "/" + f.Name() + if f.IsDir() { + Log.Debugf("DIR %s", p) + newTree := new(config.PathConfigTree) + if tree.Sub == nil { + tree.Sub = make([]*config.PathConfigTree, 0) + } + tree.Sub = append(tree.Sub, newTree) + ReadContentDir(tree.InputPath, tree.OutputPath, f.Name(), tree.Config, newTree) + } + } +} + +func ProcessContent(rootConf, conf *config.PathConfigTree) { + CreateDirectory(conf.OutputPath) + + curNavPath := strings.TrimPrefix(conf.OutputPath, config.Config.Directories.Output) + curNavPath = strings.TrimPrefix(curNavPath, "/") + curNavPath = path.Clean(curNavPath) + if curNavPath == "." { + curNavPath = "" + } + + goTo := conf.Config.This.GoTo + if goTo != nil && *goTo != "" { + goToFixed := *goTo + if strings.HasPrefix(goToFixed, "/") { + goToFixed = BackToRoot(curNavPath) + goToFixed + } + goToFixed = path.Clean(goToFixed) + + switch config.Config.Webserver.Type { + case "apache": + htaccessFile := conf.OutputPath + "/.htaccess" + Log.Noticef("writing '%s' with redirect to: %s", htaccessFile, goToFixed) + err := ioutil.WriteFile(htaccessFile, []byte(`RewriteEngine on +RewriteRule ^$ %{REQUEST_URI}`+goToFixed+`/ [R,L] +`), 0644) + if err != nil { + Log.Panicf("could not write '%s': %s", htaccessFile, err) + } + break + } + } + + for _, file := range conf.InputFiles { + inFile := conf.InputPath + "/" + file + Log.Debugf("reading file: %s", inFile) + + input, err := ioutil.ReadFile(inFile) + if err != nil { + Log.Panicf("could not read '%s':%s", inFile, err) + } + Log.Infof("processing input file '%s'", inFile) + + newConfig := new(config.PathConfig) + + regex := regexp.MustCompile("(?s)^---(.*?)\\r?\\n\\r?---\\r?\\n\\r?") + yamlData := regex.Find(input) + if string(yamlData) != "" { + Log.Debugf("found yaml header in '%s', merging config", inFile) + err = yaml.Unmarshal(yamlData, newConfig) + if err != nil { + Log.Panicf("could not parse YAML header from '%s': %s", inFile, err) + } + + Log.Debug("merging config with upper config") + oldThis := newConfig.This + config.Merge(newConfig, conf.Config) + newConfig.This = oldThis + + Log.Debug(spew.Sdump(newConfig)) + + input = regex.ReplaceAll(input, []byte("")) + } else { + config.Merge(newConfig, conf.Config) + } + + // ignore ??? + ignoreFile := false + var ignoreRegex *string + var stripRegex *string + var outputExt *string + if f := newConfig.Filename; f != nil { + ignoreRegex = f.Ignore + stripRegex = f.Strip + outputExt = f.OutputExtension + } + if ignoreRegex != nil && *ignoreRegex != "" { + regex, err := regexp.Compile(*ignoreRegex) + if err != nil { + Log.Panicf("could not compile filename.ignore regexp '%s' for file '%s': %s", *ignoreRegex, inFile, err) + } + ignoreFile = regex.MatchString(file) + } + + if ignoreFile { + Log.Infof("ignoring file '%s', because of filename.ignore", inFile) + } else { + + // build output filename + outputFilename := file + + var indexInputFile *string + var indexOutputFile *string + if i := newConfig.Index; i != nil { + indexInputFile = i.InputFile + indexOutputFile = i.OutputFile + } + + if indexInputFile != nil && *indexInputFile == file && indexOutputFile != nil && *indexOutputFile != "" { + outputFilename = *indexOutputFile + } else { + if stripRegex != nil && *stripRegex != "" { + regex, err := regexp.Compile(*stripRegex) + if err != nil { + Log.Panicf("could not compile filename.strip regexp '%s' for file '%s': %s", *stripRegex, inFile, err) + } + outputFilename = regex.ReplaceAllString(outputFilename, "$1") + } + if outputExt != nil && *outputExt != "" { + outputFilename += "." + *outputExt + } + } + + outFile := conf.OutputPath + "/" + outputFilename + Log.Debugf("using '%s' as output file", outFile) + + var options []blackfriday.Option + + var chromaRenderer *bool + var chromaStyle *string + if m := newConfig.Markdown; m != nil { + chromaRenderer = m.ChromaRenderer + chromaStyle = m.ChromaStyle + } + if chromaStyle == nil { + style := "monokai" + chromaStyle = &style + } + if chromaRenderer != nil && *chromaRenderer { + options = []blackfriday.Option{ + blackfriday.WithRenderer( + bfchroma.NewRenderer( + bfchroma.Style(*chromaStyle), + ), + ), + } + } + + // fix \r from markdown for blackfriday + input = bytes.Replace(input, []byte("\r"), []byte(""), -1) + html := blackfriday.Run(input, options...) + + // use --- for splitting document in markdown parts + regex := regexp.MustCompile("\\r?\\n\\r?---\\r?\\n\\r?") + inputParts := regex.Split(string(input), -1) + htmlParts := make([]*pongo2.Value, 0) + for _, iPart := range inputParts { + htmlParts = append(htmlParts, pongo2.AsSafeValue(string(blackfriday.Run([]byte(iPart), options...)))) + } + + // build navigation + navMap := make(map[string]*NavElement) + navSlice := make([]*NavElement, 0) + navActive := make([]*NavElement, 0) + BuildNavigation(rootConf, &navMap, &navSlice, &navActive, curNavPath) + + // read yaml header as data for template + ctx := make(map[string]interface{}) + ctx["This"] = newConfig.This + ctx["Meta"] = newConfig.Meta + ctx["Data"] = newConfig.Data + ctx["NavMap"] = navMap + ctx["NavSlice"] = navSlice + ctx["NavActive"] = navActive + ctx["Body"] = pongo2.AsSafeValue(string(html)) + ctx["BodyParts"] = htmlParts + ctx["AssetsPath"] = config.Config.Assets.ToPath + ctx["CurrentPath"] = curNavPath + + // register functions + ctx["fnRequest"] = RequestFn + ctx["fnRender"] = RenderFn + + Log.Debugf("rendering template '%s' for '%s'", *newConfig.Template, outFile) + templateFilename := *newConfig.Template + result, err := RenderTemplate(*newConfig.Template, conf, newConfig, &ctx) + if err != nil { + Log.Panicf("could not execute template '%s' for input file '%s': %s", templateFilename, inFile, err) + } + + result = FixAssetsPath(result, curNavPath) + + Log.Noticef("writing to output file: %s", outFile) + err = ioutil.WriteFile(outFile, []byte(result), 0644) + if err != nil { + Log.Panicf("could not write to output file '%s': %s", outFile, err) + } + + //fmt.Println(string(html)) + } + } + + // process other files, copy... + for _, file := range conf.OtherFiles { + switch config.Config.OtherFiles.Action { + case "copy": + from := conf.InputPath + "/" + file + to := conf.OutputPath + "/" + file + Log.Noticef("copying file from '%s' to '%s'", from, to) + err := cpy.Copy(from, to) + if err != nil { + Log.Panicf("could not copy file from '%s' to '%s': %s", from, to, err) + } + } + } + + for _, el := range conf.Sub { + ProcessContent(rootConf, el) + } +} diff --git a/helper/navigation.go b/helper/navigation.go new file mode 100644 index 0000000..8e8b6fe --- /dev/null +++ b/helper/navigation.go @@ -0,0 +1,94 @@ +package helper + +import ( + "path" + "regexp" + "strings" + + "gitbase.de/apairon/mark2web/config" +) + +type NavElement struct { + Navname string + GoTo string + Active bool + + Data interface{} + + This config.ThisPathConfig + + SubMap *map[string]*NavElement + SubSlice *[]*NavElement +} + +func BuildNavigation(conf *config.PathConfigTree, curNavMap *map[string]*NavElement, curNavSlice *[]*NavElement, navActive *[]*NavElement, activeNav string) { + for _, el := range conf.Sub { + var ignNav *string + if p := el.Config.Path; p != nil { + ignNav = p.IgnoreForNav + } + if ignNav != nil && *ignNav != "" { + regex, err := regexp.Compile(*ignNav) + if err != nil { + Log.Panicf("could not compile IngoreForNav regexp '%s' in '%s': %s", *ignNav, el.InputPath, err) + } + if regex.MatchString(path.Base(el.InputPath)) { + Log.Debugf("ignoring input directory '%s' in navigation", el.InputPath) + continue + } + } + + elPath := strings.TrimPrefix(el.OutputPath, config.Config.Directories.Output+"/") + + subMap := make(map[string]*NavElement) + subSlice := make([]*NavElement, 0) + navEl := NavElement{ + Active: strings.HasPrefix(activeNav, elPath), + Data: el.Config.Data, + SubMap: &subMap, + SubSlice: &subSlice, + } + + navEl.This = el.Config.This + + if navEl.Active { + // add to navActive level navigation + currentLevel := strings.Count(activeNav, "/") + if len(*navActive) <= currentLevel { + // not registered + *navActive = append(*navActive, &navEl) + } + } + + n := el.Config.This.Navname + if n != nil { + navEl.Navname = *n + } + g := el.Config.This.GoTo + if g != nil { + if strings.HasPrefix(*g, "/") { + // abslute + navEl.GoTo = *g + } else { + // relative + navEl.GoTo = elPath + "/" + *g + } + } else { + navEl.GoTo = elPath + "/" + } + + if activeNav != "" && activeNav != "/" { + // calculate relative path + bToRoot := BackToRoot(activeNav) + navEl.GoTo = bToRoot + navEl.GoTo + navEl.GoTo = path.Clean(navEl.GoTo) + } + + (*curNavMap)[navEl.Navname] = &navEl + if curNavSlice != nil { + *curNavSlice = append(*curNavSlice, &navEl) + } + + BuildNavigation(el, &subMap, &subSlice, navActive, activeNav) + } +} diff --git a/main.go b/main.go index 86ade26..4d340e5 100644 --- a/main.go +++ b/main.go @@ -1,24 +1,12 @@ package main import ( - "bytes" "flag" "fmt" - "io/ioutil" "os" - "path" - "regexp" - "strings" "gitbase.de/apairon/mark2web/config" "gitbase.de/apairon/mark2web/helper" - "github.com/Depado/bfchroma" - "github.com/davecgh/go-spew/spew" - "github.com/extemporalgenome/slug" - "github.com/flosch/pongo2" - cpy "github.com/otiai10/copy" - "gopkg.in/russross/blackfriday.v2" - "gopkg.in/yaml.v2" ) var ( @@ -32,436 +20,11 @@ var ( var log = helper.Log -var inDir *string -var outDir *string - var contentConfig = new(config.PathConfigTree) -func readContentDir(inBase string, outBase string, dir string, conf *config.PathConfig, tree *config.PathConfigTree) { - inPath := inBase - if dir != "" { - inPath += "/" + dir - } - - log.Infof("reading input directory: %s", inPath) - - files, err := ioutil.ReadDir(inPath) - if err != nil { - log.Panic(err) - } - - tree.InputPath = inPath - - // read config - newConfig := new(config.PathConfig) - log.Debug("looking for config.yml ...") - configFile := inPath + "/config.yml" - if _, err = os.Stat(configFile); os.IsNotExist(err) { - log.Debug("no config.yml found in this directory, using upper configs") - config.Merge(newConfig, conf) - // remove this - newConfig.This = config.ThisPathConfig{} - } else { - log.Debug("reading config...") - data, err := ioutil.ReadFile(configFile) - if err != nil { - log.Panicf("could not read file '%s': %s", configFile, err) - } - err = yaml.Unmarshal(data, newConfig) - if err != nil { - log.Panicf("could not parse YAML file '%s': %s", configFile, err) - } - - log.Debug("merging config with upper config") - oldThis := newConfig.This - config.Merge(newConfig, conf) - newConfig.This = oldThis - - log.Debug(spew.Sdump(newConfig)) - } - - tree.Config = newConfig - - // calc outDir - stripedDir := dir - var regexStr *string - if newConfig.Path != nil { - regexStr = newConfig.Path.Strip - } - if regexStr != nil && *regexStr != "" { - if regex, err := regexp.Compile(*regexStr); err != nil { - log.Panicf("error compiling path.strip regex '%s' from '%s': %s", *regexStr, inBase+"/"+dir, err) - } else { - stripedDir = regex.ReplaceAllString(stripedDir, "$1") - } - } - - if tree.Config.This.Navname == nil { - navname := strings.Replace(stripedDir, "_", " ", -1) - tree.Config.This.Navname = &navname - } - - stripedDir = slug.Slug(stripedDir) - outPath := outBase + "/" + stripedDir - outPath = path.Clean(outPath) - - log.Infof("calculated output directory: %s", outPath) - tree.OutputPath = outPath - - // first only files - for _, f := range files { - p := inPath + "/" + f.Name() - if !f.IsDir() && f.Name() != "config.yml" { - switch path.Ext(f.Name()) { - case ".md": - log.Debugf(".MD %s", p) - if tree.InputFiles == nil { - tree.InputFiles = make([]string, 0) - } - tree.InputFiles = append(tree.InputFiles, f.Name()) - break - default: - log.Debugf("FIL %s", p) - if tree.OtherFiles == nil { - tree.OtherFiles = make([]string, 0) - } - tree.OtherFiles = append(tree.OtherFiles, f.Name()) - } - } - } - - // only directorys, needed config before - for _, f := range files { - p := inPath + "/" + f.Name() - if f.IsDir() { - log.Debugf("DIR %s", p) - newTree := new(config.PathConfigTree) - if tree.Sub == nil { - tree.Sub = make([]*config.PathConfigTree, 0) - } - tree.Sub = append(tree.Sub, newTree) - readContentDir(inPath, outPath, f.Name(), newConfig, newTree) - } - } -} - -type navElement struct { - Navname string - GoTo string - Active bool - - Data interface{} - - This config.ThisPathConfig - - SubMap *map[string]*navElement - SubSlice *[]*navElement -} - -func buildNavigation(conf *config.PathConfigTree, curNavMap *map[string]*navElement, curNavSlice *[]*navElement, navActive *[]*navElement, activeNav string) { - for _, el := range conf.Sub { - var ignNav *string - if p := el.Config.Path; p != nil { - ignNav = p.IgnoreForNav - } - if ignNav != nil && *ignNav != "" { - regex, err := regexp.Compile(*ignNav) - if err != nil { - log.Panicf("could not compile IngoreForNav regexp '%s' in '%s': %s", *ignNav, el.InputPath, err) - } - if regex.MatchString(path.Base(el.InputPath)) { - log.Debugf("ignoring input directory '%s' in navigation", el.InputPath) - continue - } - } - - elPath := strings.TrimPrefix(el.OutputPath, *outDir+"/") - - subMap := make(map[string]*navElement) - subSlice := make([]*navElement, 0) - navEl := navElement{ - Active: strings.HasPrefix(activeNav, elPath), - Data: el.Config.Data, - SubMap: &subMap, - SubSlice: &subSlice, - } - - navEl.This = el.Config.This - - if navEl.Active { - // add to navActive level navigation - currentLevel := strings.Count(activeNav, "/") - if len(*navActive) <= currentLevel { - // not registered - *navActive = append(*navActive, &navEl) - } - } - - n := el.Config.This.Navname - if n != nil { - navEl.Navname = *n - } - g := el.Config.This.GoTo - if g != nil { - if strings.HasPrefix(*g, "/") { - // abslute - navEl.GoTo = *g - } else { - // relative - navEl.GoTo = elPath + "/" + *g - } - } else { - navEl.GoTo = elPath + "/" - } - - if activeNav != "" && activeNav != "/" { - // calculate relative path - bToRoot := helper.BackToRoot(activeNav) - navEl.GoTo = bToRoot + navEl.GoTo - navEl.GoTo = path.Clean(navEl.GoTo) - } - - (*curNavMap)[navEl.Navname] = &navEl - if curNavSlice != nil { - *curNavSlice = append(*curNavSlice, &navEl) - } - - buildNavigation(el, &subMap, &subSlice, navActive, activeNav) - } -} - -func processContent(conf *config.PathConfigTree) { - helper.CreateDirectory(conf.OutputPath) - - curNavPath := strings.TrimPrefix(conf.OutputPath, *outDir) - curNavPath = strings.TrimPrefix(curNavPath, "/") - curNavPath = path.Clean(curNavPath) - if curNavPath == "." { - curNavPath = "" - } - - goTo := conf.Config.This.GoTo - if goTo != nil && *goTo != "" { - goToFixed := *goTo - if strings.HasPrefix(goToFixed, "/") { - goToFixed = helper.BackToRoot(curNavPath) + goToFixed - } - goToFixed = path.Clean(goToFixed) - - switch config.Config.Webserver.Type { - case "apache": - htaccessFile := conf.OutputPath + "/.htaccess" - log.Noticef("writing '%s' with redirect to: %s", htaccessFile, goToFixed) - err := ioutil.WriteFile(htaccessFile, []byte(`RewriteEngine on -RewriteRule ^$ %{REQUEST_URI}`+goToFixed+`/ [R,L] -`), 0644) - if err != nil { - log.Panicf("could not write '%s': %s", htaccessFile, err) - } - break - } - } - - for _, file := range conf.InputFiles { - inFile := conf.InputPath + "/" + file - log.Debugf("reading file: %s", inFile) - - input, err := ioutil.ReadFile(inFile) - if err != nil { - log.Panicf("could not read '%s':%s", inFile, err) - } - log.Infof("processing input file '%s'", inFile) - - newConfig := new(config.PathConfig) - - regex := regexp.MustCompile("(?s)^---(.*?)\\r?\\n\\r?---\\r?\\n\\r?") - yamlData := regex.Find(input) - if string(yamlData) != "" { - log.Debugf("found yaml header in '%s', merging config", inFile) - err = yaml.Unmarshal(yamlData, newConfig) - if err != nil { - log.Panicf("could not parse YAML header from '%s': %s", inFile, err) - } - - log.Debug("merging config with upper config") - oldThis := newConfig.This - config.Merge(newConfig, conf.Config) - newConfig.This = oldThis - - log.Debug(spew.Sdump(newConfig)) - - input = regex.ReplaceAll(input, []byte("")) - } else { - config.Merge(newConfig, conf.Config) - } - - // ignore ??? - ignoreFile := false - var ignoreRegex *string - var stripRegex *string - var outputExt *string - if f := newConfig.Filename; f != nil { - ignoreRegex = f.Ignore - stripRegex = f.Strip - outputExt = f.OutputExtension - } - if ignoreRegex != nil && *ignoreRegex != "" { - regex, err := regexp.Compile(*ignoreRegex) - if err != nil { - log.Panicf("could not compile filename.ignore regexp '%s' for file '%s': %s", *ignoreRegex, inFile, err) - } - ignoreFile = regex.MatchString(file) - } - - if ignoreFile { - log.Infof("ignoring file '%s', because of filename.ignore", inFile) - } else { - - // build output filename - outputFilename := file - - var indexInputFile *string - var indexOutputFile *string - if i := newConfig.Index; i != nil { - indexInputFile = i.InputFile - indexOutputFile = i.OutputFile - } - - if indexInputFile != nil && *indexInputFile == file && indexOutputFile != nil && *indexOutputFile != "" { - outputFilename = *indexOutputFile - } else { - if stripRegex != nil && *stripRegex != "" { - regex, err := regexp.Compile(*stripRegex) - if err != nil { - log.Panicf("could not compile filename.strip regexp '%s' for file '%s': %s", *stripRegex, inFile, err) - } - outputFilename = regex.ReplaceAllString(outputFilename, "$1") - } - if outputExt != nil && *outputExt != "" { - outputFilename += "." + *outputExt - } - } - - outFile := conf.OutputPath + "/" + outputFilename - log.Debugf("using '%s' as output file", outFile) - - var options []blackfriday.Option - - var chromaRenderer *bool - var chromaStyle *string - if m := newConfig.Markdown; m != nil { - chromaRenderer = m.ChromaRenderer - chromaStyle = m.ChromaStyle - } - if chromaStyle == nil { - style := "monokai" - chromaStyle = &style - } - if chromaRenderer != nil && *chromaRenderer { - options = []blackfriday.Option{ - blackfriday.WithRenderer( - bfchroma.NewRenderer( - bfchroma.Style(*chromaStyle), - ), - ), - } - } - - // fix \r from markdown for blackfriday - input = bytes.Replace(input, []byte("\r"), []byte(""), -1) - html := blackfriday.Run(input, options...) - - // use --- for splitting document in markdown parts - regex := regexp.MustCompile("\\r?\\n\\r?---\\r?\\n\\r?") - inputParts := regex.Split(string(input), -1) - htmlParts := make([]*pongo2.Value, 0) - for _, iPart := range inputParts { - htmlParts = append(htmlParts, pongo2.AsSafeValue(string(blackfriday.Run([]byte(iPart), options...)))) - } - - // build navigation - navMap := make(map[string]*navElement) - navSlice := make([]*navElement, 0) - navActive := make([]*navElement, 0) - buildNavigation(contentConfig, &navMap, &navSlice, &navActive, curNavPath) - - // read yaml header as data for template - ctx := make(map[string]interface{}) - ctx["This"] = newConfig.This - ctx["Meta"] = newConfig.Meta - ctx["Data"] = newConfig.Data - ctx["NavMap"] = navMap - ctx["NavSlice"] = navSlice - ctx["NavActive"] = navActive - ctx["Body"] = pongo2.AsSafeValue(string(html)) - ctx["BodyParts"] = htmlParts - ctx["AssetsPath"] = config.Config.Assets.ToPath - ctx["CurrentPath"] = curNavPath - - // register functions - ctx["fnRequest"] = helper.RequestFn - ctx["fnRender"] = helper.RenderFn - - log.Debugf("rendering template '%s' for '%s'", *newConfig.Template, outFile) - templateFilename := *newConfig.Template - result, err := helper.RenderTemplate(*newConfig.Template, conf, newConfig, &ctx) - if err != nil { - log.Panicf("could not execute template '%s' for input file '%s': %s", templateFilename, inFile, err) - } - - result = helper.FixAssetsPath(result, curNavPath) - - log.Noticef("writing to output file: %s", outFile) - err = ioutil.WriteFile(outFile, []byte(result), 0644) - if err != nil { - log.Panicf("could not write to output file '%s': %s", outFile, err) - } - - //fmt.Println(string(html)) - } - } - - // process other files, copy... - for _, file := range conf.OtherFiles { - switch config.Config.OtherFiles.Action { - case "copy": - from := conf.InputPath + "/" + file - to := conf.OutputPath + "/" + file - log.Noticef("copying file from '%s' to '%s'", from, to) - err := cpy.Copy(from, to) - if err != nil { - log.Panicf("could not copy file from '%s' to '%s': %s", from, to, err) - } - } - } - - for _, el := range conf.Sub { - processContent(el) - } -} - -func processAssets() { - switch config.Config.Assets.Action { - case "copy": - from := config.Config.Assets.FromPath - to := config.Config.Assets.ToPath - if !strings.HasPrefix(from, "/") { - from = *inDir + "/" + from - } - if !strings.HasPrefix(to, "/") { - to = *outDir + "/" + to - } - log.Noticef("copying assets from '%s' to '%s'", from, to) - err := cpy.Copy(from, to) - if err != nil { - log.Panicf("could not copy assets from '%s' to '%s': %s", from, to, err) - } - } -} - func main() { - inDir = flag.String("in", "./", "input directory") - outDir = flag.String("out", "html", "output directory") + inDir := flag.String("in", "./", "input directory") + outDir := flag.String("out", "html", "output directory") createOutDir := flag.Bool("create", false, "create output directory if not existing") //clearOutDir := flag.Bool("clear", false, "clear output directory before generating website") logLevel := flag.String("logLevel", "info", "log level: debug, info, warning, error") @@ -522,6 +85,8 @@ func main() { if err != nil { log.Panicf("could not read file '%s': %s", configFilename, err) } + config.Config.Directories.Input = *inDir + config.Config.Directories.Output = *outDir log.Debugf("reading input directory %s", *inDir) @@ -550,14 +115,13 @@ func main() { OutputExtension: &defaultFilenameOutputExtension, } - readContentDir(*inDir+"/content", *outDir, "", defaultPathConfig, contentConfig) + helper.ReadContentDir(*inDir+"/content", *outDir, "", defaultPathConfig, contentConfig) //spew.Dump(contentConfig) //spew.Dump(navMap) helper.SetTemplateDir(*inDir + "/templates") - processContent(contentConfig) - - processAssets() + helper.ProcessContent(contentConfig, contentConfig) + helper.ProcessAssets() }