feat: Complete Issue #41 - Add TOML frontmatter support

- Enhanced frontmatter parser to detect and parse TOML format
- Added TOML format detection heuristics before YAML parsing
- Created TOML test fixture with nested sections
- Fixed parsing order to prevent TOML-to-string conversion
- All frontmatter formats (YAML, JSON, TOML) now fully supported
- Validated all acceptance criteria for Issue #41

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-02 09:32:16 +02:00
parent 494e1b7128
commit cde2805078
2 changed files with 57 additions and 12 deletions

View File

@@ -5,6 +5,7 @@ Frontmatter parser for extracting and manipulating YAML/JSON/TOML frontmatter.
import re
import yaml
import json
import toml
from typing import Dict, Any, List, Optional
from .stats import FrontmatterStats
@@ -27,20 +28,32 @@ class FrontmatterParser:
if not frontmatter_content:
return {}
# Try to parse as YAML first (most common)
# Try to detect format first for better parsing
content = frontmatter_content.strip()
# Try TOML first if it looks like TOML
if '=' in content and ('[' in content or '"' in content):
try:
return toml.loads(frontmatter_content)
except toml.TomlDecodeError:
pass
# Try JSON if it looks like JSON
if content.startswith('{') and content.endswith('}'):
try:
return json.loads(frontmatter_content)
except json.JSONDecodeError:
pass
# Default to YAML (most common)
try:
return yaml.safe_load(frontmatter_content) or {}
result = yaml.safe_load(frontmatter_content)
# Ensure we got a dictionary, not a string
if isinstance(result, dict):
return result
except yaml.YAMLError:
pass
# Try to parse as JSON
try:
return json.loads(frontmatter_content)
except json.JSONDecodeError:
pass
# TODO: Add TOML support in future iterations
return {}
def set_frontmatter_value(self, text: str, key: str, value: Any) -> str:
@@ -118,7 +131,7 @@ class FrontmatterParser:
"""
frontmatter = self.extract_frontmatter(text)
if not frontmatter:
if not frontmatter or not isinstance(frontmatter, dict):
return FrontmatterStats(
has_frontmatter=False,
total_fields=0,
@@ -166,8 +179,11 @@ class FrontmatterParser:
content = content.strip()
if content.startswith('{') and content.endswith('}'):
return "json"
elif '=' in content and '[' in content:
# Simple heuristic for TOML
return "toml"
else:
# Default to YAML for now
# Default to YAML
return "yaml"
def _set_nested_value(self, data: Dict[str, Any], key: str, value: Any) -> None:

View File

@@ -0,0 +1,29 @@
---
title = "TOML Frontmatter Test Document"
author = "Test Author"
date = "2025-10-02"
tags = ["toml", "frontmatter", "testing"]
version = 1.4
published = true
[config]
theme = "light"
language = "en"
debug = false
[features]
search = true
toc = true
navigation = true
---
# TOML Frontmatter Test Document
This document uses TOML format for frontmatter instead of YAML or JSON.
The frontmatter parser should handle TOML format correctly and extract values like:
- title: "TOML Frontmatter Test Document"
- config.theme: "light"
- features.search: true
This tests the parser's ability to handle all three frontmatter formats as required by Issue #41.