def __create_headers(table: Table, formula: Formula):
    """
    Creates the header for the table, adds an auto-numbering field to the first cell to track the test number,
    adds the sheet name the formula is located on in the second cell.  Header cells are shaded.  Docx does not
    support cell shading, therefore the document xml is directly modified.
    :param table: table to add headers
    :param formula: formula to base the table on
    :return: n/a
    """
    table.cell(0, 0).merge(table.cell(0, 3))
    table.cell(0, 4).merge(table.cell(0, 6))

    cell = table.cell(0, 0)

    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.BOTTOM
    cell.shade_cell(__FILL_COLOR)

    paragraph = cell.paragraphs[0]
    run = paragraph.add_run('Test No. ')
    run.add_field(__AUTONUM)
    run.add_text(f" Name of test")  # TODO: Determine what the name of the test will be
    paragraph.style = 'Cell Heading'  # TODO: Create style that makes text based on a heading style so TOC can be made

    cell = table.cell(0, 6)

    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.BOTTOM
    cell.shade_cell(__FILL_COLOR)

    paragraph = cell.paragraphs[0]
    paragraph.text = f"Sheet: {formula.sheet}"
    paragraph.style = 'Cell Header Right'
Esempio n. 2
0
def merge_cells(grid: Table, section: Section) -> None:
    """
    Merge the sections cell using it's width and height.
    """
    row, col = row_pos(section), col_pos(section)
    width, height = get_width(section), get_height(section)

    grid.cell(row, col).merge(grid.cell(row + height - 1, col + width - 1))
 def _convert_table(self, table: Table):
     """
     转换表格
     :param table:
     :return:
     """
     row_count = len(table.rows)
     col_count = len(table.columns)
     result = ['<table>']
     for row in range(row_count):
         result.append('<tr>')
         for col in range(col_count):
             result.append("<td>")
             cell = table.cell(row, col)
             # result.append(''.join(self.convert_(cell.paragraphs)))
             child_result = []
             for item in self.iter_block_items(cell):
                 if isinstance(item, Paragraph):
                     child_result.append(self._convert_paragraph(item))
                 elif isinstance(item, Table):
                     child_result.append(self._convert_table(item))
             result.append('<br />'.join(child_result))
             result.append("</td>")
         result.append("</tr>")
     result.append("</table>")
     return ''.join(result)
Esempio n. 4
0
def set_cell_text(table: Table, row: int, col: int, style: str, text: str) -> None:
    """ Добавить текст в ячейку таблицы """
    cell = table.cell(row, col)
    if cell.text:
        cell.add_paragraph(text, style)
    else:
        cell.text = text
        cell.paragraphs[0].style = style
def __create_manual_formula_row(table: Table, formula: Formula):
    """
    Creates a row containing a human-readable formula based on the Excel formula
    :param table: table to add formula
    :param formula: formula to add
    :return: n/a
    """
    cell = table.cell(1, 0)
    cell.text = '1'
    cell.paragraphs[0].style = 'Cell Text'
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.TOP

    # TODO: Add the formula and text
    # TODO: use LaTeX formatting from matplotlib to create the written formula
    # TODO: Excel document will need a column to write the LaTeX markup

    cell = table.cell(1, 1).merge(table.cell(1, 6))
    cell.text = 'INSERT MANUAL FORMULA'
Esempio n. 6
0
def add_regular_key_value_pairs(cif: CifContainer, main_table: Table) -> None:
    for _, key in enumerate(cif_keywords_list):
        # key[1] contains the row number:
        cell = main_table.cell(key[1] + 1, 1)
        if cif[key[0]]:
            cell.text = cif[key[0]]
        else:
            cell.text = '?'
            continue
Esempio n. 7
0
def table_nested_parsing(cell, current_row, current_col):
    for block in cell._element:
        if isinstance(block, CT_P):
            #(Paragraph(block, cell).text)
            return (Paragraph(block, cell).text)
        if isinstance(block, CT_Tbl):
            block = Table(block, cell)
            for row in range(len(block.rows)):
                for col in range(len(block.columns)):
                    cell_table = block.cell(row, col)
                    table_nested_parsing(cell_table, row, col)
