diff options
Diffstat (limited to 'src/fenced_md_generator.rs')
| -rw-r--r-- | src/fenced_md_generator.rs | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/src/fenced_md_generator.rs b/src/fenced_md_generator.rs deleted file mode 100644 index bf44e3a..0000000 --- a/src/fenced_md_generator.rs +++ /dev/null @@ -1,178 +0,0 @@ -//! Generate Markdown and wrap the entire result in an outer Markdown fence. -//! -//! This module is useful when the generated project Markdown needs to be embedded inside another -//! document or a prompt. - -use std::{io::Write, path::Path}; - -use crate::{ - logger::Logger, md_generator::generate_markdown_from_paths, renderer::RenderOptions, - util::fence::generate_outer_backticks, -}; - -/// Generates Markdown from `paths` and wraps the full output in a fence. -/// -/// The inner Markdown is produced by [`generate_markdown_from_paths`]. The outer fence length is -/// chosen so that any backtick runs inside the generated Markdown cannot close the outer fence. -/// -/// `render_options` controls file-size limits and placeholder behavior. `root` controls displayed -/// relative paths, while `origin_base` controls how relative input paths are resolved. -pub fn generate_fenced_markdown<W: Write>( - paths: &[&Path], - mut output: W, - render_options: RenderOptions, - root: &Path, - origin_base: &Path, - project_title: Option<&str>, - logger: Logger, -) -> Result<(), Box<dyn std::error::Error>> { - let mut md_output = Vec::new(); - generate_markdown_from_paths( - paths, - &mut md_output, - render_options, - root, - origin_base, - project_title, - logger, - )?; - let fence = generate_outer_backticks(&md_output); - writeln!(output, "{}markdown", fence)?; - output.write_all(&md_output)?; - writeln!(output, "{}", fence)?; - Ok(()) -} - -#[cfg(test)] -mod tests { - use std::fs; - use std::io::Write; - use std::path::Path; - use tempfile::tempdir; - - use crate::logger::Logger; - use crate::renderer::RenderOptions; - - use super::generate_fenced_markdown; - - fn generate_fenced_with_defaults<W: Write>( - paths: &[&Path], - output: W, - root: &std::path::Path, - origin_base: &std::path::Path, - project_title: Option<&str>, - ) -> Result<(), Box<dyn std::error::Error>> { - let logger = Logger::default(); - let render_options = RenderOptions::default(); - generate_fenced_markdown( - paths, - output, - render_options, - root, - origin_base, - project_title, - logger, - ) - } - - #[test] - fn empty_path_list_produces_wrapped_header() { - let temp_dir = tempdir().unwrap(); - let paths = []; - let mut output = Vec::new(); - let root = temp_dir.path(); - let origin_base = temp_dir.path(); - - generate_fenced_with_defaults(&paths, &mut output, root, origin_base, Some("Project name")) - .unwrap(); - - assert_eq!( - String::from_utf8(output).unwrap(), - "```markdown\n# Project name\n```\n" - ); - } - - #[test] - fn single_file_is_wrapped() { - let temp_dir = tempdir().unwrap(); - let origin_base = temp_dir.path(); - let paths = [Path::new("test_main.rs")]; - let mut output = Vec::new(); - let root = temp_dir.path(); - - fs::write(origin_base.join("test_main.rs"), "fn main() {}").unwrap(); - - generate_fenced_with_defaults(&paths, &mut output, root, origin_base, None).unwrap(); - - let output_str = String::from_utf8(output).unwrap(); - // Must contain outer fence - assert!(output_str.starts_with("````markdown\n")); - assert!(output_str.ends_with("\n````\n")); - // Must contain file content - assert!(output_str.contains("## File: test_main.rs")); - assert!(output_str.contains("fn main() {}")); - } - - #[test] - fn multiple_files_are_wrapped_in_one_outer_fence() { - let temp_dir = tempdir().unwrap(); - let origin_base = temp_dir.path(); - let paths = [Path::new("a.rs"), Path::new("b.rs")]; - let mut output = Vec::new(); - let root = temp_dir.path(); - - fs::write(origin_base.join("a.rs"), "A").unwrap(); - fs::write(origin_base.join("b.rs"), "B").unwrap(); - - generate_fenced_with_defaults(&paths, &mut output, root, origin_base, None).unwrap(); - - let output_str = String::from_utf8(output).unwrap(); - // Each inner file must have its own languageāspecific fence - assert!(output_str.contains("```rust\nA\n```")); - assert!(output_str.contains("```rust\nB\n```")); - // Only one outer fence at start and end - assert_eq!(output_str.matches("````markdown").count(), 1); - assert_eq!(output_str.matches("\n````\n").count(), 1); - } - - #[test] - fn inner_file_with_four_backticks_causes_outer_fence_of_six_backticks() { - let temp_dir = tempdir().unwrap(); - let origin_base = temp_dir.path(); - let paths = [Path::new("backticks.rs")]; - let mut output = Vec::new(); - let root = temp_dir.path(); - - let content = "````"; // 4 backticks - fs::write(origin_base.join("backticks.rs"), content).unwrap(); - - generate_fenced_with_defaults(&paths, &mut output, root, origin_base, None).unwrap(); - - let output_str = String::from_utf8(output).unwrap(); - // Inner fence should be 5 backticks because inner content contains 4 backticks - assert!(output_str.contains("`````rust\n````\n`````")); - // Outer fence must then be 6 backticks - assert!(output_str.starts_with("``````markdown\n")); - assert!(output_str.ends_with("\n``````\n")); - } - - #[test] - fn project_title_with_three_backticks_causes_outer_fence_of_four_backticks() { - let temp_dir = tempdir().unwrap(); - let paths = []; - let mut output = Vec::new(); - let root = temp_dir.path(); - let origin_base = temp_dir.path(); - - let project_title = "Project ``` name"; - generate_fenced_with_defaults(&paths, &mut output, root, origin_base, Some(project_title)) - .unwrap(); - - let output_str = String::from_utf8(output).unwrap(); - // Outer fence must be 4 backticks because the header contains 3 backticks - assert!(output_str.starts_with("````markdown\n")); - assert!(output_str.ends_with("\n````\n")); - // The header line itself should appear unchanged - assert!(output_str.contains("# Project ``` name")); - } -} |
