//! Render the LLM's Markdown document to safe HTML. //! //! The LLM produces Markdown with a non-standard `==text==` highlight //! convention for stretches the doctor should double-check (suspected //! transcription errors, incomplete info, numbers without context). We //! convert those to `` tags — the only raw HTML we inject — after //! HTML-escaping the entire LLM output. That way even if the LLM writes //! `"); assert_eq!(out, "<script>alert('x')</script>"); } #[test] fn escape_and_mark_allows_only_our_mark_tags() { // LLM emits both raw HTML and a ==mark==; only the mark becomes live HTML. let out = escape_and_mark("fett und ==wichtig=="); assert_eq!(out, "<b>fett</b> und wichtig"); } #[test] fn escape_and_mark_preserves_unmatched_opener_as_text() { let out = escape_and_mark("==offen ohne Ende"); assert_eq!(out, "==offen ohne Ende"); } #[test] fn escape_and_mark_does_not_cross_newlines() { let out = escape_and_mark("==kein\nmark=="); // A newline between the openers cancels the highlight. assert_eq!(out, "==kein\nmark=="); } #[test] fn escape_and_mark_handles_multiple_marks_in_one_line() { let out = escape_and_mark("==A== und ==B=="); assert_eq!(out, "A und B"); } #[test] fn escape_and_mark_handles_unicode_content_in_mark() { let out = escape_and_mark("==Blutdruck 140/90 über Norm=="); assert_eq!(out, "Blutdruck 140/90 über Norm"); } #[test] fn md_to_html_wraps_plain_text_in_paragraph() { let out = md_to_html("Fließtext ohne Auszeichnung."); assert_eq!(out.trim(), "

Fließtext ohne Auszeichnung.

"); } #[test] fn md_to_html_renders_mark_inline() { let out = md_to_html("Patient klagt über ==Tastanalyse==."); assert!(out.contains("Tastanalyse")); assert!(out.contains("

")); } #[test] fn md_to_html_blocks_raw_html_from_llm() { // Even if the LLM embeds a "); assert!(!out.contains("