def __create_excel_formula_row(table: Table, formula: Formula):
    """
    Creates a row containing the Excel readable formula to compare to human formula
    Cell shading is done using direct document xml modification
    :param table: table to update
    :param formula: formula to base the row on
    :return: n/a
    """
    table.cell(2, 0).merge(table.cell(3, 0))
    table.cell(2, 1).merge(table.cell(3, 5))

    cell = table.cell(2, 0)
    cell.text = '2'
    cell.paragraphs[0].style = 'Cell Text'
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.TOP

    cell = table.cell(2, 6)
    cell.text = 'Pass?'
    cell.paragraphs[0].style = 'Cell Header Center'
    cell.shade_cell(__FILL_COLOR)

    cell = table.cell(2, 1)
    formula = '=' + formula.value
    cell.text = \
        'Compare the above formula to the Excel formula to determine if it should calculate the same as above:'
    cell.paragraphs[0].style = 'Cell Text'
    cell.add_paragraph(f'\n{formula}', 'Cell Text Center')
Esempio n. 9
0
 def get_segments(self, tree):
     segments = []
     for child in tree.element.body.iterchildren():
         if isinstance(child, CT_P):
             segment = {"paragraph": {"words": []}}
             paragraph = Paragraph(child, tree)
             words = self.text_from_paragraph(paragraph)
             for word in words:
                 segment["paragraph"]["words"].append({
                     "style": None,
                     "coordinates": None,
                     "txt": word
                 })
             segments.append({"label": "PARA", "segment": segment})
         elif isinstance(child, CT_Tbl):
             table = Table(child, tree)
             num_rows = len(table.rows)
             num_cols = len(table.columns)
             segment = {
                 "table": {
                     "numRows": num_rows,
                     "numCols": num_cols,
                     "headers": [],
                     "cells": []
                 }
             }
             for i in range(num_rows):
                 for j in range(num_cols):
                     cell_items = {
                         "rowIndex": i,
                         "colIndex": j,
                         "words": []
                     }
                     cell = table.cell(i, j)
                     words = []
                     paragraphs = cell.paragraphs
                     for paragraph in paragraphs:
                         words.extend(self.text_from_paragraph(paragraph))
                     for word in words:
                         cell_items["words"].append({
                             "style": None,
                             "coordinates": None,
                             "txt": word
                         })
                     segment["table"]["cells"].append(cell_items)
             segments.append({"label": "TABLE", "segment": segment})
     return segments
Esempio n. 10
0
def format_space_group(table: Table,
                       cif: CifContainer,
                       column: int,
                       row: int = 6) -> None:
    """
    Sets formating of the space group symbol in row 6.
    """
    space_group = cif.space_group
    it_number = ''
    with suppress(AttributeError):
        it_number = str(cif.spgr_number)
    paragraph = table.cell(row, column).paragraphs[0]
    try:
        # The HM space group symbol
        s = SpaceGroups()
        spgrxml = s.to_mathml(space_group)
        paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
        paragraph._element.append(math_to_word(spgrxml))
        paragraph.add_run(' ({})'.format(it_number))
    except Exception:
        if it_number:
            paragraph.add_run('{} ({})'.format(space_group, it_number))
        else:
            paragraph.add_run(space_group)
