chore: checkpoint current milestone work

This commit is contained in:
shen
2026-05-22 13:28:53 +08:00
parent 6d196d64e5
commit 5698aeaead
68 changed files with 5694 additions and 3291 deletions
@@ -167,6 +167,43 @@ public struct RDEPUBTextOffsetRangeInfo: Codable, Equatable {
}
}
public enum RDEPUBTextPageBreakReason: String, Codable, Equatable {
case chapterEnd
case frameLimit
case blockBoundary
case attachmentBoundary
}
public enum RDEPUBTextAttachmentKind: String, Codable, Equatable {
case image
case generic
}
public struct RDEPUBTextPageMetadata: Codable, Equatable {
public var breakReason: RDEPUBTextPageBreakReason
public var blockRange: NSRange?
public var attachmentRanges: [NSRange]
public var attachmentKinds: [RDEPUBTextAttachmentKind]
public var trailingFragmentID: String?
public var diagnostics: [String]
public init(
breakReason: RDEPUBTextPageBreakReason,
blockRange: NSRange? = nil,
attachmentRanges: [NSRange] = [],
attachmentKinds: [RDEPUBTextAttachmentKind] = [],
trailingFragmentID: String? = nil,
diagnostics: [String] = []
) {
self.breakReason = breakReason
self.blockRange = blockRange
self.attachmentRanges = attachmentRanges
self.attachmentKinds = attachmentKinds
self.trailingFragmentID = trailingFragmentID
self.diagnostics = diagnostics
}
}
public struct RDEPUBHighlight: Codable, Equatable {
public var id: String
public var bookIdentifier: String?
@@ -57,6 +57,35 @@ public final class RDEPUBResourceResolver {
return pathPart
}
public func normalizedHref(_ href: String, relativeToHref baseHref: String) -> String? {
guard let opfDirectoryURL else {
return href.components(separatedBy: "#").first
}
let pathPart = href.components(separatedBy: "#").first ?? href
let basePath = baseHref.components(separatedBy: "#").first ?? baseHref
let baseURL = opfDirectoryURL
.appendingPathComponent(basePath)
.deletingLastPathComponent()
guard let resolvedURL = URL(string: pathPart, relativeTo: baseURL)?.standardizedFileURL else {
return pathPart
}
let opfPath = opfDirectoryURL.standardizedFileURL.path + "/"
if resolvedURL.path.hasPrefix(opfPath) {
return String(resolvedURL.path.dropFirst(opfPath.count))
}
return pathPart
}
public func fileURL(forReference href: String, relativeToHref baseHref: String) -> URL? {
guard let normalizedHref = normalizedHref(href, relativeToHref: baseHref) else {
return nil
}
return fileURL(forRelativePath: normalizedHref)
}
public func normalizedLocation(
_ location: RDEPUBLocation,
relativeToSpineIndex spineIndex: Int? = nil,
@@ -122,4 +151,4 @@ public final class RDEPUBResourceResolver {
normalizedHref($0.href) == targetHref
}
}
}
}