commit 40a77c87e7ad561df0ee8e7606c2d8b52e331158
parent a0bc1c7f6afbcb567538aa709c933442b3b70065
Author: Michael Camilleri <[email protected]>
Date: Tue, 19 May 2026 09:39:01 +0900
Clean .puz author strings and label the credits page
The .puz to .xd converter wrote the raw Across Lite author field straight into
the Author: metadata. Those strings frequently embed the credit phrasing itself
("by Jane Doe", "Edited by John Smith"), which would then collide with any "By"
prefix at display time.
Thia commit adds displayAuthor(fromPUZAuthor:), mirroring the existing
displayTitle helper: it trims surrounding whitespace and strips a leading
case-insensitive "by "/"edited by " so the stored Author: value is a clean name.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
Diffstat:
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/Crossmate/Services/PUZToXDConverter.swift b/Crossmate/Services/PUZToXDConverter.swift
@@ -60,7 +60,7 @@ enum PUZToXDConverter {
}
let title = displayTitle(fromPUZTitle: stringTable.strings[0])
- let author = stringTable.strings[1]
+ let author = displayAuthor(fromPUZAuthor: stringTable.strings[1])
let copyright = stringTable.strings[2]
let clueTexts = Array(stringTable.strings[3..<(3 + clueCount)])
let extensions = parseExtensions(in: data, from: stringTable.endOffset)
@@ -264,6 +264,21 @@ enum PUZToXDConverter {
return result
}
+ /// `.puz` author strings frequently embed the credit phrasing
+ /// ("by Jane Doe", "Edited by John Smith"). Strip a leading
+ /// "by"/"edited by" and surrounding whitespace so the stored
+ /// `Author:` metadata is a clean name, matching the NYT path; the
+ /// credits view supplies the "By " label at render time.
+ private static func displayAuthor(fromPUZAuthor author: String) -> String {
+ var result = author.trimmingCharacters(in: .whitespacesAndNewlines)
+ for prefix in ["edited by ", "by "] where result.lowercased().hasPrefix(prefix) {
+ result = String(result.dropFirst(prefix.count))
+ .trimmingCharacters(in: .whitespacesAndNewlines)
+ break
+ }
+ return result
+ }
+
private static func parseExtensions(in data: Data, from start: Int) -> [String: Data] {
var extensions: [String: Data] = [:]
var offset = start