def __create_variable_rows(table: Table, formula: Formula, total_rows: int):
    # Merge as appropriate
    table.cell(4, 0).merge(table.cell(total_rows - 1, 0))
    table.cell(4, 4).merge(table.cell(4, 6))
    table.cell(total_rows - 2, 1).merge(table.cell(total_rows - 1, 1))
    table.cell(total_rows - 2, 2).merge(table.cell(total_rows - 1, 2))
    table.cell(total_rows - 2, 3).merge(table.cell(total_rows - 1, 3))

    # Numbered cell
    cell = table.cell(4, 0)
    cell.text = '3'
    cell.paragraphs[0].style = 'Cell Text'
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.TOP

    # Header row
    headers = ['Formula Variable', 'Cell', 'Range Name', 'Value']
    for i in range(1, 4+1):
        cell = table.cell(4, i)
        cell.text = headers[i - 1]
        cell.paragraphs[0].style = 'Cell Header'
        cell.shade_cell(__FILL_COLOR)

    # Individual Variable rows
    for i, var in enumerate(formula.variables):
        if var is None:
            continue
        table.cell(5 + i, 4).merge(table.cell(5 + i, 6))
        cell = table.cell(5 + i, 2)
        cell.text = var.coordinate or 'N/A'
        cell.paragraphs[0].style = 'Cell Text'

        cell = table.cell(5 + i, 3)
        cell.text = var.name
        cell.paragraphs[0].style = 'Cell Text'

        # TODO: work on figuring out what the value is supposed to be -- input/output?
        # TODO: May have to be manually entered?  Possibly in the spreadsheet
        # TODO: Two step process of creating the file containing the formulas, then entering the values they should be

        cell = table.cell(5 + i, 4)
        # NOTE: Possibilities for output values
        #  - Name/Formula/Variable (i: val/form, o: val)
        #  - Name/Formula/Variable (i: val/form, o: None) -
        #  - Name/Formula/Variable (i: None, o: None) - Blank cells?
        #  - Global Names?
        cell.text = var.output or ''  # FIXME: output not outputting, 0's causing issue?
        cell.paragraphs[0].style = 'Cell Text'

    # TODO: Add formula variable itself (Last Row)
    cell = table.cell(total_rows - 1, 2)
    cell.text = formula.coordinate
    cell.paragraphs[0].style = 'Cell Text'

    cell = table.cell(total_rows - 1, 3)
    cell.text = formula.name
    cell.paragraphs[0].style = 'Cell Text'

    # TODO: Make separate function for this?
    # Sub header rows
    headers = ['Manual', 'Excel', 'Pass']
    for i in range(4, 6+1):
        cell = table.cell(total_rows - 2, i)
        cell.text = headers[i - 4]
        cell.paragraphs[0].style = 'Cell Header Center'
        cell.shade_cell(__FILL_COLOR)
