88import json
99import os
1010import sys
11+ import re
1112
1213def convert_json_to_html (json_path , output_path ):
1314 """Convert a Chart Studio JSON export to standalone HTML"""
@@ -37,6 +38,18 @@ def convert_json_to_html(json_path, output_path):
3738
3839 return output_path
3940
41+ def sanitize_filename (title ):
42+ """Convert a title to a safe filename"""
43+ # Remove any characters that aren't alphanumeric, spaces, hyphens, or underscores
44+ safe_name = re .sub (r'[^\w\s-]' , '' , title )
45+ # Replace spaces with hyphens
46+ safe_name = re .sub (r'\s+' , '-' , safe_name )
47+ # Remove multiple consecutive hyphens
48+ safe_name = re .sub (r'-+' , '-' , safe_name )
49+ # Strip leading/trailing hyphens
50+ safe_name = safe_name .strip ('-' )
51+ return safe_name if safe_name else 'chart'
52+
4053def main ():
4154 # Convert all JSON files in the json/ directory (including subdirectories)
4255 json_dir = "json"
@@ -60,8 +73,36 @@ def main():
6073 # Calculate relative path from json_dir
6174 rel_path = os .path .relpath (json_path , json_dir )
6275
63- # Create corresponding output path in charts_dir
64- html_rel_path = rel_path .replace ('.json' , '.html' )
76+ # Try to extract title from the JSON to use as filename
77+ try :
78+ with open (json_path , 'r' ) as f :
79+ chart_data = json .load (f )
80+
81+ # Check if layout.title exists
82+ layout = chart_data .get ('layout' , {})
83+ title = None
84+
85+ # Handle both string titles and object titles
86+ if 'title' in layout :
87+ if isinstance (layout ['title' ], str ):
88+ title = layout ['title' ]
89+ elif isinstance (layout ['title' ], dict ) and 'text' in layout ['title' ]:
90+ title = layout ['title' ]['text' ]
91+
92+ if title :
93+ # Use sanitized title as filename
94+ html_filename = sanitize_filename (title ) + '.html'
95+ # Preserve the subdirectory structure
96+ rel_dir = os .path .dirname (rel_path )
97+ html_rel_path = os .path .join (rel_dir , html_filename ) if rel_dir else html_filename
98+ else :
99+ # Fall back to original filename
100+ html_rel_path = rel_path .replace ('.json' , '.html' )
101+
102+ except Exception :
103+ # If we can't read the JSON, fall back to original filename
104+ html_rel_path = rel_path .replace ('.json' , '.html' )
105+
65106 html_path = os .path .join (charts_dir , html_rel_path )
66107
67108 # Create subdirectories if needed
0 commit comments