Commit 2e4960dc31
2e4960dc311b6c2d47c81c6265580111a4f32ded
parent: 64abbc5db5
Verified · cmc
cmc <hello@cleberg.net> · 2026-10-16 02:15 UTC
Org math at the size of the text it sits in
krz/org-swift 0.9.0 tells OrgView's math hook the text style of each
expression's run, so math in a heading, table cell or footnote is set
at that style's size for the current Dynamic Type size rather than at
body size.
Closes #41
Layout: unified · split
gitbay.xcodeproj/project.pbxproj
+1 −1
| @@ -603,7 +603,7 @@ |
| 603 | 603 | repositoryURL = "ssh://git@gitbay.org/krz/org-swift.git"; |
| 604 | 604 | requirement = { |
| 605 | 605 | kind = upToNextMinorVersion; |
| 606 | | minimumVersion = 0.8.0; |
| 606 | minimumVersion = 0.9.0; |
| 607 | 607 | }; |
| 608 | 608 | }; |
| 609 | 609 | 8B2898B0303FF3E5001BF44A /* XCRemoteSwiftPackageReference "Highlightr" */ = { |
gitbay.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+2 −2
| @@ -15,8 +15,8 @@ |
| 15 | 15 | "kind" : "remoteSourceControl", |
| 16 | 16 | "location" : "ssh://git@gitbay.org/krz/org-swift.git", |
| 17 | 17 | "state" : { |
| 18 | | "revision" : "49b729cc966ddb8270e0184b0e4dd02a4e1956e8", |
| 19 | | "version" : "0.8.0" |
| 18 | "revision" : "799d4ba18ece2bd259bd4760cca46faeae0fd1e1", |
| 19 | "version" : "0.9.0" |
| 20 | 20 | } |
| 21 | 21 | }, |
| 22 | 22 | { |
gitbay/Views/Repos/FormattedBodyView.swift
+1 −1
| @@ -27,7 +27,7 @@ struct FormattedBodyView: View { |
| 27 | 27 | styler: OrgSyntaxStyler(colorScheme: colorScheme), |
| 28 | 28 | keywords: OrgKeywordStyle(todo: .gbOK, done: .gbDone), |
| 29 | 29 | textTransform: repo.map { repo in { linkReferences(in: &$0, repo: repo) } }, |
| 30 | | math: MathRenderer.org(pointSize: UIFont.pointSize(.body, dynamicTypeSize), allowance: allowance) |
| 30 | math: MathRenderer.org(dynamicTypeSize: dynamicTypeSize, allowance: allowance) |
| 31 | 31 | ) |
| 32 | 32 | } else { |
| 33 | 33 | MarkdownView(markdown: text, referenceRepo: repo) |
gitbay/Views/Repos/ReadmeView.swift
+1 −1
| @@ -31,7 +31,7 @@ struct ReadmeView: View { |
| 31 | 31 | // org's TODO/DONE are the same open/done distinction the forge already |
| 32 | 32 | // colors, so they reuse those tokens rather than a third treatment. |
| 33 | 33 | keywords: OrgKeywordStyle(todo: .gbOK, done: .gbDone), |
| 34 | | math: MathRenderer.org(pointSize: UIFont.pointSize(.body, dynamicTypeSize), allowance: allowance) |
| 34 | math: MathRenderer.org(dynamicTypeSize: dynamicTypeSize, allowance: allowance) |
| 35 | 35 | ) |
| 36 | 36 | } else { |
| 37 | 37 | MarkdownView(markdown: content, linkOptions: renderOptions) |
gitbay/Views/Shared/MathRendering.swift
+28 −4
| @@ -171,10 +171,12 @@ enum MathRenderer { |
| 171 | 171 | .baselineOffset(-rendered.descent) |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | | /// `OrgView`'s math hook: each expression the allowance admits, drawn at `pointSize`. |
| 175 | | static func org(pointSize: CGFloat, allowance: MathAllowance) -> OrgMathRenderer { |
| 176 | | { math in |
| 177 | | allowance.admits(math) ? drawn(math.tex, display: math.display, pointSize: pointSize) : nil |
| 174 | /// `OrgView`'s math hook: each expression the allowance admits, drawn at the size of |
| 175 | /// the text it sits in. |
| 176 | static func org(dynamicTypeSize: DynamicTypeSize, allowance: MathAllowance) -> OrgMathRenderer { |
| 177 | { math, style in |
| 178 | guard allowance.admits(math) else { return nil } |
| 179 | return drawn(math.tex, display: math.display, pointSize: UIFont.pointSize(style, dynamicTypeSize)) |
| 178 | 180 | } |
| 179 | 181 | } |
| 180 | 182 | } |
| @@ -242,4 +244,26 @@ extension UIFont { |
| 242 | 244 | compatibleWith: UITraitCollection(preferredContentSizeCategory: UIContentSizeCategory(size))) |
| 243 | 245 | .pointSize |
| 244 | 246 | } |
| 247 | |
| 248 | static func pointSize(_ style: Font.TextStyle, _ size: DynamicTypeSize) -> CGFloat { |
| 249 | pointSize(UIFont.TextStyle(style), size) |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | extension UIFont.TextStyle { |
| 254 | init(_ style: Font.TextStyle) { |
| 255 | switch style { |
| 256 | case .largeTitle: self = .largeTitle |
| 257 | case .title: self = .title1 |
| 258 | case .title2: self = .title2 |
| 259 | case .title3: self = .title3 |
| 260 | case .headline: self = .headline |
| 261 | case .subheadline: self = .subheadline |
| 262 | case .callout: self = .callout |
| 263 | case .footnote: self = .footnote |
| 264 | case .caption: self = .caption1 |
| 265 | case .caption2: self = .caption2 |
| 266 | default: self = .body |
| 267 | } |
| 268 | } |
| 245 | 269 | } |
gitbayTests/MathTests.swift
+10 −3
| @@ -1,4 +1,5 @@ |
| 1 | 1 | import Foundation |
| 2 | import SwiftUI |
| 2 | 3 | import Testing |
| 3 | 4 | @testable import gitbay |
| 4 | 5 | import OrgSwift |
| @@ -197,9 +198,15 @@ struct OrgMathHookTests { |
| 197 | 198 | } |
| 198 | 199 | |
| 199 | 200 | @Test func drawsWhatRendersAndKeepsTheSourceOtherwise() { |
| 200 | | let draw = MathRenderer.org(pointSize: 17, allowance: MathAllowance()) |
| 201 | | #expect(draw(org("x^2")) != nil) |
| 202 | | #expect(draw(org(#"\notacommand"#)) == nil) |
| 201 | let draw = MathRenderer.org(dynamicTypeSize: .large, allowance: MathAllowance()) |
| 202 | #expect(draw(org("x^2"), .body) != nil) |
| 203 | #expect(draw(org(#"\notacommand"#), .body) == nil) |
| 204 | } |
| 205 | |
| 206 | @Test func mathIsSizedToTheTextItSitsIn() { |
| 207 | #expect(UIFont.pointSize(Font.TextStyle.title, .large) > UIFont.pointSize(Font.TextStyle.body, .large)) |
| 208 | #expect(UIFont.pointSize(Font.TextStyle.body, .large) == UIFont.pointSize(UIFont.TextStyle.body, .large)) |
| 209 | #expect(UIFont.pointSize(Font.TextStyle.body, .xxxLarge) > UIFont.pointSize(Font.TextStyle.body, .large)) |
| 203 | 210 | } |
| 204 | 211 | |
| 205 | 212 | @Test func theAllowanceIsTheWebsDocumentBudget() { |