html_translation_lib/lib.rs
1//! HTML翻译库
2//!
3//! 这个库提供了一个完整的HTML内容翻译解决方案,专门为网页本地化而设计。
4//! 它可以智能识别HTML文档中的可翻译文本内容,并将其翻译为目标语言,
5//! 同时保持HTML结构的完整性。
6//!
7//! ## 核心特性
8//!
9//! - **智能文本识别**: 自动识别HTML中需要翻译的文本内容,跳过代码、链接等
10//! - **批量处理优化**: 将多个文本项组合成批次,减少翻译API调用次数
11//! - **DOM结构保护**: 翻译过程中完全保持HTML的DOM结构不变
12//! - **缓存机制**: 内置缓存系统,避免重复翻译相同内容
13//! - **错误恢复**: 自动重试机制和错误处理,确保翻译过程的可靠性
14//! - **异步支持**: 支持异步操作,不阻塞主线程
15//!
16//! ## 使用示例
17//!
18//! ### 基本翻译
19//!
20//! ```rust,no_run
21//! use html_translation_lib::{TranslationConfig, HtmlTranslator};
22//!
23//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
24//! // 创建翻译配置
25//! let config = TranslationConfig::new()
26//! .target_language("zh")
27//! .api_url("http://localhost:1188/translate")
28//! .enable_cache(true);
29//!
30//! // 创建翻译器
31//! let mut translator = HtmlTranslator::new(config).await?;
32//!
33//! // 翻译HTML内容
34//! let html = r#"<html><body><h1>Hello World</h1></body></html>"#;
35//! let translated_html = translator.translate_html(html).await?;
36//! println!("{}", translated_html);
37//! # Ok(())
38//! # }
39//! ```
40//!
41//! ### 翻译文件
42//!
43//! ```rust,no_run
44//! use html_translation_lib::{TranslationConfig, HtmlTranslator};
45//!
46//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
47//! let config = TranslationConfig::new().target_language("zh");
48//! let mut translator = HtmlTranslator::new(config).await?;
49//!
50//! // 翻译整个HTML文件
51//! translator.translate_file("input.html", "output_zh.html").await?;
52//! # Ok(())
53//! # }
54//! ```
55//!
56//! ### 与Monolith集成
57//!
58//! ```rust,no_run
59//! use html_translation_lib::{TranslationConfig, translate_before_merge};
60//! use markup5ever_rcdom::RcDom;
61//! use html5ever::parse_document;
62//! use html5ever::tendril::TendrilSink;
63//!
64//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
65//! // 解析HTML为DOM
66//! let html = "<html><body><h1>Hello</h1></body></html>";
67//! let dom = parse_document(RcDom::default(), Default::default())
68//! .from_utf8()
69//! .read_from(&mut html.as_bytes())?;
70//!
71//! let config = TranslationConfig::new().target_language("zh");
72//! let translated_dom = translate_before_merge(dom, config).await?;
73//! // 然后继续使用monolith进行资源合并
74//! # Ok(())
75//! # }
76//! ```
77
78#![warn(missing_docs)]
79#![warn(rust_2018_idioms)]
80
81// 公开模块
82pub mod config;
83pub mod core;
84pub mod error;
85pub mod pipeline;
86pub mod storage;
87pub mod utils;
88
89// 测试工具模块 (仅在测试时可用)
90#[cfg(test)]
91pub mod test_utils;
92
93// 重新导出核心类型
94pub use config::{TranslationConfig, TranslationConfigBuilder};
95pub use core::HtmlTranslator;
96pub use error::{TranslationError, TranslationResult};
97
98use markup5ever_rcdom::RcDom;
99
100// 内部模块 (临时移除)
101// mod translator;
102
103// use markup5ever_rcdom::RcDom; // 临时注释掉未使用的导入
104
105/// 翻译HTML内容的便利函数
106///
107/// 这是一个简单的一次性翻译函数,适用于简单的翻译需求。
108/// 对于需要复杂配置或多次翻译的场景,建议使用 `HtmlTranslator`。
109///
110/// # 参数
111///
112/// * `html_content` - 要翻译的HTML内容字符串
113/// * `target_lang` - 目标语言代码(如 "zh", "en", "ja")
114/// * `api_url` - 可选的翻译API URL
115///
116/// # 返回值
117///
118/// 返回翻译后的HTML内容字符串
119///
120/// # 示例
121///
122/// ```rust,no_run
123/// use html_translation_lib::translate_html_content;
124///
125/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
126/// let html = r#"<h1>Hello World</h1>"#;
127/// let translated = translate_html_content(
128/// html,
129/// "zh",
130/// Some("http://localhost:1188/translate")
131/// ).await?;
132/// println!("{}", translated);
133/// # Ok(())
134/// # }
135/// ```
136#[cfg(feature = "async")]
137pub async fn translate_html_content(
138 html_content: &str,
139 target_lang: &str,
140 api_url: Option<&str>,
141) -> TranslationResult<String> {
142 let config = TranslationConfig::new()
143 .target_language(target_lang)
144 .api_url(api_url.unwrap_or("http://localhost:1188/translate"));
145
146 let mut translator = HtmlTranslator::new(config).await?;
147 translator.translate_html(html_content).await
148}
149
150/// 在Monolith合并前翻译DOM内容
151///
152/// 专门为与Monolith工具集成而设计的函数。在资源合并之前对HTML内容进行翻译,
153/// 确保翻译后的内容能够正确地被Monolith处理。
154///
155/// # 参数
156///
157/// * `dom` - 要翻译的HTML DOM树
158/// * `config` - 翻译配置
159///
160/// # 返回值
161///
162/// 返回翻译后的DOM树,可以直接传给Monolith进行后续处理
163///
164/// # 示例
165///
166/// ```rust,no_run
167/// use html_translation_lib::{TranslationConfig, translate_before_merge};
168/// use markup5ever_rcdom::RcDom;
169/// use html5ever::parse_document;
170/// use html5ever::tendril::TendrilSink;
171///
172/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
173/// // 解析HTML文件
174/// let html = std::fs::read_to_string("example.html")?;
175/// let dom = parse_document(RcDom::default(), Default::default())
176/// .from_utf8()
177/// .read_from(&mut html.as_bytes())?;
178///
179/// let config = TranslationConfig::new()
180/// .target_language("zh")
181/// .enable_cache(true);
182///
183/// let translated_dom = translate_before_merge(dom, config).await?;
184/// // 现在可以传给monolith进行资源合并
185/// # Ok(())
186/// # }
187/// ```
188#[cfg(feature = "async")]
189pub async fn translate_before_merge(
190 dom: RcDom,
191 config: TranslationConfig,
192) -> TranslationResult<RcDom> {
193 let mut translator = HtmlTranslator::new(config).await?;
194 translator.translate_dom(dom).await
195}
196
197/// 同步版本的HTML内容翻译
198///
199/// 为不支持异步的环境提供的同步接口。内部使用异步运行时执行翻译。
200///
201/// # 参数
202///
203/// * `html_content` - 要翻译的HTML内容
204/// * `target_lang` - 目标语言代码
205/// * `api_url` - 可选的翻译API URL
206///
207/// # 示例
208///
209/// ```rust,no_run
210/// use html_translation_lib::translate_html_content_sync;
211///
212/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
213/// let html = r#"<h1>Hello World</h1>"#;
214/// let translated = translate_html_content_sync(
215/// html,
216/// "zh",
217/// Some("http://localhost:1188/translate")
218/// )?;
219/// println!("{}", translated);
220/// # Ok(())
221/// # }
222/// ```
223#[cfg(feature = "sync")]
224pub fn translate_html_content_sync(
225 html_content: &str,
226 target_lang: &str,
227 api_url: Option<&str>,
228) -> TranslationResult<String> {
229 use tokio::runtime::Runtime;
230
231 let rt = Runtime::new()
232 .map_err(|e| TranslationError::InternalError(format!("创建异步运行时失败: {e}")))?;
233
234 rt.block_on(translate_html_content(html_content, target_lang, api_url))
235}
236
237/// 库信息
238#[derive(Debug, Clone)]
239pub struct LibraryInfo {
240 /// 库名称
241 pub name: &'static str,
242 /// 库版本
243 pub version: &'static str,
244 /// 支持的特性列表
245 pub features: Vec<&'static str>,
246}
247
248/// 获取库信息
249///
250/// 返回当前库的版本信息和启用的特性
251#[allow(clippy::vec_init_then_push)]
252pub fn get_library_info() -> LibraryInfo {
253 let mut features = Vec::new();
254
255 #[cfg(feature = "async")]
256 features.push("async");
257
258 #[cfg(feature = "sync")]
259 features.push("sync");
260
261 LibraryInfo {
262 name: env!("CARGO_PKG_NAME"),
263 version: env!("CARGO_PKG_VERSION"),
264 features,
265 }
266}