diff --git a/utils/table-generator/convert.py b/utils/table-generator/convert.py index 6fbce50..859762c 100755 --- a/utils/table-generator/convert.py +++ b/utils/table-generator/convert.py @@ -34,6 +34,27 @@ def convert_usecase_v1(filename, data): return generate_table(merged_lines) +def convert_activity_v1(filename, data): + split_raw_lines_from_file = [i.split(" | ") for i in data.split("\n") if i] + + if '/' in filename: + use_case_name = filename.rsplit("/", 1)[1].upper() + elif '\\' in filename: + use_case_name = filename.rsplit("\\", 1)[1].upper() + else: + use_case_name = filename.upper() + + split_raw_lines = [["ID", use_case_name]] + split_raw_lines_from_file + + merged_lines = [] + for i in split_raw_lines: + if i[0].replace(" ", "") == "": + merged_lines[-1][1] += "
" + i[1] + else: + merged_lines.append(i) + + return generate_table_with_activity_diagram(merged_lines) + def generate_table(raw_table_data): table_lines = raw_table_data transposed_table = list(zip(*table_lines)) @@ -60,15 +81,101 @@ def generate_table(raw_table_data): return "\n".join(formatted_table_lines) +def convert_line_to_activity_diagram(line): + split_line = line[1].split("
") + + result = "@startuml\n %PLACEHOLDER%\nstop\n@enduml" + + last_swimline_name = "" + initiator_name = "" + + for i in split_line: + clear_line = i.lstrip("1234567890. ") + swimline_label, combined_action = clear_line.split(" ", 1) + + action_and_exceptions = combined_action.split(" (") + + if len(action_and_exceptions) > 1: + action = action_and_exceptions[0].strip().capitalize() + exceptions = action_and_exceptions[1].strip(") ").capitalize() + else: + action = action_and_exceptions[0].strip().capitalize() + exceptions = "" + + # запам'ятовуємо назву користувача системи + # (він завжди починає взаємодію, а, отже, + # перша дія завжди належить йому) + if not initiator_name: + initiator_name = swimline_label + + # змінюємо swinline, якщо керування перейшло до іншого актора + if last_swimline_name != swimline_label: + result = result.replace("%PLACEHOLDER%", f"|{swimline_label}|\n %PLACEHOLDER%") + + # якщо це перша дія, то вказуємо start + if not last_swimline_name: + result = result.replace("%PLACEHOLDER%", f"start\n %PLACEHOLDER%") + + # зберігаємо нове ім'я актора + last_swimline_name = swimline_label + + # прописуємо поточну дію актора + result = result.replace("%PLACEHOLDER%", f": {action};\n %PLACEHOLDER%") + + # якщо є виключні ситуації, додаємо інформацію про них + if exceptions: + result = result.replace("%PLACEHOLDER%", f"note right #lightpink\n {exceptions}\n end note\n %PLACEHOLDER%") + + # впенюємося, що взаємодія закінчується на swinline користувача + if last_swimline_name != initiator_name: + result = result.replace("%PLACEHOLDER%", f"|{initiator_name}|\n %PLACEHOLDER%") + + # видаляємо мітку %PLACEHOLDER% + result = result.replace("%PLACEHOLDER%\n", "") + return result + + +def generate_table_with_activity_diagram(raw_table_data): + table_lines = raw_table_data[:-1] + activity_line = raw_table_data[-1] + + transposed_table = list(zip(*table_lines)) + + field_sizes = [max([max([len(k)+2 for k in j.split("\n")]) for j in i]) for i in transposed_table] + + formatted_table_lines = [] + + l = "|" + for i, field in enumerate(table_lines[0]): + l += field.center(field_sizes[i]) + l += "|" + + formatted_table_lines.append(l) + formatted_table_lines.append(f"|{'|'.join([':'+'-'*(i-2)+':' for i in field_sizes])}|") + + for line in table_lines[1:]: + l = "|" + for i, field in enumerate(line): + l += field.center(field_sizes[i]) + l += "|" + + formatted_table_lines.append(l) + + activity_diagram = convert_line_to_activity_diagram(activity_line) + + return "\n".join(formatted_table_lines) + "\n" + activity_diagram + if __name__=="__main__": # parse args files = [] + write_to_file = AUTO write_to_stdout = AUTO usecase_formatting = AUTO verbose = AUTO process_table_files = AUTO + convert_to_activity_diagram = AUTO file_output_path = None # 1 pass (argument harvest) @@ -104,6 +211,12 @@ if __name__=="__main__": elif i in ["-nt", "--no-process-table"]: process_table_files = NO + # перетворює останню клітинку таблиці в діаграму активностей + if i in ["-a", "--convert-to-activity-diagram"]: + convert_to_activity_diagram = YES + elif i in ["-na", "--no-convert-to-activity-diagram"]: + convert_to_activity_diagram = NO + # задає папку, в яку необхідно зберігати конвертовані таблиці elif i in ["-d", "--destination"]: file_output_path = sys.argv[n+2] @@ -133,7 +246,14 @@ if __name__=="__main__": elif (name.endswith(".usecase") or name.endswith(".uc")) and usecase_formatting >= AUTO: if verbose == YES: print(f"Auto-detected use-case in file {name}\n") - formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data) + + if convert_to_activity_diagram == YES: + if verbose == YES: + print(f"Converting file {name} to activity diagram\n") + + formatted_table_data = convert_activity_v1(name.rsplit(".", 1)[0], data) + else: + formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data) else: formatted_table_data = convert_generic_v1(data) @@ -162,7 +282,14 @@ if __name__=="__main__": elif (name.endswith(".usecase") or name.endswith(".uc")) and usecase_formatting >= AUTO: if verbose >= AUTO: print(f"Auto-detected use-case in file {name}") - formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data) + + if convert_to_activity_diagram == YES: + if verbose == YES: + print(f"Converting file {name} to activity diagram\n") + + formatted_table_data = convert_activity_v1(name.rsplit(".", 1)[0], data) + else: + formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data) else: formatted_table_data = convert_generic_v1(data) diff --git a/utils/table-generator/update-activities.sh b/utils/table-generator/update-activities.sh new file mode 100755 index 0000000..af44f7f --- /dev/null +++ b/utils/table-generator/update-activities.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +mkdir -p activities/ +./convert.py use-cases/* -a -nv -d activities/ + +if [ -f activities.md ]; then + rm activities.md +fi + +for i in activities/*; do + cat $i >> activities.md + echo "" >> activities.md +done