Bump to 1.6.2 (16) !134
3 files changed, +10 −75
Layout: unified · split
gitbay.xcodeproj/project.pbxproj +4 −4
| @@ -415,7 +415,7 @@ | |||
| 415 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; | 415 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; |
| 416 | CODE_SIGN_ENTITLEMENTS = gitbay/gitbay.entitlements; | 416 | CODE_SIGN_ENTITLEMENTS = gitbay/gitbay.entitlements; |
| 417 | CODE_SIGN_STYLE = Automatic; | 417 | CODE_SIGN_STYLE = Automatic; |
| 418 | CURRENT_PROJECT_VERSION = 15; | 418 | CURRENT_PROJECT_VERSION = 16; |
| 419 | DEVELOPMENT_TEAM = ZCNAX3VL9D; | 419 | DEVELOPMENT_TEAM = ZCNAX3VL9D; |
| 420 | ENABLE_PREVIEWS = YES; | 420 | ENABLE_PREVIEWS = YES; |
| 421 | GENERATE_INFOPLIST_FILE = YES; | 421 | GENERATE_INFOPLIST_FILE = YES; |
| @@ -431,7 +431,7 @@ | |||
| 431 | "$(inherited)", | 431 | "$(inherited)", |
| 432 | "@executable_path/Frameworks", | 432 | "@executable_path/Frameworks", |
| 433 | ); | 433 | ); |
| 434 | MARKETING_VERSION = 1.6.1; | 434 | MARKETING_VERSION = 1.6.2; |
| 435 | PRODUCT_BUNDLE_IDENTIFIER = org.gitbay.gitbay; | 435 | PRODUCT_BUNDLE_IDENTIFIER = org.gitbay.gitbay; |
| 436 | PRODUCT_NAME = "$(TARGET_NAME)"; | 436 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 437 | STRING_CATALOG_GENERATE_SYMBOLS = YES; | 437 | STRING_CATALOG_GENERATE_SYMBOLS = YES; |
| @@ -451,7 +451,7 @@ | |||
| 451 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; | 451 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; |
| 452 | CODE_SIGN_ENTITLEMENTS = gitbay/gitbay.entitlements; | 452 | CODE_SIGN_ENTITLEMENTS = gitbay/gitbay.entitlements; |
| 453 | CODE_SIGN_STYLE = Automatic; | 453 | CODE_SIGN_STYLE = Automatic; |
| 454 | CURRENT_PROJECT_VERSION = 15; | 454 | CURRENT_PROJECT_VERSION = 16; |
| 455 | DEVELOPMENT_TEAM = ZCNAX3VL9D; | 455 | DEVELOPMENT_TEAM = ZCNAX3VL9D; |
| 456 | ENABLE_PREVIEWS = YES; | 456 | ENABLE_PREVIEWS = YES; |
| 457 | GENERATE_INFOPLIST_FILE = YES; | 457 | GENERATE_INFOPLIST_FILE = YES; |
| @@ -467,7 +467,7 @@ | |||
| 467 | "$(inherited)", | 467 | "$(inherited)", |
| 468 | "@executable_path/Frameworks", | 468 | "@executable_path/Frameworks", |
| 469 | ); | 469 | ); |
| 470 | MARKETING_VERSION = 1.6.1; | 470 | MARKETING_VERSION = 1.6.2; |
| 471 | PRODUCT_BUNDLE_IDENTIFIER = org.gitbay.gitbay; | 471 | PRODUCT_BUNDLE_IDENTIFIER = org.gitbay.gitbay; |
| 472 | PRODUCT_NAME = "$(TARGET_NAME)"; | 472 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 473 | STRING_CATALOG_GENERATE_SYMBOLS = YES; | 473 | STRING_CATALOG_GENERATE_SYMBOLS = YES; |
gitbay/Views/Repos/MarkdownView.swift +6 −31
| @@ -86,14 +86,9 @@ struct MarkdownView: View { | |||
| 86 | } | 86 | } |
| 87 | if trimmed.hasPrefix("- ") || trimmed.hasPrefix("* ") || trimmed.hasPrefix("+ ") { | 87 | if trimmed.hasPrefix("- ") || trimmed.hasPrefix("* ") || trimmed.hasPrefix("+ ") { |
| 88 | var items: [String] = [] | 88 | var items: [String] = [] |
| 89 | while let next = lines.first?.trimmingCharacters(in: .whitespaces) { | 89 | while let next = lines.first?.trimmingCharacters(in: .whitespaces), |
| 90 | if next.hasPrefix("- ") || next.hasPrefix("* ") || next.hasPrefix("+ ") { | 90 | next.hasPrefix("- ") || next.hasPrefix("* ") || next.hasPrefix("+ ") { |
| 91 | items.append(String(next.dropFirst(2))) | 91 | items.append(String(next.dropFirst(2))) |
| 92 | } else if Self.continuesItem(lines) { | ||
| 93 | items[items.count - 1] += " " + next | ||
| 94 | } else { | ||
| 95 | break | ||
| 96 | } | ||
| 97 | lines = lines.dropFirst() | 92 | lines = lines.dropFirst() |
| 98 | } | 93 | } |
| 99 | blocks.append(.bullet(items)) | 94 | blocks.append(.bullet(items)) |
| @@ -101,14 +96,9 @@ struct MarkdownView: View { | |||
| 101 | } | 96 | } |
| 102 | if trimmed.range(of: #"^\d+\. "#, options: .regularExpression) != nil { | 97 | if trimmed.range(of: #"^\d+\. "#, options: .regularExpression) != nil { |
| 103 | var items: [String] = [] | 98 | var items: [String] = [] |
| 104 | while let next = lines.first?.trimmingCharacters(in: .whitespaces) { | 99 | while let next = lines.first?.trimmingCharacters(in: .whitespaces), |
| 105 | if let range = next.range(of: #"^\d+\. "#, options: .regularExpression) { | 100 | let range = next.range(of: #"^\d+\. "#, options: .regularExpression) { |
| 106 | items.append(String(next[range.upperBound...])) | 101 | items.append(String(next[range.upperBound...])) |
| 107 | } else if Self.continuesItem(lines) { | ||
| 108 | items[items.count - 1] += " " + next | ||
| 109 | } else { | ||
| 110 | break | ||
| 111 | } | ||
| 112 | lines = lines.dropFirst() | 102 | lines = lines.dropFirst() |
| 113 | } | 103 | } |
| 114 | blocks.append(.ordered(items)) | 104 | blocks.append(.ordered(items)) |
| @@ -150,19 +140,6 @@ struct MarkdownView: View { | |||
| 150 | return blocks | 140 | return blocks |
| 151 | } | 141 | } |
| 152 | 142 | ||
| 153 | /// A line that wraps the list item above it: anything but a blank line or | ||
| 154 | /// the start of another block, indented or not, as in CommonMark. | ||
| 155 | private static func continuesItem(_ lines: ArraySlice<String>) -> Bool { | ||
| 156 | guard let line = lines.first?.trimmingCharacters(in: .whitespaces), !line.isEmpty | ||
| 157 | else { return false } | ||
| 158 | let startsBlock = line.hasPrefix("#") || line.hasPrefix("```") || line.hasPrefix(">") | ||
| 159 | || line.hasPrefix("- ") || line.hasPrefix("* ") || line.hasPrefix("+ ") | ||
| 160 | || line == "---" || line == "***" || line == "___" | ||
| 161 | || line.range(of: #"^\d+\. "#, options: .regularExpression) != nil | ||
| 162 | || tableStart(lines) != nil | ||
| 163 | return !startsBlock | ||
| 164 | } | ||
| 165 | |||
| 166 | // MARK: - Tables | 143 | // MARK: - Tables |
| 167 | 144 | ||
| 168 | /// A table begins where a row of cells is followed by a separator row with the | 145 | /// A table begins where a row of cells is followed by a separator row with the |
| @@ -247,7 +224,6 @@ struct MarkdownView: View { | |||
| 247 | HStack(alignment: .firstTextBaseline, spacing: 8) { | 224 | HStack(alignment: .firstTextBaseline, spacing: 8) { |
| 248 | Text("•") | 225 | Text("•") |
| 249 | Self.inline(item, linkOptions: linkOptions) | 226 | Self.inline(item, linkOptions: linkOptions) |
| 250 | .fixedSize(horizontal: false, vertical: true) | ||
| 251 | } | 227 | } |
| 252 | } | 228 | } |
| 253 | } | 229 | } |
| @@ -257,7 +233,6 @@ struct MarkdownView: View { | |||
| 257 | HStack(alignment: .firstTextBaseline, spacing: 8) { | 233 | HStack(alignment: .firstTextBaseline, spacing: 8) { |
| 258 | Text("\(index + 1).").monospacedDigit() | 234 | Text("\(index + 1).").monospacedDigit() |
| 259 | Self.inline(item, linkOptions: linkOptions) | 235 | Self.inline(item, linkOptions: linkOptions) |
| 260 | .fixedSize(horizontal: false, vertical: true) | ||
| 261 | } | 236 | } |
| 262 | } | 237 | } |
| 263 | } | 238 | } |
gitbayTests/MarkdownTests.swift −40
| @@ -135,43 +135,3 @@ struct MarkdownLinkTests { | |||
| 135 | == ["ARCHITECTURE.md"]) | 135 | == ["ARCHITECTURE.md"]) |
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| 138 | |||
| 139 | @MainActor | ||
| 140 | struct MarkdownListTests { | ||
| 141 | |||
| 142 | private func blocks(_ markdown: String) -> [MarkdownView.Block] { | ||
| 143 | MarkdownView(markdown: markdown).blocks | ||
| 144 | } | ||
| 145 | |||
| 146 | @Test func indentedContinuationLinesStayInTheItem() { | ||
| 147 | let parsed = blocks(""" | ||
| 148 | - Org source files in `content/`. | ||
| 149 | That directory is the URL root. | ||
| 150 | - HTML templates. | ||
| 151 | """) | ||
| 152 | #expect(parsed == [.bullet([ | ||
| 153 | "Org source files in `content/`. That directory is the URL root.", | ||
| 154 | "HTML templates.", | ||
| 155 | ])]) | ||
| 156 | } | ||
| 157 | |||
| 158 | @Test func unindentedContinuationLinesStayInTheItem() { | ||
| 159 | let parsed = blocks("- one\ncontinued\n- two") | ||
| 160 | #expect(parsed == [.bullet(["one continued", "two"])]) | ||
| 161 | } | ||
| 162 | |||
| 163 | @Test func orderedItemsTakeContinuationLines() { | ||
| 164 | let parsed = blocks("1. first\n more\n2. second") | ||
| 165 | #expect(parsed == [.ordered(["first more", "second"])]) | ||
| 166 | } | ||
| 167 | |||
| 168 | @Test func aListEndsAtABlankLine() { | ||
| 169 | let parsed = blocks("- one\n\nAfter the list.") | ||
| 170 | #expect(parsed == [.bullet(["one"]), .paragraph("After the list.")]) | ||
| 171 | } | ||
| 172 | |||
| 173 | @Test func aHeadingEndsAList() { | ||
| 174 | let parsed = blocks("- one\n## Next") | ||
| 175 | #expect(parsed == [.bullet(["one"]), .heading(level: 2, text: "Next")]) | ||
| 176 | } | ||
| 177 | } | ||