refactor: 添加中文注释 + 优化模块结构
- 给全部 78 个 Swift 源文件添加详细的中文注释(文件级、类级、方法级) - 删除 LegacyRDReaderController/ 死代码目录(16 文件 4592 行) - 根目录翻页容器文件移入 ReaderView/ 目录 - Resources/ 移入 EPUBCore/Resources/(与使用者归属一致) - RDEPUBTextIndexTable.swift 移入 EPUBTextRendering/(消除反向依赖) - RDURLReaderController.swift 移入 EPUBUI/(入口控制器归入 UI 层) - 更新 podspec 资源路径
This commit is contained in:
@@ -4,13 +4,36 @@ import UIKit
|
||||
import DTCoreText
|
||||
#endif
|
||||
|
||||
/// 渲染器支持工具集:负责 HTML 预处理、fragment 标记注入/提取、CSS 组装和字体标准化。
|
||||
///
|
||||
/// 本枚举是渲染链路的预处理层,`RDEPUBTextBookBuilder` 在调用渲染器前通过
|
||||
/// `makeChapterRenderRequest()` 完成 HTML 的全部预处理工作。
|
||||
///
|
||||
/// 核心职责:
|
||||
/// - HTML 规范化:清理冗余字符、规范化附件标记
|
||||
/// - Fragment 标记注入/提取:id 属性 → ${id=xxx} 标记 → 字符偏移量映射
|
||||
/// - 语义标记注入:HTML 标签 → ${rd-sem-start/end} 标记 → NSAttributedString 属性
|
||||
/// - CSS 组装:按优先级合并 default/replace/dark/epub/user 五层样式表
|
||||
/// - 字体标准化:将 EPUB 原始字体映射到用户设置的字体
|
||||
/// - 附件规范化:图片尺寸、脚注图标、封面图片等特殊处理
|
||||
enum RDEPUBTextRendererSupport {
|
||||
/// 外部样式表链接正则
|
||||
private static let stylesheetLinkPattern = #"<link\b[^>]*rel\s*=\s*["'][^"']*stylesheet[^"']*["'][^>]*href\s*=\s*["']([^"']+)["'][^>]*>"#
|
||||
/// 图片源地址正则
|
||||
private static let imageSourcePattern = #"<img\b[^>]*src\s*=\s*["']([^"']+)["'][^>]*>"#
|
||||
/// 语义标记正则(${rd-sem-start:...} / ${rd-sem-end:...})
|
||||
private static let semanticMarkerPattern = #"\$\{rd-sem-(start|end):([^}]+)\}"#
|
||||
/// 脚注附件日志已输出标记(避免重复日志)
|
||||
private static var didLogFootnoteAttachment = false
|
||||
/// 封面附件日志已输出标记(避免重复日志)
|
||||
private static var didLogCoverAttachment = false
|
||||
|
||||
// MARK: - Fragment 标记注入/提取
|
||||
|
||||
/// 将 HTML 中的 id 属性元素注入 fragment 标记。
|
||||
///
|
||||
/// 将 `<tag id="xxx" ...>` 转换为 `${id=xxx}<tag id="xxx" ...>`,
|
||||
/// 使 DTCoreText 渲染后能在富文本中定位到 fragment 偏移量。
|
||||
static func injectFragmentMarkers(into html: String) -> String {
|
||||
guard let regex = try? NSRegularExpression(pattern: #"(<[^>]+\sid="([^"]+)"[^>]*>)"#, options: [.caseInsensitive]) else {
|
||||
return html
|
||||
@@ -23,6 +46,10 @@ enum RDEPUBTextRendererSupport {
|
||||
)
|
||||
}
|
||||
|
||||
/// 从渲染后的富文本中提取 fragment 偏移量映射。
|
||||
///
|
||||
/// 扫描 `${id=xxx}` 标记,记录每个 fragment ID 的字符偏移量,
|
||||
/// 然后删除标记文本,返回 [fragmentID: offset] 字典。
|
||||
static func extractFragmentOffsets(from attributedString: NSMutableAttributedString) -> [String: Int] {
|
||||
let markerPattern = #"\$\{id=([^}]+)\}"#
|
||||
guard let regex = try? NSRegularExpression(pattern: markerPattern, options: []) else {
|
||||
@@ -51,6 +78,10 @@ enum RDEPUBTextRendererSupport {
|
||||
return fragmentOffsets
|
||||
}
|
||||
|
||||
/// 将 HTML 中注入的语义标记(${rd-sem-start/end})应用到富文本属性中。
|
||||
///
|
||||
/// 标记包含 blockKind、semanticHints、attachmentPlacement 等信息,
|
||||
/// 解析后写入对应的 .rdPage* 属性键,供分页引擎读取。
|
||||
static func applyPaginationSemantics(in attributedString: NSMutableAttributedString) {
|
||||
guard let regex = try? NSRegularExpression(pattern: semanticMarkerPattern, options: []) else {
|
||||
return
|
||||
@@ -85,6 +116,14 @@ enum RDEPUBTextRendererSupport {
|
||||
}
|
||||
}
|
||||
|
||||
/// 规范化阅读属性:统一字体、行距、颜色,并注入分页语义属性。
|
||||
///
|
||||
/// 遍历富文本的所有属性区间:
|
||||
/// 1. 将 EPUB 原始字体映射到用户设置字体(保留粗体/斜体特征)
|
||||
/// 2. 统一行距和段间距
|
||||
/// 3. 应用用户设置的文本颜色
|
||||
/// 4. 规范化附件显示尺寸
|
||||
/// 5. 注入块级元素范围、序号、类型等分页语义属性
|
||||
static func normalizeReadingAttributes(in attributedString: NSMutableAttributedString, style: RDEPUBTextRenderStyle) {
|
||||
let fullRange = NSRange(location: 0, length: attributedString.length)
|
||||
var blockIndex = 0
|
||||
@@ -128,6 +167,7 @@ enum RDEPUBTextRendererSupport {
|
||||
}
|
||||
}
|
||||
|
||||
/// 回退渲染:当 DTCoreText 不可用时,将 HTML 源码当作纯文本处理。
|
||||
static func fallbackAttributedString(for html: String, style: RDEPUBTextRenderStyle) -> NSMutableAttributedString {
|
||||
let fallbackAttributes: [NSAttributedString.Key: Any] = [
|
||||
.font: style.font,
|
||||
@@ -137,6 +177,16 @@ enum RDEPUBTextRendererSupport {
|
||||
return NSMutableAttributedString(string: html, attributes: fallbackAttributes)
|
||||
}
|
||||
|
||||
/// 核心预处理方法:将原始 HTML 转换为完整的章节渲染请求。
|
||||
///
|
||||
/// 预处理流程:
|
||||
/// 1. normalizeHTML:清理冗余字符、规范化附件 HTML 标记
|
||||
/// 2. injectPaginationSemanticMarkers:为 HTML 标签注入语义标记
|
||||
/// 3. inlineLinkedStyleSheets:将外部样式表内联到 HTML 中
|
||||
/// 4. 组装五层 CSS(default/replace/dark/epub/user)并注入 style 标签
|
||||
/// 5. injectBaseHref:注入 base 标签以解析相对路径
|
||||
/// 6. injectFragmentMarkers:注入 fragment 锚点标记
|
||||
/// 7. collectImageDiagnostics:收集图片资源引用诊断
|
||||
static func makeChapterRenderRequest(
|
||||
href: String,
|
||||
title: String,
|
||||
@@ -197,6 +247,7 @@ enum RDEPUBTextRendererSupport {
|
||||
return RDEPUBTextChapterRenderRequest(context: context, style: style)
|
||||
}
|
||||
|
||||
/// HTML 规范化:清理冗余字符(CR、多余换行),规范化附件 HTML 标记
|
||||
static func normalizeHTML(_ html: String) -> String {
|
||||
var cleanedHTML = html
|
||||
let replacements: [(pattern: String, template: String)] = [
|
||||
|
||||
Reference in New Issue
Block a user