|
10 | 10 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
11 | 11 | <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> |
12 | 12 | <!-- Add Marked.js for Markdown parsing --> |
13 | | - <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> |
| 13 | + <script src="https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js"></script> |
14 | 14 | <!-- Add highlight.js for code syntax highlighting --> |
15 | 15 | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/styles/github.css"> |
16 | 16 | <script src="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/lib/highlight.min.js"></script> |
17 | 17 | <!-- Add MathJax for rendering LaTeX equations --> |
18 | 18 | <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script> |
19 | 19 | <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> |
| 20 | + <style> |
| 21 | + /* Debug panel styles */ |
| 22 | + #debug-panel { |
| 23 | + position: fixed; |
| 24 | + bottom: 0; |
| 25 | + right: 0; |
| 26 | + width: 400px; |
| 27 | + max-height: 300px; |
| 28 | + overflow-y: auto; |
| 29 | + background-color: rgba(0, 0, 0, 0.8); |
| 30 | + color: #fff; |
| 31 | + font-family: monospace; |
| 32 | + font-size: 12px; |
| 33 | + padding: 10px; |
| 34 | + z-index: 9999; |
| 35 | + display: none; |
| 36 | + } |
| 37 | + #debug-panel.show { |
| 38 | + display: block; |
| 39 | + } |
| 40 | + #debug-panel .log { |
| 41 | + margin-bottom: 5px; |
| 42 | + border-bottom: 1px solid #444; |
| 43 | + padding-bottom: 5px; |
| 44 | + } |
| 45 | + #debug-panel .error { |
| 46 | + color: #ff6b6b; |
| 47 | + } |
| 48 | + #debug-panel .warn { |
| 49 | + color: #feca57; |
| 50 | + } |
| 51 | + #debug-panel .info { |
| 52 | + color: #54a0ff; |
| 53 | + } |
| 54 | + #debug-toggle { |
| 55 | + position: fixed; |
| 56 | + bottom: 10px; |
| 57 | + right: 10px; |
| 58 | + background-color: #333; |
| 59 | + color: white; |
| 60 | + border: none; |
| 61 | + padding: 5px 10px; |
| 62 | + border-radius: 4px; |
| 63 | + cursor: pointer; |
| 64 | + z-index: 10000; |
| 65 | + } |
| 66 | + </style> |
20 | 67 | </head> |
21 | 68 | <body> |
22 | 69 | <header> |
@@ -99,22 +146,74 @@ <h3>Related Papers</h3> |
99 | 146 | </div> |
100 | 147 | </footer> |
101 | 148 |
|
| 149 | + <div id="debug-panel"></div> |
| 150 | + <button id="debug-toggle">Debug</button> |
| 151 | + |
102 | 152 | <script src="js/main.js"></script> |
103 | 153 | <script> |
| 154 | + // Custom logger for debugging |
| 155 | + const debugPanel = document.getElementById('debug-panel'); |
| 156 | + const debugToggle = document.getElementById('debug-toggle'); |
| 157 | + |
| 158 | + // Override console methods to also display in debug panel |
| 159 | + const originalConsole = { |
| 160 | + log: console.log, |
| 161 | + error: console.error, |
| 162 | + warn: console.warn, |
| 163 | + info: console.info |
| 164 | + }; |
| 165 | + |
| 166 | + function addToDebugPanel(type, ...args) { |
| 167 | + const logItem = document.createElement('div'); |
| 168 | + logItem.className = `log ${type}`; |
| 169 | + logItem.textContent = args.map(arg => |
| 170 | + typeof arg === 'object' ? JSON.stringify(arg) : String(arg) |
| 171 | + ).join(' '); |
| 172 | + debugPanel.appendChild(logItem); |
| 173 | + debugPanel.scrollTop = debugPanel.scrollHeight; |
| 174 | + } |
| 175 | + |
| 176 | + console.log = function(...args) { |
| 177 | + originalConsole.log(...args); |
| 178 | + addToDebugPanel('log', ...args); |
| 179 | + }; |
| 180 | + |
| 181 | + console.error = function(...args) { |
| 182 | + originalConsole.error(...args); |
| 183 | + addToDebugPanel('error', ...args); |
| 184 | + }; |
| 185 | + |
| 186 | + console.warn = function(...args) { |
| 187 | + originalConsole.warn(...args); |
| 188 | + addToDebugPanel('warn', ...args); |
| 189 | + }; |
| 190 | + |
| 191 | + console.info = function(...args) { |
| 192 | + originalConsole.info(...args); |
| 193 | + addToDebugPanel('info', ...args); |
| 194 | + }; |
| 195 | + |
| 196 | + debugToggle.addEventListener('click', function() { |
| 197 | + debugPanel.classList.toggle('show'); |
| 198 | + }); |
| 199 | + |
104 | 200 | document.addEventListener('DOMContentLoaded', async function() { |
105 | 201 | // Get the paper ID from the URL parameter |
106 | 202 | const urlParams = new URLSearchParams(window.location.search); |
107 | 203 | const paperId = urlParams.get('id') || 'example-paper'; // Default to example-paper if no ID provided |
108 | 204 |
|
| 205 | + console.log(`Loading paper with ID: ${paperId}`); |
| 206 | + |
109 | 207 | try { |
110 | 208 | // Load paper metadata and content |
111 | 209 | const metadataResponse = await fetch(`papers/${paperId}/metadata.json`); |
112 | 210 |
|
113 | 211 | if (!metadataResponse.ok) { |
114 | | - throw new Error('Failed to load paper metadata'); |
| 212 | + throw new Error(`Failed to load paper metadata: ${metadataResponse.status} ${metadataResponse.statusText}`); |
115 | 213 | } |
116 | 214 |
|
117 | 215 | const metadata = await metadataResponse.json(); |
| 216 | + console.log('Metadata loaded successfully:', metadata); |
118 | 217 |
|
119 | 218 | // Update page title |
120 | 219 | document.title = `Paper Review - ${metadata.title}`; |
@@ -159,38 +258,118 @@ <h3>Related Papers</h3> |
159 | 258 | } |
160 | 259 |
|
161 | 260 | // Load and render the Markdown content |
162 | | - const contentResponse = await fetch(`papers/${paperId}/review.md`); |
163 | | - |
164 | | - if (!contentResponse.ok) { |
165 | | - throw new Error('Failed to load paper content'); |
166 | | - } |
167 | | - |
168 | | - const markdownContent = await contentResponse.text(); |
169 | | - |
170 | | - // Configure marked.js options |
171 | | - marked.setOptions({ |
172 | | - highlight: function(code, lang) { |
173 | | - if (lang && hljs.getLanguage(lang)) { |
174 | | - return hljs.highlight(code, { language: lang }).value; |
| 261 | + console.log(`Attempting to load Markdown content from papers/${paperId}/review.md`); |
| 262 | + try { |
| 263 | + let markdownContent = ''; |
| 264 | + |
| 265 | + try { |
| 266 | + // First try with fetch API |
| 267 | + console.log('Trying fetch API first...'); |
| 268 | + const contentResponse = await fetch(`papers/${paperId}/review.md`); |
| 269 | + |
| 270 | + if (!contentResponse.ok) { |
| 271 | + throw new Error(`Failed to load paper content: ${contentResponse.status} ${contentResponse.statusText}`); |
175 | 272 | } |
176 | | - return hljs.highlightAuto(code).value; |
177 | | - }, |
178 | | - breaks: true |
179 | | - }); |
180 | | - |
181 | | - // Convert markdown to HTML and insert into the page |
182 | | - document.getElementById('markdown-content').innerHTML = marked.parse(markdownContent); |
183 | | - |
184 | | - // Initialize syntax highlighting for code blocks |
185 | | - document.querySelectorAll('pre code').forEach((block) => { |
186 | | - hljs.highlightBlock(block); |
187 | | - }); |
188 | | - |
189 | | - // Render MathJax equations |
190 | | - if (typeof MathJax !== 'undefined') { |
191 | | - MathJax.typesetPromise().catch((err) => { |
192 | | - console.error('Error rendering MathJax:', err); |
| 273 | + |
| 274 | + markdownContent = await contentResponse.text(); |
| 275 | + console.log('Markdown content loaded via fetch, length:', markdownContent.length); |
| 276 | + } catch (fetchError) { |
| 277 | + console.warn('Fetch failed, trying XMLHttpRequest as fallback:', fetchError); |
| 278 | + |
| 279 | + // Fallback to XMLHttpRequest (sometimes works better with local files) |
| 280 | + markdownContent = await new Promise((resolve, reject) => { |
| 281 | + const xhr = new XMLHttpRequest(); |
| 282 | + xhr.open('GET', `papers/${paperId}/review.md`, true); |
| 283 | + xhr.onload = function() { |
| 284 | + if (xhr.status === 200) { |
| 285 | + console.log('Markdown content loaded via XHR, length:', xhr.responseText.length); |
| 286 | + resolve(xhr.responseText); |
| 287 | + } else { |
| 288 | + reject(new Error(`XHR request failed: ${xhr.status}`)); |
| 289 | + } |
| 290 | + }; |
| 291 | + xhr.onerror = function() { |
| 292 | + reject(new Error('Network error occurred')); |
| 293 | + }; |
| 294 | + xhr.send(); |
| 295 | + }); |
| 296 | + } |
| 297 | + |
| 298 | + // Verify content loaded |
| 299 | + if (!markdownContent || markdownContent.trim() === '') { |
| 300 | + throw new Error('Markdown content is empty'); |
| 301 | + } |
| 302 | + |
| 303 | + // Check if marked.js is available |
| 304 | + if (typeof marked === 'undefined') { |
| 305 | + throw new Error('marked.js library is not loaded'); |
| 306 | + } |
| 307 | + |
| 308 | + // Configure marked.js options |
| 309 | + console.log('Configuring marked.js...'); |
| 310 | + try { |
| 311 | + // Using the latest marked.js API |
| 312 | + marked.use({ |
| 313 | + pedantic: false, |
| 314 | + gfm: true, |
| 315 | + breaks: true, |
| 316 | + sanitize: false, |
| 317 | + smartLists: true, |
| 318 | + smartypants: true, |
| 319 | + highlight: function(code, lang) { |
| 320 | + if (lang && hljs.getLanguage(lang)) { |
| 321 | + return hljs.highlight(code, { language: lang }).value; |
| 322 | + } |
| 323 | + return hljs.highlightAuto(code).value; |
| 324 | + } |
| 325 | + }); |
| 326 | + |
| 327 | + // Convert markdown to HTML and insert into the page |
| 328 | + console.log('Parsing Markdown content...'); |
| 329 | + const parsedHtml = marked.parse(markdownContent); |
| 330 | + console.log('Markdown parsed successfully, HTML length:', parsedHtml.length); |
| 331 | + |
| 332 | + // Set the HTML content |
| 333 | + document.getElementById('markdown-content').innerHTML = parsedHtml; |
| 334 | + console.log('HTML content set to DOM'); |
| 335 | + } catch (markdownError) { |
| 336 | + console.error('Error in marked.js:', markdownError); |
| 337 | + |
| 338 | + // Fallback to basic HTML |
| 339 | + document.getElementById('markdown-content').innerHTML = ` |
| 340 | + <div class="error"> |
| 341 | + <h2>Error Processing Markdown</h2> |
| 342 | + <p>${markdownError.message}</p> |
| 343 | + <hr> |
| 344 | + <pre>${markdownContent}</pre> |
| 345 | + </div> |
| 346 | + `; |
| 347 | + } |
| 348 | + |
| 349 | + // Initialize syntax highlighting for code blocks |
| 350 | + console.log('Initializing syntax highlighting...'); |
| 351 | + document.querySelectorAll('pre code').forEach((block) => { |
| 352 | + hljs.highlightBlock(block); |
193 | 353 | }); |
| 354 | + |
| 355 | + // Render MathJax equations |
| 356 | + if (typeof MathJax !== 'undefined') { |
| 357 | + console.log('Rendering MathJax equations...'); |
| 358 | + MathJax.typesetPromise().catch((err) => { |
| 359 | + console.error('Error rendering MathJax:', err); |
| 360 | + }); |
| 361 | + } else { |
| 362 | + console.warn('MathJax is not available'); |
| 363 | + } |
| 364 | + } catch (contentError) { |
| 365 | + console.error('Error loading/rendering Markdown:', contentError); |
| 366 | + document.getElementById('markdown-content').innerHTML = ` |
| 367 | + <div class="error"> |
| 368 | + <h2>Error Loading Paper Content</h2> |
| 369 | + <p>${contentError.message}</p> |
| 370 | + <p>Please check that the review.md file exists at papers/${paperId}/review.md</p> |
| 371 | + </div> |
| 372 | + `; |
194 | 373 | } |
195 | 374 |
|
196 | 375 | } catch (error) { |
|
0 commit comments