Loading doc2tosca.py +54 −21 Original line number Diff line number Diff line Loading @@ -4,7 +4,8 @@ Generate tosca definitions from Docx specfication ''' import sys from io import BytesIO as StringIO import re from io import StringIO import docx from docx.table import Table Loading @@ -12,31 +13,37 @@ from docx.text.paragraph import Paragraph BASE_FILENAME = "try-tosca-export_{}.yaml" TOSCA_VERSION = "tosca_simple_yaml_1_2" SPEC_VERSION = "2.5.1" SPEC_VERSION = "2.6.1" MODEL_NAMES = ['vnfd', 'nsd', 'pnfd', 'common'] HDR = '''tosca_definitions_version: {tosca_version} description: ETSI NFV SOL 001 {model} types definitions version {spec_version} metadata: - template_name: {model} - template_name: ETSI_NFV - template_version: {spec_version} imports: {imports} data_types: ''' def match_definition_incipit(txt): return bool(re.match(r'^tosca\.[a-zA-Z\.:0-9\s]*$',txt.split("\n")[0].strip())) def is_tosca_def(table): ''' Returns true when a table contains TOSCA definitions, i.e. the table contains just one cell and text starts with an empty space ' ' ''' txt = table.rows[0].cells[0].text[0] txt = table.rows[0].cells[0].text return \ len(table.rows) == 1 and \ len(table.columns) == 1 and \ txt.startswith(' ') match_definition_incipit(txt) def tosca_model_info(name, imports): ''' Loading Loading @@ -66,9 +73,9 @@ def get_content(doc): ret.append(Table(element, body)) table_count = table_count + 1 else: print "Non paragraph or table " + str(type(element)) print "Paragraphs: " + str(parag_count) print "Tables: " + str(table_count) print("Non paragraph or table " + str(type(element))) print("Paragraphs: " + str(parag_count)) print("Tables: " + str(table_count)) return ret def find_sect(sect_to_find, start_idx, doc_content): Loading @@ -83,15 +90,29 @@ def find_sect(sect_to_find, start_idx, doc_content): break start_idx = start_idx + 1 print "FOUND " + sect_to_find + " at " + str(start_idx) print("FOUND " + sect_to_find + " at " + str(start_idx)) return start_idx def write_table_to_file(tab, buf): ''' Writes content of table t in utf-8 encoding to file F ''' buf.write(tab.rows[0].cells[0].text.encode('utf-8')) buf.write('\n# -------------------- #\n') def pad2 (txt): if txt.startswith(" "): return " " + txt if txt.startswith(" "): return " " + txt if txt.startswith(" "): return " " + txt return " " + txt txt = tab.rows[0].cells[0].text # print("+++++ Included in: " + tab.rows[0].cells[0].text.split("\n")[0]) buf.write("\n".join([pad2(x) for x in txt.split("\n")])) # buf.write('\n# -------------------- #\n') if not txt.endswith('\n'): buf.write('\n') buf.write('\n') def generate_tables_between(a_id, b_id, content, buf): ''' Loading @@ -104,6 +125,18 @@ def generate_tables_between(a_id, b_id, content, buf): if isinstance(tmp_elem, Table) and is_tosca_def(tmp_elem): write_table_to_file(tmp_elem, buf) definitions_count = definitions_count + 1 elif isinstance(tmp_elem, Table): txt = tmp_elem.rows[0].cells[0].text if txt.strip().startswith("Name") or txt.strip().startswith("Shorthand") or \ txt.strip().startswith("tosca_def"): continue print("----- Filtered out: " + txt.split("\n")[0]) if not len(tmp_elem.rows) == 1: print(" Rows count != 1 ") if not len(tmp_elem.columns) == 1: print(" Columns count != 1 ") if not match_definition_incipit(txt): print(" Regex != 1 ") return definitions_count def dump_header(model_name, buf, imports): Loading @@ -127,11 +160,11 @@ if __name__ == "__main__": try: SOL001_FN = sys.argv[1] except: print 'Error: Filename missing or filename not a docx document' print 'Usage: doc2tosca <docx-with-tosca-definitions>' print('Error: Filename missing or filename not a docx document') print('Usage: doc2tosca <docx-with-tosca-definitions>') sys.exit(1) print "Opening " + SOL001_FN print( "Opening " + SOL001_FN) SOL001 = docx.Document(SOL001_FN) Loading @@ -152,7 +185,7 @@ if __name__ == "__main__": p_id = p_id + 1 if p_id >= len(CONTENT): print "FOREWORD NOT FOUND" print( "FOREWORD NOT FOUND") sect_6_id = find_sect("6\tVNFD TOSCA model", p_id, CONTENT) Loading @@ -163,13 +196,13 @@ if __name__ == "__main__": annex_a_id = find_sect("Annex A (informative):", sect_7_id + 1, CONTENT) count = generate_tables_between(sect_6_id, sect_7_id, CONTENT, MODELS['vnfd']['buf']) print "Printed " + str(count) + " types to " + "VNFD" print("Printed " + str(count) + " types to " + "VNFD\n\n\n") count = generate_tables_between(sect_7_id, sect_8_id, CONTENT, MODELS['nsd']['buf']) print "Printed " + str(count) + " types to " + "NSD" print("Printed " + str(count) + " types to " + "NSD\n\n\n") count = generate_tables_between(sect_8_id, annex_a_id, CONTENT, MODELS['pnfd']['buf']) print "Printed " + str(count) + " types to " + "PNFD" print("Printed " + str(count) + " types to " + "PNFD\n\n\n") for m in MODELS: MODELS[m]['fd'] = open(MODELS[m]['fn'], 'w') Loading tosca2doc.py +3 −4 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ Parses a TOSCA template and generates a docx file ''' import sys import toscaparser.utils.yamlparser as yaml Loading Loading @@ -61,7 +60,7 @@ def print_lvl(num, txt): if num + 1 > PRINT_TRESHOLD: return index = ".".join(map(str, IDS[:(num+1)])) print index + " " + ('-'*(num+1)) + ' ' + txt print(index + " " + ('-'*(num+1)) + ' ' + txt) def add_heading_with_num(num, txt, doc): ''' Loading Loading @@ -178,12 +177,12 @@ if __name__ == "__main__": doc = docx.Document() if len(sys.argv) < 2: print "Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]" print("Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]") sys.exit() FOLDR = sys.argv[1] print "Using folder: " + sys.argv[1] print("Using folder: " + sys.argv[1]) for fn in ['VNFD', 'NSD', 'PNFD']: generate_from_file(fn, doc, FOLDR + '/' + FNS[fn]) Loading Loading
doc2tosca.py +54 −21 Original line number Diff line number Diff line Loading @@ -4,7 +4,8 @@ Generate tosca definitions from Docx specfication ''' import sys from io import BytesIO as StringIO import re from io import StringIO import docx from docx.table import Table Loading @@ -12,31 +13,37 @@ from docx.text.paragraph import Paragraph BASE_FILENAME = "try-tosca-export_{}.yaml" TOSCA_VERSION = "tosca_simple_yaml_1_2" SPEC_VERSION = "2.5.1" SPEC_VERSION = "2.6.1" MODEL_NAMES = ['vnfd', 'nsd', 'pnfd', 'common'] HDR = '''tosca_definitions_version: {tosca_version} description: ETSI NFV SOL 001 {model} types definitions version {spec_version} metadata: - template_name: {model} - template_name: ETSI_NFV - template_version: {spec_version} imports: {imports} data_types: ''' def match_definition_incipit(txt): return bool(re.match(r'^tosca\.[a-zA-Z\.:0-9\s]*$',txt.split("\n")[0].strip())) def is_tosca_def(table): ''' Returns true when a table contains TOSCA definitions, i.e. the table contains just one cell and text starts with an empty space ' ' ''' txt = table.rows[0].cells[0].text[0] txt = table.rows[0].cells[0].text return \ len(table.rows) == 1 and \ len(table.columns) == 1 and \ txt.startswith(' ') match_definition_incipit(txt) def tosca_model_info(name, imports): ''' Loading Loading @@ -66,9 +73,9 @@ def get_content(doc): ret.append(Table(element, body)) table_count = table_count + 1 else: print "Non paragraph or table " + str(type(element)) print "Paragraphs: " + str(parag_count) print "Tables: " + str(table_count) print("Non paragraph or table " + str(type(element))) print("Paragraphs: " + str(parag_count)) print("Tables: " + str(table_count)) return ret def find_sect(sect_to_find, start_idx, doc_content): Loading @@ -83,15 +90,29 @@ def find_sect(sect_to_find, start_idx, doc_content): break start_idx = start_idx + 1 print "FOUND " + sect_to_find + " at " + str(start_idx) print("FOUND " + sect_to_find + " at " + str(start_idx)) return start_idx def write_table_to_file(tab, buf): ''' Writes content of table t in utf-8 encoding to file F ''' buf.write(tab.rows[0].cells[0].text.encode('utf-8')) buf.write('\n# -------------------- #\n') def pad2 (txt): if txt.startswith(" "): return " " + txt if txt.startswith(" "): return " " + txt if txt.startswith(" "): return " " + txt return " " + txt txt = tab.rows[0].cells[0].text # print("+++++ Included in: " + tab.rows[0].cells[0].text.split("\n")[0]) buf.write("\n".join([pad2(x) for x in txt.split("\n")])) # buf.write('\n# -------------------- #\n') if not txt.endswith('\n'): buf.write('\n') buf.write('\n') def generate_tables_between(a_id, b_id, content, buf): ''' Loading @@ -104,6 +125,18 @@ def generate_tables_between(a_id, b_id, content, buf): if isinstance(tmp_elem, Table) and is_tosca_def(tmp_elem): write_table_to_file(tmp_elem, buf) definitions_count = definitions_count + 1 elif isinstance(tmp_elem, Table): txt = tmp_elem.rows[0].cells[0].text if txt.strip().startswith("Name") or txt.strip().startswith("Shorthand") or \ txt.strip().startswith("tosca_def"): continue print("----- Filtered out: " + txt.split("\n")[0]) if not len(tmp_elem.rows) == 1: print(" Rows count != 1 ") if not len(tmp_elem.columns) == 1: print(" Columns count != 1 ") if not match_definition_incipit(txt): print(" Regex != 1 ") return definitions_count def dump_header(model_name, buf, imports): Loading @@ -127,11 +160,11 @@ if __name__ == "__main__": try: SOL001_FN = sys.argv[1] except: print 'Error: Filename missing or filename not a docx document' print 'Usage: doc2tosca <docx-with-tosca-definitions>' print('Error: Filename missing or filename not a docx document') print('Usage: doc2tosca <docx-with-tosca-definitions>') sys.exit(1) print "Opening " + SOL001_FN print( "Opening " + SOL001_FN) SOL001 = docx.Document(SOL001_FN) Loading @@ -152,7 +185,7 @@ if __name__ == "__main__": p_id = p_id + 1 if p_id >= len(CONTENT): print "FOREWORD NOT FOUND" print( "FOREWORD NOT FOUND") sect_6_id = find_sect("6\tVNFD TOSCA model", p_id, CONTENT) Loading @@ -163,13 +196,13 @@ if __name__ == "__main__": annex_a_id = find_sect("Annex A (informative):", sect_7_id + 1, CONTENT) count = generate_tables_between(sect_6_id, sect_7_id, CONTENT, MODELS['vnfd']['buf']) print "Printed " + str(count) + " types to " + "VNFD" print("Printed " + str(count) + " types to " + "VNFD\n\n\n") count = generate_tables_between(sect_7_id, sect_8_id, CONTENT, MODELS['nsd']['buf']) print "Printed " + str(count) + " types to " + "NSD" print("Printed " + str(count) + " types to " + "NSD\n\n\n") count = generate_tables_between(sect_8_id, annex_a_id, CONTENT, MODELS['pnfd']['buf']) print "Printed " + str(count) + " types to " + "PNFD" print("Printed " + str(count) + " types to " + "PNFD\n\n\n") for m in MODELS: MODELS[m]['fd'] = open(MODELS[m]['fn'], 'w') Loading
tosca2doc.py +3 −4 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ Parses a TOSCA template and generates a docx file ''' import sys import toscaparser.utils.yamlparser as yaml Loading Loading @@ -61,7 +60,7 @@ def print_lvl(num, txt): if num + 1 > PRINT_TRESHOLD: return index = ".".join(map(str, IDS[:(num+1)])) print index + " " + ('-'*(num+1)) + ' ' + txt print(index + " " + ('-'*(num+1)) + ' ' + txt) def add_heading_with_num(num, txt, doc): ''' Loading Loading @@ -178,12 +177,12 @@ if __name__ == "__main__": doc = docx.Document() if len(sys.argv) < 2: print "Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]" print("Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]") sys.exit() FOLDR = sys.argv[1] print "Using folder: " + sys.argv[1] print("Using folder: " + sys.argv[1]) for fn in ['VNFD', 'NSD', 'PNFD']: generate_from_file(fn, doc, FOLDR + '/' + FNS[fn]) Loading