From b1657c7960b94f9c1f90fa1efaf49e04f78e0f91 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 5 Oct 2019 21:03:17 -0400 Subject: Support UTF-8 aliases and correct problem with UTF-8 page count alias --- fpdf.go | 29 ++++++++++++++++++----------- fpdf_test.go | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/fpdf.go b/fpdf.go index 5486842..6bc4aa3 100644 --- a/fpdf.go +++ b/fpdf.go @@ -3782,17 +3782,28 @@ func (f *Fpdf) SetJavascript(script string) { // replace all occurrences of that alias after writing but before the // document is closed. func (f *Fpdf) RegisterAlias(alias, replacement string) { + // Note: map[string]string assignments embed literal escape ("\00") sequences + // into utf16 key and value strings. Consequently, subsequent search/replace + // operations will fail unexpectedly if utf8toutf16() conversions take place + // here. Instead, conversions are deferred until the actual search/replace + // operation takes place when the PDF output is generated. 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) + for mode := 0; mode < 2; mode++ { + for alias, replacement := range f.aliasMap { + if mode == 1 { + alias = utf8toutf16(alias, false) + replacement = utf8toutf16(replacement, false) + } + 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) + } } } } @@ -3801,14 +3812,10 @@ func (f *Fpdf) replaceAliases() { func (f *Fpdf) putpages() { var wPt, hPt float64 var pageSize SizeType - // var linkList []linkType var ok bool nb := f.page if len(f.aliasNbPagesStr) > 0 { // Replace number of pages - alias := utf8toutf16(f.aliasNbPagesStr, false) - r := utf8toutf16(sprintf("%d", nb), false) - f.RegisterAlias(alias, r) f.RegisterAlias(f.aliasNbPagesStr, sprintf("%d", nb)) } f.replaceAliases() diff --git a/fpdf_test.go b/fpdf_test.go index 5035bd8..30ee11b 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -2246,13 +2246,14 @@ func ExampleFpdf_AddSpotColor() { func ExampleFpdf_RegisterAlias() { pdf := gofpdf.New("P", "mm", "A4", "") pdf.SetFont("Arial", "", 12) + pdf.AliasNbPages("") 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.Cell(0, 10, fmt.Sprintf("Section %d begins on page {mark %d}", i, i)) pdf.Ln(10) } @@ -2261,8 +2262,8 @@ func ExampleFpdf_RegisterAlias() { // 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)) + pdf.RegisterAlias(fmt.Sprintf("{mark %d}", i), fmt.Sprintf("%d", pdf.PageNo())) + pdf.Write(10, fmt.Sprintf("Section %d, page %d of {nb}", i, pdf.PageNo())) } fileStr := example.Filename("Fpdf_RegisterAlias") @@ -2272,6 +2273,40 @@ func ExampleFpdf_RegisterAlias() { // Successfully generated pdf/Fpdf_RegisterAlias.pdf } +// ExampleFpdf_RegisterAliasUTF8 demonstrates how to use `RegisterAlias` to +// create a table of contents. This particular example demonstrates the use of +// UTF-8 aliases. +func ExampleFpdf_RegisterAliasUTF8() { + pdf := gofpdf.New("P", "mm", "A4", "") + pdf.AddUTF8Font("dejavu", "", example.FontFile("DejaVuSansCondensed.ttf")) + pdf.SetFont("dejavu", "", 12) + pdf.AliasNbPages("{entute}") + 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("Sekcio %d komenciĝas ĉe paĝo {ĉi tiu marko %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("{ĉi tiu marko %d}", i), fmt.Sprintf("%d", pdf.PageNo())) + pdf.Write(10, fmt.Sprintf("Sekcio %d, paĝo %d de {entute}", i, pdf.PageNo())) + } + + fileStr := example.Filename("Fpdf_RegisterAliasUTF8") + err := pdf.OutputFileAndClose(fileStr) + example.Summary(err, fileStr) + // Output: + // Successfully generated pdf/Fpdf_RegisterAliasUTF8.pdf +} + // ExampleNewGrid demonstrates the generation of graph grids. func ExampleNewGrid() { pdf := gofpdf.New("P", "mm", "A4", "") -- cgit v1.2.1-24-ge1ad