diff --git a/.needle-predispatch-sha b/.needle-predispatch-sha index 9a2a6bb..d955701 100644 --- a/.needle-predispatch-sha +++ b/.needle-predispatch-sha @@ -1 +1 @@ -157680f4ee7b3e4597283f81c4d0f5dd4a643728 +14a9408a31d7444af4127464e86bea2e186c3f87 diff --git a/crates/pdftract-cli/src/doctor/output/human.rs b/crates/pdftract-cli/src/doctor/output/human.rs index a11631a..71fb182 100644 --- a/crates/pdftract-cli/src/doctor/output/human.rs +++ b/crates/pdftract-cli/src/doctor/output/human.rs @@ -74,16 +74,17 @@ pub fn output_text(results: &[CheckResult], opts: &TextOptions) -> Result<()> { stdout.reset()?; // Print detail (truncate if too long for terminal) - let detail = if std::io::stdout().is_terminal() && !opts.no_color { - let term_width = terminal_size::terminal_size() + // For TTY, use actual terminal width; for non-TTY, assume 80 columns + let term_width = if std::io::stdout().is_terminal() && !opts.no_color { + terminal_size::terminal_size() .map(|(w, _)| w.0 as usize) - .unwrap_or(80); - let max_detail = term_width.saturating_sub(38); // 30 + 1 + 6 + 1 = 38 columns before detail - if result.detail.len() > max_detail { - format!("{}...", &result.detail[..max_detail.saturating_sub(3)]) - } else { - result.detail.clone() - } + .unwrap_or(80) + } else { + 80 + }; + let max_detail = term_width.saturating_sub(38); // 30 + 1 + 6 + 1 = 38 columns before detail + let detail = if result.detail.len() > max_detail { + format!("{}...", &result.detail[..max_detail.saturating_sub(3)]) } else { result.detail.clone() }; diff --git a/notes/pdftract-1w5u1.md b/notes/pdftract-1w5u1.md index eb60772..0662f29 100644 --- a/notes/pdftract-1w5u1.md +++ b/notes/pdftract-1w5u1.md @@ -48,6 +48,9 @@ The three output formats for `pdftract doctor` were already implemented in: - Output fits within 80 columns without wrapping - Column widths: name=30, status=6, detail=flex - Separator line is exactly 80 characters +- **FIX:** Detail truncation now applies uniformly to TTY and non-TTY output +- Previously: Truncation only in TTY mode, causing >80-char lines when piped or using --no-color +- Now: Truncation always based on 80 columns (TTY uses actual width, non-TTY assumes 80) ### PASS: N/A row handling - N/A checks excluded from human output (verified in code: line 41-43 of human.rs) @@ -61,7 +64,22 @@ The three output formats for `pdftract doctor` were already implemented in: ## Implementation Notes -The output modules were already implemented with: +### Fix Applied + +**File:** `crates/pdftract-cli/src/doctor/output/human.rs` + +**Issue:** Detail field truncation only applied to TTY output. When piping to `cat` or using `--no-color`, long detail strings were not truncated, causing lines to exceed 80 columns. + +**Solution:** Modified truncation logic (lines 77-89) to: +1. Determine terminal width: TTY uses actual width, non-TTY assumes 80 columns +2. Calculate max detail width: `term_width - 38` (30 name + 1 space + 6 status + 1 space) +3. Truncate detail to max width with "..." suffix if needed + +**Result:** Max line width now exactly 80 characters for all output modes. + +### Existing Implementation + +The output modules were implemented with: 1. **TTY detection** via `std::io::IsTerminal` trait (nightly feature stabilized) 2. **Color control** via `termcolor` crate with `ColorChoice` enum 3. **Terminal width detection** via `terminal_size` crate @@ -69,4 +87,4 @@ The output modules were already implemented with: 5. **Summary line** at bottom with bold formatting 6. **Stderr output** for failures (in addition to stdout summary) -All acceptance criteria are met. No changes were required to the codebase. +All acceptance criteria are met. One fix was applied to ensure 80-column compliance for non-TTY output.