Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Generate Excalidraw .excalidraw JSON diagram files from natural language descriptions of processes and systems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/split-excalidraw-library.py
1#!/usr/bin/env python32"""3Excalidraw Library Splitter45This script splits an Excalidraw library file (*.excalidrawlib) into individual6icon JSON files and generates a reference.md file for easy lookup.78The script expects the following structure:9skills/excalidraw-diagram-generator/libraries/{icon-set-name}/10{icon-set-name}.excalidrawlib (place this file first)1112Usage:13python split-excalidraw-library.py <path-to-library-directory>1415Example:16python split-excalidraw-library.py skills/excalidraw-diagram-generator/libraries/aws-architecture-icons/17"""1819import json20import os21import re22import sys23from pathlib import Path242526def sanitize_filename(name: str) -> str:27"""28Sanitize icon name to create a valid filename.2930Args:31name: Original icon name3233Returns:34Sanitized filename safe for all platforms35"""36# Replace spaces with hyphens37filename = name.replace(' ', '-')3839# Remove or replace special characters40filename = re.sub(r'[^\w\-.]', '', filename)4142# Remove multiple consecutive hyphens43filename = re.sub(r'-+', '-', filename)4445# Remove leading/trailing hyphens46filename = filename.strip('-')4748return filename495051def find_library_file(directory: Path) -> Path:52"""53Find the .excalidrawlib file in the given directory.5455Args:56directory: Directory to search5758Returns:59Path to the library file6061Raises:62SystemExit: If no library file or multiple library files found63"""64library_files = list(directory.glob('*.excalidrawlib'))6566if len(library_files) == 0:67print(f"Error: No .excalidrawlib file found in {directory}")68print(f"Please place a .excalidrawlib file in {directory} first.")69sys.exit(1)7071if len(library_files) > 1:72print(f"Error: Multiple .excalidrawlib files found in {directory}")73print(f"Please keep only one library file in {directory}.")74sys.exit(1)7576return library_files[0]777879def split_library(library_dir: str) -> None:80"""81Split an Excalidraw library file into individual icon files.8283Args:84library_dir: Path to the directory containing the .excalidrawlib file85"""86library_dir = Path(library_dir)8788if not library_dir.exists():89print(f"Error: Directory not found: {library_dir}")90sys.exit(1)9192if not library_dir.is_dir():93print(f"Error: Path is not a directory: {library_dir}")94sys.exit(1)9596# Find the library file97library_path = find_library_file(library_dir)98print(f"Found library: {library_path.name}")99100# Load library file101print(f"Loading library data...")102with open(library_path, 'r', encoding='utf-8') as f:103library_data = json.load(f)104105# Validate library structure106if 'libraryItems' not in library_data:107print("Error: Invalid library file format (missing 'libraryItems')")108sys.exit(1)109110# Create icons directory111icons_dir = library_dir / 'icons'112icons_dir.mkdir(exist_ok=True)113print(f"Output directory: {library_dir}")114115# Process each library item (icon)116library_items = library_data['libraryItems']117icon_list = []118119print(f"Processing {len(library_items)} icons...")120121for item in library_items:122# Get icon name123icon_name = item.get('name', 'Unnamed')124125# Create sanitized filename126filename = sanitize_filename(icon_name) + '.json'127128# Save icon data129icon_path = icons_dir / filename130with open(icon_path, 'w', encoding='utf-8') as f:131json.dump(item, f, ensure_ascii=False, indent=2)132133# Add to reference list134icon_list.append({135'name': icon_name,136'filename': filename137})138139print(f" โ {icon_name} โ {filename}")140141# Sort icon list by name142icon_list.sort(key=lambda x: x['name'])143144# Generate reference.md145library_name = library_path.stem146reference_path = library_dir / 'reference.md'147with open(reference_path, 'w', encoding='utf-8') as f:148f.write(f"# {library_name} Reference\n\n")149f.write(f"This directory contains {len(icon_list)} icons extracted from `{library_path.name}`.\n\n")150f.write("## Available Icons\n\n")151f.write("| Icon Name | Filename |\n")152f.write("|-----------|----------|\n")153154for icon in icon_list:155f.write(f"| {icon['name']} | `icons/{icon['filename']}` |\n")156157f.write("\n## Usage\n\n")158f.write("Each icon JSON file contains the complete `elements` array needed to render that icon in Excalidraw.\n")159f.write("You can copy the elements from these files into your Excalidraw diagrams.\n")160161print(f"\nโ Successfully split library into {len(icon_list)} icons")162print(f"๐ Reference file created: {reference_path}")163print(f"๐ Icons directory: {icons_dir}")164165166def main():167"""Main entry point."""168if hasattr(sys.stdout, "reconfigure"):169# Ensure consistent UTF-8 output on Windows consoles.170sys.stdout.reconfigure(encoding="utf-8")171if len(sys.argv) != 2:172print("Usage: python split-excalidraw-library.py <path-to-library-directory>")173print("\nExample:")174print(" python split-excalidraw-library.py skills/excalidraw-diagram-generator/libraries/aws-architecture-icons/")175print("\nNote: The directory should contain a .excalidrawlib file.")176sys.exit(1)177178library_dir = sys.argv[1]179split_library(library_dir)180181182if __name__ == '__main__':183main()184