@@ -118,17 +118,47 @@ def build_hierarchy(flat_sections: List[MarkdownSection]) -> List[MarkdownSectio
118118 return root .children
119119
120120
121+ # Mapping of title variations to their canonical form
122+ # This ensures consistent output paths regardless of singular/plural usage
123+ TITLE_NORMALIZATION_MAP = {
124+ 'state' : 'states' ,
125+ # Add more mappings here as needed, e.g.:
126+ # 'variant': 'variants',
127+ # 'property': 'properties',
128+ }
129+
130+
131+ def normalize_title (title : str ) -> str :
132+ """
133+ Normalize section titles to their canonical form
134+ Handles singular/plural variations (e.g., "State" -> "States")
135+
136+ Args:
137+ title: Original heading text
138+
139+ Returns:
140+ Normalized title
141+ """
142+ title_lower = title .lower ().strip ()
143+ if title_lower in TITLE_NORMALIZATION_MAP :
144+ return TITLE_NORMALIZATION_MAP [title_lower ]
145+ return title
146+
147+
121148def sanitize_filename (name : str ) -> str :
122149 """
123150 Clean filename by replacing special characters
124151 Converts "Basic Usage" to "basic_usage"
152+ Also normalizes title variations (e.g., "State" -> "states")
125153
126154 Args:
127155 name: Original heading text
128156
129157 Returns:
130158 Sanitized filename safe for file systems
131159 """
160+ # First normalize the title (handle singular/plural variations)
161+ name = normalize_title (name )
132162 # Convert to lowercase
133163 name = name .lower ()
134164 # Replace spaces with underscores
0 commit comments