1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! 这个文件可以理解成“库的总入口”。
//!
//! 别的 Rust 项目接入 `pdfxml` 时,最先接触到的通常就是这里。
//! 因为这里决定了两件事:
//! - 哪些模块对外公开
//! - 外部最常用的类型和函数有哪些
//!
//! 如果你只是想会用这个库,不想一下子钻进所有实现细节,
//! 那直接从这个文件看就够了。
//!
//! 你可以把这里当成“对外使用说明 + API 门面”:
//! - 想读 XFDF:看 [`load_xfdf`]
//! - 想从 PDF 读注释:看 [`load_annotations_from_pdf`]
//! - 想把注释导出成 PDF:看 [`export_annotations`]
//! - 想自己细调导出行为:看 [`PdfAnnotationExporter`]
//!
//! 建议阅读顺序:
//! 1. 先看下面的 `pub mod ...`,知道项目分成哪几块
//! 2. 再看 `pub use ...`,知道外部能直接拿到哪些 API
//! 3. 最后看几个顶层函数,理解最常见调用流程
/// 注释数据结构模块。
///
/// 这里定义了文本注释、高亮、线条、图章等 Rust 类型。
/// 如果你想在代码里直接查看或修改注释内容,通常会用到这里导出的类型。
/// 统一错误类型模块。
///
/// 读取文件、解析 XML、处理 PDF 失败时,
/// 最后都会尽量统一收口到这里定义的错误类型。
/// PDF 读写模块。
///
/// 这里放的是把注释真正写进 PDF、或者从 PDF 里读回注释的核心逻辑。
/// XFDF/XML 解析模块。
///
/// 它负责把 XFDF 字符串解析成 Rust 结构,
/// 也负责把 Rust 结构重新写回 XFDF 字符串。
pub use *;
pub use ;
pub use PdfAnnotationExporter;
pub use ;
use fs;
use Path;
/// 从磁盘读取一个 XFDF 文件,并解析成 [`XfdfDocument`]。
///
/// 可以把它理解成“两步合成一步”:
/// 1. 先把文件内容读出来
/// 2. 再把读到的 XML 解析成程序能直接使用的数据结构
///
/// # 示例
///
/// ```no_run
/// use pdfxml::load_xfdf;
///
/// let doc = load_xfdf("examples/sample.xfdf")?;
/// assert!(!doc.annotations.is_empty());
/// # Ok::<(), pdfxml::PdfXmlError>(())
/// ```
/// 从 PDF 中读取注释,并转换成项目统一使用的 [`XfdfDocument`]。
///
/// 这样做的好处是:
/// - 后面可以继续复用同一套数据结构
/// - 测试和导出 XFDF 的逻辑也都能继续复用
///
/// # 示例
///
/// ```no_run
/// use pdfxml::load_annotations_from_pdf;
///
/// let doc = load_annotations_from_pdf("annotated.pdf")?;
/// println!("{}", doc.annotations.len());
/// # Ok::<(), pdfxml::PdfXmlError>(())
/// ```
/// 把 PDF 里的注释直接导出成一个标准 XFDF 文件。
///
/// # 示例
///
/// ```no_run
/// use pdfxml::export_pdf_annotations_to_xfdf;
///
/// export_pdf_annotations_to_xfdf("annotated.pdf", "exported.xfdf")?;
/// # Ok::<(), pdfxml::PdfXmlError>(())
/// ```
/// 把已经解析好的注释导出成 PDF。
///
/// 规则很简单:
/// - 如果给了 `target_pdf`,就把注释合并进已有 PDF
/// - 如果没有给 `target_pdf`,就新建一个 PDF 来放这些注释
///
/// 这个函数适合直接给 SDK 调用方使用。
/// 如果你需要更细的控制,也可以直接使用 [`PdfAnnotationExporter`]。
///
/// # 示例
///
/// ```no_run
/// use pdfxml::{export_annotations, XfdfDocument};
///
/// let doc = XfdfDocument::parse(r#"
/// <?xml version="1.0" encoding="UTF-8" ?>
/// <xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
/// <annots>
/// <text page="0" rect="100,700,250,730">Hello</text>
/// </annots>
/// </xfdf>
/// "#)?;
/// export_annotations(&doc, Option::<&str>::None, "output.pdf")?;
/// # Ok::<(), pdfxml::PdfXmlError>(())
/// ```