#!/usr/bin/env python3 """ Script to parse epic details markdown and generate a presentation-style website showing all user stories with User Story, Background, and Acceptance Criteria. """ import re from pathlib import Path def parse_epic_details(file_path): """Parse the epic details markdown file and extract stories.""" with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # Split by stories story_pattern = r'### Story ([\d.]+): (.+?)\n\n(.*?)(?=\n### Story [\d.]+:|$)' matches = re.findall(story_pattern, content, re.DOTALL) stories = [] for story_num, title, body in matches: # Extract User Story user_story_match = re.search(r'#### User Story\n\n(.*?)(?=\n####|$)', body, re.DOTALL) user_story = user_story_match.group(1).strip() if user_story_match else "Not found" # Extract Background background_match = re.search(r'#### Background\n\n(.*?)(?=\n####|$)', body, re.DOTALL) background = background_match.group(1).strip() if background_match else "Not found" # Extract Acceptance Criteria acceptance_match = re.search(r'#### Acceptance Criteria\n\n(.*?)(?=\n####|$)', body, re.DOTALL) acceptance = acceptance_match.group(1).strip() if acceptance_match else "Not found" # Clean up content user_story = clean_content(user_story) background = clean_content(background) acceptance = clean_content(acceptance) stories.append({ 'number': story_num, 'title': title, 'user_story': user_story, 'background': background, 'acceptance': acceptance }) return stories def clean_content(text): """Clean and escape content for HTML/JS embedding.""" if not text: return "" # Replace problematic characters but preserve meaningful formatting text = text.replace('\\', '\\\\') text = text.replace("'", "\\'") text = text.replace('"', '\\"') text = text.replace('\n', '\\n') return text def generate_html(stories): """Generate the HTML presentation website.""" # Build the HTML structure html_parts = [ '', '', '', ' ', ' ', ' FloDoc User Stories - Epic Details', ' ', '', '', '
', '
Loading stories...
', ' ', ' ', '', '' ]) return '\n'.join(html_parts) def main(): # Paths epic_file = Path('/home/dev-mode/dev/dyict-projects/floDoc-v3/docs/prd/6-epic-details.md') output_dir = Path('/home/dev-mode/dev/dyict-projects/floDoc-v3/docs/backlog') output_html = output_dir / 'stories-presentation.html' print("Parsing epic details file...") stories = parse_epic_details(epic_file) print(f"Found {len(stories)} stories") print("Generating presentation HTML...") html = generate_html(stories) with open(output_html, 'w') as f: f.write(html) print(f"āœ… Presentation generated: {output_html}") print(f"šŸ“Š Total stories: {len(stories)}") print("\nStories included:") for story in stories: print(f" - {story['number']}: {story['title']}") # Also generate a summary markdown file summary_md = output_dir / 'STORIES_SUMMARY.md' with open(summary_md, 'w', encoding='utf-8') as f: f.write("# FloDoc User Stories - Summary\n\n") f.write(f"**Total Stories:** {len(stories)}\n\n") f.write("## Quick Reference\n\n") for story in stories: f.write(f"### {story['number']}: {story['title']}\n\n") f.write("**User Story:**\n") # Unescape for markdown user_story = story['user_story'].replace('\\n', '\n').replace('\\t', '\t') user_story = user_story.replace("\\'", "'").replace('\\"', '"') f.write(f"{user_story}\n\n") f.write("---\n\n") print(f"\nāœ… Summary generated: {summary_md}") if __name__ == '__main__': main()