Example #1
0
 def test_rl_config_reset(self):
     from reportlab import rl_config
     from reportlab.pdfbase import pdfmetrics, _fontdata
     tfd = pdfmetrics._typefaces
     fbn = _fontdata.fontsByName
     tfd[' a ']=1
     fbn[' b ']=1
     ntfd = len(tfd)
     nfbn = len(fbn)
     from reportlab.lib import sequencer
     seq = sequencer.getSequencer()
     seq._dingo = 1
     rl_config._reset()
     assert not hasattr(seq,'_dingo')
     assert ' a ' not in tfd and len(tfd)<ntfd
     assert ' a ' not in fbn and len(fbn)<nfbn
Example #2
0
 def test_rl_config_reset(self):
     from reportlab import rl_config
     from reportlab.pdfbase import pdfmetrics, _fontdata
     tfd = pdfmetrics._typefaces
     fbn = _fontdata.fontsByName
     tfd[' a '] = 1
     fbn[' b '] = 1
     ntfd = len(tfd)
     nfbn = len(fbn)
     from reportlab.lib import sequencer
     seq = sequencer.getSequencer()
     seq._dingo = 1
     rl_config._reset()
     assert not hasattr(seq, '_dingo')
     assert ' a ' not in tfd and len(tfd) < ntfd
     assert ' a ' not in fbn and len(fbn) < nfbn
Example #3
0
 def _textual(self, node, x=0, y=0):
     text = node.text and node.text.encode('utf-8') or ''
     rc = utils._process_text(self, text)
     for n in node:
         if n.tag == 'seq':
             from reportlab.lib.sequencer import getSequencer
             seq = getSequencer()
             rc += str(seq.next(n.get('id')))
         if n.tag == 'pageCount':
             if x or y:
                 self.canvas.translate(x,y)
             self.canvas.doForm('pageCount%s' % (self.canvas._storyCount,))
             if x or y:
                 self.canvas.translate(-x,-y)
         if n.tag == 'pageNumber':
             rc += str(self.canvas.getPageNumber())
         rc += utils._process_text(self, n.tail)
     return rc.replace('\n','')
Example #4
0
 def _textual(self, node, x=0, y=0):
     text = node.text and node.text.encode('utf-8') or ''
     rc = utils._process_text(self, text)
     for n in node:
         if n.tag == 'seq':
             from reportlab.lib.sequencer import getSequencer
             seq = getSequencer()
             rc += str(seq.next(n.get('id')))
         if n.tag == 'pageCount':
             if x or y:
                 self.canvas.translate(x,y)
             self.canvas.doForm('pageCount%s' % (self.canvas._storyCount,))
             if x or y:
                 self.canvas.translate(-x,-y)
         if n.tag == 'pageNumber':
             rc += str(self.canvas.getPageNumber())
         rc += utils._process_text(self, n.tail)
     return rc.replace('\n','')
Example #5
0
    def _textual(self, node, x=0, y=0):
        text = node.text and node.text.encode("utf-8") or ""
        rc = utils._process_text(self, text)
        for n in node:
            if n.tag == "seq":
                from reportlab.lib.sequencer import getSequencer

                seq = getSequencer()
                rc += str(seq.next(n.get("id")))
            if n.tag == "pageCount":
                if x or y:
                    self.canvas.translate(x, y)
                self.canvas.doForm("pageCount%s" % (self.canvas._storyCount,))
                if x or y:
                    self.canvas.translate(-x, -y)
            if n.tag == "pageNumber":
                rc += str(self.canvas.getPageNumber())
            rc += utils._process_text(self, n.tail)
        return rc.replace("\n", "")
def paragraph_numbering():
    doc = SimpleDocTemplate("paragraph_numbering.pdf", pagesize=letter)
    styles = getSampleStyleSheet()

    flowables = []

    for item in range(1, 4):
        ptext = '<seq id="test"> thing(s)'
        para = Paragraph(ptext, style=styles["Normal"])
        flowables.append(para)

    # templates
    seq = getSequencer()
    seq.setFormat('Section', '1')
    seq.setFormat('FigureNo', 'A')

    for item in range(4, 8):
        text = 'Fig. <seq template="%(Section)s-%(FigureNo+)s"/>'
        para = Paragraph(text, style=styles["Normal"])
        flowables.append(para)

    doc.build(flowables)
