From aae0eda51e7e0d0580dd8e257060fa1fa2009275 Mon Sep 17 00:00:00 2001 From: Bill Mill Date: Tue, 17 Mar 2026 08:46:27 -0400 Subject: [PATCH 1/3] feat: add --padding option for left margin Add a --padding option that prepends N spaces to every output line, shifting content to start at column N+1 of the terminal. - Reduces effective width by padding amount so wrapping accounts for it - Supports MDRIVER_PADDING environment variable (CLI flag takes precedence) - Only applies in color mode; passthrough mode is unaffected - Padding is applied in main.rs as a post-processing step, keeping the streaming parser free of presentation concerns --- src/main.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6717a65..183f275 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ fn print_help() { println!(" --theme Use specified syntax highlighting theme"); println!(" --images Enable image rendering (protocols: kitty)"); println!(" --width Set output width for line wrapping (default: min(terminal width, 80))"); + println!(" --padding Add N spaces of left padding to output (default: 0)"); println!(" --color When to use colors: auto, always, never (default: auto)"); println!(); println!("ARGS:"); @@ -31,6 +32,7 @@ fn print_help() { println!("ENVIRONMENT:"); println!(" MDRIVER_THEME Default syntax highlighting theme (overridden by --theme)"); println!(" MDRIVER_WIDTH Default output width (overridden by --width)"); + println!(" MDRIVER_PADDING Default left padding (overridden by --padding)"); println!(); println!("EXAMPLES:"); println!(" mdriver README.md"); @@ -43,6 +45,34 @@ fn print_help() { println!(" MDRIVER_THEME=\"InspiredGitHub\" mdriver file.md"); } +/// Prepend `padding` spaces to each line of text. +/// The trailing empty string from a final `\n` is not padded, so we don't +/// add a spurious trailing line of spaces. +fn apply_padding(text: &str, padding: usize) -> String { + if padding == 0 || text.is_empty() { + return text.to_string(); + } + + let pad = " ".repeat(padding); + let lines: Vec<&str> = text.split('\n').collect(); + let last_idx = lines.len() - 1; + let mut result = String::new(); + + for (i, line) in lines.iter().enumerate() { + if i > 0 { + result.push('\n'); + } + // Don't pad the trailing empty string that results from a final \n + if i == last_idx && line.is_empty() { + continue; + } + result.push_str(&pad); + result.push_str(line); + } + + result +} + /// Color output mode #[derive(Clone, Copy, PartialEq)] enum ColorMode { @@ -58,6 +88,7 @@ fn run() -> io::Result<()> { // Parse arguments let mut theme: Option = None; let mut width: Option = None; + let mut padding: Option = None; let mut image_protocol = mdriver::ImageProtocol::None; let mut color_mode = ColorMode::Auto; let mut file_path: Option = None; @@ -129,6 +160,25 @@ fn run() -> io::Result<()> { std::process::exit(1); } } + "--padding" => { + if i + 1 < args.len() { + match args[i + 1].parse::() { + Ok(p) => { + padding = Some(p); + i += 2; + } + _ => { + eprintln!("Error: --padding requires a non-negative integer"); + eprintln!("Run 'mdriver --help' for usage information"); + std::process::exit(1); + } + } + } else { + eprintln!("Error: --padding requires a number"); + eprintln!("Run 'mdriver --help' for usage information"); + std::process::exit(1); + } + } "--images" => { if i + 1 < args.len() { match args[i + 1].as_str() { @@ -215,8 +265,29 @@ fn run() -> io::Result<()> { // Get width from parameter, environment variable, or use default let width = width.or_else(|| env::var("MDRIVER_WIDTH").ok().and_then(|s| s.parse().ok())); + // Get padding from parameter, environment variable, or default to 0 + let padding = padding + .or_else(|| { + env::var("MDRIVER_PADDING") + .ok() + .and_then(|s| s.parse().ok()) + }) + .unwrap_or(0); + + // Reduce the effective width by the padding so wrapping accounts for it let mut parser = if let Some(w) = width { - StreamingParser::with_width(&theme, image_protocol, w) + let effective = if w > padding { w - padding } else { 1 }; + StreamingParser::with_width(&theme, image_protocol, effective) + } else if padding > 0 { + let default_w = term_size::dimensions() + .map(|(w, _)| w.min(80)) + .unwrap_or(80); + let effective = if default_w > padding { + default_w - padding + } else { + 1 + }; + StreamingParser::with_width(&theme, image_protocol, effective) } else { StreamingParser::with_theme(&theme, image_protocol) }; @@ -230,12 +301,12 @@ fn run() -> io::Result<()> { let chunk = String::from_utf8_lossy(&buffer[..bytes_read]); let output = parser.feed(&chunk); - write!(stdout, "{}", output)?; + write!(stdout, "{}", apply_padding(&output, padding))?; } // Flush any remaining buffered content let output = parser.flush(); - write!(stdout, "{}", output)?; + write!(stdout, "{}", apply_padding(&output, padding))?; } else { // Passthrough mode: act like cat, no formatting loop { From 9d00496224faa28b0d9012492d9249ae97340a7a Mon Sep 17 00:00:00 2001 From: Bill Mill Date: Tue, 17 Mar 2026 08:46:56 -0400 Subject: [PATCH 2/3] docs: add session transcript for left-pad PR --- transcripts/left-pad.html | 3879 +++++++++++++++++++++++++++++++++++++ 1 file changed, 3879 insertions(+) create mode 100644 transcripts/left-pad.html diff --git a/transcripts/left-pad.html b/transcripts/left-pad.html new file mode 100644 index 0000000..3a06caa --- /dev/null +++ b/transcripts/left-pad.html @@ -0,0 +1,3879 @@ + + + + + + Session Export + + + + + +
+ +
+
+
+
+
+ +
+
+ + + + + + + + + + + + + From 014fa0d2c5f634be95970f676dbbbc3868e9f624 Mon Sep 17 00:00:00 2001 From: Bill Mill Date: Tue, 17 Mar 2026 08:48:10 -0400 Subject: [PATCH 3/3] fix: pr numbers on transcripts --- .../{pin-rust-toolchain.html => 62-pin-rust-toolchain.html} | 0 transcripts/{left-pad.html => 67-left-pad.html} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename transcripts/{pin-rust-toolchain.html => 62-pin-rust-toolchain.html} (100%) rename transcripts/{left-pad.html => 67-left-pad.html} (100%) diff --git a/transcripts/pin-rust-toolchain.html b/transcripts/62-pin-rust-toolchain.html similarity index 100% rename from transcripts/pin-rust-toolchain.html rename to transcripts/62-pin-rust-toolchain.html diff --git a/transcripts/left-pad.html b/transcripts/67-left-pad.html similarity index 100% rename from transcripts/left-pad.html rename to transcripts/67-left-pad.html