Esempio n. 12
0
def populate_main_table_values(main_table: Table, cif: CifContainer, column=1):
    """
    Fills the main table with residuals. Column, by column.
    """
    radiation_type = cif['_diffrn_radiation_type']
    radiation_wavelength = cif['_diffrn_radiation_wavelength']
    crystal_size_min = cif['_exptl_crystal_size_min']
    crystal_size_mid = cif['_exptl_crystal_size_mid']
    crystal_size_max = cif['_exptl_crystal_size_max']
    limit_h_min = cif['_diffrn_reflns_limit_h_min']
    limit_h_max = cif['_diffrn_reflns_limit_h_max']
    limit_k_min = cif['_diffrn_reflns_limit_k_min']
    limit_k_max = cif['_diffrn_reflns_limit_k_max']
    theta_min = cif['_diffrn_reflns_theta_min']
    theta_max = cif['_diffrn_reflns_theta_max']
    limit_l_min = cif['_diffrn_reflns_limit_l_min']
    limit_l_max = cif['_diffrn_reflns_limit_l_max']
    reflns_number_total = cif['_reflns_number_total']
    reflns_av_R_equivalents = cif['_diffrn_reflns_av_R_equivalents']
    reflns_av_unetI = cif['_diffrn_reflns_av_unetI/netI']
    ls_number_reflns = cif['_refine_ls_number_reflns']
    ls_number_restraints = cif['_refine_ls_number_restraints']
    ls_number_parameters = cif['_refine_ls_number_parameters']
    ls_R_factor_gt = cif['_refine_ls_R_factor_gt']
    ls_wR_factor_gt = cif['_refine_ls_wR_factor_gt']
    ls_R_factor_all = cif['_refine_ls_R_factor_all']
    ls_wR_factor_ref = cif['_refine_ls_wR_factor_ref']
    goof = cif['_refine_ls_goodness_of_fit_ref']

    main_table.cell(0,
                    column).paragraphs[0].add_run(cif.fileobj.name).bold = True
    main_table.cell(1, column).paragraphs[0].add_run(
        cif['_database_code_depnum_ccdc_archive'])

    # Set text for all usual cif keywords by a lookup table:
    for _, key in enumerate(cif_keywords_list):
        # key[1] contains the row number:
        cell = main_table.cell(key[1] + 1, column)
        if cif[key[0]]:
            cell.text = cif[key[0]]
        else:
            cell.text = '?'
            continue
    # Now the special handling:
    # The sum formula:
    if cif['_chemical_formula_sum']:
        sum_formula_group = make_sumform_to_group_of_str_and_numbers(cif)
        for _, word in enumerate(sum_formula_group):
            formula_run = main_table.cell(2, column).paragraphs[0]
            formula_run_subscript = formula_run.add_run(word)
            if isfloat(word):
                formula_run_subscript.font.subscript = True
    else:
        main_table.cell(2, column).paragraphs[0].add_run('no sum formula')
    format_space_group(main_table, cif, column, row=6)
    try:
        completeness = "{0:.1f} %".format(
            round(float(cif['_diffrn_measured_fraction_theta_full']) * 100, 1))
    except ValueError:
        completeness = '?'
    try:
        diff_density_min = "{0:.2f}".format(
            round(float(cif['_refine_diff_density_min']), 2))
    except ValueError:
        diff_density_min = '?'
    try:
        diff_density_max = "{0:.2f}".format(
            round(float(cif['_refine_diff_density_max']), 2))
    except ValueError:
        diff_density_max = '?'

    # now prepare & write all the concatenated & derived cell contents:
    main_table.cell(18, column).text = this_or_quest(crystal_size_max) + timessym + \
                                       this_or_quest(crystal_size_mid) + timessym + \
                                       this_or_quest(crystal_size_min)
    wavelength = str(' ({} ='.format(lambdasym) +
                     this_or_quest(radiation_wavelength) +
                     '{}{})'.format(protected_space, angstrom)).replace(
                         ' ', '')
    # radtype: ('Mo', 'K', '\\a')
    radtype = format_radiation(radiation_type)
    radrun = main_table.cell(21, column).paragraphs[0]
    # radiation type e.g. Mo:
    radrun.add_run(radtype[0])
    # K line:
    radrunita = radrun.add_run(radtype[1])
    radrunita.font.italic = True
    alpha = radrun.add_run(radtype[2])
    alpha.font.italic = True
    alpha.font.subscript = True
    # wavelength lambda:
    radrun.add_run(' ' + wavelength)
    try:
        d_max = ' ({:.2f}{}{})'.format(
            float(radiation_wavelength) / (2 * sin(radians(float(theta_max)))),
            protected_space, angstrom)
        # 2theta range:
        main_table.cell(22, column).text = "{:.2f} to {:.2f}{}" \
            .format(2 * float(theta_min), 2 * float(theta_max), d_max)
    except ValueError:
        main_table.cell(22, column).text = '? to ?'
    main_table.cell(23, column).text = limit_h_min + ' {} h {} '.format(less_or_equal, less_or_equal) + limit_h_max \
                                       + '\n' \
                                       + limit_k_min + ' {} k {} '.format(less_or_equal, less_or_equal) + limit_k_max \
                                       + '\n' \
                                       + limit_l_min + ' {} l {} '.format(less_or_equal, less_or_equal) + limit_l_max
    rint_p = main_table.cell(25, column).paragraphs[0]
    rint_p.add_run(this_or_quest(reflns_number_total) + '\n')
    rint_p.add_run('R').font.italic = True
    rint_p.add_run('int').font.subscript = True
    rint_p.add_run(' = ' + this_or_quest(reflns_av_R_equivalents) + '\n')
    rint_p.add_run('R').font.italic = True
    rint_p.add_run('sigma').font.subscript = True
    rint_p.add_run(' = ' + this_or_quest(reflns_av_unetI))
    main_table.cell(26, column).paragraphs[0].add_run(completeness)
    main_table.cell(27, column).text = this_or_quest(ls_number_reflns) + '/' \
                                       + this_or_quest(ls_number_restraints) + '/' \
                                       + this_or_quest(ls_number_parameters)
    main_table.cell(28, column).paragraphs[0].add_run(goof)
    r2sig_p = main_table.cell(29, column).paragraphs[0]
    r2sig_p.add_run('R').font.italic = True
    r2sig_p.add_run('1').font.subscript = True
    r2sig_p.add_run(' = ' + this_or_quest(ls_R_factor_gt))
    r2sig_p.add_run('\nw')
    r2sig_p.add_run('R').font.italic = True
    r2sig_p.add_run('2').font.subscript = True
    r2sig_p.add_run(' = ' + this_or_quest(ls_wR_factor_gt))
    rfull_p = main_table.cell(30, column).paragraphs[0]
    rfull_p.add_run('R').font.italic = True
    rfull_p.add_run('1').font.subscript = True
    rfull_p.add_run(' = ' + this_or_quest(ls_R_factor_all))
    rfull_p.add_run('\nw')
    rfull_p.add_run('R').font.italic = True
    rfull_p.add_run('2').font.subscript = True
    rfull_p.add_run(' = ' + ls_wR_factor_ref)
    main_table.cell(31,
                    column).text = diff_density_max + '/' + diff_density_min
    if not cif.is_centrosymm:
        main_table.cell(
            32, column).text = cif['_refine_ls_abs_structure_Flack'] or '?'
    exti = cif['_refine_ls_extinction_coef']
    # if exti not in ['.', "'.'", '?', '']:
    #    num = len(main_table.columns[0].cells)
    main_table.columns[column].cells[33].text = exti
