feat(html): scaffold op-html importer crate with public API

This commit is contained in:
Kayshen-X 2026-07-18 13:10:51 +08:00
parent a4706476bd
commit 370aa5dac4
2 changed files with 75 additions and 0 deletions

12
crates/op-html/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "op-html"
version.workspace = true
edition = "2021"
description = "HTML/CSS-subset importer: converts HTML into editable PenNode trees"
license = "MIT"
[dependencies]
html5ever = "0.27"
markup5ever_rcdom = "0.3"
base64 = "0.22"
jian-ops-schema = { path = "../../vendor/jian/crates/jian-ops-schema" }

63
crates/op-html/src/lib.rs Normal file
View file

@ -0,0 +1,63 @@
//! HTML → PenNode importer (structured path, CSS-subset cascade).
use jian_ops_schema::node::PenNode;
pub struct HtmlImportOptions {
pub viewport_width: f64,
pub base_font_size: f64,
pub document_name: Option<String>,
}
impl Default for HtmlImportOptions {
fn default() -> Self {
Self {
viewport_width: 1440.0,
base_font_size: 16.0,
document_name: None,
}
}
}
pub struct HtmlImportResult {
pub nodes: Vec<PenNode>,
pub warnings: Vec<String>,
}
pub fn import_html(source: &str, opts: &HtmlImportOptions) -> HtmlImportResult {
let _ = opts;
let mut warnings = Vec::new();
if source.trim().is_empty() {
warnings.push("no importable content: input HTML is empty".to_string());
return HtmlImportResult {
nodes: Vec::new(),
warnings,
};
}
// Pipeline lands in later tasks; non-empty input is wired up in Task 11.
warnings.push("no importable content: importer pipeline not yet implemented".to_string());
HtmlImportResult {
nodes: Vec::new(),
warnings,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_input_yields_no_nodes_and_a_warning() {
let r = import_html("", &HtmlImportOptions::default());
assert!(r.nodes.is_empty());
assert_eq!(r.warnings.len(), 1);
assert!(r.warnings[0].contains("no importable content"));
}
#[test]
fn options_default_values() {
let o = HtmlImportOptions::default();
assert_eq!(o.viewport_width, 1440.0);
assert_eq!(o.base_font_size, 16.0);
assert!(o.document_name.is_none());
}
}