168 lines
4.8 KiB
Go
168 lines
4.8 KiB
Go
package main
|
|
|
|
import "strconv"
|
|
|
|
// TOCItem is one entry in the Inhaltsverzeichnis.
|
|
type TOCItem struct {
|
|
Level int
|
|
Title string
|
|
PageStr string // formatted page number (Roman or Arabic)
|
|
}
|
|
|
|
// TableItem is one entry in the Tabellenverzeichnis.
|
|
type TableItem struct {
|
|
Title string
|
|
PageStr string
|
|
}
|
|
|
|
// FigureItem is one entry in the Abbildungsverzeichnis.
|
|
type FigureItem struct {
|
|
Title string
|
|
PageStr string
|
|
}
|
|
|
|
// dirEntry is the internal representation used by renderDirEntries.
|
|
type dirEntry struct {
|
|
indent int // indentation level (0 = none)
|
|
title string // translated title text
|
|
pageStr string // page number string
|
|
}
|
|
|
|
// RecordHeader adds a heading to the TOC with the appropriate page number.
|
|
// Front-matter headings use Roman numerals; main-body headings use Arabic.
|
|
// Headings on the title page (NumNone) are not recorded.
|
|
func (r *IHKRenderer) RecordHeader(level int, title string) {
|
|
var pageStr string
|
|
switch r.numType {
|
|
case NumRoman:
|
|
pageStr = toRoman(r.pdf.PageNo())
|
|
case NumArabic:
|
|
dp := r.pdf.PageNo() - r.pageOffset
|
|
if dp <= 0 {
|
|
dp = 1
|
|
}
|
|
pageStr = strconv.Itoa(dp)
|
|
default:
|
|
return
|
|
}
|
|
r.tocItems = append(r.tocItems, TOCItem{Level: level, Title: title, PageStr: pageStr})
|
|
}
|
|
|
|
// RecordTable adds an entry to the Tabellenverzeichnis.
|
|
func (r *IHKRenderer) RecordTable(title string) {
|
|
dp := r.pdf.PageNo() - r.pageOffset
|
|
if dp <= 0 {
|
|
dp = 1
|
|
}
|
|
r.tableItems = append(r.tableItems, TableItem{Title: title, PageStr: strconv.Itoa(dp)})
|
|
}
|
|
|
|
// RecordFigure adds an entry to the Abbildungsverzeichnis.
|
|
func (r *IHKRenderer) RecordFigure(title string) {
|
|
dp := r.pdf.PageNo() - r.pageOffset
|
|
if dp <= 0 {
|
|
dp = 1
|
|
}
|
|
r.figureItems = append(r.figureItems, FigureItem{Title: title, PageStr: strconv.Itoa(dp)})
|
|
}
|
|
|
|
// RenderTOC renders the Inhaltsverzeichnis on a new Roman-numbered page.
|
|
// In pass 1 the list is empty (no tocItems yet); pass 2 fills it in.
|
|
// Note: if the TOC spans more pages than in pass 1, subsequent page numbers
|
|
// will be off by the difference — an inherent two-pass limitation.
|
|
func (r *IHKRenderer) RenderTOC() {
|
|
r.numType = NumRoman
|
|
r.pdf.AddPage()
|
|
|
|
r.pdf.SetFont("Helvetica", "B", dinFontHeading)
|
|
r.pdf.CellFormat(0, dinLineHtHeading+4, r.tr("Inhaltsverzeichnis"), "", 1, "L", false, 0, "")
|
|
r.pdf.Ln(dinSpaceAfterHeading)
|
|
|
|
if len(r.tocItems) == 0 {
|
|
return
|
|
}
|
|
|
|
// Column header row
|
|
uw := r.usableWidth()
|
|
r.pdf.SetFont("Helvetica", "B", dinFontBody)
|
|
r.pdf.CellFormat(uw-20, dinLineHtBody, r.tr("Inhalt"), "", 0, "L", false, 0, "")
|
|
r.pdf.CellFormat(20, dinLineHtBody, r.tr("Seite"), "", 1, "R", false, 0, "")
|
|
r.pdf.Ln(2)
|
|
|
|
entries := make([]dirEntry, len(r.tocItems))
|
|
for i, item := range r.tocItems {
|
|
entries[i] = dirEntry{
|
|
indent: item.Level - 1,
|
|
title: item.Title,
|
|
pageStr: item.PageStr,
|
|
}
|
|
}
|
|
r.renderDirEntries(entries)
|
|
}
|
|
|
|
// RenderListOfTables renders the Tabellenverzeichnis if any tables were recorded.
|
|
func (r *IHKRenderer) RenderListOfTables() {
|
|
if len(r.tableItems) == 0 {
|
|
return
|
|
}
|
|
r.pdf.AddPage()
|
|
r.pdf.SetFont("Helvetica", "B", dinFontHeading)
|
|
r.pdf.CellFormat(0, dinLineHtHeading+4, r.tr("Tabellenverzeichnis"), "", 1, "L", false, 0, "")
|
|
r.pdf.Ln(dinSpaceAfterHeading)
|
|
|
|
entries := make([]dirEntry, len(r.tableItems))
|
|
for i, item := range r.tableItems {
|
|
entries[i] = dirEntry{indent: 0, title: item.Title, pageStr: item.PageStr}
|
|
}
|
|
r.renderDirEntries(entries)
|
|
}
|
|
|
|
// RenderListOfFigures renders the Abbildungsverzeichnis if any figures were recorded.
|
|
func (r *IHKRenderer) RenderListOfFigures() {
|
|
if len(r.figureItems) == 0 {
|
|
return
|
|
}
|
|
r.pdf.AddPage()
|
|
r.pdf.SetFont("Helvetica", "B", dinFontHeading)
|
|
r.pdf.CellFormat(0, dinLineHtHeading+4, r.tr("Abbildungsverzeichnis"), "", 1, "L", false, 0, "")
|
|
r.pdf.Ln(dinSpaceAfterHeading)
|
|
|
|
entries := make([]dirEntry, len(r.figureItems))
|
|
for i, item := range r.figureItems {
|
|
entries[i] = dirEntry{indent: 0, title: item.Title, pageStr: item.PageStr}
|
|
}
|
|
r.renderDirEntries(entries)
|
|
}
|
|
|
|
// renderDirEntries renders a list of title/page entries with dot leaders,
|
|
// per DIN 5008 Inhaltsverzeichnis layout.
|
|
func (r *IHKRenderer) renderDirEntries(entries []dirEntry) {
|
|
uw := r.usableWidth()
|
|
lm, _, _, _ := r.pdf.GetMargins()
|
|
r.pdf.SetFont("Helvetica", "", dinFontBody)
|
|
|
|
for _, e := range entries {
|
|
indent := float64(e.indent * 8)
|
|
r.pdf.SetX(lm + indent)
|
|
|
|
title := r.tr(e.title)
|
|
pageStr := e.pageStr
|
|
tw := r.pdf.GetStringWidth(title)
|
|
pw := r.pdf.GetStringWidth(pageStr)
|
|
avail := uw - indent - tw - pw - 6
|
|
|
|
r.pdf.CellFormat(tw+2, dinLineHtBody, title, "", 0, "L", false, 0, "")
|
|
if avail > 0 {
|
|
dots := ""
|
|
dw := r.pdf.GetStringWidth(".")
|
|
if dw > 0 {
|
|
for float64(len([]rune(dots)))*dw < avail {
|
|
dots += "."
|
|
}
|
|
}
|
|
r.pdf.CellFormat(avail, dinLineHtBody, dots, "", 0, "L", false, 0, "")
|
|
}
|
|
r.pdf.CellFormat(pw+4, dinLineHtBody, pageStr, "", 1, "R", false, 0, "")
|
|
}
|
|
}
|