func GenerateWholeBook(p *Process) error { // Get the parts of the config file sourcePath := config.SourcePath(source) // Set the config file name configFile := config.ConfigFile(sourcePath, cfgfile) // Log the attempt to read the configuration file log.Printf("Reading configuration file %s\n", configFile) // Read the configuration c, err := config.ReadConfigFromFile(cfgfile, source) if err != nil { fmt.Printf("Error:: %v\n", err) p.Done <- true return err } // Set the source path c.SourcePath = sourcePath // Process and generate the book log.Printf("Generating Book\n") err = GenerateBook(p, c) if err != nil { fmt.Printf("Error:: %v\n", err) p.Done <- true return err } return nil }
func ReadAllModTimes(c *config.Config, p *Process) error { // Get the parts of the config file sourcePath := config.SourcePath(source) configFileLocation := config.ConfigFile(sourcePath, cfgfile) // Set the config file name configFileInfo, err := os.Stat(configFileLocation) if err != nil { return err } // Read all the layouts for html htmlLayouts := c.Layouts["html"] // Save the config info p.ConfigFileInfo = &configFileInfo // Get the file info for the pageLayout file pageLayoutFile := fmt.Sprintf("%s/%s", p.Source, htmlLayouts.Page) pageLayoutFileInfo, err := os.Stat(pageLayoutFile) p.PageLayoutFileInfo = &pageLayoutFileInfo // Get the file info for the pageLayout file indexLayoutFile := fmt.Sprintf("%s/%s", p.Source, htmlLayouts.Index) indexLayoutFileInfo, err := os.Stat(indexLayoutFile) p.IndexFileInfo = &indexLayoutFileInfo // Copy over all the assets for _, asset := range c.Assets { assetLocation := fmt.Sprintf("%s/%s", p.Source, asset) // Get the file info for the pageLayout file assetFileInfo, err := os.Stat(assetLocation) if err != nil { return err } p.AssetsFileInfo[asset] = &assetFileInfo } for _, page := range c.TableOfContents { // Get the file info for the pageLayout file pageFileInfo, err := os.Stat(fmt.Sprintf("%s/%s", p.Source, page.File)) if err != nil { return err } p.PagesFileInfo[page.File] = &pageFileInfo } return nil }
func ReadConfiguration(p *Process) (*config.Config, error) { // Get the parts of the config file sourcePath := config.SourcePath(source) // Set the config file name configFile := config.ConfigFile(sourcePath, cfgfile) // Log the attempt to read the configuration file log.Printf("Reading configuration file %s\n", configFile) // Read the configuration c, err := config.ReadConfigFromFile(cfgfile, source) if err != nil { fmt.Printf("Error:: %v\n", err) p.Done <- true return nil, err } // Set the source path c.SourcePath = sourcePath return c, err }
func GenerateBook(p *Process, c *config.Config) error { // Read all the layouts for html htmlLayouts := c.Layouts["html"] indexLayout := htmlLayouts.Index pageLayout := htmlLayouts.Page // Get the parts of the config file sourcePath := config.SourcePath(source) // Set the config file name configFile := config.ConfigFile(sourcePath, cfgfile) configFileInfo, err := os.Stat(configFile) if err == nil { p.ConfigFileInfo = &configFileInfo } // Get the right location for the page layout file indexLayoutFile := fmt.Sprintf("%s/%s", p.Source, indexLayout) // Get the file info for the pageLayout file indexLayoutFileInfo, err := os.Stat(indexLayoutFile) if err == nil { p.IndexFileInfo = &indexLayoutFileInfo } // Get the right location for the page layout file pageLayoutFile := fmt.Sprintf("%s/%s", p.Source, pageLayout) // Get the file info for the pageLayout file pageLayoutFileInfo, err := os.Stat(pageLayoutFile) if err == nil { p.PageLayoutFileInfo = &pageLayoutFileInfo } // Read the page layout file in layoutBytes, err := ioutil.ReadFile(pageLayoutFile) if err != nil { log.Printf("no layout file found for %s\n", pageLayoutFile) } // Parse the template into an object pageTemplate, err := template.New("pageTemplate").Parse(string(layoutBytes)) if err != nil { log.Printf("invalid template found in %s page template file\n", pageLayoutFile) } // Copy over all the assets for _, asset := range c.Assets { assetLocation := fmt.Sprintf("%s/%s", p.Source, asset) fileContent, err := ioutil.ReadFile(assetLocation) // Get the file info for the pageLayout file assetFileInfo, err := os.Stat(assetLocation) if err == nil { p.AssetsFileInfo[asset] = &assetFileInfo } if err == nil { assetOutputLocation := fmt.Sprintf("%s/%s", c.OutputDirectory, filepath.Base(asset)) log.Printf("Saving asset to %s\n", assetOutputLocation) err = ioutil.WriteFile(assetOutputLocation, fileContent, 0755) if err != nil { log.Fatalf("Failed to save the asset %s to %s\n", asset, assetOutputLocation) } } else { log.Fatalf("Could not locate the asset %s\n", asset) } } // Read all the pages in for pageIndex, page := range c.TableOfContents { log.Printf("Generate page %s\n", page.File) // Split the file up so we can get the "name" fileNameParts := strings.Split(page.File, ".") fileName := strings.Join(fileNameParts[0:(len(fileNameParts)-1)], ".") // Read the page pageFile := fmt.Sprintf("%s/%s", p.Source, page.File) // Get the file info for the pageLayout file pageFileInfo, err := os.Stat(pageFile) if err != nil { return err } if err == nil { p.PagesFileInfo[page.File] = &pageFileInfo } // Read the page into memory data, err := ioutil.ReadFile(pageFile) if err != nil { return err } // Render the mardown html := p.CustomTransformer.Transform(data) // Pass to the template if it's defined if pageTemplate != nil { // Output buffer buffer := bytes.NewBuffer(nil) // Render the template err = pageTemplate.Execute(buffer, BuildContext(pageIndex, string(html), c)) if err != nil { log.Fatalf("Failed to execute template %s\n", pageLayoutFile) os.Exit(0) } // Save the data as the new page html = buffer.Bytes() } // Let's write the resulting page out err = ioutil.WriteFile(fmt.Sprintf("%s/%s.html", c.OutputDirectory, fileName), html, 0755) if err != nil { return err } } return nil }
func WatchMode(delay int64, p *Process) { go func() { for true { // Get the parts of the config file sourcePath := config.SourcePath(source) configFileLocation := config.ConfigFile(sourcePath, cfgfile) // Set the config file name configFileInfo, err := os.Stat(configFileLocation) if err != nil { log.Printf("Failed to read configuration file from %s\n", configFileLocation) continue } // Read the configuration c, err := config.ReadConfigFromFile(cfgfile, source) if err != nil { log.Printf("Failed to read configuration file from %s\n", configFileLocation) continue } // Point to the actual instance configFileInfoInstance := *p.ConfigFileInfo // If config time finished if !configFileInfo.ModTime().Equal(configFileInfoInstance.ModTime()) { log.Printf("Configuration file changed, regenerating whole book\n") // Re-generate the whole book GenerateWholeBook(p) // Save the new configuration file info p.ConfigFileInfo = &configFileInfo // Done, let's watch again continue } // Read all the layouts for html htmlLayouts := c.Layouts["html"] indexLayout := htmlLayouts.Index pageLayout := htmlLayouts.Page // Get the file info for the pageLayout file pageLayoutFile := fmt.Sprintf("%s/%s", p.Source, pageLayout) pageLayoutFileInfo, err := os.Stat(pageLayoutFile) if err != nil { log.Printf("Index layout file changed, regenerating whole book\n") // Re-generate the whole book GenerateWholeBook(p) // Update the time p.PageLayoutFileInfo = &pageLayoutFileInfo continue } // Get the file info for the pageLayout file indexLayoutFile := fmt.Sprintf("%s/%s", p.Source, indexLayout) indexLayoutFileInfo, err := os.Stat(indexLayoutFile) if err != nil { log.Printf("Index layout file changed, regenerating whole book\n") // Re-generate the whole book GenerateWholeBook(p) // Update the time p.IndexFileInfo = &indexLayoutFileInfo continue } // Read the page layout file in layoutBytes, err := ioutil.ReadFile(pageLayoutFile) if err != nil { log.Printf("no layout file found for %s\n", pageLayoutFile) } // Parse the template into an object pageTemplate, err := template.New("pageTemplate").Parse(string(layoutBytes)) if err != nil { log.Printf("invalid template found in %s page template file\n", pageLayoutFile) } // Copy over all the assets for _, asset := range c.Assets { assetLocation := fmt.Sprintf("%s/%s", p.Source, asset) fileContent, err := ioutil.ReadFile(assetLocation) // Get the file info for the pageLayout file assetFileInfo, err := os.Stat(assetLocation) if err == nil { modTime := *p.AssetsFileInfo[asset] if modTime != nil && modTime.ModTime().Equal(assetFileInfo.ModTime()) { continue } p.AssetsFileInfo[asset] = &assetFileInfo } if err == nil { assetOutputLocation := fmt.Sprintf("%s/%s", c.OutputDirectory, filepath.Base(asset)) log.Printf("Saving asset to %s\n", assetOutputLocation) err = ioutil.WriteFile(assetOutputLocation, fileContent, 0755) if err != nil { log.Fatalf("Failed to save the asset %s to %s\n", asset, assetOutputLocation) } } else { log.Fatalf("Could not locate the asset %s\n", asset) } } // We only re-generate pages that have changed // Read all the pages in for pageIndex, page := range c.TableOfContents { // Split the file up so we can get the "name" fileNameParts := strings.Split(page.File, ".") fileName := strings.Join(fileNameParts[0:(len(fileNameParts)-1)], ".") // Read the page pageFile := fmt.Sprintf("%s/%s", p.Source, page.File) // Get the file info for the pageLayout file pageFileInfo, err := os.Stat(pageFile) if err == nil { modTime := *p.PagesFileInfo[page.File] if modTime != nil && modTime.ModTime().Equal(pageFileInfo.ModTime()) { continue } log.Printf("Generate page %s\n", page.File) p.PagesFileInfo[page.File] = &pageFileInfo } // Read the page into memory data, err := ioutil.ReadFile(pageFile) if err != nil { continue } // Render the mardown html := p.CustomTransformer.Transform(data) // Pass to the template if it's defined if pageTemplate != nil { // var buffer bytes.Buffer buffer := bytes.NewBuffer(nil) err = pageTemplate.Execute(buffer, BuildContext(pageIndex, string(html), c)) if err != nil { log.Fatalf("Failed to execute template %s\n", pageLayoutFile) os.Exit(0) } // Save the data as the new page html = buffer.Bytes() } // Let's write the resulting page out err = ioutil.WriteFile(fmt.Sprintf("%s/%s.html", c.OutputDirectory, fileName), html, 0755) if err != nil { continue } } // Just sleep a bit and watch again time.Sleep(time.Duration(delay) * time.Millisecond) } }() // Wait until we are done <-p.Done }