use std::sync::Arc;
use anyhow::Result;
use async_trait::async_trait;
use htmd::HtmlToMarkdown;
use swiftide_core::{Transformer, indexing::TextNode};
#[swiftide_macros::indexing_transformer(derive(skip_default, skip_debug))]
pub struct HtmlToMarkdownTransformer {
htmd: Arc<HtmlToMarkdown>,
}
impl Default for HtmlToMarkdownTransformer {
fn default() -> Self {
Self {
htmd: HtmlToMarkdown::builder()
.skip_tags(vec!["script", "style"])
.build()
.into(),
concurrency: None,
client: None,
indexing_defaults: None,
}
}
}
impl std::fmt::Debug for HtmlToMarkdownTransformer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HtmlToMarkdownTransformer").finish()
}
}
#[async_trait]
impl Transformer for HtmlToMarkdownTransformer {
type Input = String;
type Output = String;
#[tracing::instrument(skip_all, name = "transformer.html_to_markdown")]
async fn transform_node(&self, node: TextNode) -> Result<TextNode> {
let chunk = self.htmd.convert(&node.chunk)?;
TextNode::build_from_other(&node).chunk(chunk).build()
}
fn concurrency(&self) -> Option<usize> {
self.concurrency
}
}
#[cfg(test)]
mod test {
use super::*;
#[tokio::test]
async fn test_html_to_markdown() {
let node = TextNode::new("<h1>Hello, World!</h1>");
let transformer = HtmlToMarkdownTransformer::default();
let transformed_node = transformer.transform_node(node).await.unwrap();
assert_eq!(transformed_node.chunk, "# Hello, World!");
}
}