From 80c5811b6b15479b473e814cad0aae7de9920bb3 Mon Sep 17 00:00:00 2001 From: David Fish Date: Mon, 8 Jan 2018 11:19:41 -0800 Subject: Added generic alias-replacement function to enable Table of Contents functionality --- def.go | 6 +++++- fpdf.go | 32 +++++++++++++++++++++++--------- fpdf_test.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/def.go b/def.go index 52e6474..936ca09 100644 --- a/def.go +++ b/def.go @@ -40,7 +40,10 @@ type gradientType struct { } const ( - OrientationPortrait = "portrait" + // OrientationPortrait represents the portrait orientation. + OrientationPortrait = "portrait" + + // OrientationLandscape represents the landscape orientation. OrientationLandscape = "landscape" ) @@ -243,6 +246,7 @@ type Fpdf struct { fontSize float64 // current font size in user unit ws float64 // word spacing images map[string]*ImageInfoType // array of used images + aliasMap map[string]string // map of alias->replacement pageLinks [][]linkType // pageLinks[page][link], both 1-based links []intLinkType // array of internal links outlines []outlineType // array of outlines diff --git a/fpdf.go b/fpdf.go index 567311d..ad29d18 100644 --- a/fpdf.go +++ b/fpdf.go @@ -88,6 +88,7 @@ func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType) f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0)) // pageLinks[0] is unused (1-based) f.links = make([]intLinkType, 0, 8) f.links = append(f.links, intLinkType{}) // links[0] is unused (1-based) + f.aliasMap = make(map[string]string) f.inHeader = false f.inFooter = false f.lasth = 0 @@ -3071,6 +3072,26 @@ func (f *Fpdf) SetJavascript(script string) { f.javascript = &script } +// RegisterAlias adds an (alias, replacement) pair to the document so we can +// replace all occurrences of that alias after writing but before the +// document is closed. +func (f *Fpdf) RegisterAlias(alias, replacement string) { + f.aliasMap[alias] = replacement +} + +func (f *Fpdf) replaceAliases() { + for alias, replacement := range f.aliasMap { + for n := 1; n <= f.page; n++ { + s := f.pages[n].String() + if strings.Contains(s, alias) { + s = strings.Replace(s, alias, replacement, -1) + f.pages[n].Truncate(0) + f.pages[n].WriteString(s) + } + } + } +} + func (f *Fpdf) putpages() { var wPt, hPt float64 var pageSize SizeType @@ -3079,16 +3100,9 @@ func (f *Fpdf) putpages() { nb := f.page if len(f.aliasNbPagesStr) > 0 { // Replace number of pages - nbStr := sprintf("%d", nb) - for n := 1; n <= nb; n++ { - s := f.pages[n].String() - if strings.Contains(s, f.aliasNbPagesStr) { - s = strings.Replace(s, f.aliasNbPagesStr, nbStr, -1) - f.pages[n].Truncate(0) - f.pages[n].WriteString(s) - } - } + f.RegisterAlias(f.aliasNbPagesStr, sprintf("%d", nb)) } + f.replaceAliases() if f.defOrientation == "P" { wPt = f.defPageSize.Wd * f.k hPt = f.defPageSize.Ht * f.k diff --git a/fpdf_test.go b/fpdf_test.go index ff41fd2..c7d843a 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -2060,3 +2060,34 @@ func ExampleFpdf_AddSpotColor() { // Output: // Successfully generated pdf/Fpdf_AddSpotColor.pdf } + +// This example demonstrates how to use `RegisterAlias` to create a table of +// contents. +func ExampleFpdf_TableOfContents() { + pdf := gofpdf.New("P", "mm", "A4", "") + pdf.SetFont("Arial", "", 12) + pdf.AddPage() + + // Write the table of contents. We use aliases instead of the page number + // because we don't know which page the section will begin on. + numSections := 3 + for i := 1; i <= numSections; i++ { + pdf.Cell(0, 10, fmt.Sprintf("Section %d begins on page {%d}", i, i)) + pdf.Ln(10) + } + + // Write the sections. Before we start writing, we use `RegisterAlias` to + // ensure that the alias written in the table of contents will be replaced + // by the current page number. + for i := 1; i <= numSections; i++ { + pdf.AddPage() + pdf.RegisterAlias(fmt.Sprintf("{%d}", i), fmt.Sprintf("%d", pdf.PageNo())) + pdf.Write(10, fmt.Sprintf("Section %d", i)) + } + + fileStr := example.Filename("Fpdf_TableOfContents") + err := pdf.OutputFileAndClose(fileStr) + example.Summary(err, fileStr) + // Output: + // Successfully generated pdf/Fpdf_TableOfContents.pdf +} -- cgit v1.2.1-24-ge1ad From d65c2335e8ec3db6c87c9e23aa2ff329da57e182 Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 8 Jan 2018 15:32:13 -0500 Subject: Acknowledge David Fish's generic alias replacement contribution; change test name so that example hang's off of RegisterAlias method in documentation --- README.md | 6 ++++-- doc.go | 6 ++++-- fpdf_test.go | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d0cd77c..cc6b459 100644 --- a/README.md +++ b/README.md @@ -217,8 +217,10 @@ basic HTML functionality with aligned text. Kent Quirk implemented backwards-compatible support for reading DPI from images that support it, and for setting DPI manually and then having it properly taken into account when calculating image size. Paulo Coutinho provided support for static embedded -fonts. Dan Meyers added support for embedded JavaScript. Bruno Michel has -provided valuable assistance with the code. +fonts. Dan Meyers added support for embedded JavaScript. David Fish added a +generic alias-replacement function to enable, among other things, Table of +Contents functionality. Bruno Michel has provided valuable assistance with the +code. ## Roadmap diff --git a/doc.go b/doc.go index 4c63289..598e13c 100644 --- a/doc.go +++ b/doc.go @@ -230,8 +230,10 @@ basic HTML functionality with aligned text. Kent Quirk implemented backwards-compatible support for reading DPI from images that support it, and for setting DPI manually and then having it properly taken into account when calculating image size. Paulo Coutinho provided support for static embedded -fonts. Dan Meyers added support for embedded JavaScript. Bruno Michel has -provided valuable assistance with the code. +fonts. Dan Meyers added support for embedded JavaScript. David Fish added a +generic alias-replacement function to enable, among other things, Table of +Contents functionality. Bruno Michel has provided valuable assistance with the +code. Roadmap diff --git a/fpdf_test.go b/fpdf_test.go index c7d843a..c7cd582 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -2063,7 +2063,7 @@ func ExampleFpdf_AddSpotColor() { // This example demonstrates how to use `RegisterAlias` to create a table of // contents. -func ExampleFpdf_TableOfContents() { +func ExampleFpdf_RegisterAlias() { pdf := gofpdf.New("P", "mm", "A4", "") pdf.SetFont("Arial", "", 12) pdf.AddPage() @@ -2085,9 +2085,9 @@ func ExampleFpdf_TableOfContents() { pdf.Write(10, fmt.Sprintf("Section %d", i)) } - fileStr := example.Filename("Fpdf_TableOfContents") + fileStr := example.Filename("Fpdf_RegisterAlias") err := pdf.OutputFileAndClose(fileStr) example.Summary(err, fileStr) // Output: - // Successfully generated pdf/Fpdf_TableOfContents.pdf + // Successfully generated pdf/Fpdf_RegisterAlias.pdf } -- cgit v1.2.1-24-ge1ad