Esempio n. 13
0
def populate_description_columns(main_table: Table) -> None:
    """
    This Method adds the descriptions to the fist property table column.
    """
    main_table.cell(0, 0).paragraphs[0].add_run('')
    main_table.cell(1, 0).paragraphs[0].add_run('CCDC number')
    main_table.cell(2, 0).paragraphs[0].add_run('Empirical formula')
    main_table.cell(3, 0).paragraphs[0].add_run('Formula weight')
    main_table.cell(4, 0).paragraphs[0].add_run('Temperature [K]')
    main_table.cell(5, 0).paragraphs[0].add_run('Crystal system')
    main_table.cell(6, 0).paragraphs[0].add_run('Space group (number)')
    lgnd6 = main_table.cell(7, 0).paragraphs[0]
    lgnd6.add_run('a').font.italic = True
    lgnd6.add_run(' [{}]'.format(angstrom))
    lgnd7 = main_table.cell(8, 0).paragraphs[0]
    lgnd7.add_run('b').font.italic = True
    lgnd7.add_run(' [{}]'.format(angstrom))
    lgnd8 = main_table.cell(9, 0).paragraphs[0]
    lgnd8.add_run('c').font.italic = True
    lgnd8.add_run(' [{}]'.format(angstrom))
    lgnd9 = main_table.cell(10, 0).paragraphs[0].add_run(
        '\u03B1 [{}]'.format(degree_sign))
    lgnd10 = main_table.cell(11, 0).paragraphs[0].add_run(
        '\u03B2 [{}]'.format(degree_sign))
    lgnd11 = main_table.cell(12, 0).paragraphs[0].add_run(
        '\u03B3 [{}]'.format(degree_sign))
    lgnd12 = main_table.cell(13, 0).paragraphs[0]
    lgnd12.add_run('Volume [{}'.format(angstrom))
    lgnd12.add_run('3').font.superscript = True
    lgnd12.add_run(']')
    lgnd13 = main_table.cell(14,
                             0).paragraphs[0].add_run('Z').font.italic = True
    lgnd14 = main_table.cell(15, 0).paragraphs[0]
    lgnd14.add_run('\u03C1').font.italic = True
    lgnd14.add_run('calc').font.subscript = True
    lgnd14.add_run(' [gcm')
    lgnd14.add_run(minus_sign + '3').font.superscript = True
    lgnd14.add_run(']')
    lgnd15 = main_table.cell(16, 0).paragraphs[0]
    lgnd15.add_run('\u03BC').font.italic = True
    lgnd15.add_run(' [mm')
    lgnd15.add_run(minus_sign + '1').font.superscript = True
    lgnd15.add_run(']')
    lgnd16 = main_table.cell(17, 0).paragraphs[0]
    lgnd16.add_run('F').font.italic = True
    lgnd16.add_run('(000)')
    lgnd17 = main_table.cell(18, 0).paragraphs[0]
    lgnd17.add_run('Crystal size [mm')
    lgnd17.add_run('3').font.superscript = True
    lgnd17.add_run(']')
    lgnd18 = main_table.cell(19, 0).paragraphs[0].add_run('Crystal colour')
    lgnd19 = main_table.cell(20, 0).paragraphs[0].add_run('Crystal shape')
    lgnd20 = main_table.cell(21, 0).paragraphs[0].add_run('Radiation')
    lgnd21 = main_table.cell(22,
                             0).paragraphs[0].add_run('2\u03F4 range [\u00b0]')
    lgnd22 = main_table.cell(23, 0).paragraphs[0].add_run('Index ranges')
    lgnd23 = main_table.cell(24,
                             0).paragraphs[0].add_run('Reflections collected')
    lgnd24 = main_table.cell(
        25, 0).paragraphs[0].add_run('Independent reflections')
    lgnd25 = main_table.cell(26, 0).paragraphs[0]
    # theta_full = cif['_diffrn_reflns_theta_full']
    # if theta_full:
    #    lgnd25.add_run('Completeness to \n\u03B8 = {}°'.format(theta_full))
    # else:
    lgnd25.add_run('Completeness')
    main_table.cell(27,
                    0).paragraphs[0].add_run('Data / Restraints / Parameters')
    lgnd27 = main_table.cell(28, 0).paragraphs[0]
    lgnd27.add_run('Goodness-of-fit on ')
    lgnd27.add_run('F').font.italic = True
    lgnd27.add_run('2').font.superscript = True
    lgnd28 = main_table.cell(29, 0).paragraphs[0]
    lgnd28.add_run('Final ')
    lgnd28.add_run('R').font.italic = True
    lgnd28.add_run(' indexes \n[')
    lgnd28.add_run('I').font.italic = True
    lgnd28.add_run('{}2{}('.format(bequal, sigma_sm))
    lgnd28.add_run('I').font.italic = True
    lgnd28.add_run(')]')
    lgnd29 = main_table.cell(30, 0).paragraphs[0]
    lgnd29.add_run('Final ')
    lgnd29.add_run('R').font.italic = True
    lgnd29.add_run(' indexes \n[all data]')
    lgnd30 = main_table.cell(31, 0).paragraphs[0]
    lgnd30.add_run('Largest peak/hole [e{}'.format(angstrom))
    lgnd30.add_run(minus_sign + '3').font.superscript = True
    lgnd30.add_run(']')
    lgnd31 = main_table.cell(32, 0).paragraphs[0]
    lgnd31.add_run('Flack X parameter')
    main_table.cell(33, 0).paragraphs[0].add_run('Extinction coefficient')
