import os import re templates_to_update = [ 'src/main/resources/templates/dao-tao-detail.html', 'src/main/resources/templates/posts/full-width.html', 'src/main/resources/templates/posts/livestream.html', 'src/main/resources/templates/posts/sidebar.html', 'src/main/resources/templates/posts/standard.html' ] # In dao-tao-detail, the loop is `blocks.forEach(function(block) {` # In others, the loop is `data.blocks.forEach(function(block) {` # The switch starts with `switch(block.type) {` and ends with `}` before the end of the loop. for filepath in templates_to_update: if not os.path.exists(filepath): print(f"Skipping {filepath}, does not exist") continue with open(filepath, 'r', encoding='utf-8') as f: content = f.read() # Find the block loop start loop_start_match = re.search(r'(data\.blocks|blocks)\.forEach\(function\(block\)\s*\{', content) if not loop_start_match: print(f"Loop not found in {filepath}") continue # We want to replace the whole forEach logic with our new state machine logic. # But we need the existing switch cases! switch_match = re.search(r'switch\s*\(\s*block\.type\s*\)\s*\{([\s\S]*?)default:', content) if not switch_match: print(f"Switch not found in {filepath}") continue cases_content = switch_match.group(1) new_parser_code = """ var inTabs = false; var tabsGroup = null; function renderSingleBlock(block) { var html = ""; switch(block.type) { """ + cases_content + """ case "tabStart": case "tabEnd": break; default: console.log("Unknown block type", block.type); } return html; } var blockList = data && data.blocks ? data.blocks : (typeof blocks !== 'undefined' ? blocks : []); var finalHtml = ""; blockList.forEach(function(block) { if (block.type === 'tabStart') { if (!inTabs) { inTabs = true; tabsGroup = { tabs: [] }; } tabsGroup.tabs.push({ title: block.data.title || 'Tab', contentHtml: '' }); return; } if (block.type === 'tabEnd') { if (inTabs && tabsGroup) { inTabs = false; var groupHtml = '
'; groupHtml += '
'; tabsGroup.tabs.forEach(function(tab, index) { var activeClass = (index === 0) ? 'active' : ''; groupHtml += ''; }); groupHtml += '
'; tabsGroup.tabs.forEach(function(tab, index) { var displayStyle = (index === 0) ? 'block' : 'none'; groupHtml += '
'; groupHtml += tab.contentHtml; groupHtml += '
'; }); groupHtml += '
'; finalHtml += groupHtml; tabsGroup = null; } return; } var blockHtml = renderSingleBlock(block); if (inTabs && tabsGroup && tabsGroup.tabs.length > 0) { tabsGroup.tabs[tabsGroup.tabs.length - 1].contentHtml += blockHtml; } else { finalHtml += blockHtml; } }); if (inTabs && tabsGroup) { // Close unclosed tabs at the end var groupHtml = '
'; groupHtml += '
'; tabsGroup.tabs.forEach(function(tab, index) { var activeClass = (index === 0) ? 'active' : ''; groupHtml += ''; }); groupHtml += '
'; tabsGroup.tabs.forEach(function(tab, index) { var displayStyle = (index === 0) ? 'block' : 'none'; groupHtml += '
'; groupHtml += tab.contentHtml; groupHtml += '
'; }); groupHtml += '
'; finalHtml += groupHtml; } html = finalHtml; // Assign back to whatever variable the original script used. """ # We need to replace the entire forEach loop. # We will use regex to find the block from data.blocks.forEach up to the end of the loop. # It's tricky to balance braces with regex. Let's do string replacement. if filepath.endswith('dao-tao-detail.html'): start_marker = "blocks.forEach(function(block) {" end_marker = "html += \"\";\n break;" start_idx = content.find(start_marker) # Find the closing brace of the switch statement after end_marker end_marker_idx = content.find(end_marker, start_idx) + len(end_marker) # We need to replace up to the end of the forEach loop. end_loop_idx = content.find("});", end_marker_idx) + 3 content = content[:start_idx] + new_parser_code + content[end_loop_idx:] else: start_marker = "data.blocks.forEach(function(block) {" end_marker = "case \"raw\":\n html += block.data.html;\n break;" start_idx = content.find(start_marker) end_marker_idx = content.find(end_marker, start_idx) + len(end_marker) end_loop_idx = content.find("});", end_marker_idx) + 3 content = content[:start_idx] + new_parser_code + content[end_loop_idx:] # Inject tab switching script at the end of the file if not present switch_script = """ """ if "custom-tab-btn" not in content: content = content.replace("", switch_script + "") with open(filepath, 'w', encoding='utf-8') as f: f.write(content) print(f"Updated {filepath}")