Sources/OrgSwift/AST/OrgURLResolver.swift
40 lines · 1467 bytes
1import Foundation
2
3/// Resolves a link target or image source to a safe absolute URL string, or nil when it
4/// cannot be made safe.
5///
6/// Because the tree keeps targets typed, resolution is a renderer concern applied to the
7/// `.file` case only — no resolver closure has to be threaded through the parse. Both
8/// renderers resolve identically, so a link that degrades to text in HTML degrades to text
9/// natively too.
10package struct OrgURLResolver: Sendable {
11 package var options: OrgRenderOptions
12
13 package init(options: OrgRenderOptions) {
14 self.options = options
15 }
16
17 package func href(for target: OrgLinkTarget) -> String? {
18 switch target {
19 case .id(let identifier):
20 return sanitizedReadmeLinkURLString("#\(identifier)")
21 case .external(let url):
22 return sanitizedReadmeLinkURLString(url)
23 case .file(let path):
24 return sanitizedReadmeLinkURLString(options.linkURLResolver()?(path) ?? path)
25 }
26 }
27
28 package func imageSource(_ source: String) -> String? {
29 sanitizedReadmeImageURLString(options.imageURLResolver()?(source) ?? source)
30 }
31
32 /// The text a target shows when it carries no description.
33 package func displayValue(_ target: OrgLinkTarget) -> String {
34 switch target {
35 case .external(let url): return url
36 case .file(let path): return path
37 case .id(let identifier): return identifier
38 }
39 }
40}