Esempio n. 14
0
from docx import Document
from docx.shared import Inches
from docx.table import Table

# %%
docu = Document("C:/Program Files/pdfbox/2020Q1.docx")
docu

# %%
len(docu.tables)
# %%
type(docu.tables[10])

# %%
table = docu.tables[7]
table = Table()

# %%
table.cell(0, 0).text
# %%
len(docu.paragraphs)

# %%

# %%
for parag in docu.paragraphs:
    print(parag.text)
# %%
print(docu.paragraphs[149].text)
# %%
Esempio n. 15
0
def populate_main_table_values(main_table: Table, cif: CifContainer):
    """
    Fills the main table with residuals. Column, by column.
    """
    main_table.cell(0, 1).paragraphs[0].add_run(
        cif['_database_code_depnum_ccdc_archive'])
    # Set text for all usual cif keywords by a lookup table:
    add_regular_key_value_pairs(cif, main_table)
    # Now the special handling:
    formula_paragraph = main_table.cell(1, 1).paragraphs[0]
    sum_formula = cif['_chemical_formula_sum'].replace(" ", "")
    add_sum_formula(formula_paragraph, sum_formula)
    spgr_paragraph = main_table.cell(5, 1).paragraphs[0]
    space_group = cif.space_group
    try:
        it_number = str(cif.spgr_number)
    except AttributeError:
        it_number = ''
    format_space_group(spgr_paragraph, space_group, it_number)
    radiation_type = cif['_diffrn_radiation_type']
    radiation_wavelength = cif['_diffrn_radiation_wavelength']
    crystal_size_min = cif['_exptl_crystal_size_min']
    crystal_size_mid = cif['_exptl_crystal_size_mid']
    crystal_size_max = cif['_exptl_crystal_size_max']
    theta_min = cif['_diffrn_reflns_theta_min']
    theta_max = cif['_diffrn_reflns_theta_max']
    limit_h_min = cif['_diffrn_reflns_limit_h_min']
    limit_h_max = cif['_diffrn_reflns_limit_h_max']
    limit_k_min = cif['_diffrn_reflns_limit_k_min']
    limit_k_max = cif['_diffrn_reflns_limit_k_max']
    limit_l_min = cif['_diffrn_reflns_limit_l_min']
    limit_l_max = cif['_diffrn_reflns_limit_l_max']
    ls_number_reflns = cif['_refine_ls_number_reflns']
    ls_number_restraints = cif['_refine_ls_number_restraints']
    ls_number_parameters = cif['_refine_ls_number_parameters']
    goof = cif['_refine_ls_goodness_of_fit_ref']
    try:
        completeness = "{0:.1f} %".format(
            round(float(cif['_diffrn_measured_fraction_theta_full']) * 100, 1))
    except ValueError:
        completeness = '?'
    try:
        diff_density_min = "{0:.2f}".format(
            round(float(cif['_refine_diff_density_min']), 2))
    except ValueError:
        diff_density_min = '?'
    try:
        diff_density_max = "{0:.2f}".format(
            round(float(cif['_refine_diff_density_max']), 2))
    except ValueError:
        diff_density_max = '?'

    # now prepare & write all the concatenated & derived cell contents:
    main_table.cell(17, 1).text = this_or_quest(crystal_size_max) + timessym + \
                                  this_or_quest(crystal_size_mid) + timessym + \
                                  this_or_quest(crystal_size_min)
    wavelength = str(' ({} ='.format(lambdasym) +
                     this_or_quest(radiation_wavelength) +
                     '{}{})'.format(protected_space, angstrom)).replace(
                         ' ', '')
    # radtype: ('Mo', 'K', '\\a')
    radtype = format_radiation(radiation_type)
    radrun = main_table.cell(20, 1).paragraphs[0]
    # radiation type e.g. Mo:
    radrun.add_run(radtype[0])
    # K line:
    radrunita = radrun.add_run(radtype[1])
    radrunita.font.italic = True
    alpha = radrun.add_run(radtype[2])
    alpha.font.italic = True
    alpha.font.subscript = True
    # wavelength lambda:
    radrun.add_run(' ' + wavelength)
    try:
        d_max = ' ({:.2f}{}{})'.format(
            float(radiation_wavelength) / (2 * sin(radians(float(theta_max)))),
            protected_space, angstrom)
        # 2theta range:
        main_table.cell(21, 1).text = "{:.2f} to {:.2f}{}".format(
            2 * float(theta_min), 2 * float(theta_max), d_max)
    except ValueError:
        main_table.cell(21, 1).text = '? to ?'
    main_table.cell(22, 1).text = limit_h_min + ' {} h {} '.format(less_or_equal, less_or_equal) + limit_h_max + '\n' \
                                  + limit_k_min + ' {} k {} '.format(less_or_equal, less_or_equal) + limit_k_max + '\n' \
                                  + limit_l_min + ' {} l {} '.format(less_or_equal, less_or_equal) + limit_l_max
    rint_p = main_table.cell(24, 1).paragraphs[0]
    add_r_int_value(cif, rint_p)
    main_table.cell(25, 1).paragraphs[0].add_run(completeness)
    main_table.cell(26, 1).text = this_or_quest(ls_number_reflns) + '/' \
                                  + this_or_quest(ls_number_restraints) + '/' \
                                  + this_or_quest(ls_number_parameters)
    main_table.cell(27, 1).paragraphs[0].add_run(goof)
    r1sig_p = main_table.cell(28, 1).paragraphs[0]
    rfull_p = main_table.cell(29, 1).paragraphs[0]
    add_r1sig_and_wr2full(cif, r1sig_p, rfull_p)
    main_table.cell(30, 1).text = diff_density_max + '/' + diff_density_min
    if not cif.is_centrosymm:
        main_table.cell(31,
                        1).text = cif['_refine_ls_abs_structure_Flack'] or '?'
    exti = cif['_refine_ls_extinction_coef']
    if exti not in ['.', "'.'", '?', '']:
        num = len(main_table.columns[0].cells)
        main_table.columns[1].cells[num - 1].text = exti