|
45 | 45 | .pagination { margin: 1em 0; } |
46 | 46 | .pagination a { margin: 0 0.5em; } |
47 | 47 | .prefooter { margin-top: 2em; font-size: small; text-align: center; } |
| 48 | + .loda-program-container { |
| 49 | + margin-top: 0.5em; |
| 50 | + border: 1px solid #ddd; |
| 51 | + border-radius: 4px; |
| 52 | + background: #f8f9fa; |
| 53 | + } |
| 54 | + .loda-program-header { |
| 55 | + padding: 0.5em; |
| 56 | + background: #e9ecef; |
| 57 | + border-bottom: 1px solid #ddd; |
| 58 | + display: flex; |
| 59 | + justify-content: space-between; |
| 60 | + align-items: center; |
| 61 | + } |
| 62 | + .loda-program-code { |
| 63 | + padding: 1em; |
| 64 | + font-family: 'Courier New', monospace; |
| 65 | + font-size: 0.9em; |
| 66 | + line-height: 1.4; |
| 67 | + overflow-x: auto; |
| 68 | + } |
| 69 | + .loda-button { |
| 70 | + background: #007bff; |
| 71 | + color: white; |
| 72 | + border: none; |
| 73 | + padding: 0.3em 0.8em; |
| 74 | + border-radius: 3px; |
| 75 | + cursor: pointer; |
| 76 | + font-size: 0.85em; |
| 77 | + text-decoration: none; |
| 78 | + display: inline-block; |
| 79 | + } |
| 80 | + .loda-button:hover { |
| 81 | + background: #0056b3; |
| 82 | + color: white; |
| 83 | + } |
| 84 | + .loda-button.secondary { |
| 85 | + background: #6c757d; |
| 86 | + } |
| 87 | + .loda-button.secondary:hover { |
| 88 | + background: #545b62; |
| 89 | + } |
| 90 | + .loading-text { |
| 91 | + color: #666; |
| 92 | + font-style: italic; |
| 93 | + } |
| 94 | + /* Dark mode styles */ |
| 95 | + body.dark-mode .loda-program-container { |
| 96 | + border-color: #444; |
| 97 | + background: #2d2d2d; |
| 98 | + } |
| 99 | + body.dark-mode .loda-program-header { |
| 100 | + background: #3a3a3a; |
| 101 | + border-bottom-color: #444; |
| 102 | + color: #e0e0e0; |
| 103 | + } |
| 104 | + body.dark-mode .loda-program-code { |
| 105 | + background: #2d2d2d; |
| 106 | + color: #e0e0e0; |
| 107 | + } |
48 | 108 | </style> |
49 | 109 | </head> |
50 | 110 | <body> |
@@ -186,40 +246,125 @@ <h1 class="post-title">Integer Sequences and LODA Programs</h1> |
186 | 246 | return { total: data.total || 0, results: data.results || [] }; |
187 | 247 | } |
188 | 248 |
|
| 249 | + // --- Fetch LODA program code --- |
| 250 | + async function fetchLodaProgram(sequenceId) { |
| 251 | + try { |
| 252 | + const url = `https://api.loda-lang.org/v2/programs/${sequenceId}`; |
| 253 | + const resp = await fetch(url); |
| 254 | + if (!resp.ok) return null; |
| 255 | + const data = await resp.json(); |
| 256 | + return data.code; |
| 257 | + } catch (error) { |
| 258 | + console.error('Error fetching LODA program:', error); |
| 259 | + return null; |
| 260 | + } |
| 261 | + } |
| 262 | + |
189 | 263 | // --- Render sequence list --- |
190 | 264 | function renderSequenceList(results) { |
191 | 265 | const list = document.getElementById('sequence-list'); |
192 | 266 | list.innerHTML = ''; |
193 | | - results.forEach(entry => { |
| 267 | + results.forEach((entry, index) => { |
194 | 268 | const row0 = document.createElement('div'); |
195 | 269 | row0.className = 'col0'; |
196 | 270 | const oeisLink = document.createElement('a'); |
197 | 271 | oeisLink.target = '_blank'; |
198 | 272 | oeisLink.href = `https://oeis.org/${entry.id}`; |
199 | 273 | oeisLink.textContent = entry.id; |
200 | 274 | row0.appendChild(oeisLink); |
| 275 | + |
201 | 276 | const row1 = document.createElement('div'); |
202 | 277 | row1.className = 'col1'; |
203 | 278 | const linkbox = document.createElement('div'); |
204 | 279 | linkbox.className = 'linkbox'; |
205 | | - // Show LODA program link only if 'loda' keyword is present |
| 280 | + |
| 281 | + // Show LODA program button only if 'loda' keyword is present |
206 | 282 | if (entry.keywords && Array.isArray(entry.keywords) && entry.keywords.includes('loda')) { |
207 | | - const lodaLink = document.createElement('a'); |
208 | | - lodaLink.target = '_blank'; |
209 | | - lodaLink.href = `https://loda-lang.org/edit/?oeis=${entry.id.slice(1)}`; |
210 | | - lodaLink.textContent = 'LODA'; |
211 | | - linkbox.appendChild(lodaLink); |
| 283 | + const lodaButton = document.createElement('button'); |
| 284 | + lodaButton.className = 'loda-button'; |
| 285 | + lodaButton.textContent = 'Show LODA'; |
| 286 | + lodaButton.onclick = () => toggleLodaProgram(entry.id, lodaButton, row1); |
| 287 | + linkbox.appendChild(lodaButton); |
212 | 288 | } |
| 289 | + |
213 | 290 | row1.appendChild(linkbox); |
214 | 291 | const desc = document.createElement('div'); |
215 | 292 | desc.className = 'sequence-description'; |
216 | 293 | desc.textContent = entry.name; |
217 | 294 | row1.appendChild(desc); |
| 295 | + |
218 | 296 | list.appendChild(row0); |
219 | 297 | list.appendChild(row1); |
220 | 298 | }); |
221 | 299 | } |
222 | 300 |
|
| 301 | + // --- Toggle LODA program display --- |
| 302 | + async function toggleLodaProgram(sequenceId, button, container) { |
| 303 | + const programId = `loda-program-${sequenceId}`; |
| 304 | + let programContainer = document.getElementById(programId); |
| 305 | + |
| 306 | + if (programContainer) { |
| 307 | + // If program is already shown, hide it |
| 308 | + programContainer.remove(); |
| 309 | + button.textContent = 'Show LODA'; |
| 310 | + return; |
| 311 | + } |
| 312 | + |
| 313 | + // Show loading state |
| 314 | + button.textContent = 'Loading...'; |
| 315 | + button.disabled = true; |
| 316 | + |
| 317 | + // Fetch the program code |
| 318 | + const code = await fetchLodaProgram(sequenceId); |
| 319 | + |
| 320 | + if (code) { |
| 321 | + // Create program container |
| 322 | + programContainer = document.createElement('div'); |
| 323 | + programContainer.id = programId; |
| 324 | + programContainer.className = 'loda-program-container'; |
| 325 | + |
| 326 | + // Create header with edit button |
| 327 | + const header = document.createElement('div'); |
| 328 | + header.className = 'loda-program-header'; |
| 329 | + |
| 330 | + const title = document.createElement('span'); |
| 331 | + title.textContent = `LODA Program for ${sequenceId}`; |
| 332 | + |
| 333 | + const editButton = document.createElement('a'); |
| 334 | + editButton.className = 'loda-button secondary'; |
| 335 | + editButton.href = `https://loda-lang.org/edit/?oeis=${sequenceId.slice(1)}`; |
| 336 | + editButton.target = '_blank'; |
| 337 | + editButton.textContent = 'Open in Editor'; |
| 338 | + |
| 339 | + header.appendChild(title); |
| 340 | + header.appendChild(editButton); |
| 341 | + |
| 342 | + // Create code container |
| 343 | + const codeContainer = document.createElement('pre'); |
| 344 | + codeContainer.className = 'loda-program-code'; |
| 345 | + const codeElement = document.createElement('code'); |
| 346 | + codeElement.className = 'language-asm'; |
| 347 | + codeElement.textContent = code; |
| 348 | + codeContainer.appendChild(codeElement); |
| 349 | + |
| 350 | + programContainer.appendChild(header); |
| 351 | + programContainer.appendChild(codeContainer); |
| 352 | + container.appendChild(programContainer); |
| 353 | + |
| 354 | + // Apply syntax highlighting |
| 355 | + hljs.highlightElement(codeElement); |
| 356 | + |
| 357 | + button.textContent = 'Hide LODA'; |
| 358 | + } else { |
| 359 | + button.textContent = 'Error loading'; |
| 360 | + setTimeout(() => { |
| 361 | + button.textContent = 'Show LODA'; |
| 362 | + }, 2000); |
| 363 | + } |
| 364 | + |
| 365 | + button.disabled = false; |
| 366 | + } |
| 367 | + |
223 | 368 | // --- Render pagination --- |
224 | 369 | function renderPagination() { |
225 | 370 | const pag = document.getElementById('pagination'); |
|
0 commit comments