From 19350c70564030d16bfd88b9692d5b66579b3b3a Mon Sep 17 00:00:00 2001 From: Michele Carignani <michele.carignani@etsi.org> Date: Wed, 27 Feb 2019 23:39:10 +0100 Subject: [PATCH] produce docx --- main.py | 213 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 165 insertions(+), 48 deletions(-) diff --git a/main.py b/main.py index 0591013..a7f437f 100755 --- a/main.py +++ b/main.py @@ -1,65 +1,182 @@ #!/usr/bin/python2.7 +''' +Parses a TOSCA template and generates a docx file +''' + -import toscaparser import sys -import os -#import toscaparser.tosca_template import toscaparser.utils.yamlparser as yaml -print "Opening file " + sys.argv[1] -#res = toscaparser.validate(sys.argv[1]) -#templ = toscaparser.tosca_template.ToscaTemplate(os.path.join( -# os.path.dirname(os.path.abspath(__file__)), -# 'data', -# sys.argv[1])) +import docx +from docx.enum.text import WD_PARAGRAPH_ALIGNMENT TEMPLATES = {} -def load_template(fn, templs, key): - yaml_data = open(fn).read() - templs[key] = yaml.simple_ordered_parse(yaml_data) - -tosca_types = [ - 'data_types', - 'artifact_types', - 'capability_types', - 'requirements_types', - 'relationship_types', - 'interface_types', - 'node_types', - 'group_types', - 'policy_types' +FNS = { + 'VNFD' : 'etsi_nfv_sol001_vnfd_2_5_1_types.yaml', + 'NSD' : 'etsi_nfv_sol001_nsd_2_5_1_types.yaml', + 'PNFD' : 'etsi_nfv_sol001_pnfd_2_5_1_types.yaml' +} + +TOSCA_TYPES = [ + 'data_types', + 'artifact_types', + 'capability_types', + 'requirements_types', + 'relationship_types', + 'interface_types', + 'node_types', + 'group_types', + 'policy_types' ] -ids = [ 6, 2, 1] +TOSCA_TYPES_PRETTYPRINT = { + 'data_types': 'Data Types', + 'artifact_types': 'Artifact Types', + 'capability_types': 'Capability Types', + 'requirements_types': 'Requirements types', + 'relationship_types': 'Relationship Types', + 'interface_types': 'Interface Types', + 'node_types': 'Node Types', + 'group_types': 'Group Types', + 'policy_types': 'Policy Types' +} + + +IDS = [6, 2, 1, 1] + +doc = docx.Document() + +def load_template(file_path, templs, key): + ''' + Loads the content of the file at file_patch into the YAML templates array + ''' + yaml_data = open(file_path).read() + templs[key] = yaml.simple_ordered_parse(yaml_data) + +def print_lvl(num, txt): + index = ".".join(map(str, IDS[:(num+1)])) + print index + " " + ('-'*(num+1)) + ' ' + txt + +def add_heading_with_num(num, txt): + ''' + Add a new heading to the document, with the calculated index number + ''' + index = ".".join(map(str, IDS[:(num+1)])) + doc.add_heading(index + " " + txt, num) + +def cell_text_bold(cell): + cell.paragraphs[0].runs[0].font.bold = True + +def cell_text_centered(cell): + cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER + +def mk_props_table_hdr(table): + hdr_cells = table.rows[0].cells + hdr_cells[0].text = 'Name' + hdr_cells[1].text = 'Required' + hdr_cells[2].text = 'Type' + hdr_cells[3].text = 'Constraints' + hdr_cells[4].text = 'Description' + map(cell_text_bold, hdr_cells) + map(cell_text_centered, hdr_cells) + +def dt_name_from_path(dt_path): + return dt_path.split('.')[-1] + +def prop_field_to_str(prop_field): + if type(prop_field) == bool: + return 'yes' if prop_field else 'no' + return str(prop_field) -def print_lvl(n, txt): - index = ".".join(map(str,ids[:(n+1)])) - print index + " " + ('-'*(n+1)) + ' ' + txt +def add_prop_row(prop_name, prop_fields, table): + ''' + Add a row to table and fills it with info from prop + ''' + nrow = table.add_row() + prop_cells = nrow.cells + prop_cells[0].text = prop_name + + all_fields = ['required', 'type', 'constraints', 'description'] + + counter = 1 + for field in all_fields: + if field in prop_fields: + prop_cells[counter].text = prop_field_to_str(prop_fields[field]) + counter = counter + 1 def print_all_types(templ, lvl): - for tt in tosca_types: - if not tt in templ: - continue - print_lvl(lvl, tt) - for dt in templ[tt]: - print_lvl(lvl + 1, dt) - ids[lvl+1] = ids[lvl+1] + 1 - ids[lvl+1] = 1 - ids[lvl] = ids[lvl] + 1 - print - ids[lvl] = 2 + for tosca_type in TOSCA_TYPES: + if not tosca_type in templ: + continue + print_lvl(lvl, tosca_type) + add_heading_with_num(lvl, TOSCA_TYPES_PRETTYPRINT[tosca_type]) + for data_type in templ[tosca_type]: + print_lvl(lvl + 1, data_type) + add_heading_with_num(lvl + 1, data_type) + + if 'description' in templ[tosca_type][data_type]: + print_lvl(lvl + 2, 'Description') + add_heading_with_num(lvl + 2, 'Description') + doc.add_paragraph(templ[tosca_type][data_type]['description']) + IDS[lvl+2] = IDS[lvl+2] + 1 + + if 'properties' in templ[tosca_type][data_type]: + print_lvl(lvl + 2, 'Properties') + add_heading_with_num(lvl + 2, 'Properties') + # num_row = templ[tosca_type][data_type]['properties'].items() + doc.add_paragraph("The properties of the "+ + dt_name_from_path(data_type) + +" data type shall comply with the provisions set out in table REF_TBD.") + table = doc.add_table(rows=1, cols=5) + mk_props_table_hdr(table) + for prop in templ[tosca_type][data_type]['properties']: + # print "PROP: " + prop + ", VAL: " + str(templ[tosca_type][data_type]['properties'][prop]) + add_prop_row(prop, templ[tosca_type][data_type]['properties'][prop], table) + IDS[lvl+2] = IDS[lvl+2] + 1 + + print_lvl(lvl + 2, 'Definition') + add_heading_with_num(lvl + 2, 'Definition') + doc.add_paragraph("The syntax of the "+ + dt_name_from_path(data_type)+ + " data type shall comply with the following definition:") + def_table = doc.add_table(rows=1, cols=1) + def_table.rows[0].cells[0].text = 'TBD' + IDS[lvl+2] = IDS[lvl+2] + 1 + + print_lvl(lvl + 2, 'Examples') + add_heading_with_num(lvl + 2, 'Examples') + def_table = doc.add_table(rows=1, cols=1) + def_table.rows[0].cells[0].text = 'TBD' + IDS[lvl+2] = IDS[lvl+2] + 1 + + print_lvl(lvl + 2, 'Additional Requirements') + add_heading_with_num(lvl + 2, 'Additional Requirements') + doc.add_paragraph("None.") + IDS[lvl+2] = IDS[lvl+2] + 1 + + IDS[lvl+1] = IDS[lvl+1] + 1 + IDS[lvl+2] = 1 + + IDS[lvl+1] = 1 + IDS[lvl] = IDS[lvl] + 1 + IDS[lvl] = 2 FOLDR = sys.argv[1] -fns = { - 'VNFD' : 'etsi_nfv_sol001_vnfd_2_5_1_types.yaml', - 'NSD' : 'etsi_nfv_sol001_nsd_2_5_1_types.yaml', - 'PNFD' : 'etsi_nfv_sol001_pnfd_2_5_1_types.yaml' -} +if __name__ == "__main__": + + if len(sys.argv) < 2: + print "Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]" + + + print "Using folder: " + sys.argv[1] + + for fn in ['VNFD', 'NSD', 'PNFD']: + load_template(FOLDR + '/' + FNS[fn], TEMPLATES, fn) + print_lvl(0, fn) + add_heading_with_num(0, fn) + print_all_types(TEMPLATES[fn], 1) + IDS[0] = IDS[0] + 1 -for fn in ['VNFD', 'NSD', 'PNFD']: - load_template(FOLDR + '/' + fns[fn], TEMPLATES, fn) - print_lvl(0, fn) - print_all_types(TEMPLATES[fn], 1) - ids[0] = ids[0] + 1 + doc.save('sol001.docx') -- GitLab