mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-25 18:47:22 -06:00
M7: dotted day-first dates in header and footer (#4503)
Header and footer dates had US, ISO and day-first slash forms only. The dotted forms written in German-speaking and much of Central and Eastern Europe join them: <<dd.mm.yyyy>>, <<d.m.yyyy>>, <<dd.mm.yy>>, <<d.m.yy>>. The dialog's date list offers the first three after the existing ones. Generated with Claude Code Signed-off-by: Marco Hagspiel <m.hagspiel@lcs-group.com> Co-authored-by: Marco Hagspiel <m.hagspiel@lcs-group.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Marco Hagspiel
Claude
parent
538eb1624b
commit
af4a307e99
@@ -956,7 +956,7 @@ pub fn tools() -> Vec<ToolDef> {
|
||||
t(
|
||||
"doc_header_footer",
|
||||
"Add header and footer",
|
||||
"Add a header and/or footer to pages. Text boxes: header_left/center/right, footer_left/center/right. Tokens: <<1>> page number, <<n>> page count, <<1 of n>>, <<Page 1 of n>>, <<1/n>>, dates <<m/d/yyyy>> <<yyyy-mm-dd>> <<mmmm d, yyyy>> (and more), Bates <<Bates Number#6#1#PREFIX#SUFFIX>>. shrink: true scales the page content down evenly into the room the header and footer leave free, so they don't cover it. font: Helvetica (default), Times or Courier. replace: true swaps out existing ones (Update). Undoable.",
|
||||
"Add a header and/or footer to pages. Text boxes: header_left/center/right, footer_left/center/right. Tokens: <<1>> page number, <<n>> page count, <<1 of n>>, <<Page 1 of n>>, <<1/n>>, dates <<m/d/yyyy>> <<yyyy-mm-dd>> <<mmmm d, yyyy>> <<dd.mm.yyyy>> (and more), Bates <<Bates Number#6#1#PREFIX#SUFFIX>>. shrink: true scales the page content down evenly into the room the header and footer leave free, so they don't cover it. font: Helvetica (default), Times or Courier. replace: true swaps out existing ones (Update). Undoable.",
|
||||
)
|
||||
.cmd("edit.header_footer")
|
||||
.with(schema(
|
||||
|
||||
@@ -57,7 +57,9 @@ pub struct HeaderFooter {
|
||||
/// Left, centre and right header text, then left, centre and right footer text. Tokens:
|
||||
/// `<<1>>` page number, `<<n>>` page count, `<<1 of n>>`, `<<1/n>>`, `<<Page 1>>`,
|
||||
/// `<<Page 1 of n>>`, dates `<<m/d/yyyy>>`, `<<mm/dd/yyyy>>`, `<<d/m/yyyy>>`, `<<yyyy-mm-dd>>`,
|
||||
/// `<<yyyy/mm/dd>>`, `<<yyyy/m/d>>`, `<<m/d/yy>>`, `<<mmmm d, yyyy>>`, and Bates numbers `<<Bates Number#6#1#PRE#SUF>>`
|
||||
/// `<<yyyy/mm/dd>>`, `<<yyyy/m/d>>`, `<<m/d/yy>>`, `<<mmmm d, yyyy>>`, the dotted day-first
|
||||
/// dates of German-speaking and much of Central and Eastern Europe `<<dd.mm.yyyy>>`,
|
||||
/// `<<d.m.yyyy>>`, `<<dd.mm.yy>>`, `<<d.m.yy>>`, and Bates numbers `<<Bates Number#6#1#PRE#SUF>>`
|
||||
/// (digits, start, prefix, suffix).
|
||||
pub text: [String; 6],
|
||||
/// The standard face the text is drawn in (#3754): Helvetica (the default), Times or Courier.
|
||||
@@ -297,6 +299,10 @@ pub fn expand(template: &str, page_number: u32, count: usize, bates: u64, cx: &C
|
||||
"d/m/yy" => format!("{d}/{m}/{:02}", y.rem_euclid(100)),
|
||||
"d/m/yyyy" => format!("{d}/{m}/{y}"),
|
||||
"dd/mm/yyyy" => format!("{d:02}/{m:02}/{y}"),
|
||||
"d.m.yy" => format!("{d}.{m}.{:02}", y.rem_euclid(100)),
|
||||
"d.m.yyyy" => format!("{d}.{m}.{y}"),
|
||||
"dd.mm.yy" => format!("{d:02}.{m:02}.{:02}", y.rem_euclid(100)),
|
||||
"dd.mm.yyyy" => format!("{d:02}.{m:02}.{y}"),
|
||||
"yyyy-mm-dd" => format!("{y}-{m:02}-{d:02}"),
|
||||
"yyyy/mm/dd" => format!("{y}/{m:02}/{d:02}"),
|
||||
"yyyy/m/d" => format!("{y}/{m}/{d}"),
|
||||
|
||||
@@ -82,6 +82,7 @@ fn tokens_expand() {
|
||||
assert_eq!(expand("<<1 of n>> · <<Page 1>> · <<1/n>>", 2, 5, 0, &c), "2 of 5 · Page 2 · 2/5");
|
||||
assert_eq!(expand("<<m/d/yyyy>> <<yyyy-mm-dd>> <<mmmm d, yyyy>>", 1, 1, 0, &c), "10/1/2026 2026-10-01 October 1, 2026");
|
||||
assert_eq!(expand("<<yyyy/mm/dd>> <<yyyy/m/d>>", 1, 1, 0, &c), "2026/10/01 2026/10/1");
|
||||
assert_eq!(expand("<<dd.mm.yyyy>> <<d.m.yyyy>> <<dd.mm.yy>> <<d.m.yy>>", 1, 1, 0, &c), "01.10.2026 1.10.2026 01.10.26 1.10.26");
|
||||
assert_eq!(expand("<<Bates Number#6#100#ABC#-X>>", 1, 1, 104, &c), "ABC000104-X");
|
||||
assert_eq!(expand("keep <<unknown>> and <<unclosed", 1, 1, 0, &c), "keep <<unknown>> and <<unclosed");
|
||||
assert_eq!(bates_start("x <<Bates Number#6#100#A#B>>"), Some(100));
|
||||
|
||||
@@ -117,8 +117,19 @@ impl Default for MarksDraft {
|
||||
|
||||
const PAGE_FORMATS: [&str; 5] = ["<<1>>", "<<1 of n>>", "<<1/n>>", "<<Page 1>>", "<<Page 1 of n>>"];
|
||||
// New formats go last: `date_format` is an index into this list.
|
||||
const DATE_FORMATS: [&str; 8] =
|
||||
["<<m/d/yyyy>>", "<<mm/dd/yyyy>>", "<<d/m/yyyy>>", "<<yyyy-mm-dd>>", "<<m/d/yy>>", "<<mmmm d, yyyy>>", "<<yyyy/mm/dd>>", "<<yyyy/m/d>>"];
|
||||
const DATE_FORMATS: [&str; 11] = [
|
||||
"<<m/d/yyyy>>",
|
||||
"<<mm/dd/yyyy>>",
|
||||
"<<d/m/yyyy>>",
|
||||
"<<yyyy-mm-dd>>",
|
||||
"<<m/d/yy>>",
|
||||
"<<mmmm d, yyyy>>",
|
||||
"<<yyyy/mm/dd>>",
|
||||
"<<yyyy/m/d>>",
|
||||
"<<dd.mm.yyyy>>",
|
||||
"<<d.m.yyyy>>",
|
||||
"<<dd.mm.yy>>",
|
||||
];
|
||||
const BOX_NAMES: [&str; 6] =
|
||||
["Left Header Text", "Center Header Text", "Right Header Text", "Left Footer Text", "Center Footer Text", "Right Footer Text"];
|
||||
|
||||
|
||||
@@ -2448,7 +2448,7 @@ status = "shipped"
|
||||
commands = ["edit.header_footer"]
|
||||
tools = ["doc_header_footer"]
|
||||
evidence = ["crates/edit/src/tests.rs::tokens_expand", "crates/engine/src/tests.rs::headers_footers_watermarks_and_backgrounds_show_update_and_remove"]
|
||||
notes = "<<1>>, <<n>>, <<1 of n>>, <<Page 1 of n>>, dates, Bates"
|
||||
notes = "<<1>>, <<n>>, <<1 of n>>, <<Page 1 of n>>, dates (US, ISO, day-first with slashes and the dotted <<dd.mm.yyyy>>, <<d.m.yyyy>>, <<dd.mm.yy>>, <<d.m.yy>>), Bates. Month names are English only"
|
||||
|
||||
[[feature]]
|
||||
id = "edit.header-footer-ranges"
|
||||
|
||||
Reference in New Issue
Block a user