Commit 4b5c7c4231

4b5c7c4231abd09204bbb386a61e7f1d78e07c3c

parent: 481c39f230

Unsigned

cmc <hello@cleberg.net> · 2026-03-30 22:20 UTC

Fix nonisolated table alignment lookup in Readme View

Layout: unified · split

Hutch.xcodeproj/project.pbxproj +40 −14
@@ -10,7 +10,11 @@
10 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89632F69DEB900FC0253 /* LICENSE */; }; 10 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89632F69DEB900FC0253 /* LICENSE */; };
11 8B2F89672F69DEB900FC0253 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89642F69DEB900FC0253 /* README.md */; }; 11 8B2F89672F69DEB900FC0253 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89642F69DEB900FC0253 /* README.md */; };
12 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89652F69DEB900FC0253 /* SECURITY.md */; }; 12 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89652F69DEB900FC0253 /* SECURITY.md */; };
13 8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8BE081F62F80000100000001 /* HutchWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 13 8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 8BE081F62F80000100000001 /* HutchWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
14 8BE09E7F2F7B2CC300F88693 /* storebutton.svg in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7C2F7B2CC300F88693 /* storebutton.svg */; };
15 8BE09E802F7B2CC300F88693 /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7A2F7B2CC300F88693 /* index.html */; };
16 8BE09E812F7B2CC300F88693 /* styles.css in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7D2F7B2CC300F88693 /* styles.css */; };
17 8BE09E822F7B2CC300F88693 /* privacy.html in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7B2F7B2CC300F88693 /* privacy.html */; };
14 8BF100032F9A000100000001 /* Markdown in Frameworks */ = {isa = PBXBuildFile; productRef = 8BF100022F9A000100000001 /* Markdown */; }; 18 8BF100032F9A000100000001 /* Markdown in Frameworks */ = {isa = PBXBuildFile; productRef = 8BF100022F9A000100000001 /* Markdown */; };
15/* End PBXBuildFile section */ 19/* End PBXBuildFile section */
16 20
@@ -32,15 +36,15 @@
32/* End PBXContainerItemProxy section */ 36/* End PBXContainerItemProxy section */
33 37
34/* Begin PBXCopyFilesBuildPhase section */ 38/* Begin PBXCopyFilesBuildPhase section */
35 8BE081FA2F80000100000001 /* Embed App Extensions */ = { 39 8BE081FA2F80000100000001 /* Embed Foundation Extensions */ = {
36 isa = PBXCopyFilesBuildPhase; 40 isa = PBXCopyFilesBuildPhase;
37 buildActionMask = 2147483647; 41 buildActionMask = 2147483647;
38 dstPath = ""; 42 dstPath = "";
39 dstSubfolderSpec = 13; 43 dstSubfolderSpec = 13;
40 files = ( 44 files = (
41 8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed App Extensions */, 45 8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed Foundation Extensions */,
42 ); 46 );
43 name = "Embed App Extensions"; 47 name = "Embed Foundation Extensions";
44 runOnlyForDeploymentPostprocessing = 0; 48 runOnlyForDeploymentPostprocessing = 0;
45 }; 49 };
46/* End PBXCopyFilesBuildPhase section */ 50/* End PBXCopyFilesBuildPhase section */
@@ -54,6 +58,10 @@
54 8B8182C22F6B742B000AE049 /* HutchTests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = HutchTests; sourceTree = "<group>"; }; 58 8B8182C22F6B742B000AE049 /* HutchTests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = HutchTests; sourceTree = "<group>"; };
55 8BDCA5272F6B76B20066AA29 /* HutchTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = HutchTests.xctestplan; sourceTree = "<group>"; }; 59 8BDCA5272F6B76B20066AA29 /* HutchTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = HutchTests.xctestplan; sourceTree = "<group>"; };
56 8BE081F62F80000100000001 /* HutchWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = HutchWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 60 8BE081F62F80000100000001 /* HutchWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = HutchWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
61 8BE09E7A2F7B2CC300F88693 /* index.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
62 8BE09E7B2F7B2CC300F88693 /* privacy.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = privacy.html; sourceTree = "<group>"; };
63 8BE09E7C2F7B2CC300F88693 /* storebutton.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = storebutton.svg; sourceTree = "<group>"; };
64 8BE09E7D2F7B2CC300F88693 /* styles.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = styles.css; sourceTree = "<group>"; };
57/* End PBXFileReference section */ 65/* End PBXFileReference section */
58 66
59/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ 67/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@@ -131,6 +139,7 @@
131 8B4B28C82F6704280045FA19 = { 139 8B4B28C82F6704280045FA19 = {
132 isa = PBXGroup; 140 isa = PBXGroup;
133 children = ( 141 children = (
142 8BE09E7E2F7B2CC300F88693 /* website */,
134 8BDCA5272F6B76B20066AA29 /* HutchTests.xctestplan */, 143 8BDCA5272F6B76B20066AA29 /* HutchTests.xctestplan */,
135 8B8182C22F6B742B000AE049 /* HutchTests */, 144 8B8182C22F6B742B000AE049 /* HutchTests */,
136 8B2F89632F69DEB900FC0253 /* LICENSE */, 145 8B2F89632F69DEB900FC0253 /* LICENSE */,
@@ -154,6 +163,17 @@
154 name = Products; 163 name = Products;
155 sourceTree = "<group>"; 164 sourceTree = "<group>";
156 }; 165 };
166 8BE09E7E2F7B2CC300F88693 /* website */ = {
167 isa = PBXGroup;
168 children = (
169 8BE09E7A2F7B2CC300F88693 /* index.html */,
170 8BE09E7B2F7B2CC300F88693 /* privacy.html */,
171 8BE09E7C2F7B2CC300F88693 /* storebutton.svg */,
172 8BE09E7D2F7B2CC300F88693 /* styles.css */,
173 );
174 path = website;
175 sourceTree = "<group>";
176 };
157/* End PBXGroup section */ 177/* End PBXGroup section */
158 178
159/* Begin PBXNativeTarget section */ 179/* Begin PBXNativeTarget section */
@@ -164,7 +184,7 @@
164 8B4B28CD2F6704280045FA19 /* Sources */, 184 8B4B28CD2F6704280045FA19 /* Sources */,
165 8B4B28CE2F6704280045FA19 /* Frameworks */, 185 8B4B28CE2F6704280045FA19 /* Frameworks */,
166 8B4B28CF2F6704280045FA19 /* Resources */, 186 8B4B28CF2F6704280045FA19 /* Resources */,
167 8BE081FA2F80000100000001 /* Embed App Extensions */, 187 8BE081FA2F80000100000001 /* Embed Foundation Extensions */,
168 ); 188 );
169 buildRules = ( 189 buildRules = (
170 ); 190 );
@@ -237,7 +257,7 @@
237 attributes = { 257 attributes = {
238 BuildIndependentTargetsInParallel = 1; 258 BuildIndependentTargetsInParallel = 1;
239 LastSwiftUpdateCheck = 2630; 259 LastSwiftUpdateCheck = 2630;
240 LastUpgradeCheck = 2630; 260 LastUpgradeCheck = 2640;
241 TargetAttributes = { 261 TargetAttributes = {
242 8B4B28D02F6704280045FA19 = { 262 8B4B28D02F6704280045FA19 = {
243 CreatedOnToolsVersion = 26.3; 263 CreatedOnToolsVersion = 26.3;
@@ -280,6 +300,10 @@
280 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */, 300 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */,
281 8B2F89672F69DEB900FC0253 /* README.md in Resources */, 301 8B2F89672F69DEB900FC0253 /* README.md in Resources */,
282 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */, 302 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */,
303 8BE09E7F2F7B2CC300F88693 /* storebutton.svg in Resources */,
304 8BE09E802F7B2CC300F88693 /* index.html in Resources */,
305 8BE09E812F7B2CC300F88693 /* styles.css in Resources */,
306 8BE09E822F7B2CC300F88693 /* privacy.html in Resources */,
283 ); 307 );
284 runOnlyForDeploymentPostprocessing = 0; 308 runOnlyForDeploymentPostprocessing = 0;
285 }; 309 };
@@ -396,6 +420,7 @@
396 MTL_FAST_MATH = YES; 420 MTL_FAST_MATH = YES;
397 ONLY_ACTIVE_ARCH = YES; 421 ONLY_ACTIVE_ARCH = YES;
398 SDKROOT = iphoneos; 422 SDKROOT = iphoneos;
423 STRING_CATALOG_GENERATE_SYMBOLS = YES;
399 SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 424 SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
400 SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 425 SWIFT_OPTIMIZATION_LEVEL = "-Onone";
401 }; 426 };
@@ -453,6 +478,7 @@
453 MTL_ENABLE_DEBUG_INFO = NO; 478 MTL_ENABLE_DEBUG_INFO = NO;
454 MTL_FAST_MATH = YES; 479 MTL_FAST_MATH = YES;
455 SDKROOT = iphoneos; 480 SDKROOT = iphoneos;
481 STRING_CATALOG_GENERATE_SYMBOLS = YES;
456 SWIFT_COMPILATION_MODE = wholemodule; 482 SWIFT_COMPILATION_MODE = wholemodule;
457 VALIDATE_PRODUCT = YES; 483 VALIDATE_PRODUCT = YES;
458 }; 484 };
@@ -465,7 +491,7 @@
465 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 491 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
466 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements; 492 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
467 CODE_SIGN_STYLE = Automatic; 493 CODE_SIGN_STYLE = Automatic;
468 CURRENT_PROJECT_VERSION = 13; 494 CURRENT_PROJECT_VERSION = 14;
469 DEVELOPMENT_TEAM = ZCNAX3VL9D; 495 DEVELOPMENT_TEAM = ZCNAX3VL9D;
470 ENABLE_PREVIEWS = YES; 496 ENABLE_PREVIEWS = YES;
471 GENERATE_INFOPLIST_FILE = YES; 497 GENERATE_INFOPLIST_FILE = YES;
@@ -482,7 +508,7 @@
482 "$(inherited)", 508 "$(inherited)",
483 "@executable_path/Frameworks", 509 "@executable_path/Frameworks",
484 ); 510 );
485 MARKETING_VERSION = 2.5.1; 511 MARKETING_VERSION = 2.5.2;
486 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; 512 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
487 PRODUCT_NAME = "$(TARGET_NAME)"; 513 PRODUCT_NAME = "$(TARGET_NAME)";
488 STRING_CATALOG_GENERATE_SYMBOLS = YES; 514 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -502,7 +528,7 @@
502 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 528 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
503 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements; 529 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
504 CODE_SIGN_STYLE = Automatic; 530 CODE_SIGN_STYLE = Automatic;
505 CURRENT_PROJECT_VERSION = 13; 531 CURRENT_PROJECT_VERSION = 14;
506 DEVELOPMENT_TEAM = ZCNAX3VL9D; 532 DEVELOPMENT_TEAM = ZCNAX3VL9D;
507 ENABLE_PREVIEWS = YES; 533 ENABLE_PREVIEWS = YES;
508 GENERATE_INFOPLIST_FILE = YES; 534 GENERATE_INFOPLIST_FILE = YES;
@@ -519,7 +545,7 @@
519 "$(inherited)", 545 "$(inherited)",
520 "@executable_path/Frameworks", 546 "@executable_path/Frameworks",
521 ); 547 );
522 MARKETING_VERSION = 2.5.1; 548 MARKETING_VERSION = 2.5.2;
523 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; 549 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
524 PRODUCT_NAME = "$(TARGET_NAME)"; 550 PRODUCT_NAME = "$(TARGET_NAME)";
525 STRING_CATALOG_GENERATE_SYMBOLS = YES; 551 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -582,7 +608,7 @@
582 APPLICATION_EXTENSION_API_ONLY = YES; 608 APPLICATION_EXTENSION_API_ONLY = YES;
583 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; 609 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
584 CODE_SIGN_STYLE = Automatic; 610 CODE_SIGN_STYLE = Automatic;
585 CURRENT_PROJECT_VERSION = 13; 611 CURRENT_PROJECT_VERSION = 14;
586 DEVELOPMENT_TEAM = ZCNAX3VL9D; 612 DEVELOPMENT_TEAM = ZCNAX3VL9D;
587 GENERATE_INFOPLIST_FILE = NO; 613 GENERATE_INFOPLIST_FILE = NO;
588 INFOPLIST_FILE = HutchWidgetExtension/Info.plist; 614 INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -592,7 +618,7 @@
592 "@executable_path/Frameworks", 618 "@executable_path/Frameworks",
593 "@executable_path/../../Frameworks", 619 "@executable_path/../../Frameworks",
594 ); 620 );
595 MARKETING_VERSION = 2.5.1; 621 MARKETING_VERSION = 2.5.2;
596 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; 622 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
597 PRODUCT_NAME = "$(TARGET_NAME)"; 623 PRODUCT_NAME = "$(TARGET_NAME)";
598 SKIP_INSTALL = YES; 624 SKIP_INSTALL = YES;
@@ -611,7 +637,7 @@
611 APPLICATION_EXTENSION_API_ONLY = YES; 637 APPLICATION_EXTENSION_API_ONLY = YES;
612 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; 638 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
613 CODE_SIGN_STYLE = Automatic; 639 CODE_SIGN_STYLE = Automatic;
614 CURRENT_PROJECT_VERSION = 13; 640 CURRENT_PROJECT_VERSION = 14;
615 DEVELOPMENT_TEAM = ZCNAX3VL9D; 641 DEVELOPMENT_TEAM = ZCNAX3VL9D;
616 GENERATE_INFOPLIST_FILE = NO; 642 GENERATE_INFOPLIST_FILE = NO;
617 INFOPLIST_FILE = HutchWidgetExtension/Info.plist; 643 INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -621,7 +647,7 @@
621 "@executable_path/Frameworks", 647 "@executable_path/Frameworks",
622 "@executable_path/../../Frameworks", 648 "@executable_path/../../Frameworks",
623 ); 649 );
624 MARKETING_VERSION = 2.5.1; 650 MARKETING_VERSION = 2.5.2;
625 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; 651 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
626 PRODUCT_NAME = "$(TARGET_NAME)"; 652 PRODUCT_NAME = "$(TARGET_NAME)";
627 SKIP_INSTALL = YES; 653 SKIP_INSTALL = YES;
Hutch.xcodeproj/xcshareddata/xcschemes/Hutch.xcscheme +1 −1
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<Scheme 2<Scheme
3 LastUpgradeVersion = "2630" 3 LastUpgradeVersion = "2640"
4 version = "1.7"> 4 version = "1.7">
5 <BuildAction 5 <BuildAction
6 parallelizeBuildables = "YES" 6 parallelizeBuildables = "YES"
Hutch.xcodeproj/xcshareddata/xcschemes/HutchTests.xcscheme +1 −1
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<Scheme 2<Scheme
3 LastUpgradeVersion = "2630" 3 LastUpgradeVersion = "2640"
4 version = "1.7"> 4 version = "1.7">
5 <BuildAction 5 <BuildAction
6 parallelizeBuildables = "YES" 6 parallelizeBuildables = "YES"
Hutch/Views/Repositories/ReadmeView.swift +7 −2
@@ -1001,7 +1001,7 @@ nonisolated private func renderHTMLTable(
1001 if hasHeaderSeparator { 1001 if hasHeaderSeparator {
1002 html += "<thead><tr>" 1002 html += "<thead><tr>"
1003 for (index, cell) in headerRow.enumerated() { 1003 for (index, cell) in headerRow.enumerated() {
1004 html += "<th" + tableAlignmentStyleAttribute(columnAlignments[safe: index] ?? nil) + ">" + inlineRenderer(cell) + "</th>" 1004 html += "<th" + tableAlignmentStyleAttribute(columnAlignment(at: index, in: columnAlignments)) + ">" + inlineRenderer(cell) + "</th>"
1005 } 1005 }
1006 html += "</tr></thead>\n" 1006 html += "</tr></thead>\n"
1007 } 1007 }
@@ -1010,7 +1010,7 @@ nonisolated private func renderHTMLTable(
1010 for row in bodyRows { 1010 for row in bodyRows {
1011 html += "<tr>" 1011 html += "<tr>"
1012 for (index, cell) in row.enumerated() { 1012 for (index, cell) in row.enumerated() {
1013 html += "<td" + tableAlignmentStyleAttribute(columnAlignments[safe: index] ?? nil) + ">" + inlineRenderer(cell) + "</td>" 1013 html += "<td" + tableAlignmentStyleAttribute(columnAlignment(at: index, in: columnAlignments)) + ">" + inlineRenderer(cell) + "</td>"
1014 } 1014 }
1015 html += "</tr>\n" 1015 html += "</tr>\n"
1016 } 1016 }
@@ -1019,6 +1019,11 @@ nonisolated private func renderHTMLTable(
1019 return html 1019 return html
1020} 1020}
1021 1021
1022nonisolated private func columnAlignment(at index: Int, in alignments: [String?]) -> String? {
1023 guard alignments.indices.contains(index) else { return nil }
1024 return alignments[index]
1025}
1026
1022nonisolated private func tableAlignmentStyleAttribute(_ alignment: String?) -> String { 1027nonisolated private func tableAlignmentStyleAttribute(_ alignment: String?) -> String {
1023 guard let alignment, !alignment.isEmpty else { return "" } 1028 guard let alignment, !alignment.isEmpty else { return "" }
1024 return #" style="text-align: \#(alignment);""# 1029 return #" style="text-align: \#(alignment);""#