5326: Add Alphabetical Index and Table of Contents generation for pdf reports

svn: r18870
This commit is contained in:
Nick Hall
2012-02-12 21:55:07 +00:00
parent c91e45c547
commit 8a443da4d2
8 changed files with 566 additions and 7 deletions

View File

@@ -38,6 +38,8 @@ import sys
#
#------------------------------------------------------------------------
import libcairodoc
from gen.plug.docgen import INDEX_TYPE_ALP, INDEX_TYPE_TOC
from gen.plug.report.toc_index import write_toc, write_index
import Errors
#------------------------------------------------------------------------
@@ -109,11 +111,69 @@ class PdfDoc(libcairodoc.CairoDoc):
cr.update_context(pango_context)
# paginate the document
finished = self.paginate(layout, page_width, page_height, DPI, DPI)
while not finished:
finished = self.paginate(layout, page_width, page_height, DPI, DPI)
self.paginate_document(layout, page_width, page_height, DPI, DPI)
body_pages = self._pages
# build the table of contents and alphabetical index
toc_page = None
index_page = None
toc = []
index = {}
for page_nr, page in enumerate(body_pages):
if page.has_toc():
toc_page = page_nr
if page.has_index():
index_page = page_nr
for mark in page.get_marks():
if mark.type == INDEX_TYPE_ALP:
if mark.key in index:
if page_nr + 1 not in index[mark.key]:
index[mark.key].append(page_nr + 1)
else:
index[mark.key] = [page_nr + 1]
elif mark.type == INDEX_TYPE_TOC:
toc.append([mark, page_nr + 1])
# paginate the table of contents
rebuild_required = False
if toc_page is not None:
toc_pages = self.__generate_toc(layout, page_width, page_height,
toc)
offset = len(toc_pages) - 1
if offset > 0:
self.__increment_pages(toc, index, toc_page, offset)
rebuild_required = True
else:
toc_pages = []
# paginate the index
if index_page is not None:
index_pages = self.__generate_index(layout, page_width, page_height,
index)
offset = len(index_pages) - 1
if offset > 0:
self.__increment_pages(toc, index, index_page, offset)
rebuild_required = True
else:
index_pages = []
# rebuild the table of contents and index if required
if rebuild_required:
if toc_page is not None:
toc_pages = self.__generate_toc(layout, page_width, page_height,
toc)
if index_page is not None:
index_pages = self.__generate_index(layout, page_width,
page_height, index)
# render the pages
if toc_page is not None:
body_pages = body_pages[:toc_page] + toc_pages + \
body_pages[toc_page+1:]
if index_page is not None:
body_pages = body_pages[:index_page] + index_pages + \
body_pages[index_page+1:]
self._pages = body_pages
for page_nr in range(len(self._pages)):
cr.save()
cr.translate(left_margin, top_margin)
@@ -130,3 +190,96 @@ class PdfDoc(libcairodoc.CairoDoc):
# if we don't restore the resolution.
fontmap.set_resolution(saved_resolution)
def __increment_pages(self, toc, index, start_page, offset):
"""
Increment the page numbers in the table of contents and index.
"""
for n, value in enumerate(toc):
page_nr = toc[n][1]
toc[n][1] = page_nr + (offset if page_nr > start_page else 0)
for key, value in index.iteritems():
index[key] = [page_nr + (offset if page_nr > start_page else 0)
for page_nr in value]
def __generate_toc(self, layout, page_width, page_height, toc):
"""
Generate the table of contents.
"""
self._doc = libcairodoc.GtkDocDocument()
self._active_element = self._doc
self._pages = []
write_toc(toc, self)
self.paginate_document(layout, page_width, page_height, DPI, DPI)
return self._pages
def __generate_index(self, layout, page_width, page_height, index):
"""
Generate the index.
"""
self._doc = libcairodoc.GtkDocDocument()
self._active_element = self._doc
self._pages = []
write_index(index, self)
self.paginate_document(layout, page_width, page_height, DPI, DPI)
return self._pages
def write_toc(toc, doc):
"""
Write the table of contents.
"""
if not toc:
return
doc.start_paragraph('TOC-Title')
doc.write_text(_('Contents'))
doc.end_paragraph()
doc.start_table('toc', 'TOC-Table')
for mark, page_nr in toc:
doc.start_row()
doc.start_cell('TOC-Cell')
if mark.level == 1:
style_name = "TOC-Heading1"
elif mark.level == 2:
style_name = "TOC-Heading2"
else:
style_name = "TOC-Heading3"
doc.start_paragraph(style_name)
doc.write_text(mark.key)
doc.end_paragraph()
doc.end_cell()
doc.start_cell('TOC-Cell')
doc.start_paragraph('TOC-Number')
doc.write_text(str(page_nr))
doc.end_paragraph()
doc.end_cell()
doc.end_row()
doc.end_table()
def write_index(index, doc):
"""
Write the alphabetical index.
"""
if not index:
return
doc.start_paragraph('Index-Title')
doc.write_text(_('Index'))
doc.end_paragraph()
doc.start_table('index', 'Index-Table')
for key in sorted(index.iterkeys()):
doc.start_row()
doc.start_cell('Index-Cell')
doc.start_paragraph('Index-Number')
doc.write_text(key)
doc.end_paragraph()
doc.end_cell()
doc.start_cell('Index-Cell')
doc.start_paragraph('Index-Number')
pages = [str(page_nr) for page_nr in index[key]]
doc.write_text(', '.join(pages))
doc.end_paragraph()
doc.end_cell()
doc.end_row()
doc.end_table()