- Rename source module from RDReaderView to RDEpubReaderView - Move all source files from Sources/RDReaderView/ to Sources/RDEpubReaderView/ - Update podspec: RDReaderView.podspec -> RDEpubReaderView.podspec - Update Podfile, demo project, and CocoaPods config for new pod name - Delete old RDReaderView pod support files from ReadViewDemo/Pods - Add new RDEpubReaderView pod support files - Update documentation (API ref, architecture, UML, conventions, etc.) - Add FixedLayoutRotationTests - Update .gitignore: exclude .DS_Store, manual unpack backups, _ssoft-output
102 lines
3.8 KiB
Swift
102 lines
3.8 KiB
Swift
|
|
import Foundation
|
|
import UIKit
|
|
|
|
extension RDEPUBParser {
|
|
|
|
public func manifestItem(for id: String) -> RDEPUBManifestItem? {
|
|
manifest[id]
|
|
}
|
|
|
|
public func manifestItem(forHref href: String) -> RDEPUBManifestItem? {
|
|
let target = href.components(separatedBy: "#").first ?? href
|
|
return manifest.values.first { item in
|
|
normalize(href: item.href, relativeTo: opfDirectoryURL ?? URL(fileURLWithPath: "/")) == target
|
|
}
|
|
}
|
|
|
|
public func href(forSpineIndex index: Int) -> String? {
|
|
guard spine.indices.contains(index) else { return nil }
|
|
return spine[index].href
|
|
}
|
|
|
|
public func fileURL(forRelativePath relativePath: String) -> URL? {
|
|
guard let opfDirectoryURL else { return nil }
|
|
let path = relativePath.components(separatedBy: "#").first ?? relativePath
|
|
guard !path.isEmpty else { return nil }
|
|
let resolvedURL = URL(fileURLWithPath: path, relativeTo: opfDirectoryURL).standardizedFileURL
|
|
guard let rootURL = extractionRootURL?.standardizedFileURL else {
|
|
return resolvedURL
|
|
}
|
|
guard resolvedURL.path.hasPrefix(rootURL.path) else {
|
|
return nil
|
|
}
|
|
return resolvedURL
|
|
}
|
|
|
|
public func resourceURL(forRelativePath relativePath: String) -> URL? {
|
|
let normalizedPath = relativePath.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
|
|
guard !normalizedPath.isEmpty else { return nil }
|
|
guard let encodedPath = normalizedPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else {
|
|
return nil
|
|
}
|
|
var components = URLComponents()
|
|
components.scheme = RDEPUBResourceURLSchemeHandler.scheme
|
|
components.host = RDEPUBResourceURLSchemeHandler.host
|
|
components.percentEncodedPath = "/" + encodedPath
|
|
return components.url
|
|
}
|
|
|
|
public func fileURL(forResourceURL resourceURL: URL) -> URL? {
|
|
guard resourceURL.scheme == RDEPUBResourceURLSchemeHandler.scheme,
|
|
resourceURL.host == RDEPUBResourceURLSchemeHandler.host else {
|
|
return nil
|
|
}
|
|
let relativePath = resourceURL.path.removingPercentEncoding?.trimmingCharacters(in: CharacterSet(charactersIn: "/")) ?? ""
|
|
return fileURL(forRelativePath: relativePath)
|
|
}
|
|
|
|
public func coverImage() -> UIImage? {
|
|
let coverCandidates = manifest.values.filter { item in
|
|
item.properties.contains("cover-image") || item.id.lowercased().contains("cover")
|
|
}
|
|
for item in coverCandidates {
|
|
if let fileURL = fileURL(forRelativePath: item.href),
|
|
let data = resourceData(at: fileURL),
|
|
let image = UIImage(data: data) {
|
|
return image
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
public func htmlString(forSpineIndex index: Int) -> String? {
|
|
guard spine.indices.contains(index) else {
|
|
return nil
|
|
}
|
|
return htmlString(forRelativePath: spine[index].href)
|
|
}
|
|
|
|
public func htmlString(forRelativePath relativePath: String) -> String? {
|
|
guard let fileURL = fileURL(forRelativePath: relativePath) else {
|
|
return nil
|
|
}
|
|
if let provided = providedResourceData(at: fileURL) {
|
|
return String(data: provided, encoding: .utf8)
|
|
?? String(data: provided, encoding: .utf16)
|
|
}
|
|
return try? String(contentsOf: fileURL)
|
|
}
|
|
|
|
func normalize(href: String, relativeTo directoryURL: URL) -> String {
|
|
guard let resolvedURL = URL(string: href, relativeTo: directoryURL)?.standardizedFileURL else {
|
|
return href
|
|
}
|
|
let prefix = directoryURL.standardizedFileURL.path + "/"
|
|
if resolvedURL.path.hasPrefix(prefix) {
|
|
return String(resolvedURL.path.dropFirst(prefix.count))
|
|
}
|
|
return href
|
|
}
|
|
}
|