Skip to content

Instantly share code, notes, and snippets.

@GaryLee
Last active March 5, 2024 02:44
Show Gist options
  • Save GaryLee/e64c2cfa1c24c2ada34685fa4acb74d3 to your computer and use it in GitHub Desktop.
Save GaryLee/e64c2cfa1c24c2ada34685fa4acb74d3 to your computer and use it in GitHub Desktop.
This script can parse the drawio file and export all pages into distinct SVG files.
#!python
# coding: utf-8
'''Parse drawio file and generate command lines for export figures with drawio app.'''
import click
import re
import platform
from cmdlet.cmds import *
DRAWIO_BIN = {
'Windows': r'draw.io.exe',
'Darwin': r'/Applications/draw.io.app/Contents/MacOS/draw.io',
'Linux': r'draw.io',
}
DRAWIO = DRAWIO_BIN[platform.system()]
DRAWIO_FILE = r'figures.drawio'
EXPORT_PATH = r'..\docs\figures'
def get_page_info(file):
pages = {}
pattern = r"\s*<diagram(\s+(?P<key1>\w+)\s*=\s*\"(?P<value1>[^\"]+)\")(\s+(?P<key2>\w+)\s*=\s*\"(?P<value2>[^\"]+)\").*"
query_topic = readline(f'{file}') | \
match(pattern, to=dict)
for i, figure in enumerate(query_topic):
pages[i] = figure['value1'] if figure['key1'] == 'name' else figure['value2']
return pages
def export_page(page, figure, drawio_file, show_cmd=True):
cmd_export = sh(f'''"{DRAWIO}" --export --format=svg -p {page} --enable-plugins --output="{EXPORT_PATH}\\{figure}.svg" {drawio_file}''')
if show_cmd:
print('\n'.join(cmd_export.result()))
def export_pages(page_info, drawio_file, page_req):
for page, figure in page_info.items():
if not is_page_match_req(page, page_req):
continue
export_page(page, figure, drawio_file)
def is_page_match_req(page, req):
"""Check if the page matches the requirement. If req is None, all pages will be exported."""
if req is None:
return True # If no req specified, export all pages.
for r in req:
if r['i'] is not None:
if r['i'] == page:
return True
elif r['s'] is not None and r['e'] is not None:
if r['s'] <= page <= r['e']:
return True
return False # None req matches, return False.
def parse_pages_req(pages):
if not pages:
return None
req = []
for m in re.finditer(r'((?P<s>\d+)\s*\-\s*(?P<e>\d+)|(?P<i>\d+))', pages):
g = {k: int(v) if v is not None else None for k, v in m.groupdict().items()}
req.append(g)
return req
@click.command()
@click.option('-o', '--output', 'output', type=click.Path(exists=True), help='The output path of the exported figures.')
@click.option('-p', '--pages', 'pages', help='The pages to be exported(page starts from 0). Use `-` for range. e.g. 0,5,7-9.')
@click.argument('files', nargs=-1, type=click.Path(exists=True))
def export_drawio(output, files, pages):
"""Export pages from given drawio files."""
if not files:
files = [DRAWIO_FILE]
if not output:
output = EXPORT_PATH
page_req = parse_pages_req(pages)
for filename in files:
export_pages(get_page_info(filename), filename, page_req)
if __name__ == '__main__':
export_drawio()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment