"""Markdown to plain text conversion and notes slide XML generation.""" from __future__ import annotations import re from language_tags import normalize_language_tag from ..drawingml.utils import ( detect_text_lang, text_has_rtl_characters, text_uses_rtl, ) def markdown_to_plain_text(md_content: str) -> str: """Convert Markdown notes to plain text for PPTX notes. Args: md_content: Markdown formatted notes content. Returns: Plain text content. """ def strip_inline_bold(text: str) -> str: text = re.sub(r'\*\*(.+?)\*\*', r'\1', text) text = re.sub(r'__(.+?)__', r'\1', text) return text lines: list[str] = [] for line in md_content.split('\n'): if line.startswith('#'): text = re.sub(r'^#+\s*', '', line).strip() text = strip_inline_bold(text) if text: lines.append(text) lines.append('') elif line.strip().startswith('- '): item_text = line.strip()[2:] item_text = strip_inline_bold(item_text) lines.append('• ' + item_text) elif line.strip(): text = strip_inline_bold(line.strip()) lines.append(text) else: lines.append('') # Merge consecutive empty lines result: list[str] = [] is_prev_empty = False for line in lines: if line == '': if not is_prev_empty: result.append(line) is_prev_empty = True else: result.append(line) is_prev_empty = False return '\n'.join(result).strip() def create_notes_slide_xml( slide_num: int, notes_text: str, primary_language: str | None = None, ) -> str: """Create notes slide XML. Args: slide_num: Slide number. notes_text: Notes text in plain text format. primary_language: Canonical BCP-47 deck language, when available. Returns: Notes slide XML string. """ primary_language = ( normalize_language_tag(primary_language) if primary_language is not None else None ) default_language = primary_language or 'en-US' notes_text = (notes_text .replace('&', '&') .replace('<', '<') .replace('>', '>')) paragraphs: list[str] = [] for para in notes_text.split('\n'): if para.strip(): lang = detect_text_lang(para, primary_language) paragraph_rtl = ' rtl="1"' if text_uses_rtl( para, primary_language, ) else '' run_rtl = ( '' if text_has_rtl_characters(para) else '' ) paragraphs.append(f''' {run_rtl} {para} ''') else: paragraph_rtl = ( ' rtl="1"' if primary_language and text_uses_rtl('', primary_language) else '' ) paragraphs.append( f'' f'' ) paragraphs_xml = ( '\n '.join(paragraphs) if paragraphs else ( f'' ) ) return f''' {paragraphs_xml} ''' def create_notes_slide_rels_xml(slide_num: int) -> str: """Create notes slide relationship file XML. Args: slide_num: Slide number. Returns: Relationship file XML string. """ return f''' ''' def create_notes_master_xml(primary_language: str | None = None) -> str: """Create a minimal PowerPoint-compatible notes master XML.""" language = ( normalize_language_tag(primary_language) if primary_language is not None else 'en-US' ) paragraph_rtl = ' rtl="1"' if text_uses_rtl('', language) else '' return f''' ''' def create_notes_master_rels_xml() -> str: """Create notes master relationships XML.""" return ''' '''