From 68ec2fbb49086f60ebd3344b7c559c168dad9dcc Mon Sep 17 00:00:00 2001 From: "Jip J. Dekker" Date: Thu, 14 Apr 2016 22:11:34 +0200 Subject: [PATCH] Adds possibility for custom LaTeX book templates --- compiler/book.go | 2 ++ compiler/book_template.go | 72 +++++++++++++++++++++++++-------------- main.go | 1 + settings/settings.go | 4 +++ 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/compiler/book.go b/compiler/book.go index 7f24164..f92c35d 100644 --- a/compiler/book.go +++ b/compiler/book.go @@ -53,6 +53,7 @@ func MakeBook(path string, opts *settings.Settings) { helpers.Check(err, "error executing book template") f.Close() + // TODO: Better error messages when there is an error compiling latex cmd := exec.Command("latexmk", "-silent", "-pdf", "-cd", texPath) out, err := cmd.CombinedOutput() if err != nil { @@ -70,6 +71,7 @@ func MakeBook(path string, opts *settings.Settings) { "error": err, }).Error("failed to clean songbook latex files") } + // TODO: Make optional by flag err = os.Remove(texPath) helpers.Check(err, "could not remove songbook latex template") } diff --git a/compiler/book_template.go b/compiler/book_template.go index bcf0fa7..e379add 100644 --- a/compiler/book_template.go +++ b/compiler/book_template.go @@ -22,6 +22,7 @@ import ( "github.com/jjdekker/ponder/settings" ) +// parseBookTemplate parses all partial templates for the book func parseBookTemplate(opts *settings.Settings) (t *template.Template, err error) { t = template.New("Songbook") t.Funcs(template.FuncMap{ @@ -29,47 +30,68 @@ func parseBookTemplate(opts *settings.Settings) (t *template.Template, err error "unknown": unknownCategories, }) - t, err = t.Parse(bookTempl) + parsePartialTemplate(t.New("Packages"), opts.BookPackagesTempl, packagesTempl) + parsePartialTemplate(t.New("Title"), opts.BookTitleTempl, titleTempl) + parsePartialTemplate(t.New("Category"), opts.BookCategoryTempl, categoryTempl) + parsePartialTemplate(t.New("Score"), opts.BookScoreTempl, scoreTempl) + + _, err = t.Parse(bookTempl) if err != nil { log.WithFields(log.Fields{ "template": t, "source": bookTempl, "error": err, - }).Fatal("songbook template failed to compile") + }).Fatal("songbook template failed to parse") } return } -const bookTempl = ` -\documentclass[11pt,fleqn]{book} -\usepackage[utf8]{inputenc} -\usepackage{pdfpages} -\usepackage[space]{grffile} -\usepackage{hyperref} +func parsePartialTemplate(t *template.Template, source, fallback string) { + var err error + if source != "" { + _, err = t.Parse(source) + } else { + _, err = t.Parse(fallback) + } + if err != nil { + log.WithFields(log.Fields{ + "source": packagesTempl, + "error": err, + }).Fatal("packages partial template failed to parse") + } +} -{{if ne .Settings.Name ""}}\\title{ {{.Settings.Name}} }{{end}} -{{if ne .Settings.Author ""}}\\author{ {{.Settings.Author}} }{{end}} +const bookTempl = `{{ template "Packages" . }} + +{{if ne .Settings.Name ""}}\title{ {{.Settings.Name}} }{{end}} +{{if ne .Settings.Author ""}}\author{ {{.Settings.Author}} }{{end}} \date{\today} \begin{document} -\maketitle +{{ template "Title" . }} {{range $i, $cat := .Categories}} -\chapter{{printf "{"}}{{ . }}{{printf "}"}} -\newpage -{{range $.Scores}}{{if in $cat .Categories }} -\phantomsection -\addcontentsline{toc}{section}{{printf "{"}}{{ .Name }}{{printf "}"}} -\includepdf[pages=-]{{printf "{"}}{{.OutputPath}}{{printf "}"}} -{{end}}{{end}}{{end}} +{{ template "Category" . }} +{{range $.Scores}}{{if in $cat .Categories }}{{template "Score" . }}{{end}}{{end}} +{{end}} {{if not .Settings.HideUncategorized }}{{ if unknown .Scores }} -\chapter{{printf "{"}}{{ if ne .Settings.UncategorizedChapter "" }}{{.Settings.UncategorizedChapter}}{{else}}Others{{end}}{{printf "}"}} \newpage {{end}} -{{range .Scores}} -{{ if eq (len .Categories) 0 }} -\phantomsection -\addcontentsline{toc}{section}{{printf "{"}}{{ .Name }}{{printf "}"}} -\includepdf[pages=-]{{printf "{"}}{{.OutputPath}}{{printf "}"}} -{{end}}{{end}}{{end}} +{{ if ne .Settings.UncategorizedChapter "" }}{{$title := .Settings.UncategorizedChapter}}{{else}}{{$title := "Others"}}{{ template "Category" $title }}{{end}} +{{range .Scores}}{{ if eq (len .Categories) 0 }}{{template "Score" . }}{{end}}{{end}} +{{end}}{{end}} \end{document} ` + +const packagesTempl = `\documentclass[11pt,fleqn]{book} +\usepackage[utf8]{inputenc} +\usepackage{pdfpages} +\usepackage[space]{grffile} +\usepackage{hyperref}` + +const titleTempl = `\maketitle` + +const categoryTempl = `\chapter{{printf "{"}}{{ . }}{{printf "}"}}\newpage` + +const scoreTempl = `\phantomsection +\addcontentsline{toc}{section}{{printf "{"}}{{ .Name }}{{printf "}"}} +\includepdf[pages=-]{{printf "{"}}{{.OutputPath}}{{printf "}"}}` diff --git a/main.go b/main.go index d1c60bd..a3fb79d 100644 --- a/main.go +++ b/main.go @@ -24,3 +24,4 @@ func main() { // TODO: Add a clean command // TODO: Add support for Ly files to the add command // TODO: Allow an latex input file for styling +// TODO: Sort output into categories diff --git a/settings/settings.go b/settings/settings.go index d4fe6fd..3bb0461 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -32,6 +32,10 @@ type Settings struct { OutputDir string // Directory in which all complete file are stored HideUncategorized bool // Hide scores without a category from the book UncategorizedChapter string // Name of the chapter with uncategorized scores + BookPackagesTempl string // Override for the partial book template declaring packages + BookTitleTempl string // Override for the partial book template creating the title page + BookCategoryTempl string // Override for the partial book template creating category pages + BookScoreTempl string // Override for the partial book template placing scores } // FromFile reads a settings file in json format and returns the Settings struct