import xml.etree.ElementTree as ET
import re
def markdown_to_mm(md_file_path, output_mm_path):
# Root <map> element required by FreeMind/Freeplane
map_elem = ET.Element('map', version='1.0.1')
# Root node
root_node = ET.SubElement(map_elem, 'node', TEXT='Root Mindmap')
# Track hierarchy using a stack: (level, xml_node_element)
stack = [(0, root_node)]
with open(md_file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
line_str = line.strip()
if not line_str:
continue
level = None
text = ""
# Match Markdown headers (# Header 1, ## Header 2)
heading_match = re.match(r'^(#+)\s+(.*)', line_str)
if heading_match:
level = len(heading_match.group(1))
text = heading_match.group(2)
else:
# Match bullet lists (- or *) with indentation
bullet_match = re.match(r'^(\s*)([-*])\s+(.*)', line)
if bullet_match:
indent_spaces = len(bullet_match.group(1))
# Treat every 2 or 4 spaces as 1 indent level
level = (indent_spaces // 2) + 1
text = bullet_match.group(3)
if level is not None:
# Pop stack until we find the parent level
while stack and stack[-1][0] >= level:
stack.pop()
parent_node = stack[-1][1] if stack else root_node
new_node = ET.SubElement(parent_node, 'node', TEXT=text)
stack.append((level, new_node))
# Write out to .mm XML format
tree = ET.ElementTree(map_elem)
ET.indent(tree, space=" ") # Pretty print XML formatting
tree.write(output_mm_path, encoding='utf-8', xml_declaration=True)
print(f"Successfully converted '{md_file_path}' to '{output_mm_path}'")
# Usage:
# markdown_to_mm('input.md', 'output.mm')
markdown_to_mm('The Charisma Myth Mastering.coggle.md', 'The Charisma Myth Mastering.coggle.mm')
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)