1# encoding: utf-8 2 3""" 4Step implementations for document-related features 5""" 6 7from __future__ import absolute_import, print_function, unicode_literals 8 9from behave import given, then, when 10 11from docx import Document 12from docx.enum.section import WD_ORIENT, WD_SECTION 13from docx.shape import InlineShapes 14from docx.shared import Inches 15from docx.section import Sections 16from docx.styles.styles import Styles 17from docx.table import Table 18from docx.text.paragraph import Paragraph 19 20from helpers import test_docx, test_file 21 22 23# given =================================================== 24 25@given('a blank document') 26def given_a_blank_document(context): 27 context.document = Document(test_docx('doc-word-default-blank')) 28 29 30@given('a document having built-in styles') 31def given_a_document_having_builtin_styles(context): 32 context.document = Document() 33 34 35@given('a document having inline shapes') 36def given_a_document_having_inline_shapes(context): 37 context.document = Document(test_docx('shp-inline-shape-access')) 38 39 40@given('a document having sections') 41def given_a_document_having_sections(context): 42 context.document = Document(test_docx('doc-access-sections')) 43 44 45@given('a document having styles') 46def given_a_document_having_styles(context): 47 context.document = Document(test_docx('sty-having-styles-part')) 48 49 50@given('a document having three tables') 51def given_a_document_having_three_tables(context): 52 context.document = Document(test_docx('tbl-having-tables')) 53 54 55@given('a single-section document having portrait layout') 56def given_a_single_section_document_having_portrait_layout(context): 57 context.document = Document(test_docx('doc-add-section')) 58 section = context.document.sections[-1] 59 context.original_dimensions = (section.page_width, section.page_height) 60 61 62@given("a single-section Document object with headers and footers as document") 63def given_a_single_section_Document_object_with_headers_and_footers(context): 64 context.document = Document(test_docx("doc-add-section")) 65 66 67# when ==================================================== 68 69@when('I add a 2 x 2 table specifying only row and column count') 70def when_add_2x2_table_specifying_only_row_and_col_count(context): 71 document = context.document 72 document.add_table(rows=2, cols=2) 73 74 75@when('I add a 2 x 2 table specifying style \'{style_name}\'') 76def when_add_2x2_table_specifying_style_name(context, style_name): 77 document = context.document 78 document.add_table(rows=2, cols=2, style=style_name) 79 80 81@when('I add a heading specifying level={level}') 82def when_add_heading_specifying_level(context, level): 83 context.document.add_heading(level=int(level)) 84 85 86@when('I add a heading specifying only its text') 87def when_add_heading_specifying_only_its_text(context): 88 document = context.document 89 context.heading_text = text = 'Spam vs. Eggs' 90 document.add_heading(text) 91 92 93@when('I add a page break to the document') 94def when_add_page_break_to_document(context): 95 document = context.document 96 document.add_page_break() 97 98 99@when('I add a paragraph specifying its style as a {kind}') 100def when_I_add_a_paragraph_specifying_its_style_as_a(context, kind): 101 document = context.document 102 style = context.style = document.styles['Heading 1'] 103 style_spec = { 104 'style object': style, 105 'style name': 'Heading 1', 106 }[kind] 107 document.add_paragraph(style=style_spec) 108 109 110@when('I add a paragraph specifying its text') 111def when_add_paragraph_specifying_text(context): 112 document = context.document 113 context.paragraph_text = 'foobar' 114 document.add_paragraph(context.paragraph_text) 115 116 117@when('I add a paragraph without specifying text or style') 118def when_add_paragraph_without_specifying_text_or_style(context): 119 document = context.document 120 document.add_paragraph() 121 122 123@when('I add a picture specifying 1.75" width and 2.5" height') 124def when_add_picture_specifying_width_and_height(context): 125 document = context.document 126 context.picture = document.add_picture( 127 test_file('monty-truth.png'), 128 width=Inches(1.75), height=Inches(2.5) 129 ) 130 131 132@when('I add a picture specifying a height of 1.5 inches') 133def when_add_picture_specifying_height(context): 134 document = context.document 135 context.picture = document.add_picture( 136 test_file('monty-truth.png'), height=Inches(1.5) 137 ) 138 139 140@when('I add a picture specifying a width of 1.5 inches') 141def when_add_picture_specifying_width(context): 142 document = context.document 143 context.picture = document.add_picture( 144 test_file('monty-truth.png'), width=Inches(1.5) 145 ) 146 147 148@when('I add a picture specifying only the image file') 149def when_add_picture_specifying_only_image_file(context): 150 document = context.document 151 context.picture = document.add_picture(test_file('monty-truth.png')) 152 153 154@when('I add an even-page section to the document') 155def when_I_add_an_even_page_section_to_the_document(context): 156 context.section = context.document.add_section(WD_SECTION.EVEN_PAGE) 157 158 159@when('I change the new section layout to landscape') 160def when_I_change_the_new_section_layout_to_landscape(context): 161 new_height, new_width = context.original_dimensions 162 section = context.section 163 section.orientation = WD_ORIENT.LANDSCAPE 164 section.page_width = new_width 165 section.page_height = new_height 166 167 168@when("I execute section = document.add_section()") 169def when_I_execute_section_eq_document_add_section(context): 170 context.section = context.document.add_section() 171 172 173# then ==================================================== 174 175@then('document.inline_shapes is an InlineShapes object') 176def then_document_inline_shapes_is_an_InlineShapes_object(context): 177 document = context.document 178 inline_shapes = document.inline_shapes 179 assert isinstance(inline_shapes, InlineShapes) 180 181 182@then('document.paragraphs is a list containing three paragraphs') 183def then_document_paragraphs_is_a_list_containing_three_paragraphs(context): 184 document = context.document 185 paragraphs = document.paragraphs 186 assert isinstance(paragraphs, list) 187 assert len(paragraphs) == 3 188 for paragraph in paragraphs: 189 assert isinstance(paragraph, Paragraph) 190 191 192@then('document.sections is a Sections object') 193def then_document_sections_is_a_Sections_object(context): 194 sections = context.document.sections 195 msg = 'document.sections not instance of Sections' 196 assert isinstance(sections, Sections), msg 197 198 199@then('document.styles is a Styles object') 200def then_document_styles_is_a_Styles_object(context): 201 styles = context.document.styles 202 assert isinstance(styles, Styles) 203 204 205@then('document.tables is a list containing three tables') 206def then_document_tables_is_a_list_containing_three_tables(context): 207 document = context.document 208 tables = document.tables 209 assert isinstance(tables, list) 210 assert len(tables) == 3 211 for table in tables: 212 assert isinstance(table, Table) 213 214 215@then('the document contains a 2 x 2 table') 216def then_the_document_contains_a_2x2_table(context): 217 table = context.document.tables[-1] 218 assert isinstance(table, Table) 219 assert len(table.rows) == 2 220 assert len(table.columns) == 2 221 context.table_ = table 222 223 224@then('the document has two sections') 225def then_the_document_has_two_sections(context): 226 assert len(context.document.sections) == 2 227 228 229@then('the first section is portrait') 230def then_the_first_section_is_portrait(context): 231 first_section = context.document.sections[0] 232 expected_width, expected_height = context.original_dimensions 233 assert first_section.orientation == WD_ORIENT.PORTRAIT 234 assert first_section.page_width == expected_width 235 assert first_section.page_height == expected_height 236 237 238@then('the last paragraph contains only a page break') 239def then_last_paragraph_contains_only_a_page_break(context): 240 document = context.document 241 paragraph = document.paragraphs[-1] 242 assert len(paragraph.runs) == 1 243 assert len(paragraph.runs[0]._r) == 1 244 assert paragraph.runs[0]._r[0].type == 'page' 245 246 247@then('the last paragraph contains the heading text') 248def then_last_p_contains_heading_text(context): 249 document = context.document 250 text = context.heading_text 251 paragraph = document.paragraphs[-1] 252 assert paragraph.text == text 253 254 255@then('the second section is landscape') 256def then_the_second_section_is_landscape(context): 257 new_section = context.document.sections[-1] 258 expected_height, expected_width = context.original_dimensions 259 assert new_section.orientation == WD_ORIENT.LANDSCAPE 260 assert new_section.page_width == expected_width 261 assert new_section.page_height == expected_height 262 263 264@then('the style of the last paragraph is \'{style_name}\'') 265def then_the_style_of_the_last_paragraph_is_style(context, style_name): 266 document = context.document 267 paragraph = document.paragraphs[-1] 268 assert paragraph.style.name == style_name, ( 269 'got %s' % paragraph.style.name 270 ) 271