def test_ParagraphPropertySet(self): left = ParagraphPropertySet(ParagraphPropertySet.LEFT) center = left.Copy() center.Alignment = ParagraphPropertySet.CENTER # Confirm that the copies are independent objects. assert left.Alignment == ParagraphPropertySet.LEFT assert center.Alignment == ParagraphPropertySet.CENTER
def make_headerFooterDiffPagesAndSections(): doc = Document() ss = doc.StyleSheet section = Section() doc.Sections.append(section) section.FirstHeader.append('This is the header for the first page.') section.FirstFooter.append('This is the footer for the first page.') section.Header.append( 'This is the header that will appear on subsequent pages.') section.Footer.append( 'This is the footer that will appear on subsequent pages.') p = Paragraph(ss.ParagraphStyles.Heading1) p.append('Example 7') section.append(p) p = Paragraph(ss.ParagraphStyles.Normal) p.append( 'This document has different headers and footers for the first and then subsequent pages. ' 'If you insert a page break you should see a different header and footer.' ) section.append(p) p = Paragraph(ss.ParagraphStyles.Normal, ParagraphPropertySet().SetPageBreakBefore(True)) p.append('This should be page 2 ' 'with the subsequent headers and footers.') section.append(p) section = Section(break_type=Section.PAGE, first_page_number=1) doc.Sections.append(section) section.FirstHeader.append( 'This is the header for the first page of the second section.') section.FirstFooter.append( 'This is the footer for the first page of the second section.') section.Header.append( 'This is the header that will appear on subsequent pages for the second section.' ) p = Paragraph( 'This is the footer that will appear on subsequent pages for the second section.', LINE) p.append(PAGE_NUMBER, ' of ', SECTION_PAGES) section.Footer.append(p) section.append('This is the first page') p = Paragraph(ParagraphPropertySet().SetPageBreakBefore(True), 'This is the second page') section.append(p) return doc
def addConsultationBox(self, section, document): """ Add the consultation box that needs to be signed by the employer and workers. """ ss = document.StyleSheet styles = document.StyleSheet.ParagraphStyles thin_edge = BorderPropertySet(width=20, style=BorderPropertySet.SINGLE) t = lambda txt: "".join([ "\u%s?" % str(ord(e)) for e in translate(txt, context=self.request) ]) table = Table(9500) thin_edge = BorderPropertySet(width=20, style=BorderPropertySet.SINGLE) no_edge = BorderPropertySet(width=0, colour=ss.Colours.White) p = Paragraph( styles.Heading3, ParagraphPropertySet(alignment=ParagraphPropertySet.CENTER), t( _("header_oira_report_consultation", default="Consultation of workers"))) c = Cell(p, FramePropertySet(thin_edge, thin_edge, no_edge, thin_edge)) table.AddRow(c) p = Paragraph( styles.Normal, ParagraphPropertySet(alignment=ParagraphPropertySet.LEFT), t( _("paragraph_oira_consultation_of_workers", default="The undersigned hereby declare that the workers " "have been consulted on the content of this " "document.")), LINE) c = Cell(p, FramePropertySet(no_edge, thin_edge, no_edge, thin_edge)) table.AddRow(c) p = Paragraph( styles.Normal, ParagraphPropertySet(alignment=ParagraphPropertySet.LEFT), ) employer = t( _("oira_consultation_employer", default="On behalf of the employer:")) workers = t( _("oira_consultation_workers", default="On behalf of the workers:")) p.append(employer, TAB, TAB, TAB, TAB, workers, LINE, LINE) c = Cell(p, FramePropertySet(no_edge, thin_edge, no_edge, thin_edge)) table.AddRow(c) p = Paragraph( ParagraphPropertySet(alignment=ParagraphPropertySet.LEFT), t(_("oira_survey_date", default="Date:")), LINE, LINE) c = Cell(p, FramePropertySet(no_edge, thin_edge, thin_edge, thin_edge)) table.AddRow(c) section.append(table)
def make_paraTabs(): doc, section, styles = RTFTestCase.initializeDoc() p = Paragraph() p.append( 'The paragraph itself can also be overridden in lots of ways: ' 'tabs, borders, alignment, etc., can all be modified either in ' 'the style or as an override during the creation of the ' 'paragraph. This is demonstrated below with custom tab widths ' 'and embedded carriage returns (i.e., new line markers that do ' 'not cause a paragraph break).') section.append(p) tabs = [ TabPropertySet(width=TabPropertySet.DEFAULT_WIDTH), TabPropertySet(width=TabPropertySet.DEFAULT_WIDTH * 2), TabPropertySet(width=TabPropertySet.DEFAULT_WIDTH)] para_props = ParagraphPropertySet(tabs=tabs) p = Paragraph(styles.ParagraphStyles.Normal, para_props) p.append( 'Phrase at Left Tab', TAB, 'Middle Phrase One', TAB, 'Right Phrase', LINE, 'Second Left Phrase', TAB, 'Middle Phrase Two', TAB, 'Another Right Phrase' ) section.append(p) return doc
def _makePara(name): tabs = TabPropertySet( section.TwipsToRightMargin(), alignment=TabPropertySet.RIGHT, leader=getattr(TabPropertySet, name.upper().replace(' ', '_'))) para_props = ParagraphPropertySet(tabs=[tabs]) return Paragraph(styles.ParagraphStyles.Normal, para_props)
def make_tableVerticalCellMerge(): doc, section, styles = RTFTestCase.initializeDoc() section.append('Table with Vertical Cells Merged') table = Table(TableTestCase.col1, TableTestCase.col2, TableTestCase.col3) table.AddRow(Cell('A-one'), Cell('A-two', vertical_merge=True), Cell('A-three')) table.AddRow(Cell('A-one'), Cell(vertical_merge=True), Cell('A-three')) table.AddRow(Cell('A-one'), Cell('A-two', start_vertical_merge=True), Cell('A-three')) table.AddRow(Cell('A-one'), Cell(vertical_merge=True), Cell('A-three')) table.AddRow( Cell(Paragraph( ParagraphPropertySet(alignment=ParagraphPropertySet.CENTER), 'SPREAD'), span=3)) table.AddRow(Cell('A-one'), Cell('A-two', vertical_merge=True), Cell('A-three')) table.AddRow(Cell('A-one'), Cell(vertical_merge=True), Cell('A-three')) table.AddRow(Cell('A-one'), Cell('A-two', start_vertical_merge=True), Cell('A-three')) table.AddRow(Cell('A-one'), Cell(vertical_merge=True), Cell('A-three')) section.append(table) return doc
def make_spaceBetweenLines(): doc, section, styles = RTFTestCase.initializeDoc() para_props = ParagraphPropertySet() quarterInch = 1440/2 para_props.SetSpaceBetweenLines(quarterInch) p = Paragraph(para_props) p.append( 'Paragraph One', LINE, 'Second line', LINE, 'Third line', ) section.append(p) para_props = ParagraphPropertySet() para_props.SetSpaceBetweenLines(-quarterInch) p = Paragraph(para_props) p.append( 'Paragraph Two', LINE, 'Second line', LINE, 'Third line', ) section.append(p) return doc
def make_paraIndents(): doc, section, styles = RTFTestCase.initializeDoc() section.append( 'The paragraphs below demonstrate the flexibility , the following is all at the ' 'same indent level and the one after it has the first line at a ' 'different indent to the rest. The third has the first line ' 'going in the other direction and is also separated by a page ' 'break. Note that the FirstLineIndent is defined as being the ' 'difference from the LeftIndent.') creditURL = 'http://www.shakespeare-online.com/plots/1kh4ps.html' section.append('(Paragraph text from %s.)' % creditURL) sampleParagraph = """The play opens one year after the death of Richard II, and King Henry is making plans for a crusade to the Holy Land to cleanse himself of the guilt he feels over the usurpation of Richard's crown. But the crusade must be postponed when Henry learns that Welsh rebels, led by Owen Glendower, have defeated and captured Mortimer. Although the brave Henry Percy, nicknamed Hotspur, has quashed much of the uprising, there is still much trouble in Scotland. King Henry has a deep admiration for Hotspur and he longs for his own son, Prince Hal, to display some of Hotspur's noble qualities. Hal is more comfortable in a tavern than on the battlefield, and he spends his days carousing with riff-raff in London. But King Henry also has his problems with the headstrong Hotspur, who refuses to turn over his prisoners to the state as he has been so ordered. Westmoreland tells King Henry that Hotspur has many of the traits of his uncle, Thomas Percy, the Earl of Worcester, and defying authority runs in the family.""" sampleParagraph = re.sub('\s+', ' ', sampleParagraph) para_props = ParagraphPropertySet() para_props.SetLeftIndent(TabPropertySet.DEFAULT_WIDTH * 3) p = Paragraph(styles.ParagraphStyles.Normal, para_props) p.append(sampleParagraph) section.append(p) para_props = ParagraphPropertySet() para_props.SetFirstLineIndent(TabPropertySet.DEFAULT_WIDTH * -2) para_props.SetLeftIndent(TabPropertySet.DEFAULT_WIDTH * 3) p = Paragraph(styles.ParagraphStyles.Normal, para_props) p.append(sampleParagraph) section.append(p) para_props = ParagraphPropertySet() para_props.SetFirstLineIndent(TabPropertySet.DEFAULT_WIDTH) para_props.SetLeftIndent(TabPropertySet.DEFAULT_WIDTH) p = Paragraph(styles.ParagraphStyles.Normal, para_props) p.append(sampleParagraph) section.append(p) return doc
csvReader = csv.reader(open('Award Data Collection Effort Sample.csv', 'rb'), delimiter='|') n = 0 previousYear = None previousRFA = None report_title = 'Sample CTSI Pilot Award Report' doc = Document() ss = doc.StyleSheet # Improve the style sheet ps = ParagraphStyle('Title', TextStyle(TextPropertySet(ss.Fonts.Arial, 44)).Copy(), ParagraphPropertySet(space_before=60, space_after=60)) ss.ParagraphStyles.append(ps) ps = ParagraphStyle('Heading 3', TextStyle(TextPropertySet(ss.Fonts.Arial, 22)).Copy(), ParagraphPropertySet(space_before=60, space_after=60)) ss.ParagraphStyles.append(ps) ps = ParagraphStyle('Heading 4', TextStyle(TextPropertySet(ss.Fonts.Arial, 22)).Copy(), ParagraphPropertySet(space_before=60, space_after=60)) ss.ParagraphStyles.append(ps) section = Section() doc.Sections.append(section) section.FirstHeader.append(' ') p = Paragraph(ss.ParagraphStyles.Normal)
doc = Document() ss = doc.StyleSheet # Set the margins for the section at 0.5 inch on all sides ms = MarginsPropertySet(top=720, left=720, right=720, bottom=720) section = Section(margins=ms) doc.Sections.append(section) # Improve the style sheet. 1440 twips to the inch ps = ParagraphStyle( 'Title', TextStyle(TextPropertySet(ss.Fonts.Arial, 22, bold=True)).Copy(), ParagraphPropertySet(alignment=3, space_before=270, space_after=30)) ss.ParagraphStyles.append(ps) ps = ParagraphStyle( 'Subtitle', TextStyle(TextPropertySet(ss.Fonts.Arial, 16)).Copy(), ParagraphPropertySet(alignment=3, space_before=0, space_after=0)) ss.ParagraphStyles.append(ps) ps = ParagraphStyle('SubtitleLeft', TextStyle(TextPropertySet(ss.Fonts.Arial, 16)).Copy(), ParagraphPropertySet(space_before=0, space_after=0)) ss.ParagraphStyles.append(ps) ps = ParagraphStyle( 'Heading 3', TextStyle(TextPropertySet(ss.Fonts.Arial, 22, bold=True)).Copy(), ParagraphPropertySet(space_before=180, space_after=60,
def addIdentificationResults(self, document): survey = self.request.survey section = createIdentificationReportSection(document, self.context, self.request) lang = getattr(self.request, 'LANGUAGE', 'en') if "-" in lang: elems = lang.split("-") lang = "{0}_{1}".format(elems[0], elems[1].upper()) styles = document.StyleSheet.ParagraphStyles normal_style = document.StyleSheet.ParagraphStyles.Normal header_styles = { 0: styles.Heading2, 1: styles.Heading3, 2: styles.Heading4, 3: styles.Heading5, 4: styles.Heading6, } for node in self.getNodes(): section.append( Paragraph(header_styles.get(node.depth, styles.Heading6), u"%s %s" % (node.number, node.title))) if node.type != "risk": continue description = legal_reference = None if not getattr(node, 'is_custom_node', None): zope_node = survey.restrictedTraverse( node.zodb_path.split("/"), None) if zope_node is not None: description = getattr(zope_node, "description", None) legal_reference = getattr(zope_node, "legal_reference", None) if description and description.strip(): for el in report.HtmlToRtf(description, normal_style): section.append(el) if legal_reference and legal_reference.strip(): p = Paragraph(styles.Normal, "") section.append(p) section.append( Paragraph( styles.LegalHeading, translate(_('header_legal_references', default=u'Legal and policy references'), target_language=lang), )) p = Paragraph(styles.Normal, "") section.append(p) for el in report.HtmlToRtf(legal_reference, normal_style): section.append(el) tabs = TabPropertySet(section.TwipsToRightMargin(), alignment=TabPropertySet.RIGHT, leader=getattr(TabPropertySet, 'UNDERLINE')) p = Paragraph(styles.Normal, ParagraphPropertySet(tabs=[tabs])) p.append(TAB) section.append(p) if node.comment and node.comment.strip(): section.append(Paragraph(styles.Comment, node.comment))
def render(self): """ Mostly a copy of the render method in OSHAActionPlanReportDownload, but with some changes to handle the special reqs of Italy """ document = report.createDocument(self.session) ss = document.StyleSheet # Define some more custom styles ss.ParagraphStyles.append( ParagraphStyle( "RiskPriority", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=22, italic=True, colour=ss.Colours.Blue)), ParagraphPropertySet(left_indent=300, right_indent=300))) ss.ParagraphStyles.append( ParagraphStyle( "MeasureField", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=18, underline=True)), ParagraphPropertySet(left_indent=300, right_indent=300))) ss.ParagraphStyles.append( ParagraphStyle( "ITTitle", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=36, italic=True, bold=True)), ParagraphPropertySet(left_indent=300, right_indent=300))) ss.ParagraphStyles.append( ParagraphStyle( "ITSubtitle", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=32, italic=True, bold=True)), ParagraphPropertySet(left_indent=300, right_indent=300))) ss.ParagraphStyles.append( ParagraphStyle( "ITSubSubtitle", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=28, italic=True, bold=True)), ParagraphPropertySet(left_indent=300, right_indent=300))) ss.ParagraphStyles.append( ParagraphStyle( "ITNormalBold", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=24, bold=True)), ParagraphPropertySet(left_indent=50, right_indent=50))) # XXX: This part is removed # self.addActionPlan(document) # XXX: and replaced with this part: t = lambda txt: "".join([ "\u%s?" % str(ord(e)) for e in translate(txt, context=self.request) ]) intro = createItalianIntro(document, self.context, self.request) toc = createSection(document, self.context, self.request, first_page_number=2) body = Section() heading = t( _("header_oira_report_download", default=u"OiRA Report: \"${title}\"", mapping=dict(title=self.session.title))) toc.append( Paragraph( ss.ParagraphStyles.Heading1, ParagraphPropertySet(alignment=ParagraphPropertySet.CENTER), heading, )) if self.session.report_comment: # Add comment. #5985 normal_style = document.StyleSheet.ParagraphStyles.Normal toc.append(Paragraph(normal_style, self.session.report_comment)) toc_props = ParagraphPropertySet() toc_props.SetLeftIndent(TabPropertySet.DEFAULT_WIDTH * 1) toc_props.SetRightIndent(TabPropertySet.DEFAULT_WIDTH * 1) p = Paragraph(ss.ParagraphStyles.Heading6, toc_props) txt = t(_("toc_header", default=u"Contents")) p.append(character.Text(txt)) toc.append(p) headings = [ t(u"Adempimenti/rischi identificati, valutati e gestiti con misure " "obbligatorie adottate ed eventuali misure di miglioramento"), t(u"Adempimenti/rischi non pertinenti"), ] nodes = [ self.actioned_nodes, self.risk_not_present_nodes, ] for nodes, heading in zip(nodes, headings): if not nodes: continue self.addReportNodes(document, nodes, heading, toc, body) toc.append(Paragraph(LINE)) body.append(Paragraph(LINE)) document.Sections.append(body) # Until here... renderer = Renderer() output = StringIO() renderer.Write(document, output) # Custom filename filename = u"Documento di valutazione dei rischi {}".format( self.session.title) self.request.response.setHeader( "Content-Disposition", "attachment; filename=\"%s.rtf\"" % filename.encode("utf-8")) self.request.response.setHeader("Content-Type", "application/rtf") return output.getvalue()
def render(self): """ Mostly a copy of the render method in euphorie.client, but with some changes to also show unanswered risks and non-present risks. #1517 and #1518 """ document = report.createDocument(self.session) ss = document.StyleSheet # Define some more custom styles ss.ParagraphStyles.append( ParagraphStyle( "RiskPriority", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=22, italic=True, colour=ss.Colours.Blue)), ParagraphPropertySet(left_indent=300, right_indent=300))) ss.ParagraphStyles.append( ParagraphStyle( "MeasureField", TextStyle( TextPropertySet(font=ss.Fonts.Arial, size=18, underline=True)), ParagraphPropertySet(left_indent=300, right_indent=300))) # XXX: This part is removed # self.addActionPlan(document) # XXX: and replaced with this part: t = lambda txt: "".join([ "\u%s?" % str(ord(e)) for e in translate(txt, context=self.request) ]) toc = createSection(document, self.context, self.request) body = Section() heading = t( _("header_oira_report_download", default=u"OiRA Report: \"${title}\"", mapping=dict(title=self.session.title))) toc.append( Paragraph( ss.ParagraphStyles.Heading1, ParagraphPropertySet(alignment=ParagraphPropertySet.CENTER), heading, )) if self.session.report_comment: # Add comment. #5985 normal_style = document.StyleSheet.ParagraphStyles.Normal toc.append(Paragraph(normal_style, self.session.report_comment)) toc_props = ParagraphPropertySet() toc_props.SetLeftIndent(TabPropertySet.DEFAULT_WIDTH * 1) toc_props.SetRightIndent(TabPropertySet.DEFAULT_WIDTH * 1) p = Paragraph(ss.ParagraphStyles.Heading6, toc_props) txt = t(_("toc_header", default=u"Contents")) p.append(character.Text(txt)) toc.append(p) headings = [ t( _("header_present_risks", default=u"Risks that have been identified, " u"evaluated and have an Action Plan")), t( _("header_unevaluated_risks", default=u"Risks that have been identified but " u"do NOT have an Action Plan")), t( _("header_unanswered_risks", default=u'Hazards/problems that have been "parked" ' u'and are still to be dealt with')), t( _("header_risks_not_present", default=u"Hazards/problems that have been managed " u"or are not present in your organisation")) ] nodes = [ self.actioned_nodes, self.unactioned_nodes, self.unanswered_nodes, self.risk_not_present_nodes, ] for nodes, heading in zip(nodes, headings): if not nodes: continue self.addReportNodes(document, nodes, heading, toc, body) toc.append(Paragraph(LINE)) body.append(Paragraph(LINE)) self.addConsultationBox(body, document) document.Sections.append(body) # Until here... renderer = Renderer() output = StringIO() renderer.Write(document, output) filename = translate( _("filename_report_actionplan", default=u"Action plan ${title}", mapping=dict(title=self.session.title)), context=self.request, ) self.request.response.setHeader( "Content-Disposition", "attachment; filename=\"%s.rtf\"" % filename.encode("utf-8")) self.request.response.setHeader("Content-Type", "application/rtf") return output.getvalue()
def addMeasure(self, document, heading, section, measure): """ Requirements for how the measure section should be displayed are in #2611 """ t = lambda txt: "".join([ "\u%s?" % str(ord(e)) for e in translate(txt, context=self.request) ]) ss = document.StyleSheet styles = ss.ParagraphStyles table = Table(9500) thin_edge = BorderPropertySet(width=20, style=BorderPropertySet.SINGLE) no_edge = BorderPropertySet(width=0, colour=ss.Colours.White) p = Paragraph(styles.MeasureHeading, ParagraphPropertySet(left_indent=300, right_indent=300), t(_("header_measure_single", default=u"Measure"))) c = Cell(p, FramePropertySet(thin_edge, thin_edge, no_edge, thin_edge)) table.AddRow(c) ss = document.StyleSheet styles = document.StyleSheet.ParagraphStyles headings = [ t( _("label_measure_action_plan", default=u"General approach (to " u"eliminate or reduce the risk)")), t( _("label_measure_prevention_plan", default=u"Specific action(s) " u"required to implement this approach")), t( _("label_measure_requirements", default=u"Level of expertise " u"and/or requirements needed")), t( _("label_action_plan_responsible", default=u"Who is " u"responsible?")), t(_("label_action_plan_budget", default=u"Budget")), t(_("label_action_plan_start", default=u"Planning start")), t(_("label_action_plan_end", default=u"Planning end")), ] m = measure values = [ m.action_plan, m.prevention_plan, m.requirements, m.responsible, m.budget and str(m.budget) or '', m.planning_start and formatDate(self.request, m.planning_start) or '', m.planning_end and formatDate(self.request, m.planning_end) or '', ] for heading, value in zip(headings, values): p = Paragraph(styles.MeasureField, heading) c = Cell(p, FramePropertySet(no_edge, thin_edge, no_edge, thin_edge)) table.AddRow(c) if headings.index(heading) == len(headings) - 1: frame = FramePropertySet(no_edge, thin_edge, thin_edge, thin_edge) else: frame = FramePropertySet(no_edge, thin_edge, no_edge, thin_edge) p = Paragraph( styles.Normal, ParagraphPropertySet(left_indent=600, right_indent=600), value) c = Cell(p, frame) table.AddRow(c) section.append(table)
def addReportNodes(self, document, nodes, heading, toc, body): """ """ t = lambda txt: "".join([ "\u%s?" % str(ord(e)) for e in translate(txt, context=self.request) ]) ss = document.StyleSheet toc_props = ParagraphPropertySet() toc_props.SetLeftIndent(TabPropertySet.DEFAULT_WIDTH * 1) toc_props.SetRightIndent(TabPropertySet.DEFAULT_WIDTH * 1) p = Paragraph(ss.ParagraphStyles.Heading6, toc_props) p.append(character.Text(heading, TextPropertySet(italic=True))) toc.append(p) body.append(Paragraph(ss.ParagraphStyles.Heading1, heading)) survey = self.request.survey styles = ss.ParagraphStyles header_styles = { 0: styles.Heading2, 1: styles.Heading3, 2: styles.Heading4, 3: styles.Heading5, 4: styles.Heading6, } for node in nodes: zodb_node = None if node.zodb_path == 'custom-risks': title = self.title_custom_risks elif getattr(node, 'is_custom_risk', None): title = node.title else: zodb_node = survey.restrictedTraverse( node.zodb_path.split("/")) title = node_title(node, zodb_node) thin_edge = BorderPropertySet(width=20, style=BorderPropertySet.SINGLE) if node.depth == 1: p = Paragraph( header_styles.get(node.depth, styles.Heading6), FramePropertySet(thin_edge, thin_edge, thin_edge, thin_edge), u"%s %s" % (node.number, title)) else: p = Paragraph(header_styles.get(node.depth, styles.Heading6), u"%s %s" % (node.number, title)) body.append(p) if node.type != "risk": continue if node.priority: if node.priority == "low": level = _("risk_priority_low", default=u"low") elif node.priority == "medium": level = _("risk_priority_medium", default=u"medium") elif node.priority == "high": level = _("risk_priority_high", default=u"high") msg = _("risk_priority", default="This is a ${priority_value} priority risk.", mapping={'priority_value': level}) body.append(Paragraph(styles.RiskPriority, t(msg))) # In the report for Italy, don't print the description if (getattr(node, 'identification', None) == 'no' and not IOSHAItalyReportPhaseSkinLayer.providedBy( self.request)): if zodb_node is None: description = node.title else: description = zodb_node.description body.append( Paragraph( styles.Normal, ParagraphPropertySet(left_indent=300, right_indent=300), t( _( utils.html_unescape( htmllaundry.StripMarkup(description)))))) body.append(Paragraph("")) if node.comment and node.comment.strip(): body.append(Paragraph(styles.Comment, node.comment)) for (idx, measure) in enumerate(node.action_plans): if not measure.action_plan: continue if len(node.action_plans) == 1: heading = t(_("header_measure_single", default=u"Measure")) else: heading = t( _("header_measure", default=u"Measure ${index}", mapping={"index": idx + 1})) self.addMeasure(document, heading, body, measure)