Files

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, "")
}
}