update_section
Modify content in specific sections of Markdown documents while maintaining document integrity through automatic saving and validation.
Instructions
Update the content of an existing section.
The document will be saved after the operation if successful and auto_save is True.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| document_path | Yes | ||
| section_id | Yes | ||
| content | Yes | ||
| auto_save | No | ||
| backup | No | ||
| validation_level | No | NORMAL |
Implementation Reference
- src/quantalogic_markdown_mcp/mcp_server.py:203-240 (registration)MCP tool registration and handler for 'update_section'. Defines the tool function that loads the document statelessly, finds the section by ID, calls SafeMarkdownEditor.update_section_content, and processes via StatelessMarkdownProcessor.execute_operation.@self.mcp.tool() def update_section(document_path: str, section_id: str, content: str, auto_save: bool = True, backup: bool = True, validation_level: str = "NORMAL") -> Dict[str, Any]: """ Update the content of an existing section. The document will be saved after the operation if successful and auto_save is True. """ """ Update the content of an existing section. Args: document_path: Path to the Markdown file section_id: The section ID to update content: New content for the section auto_save: Whether to automatically save the document backup: Whether to create a backup before saving validation_level: Validation strictness - "STRICT", "NORMAL", or "PERMISSIVE" """ def operation(editor): section_ref = editor.get_section_by_id(section_id) if not section_ref: from .safe_editor_types import EditResult, OperationType return EditResult( success=False, operation=OperationType.UPDATE, modified_sections=[], errors=[f"Section with ID '{section_id}' not found"], warnings=[] ) return editor.update_section_content(section_ref, content) validation_map = {"STRICT": ValidationLevel.STRICT, "NORMAL": ValidationLevel.NORMAL, "PERMISSIVE": ValidationLevel.PERMISSIVE} validation_enum = validation_map.get(validation_level.upper(), ValidationLevel.NORMAL) return self.processor.execute_operation(document_path, operation, auto_save, backup, validation_enum)
- Core handler logic for updating section content in SafeMarkdownEditor. Replaces the section's content lines while preserving the heading, handles duplicate header removal, records transactions for rollback, updates parser state, and returns detailed EditResult.def update_section_content(self, section_ref: SectionReference, content: str, preserve_subsections: bool = True) -> EditResult: """ Update content of a specific section. Args: section_ref: Immutable reference to target section content: New content (markdown text without heading) preserve_subsections: Whether to keep existing subsections Returns: EditResult with operation status and details """ with self._lock: try: # First validate the operation preview_result = self.preview_operation( EditOperation.UPDATE_SECTION, section_ref=section_ref, content=content ) if not preview_result.success: return preview_result # Create transaction for rollback transaction = self._create_transaction([{ 'operation': EditOperation.UPDATE_SECTION, 'section_ref': section_ref, 'content': content, 'preserve_subsections': preserve_subsections }]) # Apply the changes lines = self._current_text.split('\n') start_line = section_ref.line_start end_line = section_ref.line_end if preserve_subsections: # Find where section content ends and subsections begin section_content_end = self._find_section_content_end(section_ref) end_line = section_content_end # Replace content while preserving heading if start_line < len(lines): new_content_lines = content.split('\n') # Check if the new content starts with a duplicate header # If so, remove it to prevent duplication if new_content_lines and new_content_lines[0].strip(): first_line = new_content_lines[0] expected_header = "#" * section_ref.level + " " + section_ref.title # Only remove if it's an EXACT match (including spacing) if first_line == expected_header: # Skip the duplicate header and any following empty lines skip_lines = 1 while (skip_lines < len(new_content_lines) and not new_content_lines[skip_lines].strip()): skip_lines += 1 new_content_lines = new_content_lines[skip_lines:] new_lines = (lines[:start_line + 1] + new_content_lines + lines[end_line + 1:]) # Update state self._current_text = '\n'.join(new_lines) self._current_result = self._parser.parse(self._current_text) self._wrapper = ASTWrapper(self._current_result) self._last_modified = datetime.now() self._version += 1 # Add transaction to history self._transaction_history.append(transaction) self._trim_transaction_history() # Get updated section reference updated_sections = self._build_section_references() updated_section = None for section in updated_sections: if section.title == section_ref.title and section.level == section_ref.level: updated_section = section break return EditResult( success=True, operation=EditOperation.UPDATE_SECTION, modified_sections=[updated_section] if updated_section else [], errors=[], warnings=[], metadata={ 'transaction_id': transaction.transaction_id, 'version': self._version, 'preserve_subsections': preserve_subsections } ) return EditResult( success=False, operation=EditOperation.UPDATE_SECTION, modified_sections=[], errors=[SafeParseError( message="Section not found or invalid line range", error_code="SECTION_NOT_FOUND", category=ErrorCategory.OPERATION )], warnings=[] ) except Exception as e: return EditResult( success=False, operation=EditOperation.UPDATE_SECTION, modified_sections=[], errors=[SafeParseError( message=f"Update operation failed: {str(e)}", error_code="UPDATE_ERROR", category=ErrorCategory.SYSTEM )], warnings=[] )
- Alternative/enhanced MCP tool handler for 'update_section' in enhanced server, similar to main server but slightly simplified.@self.mcp.tool() def update_section(document_path: str, section_id: str, content: str, auto_save: bool = True, backup: bool = True, validation_level: str = "NORMAL") -> Dict[str, Any]: """Update a section's content (stateless only).""" def operation(editor: SafeMarkdownEditor): section = editor.get_section_by_id(section_id) if section: return editor.update_section_content( section_ref=section, content=content ) else: from .safe_editor_types import EditResult return EditResult( success=False, operation=EditOperation.UPDATE_SECTION, errors=["Section not found"] ) validation_map = {"STRICT": ValidationLevel.STRICT, "NORMAL": ValidationLevel.NORMAL, "PERMISSIVE": ValidationLevel.PERMISSIVE} validation_enum = validation_map.get(validation_level.upper(), ValidationLevel.NORMAL) return self.processor.execute_operation(document_path, operation, auto_save, backup, validation_enum)
- Internal implementation helper for synchronous tool calls in testing.def _update_section_impl(self, document_path: str, section_id: str, content: str, auto_save: bool = True, backup: bool = True) -> Dict[str, Any]: """Implementation for update_section tool.""" def operation(editor): section = editor.get_section_by_id(section_id) if not section: return {"success": False, "error": f"Section '{section_id}' not found"} return editor.update_section_content(section, content) validation_enum = ValidationLevel.NORMAL return self.processor.execute_operation(document_path, operation, auto_save, backup, validation_enum)