Example #7
0
def picklist_to_pdf(invoice, outf):
    normal_style = ParagraphStyle("normal", fontName="Helvetica")
    piece_condition_style = ParagraphStyle("piececondition", normal_style, fontSize=normal_style.fontSize - 2,
                                           leading=normal_style.leading - 2)
    piece_details_style = ParagraphStyle("pieceseller", piece_condition_style)

    def invoice_header(canvas, doc):
        draw_invoice_header(canvas, doc, invoice, "Pick-List for:")

    doc = SimpleDocTemplate(outf, pagesize=LETTER,
                            leftMargin=0.75 * inch, rightMargin=0.75 * inch,
                            topMargin=1.75 * inch, bottomMargin=0.75 * inch,
                            onFirstPage=invoice_header, onLaterPages=invoice_header)

    story = []

    body_data = [
        ["Loc.", "Code", "\u2714", "Description", "Amount", "\u2714"],
        [Paragraph('<para align="right">Confirm Bidder ID on each sheet</para>', normal_style), "", "", "", "", "[ ]"],
    ]

    num_items = 0
    for item in invoice.invoiceitem_set.order_by("piece__location", "piece__artist__artistid", "piece__pieceid"):
        num_items += 1
        piece = item.piece
        paragraphs = [
            Paragraph("<i>" + escape(piece.name) + "</i> \u2014 by " + escape(piece.artistname()), normal_style)]
        details_body_parts = [escape(piece.media)]
        if piece.condition:
            details_body_parts.append(escape(piece.condition))
        if piece.other_artist:
            details_body_parts.append(escape("sold by " + piece.artist.artistname()))
        paragraphs.append(Paragraph(" \u2014 ".join(details_body_parts), piece_details_style))
        body_data.append([piece.location, piece.code, "[ ]", paragraphs,
                          Paragraph("<para align=\"right\"><b>" + escape(str(item.price)) + "</b></para>",
                                    normal_style),
                          "[ ]"])

    body_data.append([Paragraph('<para align="right">Confirm <b>%s</b> items, <b>%s</b> '
                                'bid-sheets, then initial</para>' % (num_items, num_items),
                                normal_style), "", "", "", "", "__"])

    body_table_style = [
        ("FONTSIZE", (0, 0), (-1, 0), normal_style.fontSize - 4),
        ("FONT", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("LEADING", (0, 0), (-1, 0), normal_style.leading - 4),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("ALIGN", (4, 0), (4, -1), "RIGHT"),
        ("SPAN", (0, 1), (4, 1)),
        ("SPAN", (0, num_items + 2), (4, num_items + 2)),
        ("LINEBELOW", (0, 0), (-1, -1), 0.1, colors.black),
        # ("GRID", (0,0), (-1,-1), 0.1, colors.black),
    ]

    body_table = Table(body_data, colWidths=[0.5 * inch, 0.75 * inch, 0.25 * inch, 4.25 * inch, 1 * inch, 0.25 * inch],
                       style=body_table_style,
                       repeatRows=1)
    story.append(body_table)
    story.append(Spacer(0.25 * inch, 0.25 * inch))

    signature_block = KeepTogether([
        Paragraph(escape("I, %s, or a duly authorized agent, acknowledge receiving the above "
                         "%d items." % (invoice.payer.name(), num_items)), normal_style),
        Spacer(0.25 * inch, 0.25 * inch),
        Paragraph("Signature _______________________________________________", normal_style),
        Spacer(0.25 * inch, 0.25 * inch),
        Paragraph("Agent Name _______________________________________________", normal_style),
    ])
    story.append(signature_block)

    # TODO - Figure out a better way of handling this horrible hack.
    # "Paragraph" does not use the sequencer inside the Document, but instead the global sequencer :(
    getSequencer().reset("pageno", 0)

    doc.build(story, onFirstPage=invoice_header, onLaterPages=invoice_header)
def restartList():
    getSequencer().reset("list1")
Example #9
0
 def __init__(self,
              filename,
              title,
              subject,
              author,
              pagesize=defaultPageSize,
              top=1,
              bottom=1,
              left=1,
              right=1,
              col=0.25):
     self.nTop, self.nBottom, self.nLeft, self.nRight, self.nCol = top, bottom, left, right, col
     self.pagesize = pagesize
     BaseDocTemplate.__init__(self, filename, pagesize=pagesize)
     if not title: title = u"Pydro Feature Report"
     if not author: author = u"NOAA"
     if not subject: subject = u"NOAA Hydrographic Survey"
     self.title, self.author, self.subject = GetUnicode(
         [title, author, subject])
     styleSheet = getSampleStyleSheet()
     styleSheet.add(ParagraphStyle(name='CenteredHeading1',
                                   parent=styleSheet['Title'],
                                   alignment=TA_CENTER),
                    alias='cenh1')
     styleSheet.add(ParagraphStyle(name='CenteredHeading2',
                                   parent=styleSheet['Heading2'],
                                   alignment=TA_CENTER),
                    alias='cenh2')
     styleSheet.add(ParagraphStyle(name='CenteredLabel2',
                                   parent=styleSheet['Heading2'],
                                   alignment=TA_CENTER),
                    alias='clab2')
     styleSheet.add(ParagraphStyle(name='FigCaption',
                                   parent=styleSheet['Italic'],
                                   alignment=TA_CENTER),
                    alias='figc')
     styleSheet.add(ParagraphStyle(name='CenteredDisc',
                                   parent=styleSheet['BodyText'],
                                   alignment=TA_CENTER),
                    alias='cend')
     self._T1 = styleSheet['Title']  # fontbasesize=18
     self._H2 = styleSheet['Heading2']  # fontbasesize=14
     self._CH1 = styleSheet['CenteredHeading1']  # fontbasesize=18
     self._CH2 = styleSheet['CenteredHeading2']  # fontbasesize=14
     self._CL2 = styleSheet['CenteredLabel2']  # fontbasesize=14
     self._FC = styleSheet['FigCaption']  # fontbasesize=10
     self._PC = copy.copy(styleSheet['FigCaption'])  # fontbasesize=10
     self._PC.name = 'PicCaption'  # not conditioned upon in afterFlowable()--for X.X.n labeling
     self._B = styleSheet['BodyText']  # fontbasesize=10
     self._CB = styleSheet['CenteredDisc']  # fontbasesize=10
     self._BU = styleSheet['Bullet']  # fontbasesize=10
     self.seq = getSequencer()
     self.seq.setFormat('Chapter', '1')  # TODO: change to 'Section'
     self.seq.reset('Chapter')
     self.seqChapter = {}
     self.seq.setFormat('Section', '1')  # TODO: change to 'SubSection'
     self.seq.reset('Section')
     self.seq.setFormat('Figure', '1')
     self.seq.reset('Figure')
     self.seqchainChapterSection = {}
     self.seq.chain('Section', 'Figure')
     self.report = {}
     self.reportOutlineLabels = {}
Example #10
0
 def restartList(self):
     getSequencer().reset('blist')
Example #11
0
#print quickfix("$testing$ testing $one$ ^two^ $three(^four^)$")



H1 = styleSheet['Heading1']
H2 = styleSheet['Heading2']
H3 = styleSheet['Heading3']
H4 = styleSheet['Heading4']
B = styleSheet['BodyText']
BU = styleSheet['Bullet']
Comment = styleSheet['Comment']
Centred = styleSheet['Centred']
Caption = styleSheet['Caption']

#set up numbering
seq = getSequencer()
seq.setFormat('Chapter','1')
seq.setFormat('Section','1')
seq.setFormat('Appendix','A')
seq.setFormat('Figure', '1')
seq.chain('Chapter','Section')
seq.chain('Chapter','Figure')

lessonnamestyle = H2
discussiontextstyle = B
exampletextstyle = styleSheet['Code']
# size for every example
examplefunctionxinches = 5.5
examplefunctionyinches = 3
examplefunctiondisplaysizes = (examplefunctionxinches*inch, examplefunctionyinches*inch)
Example #12
0
def restartList():
    getSequencer().reset('list1')
Example #13
0
def restartList():
    getSequencer().reset('list1')
Example #14
0

#print quickfix("$testing$ testing $one$ ^two^ $three(^four^)$")

H1 = styleSheet['Heading1']
H2 = styleSheet['Heading2']
H3 = styleSheet['Heading3']
H4 = styleSheet['Heading4']
B = styleSheet['BodyText']
BU = styleSheet['Bullet']
Comment = styleSheet['Comment']
Centred = styleSheet['Centred']
Caption = styleSheet['Caption']

#set up numbering
seq = getSequencer()
seq.setFormat('Chapter', '1')
seq.setFormat('Section', '1')
seq.setFormat('Appendix', 'A')
seq.setFormat('Figure', '1')
seq.chain('Chapter', 'Section')
seq.chain('Chapter', 'Figure')

lessonnamestyle = H2
discussiontextstyle = B
exampletextstyle = styleSheet['Code']
# size for every example
examplefunctionxinches = 5.5
examplefunctionyinches = 3
examplefunctiondisplaysizes = (examplefunctionxinches * inch,
                               examplefunctionyinches * inch)
Example #15
0
def invoice_to_pdf(invoice, outf):
    normal_style = ParagraphStyle("normal", fontName="Helvetica")
    piece_condition_style = ParagraphStyle("piececondition", normal_style, fontSize=normal_style.fontSize - 2,
                                           leading=normal_style.leading - 2)
    piece_details_style = ParagraphStyle("pieceseller", piece_condition_style)

    def invoice_header(canvas, doc):
        draw_invoice_header(canvas, doc, invoice, "Invoice for:")

    doc = SimpleDocTemplate(outf, pagesize=LETTER,
                            leftMargin=0.75 * inch, rightMargin=0.75 * inch,
                            topMargin=1.75 * inch, bottomMargin=0.75 * inch,
                            onFirstPage=invoice_header, onLaterPages=invoice_header)

    story = []

    body_data = [["Code", "Description", "Amount (" + settings.ARTSHOW_MONEY_CURRENCY + ")"]]

    num_items = 0
    for item in invoice.invoiceitem_set.order_by("piece__artist__artistid", "piece__pieceid"):
        num_items += 1
        piece = item.piece
        paragraphs = [
            Paragraph("<i>" + escape(piece.name) + "</i> \u2014 by " + escape(piece.artistname()), normal_style)]
        details_body_parts = [escape(piece.media)]
        if piece.condition:
            details_body_parts.append(escape(piece.condition))
        if piece.other_artist:
            details_body_parts.append(escape("sold by " + piece.artist.artistname()))
        paragraphs.append(Paragraph(" \u2014 ".join(details_body_parts), piece_details_style))
        body_data.append([item.piece.code, paragraphs, format_money(item.price)])

    if invoice.tax_paid:
        subtotal_row = len(body_data)
        body_data.append(["", "Subtotal", format_money(invoice.item_total())])
        body_data.append(["", settings.ARTSHOW_TAX_DESCRIPTION, format_money(invoice.tax_paid)])
    else:
        subtotal_row = None

    total_row = len(body_data)
    body_data.append(["", str(num_items) + " items \u2014 Total Due", format_money(invoice.item_and_tax_total())])

    body_data.append(["", "", ""])

    for payment in invoice.invoicepayment_set.all():
        body_data.append(["", payment.get_payment_method_display(), format_money(payment.amount)])

    body_data.append(["", "Total Paid", str(invoice.total_paid())])

    body_table_style = [
        ("FONTSIZE", (0, 0), (-1, 0), normal_style.fontSize - 4),
        ("FONT", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("LEADING", (0, 0), (-1, 0), normal_style.leading - 4),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("ALIGN", (2, 0), (2, -1), "RIGHT"),
        ("ALIGN", (1, total_row), (1, -1), "RIGHT"),
        ("FONT", (2, total_row), (2, total_row), "Helvetica-Bold"),
        ("FONT", (2, -1), (2, -1), "Helvetica-Bold"),
        ("LINEBELOW", (0, 0), (-1, -1), 0.1, colors.black),
        ("LINEABOVE", (0, total_row), (-1, total_row), 0.75, colors.black),
        ("LINEABOVE", (0, -1), (-1, -1), 0.75, colors.black),
    ]

    if subtotal_row is not None:
        body_table_style.append(("ALIGN", (1, subtotal_row), (1, subtotal_row + 1), "RIGHT"))
        body_table_style.append(("LINEABOVE", (0, subtotal_row), (-1, subtotal_row), 0.75, colors.black))

    body_table = Table(body_data, colWidths=[0.75 * inch, 5.0 * inch, 1.25 * inch], style=body_table_style,
                       repeatRows=1)
    story.append(body_table)

    # TODO - Figure out a better way of handling this horrible hack.
    # "Paragraph" does not use the sequencer inside the Document, but instead the global sequencer :(
    getSequencer().reset("pageno", 0)

    doc.build(story, onFirstPage=invoice_header, onLaterPages=invoice_header)
Example #16
0
def picklist_to_pdf(invoice, outf):
    normal_style = ParagraphStyle("normal", fontName="Helvetica")
    piece_condition_style = ParagraphStyle("piececondition", normal_style, fontSize=normal_style.fontSize - 2,
                                           leading=normal_style.leading - 2)
    piece_details_style = ParagraphStyle("pieceseller", piece_condition_style)

    def invoice_header(canvas, doc):
        draw_invoice_header(canvas, doc, invoice, "Pick-List for:")

    doc = SimpleDocTemplate(outf, pagesize=LETTER,
                            leftMargin=0.75 * inch, rightMargin=0.75 * inch,
                            topMargin=1.75 * inch, bottomMargin=0.75 * inch,
                            onFirstPage=invoice_header, onLaterPages=invoice_header)

    story = []

    body_data = [
        ["Loc.", "Code", u"\u2714", "Description", "Amount", u"\u2714"],
        [Paragraph('<para align="right">Confirm Bidder ID on each sheet</para>', normal_style), "", "", "", "", u"[ ]"],
    ]

    num_items = 0
    for item in invoice.invoiceitem_set.order_by("piece__location", "piece__artist__artistid", "piece__pieceid"):
        num_items += 1
        piece = item.piece
        paragraphs = [
            Paragraph("<i>" + escape(piece.name) + u"</i> \u2014 by " + escape(piece.artistname()), normal_style)]
        details_body_parts = [escape(piece.media)]
        if piece.condition:
            details_body_parts.append(escape(piece.condition))
        if piece.other_artist:
            details_body_parts.append(escape("sold by " + piece.artist.artistname()))
        paragraphs.append(Paragraph(u" \u2014 ".join(details_body_parts), piece_details_style))
        body_data.append([piece.location, piece.code, u"[ ]", paragraphs,
                          Paragraph("<para align=\"right\"><b>" + escape(str(item.price)) + "</b></para>",
                                    normal_style),
                          u"[ ]"])

    body_data.append([Paragraph('<para align="right">Confirm <b>%s</b> items, <b>%s</b> '
                                'bid-sheets, then initial</para>' % (num_items, num_items),
                                normal_style), "", "", "", "", "__"])

    body_table_style = [
        ("FONTSIZE", (0, 0), (-1, 0), normal_style.fontSize - 4),
        ("FONT", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("LEADING", (0, 0), (-1, 0), normal_style.leading - 4),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("ALIGN", (4, 0), (4, -1), "RIGHT"),
        ("SPAN", (0, 1), (4, 1)),
        ("SPAN", (0, num_items + 2), (4, num_items + 2)),
        ("LINEBELOW", (0, 0), (-1, -1), 0.1, colors.black),
        #("GRID", (0,0), (-1,-1), 0.1, colors.black),
    ]

    body_table = Table(body_data, colWidths=[0.5 * inch, 0.75 * inch, 0.25 * inch, 4.25 * inch, 1 * inch, 0.25 * inch],
                       style=body_table_style,
                       repeatRows=1)
    story.append(body_table)
    story.append(Spacer(0.25 * inch, 0.25 * inch))

    signature_block = KeepTogether([
        Paragraph(escape("I, %s, or a duly authorized agent, acknowledge receiving the above "
                         "%d items." % (invoice.payer.name(), num_items)), normal_style),
        Spacer(0.25 * inch, 0.25 * inch),
        Paragraph("Signature _______________________________________________", normal_style),
        Spacer(0.25 * inch, 0.25 * inch),
        Paragraph("Agent Name _______________________________________________", normal_style),
    ])
    story.append(signature_block)


    # TODO - Figure out a better way of handling this horrible hack.
    # "Paragraph" does not use the sequencer inside the Document, but instead the global sequencer :(
    getSequencer().reset("pageno", 0)

    doc.build(story, onFirstPage=invoice_header, onLaterPages=invoice_header)
Example #17
0
def invoice_to_pdf(invoice, outf):
    normal_style = ParagraphStyle("normal", fontName="Helvetica")
    piece_condition_style = ParagraphStyle("piececondition", normal_style, fontSize=normal_style.fontSize - 2,
                                           leading=normal_style.leading - 2)
    piece_details_style = ParagraphStyle("pieceseller", piece_condition_style)

    def invoice_header(canvas, doc):
        draw_invoice_header(canvas, doc, invoice, "Invoice for:")

    doc = SimpleDocTemplate(outf, pagesize=LETTER,
                            leftMargin=0.75 * inch, rightMargin=0.75 * inch,
                            topMargin=1.75 * inch, bottomMargin=0.75 * inch,
                            onFirstPage=invoice_header, onLaterPages=invoice_header)

    story = []

    body_data = [["Code", "Description", "Amount (" + settings.ARTSHOW_MONEY_CURRENCY + ")"]]

    num_items = 0
    for item in invoice.invoiceitem_set.order_by("piece__artist__artistid", "piece__pieceid"):
        num_items += 1
        piece = item.piece
        paragraphs = [
            Paragraph("<i>" + escape(piece.name) + u"</i> \u2014 by " + escape(piece.artistname()), normal_style)]
        details_body_parts = [escape(piece.media)]
        if piece.condition:
            details_body_parts.append(escape(piece.condition))
        if piece.other_artist:
            details_body_parts.append(escape("sold by " + piece.artist.artistname()))
        paragraphs.append(Paragraph(u" \u2014 ".join(details_body_parts), piece_details_style))
        body_data.append([item.piece.code, paragraphs, format_money(item.price)])

    if invoice.tax_paid:
        subtotal_row = len(body_data)
        body_data.append(["", "Subtotal", format_money(invoice.item_total())])
        body_data.append(["", settings.ARTSHOW_TAX_DESCRIPTION, format_money(invoice.tax_paid)])
    else:
        subtotal_row = None

    total_row = len(body_data)
    body_data.append(["", str(num_items) + u" items \u2014 Total Due", format_money(invoice.item_and_tax_total())])

    body_data.append(["", "", ""])

    for payment in invoice.invoicepayment_set.all():
        body_data.append(["", payment.get_payment_method_display(), format_money(payment.amount)])

    body_data.append(["", "Total Paid", unicode(invoice.total_paid())])

    body_table_style = [
        ("FONTSIZE", (0, 0), (-1, 0), normal_style.fontSize - 4),
        ("FONT", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("LEADING", (0, 0), (-1, 0), normal_style.leading - 4),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("ALIGN", (2, 0), (2, -1), "RIGHT"),
        ("ALIGN", (1, total_row), (1, -1), "RIGHT"),
        ("FONT", (2, total_row), (2, total_row), "Helvetica-Bold"),
        ("FONT", (2, -1), (2, -1), "Helvetica-Bold"),
        ("LINEBELOW", (0, 0), (-1, -1), 0.1, colors.black),
        ("LINEABOVE", (0, total_row), (-1, total_row), 0.75, colors.black),
        ("LINEABOVE", (0, -1), (-1, -1), 0.75, colors.black),
    ]

    if subtotal_row is not None:
        body_table_style.append(("ALIGN", (1, subtotal_row), (1, subtotal_row + 1), "RIGHT"))
        body_table_style.append(("LINEABOVE", (0, subtotal_row), (-1, subtotal_row), 0.75, colors.black))

    body_table = Table(body_data, colWidths=[0.75 * inch, 5.0 * inch, 1.25 * inch], style=body_table_style,
                       repeatRows=1)
    story.append(body_table)

    # TODO - Figure out a better way of handling this horrible hack.
    # "Paragraph" does not use the sequencer inside the Document, but instead the global sequencer :(
    getSequencer().reset("pageno", 0)

    doc.build(story, onFirstPage=invoice_header, onLaterPages=invoice_header)