1use printpdf::*;
2use scraper::{Html, Selector};
3use std::fs::File;
4use std::io::BufWriter;
5use std::path::Path;
6use anyhow::{Context, Result};
7
8fn html_to_text(html: &str) -> String {
10 let document = Html::parse_document(html);
11 let body_selector = Selector::parse("body").unwrap();
12 let mut text_content = String::new();
13
14 if let Some(body) = document.select(&body_selector).next() {
16 for node in body.text() {
17 text_content.push_str(node.trim());
18 text_content.push('\n'); }
20 }
21
22 text_content
23}
24
25pub fn html_to_pdf(html: &str, output_path: &Path) -> Result<()> {
27 let text = html_to_text(html);
28 let (document, page1, layer1) = PdfDocument::new("HTML to PDF", Mm(210.0), Mm(297.0), "Layer 1");
29
30 let font = document.add_builtin_font(BuiltinFont::Helvetica)
32 .context("Failed to add built-in font")?;
33 let font_size = 12.0;
34 let mut y_position = 287.0; let file = File::create(output_path).context("Failed to create output file")?;
38 let mut buffer = BufWriter::new(file);
39
40 let mut current_layer = document.get_page(page1).get_layer(layer1);
42
43 for line in text.lines() {
45 if !line.trim().is_empty() {
46 if y_position < 10.0 {
48 let (new_page, new_layer) = document.add_page(Mm(210.0), Mm(297.0), "New Page");
50 current_layer = document.get_page(new_page).get_layer(new_layer);
51 y_position = 287.0; }
53
54 current_layer.use_text(line, font_size, Mm(10.0), Mm(y_position), &font);
56 y_position -= font_size + 2.0; }
58 }
59
60 document.save(&mut buffer).context("Failed to save PDF")?;
62
63 Ok(())
64}