def gather_elements(self, client, node, style):
        if isinstance(node.parent, docutils.nodes.authors):
            # Is only one of multiple authors. Return a paragraph
            node.elements = [
                Paragraph(client.gather_pdftext(node), style=style)
            ]
            if client.doc_author:
                client.doc_author += client.author_separator(style=style) \
                    + node.astext().strip()
            else:
                client.doc_author = node.astext().strip()
        else:
            # A single author: works like a field
            fb = client.gather_pdftext(node)

            t_style = TableStyle(client.styles['field-list'].commands)
            colWidths = list(
                map(client.styles.adjustUnits,
                    client.styles['field-list'].colWidths))

            node.elements = [
                Table([[
                    Paragraph(client.text_for_label("author", style) + ":",
                              style=client.styles['fieldname']),
                    Paragraph(fb, style)
                ]],
                      style=t_style,
                      colWidths=colWidths)
            ]
            client.doc_author = node.astext().strip()
        return node.elements
    def gather_elements(self, client, node, style):
        odd = []
        even = []
        # from pudb import set_trace; set_trace()
        if node.children:
            if isinstance(node.children[0], docutils.nodes.paragraph):
                if node.children[0].get('classes'):
                    s = client.styles[node.children[0].get('classes')[0]]
                else:
                    s = style
                odd = [Paragraph(client.gather_pdftext(node.children[0]), s)]
            else:
                # A compound element
                odd = client.gather_elements(node.children[0])
        if len(node.children) > 1:
            if isinstance(node.children[1], docutils.nodes.paragraph):
                if node.children[1].get('classes'):
                    s = client.styles[node.children[1].get('classes')[0]]
                else:
                    s = style
                even = [Paragraph(client.gather_pdftext(node.children[1]), s)]
            else:
                even = client.gather_elements(node.children[1])

        return [OddEven(odd=odd, even=even)]
    def gather_elements(self, client, node, style):
        # Special cases: (Not sure this is right ;-)
        if isinstance(node.parent, docutils.nodes.document):
            # node.elements = [Paragraph(client.gen_pdftext(node),
            # client.styles['title'])]
            # The visible output is now done by the cover template
            node.elements = []
            client.doc_title = node.rawsource
            client.doc_title_clean = node.astext().strip()
        elif isinstance(node.parent, docutils.nodes.topic):
            node.elements = [
                Paragraph(client.gen_pdftext(node),
                          client.styles['topic-title'])
            ]
        elif isinstance(node.parent, docutils.nodes.Admonition):
            node.elements = [
                Paragraph(client.gen_pdftext(node),
                          client.styles['admonition-title'])
            ]
        elif isinstance(node.parent, docutils.nodes.table):
            node.elements = [
                Paragraph(client.gen_pdftext(node),
                          client.styles['table-title'])
            ]
        elif isinstance(node.parent, docutils.nodes.sidebar):
            node.elements = [
                Paragraph(client.gen_pdftext(node),
                          client.styles['sidebar-title'])
            ]
        else:
            # Section/Subsection/etc.
            text = client.gen_pdftext(node)
            fch = node.children[0]
            if isinstance(fch, docutils.nodes.generated) and \
                fch['classes'] == ['sectnum']:
                snum = fch.astext()
            else:
                snum = None
            key = node.get('refid')
            maxdepth = 6

            # The parent ID is the refid + an ID to make it unique for Sphinx
            parent_id = (node.parent.get('ids', [None])
                         or [None])[0] + '-' + str(id(node))
            node.elements = [
                Heading(text,
                        client.styles['heading%d' %
                                      min(client.depth, maxdepth)],
                        level=client.depth - 1,
                        parent_id=parent_id,
                        node=node,
                        section_header_depth=client.section_header_depth)
            ]
            if client.depth <= client.breaklevel:
                node.elements.insert(0, MyPageBreak(breakTo=client.breakside))
        return node.elements
    def gather_elements(self, client, node, style):
        # It seems a footnote contains a label and a series of elements
        ltext = client.gather_pdftext(node.children[0])
        label = None
        ids = ''
        for i in node.get('ids', []):
            ids += '<a name="%s"/>' % (i)
        client.targets.extend(node.get('ids', [ltext]))

        if len(node['backrefs']) > 1 and client.footnote_backlinks:
            backrefs = []
            i = 1
            for r in node['backrefs']:
                backrefs.append('<a href="#%s" color="%s">%d</a>' %
                                (r, client.styles.linkColor, i))
                i += 1
            backrefs = '(%s)' % ', '.join(backrefs)
            if ltext not in client.targets:
                label = Paragraph(ids + '%s' % (ltext + backrefs),
                                  client.styles["endnote"])
                client.targets.append(ltext)
        elif len(node['backrefs']) == 1 and client.footnote_backlinks:
            if ltext not in client.targets:
                label = Paragraph(
                    ids + '<a href="%s" color="%s">%s</a>' %
                    (node['backrefs'][0], client.styles.linkColor, ltext),
                    client.styles["endnote"])
                client.targets.append(ltext)
        else:
            if ltext not in client.targets:
                label = Paragraph(ids + ltext, client.styles["endnote"])
                client.targets.append(ltext)
        if not label:
            label = Paragraph(ids + ltext, client.styles["endnote"])
        contents = client.gather_elements(node, client.styles["endnote"])[1:]
        if client.inline_footnotes:
            st = client.styles['endnote']
            t_style = TableStyle(st.commands)
            colWidths = client.styles['endnote'].colWidths
            node.elements = [
                MySpacer(0, st.spaceBefore),
                DelayedTable([[label, contents]],
                             style=t_style,
                             colWidths=colWidths),
                MySpacer(0, st.spaceAfter)
            ]
            if client.real_footnotes:
                client.mustMultiBuild = True
                for e in node.elements:
                    e.isFootnote = True
        else:
            client.decoration['endnotes'].append([label, contents])
            node.elements = []
        return node.elements
    def wrap(self, availWidth, availHeight):
        """
        Adds hyperlink to toc entry.
        """
        widths = (availWidth - self.rightColumnWidth,
                  self.rightColumnWidth)
        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [(0, 'Placeholder for table of contents',
                             0, None)]
        else:
            _tempEntries = self._lastEntries

        if _tempEntries:
            base_level = _tempEntries[0][0]
        else:
            base_level = 0
        tableData = []
        for entry in _tempEntries:
            level, text, pageNum = entry[:3]
            left_col_level = level - base_level
            leftColStyle = self.getLevelStyle(left_col_level)
            label = self.refid_lut.get((level, text, pageNum), None)
            if label:
                pre = '<a href="%s" color="%s">' % (label, self.linkColor)
                post = '</a>'
                if not isinstance(text, str):
                    text = str(text, 'utf-8')
                text = pre + text + post
            else:
                pre = ''
                post = ''
            # right col style is right aligned
            rightColStyle = ParagraphStyle(
                name='leftColLevel%d' % left_col_level,
                parent=leftColStyle,
                leftIndent=0,
                alignment=TA_RIGHT
            )
            leftPara = Paragraph(text, leftColStyle)
            rightPara = Paragraph(pre + str(pageNum) + post, rightColStyle)
            tableData.append([leftPara, rightPara])

        self._table = Table(tableData, colWidths=widths, style=self.tableStyle)

        self.width, self.height = self._table.wrapOn(self.canv, availWidth, availHeight)
        return self.width, self.height
 def gather_elements(self, client, node, style):
     fb = client.gather_pdftext(node)
     t_style = TableStyle(client.styles['field-list'].commands)
     colWidths = client.styles['field-list'].colWidths
     if self.adjustwidths:
         colWidths = list(map(client.styles.adjustUnits, colWidths))
     label = client.text_for_label(self.labeltext, style) + ":"
     t = self.TableType([[
         Paragraph(label, style=client.styles['fieldname']),
         Paragraph(fb, style)
     ]],
                        style=t_style,
                        colWidths=colWidths)
     return [t]
    def draw(self):
        # Add outline entry
        self.canv.bookmarkHorizontal(self.parent_id, 0, 0 + self.height)
        # self.section_header_depth is for Issue 391
        if self.canv.firstSect and self.level < self.section_header_depth:
            self.canv.sectName = self.stext
            self.canv.firstSect = False
            if self.snum is not None:
                self.canv.sectNum = self.snum
            else:
                self.canv.sectNum = ""

        self.canv.addOutlineEntry(self.stext.encode('utf-8', 'replace'),
                                  self.parent_id.encode('utf-8', 'replace'),
                                  int(self.level), False)
        Paragraph.draw(self)
 def gather_elements(self, client, node, style):
     # Sphinx uses a rubric as footnote container
     if self.sphinxmode and len(node.children) == 1 \
         and node.children[0].astext() == 'Footnotes':
         return []
     else:
         return [
             Paragraph(client.gather_pdftext(node), client.styles['rubric'])
         ]
    def gather_elements(self, client, node, style):
        # Multiple authors. Create a two-column table.
        # Author references on the right.
        t_style = TableStyle(client.styles['field-list'].commands)
        colWidths = client.styles['field-list'].colWidths

        td = [[
            Paragraph(client.text_for_label("authors", style) + ":",
                      style=client.styles['fieldname']),
            client.gather_elements(node, style=style)
        ]]
        return [DelayedTable(td, style=t_style, colWidths=colWidths)]
    def gather_elements(self, client, node, style):
        # I need to catch the classifiers here
        tt = []
        dt = []
        ids = []
        for n in node.children:
            if isinstance(n, docutils.nodes.term):
                for i in n['ids']:  # Used by sphinx glossary lists
                    if i not in client.targets:
                        ids.append('<a name="%s"/>' % i)
                        client.targets.append(i)
                o, c = client.styleToTags("definition-list-term")
                tt.append(o + client.gather_pdftext(n) + c)
            elif isinstance(n, docutils.nodes.classifier):
                o, c = client.styleToTags("definition-list-classifier")
                tt.append(o + client.gather_pdftext(n) + c)
            else:
                dt.extend(client.gen_elements(n, style))

        # FIXME: make this configurable from the stylesheet
        t_style = TableStyle(client.styles['definition'].commands)
        cw = getattr(client.styles['definition'], 'colWidths', [])

        if client.splittables:
            node.elements = [
                Paragraph(''.join(ids) + ' : '.join(tt),
                          client.styles['definition-list-term']),
                SplitTable([['', dt]], colWidths=cw, style=t_style)
            ]
        else:
            node.elements = [
                Paragraph(''.join(ids) + ' : '.join(tt),
                          client.styles['definition-list-term']),
                DelayedTable([['', dt]], colWidths=[10, None], style=t_style)
            ]

        return node.elements
    def gather_elements(self, client, node, style):
        # A field has two child elements, a field_name and a field_body.
        # We render as a two-column table, left-column is right-aligned,
        # bold, and much smaller

        fn = Paragraph(client.gather_pdftext(node.children[0]) + ":",
                       style=client.styles['fieldname'])
        fb = client.gen_elements(node.children[1],
                                 style=client.styles['fieldvalue'])
        t_style = TableStyle(client.styles['field-list'].commands)
        return [
            DelayedTable([[fn, fb]],
                         style=t_style,
                         colWidths=client.styles['field-list'].colWidths)
        ]
    def gather_elements(self, client, node, style):
        # line nodes have no classes, they have to inherit from the outermost lineblock (sigh)
        # For more info see Issue 471 and its test case.

        parent = node
        while isinstance(parent.parent,
                         (docutils.nodes.line, docutils.nodes.line_block)):
            parent = parent.parent
        p_class = (parent.get('classes') or ['line'])[0]
        qstyle = copy(client.styles[p_class])
        # Indent .5em per indent unit
        i = node.__dict__.get('indent', 0)
        # qstyle = copy(client.styles['line'])
        qstyle.leftIndent += client.styles.adjustUnits("0.5em") * i
        text = client.gather_pdftext(node)
        if not text:  # empty line
            text = "<nobr>\xa0</nobr>"
        return [Paragraph(text, style=qstyle)]
 def gather_elements(self, client, node, style):
     if isinstance(node.parent, docutils.nodes.sidebar):
         elements = [
             Paragraph(client.gen_pdftext(node),
                       client.styles['sidebar-subtitle'])
         ]
     elif isinstance(node.parent, docutils.nodes.document):
         # elements = [Paragraph(client.gen_pdftext(node),
         # client.styles['subtitle'])]
         # The visible output is now done by the cover template
         elements = []
         # FIXME: looks like subtitles don't have a rawsource like
         # titles do.
         # That means that literals and italics etc in subtitles won't
         # work.
         client.doc_subtitle = getattr(node, 'rawtext',
                                       node.astext()).strip()
     else:
         elements = node.elements  # FIXME Can we get here???
     return elements
    def gather_elements(self, client, node, style):
        # toc
        node_classes = node.attributes.get('classes', [])
        cstyles = client.styles
        if 'contents' in node_classes:
            toc_visitor = TocBuilderVisitor(node.document)
            if 'local' in node_classes:
                toc_visitor.toc = MyTableOfContents(parent=node.parent)
            else:
                toc_visitor.toc = MyTableOfContents(parent=None)
            toc_visitor.toc.linkColor = cstyles.tocColor or cstyles.linkColor
            node.walk(toc_visitor)
            toc = toc_visitor.toc
            toc.levelStyles = [cstyles['toc%d' % l] for l in range(1, 15)]
            for s in toc.levelStyles:
                # FIXME: awful slimy hack!
                s.__class__ = reportlab.lib.styles.ParagraphStyle
            # # Issue 117: add extra TOC levelStyles.
            # # 9-deep should be enough.
            # for i in range(4):
            # ps = toc.levelStyles[-1].__class__(name='Level%d'%(i+5),
            # parent=toc.levelStyles[-1],
            # leading=toc.levelStyles[-1].leading,
            # firstlineIndent=toc.levelStyles[-1].firstLineIndent,
            # leftIndent=toc.levelStyles[-1].leftIndent+1*cm)
            # toc.levelStyles.append(ps)

            # # Override fontnames (defaults to Times-Roman)
            # for levelStyle in toc.levelStyles:
            # levelStyle.__dict__['fontName'] = \
            # client.styles['tableofcontents'].fontName
            if 'local' in node_classes:
                node.elements = [toc]
            else:
                node.elements = \
                    [Paragraph(client.gen_pdftext(node.children[0]),
                    cstyles['heading1']), toc]
        else:
            node.elements = client.gather_elements(node, style=style)
        return node.elements
    def gather_elements(self, client, node, style):
        if node.children and isinstance(node.children[0],
                                        docutils.nodes.title):
            title = []
        else:
            title = [
                Paragraph(client.text_for_label(node.tagname, style),
                          style=client.styles['%s-heading' % node.tagname])
            ]
        rows = title + client.gather_elements(node, style=style)
        st = client.styles[node.tagname]
        if 'commands' in dir(st):
            t_style = TableStyle(st.commands)
        else:
            t_style = TableStyle()
        t_style.add("ROWBACKGROUNDS", [0, 0], [-1, -1], [st.backColor])
        t_style.add("BOX", [0, 0], [-1, -1], st.borderWidth, st.borderColor)

        if client.splittables:
            node.elements = [
                MySpacer(0, st.spaceBefore),
                SplitTable([['', rows]],
                           style=t_style,
                           colWidths=[0, None],
                           padding=st.borderPadding),
                MySpacer(0, st.spaceAfter)
            ]
        else:
            padding, p1, p2, p3, p4 = tablepadding(padding=st.borderPadding)
            t_style.add(*p1)
            t_style.add(*p2)
            t_style.add(*p3)
            t_style.add(*p4)
            node.elements = [
                MySpacer(0, st.spaceBefore),
                DelayedTable([['', rows]], style=t_style, colWidths=[0, None]),
                MySpacer(0, st.spaceAfter)
            ]
        return node.elements
 def gather_elements(self, client, node, style):
     return [Paragraph(client.gather_pdftext(node), style)]
 def gather_elements(self, client, node, style):
     return [
         Paragraph(client.gather_pdftext(node),
                   style=client.styles['figure-caption'])
     ]
 def gather_elements(self, client, node, style):
     return [
         Paragraph(client.gather_pdftext(node),
                   client.styles['attribution'])
     ]
    def gather_elements(self, client, node, style):
        # This method is copied from the HandleTitle class
        # in structural_dhcp_rst2pdf.genelements.

        # Special cases: (Not sure this is right ;-)
        if isinstance(node.parent, docutils.nodes.document):
            # node.elements = [Paragraph(client.gen_pdftext(node),
                                        # client.styles['title'])]
            # The visible output is now done by the cover template
            node.elements = []
            client.doc_title = node.rawsource
            client.doc_title_clean = node.astext().strip()
        elif isinstance(node.parent, docutils.nodes.topic):
            node.elements = [Paragraph(client.gen_pdftext(node),
                                       client.styles['topic-title'])]
        elif isinstance(node.parent, docutils.nodes.Admonition):
            node.elements = [Paragraph(client.gen_pdftext(node),
                                       client.styles['admonition-title'])]
        elif isinstance(node.parent, docutils.nodes.table):
            node.elements = [Paragraph(client.gen_pdftext(node),
                                       client.styles['table-title'])]
        elif isinstance(node.parent, docutils.nodes.sidebar):
            node.elements = [Paragraph(client.gen_pdftext(node),
                                       client.styles['sidebar-title'])]
        else:
            # Section/Subsection/etc.
            text = client.gen_pdftext(node)
            fch = node.children[0]
            if isinstance(fch, docutils.nodes.generated) and \
                    fch['classes'] == ['sectnum']:
                snum = fch.astext()
            else:
                snum = None
            maxdepth = 6

            # The parent ID is the refid + an ID to make it unique for Sphinx
            parent_id = (node.parent.get('ids', [None]) or
                         [None])[0] + '-' + str(id(node))
            if client.depth > 1:
                node.elements = [ Heading(text,
                        client.styles['heading%d' % min(client.depth, maxdepth)],
                        level=client.depth - 1,
                        parent_id=parent_id,
                        node=node,
                        )]
            else:  # This is an important title, do our magic ;-)
                # Hack the title template SVG
                tfile = codecs.open('titletemplate.svg', 'r', 'utf-8')
                tdata = tfile.read()
                tfile.close()
                tfile = tempfile.NamedTemporaryFile(dir='.', delete=False,
                                                    suffix='.svg')
                tfname = tfile.name
                tfile.write(tdata.replace('TITLEGOESHERE', text).encode('utf-8'))
                tfile.close()
                # Now tfname contains a SVG with the right title.
                # Make structural_dhcp_rst2pdf delete it later.
                client.to_unlink.append(tfname)
                e = FancyHeading(
                    tfname,
                    width=700,
                    height=100,
                    client=client,
                    snum=snum,
                    parent_id=parent_id,
                    text=text,
                    hstyle=client.styles['heading%d' % min(client.depth,
                                                           maxdepth)]
                )
                node.elements = [e]

            if client.depth <= client.breaklevel:
                node.elements.insert(0, MyPageBreak(breakTo=client.breakside))
        return node.elements
    def gather_elements(self, client, node, style):
        b, t = client.bullet_for_node(node)

        bStyle = copy(style)
        bStyle.alignment = 2

        # FIXME: use different unicode bullets depending on b
        if b and b in "*+-":
            b = getattr(bStyle, 'bulletText', '\u2022')

        # The style has information about the bullet:
        #
        # bulletFontSize
        # bulletFont
        # This is so the baselines of the bullet and the text align
        extra_space = bStyle.bulletFontSize - bStyle.fontSize

        bStyle.fontSize = bStyle.bulletFontSize
        bStyle.fontName = bStyle.bulletFontName

        if t == 'bullet':
            item_st = client.styles['bullet-list-item']
        else:
            item_st = client.styles['item-list-item']

        el = client.gather_elements(node, item_st)
        # FIXME: this is really really not good code
        if not el:
            el = [Paragraph("<nobr>\xa0</nobr>", item_st)]

        idx = node.parent.children.index(node)
        if idx == 0:
            # The first item in the list, so doesn't need
            # separation (it's provided by the list itself)
            sb = 0
            # It also doesn't need a first-line-indent
            fli = 0
        else:
            # Not the first item, so need to separate from
            # previous item. Account for space provided by
            # the item's content, too.
            sb = item_st.spaceBefore - item_st.spaceAfter
            fli = item_st.firstLineIndent

        bStyle.spaceBefore = 0

        t_style = TableStyle(style.commands)
        # The -3 here is to compensate for padding, 0 doesn't work :-(
        t_style._cmds.extend([
            # ["GRID", [ 0, 0 ], [ -1, -1 ], .25, "black" ],
            ["BOTTOMPADDING", [0, 0], [-1, -1], -3]
        ])
        if extra_space > 0:
            # The bullet is larger, move down the item text
            sb += extra_space
            sbb = 0
        else:
            # The bullet is smaller, move down the bullet
            sbb = -extra_space

        # colWidths = map(client.styles.adjustUnits,
        # client.styles['item_list'].colWidths)
        colWidths = getattr(style, 'colWidths', [])
        while len(colWidths) < 2:
            colWidths.append(
                client.styles['item_list'].colWidths[len(colWidths)])

        if client.splittables:
            node.elements = [
                MySpacer(0, sb),
                SplitTable([[Paragraph(b, style=bStyle), el]],
                           style=t_style,
                           colWidths=colWidths)
            ]
        else:
            node.elements = [
                MySpacer(0, sb),
                DelayedTable([[Paragraph(b, style=bStyle), el]],
                             style=t_style,
                             colWidths=colWidths)
            ]
        return node.elements