Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # SI PUES COMÉIS, Ó BEBÉIS, Ó HACÉIS OTRA COSA, HACEDLO TODO Á GLORIA DE DIOS
- # - 1 Co 10:1, La Biblia
- #
- # SOLI DEO GLORIA
- #
- # Al Dios, uno y trino. Altísimo, todopoderoso; Padre de nuestro Señor Jesucristo.
- # He cometido injusticia, usando tu santo nombre en vano, durante
- # el desarrollo de este programa; pues en la impotencia de mi
- # inteligencia, después de horas de análisis, he clamado por ti en
- # desesperación reclamando una solución pronta a mi problema.
- # La he recibido:
- # root_buffer = root_buffer_arr[next_iteration_depth-(len(root_buffer_arr)+1)]
- # Mediante esta operación, es posible calcular JIT (Just-in-Time) la localización
- # de los nodos, sin costosos almacenamientos en el búfer.
- # Además, esta operación deberá invertirse cada vez que se invierta el sentido
- # de la lista.
- # Como te prometí, te doy el entero crédito de esta obra.
- import argparse;
- from colorama import Fore, Back, Style
- """
- Configuración de argumentos
- """
- parser = argparse.ArgumentParser(description="Converts Markdown lists into Mermaid flowcharts")
- parser.add_argument("input", help="Markdown list directly pasted by the user")
- # Función que podría desarrollarse a posteriori.
- # parser.add_argument("-f","--files",help="Parse markdown file that contains (only) a list", action='append',nargs='*', type=argparse.FileType("r"))
- parser.add_argument ("-dir", "--direction", help="Direction of the flowchart (default: LR)", choices=['LR', 'RL', 'TB', "BT"], default="LR", nargs="?")
- parser.add_argument("-c", "--color", help="Display color in the flowchart; BC: by concept; BL: by level", choices=['BC', 'BL'], const ="BC", default="BC", nargs="?")
- parser.add_argument("-d", "--debug", help="Debug mode", action='store_true')
- # TODO parser.add_argument("-l", "--link", help="Link the repetitive strings", nargs="?")
- # Guardar un diccionario posicion_nodo:valor. Si algún valor se repite, sustituir todas las menciones anteriores de dicho nodo por su último valor
- args = parser.parse_args()
- def debug (output):
- if args.debug:
- print(Fore.YELLOW + "%%", output, Style.RESET_ALL)
- """
- Normaliza un string para eliminar los "-" y los espacios al principio y al final.
- """
- def normalize_str (str):
- return str.replace("-", "").strip()
- """
- Función utilizada en la asignación de estilos.
- Cumple con una propiedad matemática cuyo nombre desconozco.
- Dado un número n que debe situarse dentro de un rango determinado r, hallar la posición de n en r independientemente de los valores de ambos
- """
- def reduce_until_less_than (dividend, minor):
- while (dividend > minor):
- dividend = dividend // minor
- return dividend
- """
- Calcula la profundidad total
- """
- def calc_total_depth (mdinput):
- output = 0
- for string in mdinput:
- if output < string.count("\t"):
- output = string.count("\t")
- return output
- """
- Calcula el número de nodos
- """
- def calc_total_nodes (mdinput):
- output = 0;
- for string in mdinput:
- output+=1
- return output-1
- """
- Función principal.
- El código Mermaid será devuelto por la salida estándar a medida que se procesa.
- He utilizado print () para eso, en vez de recoger todo el código en un búfer; ¿es correcto?
- La verdad es que no lo sé.
- "Is this niggerlicious, or just divine intellect?"
- - Terry Davis
- """
- def main():
- # input of the user
- mdinput= args.input.split("\n")
- #
- total_depth = calc_total_depth (mdinput)
- #
- total_nodes = calc_total_nodes (mdinput)
- # Counter of root nodes
- counter_roots =0;
- # Counter of nodes
- counter_nodes = 0;
- # root_buffer_arr
- root_buffer_arr = []
- # current_depth
- current_depth = 0
- #
- nodes_buffer_arr = []
- #
- last_node_counter =0
- #
- previus_last_node_depth = 0
- #
- fl_next_it = False
- header= f'flowchart {args.direction}'
- print (header)
- for i in range(len(mdinput)):
- string = mdinput[i]
- # Carga del nodo 0 (root).
- if "\t" not in string:
- # Formateo del nodo root
- root_buffer = f'{counter_roots}["{normalize_str(string)}"]'
- # Suma del contador para fines de posicionado
- counter_roots+=1
- # El nodo root se añade al búfer de los nodos root para retroceder en su caso
- root_buffer_arr.append (root_buffer)
- # Carga del resto de nodos
- if "\t" in string:
- # Profundidad del nodo actual
- current_depth = string.count("\t")
- # Profundidad del nodo siguiente - si existe
- if (i+1) < len(mdinput): next_iteration = '"'+normalize_str(mdinput[i+1])+'"'
- if (i+1) < len(mdinput): next_iteration_depth = mdinput[i+1].count("\t")
- if (i+2) < len(mdinput): next_next_iteration_depth = mdinput[i+2].count("\t")
- # Formateo del nodo
- node_buffer = f'{counter_roots}.{counter_nodes}["{normalize_str(string)}"]'
- # Formateo de la unión entre la raíz y el nodo
- root_union_node = f'{root_buffer} --> {node_buffer}'
- # El nodo se añade al búfer de los nodos para su posterior estilizado
- nodes_buffer_arr.append (f'{counter_roots}.{counter_nodes}')
- # Si la siguiente iteración está en un nivel de profundidad superior, el nodo actual será la raíz del siguiente.
- if (next_iteration_depth > current_depth):
- if root_buffer not in root_buffer_arr:
- debug(" + SE CREA NUEVO ROOT " + root_buffer)
- root_buffer_arr.append (root_buffer)
- root_buffer = node_buffer
- # Suma del contador para fines de posicionado
- if args.color=="BL":
- counter_roots+=1
- # Si la siguiente iteración está en un nivel de profundidad inferior
- elif (next_iteration_depth < current_depth):
- debug (" - NO SE CREA NUEVO ROOT para "+ next_iteration)
- # Asignación del nodo raíz en base a su profundidad y orientación
- try:
- if last_node_counter % 2 == 0:
- # Hacia la derecha - Positivo
- root_buffer = root_buffer_arr[(len(root_buffer_arr)+1)-next_iteration_depth]
- else:
- # Hacia la izquierda - Negativo
- root_buffer = root_buffer_arr[next_iteration_depth-(len(root_buffer_arr)+1)]
- except: # Si una orientación no funciona, se cambia a la contraria
- root_buffer = root_buffer_arr[next_iteration_depth-(len(root_buffer_arr)+1)]
- debug (" > root_buffer_arr " + "[" + ", ".join(root_buffer_arr) + "]")
- debug (" - EL ROOT DE " + next_iteration + " SERÁ " + root_buffer)
- # Suma del contador para fines de posicionado
- if args.color=="BL":
- counter_roots-=1
- else:
- counter_roots+=1
- counter_nodes= 0
- # Disparo de una flag para prevenir la suma innecesaria de un nodo
- fl_next_it = True
- else:
- # Cuando se llega al último nodo, la orientación debe cambiar para que se realicen los cálculos adecuados.
- if next_iteration_depth != previus_last_node_depth:
- last_node_counter+=1
- previus_last_node_depth = next_iteration_depth
- # Cuando el last_node_counter es mayor que 0 y divisible por 2.
- # es que se debe eliminar del root buffer la diferencia que hay desde dicho nodo hacia atrás
- # de este modo se podría lograr el funcionamiento del diagrama en el "caso X"
- debug (" - ÚLTIMO NODO, ORIENTACIÓN: "+str(last_node_counter))
- if previus_last_node_depth != next_iteration_depth:
- previus_last_node_depth =0
- # Captura de la flag anteriormente declarada
- if (fl_next_it):
- fl_next_it = False
- else:
- counter_nodes +=1
- print (root_union_node)
- """
- Asociación de color - se pueden añadir todos los colores que se deseen, asegurándose que el número de la clase sea el correcto
- """
- if (args.color):
- color_dict = [
- "classDef Class_1 fill:#ceddff",
- "classDef Class_2 fill:#ffa8ee",
- "classDef Class_3 fill:#C8E6C9",
- "classDef Class_4 fill:#FFF9C4",
- "classDef Class_5 fill:#FFE0B2",
- "classDef Class_6 fill:#E1BEE7",
- "classDef Class_7 fill:#FFCDD2",
- ]
- for node in nodes_buffer_arr:
- print (f'{node}:::Class_{reduce_until_less_than (int (node[0]), len(color_dict))}')
- for color in color_dict:
- print (color)
- """
- Insertar el input original en forma de comentarios
- """
- print (f"%% Made with MDLMMD: *Converts Markdown lists into Mermaid flowcharts*")
- print (f"%% SOURCE LIST: ")
- for string in mdinput:
- print (f'%% {string}')
- if __name__ == "__main__":
- main()
- # Copyright (C) 2025 SDG-HURSZ
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
Advertisement
Add Comment
Please, Sign In to add comment