Skip to content

Commit be685f2

Browse files
committed
adjust docs UI
1 parent e73f165 commit be685f2

1 file changed

Lines changed: 137 additions & 26 deletions

File tree

codewiki/cli/html_generator.py

Lines changed: 137 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,32 @@ def load_metadata(self, docs_dir: Path) -> Optional[Dict[str, Any]]:
8181
return None
8282

8383

84+
def load_all_markdown_files(self, docs_dir: Path) -> Dict[str, str]:
85+
"""
86+
Load all markdown files from documentation directory.
87+
88+
Args:
89+
docs_dir: Documentation directory path
90+
91+
Returns:
92+
Dictionary mapping filename to markdown content
93+
"""
94+
markdown_files = {}
95+
96+
if not docs_dir.exists():
97+
return markdown_files
98+
99+
# Load all .md files in the directory
100+
for md_file in docs_dir.glob("*.md"):
101+
try:
102+
content = safe_read(md_file)
103+
markdown_files[md_file.name] = content
104+
except Exception:
105+
# Skip files that can't be read
106+
pass
107+
108+
return markdown_files
109+
84110
def generate(
85111
self,
86112
output_path: Path,
@@ -112,6 +138,11 @@ def generate(
112138
if docs_dir and metadata is None:
113139
metadata = self.load_metadata(docs_dir)
114140

141+
# Load all markdown content
142+
markdown_content = {}
143+
if docs_dir:
144+
markdown_content = self.load_all_markdown_files(docs_dir)
145+
115146
# Default values
116147
if module_tree is None:
117148
module_tree = {}
@@ -126,7 +157,8 @@ def generate(
126157
repository_url=repository_url,
127158
github_pages_url=github_pages_url,
128159
metadata=metadata,
129-
config=config
160+
config=config,
161+
markdown_content=markdown_content
130162
)
131163

132164
# Write to file
@@ -139,7 +171,8 @@ def _generate_html_template(
139171
repository_url: Optional[str],
140172
github_pages_url: Optional[str],
141173
metadata: Optional[Dict[str, Any]],
142-
config: Dict[str, Any]
174+
config: Dict[str, Any],
175+
markdown_content: Dict[str, str] = None
143176
) -> str:
144177
"""
145178
Generate the complete HTML template with embedded styles and scripts.
@@ -151,13 +184,15 @@ def _generate_html_template(
151184
github_pages_url: GitHub Pages URL
152185
metadata: Metadata dictionary
153186
config: Additional configuration
187+
markdown_content: Dictionary of markdown file contents
154188
155189
Returns:
156190
Complete HTML string
157191
"""
158192
# Escape and prepare JSON data for embedding
159193
module_tree_json = json.dumps(module_tree)
160194
metadata_json = json.dumps(metadata) if metadata else "null"
195+
markdown_content_json = json.dumps(markdown_content) if markdown_content else "{}"
161196

162197
html = f'''<!DOCTYPE html>
163198
<html lang="en">
@@ -448,7 +483,7 @@ def _generate_html_template(
448483
<body>
449484
<div class="container">
450485
<nav class="sidebar" id="sidebar">
451-
<div class="logo" onclick="loadPage('overview.md')">📚 {self._escape_html(title)}</div>
486+
<div class="logo" onclick="loadPage(\\'overview.md\\')">📚 {self._escape_html(title)}</div>
452487
453488
<div id="metadata-container"></div>
454489
<div id="navigation-container"></div>
@@ -467,6 +502,7 @@ def _generate_html_template(
467502
const METADATA = {metadata_json};
468503
const REPO_URL = {json.dumps(repository_url) if repository_url else "null"};
469504
const GITHUB_PAGES_URL = {json.dumps(github_pages_url) if github_pages_url else "null"};
505+
const MARKDOWN_CONTENT = {markdown_content_json};
470506
471507
// Current state
472508
let currentPage = 'overview.md';
@@ -568,7 +604,7 @@ def _generate_html_template(
568604
569605
// Add overview link
570606
let html = '<div class="nav-section">';
571-
html += '<div class="nav-item' + (currentPage === 'overview.md' ? ' active' : '') + '" onclick="loadPage(\'overview.md\')">Overview</div>';
607+
html += '<div class="nav-item' + (currentPage === 'overview.md' ? ' active' : '') + '" onclick="loadPage(\\'overview.md\\')">Overview</div>';
572608
html += '</div>';
573609
574610
// Render module tree
@@ -593,7 +629,7 @@ def _generate_html_template(
593629
// If has components, it's a clickable page
594630
if (data.components && data.components.length > 0) {{
595631
const classes = 'nav-item' + (isActive ? ' active' : '');
596-
html += `<div class="${{classes}}" onclick="loadPage('${{filename}}')">${{escapeHtml(displayName)}}</div>`;
632+
html += `<div class="${{classes}}" onclick="loadPage(\\'${{filename}}\\')">${{escapeHtml(displayName)}}</div>`;
597633
}} else {{
598634
// Otherwise it's just a header
599635
html += `<div class="nav-section-header">${{escapeHtml(displayName)}}</div>`;
@@ -616,25 +652,41 @@ def _generate_html_template(
616652
617653
// Load and render a markdown page
618654
async function loadPage(filename) {{
655+
console.log('[loadPage] Starting for:', filename);
619656
currentPage = filename;
620657
const contentEl = document.getElementById('content');
621658
622659
try {{
623660
// Show loading
624661
contentEl.innerHTML = '<div class="loading">Loading...</div>';
662+
console.log('[loadPage] Set loading message');
625663
626-
// Fetch markdown file
627-
const response = await fetch(filename);
664+
let markdown;
628665
629-
if (!response.ok) {{
630-
throw new Error(`Failed to load ${{filename}}: ${{response.statusText}}`);
666+
// Try to get content from embedded data first
667+
console.log('[loadPage] Checking MARKDOWN_CONTENT:', typeof MARKDOWN_CONTENT, Object.keys(MARKDOWN_CONTENT || {{}}).length);
668+
if (MARKDOWN_CONTENT && MARKDOWN_CONTENT[filename]) {{
669+
markdown = MARKDOWN_CONTENT[filename];
670+
console.log('[loadPage] Got embedded content, length:', markdown.length);
671+
}} else {{
672+
console.log('[loadPage] Embedded content not found, fetching...');
673+
// Fallback to fetching if not embedded (for backward compatibility)
674+
const response = await fetch(filename);
675+
676+
if (!response.ok) {{
677+
throw new Error(`Failed to load ${{filename}}: ${{response.statusText}}`);
678+
}}
679+
680+
markdown = await response.text();
681+
console.log('[loadPage] Fetched content, length:', markdown.length);
631682
}}
632683
633-
const markdown = await response.text();
634-
635684
// Convert to HTML
685+
console.log('[loadPage] Converting markdown to HTML with marked.parse()');
636686
const html = marked.parse(markdown);
687+
console.log('[loadPage] Converted, HTML length:', html.length);
637688
contentEl.innerHTML = html;
689+
console.log('[loadPage] Set content innerHTML');
638690
639691
// Render mermaid diagrams
640692
await mermaid.run({{
@@ -652,13 +704,26 @@ def _generate_html_template(
652704
653705
}} catch (error) {{
654706
console.error('Error loading page:', error);
655-
contentEl.innerHTML = `
707+
708+
let errorHtml = `
656709
<div class="error-message">
657710
<h3>Error Loading Page</h3>
658711
<p>Could not load <strong>${{escapeHtml(filename)}}</strong></p>
659-
<p>${{escapeHtml(error.message)}}</p>
660-
</div>
712+
<p><strong>Error:</strong> ${{escapeHtml(error.message)}}</p>
661713
`;
714+
715+
// Check if markdown content is missing
716+
if (!MARKDOWN_CONTENT || Object.keys(MARKDOWN_CONTENT).length === 0) {{
717+
errorHtml += `
718+
<p style="margin-top: 1rem; padding: 1rem; background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px;">
719+
<strong>Note:</strong> This HTML file was generated without embedded markdown content.
720+
Regenerate the documentation with the latest version to embed all markdown files.
721+
</p>
722+
`;
723+
}}
724+
725+
errorHtml += '</div>';
726+
contentEl.innerHTML = errorHtml;
662727
}}
663728
}}
664729
@@ -672,24 +737,70 @@ def _generate_html_template(
672737
673738
// Initialize app
674739
async function init() {{
675-
// Render metadata and navigation
676-
renderMetadata();
677-
renderNavigation();
740+
console.log('[init] Starting initialization');
741+
console.log('[init] marked:', typeof marked);
742+
console.log('[init] mermaid:', typeof mermaid);
743+
console.log('[init] MARKDOWN_CONTENT keys:', Object.keys(MARKDOWN_CONTENT || {{}}).slice(0, 5));
678744
679-
// Load initial page from hash or default to overview
680-
const hash = window.location.hash.substring(1);
681-
const initialPage = hash && hash.endsWith('.md') ? hash : 'overview.md';
682-
await loadPage(initialPage);
683-
684-
// Listen for hash changes
685-
window.addEventListener('hashchange', handleHashChange);
745+
try {{
746+
// Render metadata and navigation
747+
console.log('[init] Rendering metadata');
748+
renderMetadata();
749+
console.log('[init] Rendering navigation');
750+
renderNavigation();
751+
752+
// Load initial page from hash or default to overview
753+
const hash = window.location.hash.substring(1);
754+
const initialPage = hash && hash.endsWith('.md') ? hash : 'overview.md';
755+
console.log('[init] Initial page:', initialPage);
756+
await loadPage(initialPage);
757+
console.log('[init] Page loaded successfully');
758+
759+
// Listen for hash changes
760+
window.addEventListener('hashchange', handleHashChange);
761+
console.log('[init] Initialization complete');
762+
}} catch (error) {{
763+
console.error('[init] ERROR:', error);
764+
const contentEl = document.getElementById('content');
765+
contentEl.innerHTML = `
766+
<div class="error-message">
767+
<h3>Initialization Error</h3>
768+
<p><strong>Error:</strong> ${{error.message}}</p>
769+
<pre>${{error.stack}}</pre>
770+
</div>
771+
`;
772+
}}
773+
}}
774+
775+
// Check if external libraries loaded
776+
function checkLibraries() {{
777+
if (typeof marked === 'undefined' || typeof mermaid === 'undefined') {{
778+
const contentEl = document.getElementById('content');
779+
contentEl.innerHTML = `
780+
<div class="error-message">
781+
<h3>External Libraries Not Loaded</h3>
782+
<p>The required JavaScript libraries (marked.js and mermaid.js) failed to load.</p>
783+
<p><strong>This usually happens when opening the HTML file directly (file:// protocol).</strong></p>
784+
<h4>Solution:</h4>
785+
<p>Serve the documentation with a local web server:</p>
786+
<ol>
787+
<li><strong>Python:</strong> <code>python3 -m http.server 8000</code> then visit <code>http://localhost:8000</code></li>
788+
<li><strong>Or deploy to GitHub Pages</strong> (works perfectly there!)</li>
789+
</ol>
790+
</div>
791+
`;
792+
return false;
793+
}}
794+
return true;
686795
}}
687796
688797
// Start when DOM is ready
689798
if (document.readyState === 'loading') {{
690-
document.addEventListener('DOMContentLoaded', init);
799+
document.addEventListener('DOMContentLoaded', () => {{
800+
if (checkLibraries()) init();
801+
}});
691802
}} else {{
692-
init();
803+
if (checkLibraries()) init();
693804
}}
694805
</script>
695806
</body>

0 commit comments

Comments
 (0)