M5: year-first slash dates (yyyy/mm/dd, yyyy/m/d) for Fill & Sign and headers

Taiwan, Japan and China write dates year first with slashes (Windows'
zh-TW short date is yyyy/M/d), and neither the Fill & Sign presets nor
the header and footer date tokens offered it. Both now have yyyy/mm/dd
and yyyy/m/d. The header and footer list gains them at its end, since
its selection is an index.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RUNQSPVXx3dDBabRZHAnjz
This commit is contained in:
mtlcl410
2026-10-16 19:20:48 +08:00
co-authored by Claude Opus 5.5
parent f0c9901c39
commit b97e59190f
4 changed files with 13 additions and 3 deletions
+3 -1
View File
@@ -54,7 +54,7 @@ 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>>`,
/// `<<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>>`, and Bates numbers `<<Bates Number#6#1#PRE#SUF>>`
/// (digits, start, prefix, suffix).
pub text: [String; 6],
pub font_size: f64,
@@ -244,6 +244,8 @@ pub fn expand(template: &str, page_number: u32, count: usize, bates: u64, cx: &C
"d/m/yyyy" => format!("{d}/{m}/{y}"),
"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}"),
"mmmm d, yyyy" => format!("{} {d}, {y}", MONTHS[(m.clamp(1, 12) - 1) as usize]),
t if t.starts_with("Bates Number") => {
// Bates Number#digits#start#prefix#suffix (start is applied by the caller).
+1
View File
@@ -60,6 +60,7 @@ fn tokens_expand() {
assert_eq!(expand("Page <<1>> of <<n>>", 3, 10, 0, &c), "Page 3 of 10");
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("<<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));
+6 -1
View File
@@ -13,7 +13,7 @@ use crate::Session;
pub const DEFAULT_DATE_FORMAT: &str = "m/d/yyyy";
/// Ready-made formats for Preferences ▸ Date format. Any other valid pattern works too.
pub const DATE_FORMATS: [&str; 12] = [
pub const DATE_FORMATS: [&str; 14] = [
"m/d/yyyy",
"mm/dd/yyyy",
"d/m/yyyy",
@@ -21,6 +21,9 @@ pub const DATE_FORMATS: [&str; 12] = [
"dd.mm.yyyy",
"yyyy-mm-dd",
"yyyy.mm.dd.",
// Year first with slashes, as Taiwan, Japan and China write it (Windows' zh-TW short date).
"yyyy/mm/dd",
"yyyy/m/d",
"d mmm yyyy",
"d mmmm yyyy",
"mmm d, yyyy",
@@ -604,6 +607,8 @@ mod tests {
"07.03.2026",
"2026-03-07",
"2026.03.07.",
"2026/03/07",
"2026/3/7",
"7 Mar 2026",
"7 March 2026",
"Mar 7, 2026",
+3 -1
View File
@@ -112,7 +112,9 @@ impl Default for MarksDraft {
}
const PAGE_FORMATS: [&str; 5] = ["<<1>>", "<<1 of n>>", "<<1/n>>", "<<Page 1>>", "<<Page 1 of n>>"];
const DATE_FORMATS: [&str; 6] = ["<<m/d/yyyy>>", "<<mm/dd/yyyy>>", "<<d/m/yyyy>>", "<<yyyy-mm-dd>>", "<<m/d/yy>>", "<<mmmm d, yyyy>>"];
// 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 BOX_NAMES: [&str; 6] =
["Left Header Text", "Center Header Text", "Right Header Text", "Left Footer Text", "Center Footer Text", "Right Footer Text"];