diff --git a/markitect/document_manager.py b/markitect/document_manager.py index a7055964..3ce41f57 100644 --- a/markitect/document_manager.py +++ b/markitect/document_manager.py @@ -687,10 +687,30 @@ class DocumentManager: } markSections(element) { + // Clear existing section markers (except edited ones) + const existingSections = element.querySelectorAll('.markitect-section-editable:not([data-edited])'); + existingSections.forEach(section => { + section.classList.remove('markitect-section-editable'); + section.removeAttribute('data-section'); + }); + + // Mark new sections (skip elements inside edited wrappers) const sections = element.querySelectorAll('h1, h2, h3, h4, h5, h6, p, blockquote, pre, ul, ol'); - sections.forEach((section, index) => { + let sectionIndex = 0; + + sections.forEach((section) => { + // Skip if this element is inside an edited wrapper + if (section.closest('[data-edited]')) { + return; + } + + // Skip if already marked as edited wrapper + if (section.hasAttribute('data-edited')) { + return; + } + section.classList.add('markitect-section-editable'); - section.setAttribute('data-section', index); + section.setAttribute('data-section', sectionIndex++); }); } @@ -709,8 +729,19 @@ class DocumentManager: textarea.addEventListener('blur', () => { this.hasEdits = true; // Mark that edits have been made - section.innerHTML = marked.parse(textarea.value); - this.markSections(section.parentElement); + + // Create a wrapper div to contain the parsed content + const wrapper = document.createElement('div'); + wrapper.innerHTML = marked.parse(textarea.value); + wrapper.classList.add('markitect-section-editable'); + wrapper.setAttribute('data-section', section.getAttribute('data-section')); + wrapper.setAttribute('data-edited', 'true'); // Mark as edited + + // Replace the section with the wrapper + section.parentNode.replaceChild(wrapper, section); + + // Re-mark sections in the entire document, but skip edited wrappers + this.markSections(document.getElementById('markdown-content')); }); section.innerHTML = ''; @@ -800,32 +831,69 @@ class DocumentManager: let reconstructed = ''; sections.forEach(section => {{ - const tagName = section.tagName.toLowerCase(); - const text = section.textContent.trim(); + // Handle edited wrappers differently + if (section.hasAttribute('data-edited')) {{ + // For edited sections, convert the child elements back to markdown + const childElements = section.children; + for (let i = 0; i < childElements.length; i++) {{ + const child = childElements[i]; + const tagName = child.tagName.toLowerCase(); + const text = child.textContent.trim(); - if (tagName.startsWith('h')) {{ - const level = parseInt(tagName.charAt(1)); - reconstructed += '#'.repeat(level) + ' ' + text + '\\n\\n'; - }} else if (tagName === 'p') {{ - reconstructed += text + '\\n\\n'; - }} else if (tagName === 'blockquote') {{ - reconstructed += '> ' + text + '\\n\\n'; - }} else if (tagName === 'pre') {{ - reconstructed += '```\\n' + text + '\\n```\\n\\n'; - }} else if (tagName === 'ul') {{ - const items = section.querySelectorAll('li'); - items.forEach(item => {{ - reconstructed += '- ' + item.textContent.trim() + '\\n'; - }}); - reconstructed += '\\n'; - }} else if (tagName === 'ol') {{ - const items = section.querySelectorAll('li'); - items.forEach((item, index) => {{ - reconstructed += (index + 1) + '. ' + item.textContent.trim() + '\\n'; - }}); - reconstructed += '\\n'; + if (tagName.startsWith('h')) {{ + const level = parseInt(tagName.charAt(1)); + reconstructed += '#'.repeat(level) + ' ' + text + '\\n\\n'; + }} else if (tagName === 'p') {{ + reconstructed += text + '\\n\\n'; + }} else if (tagName === 'blockquote') {{ + reconstructed += '> ' + text + '\\n\\n'; + }} else if (tagName === 'pre') {{ + reconstructed += '```\\n' + text + '\\n```\\n\\n'; + }} else if (tagName === 'ul') {{ + const items = child.querySelectorAll('li'); + items.forEach(item => {{ + reconstructed += '- ' + item.textContent.trim() + '\\n'; + }}); + reconstructed += '\\n'; + }} else if (tagName === 'ol') {{ + const items = child.querySelectorAll('li'); + items.forEach((item, index) => {{ + reconstructed += (index + 1) + '. ' + item.textContent.trim() + '\\n'; + }}); + reconstructed += '\\n'; + }} else {{ + reconstructed += text + '\\n\\n'; + }} + }} }} else {{ - reconstructed += text + '\\n\\n'; + // Handle regular sections + const tagName = section.tagName.toLowerCase(); + const text = section.textContent.trim(); + + if (tagName.startsWith('h')) {{ + const level = parseInt(tagName.charAt(1)); + reconstructed += '#'.repeat(level) + ' ' + text + '\\n\\n'; + }} else if (tagName === 'p') {{ + reconstructed += text + '\\n\\n'; + }} else if (tagName === 'blockquote') {{ + reconstructed += '> ' + text + '\\n\\n'; + }} else if (tagName === 'pre') {{ + reconstructed += '```\\n' + text + '\\n```\\n\\n'; + }} else if (tagName === 'ul') {{ + const items = section.querySelectorAll('li'); + items.forEach(item => {{ + reconstructed += '- ' + item.textContent.trim() + '\\n'; + }}); + reconstructed += '\\n'; + }} else if (tagName === 'ol') {{ + const items = section.querySelectorAll('li'); + items.forEach((item, index) => {{ + reconstructed += (index + 1) + '. ' + item.textContent.trim() + '\\n'; + }}); + reconstructed += '\\n'; + }} else {{ + reconstructed += text + '\\n\\n'; + }} }} }});