From 635b42d9899a671b8e82d50033d970b16643c40f Mon Sep 17 00:00:00 2001 From: Juan Jurado Date: Thu, 22 Oct 2026 18:42:49 -0600 Subject: [PATCH] M10: ARCH E1 goes out as PWG 5101.1's na_wide-format_30x42in (#3752) 30 x 42 in is `na_wide-format_30x42in` in PWG 5101.1-2023 and the IANA IPP registry (checked against both). `na_arch-e1_30x42in` was asked for on the IPP list in 2021 but never registered. CUPS maps the new name to the PPD's 30 x 42 in size (cupsfilter, synthetic PPD), and the paper test pins it and fails on the old name. Doc comments for bad, printers and two paper tests, for the review's docstring check. Review: storytold/pdfcraft#4161 (CodeRabbit). --- crates/automation/src/printing.rs | 3 +++ crates/print/src/lib.rs | 10 +++++----- crates/print/src/tests.rs | 10 +++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/automation/src/printing.rs b/crates/automation/src/printing.rs index 111d27eecf..74e7328140 100644 --- a/crates/automation/src/printing.rs +++ b/crates/automation/src/printing.rs @@ -22,6 +22,7 @@ fn duplex(value: &str, cut_stack: bool) -> Result> { }) } +/// An invalid-arguments error saying `m`. fn bad(m: impl Into) -> ToolError { ToolError::InvalidArgs(m.into()) } @@ -75,6 +76,8 @@ fn spool_job(a: &Args, printer: &str, title: String, duplex: Option Result { let list: Vec = spool::printers() .into_iter() diff --git a/crates/print/src/lib.rs b/crates/print/src/lib.rs index 75b6fdf1f4..d85e766f14 100644 --- a/crates/print/src/lib.rs +++ b/crates/print/src/lib.rs @@ -309,10 +309,10 @@ pub const LABEL_PAPER: usize = 19; /// The CUPS media name for `PAPERS[index]`, so the spooler feeds the sheet the PDF was laid out /// on rather than the queue's default; `None` only past the end of `PAPERS`. The common sizes /// use their PPD keywords (`w288h432` is the usual 4×6 label, `Env10` the US #10 envelope). -/// The rest use PWG 5101.1 names (for ARCH E1, which 5101.1 lacks, the IANA registry's), spelled -/// exactly: a driverless printer may take only the names it advertises. They carry their -/// dimensions, so CUPS feeds the PPD size of those dimensions whatever the driver calls it -/// (`ARCHD`, `AnsiD`) (#3752). +/// The rest use PWG 5101.1 names (ARCH E1 is its `wide-format` size), spelled exactly as the +/// spec and the IANA registry have them: a driverless printer may take only the names it +/// advertises. They carry their dimensions, so CUPS feeds the PPD size of those dimensions +/// whatever the driver calls it (`ARCHD`, `AnsiD`) (#3752). pub fn cups_media(index: usize) -> Option<&'static str> { Some(match PAPERS.get(index)?.0 { "US Letter" => "Letter", @@ -326,7 +326,7 @@ pub fn cups_media(index: usize) -> Option<&'static str> { "ARCH B (12 x 18 in)" => "na_arch-b_12x18in", "ARCH C (18 x 24 in)" => "na_arch-c_18x24in", "ARCH D (24 x 36 in)" => "na_arch-d_24x36in", - "ARCH E1 (30 x 42 in)" => "na_arch-e1_30x42in", + "ARCH E1 (30 x 42 in)" => "na_wide-format_30x42in", "ARCH E (36 x 48 in)" => "na_arch-e_36x48in", "ANSI C (17 x 22 in)" => "na_c_17x22in", "ANSI D (22 x 34 in)" => "na_d_22x34in", diff --git a/crates/print/src/tests.rs b/crates/print/src/tests.rs index e7777fa1ac..d93bdf745b 100644 --- a/crates/print/src/tests.rs +++ b/crates/print/src/tests.rs @@ -661,6 +661,8 @@ fn architectural_sheets_preserve_full_scale() { assert!(fit[0].placed[0].matrix.0[0] < 1.0, "Fit adds margins and must not masquerade as full scale"); } +/// A sheet matches a preset either way round and rounded to whole points, but not half a point off; +/// empty, negative, infinite, NaN and custom sizes match none. #[test] fn paper_matching_accepts_rounded_metric_sizes_but_not_custom_or_invalid_sizes() { for (i, (_, (w, h))) in PAPERS.iter().enumerate() { @@ -702,7 +704,8 @@ fn every_paper_reaches_the_spooler_by_a_name_of_its_size() { assert_eq!((cups_media(PAPERS.len()), media_option(PAPERS.len())), (None, None)); // The names themselves, spelled as PWG 5101.1 has them: a driverless printer may take only the // names it advertises, so one CUPS can merely parse (ARCH A was `arch_a_9x12in`) is not enough. - // ARCH E1 isn't in 5101.1; its name is the IANA registry's. + // ARCH E1 is 5101.1's `wide-format` size: `na_arch-e1_30x42in` was asked for once and never + // registered. let names: Vec<(&str, &str)> = PAPERS.iter().enumerate().map(|(i, (name, _))| (*name, cups_media(i).unwrap_or_default())).collect(); assert_eq!( names, @@ -718,7 +721,7 @@ fn every_paper_reaches_the_spooler_by_a_name_of_its_size() { ("ARCH B (12 x 18 in)", "na_arch-b_12x18in"), ("ARCH C (18 x 24 in)", "na_arch-c_18x24in"), ("ARCH D (24 x 36 in)", "na_arch-d_24x36in"), - ("ARCH E1 (30 x 42 in)", "na_arch-e1_30x42in"), + ("ARCH E1 (30 x 42 in)", "na_wide-format_30x42in"), ("ARCH E (36 x 48 in)", "na_arch-e_36x48in"), ("ANSI C (17 x 22 in)", "na_c_17x22in"), ("ANSI D (22 x 34 in)", "na_d_22x34in"), @@ -732,9 +735,10 @@ fn every_paper_reaches_the_spooler_by_a_name_of_its_size() { ); } +/// #2734: the US #10 envelope (4.125 × 9.5 in) is offered, fed by its PPD name and laid out at +/// its own size. #[test] fn us_number_10_envelope_is_offered_and_fed_by_name() { - // 4.125 × 9.5 in (#2734). let index = matching_paper((684.0, 297.0)).unwrap(); assert_eq!(PAPERS[index].0, "US #10 Envelope (4.125 x 9.5 in)"); assert_eq!(PAPERS[index].1, (297.0, 684.0));