Skip to main content
Glama

update_section

Modify and save the content of a specific section in a Markdown document, ensuring validation and optional auto-save and backup functionality.

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
NameRequiredDescriptionDefault
auto_saveNo
backupNo
contentYes
document_pathYes
section_idYes
validation_levelNoNORMAL

Implementation Reference

  • Core handler function that performs the actual section content update logic, including validation preview, transaction creation, content replacement while preserving heading, duplicate header detection/removal, and state update.
    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=[] )
  • MCP tool registration for 'update_section'. Defines input parameters, finds section by ID, calls SafeMarkdownEditor's update_section_content method, and handles saving via stateless processor.
    @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)
  • Enum defining EditOperation.UPDATE_SECTION used throughout for operation type identification and validation.
    class EditOperation(Enum): """Supported editing operations.""" INSERT_SECTION = "insert_section" UPDATE_SECTION = "update_section" DELETE_SECTION = "delete_section" MOVE_SECTION = "move_section" CHANGE_HEADING_LEVEL = "change_heading_level" INSERT_CONTENT = "insert_content" DELETE_CONTENT = "delete_content" BATCH_OPERATIONS = "batch_operations"
  • Internal synchronous implementation for update_section tool call used in testing and direct calls.
    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)
  • Dataclass defining SectionReference type used as input parameter for identifying and referencing sections to update.
    @dataclass(frozen=True) class SectionReference: """Immutable reference to a document section.""" id: str # Stable hash-based identifier title: str # Section heading text level: int # Heading level (1-6) line_start: int # Starting line number (0-indexed) line_end: int # Ending line number (0-indexed) path: List[str] # Hierarchical path from root def __hash__(self) -> int: """Hash based on immutable properties.""" return hash((self.id, self.title, self.level, self.line_start)) def __eq__(self, other) -> bool: """Equality based on ID and position.""" return (isinstance(other, SectionReference) and self.id == other.id and self.line_start == other.line_start)

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/quantalogic/quantalogic_markdown_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server