use std::collections::HashMap;
use std::fmt::Write as FmtWrite;
use std::path::Path;
use rdocx::{
Alignment, BorderStyle, Document, Length, SectionBreak, StyleBuilder, TabAlignment, TabLeader,
VerticalAlignment,
};
fn main() {
let samples_dir = Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.parent()
.unwrap()
.join("samples");
std::fs::create_dir_all(&samples_dir).unwrap();
println!(
"Generating all sample documents in {}\n",
samples_dir.display()
);
let generators: Vec<(&str, fn(&Path) -> Document)> = vec![
("feature_showcase", generate_feature_showcase),
("proposal", generate_proposal),
("quote", generate_quote),
("invoice", generate_invoice),
("report", generate_report),
("letter", generate_letter),
("contract", generate_contract),
];
for (name, generator) in &generators {
println!("--- {} ---", name);
let doc = generator(&samples_dir);
export_all(&samples_dir, name, doc);
println!();
}
println!("All done!");
}
fn export_all(dir: &Path, name: &str, mut doc: Document) {
let docx_path = dir.join(format!("{name}.docx"));
doc.save(&docx_path).unwrap();
println!(" {name}.docx");
match doc.to_pdf() {
Ok(pdf) => {
let pdf_path = dir.join(format!("{name}.pdf"));
std::fs::write(&pdf_path, &pdf).unwrap();
println!(" {name}.pdf ({} bytes)", pdf.len());
}
Err(e) => println!(" {name}.pdf — skipped: {e}"),
}
let html = doc.to_html();
let html_path = dir.join(format!("{name}.html"));
std::fs::write(&html_path, &html).unwrap();
println!(" {name}.html ({} bytes)", html.len());
let md = doc.to_markdown();
let md_path = dir.join(format!("{name}.md"));
std::fs::write(&md_path, &md).unwrap();
println!(" {name}.md ({} bytes)", md.len());
}
fn generate_feature_showcase(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
);
doc.set_header_footer_distance(Length::twips(720), Length::twips(432));
doc.set_gutter(Length::twips(0));
doc.set_title("rdocx Feature Showcase");
doc.set_author("rdocx Sample Generator");
doc.set_subject("Comprehensive feature demonstration");
doc.set_keywords("rdocx, docx, rust, sample, showcase");
doc.set_different_first_page(true);
doc.set_first_page_header("rdocx");
doc.set_first_page_footer("Feature Showcase — Cover Page");
doc.set_header("rdocx Feature Showcase");
doc.set_footer("Generated by rdocx");
let bg = create_sample_png(612, 792, [20, 45, 90]);
doc.add_background_image(&bg, "cover_bg.png");
for _ in 0..3 {
doc.add_paragraph("");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("rdocx").bold(true).size(72.0).color("FFFFFF");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Complete Feature Showcase")
.size(28.0)
.color("FFFFFF")
.italic(true);
}
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Every feature of the rdocx Rust library")
.size(13.0)
.color("B0C4DE");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("demonstrated in a single document.")
.size(13.0)
.color("B0C4DE");
}
doc.add_paragraph("").page_break_before(true);
doc.insert_toc(doc.content_count(), 3);
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("1. Text Formatting").style("Heading1");
doc.add_paragraph("1.1 Paragraph Alignment")
.style("Heading2");
doc.add_paragraph("Left-aligned paragraph (default).")
.alignment(Alignment::Left);
doc.add_paragraph("Center-aligned paragraph.")
.alignment(Alignment::Center);
doc.add_paragraph("Right-aligned paragraph.")
.alignment(Alignment::Right);
doc.add_paragraph(
"Justified paragraph — this text is long enough to demonstrate how justified alignment \
distributes extra space across word gaps so lines fill the full width of the text area.",
)
.alignment(Alignment::Justify);
doc.add_paragraph("");
doc.add_paragraph("1.2 Run Formatting").style("Heading2");
{
let mut p = doc.add_paragraph("");
p.add_run("Bold").bold(true);
p.add_run(" | ");
p.add_run("Italic").italic(true);
p.add_run(" | ");
p.add_run("Bold Italic").bold(true).italic(true);
p.add_run(" | ");
p.add_run("Underline").underline(true);
p.add_run(" | ");
p.add_run("Strikethrough").strike(true);
p.add_run(" | ");
p.add_run("Double Strike").double_strike(true);
}
{
let mut p = doc.add_paragraph("");
p.add_run("Red").color("FF0000");
p.add_run(" | ");
p.add_run("Blue").color("0000FF");
p.add_run(" | ");
p.add_run("Green").color("00AA00");
p.add_run(" | ");
p.add_run("Highlighted").highlight("FFFF00");
}
{
let mut p = doc.add_paragraph("");
p.add_run("8pt").size(8.0);
p.add_run(" | ");
p.add_run("11pt").size(11.0);
p.add_run(" | ");
p.add_run("16pt").size(16.0);
p.add_run(" | ");
p.add_run("24pt").size(24.0);
}
{
let mut p = doc.add_paragraph("");
p.add_run("Arial").font("Arial");
p.add_run(" | ");
p.add_run("Times New Roman").font("Times New Roman");
p.add_run(" | ");
p.add_run("Courier New").font("Courier New");
}
{
let mut p = doc.add_paragraph("");
p.add_run("H");
p.add_run("2").subscript();
p.add_run("O (subscript) | E=mc");
p.add_run("2").superscript();
p.add_run(" (superscript)");
}
{
let mut p = doc.add_paragraph("");
p.add_run("ALL CAPS").all_caps(true);
p.add_run(" | ");
p.add_run("Small Caps").small_caps(true);
p.add_run(" | ");
p.add_run("Expanded").character_spacing(Length::twips(40));
p.add_run(" | ");
p.add_run("Hidden text (not visible)").hidden(true);
}
doc.add_paragraph("");
doc.add_paragraph("1.3 Underline Styles").style("Heading2");
{
let mut p = doc.add_paragraph("");
p.add_run("Single ")
.underline_style(rdocx::UnderlineStyle::Single);
p.add_run("Double ")
.underline_style(rdocx::UnderlineStyle::Double);
p.add_run("Thick ")
.underline_style(rdocx::UnderlineStyle::Thick);
p.add_run("Dotted ")
.underline_style(rdocx::UnderlineStyle::Dotted);
p.add_run("Dash ")
.underline_style(rdocx::UnderlineStyle::Dash);
p.add_run("Wave ")
.underline_style(rdocx::UnderlineStyle::Wave);
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("2. Paragraph Formatting")
.style("Heading1");
doc.add_paragraph("2.1 Shading & Borders").style("Heading2");
doc.add_paragraph("Paragraph with light green shading")
.shading("E2EFDA");
doc.add_paragraph("Paragraph with bottom border")
.border_bottom(BorderStyle::Single, 6, "2E75B6");
doc.add_paragraph("Paragraph with all borders (red)")
.border_all(BorderStyle::Single, 4, "FF0000");
doc.add_paragraph("2.2 Indentation").style("Heading2");
doc.add_paragraph("1-inch left indent + 0.5-inch hanging indent")
.indent_left(Length::inches(1.0))
.hanging_indent(Length::inches(0.5));
doc.add_paragraph("0.5-inch first-line indent on this paragraph")
.first_line_indent(Length::inches(0.5));
doc.add_paragraph("Both left and right indent (0.75 inches each)")
.indent_left(Length::inches(0.75))
.indent_right(Length::inches(0.75));
doc.add_paragraph("2.3 Spacing & Line Height")
.style("Heading2");
doc.add_paragraph("Extra space before (24pt) and after (12pt)")
.space_before(Length::pt(24.0))
.space_after(Length::pt(12.0));
doc.add_paragraph(
"Double line spacing paragraph. This text should have extra vertical space between \
lines to demonstrate line_spacing_multiple(2.0).",
)
.line_spacing_multiple(2.0);
doc.add_paragraph("Exact 20pt line spacing (fixed height).")
.line_spacing(20.0);
doc.add_paragraph("2.4 Pagination Controls")
.style("Heading2");
doc.add_paragraph("keep_with_next — this paragraph stays with the next")
.keep_with_next(true);
doc.add_paragraph("(This paragraph was kept with the one above.)");
doc.add_paragraph("keep_together — all lines of this paragraph stay on the same page")
.keep_together(true);
doc.add_paragraph("widow_control — prevents widow/orphan lines")
.widow_control(true);
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("3. Lists").style("Heading1");
doc.add_paragraph("3.1 Bullet Lists").style("Heading2");
doc.add_bullet_list_item("First item", 0);
doc.add_bullet_list_item("Second item", 0);
doc.add_bullet_list_item("Nested level 1", 1);
doc.add_bullet_list_item("Nested level 2", 2);
doc.add_bullet_list_item("Back to level 1", 1);
doc.add_bullet_list_item("Third item", 0);
doc.add_paragraph("");
doc.add_paragraph("3.2 Numbered Lists").style("Heading2");
doc.add_numbered_list_item("First numbered item", 0);
doc.add_numbered_list_item("Second numbered item", 0);
doc.add_numbered_list_item("Sub-item A", 1);
doc.add_numbered_list_item("Sub-item B", 1);
doc.add_numbered_list_item("Third numbered item", 0);
doc.add_paragraph("");
doc.add_paragraph("4. Tab Stops").style("Heading1");
doc.add_paragraph("4.1 Alignment Tabs").style("Heading2");
doc.add_paragraph("Left\tCenter\tRight\tDecimal")
.add_tab_stop(TabAlignment::Left, Length::inches(0.0))
.add_tab_stop(TabAlignment::Center, Length::inches(2.5))
.add_tab_stop(TabAlignment::Right, Length::inches(5.0))
.add_tab_stop(TabAlignment::Decimal, Length::inches(6.5));
doc.add_paragraph("4.2 Tab Leaders").style("Heading2");
doc.add_paragraph("Item\t\tPrice")
.add_tab_stop_with_leader(TabAlignment::Left, Length::inches(0.0), TabLeader::None)
.add_tab_stop_with_leader(TabAlignment::Right, Length::inches(4.0), TabLeader::Dot)
.add_tab_stop_with_leader(TabAlignment::Right, Length::inches(5.0), TabLeader::None);
doc.add_paragraph("Widget\t\t$19.99")
.add_tab_stop_with_leader(TabAlignment::Left, Length::inches(0.0), TabLeader::None)
.add_tab_stop_with_leader(TabAlignment::Right, Length::inches(4.0), TabLeader::Dot)
.add_tab_stop_with_leader(TabAlignment::Right, Length::inches(5.0), TabLeader::None);
doc.add_paragraph("Gadget\t\t$249.50")
.add_tab_stop_with_leader(TabAlignment::Left, Length::inches(0.0), TabLeader::None)
.add_tab_stop_with_leader(
TabAlignment::Right,
Length::inches(4.0),
TabLeader::Underscore,
)
.add_tab_stop_with_leader(TabAlignment::Right, Length::inches(5.0), TabLeader::None);
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("5. Tables").style("Heading1");
doc.add_paragraph("5.1 Basic Table").style("Heading2");
{
let mut tbl = doc
.add_table(4, 3)
.borders(BorderStyle::Single, 4, "000000");
for col in 0..3 {
tbl.cell(0, col).unwrap().shading("2E75B6");
}
tbl.cell(0, 0).unwrap().set_text("Name");
tbl.cell(0, 1).unwrap().set_text("Role");
tbl.cell(0, 2).unwrap().set_text("Location");
tbl.cell(1, 0).unwrap().set_text("Walter White");
tbl.cell(1, 1).unwrap().set_text("CEO");
tbl.cell(1, 2).unwrap().set_text("Albuquerque");
tbl.cell(2, 0).unwrap().set_text("Jesse Pinkman");
tbl.cell(2, 1).unwrap().set_text("CTO");
tbl.cell(2, 2).unwrap().set_text("Remote");
tbl.cell(3, 0).unwrap().set_text("Hank Schrader");
tbl.cell(3, 1).unwrap().set_text("Security");
tbl.cell(3, 2).unwrap().set_text("Washington");
}
doc.add_paragraph("");
doc.add_paragraph("5.2 Column Span & Cell Shading")
.style("Heading2");
{
let mut tbl = doc
.add_table(3, 4)
.borders(BorderStyle::Single, 4, "000000")
.width_pct(100.0);
tbl.cell(0, 0).unwrap().set_text("Quarterly Report");
tbl.cell(0, 0).unwrap().shading("1F4E79").grid_span(4);
tbl.cell(1, 0).unwrap().set_text("Region");
tbl.cell(1, 0).unwrap().shading("D6E4F0");
tbl.cell(1, 1).unwrap().set_text("Q1");
tbl.cell(1, 1).unwrap().shading("D6E4F0");
tbl.cell(1, 2).unwrap().set_text("Q2");
tbl.cell(1, 2).unwrap().shading("D6E4F0");
tbl.cell(1, 3).unwrap().set_text("Total");
tbl.cell(1, 3).unwrap().shading("D6E4F0");
tbl.cell(2, 0).unwrap().set_text("Americas");
tbl.cell(2, 1).unwrap().set_text("$2.4M");
tbl.cell(2, 2).unwrap().set_text("$2.7M");
tbl.cell(2, 3).unwrap().set_text("$5.1M");
}
doc.add_paragraph("");
doc.add_paragraph("5.3 Vertical Merge").style("Heading2");
{
let mut tbl = doc
.add_table(4, 3)
.borders(BorderStyle::Single, 4, "000000");
tbl.cell(0, 0).unwrap().set_text("Category");
tbl.cell(0, 0).unwrap().shading("E2EFDA");
tbl.cell(0, 1).unwrap().set_text("Item");
tbl.cell(0, 1).unwrap().shading("E2EFDA");
tbl.cell(0, 2).unwrap().set_text("Price");
tbl.cell(0, 2).unwrap().shading("E2EFDA");
tbl.cell(1, 0).unwrap().set_text("Hardware");
tbl.cell(1, 0).unwrap().v_merge_restart();
tbl.cell(1, 1).unwrap().set_text("Laptop");
tbl.cell(1, 2).unwrap().set_text("$1,200");
tbl.cell(2, 0).unwrap().v_merge_continue();
tbl.cell(2, 1).unwrap().set_text("Monitor");
tbl.cell(2, 2).unwrap().set_text("$450");
tbl.cell(3, 0).unwrap().set_text("Software");
tbl.cell(3, 1).unwrap().set_text("IDE License");
tbl.cell(3, 2).unwrap().set_text("$200/yr");
}
doc.add_paragraph("");
doc.add_paragraph("5.4 Nested Table").style("Heading2");
{
let mut tbl = doc
.add_table(2, 2)
.borders(BorderStyle::Single, 6, "2E75B6");
tbl.cell(0, 0).unwrap().set_text("Outer (0,0)");
tbl.cell(0, 1).unwrap().set_text("Outer (0,1)");
tbl.cell(1, 0).unwrap().set_text("Outer (1,0)");
{
let mut cell = tbl.cell(1, 1).unwrap();
cell.set_text("Nested table below:");
let mut nested = cell
.add_table(2, 2)
.borders(BorderStyle::Single, 2, "FF6600");
nested.cell(0, 0).unwrap().set_text("A");
nested.cell(0, 1).unwrap().set_text("B");
nested.cell(1, 0).unwrap().set_text("C");
nested.cell(1, 1).unwrap().set_text("D");
}
}
doc.add_paragraph("");
doc.add_paragraph("5.5 Vertical Alignment & Row Properties")
.style("Heading2");
{
let mut tbl = doc
.add_table(2, 3)
.borders(BorderStyle::Single, 4, "666666");
tbl.row(0).unwrap().height(Length::pt(50.0)).header();
tbl.cell(0, 0).unwrap().set_text("Top");
tbl.cell(0, 0)
.unwrap()
.vertical_alignment(VerticalAlignment::Top)
.shading("FFF2CC");
tbl.cell(0, 1).unwrap().set_text("Center");
tbl.cell(0, 1)
.unwrap()
.vertical_alignment(VerticalAlignment::Center)
.shading("D9E2F3");
tbl.cell(0, 2).unwrap().set_text("Bottom");
tbl.cell(0, 2)
.unwrap()
.vertical_alignment(VerticalAlignment::Bottom)
.shading("E2EFDA");
tbl.row(1).unwrap().cant_split();
tbl.cell(1, 0).unwrap().set_text("No-wrap cell");
tbl.cell(1, 0).unwrap().no_wrap();
tbl.cell(1, 1).unwrap().set_text("Fixed width");
tbl.cell(1, 1).unwrap().width(Length::inches(2.0));
tbl.cell(1, 2).unwrap().set_text("Normal");
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("6. Images").style("Heading1");
doc.add_paragraph("6.1 Inline Image").style("Heading2");
doc.add_paragraph("A blue gradient image below:");
let img = create_sample_png(200, 50, [0, 80, 200]);
doc.add_picture(&img, "chart.png", Length::inches(3.0), Length::inches(0.75));
doc.add_paragraph("");
doc.add_paragraph("6.2 Header Image").style("Heading2");
let hdr_img = create_sample_png(400, 40, [40, 40, 40]);
doc.set_header_image(
&hdr_img,
"header_logo.png",
Length::inches(2.0),
Length::inches(0.2),
);
doc.add_paragraph("The header now contains an inline image (check the top of this page).");
doc.add_paragraph("");
doc.add_paragraph("Note: Page 1 uses a full-page background image (add_background_image).");
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("7. Content Manipulation")
.style("Heading1");
doc.add_paragraph("7.1 Placeholder Replacement")
.style("Heading2");
doc.add_paragraph("Customer: {{customer}}");
doc.add_paragraph("Date: {{date}}");
doc.add_paragraph("Reference: {{ref_number}}");
{
let mut tbl = doc
.add_table(2, 2)
.borders(BorderStyle::Single, 4, "000000");
tbl.cell(0, 0).unwrap().set_text("Project");
tbl.cell(0, 0).unwrap().shading("D6E4F0");
tbl.cell(0, 1).unwrap().set_text("{{project}}");
tbl.cell(1, 0).unwrap().set_text("Status");
tbl.cell(1, 0).unwrap().shading("D6E4F0");
tbl.cell(1, 1).unwrap().set_text("{{status}}");
}
let mut replacements = HashMap::new();
replacements.insert("{{customer}}", "Tensorbee Inc.");
replacements.insert("{{date}}", "February 22, 2026");
replacements.insert("{{ref_number}}", "TB-2026-001");
replacements.insert("{{project}}", "Infrastructure Upgrade");
replacements.insert("{{status}}", "In Progress");
let n = doc.replace_all(&replacements);
doc.add_paragraph(&format!("({n} placeholders replaced above)"));
doc.add_paragraph("");
doc.add_paragraph("7.2 Regex Replacement").style("Heading2");
doc.add_paragraph("Emails: user1@example.com and admin@tensorbee.com");
let _ = doc.replace_regex(r"\b\w+@\w+\.\w+\b", "[REDACTED]");
doc.add_paragraph("(Email addresses above were redacted using regex replacement)");
doc.add_paragraph("");
doc.add_paragraph("7.3 Content Insertion").style("Heading2");
doc.add_paragraph("Section A: First content.");
doc.add_paragraph("Section C: Third content.");
if let Some(idx) = doc.find_content_index("Section C") {
doc.insert_paragraph(
idx,
"Section B: Inserted between A and C via find_content_index().",
);
}
doc.add_paragraph("").section_break(SectionBreak::NextPage);
doc.add_paragraph("8. Section Breaks & Orientation")
.style("Heading1");
doc.add_paragraph("This page is LANDSCAPE. Useful for wide tables and charts.");
{
let mut tbl = doc
.add_table(3, 7)
.borders(BorderStyle::Single, 4, "2E75B6");
let headers = ["Region", "Jan", "Feb", "Mar", "Apr", "May", "Total"];
for (c, h) in headers.iter().enumerate() {
tbl.cell(0, c).unwrap().set_text(h);
tbl.cell(0, c).unwrap().shading("2E75B6");
}
let data = [
[
"Americas", "$1.2M", "$1.3M", "$1.4M", "$1.5M", "$1.6M", "$7.0M",
],
[
"Europe", "$0.8M", "$0.9M", "$0.9M", "$1.0M", "$1.1M", "$4.7M",
],
];
for (r, row) in data.iter().enumerate() {
for (c, v) in row.iter().enumerate() {
tbl.cell(r + 1, c).unwrap().set_text(v);
}
}
}
doc.add_paragraph("")
.section_break(SectionBreak::NextPage)
.section_landscape();
doc.add_paragraph("9. Custom Styles").style("Heading1");
doc.add_style(
StyleBuilder::paragraph("CustomHighlight", "Custom Highlight")
.based_on("Normal")
.paragraph_properties({
let mut ppr = rdocx_oxml::properties::CT_PPr::default();
ppr.shading = Some(rdocx_oxml::properties::CT_Shd {
val: "clear".to_string(),
color: None,
fill: Some("FFF2CC".to_string()),
});
ppr
})
.run_properties({
let mut rpr = rdocx_oxml::properties::CT_RPr::default();
rpr.bold = Some(true);
rpr.color = Some("C45911".to_string());
rpr
}),
);
doc.add_paragraph("This paragraph uses a custom style: bold orange text on yellow background.")
.style("CustomHighlight");
doc.add_paragraph("");
doc.add_paragraph("10. Document Intelligence API")
.style("Heading1");
let wc = doc.word_count();
let hc = doc.headings().len();
let ic = doc.images().len();
let lc = doc.links().len();
doc.add_paragraph(&format!("Word count: {wc}"));
doc.add_paragraph(&format!("Heading count: {hc}"));
doc.add_paragraph(&format!("Image count: {ic}"));
doc.add_paragraph(&format!("Link count: {lc}"));
let outline = doc.document_outline();
doc.add_paragraph(&format!("Top-level outline nodes: {}", outline.len()));
let issues = doc.audit_accessibility();
doc.add_paragraph(&format!("Accessibility issues: {}", issues.len()));
for issue in &issues {
doc.add_bullet_list_item(&format!("{:?}: {}", issue.severity, issue.message), 0);
}
doc.add_paragraph("");
doc.add_paragraph("11. Document Merging").style("Heading1");
{
let mut other = Document::new();
other.add_paragraph("This paragraph was merged from another document using append().");
doc.append(&other);
}
doc.add_paragraph("");
doc.add_paragraph("Summary of Demonstrated Features")
.style("Heading1");
let features = [
"Page setup: size, margins, header/footer distance, gutter",
"Document metadata: title, author, subject, keywords",
"Headers and footers: text, images, different first page",
"Background images (full-page behind text)",
"Table of Contents generation with bookmarks",
"Text formatting: bold, italic, underline styles, strike, color, size, font",
"Advanced run: superscript, subscript, caps, small caps, spacing, hidden",
"Paragraph formatting: alignment, borders, shading, spacing, indentation",
"Pagination controls: keep-with-next, keep-together, widow control",
"Bullet and numbered lists with nesting",
"Tab stops with dot/underscore/hyphen leaders",
"Tables: borders, shading, column spans, row spans, vertical alignment, nested tables",
"Row properties: header rows, exact height, cant-split",
"Cell properties: width, no-wrap, vertical alignment",
"Inline images and header images",
"Placeholder replacement (single and batch)",
"Regex-based find and replace",
"Content insertion at specific positions",
"Section breaks with mixed portrait/landscape",
"Custom paragraph and character styles",
"Document intelligence: word count, headings, outline, images, links",
"Accessibility audit",
"Document merging (append)",
"Export: DOCX, PDF, HTML, Markdown",
];
for f in &features {
doc.add_bullet_list_item(f, 0);
}
doc.add_paragraph("");
doc.add_paragraph("All features built entirely with the rdocx Rust crate.")
.alignment(Alignment::Center)
.shading("E2EFDA")
.border_all(BorderStyle::Single, 2, "00AA00");
doc
}
fn generate_proposal(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
);
doc.set_title("AI Platform Modernization Proposal");
doc.set_author("Walter White");
doc.set_subject("Technology Proposal");
doc.set_keywords("proposal, AI, modernization, Tensorbee");
let logo_img = create_logo_png(220, 48);
let banner = build_header_banner_xml(
"rId1",
&BannerOpts {
bg_color: "1B2A4A",
banner_width: 7772400,
banner_height: 914400,
logo_width: 2011680,
logo_height: 438912,
logo_x_offset: 295125,
logo_y_offset: 237744,
},
);
doc.set_raw_header_with_images(
banner,
&[("rId1", &logo_img, "logo.png")],
rdocx_oxml::header_footer::HdrFtrType::Default,
);
doc.set_different_first_page(true);
let cover_banner = build_header_banner_xml(
"rId1",
&BannerOpts {
bg_color: "C5922E",
banner_width: 7772400,
banner_height: 914400,
logo_width: 2011680,
logo_height: 438912,
logo_x_offset: 295125,
logo_y_offset: 237744,
},
);
doc.set_raw_header_with_images(
cover_banner,
&[("rId1", &logo_img, "logo.png")],
rdocx_oxml::header_footer::HdrFtrType::First,
);
doc.set_margins(
Length::twips(2292),
Length::twips(1440),
Length::twips(1440),
Length::twips(1440),
);
doc.set_header_footer_distance(Length::twips(720), Length::twips(432));
doc.set_footer("Tensorbee — Confidential");
doc.add_style(
StyleBuilder::paragraph("ProposalTitle", "Proposal Title")
.based_on("Normal")
.run_properties({
let mut rpr = rdocx_oxml::properties::CT_RPr::default();
rpr.bold = Some(true);
rpr.font_ascii = Some("Georgia".to_string());
rpr.font_hansi = Some("Georgia".to_string());
rpr.sz = Some(rdocx_oxml::HalfPoint(56)); rpr.color = Some("1B2A4A".to_string());
rpr
}),
);
for _ in 0..4 {
doc.add_paragraph("");
}
doc.add_paragraph("AI Platform Modernization")
.style("ProposalTitle")
.alignment(Alignment::Center);
doc.add_paragraph("")
.alignment(Alignment::Center)
.border_bottom(BorderStyle::Single, 8, "C5922E");
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Prepared for Global Financial Corp.")
.size(14.0)
.color("666666")
.italic(true);
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Prepared by: Walter White, CEO — Tensorbee")
.size(12.0)
.color("888888");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("February 22, 2026").size(12.0).color("888888");
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Table of Contents").style("Heading1");
doc.insert_toc(doc.content_count(), 2);
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Executive Summary").style("Heading1");
doc.add_paragraph(
"Tensorbee proposes a comprehensive modernization of Global Financial Corp's AI platform, \
transitioning from legacy batch-processing systems to a real-time inference architecture. \
This transformation will reduce model deployment time from weeks to hours, improve \
prediction accuracy by an estimated 23%, and deliver $4.2M in annual operational savings.",
)
.first_line_indent(Length::inches(0.3));
doc.add_paragraph(
"The project spans three phases over 18 months, with a total investment of $2.8M. \
Tensorbee brings deep expertise in ML infrastructure, having successfully completed \
similar transformations for three Fortune 500 financial institutions.",
)
.first_line_indent(Length::inches(0.3));
doc.add_paragraph("");
{
let mut tbl = doc
.add_table(5, 2)
.borders(BorderStyle::Single, 4, "1B2A4A")
.width_pct(80.0);
tbl.cell(0, 0).unwrap().set_text("Key Metric");
tbl.cell(0, 0).unwrap().shading("1B2A4A");
tbl.cell(0, 1).unwrap().set_text("Value");
tbl.cell(0, 1).unwrap().shading("1B2A4A");
let rows = [
("Total Investment", "$2.8M"),
("Annual Savings", "$4.2M"),
("ROI (Year 1)", "150%"),
("Timeline", "18 months"),
];
for (i, (k, v)) in rows.iter().enumerate() {
tbl.cell(i + 1, 0).unwrap().set_text(k);
if i % 2 == 0 {
tbl.cell(i + 1, 0).unwrap().shading("F4F1EB");
}
tbl.cell(i + 1, 1).unwrap().set_text(v);
if i % 2 == 0 {
tbl.cell(i + 1, 1).unwrap().shading("F4F1EB");
}
}
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Problem Statement").style("Heading1");
doc.add_paragraph(
"Global Financial Corp's current AI infrastructure faces three critical challenges:",
);
doc.add_numbered_list_item("Deployment Latency — New models take 3-4 weeks to deploy to production, compared to the industry benchmark of 2-3 days.", 0);
doc.add_numbered_list_item("Scalability Constraints — The batch processing architecture cannot handle real-time inference demands during peak trading hours.", 0);
doc.add_numbered_list_item("Technical Debt — Legacy Python 2.7 codebases and manual deployment scripts create reliability risks and slow iteration speed.", 0);
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Proposed Solution").style("Heading1");
doc.add_paragraph("Phase 1: Foundation (Months 1-6)")
.style("Heading2");
doc.add_bullet_list_item("Deploy Kubernetes-based ML serving infrastructure", 0);
doc.add_bullet_list_item("Implement CI/CD pipeline for model deployment", 0);
doc.add_bullet_list_item("Migrate top 5 production models to new platform", 0);
doc.add_paragraph("Phase 2: Expansion (Months 7-12)")
.style("Heading2");
doc.add_bullet_list_item(
"Real-time feature engineering pipeline (Apache Kafka + Flink)",
0,
);
doc.add_bullet_list_item("A/B testing framework for model variants", 0);
doc.add_bullet_list_item("Automated model monitoring and drift detection", 0);
doc.add_paragraph("Phase 3: Optimization (Months 13-18)")
.style("Heading2");
doc.add_bullet_list_item("GPU inference optimization (TensorRT/ONNX Runtime)", 0);
doc.add_bullet_list_item("Multi-region deployment for latency reduction", 0);
doc.add_bullet_list_item(
"Self-service model deployment portal for data science teams",
0,
);
doc.add_paragraph("Budget Breakdown").style("Heading1");
{
let mut tbl = doc
.add_table(6, 3)
.borders(BorderStyle::Single, 4, "1B2A4A")
.width_pct(100.0);
tbl.cell(0, 0).unwrap().set_text("Category");
tbl.cell(0, 0).unwrap().shading("1B2A4A");
tbl.cell(0, 1).unwrap().set_text("Cost");
tbl.cell(0, 1).unwrap().shading("1B2A4A");
tbl.cell(0, 2).unwrap().set_text("Notes");
tbl.cell(0, 2).unwrap().shading("1B2A4A");
let items = [
(
"Infrastructure",
"$450,000",
"Cloud compute + GPU instances",
),
("Engineering Services", "$1,600,000", "12 FTE x 18 months"),
(
"Software Licenses",
"$350,000",
"Kafka, monitoring, CI/CD tools",
),
(
"Training & Enablement",
"$200,000",
"Team training, documentation",
),
("Contingency (10%)", "$200,000", "Risk buffer"),
];
for (i, (cat, cost, note)) in items.iter().enumerate() {
tbl.cell(i + 1, 0).unwrap().set_text(cat);
tbl.cell(i + 1, 1).unwrap().set_text(cost);
tbl.cell(i + 1, 2).unwrap().set_text(note);
if i % 2 == 0 {
tbl.cell(i + 1, 0).unwrap().shading("F4F1EB");
tbl.cell(i + 1, 1).unwrap().shading("F4F1EB");
tbl.cell(i + 1, 2).unwrap().shading("F4F1EB");
}
}
}
doc.add_paragraph("");
doc.add_paragraph("Next Steps").style("Heading1");
doc.add_numbered_list_item(
"Schedule technical deep-dive with GFC engineering team (Week 1)",
0,
);
doc.add_numbered_list_item("Finalize scope and sign SOW (Week 2-3)", 0);
doc.add_numbered_list_item("Kick off Phase 1 with joint planning session (Week 4)", 0);
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Walter White")
.bold(true)
.size(14.0)
.color("1B2A4A");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("CEO, Tensorbee | walter@tensorbee.com")
.size(10.0)
.color("888888");
}
doc
}
fn generate_quote(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(0.75),
Length::inches(0.75),
Length::inches(0.75),
Length::inches(0.75),
);
doc.set_title("Quotation QT-2026-0147");
doc.set_author("Walter White");
doc.set_keywords("quote, BOM, Tensorbee");
doc.set_header("Tensorbee — Quotation");
doc.set_footer("QT-2026-0147 | Page");
{
let mut p = doc.add_paragraph("").alignment(Alignment::Left);
p.add_run("TENSORBEE")
.bold(true)
.size(28.0)
.color("008B8B")
.font("Helvetica");
}
doc.add_paragraph("123 Innovation Drive, Suite 400")
.alignment(Alignment::Left);
doc.add_paragraph("San Francisco, CA 94105 | +1 (415) 555-0199")
.alignment(Alignment::Left);
doc.add_paragraph("")
.border_bottom(BorderStyle::Single, 8, "008B8B");
doc.add_paragraph("");
{
let mut tbl = doc.add_table(4, 4).width_pct(100.0);
tbl.cell(0, 0).unwrap().set_text("QUOTATION");
tbl.cell(0, 0).unwrap().shading("008B8B").grid_span(2);
tbl.cell(0, 2).unwrap().set_text("DATE");
tbl.cell(0, 2).unwrap().shading("008B8B");
tbl.cell(0, 3).unwrap().set_text("VALID UNTIL");
tbl.cell(0, 3).unwrap().shading("008B8B");
tbl.cell(1, 0).unwrap().set_text("Quote #:");
tbl.cell(1, 1).unwrap().set_text("QT-2026-0147");
tbl.cell(1, 2).unwrap().set_text("Feb 22, 2026");
tbl.cell(1, 3).unwrap().set_text("Mar 22, 2026");
tbl.cell(2, 0).unwrap().set_text("Prepared by:");
tbl.cell(2, 1).unwrap().set_text("Walter White");
tbl.cell(2, 2).unwrap().set_text("Payment:");
tbl.cell(2, 3).unwrap().set_text("Net 30");
tbl.cell(3, 0).unwrap().set_text("Customer:");
tbl.cell(3, 1).unwrap().set_text("Meridian Dynamics LLC");
tbl.cell(3, 2).unwrap().set_text("Currency:");
tbl.cell(3, 3).unwrap().set_text("USD");
}
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("");
p.add_run("Bill of Materials")
.bold(true)
.size(16.0)
.color("1A3C3C");
}
doc.add_paragraph("");
{
let mut tbl = doc
.add_table(10, 6)
.borders(BorderStyle::Single, 2, "008B8B")
.width_pct(100.0)
.layout_fixed();
let hdrs = [
"#",
"Part Number",
"Description",
"Qty",
"Unit Price",
"Total",
];
for (c, h) in hdrs.iter().enumerate() {
tbl.cell(0, c).unwrap().set_text(h);
tbl.cell(0, c).unwrap().shading("008B8B");
}
let items: Vec<(&str, &str, &str, &str, &str)> = vec![
(
"TB-GPU-A100",
"NVIDIA A100 80GB GPU",
"4",
"$12,500.00",
"$50,000.00",
),
(
"TB-SRV-R750",
"Dell R750xa Server Chassis",
"2",
"$8,200.00",
"$16,400.00",
),
(
"TB-RAM-256G",
"256GB DDR5 ECC Memory Module",
"8",
"$890.00",
"$7,120.00",
),
(
"TB-SSD-3840",
"3.84TB NVMe U.2 SSD",
"8",
"$1,150.00",
"$9,200.00",
),
(
"TB-NET-CX7",
"ConnectX-7 200GbE NIC",
"4",
"$1,800.00",
"$7,200.00",
),
(
"TB-SW-48P",
"48-Port 100GbE Switch",
"1",
"$22,000.00",
"$22,000.00",
),
(
"TB-CAB-RACK",
"42U Server Rack + PDU",
"1",
"$4,500.00",
"$4,500.00",
),
(
"TB-SVC-INST",
"Installation & Configuration",
"1",
"$8,500.00",
"$8,500.00",
),
(
"TB-SVC-SUPP",
"3-Year Premium Support",
"1",
"$15,000.00",
"$15,000.00",
),
];
for (i, (pn, desc, qty, unit, total)) in items.iter().enumerate() {
let row = i + 1;
tbl.cell(row, 0).unwrap().set_text(&format!("{}", i + 1));
tbl.cell(row, 1).unwrap().set_text(pn);
tbl.cell(row, 2).unwrap().set_text(desc);
tbl.cell(row, 3).unwrap().set_text(qty);
tbl.cell(row, 4).unwrap().set_text(unit);
tbl.cell(row, 5).unwrap().set_text(total);
if i % 2 == 0 {
for c in 0..6 {
tbl.cell(row, c).unwrap().shading("F0F8F8");
}
}
}
}
doc.add_paragraph("");
{
let mut tbl = doc
.add_table(4, 2)
.borders(BorderStyle::Single, 2, "008B8B")
.width(Length::inches(3.5))
.alignment(Alignment::Right);
tbl.cell(0, 0).unwrap().set_text("Subtotal");
tbl.cell(0, 1).unwrap().set_text("$139,920.00");
tbl.cell(1, 0).unwrap().set_text("Shipping & Handling");
tbl.cell(1, 1).unwrap().set_text("$2,500.00");
tbl.cell(2, 0).unwrap().set_text("Tax (8.625%)");
tbl.cell(2, 1).unwrap().set_text("$12,068.10");
tbl.cell(3, 0).unwrap().set_text("TOTAL");
tbl.cell(3, 0).unwrap().shading("E07020");
tbl.cell(3, 1).unwrap().set_text("$154,488.10");
tbl.cell(3, 1).unwrap().shading("E07020");
}
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("");
p.add_run("Terms & Conditions")
.bold(true)
.size(14.0)
.color("1A3C3C");
}
doc.add_numbered_list_item(
"This quotation is valid for 30 calendar days from the date of issue.",
0,
);
doc.add_numbered_list_item(
"All prices are in USD and exclusive of applicable taxes unless stated.",
0,
);
doc.add_numbered_list_item("Standard lead time is 4-6 weeks from PO receipt.", 0);
doc.add_numbered_list_item(
"Payment terms: Net 30 from invoice date. 2% discount for payment within 10 days.",
0,
);
doc.add_numbered_list_item(
"Warranty: 3-year manufacturer warranty on all hardware components.",
0,
);
doc.add_numbered_list_item(
"Returns subject to 15% restocking fee if initiated after 14 days.",
0,
);
doc.add_paragraph("");
doc.add_paragraph("")
.border_bottom(BorderStyle::Single, 4, "008B8B");
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("");
p.add_run("Accepted by: ").bold(true);
p.add_run("___________________________ Date: ___________");
}
{
let mut p = doc.add_paragraph("");
p.add_run("Print Name: ").bold(true);
p.add_run("___________________________ Title: ___________");
}
doc
}
fn generate_invoice(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(0.75),
Length::inches(0.75),
Length::inches(0.75),
Length::inches(0.75),
);
doc.set_title("Invoice INV-2026-0392");
doc.set_author("Walter White");
doc.set_keywords("invoice, Tensorbee");
doc.set_footer("Tensorbee — Thank you for your business!");
{
let mut tbl = doc.add_table(4, 2).width_pct(100.0);
{
let mut cell = tbl.cell(0, 0).unwrap();
let mut p = cell.add_paragraph("");
p.add_run("TENSORBEE")
.bold(true)
.size(32.0)
.color("B22222")
.font("Helvetica");
}
{
let mut cell = tbl.cell(0, 1).unwrap();
let mut p = cell.add_paragraph("");
p.add_run("INVOICE").bold(true).size(32.0).color("333333");
}
tbl.cell(1, 0)
.unwrap()
.set_text("123 Innovation Drive, Suite 400");
tbl.cell(1, 1).unwrap().set_text("Invoice #: INV-2026-0392");
tbl.cell(2, 0).unwrap().set_text("San Francisco, CA 94105");
tbl.cell(2, 1).unwrap().set_text("Date: February 22, 2026");
tbl.cell(3, 0).unwrap().set_text("walter@tensorbee.com");
tbl.cell(3, 1).unwrap().set_text("Due Date: March 24, 2026");
}
doc.add_paragraph("")
.border_bottom(BorderStyle::Thick, 8, "B22222");
doc.add_paragraph("");
{
let mut tbl = doc.add_table(4, 2).width_pct(100.0);
tbl.cell(0, 0).unwrap().set_text("BILL TO");
tbl.cell(0, 0).unwrap().shading("B22222");
tbl.cell(0, 1).unwrap().set_text("SHIP TO");
tbl.cell(0, 1).unwrap().shading("B22222");
tbl.cell(1, 0).unwrap().set_text("Meridian Dynamics LLC");
tbl.cell(1, 1).unwrap().set_text("Meridian Dynamics LLC");
tbl.cell(2, 0).unwrap().set_text("456 Enterprise Blvd");
tbl.cell(2, 1).unwrap().set_text("Attn: Server Room B");
tbl.cell(3, 0).unwrap().set_text("Austin, TX 78701");
tbl.cell(3, 1)
.unwrap()
.set_text("456 Enterprise Blvd, Austin, TX 78701");
}
doc.add_paragraph("");
{
let mut tbl = doc
.add_table(8, 5)
.borders(BorderStyle::Single, 2, "B22222")
.width_pct(100.0);
let hdrs = ["Description", "Qty", "Unit Price", "Tax", "Amount"];
for (c, h) in hdrs.iter().enumerate() {
tbl.cell(0, c).unwrap().set_text(h);
tbl.cell(0, c).unwrap().shading("B22222");
}
let items = [
(
"ML Infrastructure Setup — Phase 1",
"1",
"$45,000.00",
"$3,881.25",
"$48,881.25",
),
(
"Data Pipeline Development (160 hrs)",
"160",
"$225.00",
"$3,105.00",
"$39,105.00",
),
(
"GPU Cluster Configuration",
"1",
"$12,000.00",
"$1,035.00",
"$13,035.00",
),
(
"API Gateway Implementation",
"1",
"$18,500.00",
"$1,595.63",
"$20,095.63",
),
(
"Load Testing & QA (80 hrs)",
"80",
"$195.00",
"$1,345.50",
"$16,945.50",
),
(
"Documentation & Training",
"1",
"$8,000.00",
"$690.00",
"$8,690.00",
),
(
"Project Management (3 months)",
"3",
"$6,500.00",
"$1,679.63",
"$21,179.63",
),
];
for (i, (desc, qty, unit, tax, amt)) in items.iter().enumerate() {
let r = i + 1;
tbl.cell(r, 0).unwrap().set_text(desc);
tbl.cell(r, 1).unwrap().set_text(qty);
tbl.cell(r, 2).unwrap().set_text(unit);
tbl.cell(r, 3).unwrap().set_text(tax);
tbl.cell(r, 4).unwrap().set_text(amt);
if i % 2 == 0 {
for c in 0..5 {
tbl.cell(r, c).unwrap().shading("FAF0F0");
}
}
}
}
doc.add_paragraph("");
{
let mut tbl = doc
.add_table(4, 2)
.borders(BorderStyle::Single, 2, "B22222")
.width(Length::inches(3.0))
.alignment(Alignment::Right);
tbl.cell(0, 0).unwrap().set_text("Subtotal");
tbl.cell(0, 1).unwrap().set_text("$154,600.00");
tbl.cell(1, 0).unwrap().set_text("Tax (8.625%)");
tbl.cell(1, 1).unwrap().set_text("$13,334.25");
tbl.cell(2, 0).unwrap().set_text("Discount (5%)");
tbl.cell(2, 1).unwrap().set_text("-$7,730.00");
tbl.cell(3, 0).unwrap().set_text("AMOUNT DUE");
tbl.cell(3, 0).unwrap().shading("B22222");
tbl.cell(3, 1).unwrap().set_text("$160,204.25");
tbl.cell(3, 1).unwrap().shading("B22222");
}
doc.add_paragraph("");
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("");
p.add_run("Payment Details")
.bold(true)
.size(14.0)
.color("333333");
}
doc.add_paragraph("Bank: Silicon Valley Bank")
.indent_left(Length::inches(0.3));
doc.add_paragraph("Account: Tensorbee Inc. — 0847-2953-1120")
.indent_left(Length::inches(0.3));
doc.add_paragraph("Routing: 121140399")
.indent_left(Length::inches(0.3));
doc.add_paragraph("Swift: SVBKUS6S")
.indent_left(Length::inches(0.3));
doc.add_paragraph("");
doc.add_paragraph("Please include invoice number INV-2026-0392 in the payment reference.")
.shading("FAF0F0")
.border_all(BorderStyle::Single, 2, "B22222");
doc
}
fn generate_report(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
);
doc.set_title("Q4 2025 Environmental Impact Report");
doc.set_author("Walter White");
doc.set_subject("Quarterly Environmental Report");
doc.set_keywords("environment, sustainability, report, Tensorbee");
doc.set_different_first_page(true);
doc.set_first_page_header("");
doc.set_header("Tensorbee — Q4 2025 Environmental Impact Report");
doc.set_footer("CONFIDENTIAL — Page");
let cover_bg = create_sample_png(612, 792, [20, 50, 15]);
doc.add_background_image(&cover_bg, "report_cover.png");
for _ in 0..5 {
doc.add_paragraph("");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Q4 2025")
.bold(true)
.size(48.0)
.color("FFFFFF")
.font("Georgia");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Environmental Impact Report")
.size(24.0)
.color("90EE90")
.font("Georgia")
.italic(true);
}
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Tensorbee — Sustainability Division")
.size(14.0)
.color("C0C0C0");
}
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Prepared by Walter White, Chief Sustainability Officer")
.size(11.0)
.color("AAAAAA");
}
doc.add_paragraph("").page_break_before(true);
doc.insert_toc(doc.content_count(), 3);
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Executive Overview").style("Heading1");
doc.add_paragraph(
"This report presents Tensorbee's environmental performance for Q4 2025. Our \
sustainability initiatives have yielded a 34% reduction in carbon emissions compared \
to Q4 2024, exceeding our target of 25%. Key achievements include the transition to \
100% renewable energy in our primary data centers and the launch of our carbon offset \
marketplace.",
)
.first_line_indent(Length::inches(0.3));
let chart_img = create_chart_png(400, 200);
doc.add_paragraph("");
doc.add_picture(
&chart_img,
"performance_chart.png",
Length::inches(5.0),
Length::inches(2.5),
)
.alignment(Alignment::Center);
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Figure 1: Quarterly Carbon Emissions (tonnes CO2e)")
.italic(true)
.size(9.0)
.color("666666");
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Energy Consumption").style("Heading1");
doc.add_paragraph("Data Center Operations")
.style("Heading2");
doc.add_paragraph(
"Our three primary data centers consumed a combined 4.2 GWh in Q4 2025, \
a 12% reduction from Q3 2025 driven by improved cooling efficiency and \
server consolidation.",
);
{
let mut tbl = doc
.add_table(5, 4)
.borders(BorderStyle::Single, 4, "2D5016")
.width_pct(100.0);
let hdrs = ["Data Center", "Capacity (MW)", "Usage (GWh)", "PUE"];
for (c, h) in hdrs.iter().enumerate() {
tbl.cell(0, c).unwrap().set_text(h);
tbl.cell(0, c).unwrap().shading("2D5016");
}
let rows = [
("San Francisco (Primary)", "3.2", "1.8", "1.12"),
("Dublin (EU)", "2.1", "1.2", "1.18"),
("Singapore (APAC)", "1.8", "1.2", "1.24"),
("TOTAL", "7.1", "4.2", "1.17 avg"),
];
for (i, (dc, cap, use_, pue)) in rows.iter().enumerate() {
tbl.cell(i + 1, 0).unwrap().set_text(dc);
tbl.cell(i + 1, 1).unwrap().set_text(cap);
tbl.cell(i + 1, 2).unwrap().set_text(use_);
tbl.cell(i + 1, 3).unwrap().set_text(pue);
if i == 3 {
for c in 0..4 {
tbl.cell(i + 1, c).unwrap().shading("E2EFDA");
}
}
}
}
doc.add_paragraph("");
doc.add_paragraph("Renewable Energy Mix").style("Heading2");
doc.add_paragraph("Breakdown of energy sources across all facilities:");
doc.add_bullet_list_item("Solar PV: 42% (1.76 GWh)", 0);
doc.add_bullet_list_item("Wind Power Purchase Agreements: 38% (1.60 GWh)", 0);
doc.add_bullet_list_item("Hydroelectric: 12% (0.50 GWh)", 0);
doc.add_bullet_list_item("Grid (non-renewable): 8% (0.34 GWh)", 0);
doc.add_paragraph("Water & Waste Management")
.style("Heading1");
doc.add_paragraph("Water Usage").style("Heading2");
doc.add_paragraph(
"Total water consumption was 12.4 million gallons, a 15% reduction from Q3. \
Our closed-loop cooling systems now recycle 78% of water used in cooling operations.",
);
doc.add_paragraph("Waste Reduction").style("Heading2");
doc.add_paragraph("E-waste management results for Q4:")
.keep_with_next(true);
{
let mut tbl = doc
.add_table(4, 3)
.borders(BorderStyle::Single, 2, "6B8E23")
.width_pct(80.0);
tbl.cell(0, 0).unwrap().set_text("Category");
tbl.cell(0, 0).unwrap().shading("6B8E23");
tbl.cell(0, 1).unwrap().set_text("Weight (kg)");
tbl.cell(0, 1).unwrap().shading("6B8E23");
tbl.cell(0, 2).unwrap().set_text("Recycled %");
tbl.cell(0, 2).unwrap().shading("6B8E23");
let rows = [
("Server Hardware", "2,450", "94%"),
("Networking Equipment", "820", "91%"),
("Storage Media", "340", "99%"),
];
for (i, (cat, wt, pct)) in rows.iter().enumerate() {
tbl.cell(i + 1, 0).unwrap().set_text(cat);
tbl.cell(i + 1, 1).unwrap().set_text(wt);
tbl.cell(i + 1, 2).unwrap().set_text(pct);
}
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Q1 2026 Initiatives").style("Heading1");
doc.add_paragraph("Planned Programs").style("Heading2");
doc.add_numbered_list_item(
"Deploy on-site battery storage at SF data center (2 MWh capacity)",
0,
);
doc.add_numbered_list_item("Pilot immersion cooling in Dublin facility", 0);
doc.add_numbered_list_item("Launch employee commute carbon offset program", 0);
doc.add_numbered_list_item("Achieve ISO 14001 certification for Singapore facility", 0);
doc.add_paragraph("Investment Targets").style("Heading2");
doc.add_paragraph("Sustainability CapEx allocation for FY2026:")
.keep_with_next(true);
{
let mut tbl = doc
.add_table(5, 2)
.borders(BorderStyle::Single, 4, "2D5016");
tbl.cell(0, 0).unwrap().set_text("Initiative");
tbl.cell(0, 0).unwrap().shading("2D5016");
tbl.cell(0, 1).unwrap().set_text("Budget");
tbl.cell(0, 1).unwrap().shading("2D5016");
let rows = [
("Battery Storage", "$1.2M"),
("Immersion Cooling Pilot", "$800K"),
("Solar Panel Expansion", "$2.1M"),
("Carbon Credits", "$500K"),
];
for (i, (init, budget)) in rows.iter().enumerate() {
tbl.cell(i + 1, 0).unwrap().set_text(init);
tbl.cell(i + 1, 1).unwrap().set_text(budget);
if i % 2 == 0 {
tbl.cell(i + 1, 0).unwrap().shading("FFFAF0");
tbl.cell(i + 1, 1).unwrap().shading("FFFAF0");
}
}
}
let roadmap_img = create_sample_png(500, 100, [40, 80, 30]);
doc.add_paragraph("");
doc.add_picture(
&roadmap_img,
"roadmap.png",
Length::inches(6.0),
Length::inches(1.2),
)
.alignment(Alignment::Center);
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("Figure 2: 2026 Sustainability Roadmap")
.italic(true)
.size(9.0)
.color("666666");
}
doc.add_paragraph("");
doc.add_paragraph(
"For questions about this report, contact Walter White at sustainability@tensorbee.com.",
)
.shading("FFFAF0")
.border_all(BorderStyle::Single, 2, "2D5016");
doc
}
fn generate_letter(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(1.25),
Length::inches(1.25),
Length::inches(1.25),
Length::inches(1.25),
);
doc.set_title("Business Letter");
doc.set_author("Walter White");
let logo_img = create_logo_png(220, 48);
let banner = build_header_banner_xml(
"rId1",
&BannerOpts {
bg_color: "4A5568",
banner_width: 7772400,
banner_height: 731520, logo_width: 2011680,
logo_height: 438912,
logo_x_offset: 295125,
logo_y_offset: 146304,
},
);
doc.set_raw_header_with_images(
banner,
&[("rId1", &logo_img, "logo.png")],
rdocx_oxml::header_footer::HdrFtrType::Default,
);
doc.set_margins(
Length::twips(2000),
Length::twips(1800),
Length::twips(1440),
Length::twips(1800),
);
doc.set_header_footer_distance(Length::twips(720), Length::twips(432));
doc.set_footer(
"Tensorbee | 123 Innovation Drive, Suite 400 | San Francisco, CA 94105 | tensorbee.com",
);
doc.add_paragraph("Walter White");
doc.add_paragraph("Chief Executive Officer");
doc.add_paragraph("Tensorbee");
doc.add_paragraph("123 Innovation Drive, Suite 400");
doc.add_paragraph("San Francisco, CA 94105");
doc.add_paragraph("");
doc.add_paragraph("February 22, 2026");
doc.add_paragraph("");
doc.add_paragraph("Ms. Sarah Chen");
doc.add_paragraph("VP of Engineering");
doc.add_paragraph("Meridian Dynamics LLC");
doc.add_paragraph("456 Enterprise Boulevard");
doc.add_paragraph("Austin, TX 78701");
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("");
p.add_run("Re: Strategic Technology Partnership — Phase 2 Expansion")
.bold(true);
}
doc.add_paragraph("");
doc.add_paragraph("Dear Ms. Chen,");
doc.add_paragraph("");
doc.add_paragraph(
"I am writing to express Tensorbee's enthusiasm for expanding our strategic technology \
partnership with Meridian Dynamics. Following the successful completion of Phase 1, \
which delivered a 40% improvement in your ML inference pipeline throughput, we believe \
the foundation is firmly established for an ambitious Phase 2 engagement.",
)
.first_line_indent(Length::inches(0.5));
doc.add_paragraph(
"During our recent executive review, your team highlighted three priority areas for \
the next phase of collaboration:",
)
.first_line_indent(Length::inches(0.5));
doc.add_numbered_list_item(
"Real-time anomaly detection for your financial transaction monitoring system, \
targeting sub-100ms latency at 50,000 transactions per second.",
0,
);
doc.add_numbered_list_item(
"Federated learning infrastructure to enable model training across your distributed \
data centers without centralizing sensitive financial data.",
0,
);
doc.add_numbered_list_item(
"MLOps automation to reduce your model deployment cycle from the current 5 days \
to under 4 hours.",
0,
);
doc.add_paragraph(
"Our engineering team has prepared a detailed technical proposal addressing each of \
these areas. We have allocated a dedicated team of eight senior engineers, led by \
our CTO, to ensure continuity with the Phase 1 team your organization has already \
built a productive working relationship with.",
)
.first_line_indent(Length::inches(0.5));
doc.add_paragraph(
"I would welcome the opportunity to present our Phase 2 proposal in person. My \
assistant will reach out to coordinate a meeting at your convenience during the \
first week of March.",
)
.first_line_indent(Length::inches(0.5));
doc.add_paragraph("");
doc.add_paragraph("Warm regards,");
doc.add_paragraph("");
doc.add_paragraph("");
doc.add_paragraph("")
.border_bottom(BorderStyle::Single, 4, "4A5568");
{
let mut p = doc.add_paragraph("");
p.add_run("Walter White").bold(true).size(12.0);
}
{
let mut p = doc.add_paragraph("");
p.add_run("Chief Executive Officer, Tensorbee")
.italic(true)
.size(10.0)
.color("666666");
}
{
let mut p = doc.add_paragraph("");
p.add_run("walter@tensorbee.com | +1 (415) 555-0199")
.size(10.0)
.color("888888");
}
doc
}
fn generate_contract(_samples_dir: &Path) -> Document {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(1.25),
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
);
doc.set_title("Employment Agreement");
doc.set_author("Tensorbee HR Department");
doc.set_subject("Employment Contract — Walter White");
doc.set_keywords("employment, contract, agreement, Tensorbee");
doc.set_header("TENSORBEE — Employment Agreement");
doc.set_footer("Employment Agreement — Walter White — Page");
doc.add_paragraph("")
.border_bottom(BorderStyle::Thick, 12, "5B2C6F");
{
let mut p = doc.add_paragraph("").alignment(Alignment::Center);
p.add_run("EMPLOYMENT AGREEMENT")
.bold(true)
.size(24.0)
.color("5B2C6F")
.font("Georgia");
}
doc.add_paragraph("")
.border_bottom(BorderStyle::Thick, 12, "5B2C6F");
doc.add_paragraph("");
doc.add_paragraph(
"This Employment Agreement (\"Agreement\") is entered into as of February 22, 2026 \
(\"Effective Date\"), by and between:",
);
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("").indent_left(Length::inches(0.5));
p.add_run("EMPLOYER: ").bold(true);
p.add_run(
"Tensorbee, Inc., a Delaware corporation with its principal place of business at \
123 Innovation Drive, Suite 400, San Francisco, CA 94105 (\"Company\")",
);
}
doc.add_paragraph("");
{
let mut p = doc.add_paragraph("").indent_left(Length::inches(0.5));
p.add_run("EMPLOYEE: ").bold(true);
p.add_run(
"Walter White, residing at 308 Negra Arroyo Lane, Albuquerque, NM 87104 (\"Employee\")",
);
}
doc.add_paragraph("");
doc.add_paragraph("The Company and Employee are collectively referred to as the \"Parties.\"");
doc.add_paragraph("");
doc.add_paragraph("Article 1 — Position and Duties")
.style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("1.1 ").bold(true);
p.add_run("The Company hereby employs the Employee as ");
p.add_run("Chief Executive Officer (CEO)")
.bold(true)
.italic(true);
p.add_run(", reporting directly to the Board of Directors.");
}
{
let mut p = doc.add_paragraph("");
p.add_run("1.2 ").bold(true);
p.add_run("The Employee shall devote full working time, attention, and best efforts to \
the performance of duties as reasonably assigned by the Board, including but not limited to:");
}
doc.add_bullet_list_item(
"Setting and executing the Company's strategic vision and business plan",
0,
);
doc.add_bullet_list_item(
"Overseeing all operations, engineering, and commercial activities",
0,
);
doc.add_bullet_list_item(
"Representing the Company to investors, customers, and the public",
0,
);
doc.add_bullet_list_item("Recruiting, developing, and retaining key talent", 0);
{
let mut p = doc.add_paragraph("");
p.add_run("1.3 ").bold(true);
p.add_run(
"The Employee's primary work location shall be the Company's San Francisco \
headquarters, with reasonable travel as required by business needs.",
);
}
doc.add_paragraph("Article 2 — Compensation and Benefits")
.style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("2.1 Base Salary. ").bold(true);
p.add_run("The Company shall pay the Employee an annual base salary of ");
p.add_run("$375,000.00").bold(true);
p.add_run(" (Three Hundred Seventy-Five Thousand Dollars), payable in accordance with the \
Company's standard payroll schedule, less applicable withholdings and deductions.");
}
{
let mut p = doc.add_paragraph("");
p.add_run("2.2 Annual Bonus. ").bold(true);
p.add_run("The Employee shall be eligible for an annual performance bonus of up to ");
p.add_run("40%").bold(true);
p.add_run(
" of base salary, based on achievement of mutually agreed performance objectives.",
);
}
{
let mut p = doc.add_paragraph("");
p.add_run("2.3 Equity. ").bold(true);
p.add_run("Subject to Board approval, the Employee shall receive a stock option grant of ");
p.add_run("500,000 shares").bold(true);
p.add_run(
" of the Company's common stock, vesting over four (4) years with a one-year cliff, \
at an exercise price equal to the fair market value on the date of grant.",
);
}
doc.add_paragraph("");
{
let mut tbl = doc
.add_table(5, 2)
.borders(BorderStyle::Single, 4, "5B2C6F")
.width_pct(70.0)
.alignment(Alignment::Center);
tbl.cell(0, 0).unwrap().set_text("Compensation Element");
tbl.cell(0, 0).unwrap().shading("5B2C6F");
tbl.cell(0, 1).unwrap().set_text("Value");
tbl.cell(0, 1).unwrap().shading("5B2C6F");
let items = [
("Base Salary", "$375,000/year"),
("Target Bonus", "Up to 40% ($150,000)"),
("Equity Grant", "500,000 shares (4yr vest)"),
("Total Target Comp", "$525,000 + equity"),
];
for (i, (elem, val)) in items.iter().enumerate() {
tbl.cell(i + 1, 0).unwrap().set_text(elem);
tbl.cell(i + 1, 1).unwrap().set_text(val);
if i == 3 {
tbl.cell(i + 1, 0).unwrap().shading("E8DAEF");
tbl.cell(i + 1, 1).unwrap().shading("E8DAEF");
}
}
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("Article 3 — Benefits").style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("3.1 ").bold(true);
p.add_run(
"The Employee shall be entitled to participate in all benefit programs \
generally available to senior executives, including:",
);
}
doc.add_bullet_list_item(
"Medical, dental, and vision insurance (100% premium coverage for employee and dependents)",
0,
);
doc.add_bullet_list_item("401(k) retirement plan with 6% company match", 0);
doc.add_bullet_list_item("Life insurance and long-term disability coverage", 0);
doc.add_bullet_list_item("Annual professional development allowance of $10,000", 0);
{
let mut p = doc.add_paragraph("");
p.add_run("3.2 Paid Time Off. ").bold(true);
p.add_run(
"The Employee shall receive 25 days of paid vacation per year, plus Company holidays, \
accruing on a monthly basis.",
);
}
doc.add_paragraph("Article 4 — Term and Termination")
.style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("4.1 At-Will Employment. ").bold(true);
p.add_run(
"This Agreement is for at-will employment and may be terminated by either Party \
at any time, with or without cause, subject to the notice provisions herein.",
);
}
{
let mut p = doc.add_paragraph("");
p.add_run("4.2 Notice Period. ").bold(true);
p.add_run("Either Party shall provide ");
p.add_run("ninety (90) days").bold(true);
p.add_run(" written notice of termination, or pay in lieu thereof.");
}
{
let mut p = doc.add_paragraph("");
p.add_run("4.3 Severance. ").bold(true);
p.add_run("In the event of termination by the Company without Cause, the Employee shall \
receive (a) twelve (12) months of base salary continuation, (b) pro-rata bonus \
for the year of termination, and (c) twelve (12) months of COBRA premium coverage.");
}
doc.add_paragraph("Article 5 — Confidentiality and IP")
.style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("5.1 ").bold(true);
p.add_run(
"The Employee agrees to maintain strict confidentiality of all proprietary \
information, trade secrets, and business plans of the Company during and after \
employment.",
);
}
{
let mut p = doc.add_paragraph("");
p.add_run("5.2 ").bold(true);
p.add_run(
"All intellectual property, inventions, and works of authorship created by the \
Employee during the term of employment and within the scope of duties shall be \
the sole and exclusive property of the Company.",
);
}
doc.add_paragraph("Article 6 — Non-Competition")
.style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("6.1 ").bold(true);
p.add_run("For a period of twelve (12) months following termination, the Employee agrees \
not to engage in any business that directly competes with the Company's core \
business of AI infrastructure and ML operations services, within the United States.");
}
doc.add_paragraph("Article 7 — General Provisions")
.style("Heading1");
{
let mut p = doc.add_paragraph("");
p.add_run("7.1 Governing Law. ").bold(true);
p.add_run(
"This Agreement shall be governed by and construed in accordance with the laws of \
the State of California.",
);
}
{
let mut p = doc.add_paragraph("");
p.add_run("7.2 Entire Agreement. ").bold(true);
p.add_run(
"This Agreement constitutes the entire agreement between the Parties and supersedes \
all prior negotiations, representations, and agreements.",
);
}
{
let mut p = doc.add_paragraph("");
p.add_run("7.3 Amendment. ").bold(true);
p.add_run(
"This Agreement may only be amended by a written instrument signed by both Parties.",
);
}
doc.add_paragraph("").page_break_before(true);
doc.add_paragraph("IN WITNESS WHEREOF, the Parties have executed this Employment Agreement as of the Effective Date.")
.space_after(Length::pt(24.0));
{
let mut tbl = doc.add_table(6, 2).width_pct(100.0);
tbl.cell(0, 0).unwrap().set_text("FOR THE COMPANY:");
tbl.cell(0, 0).unwrap().shading("5B2C6F");
tbl.cell(0, 1).unwrap().set_text("EMPLOYEE:");
tbl.cell(0, 1).unwrap().shading("5B2C6F");
tbl.cell(1, 0).unwrap().set_text("");
tbl.cell(1, 1).unwrap().set_text("");
tbl.row(1).unwrap().height(Length::pt(40.0));
tbl.cell(2, 0)
.unwrap()
.set_text("Signature: ___________________________");
tbl.cell(2, 1)
.unwrap()
.set_text("Signature: ___________________________");
tbl.cell(3, 0)
.unwrap()
.set_text("Name: Board Representative");
tbl.cell(3, 1).unwrap().set_text("Name: Walter White");
tbl.cell(4, 0)
.unwrap()
.set_text("Title: Chair, Board of Directors");
tbl.cell(4, 1)
.unwrap()
.set_text("Title: Chief Executive Officer");
tbl.cell(5, 0).unwrap().set_text("Date: _______________");
tbl.cell(5, 1).unwrap().set_text("Date: _______________");
}
doc
}
fn create_sample_png(width: u32, height: u32, base_color: [u8; 3]) -> Vec<u8> {
let mut pixels = Vec::with_capacity((width * height * 4) as usize);
for y in 0..height {
for x in 0..width {
let fy = y as f64 / height as f64;
let fx = x as f64 / width as f64;
let r = (base_color[0] as f64 + (1.0 - fy) * 40.0).min(255.0) as u8;
let g = (base_color[1] as f64 + fx * 30.0).min(255.0) as u8;
let b = (base_color[2] as f64 + fy * 60.0).min(255.0) as u8;
pixels.extend_from_slice(&[r, g, b, 255]);
}
}
encode_png(width, height, &pixels)
}
fn create_chart_png(width: u32, height: u32) -> Vec<u8> {
let mut pixels = vec![0u8; (width * height * 4) as usize];
for i in 0..pixels.len() / 4 {
pixels[i * 4] = 255;
pixels[i * 4 + 1] = 255;
pixels[i * 4 + 2] = 255;
pixels[i * 4 + 3] = 255;
}
let bars: Vec<(u32, u32, [u8; 3])> = vec![
(30, 150, [45, 80, 22]), (100, 120, [45, 80, 22]), (170, 100, [45, 80, 22]), (240, 70, [45, 80, 22]), ];
for (bx, bar_height, color) in &bars {
let bar_width = 50;
let y_start = height - bar_height;
for y in y_start..height {
for x in *bx..(*bx + bar_width).min(width) {
let idx = ((y * width + x) * 4) as usize;
if idx + 3 < pixels.len() {
pixels[idx] = color[0];
pixels[idx + 1] = color[1];
pixels[idx + 2] = color[2];
pixels[idx + 3] = 255;
}
}
}
}
encode_png(width, height, &pixels)
}
fn create_logo_png(width: u32, height: u32) -> Vec<u8> {
let mut pixels = Vec::with_capacity((width * height * 4) as usize);
for y in 0..height {
for x in 0..width {
let in_text_area =
x > width / 8 && x < width * 7 / 8 && y > height / 4 && y < height * 3 / 4;
if in_text_area {
pixels.extend_from_slice(&[255, 255, 255, 255]);
} else {
pixels.extend_from_slice(&[255, 255, 255, 40]);
}
}
}
encode_png(width, height, &pixels)
}
fn encode_png(width: u32, height: u32, pixels: &[u8]) -> Vec<u8> {
let mut png = Vec::new();
{
use std::io::Write as _;
png.write_all(&[137, 80, 78, 71, 13, 10, 26, 10]).unwrap();
let mut ihdr = Vec::new();
ihdr.extend_from_slice(&width.to_be_bytes());
ihdr.extend_from_slice(&height.to_be_bytes());
ihdr.extend_from_slice(&[8, 6, 0, 0, 0]); write_chunk(&mut png, b"IHDR", &ihdr);
let mut raw = Vec::new();
for y in 0..height {
raw.push(0); let s = (y * width * 4) as usize;
raw.extend_from_slice(&pixels[s..s + (width * 4) as usize]);
}
write_chunk(&mut png, b"IDAT", &zlib_store(&raw));
write_chunk(&mut png, b"IEND", &[]);
}
png
}
fn write_chunk(out: &mut Vec<u8>, ct: &[u8; 4], data: &[u8]) {
use std::io::Write as _;
out.write_all(&(data.len() as u32).to_be_bytes()).unwrap();
out.write_all(ct).unwrap();
out.write_all(data).unwrap();
out.write_all(&crc32(ct, data).to_be_bytes()).unwrap();
}
fn crc32(ct: &[u8], data: &[u8]) -> u32 {
static T: std::sync::LazyLock<[u32; 256]> = std::sync::LazyLock::new(|| {
let mut t = [0u32; 256];
for n in 0..256u32 {
let mut c = n;
for _ in 0..8 {
c = if c & 1 != 0 {
0xEDB88320 ^ (c >> 1)
} else {
c >> 1
};
}
t[n as usize] = c;
}
t
});
let mut c = 0xFFFFFFFF_u32;
for &b in ct.iter().chain(data) {
c = T[((c ^ b as u32) & 0xFF) as usize] ^ (c >> 8);
}
c ^ 0xFFFFFFFF
}
fn zlib_store(data: &[u8]) -> Vec<u8> {
let mut out = vec![0x78, 0x01];
let chunks: Vec<&[u8]> = data.chunks(65535).collect();
for (i, chunk) in chunks.iter().enumerate() {
let last = i == chunks.len() - 1;
out.push(if last { 0x01 } else { 0x00 });
let len = chunk.len() as u16;
out.extend_from_slice(&len.to_le_bytes());
out.extend_from_slice(&(!len).to_le_bytes());
out.extend_from_slice(chunk);
}
let (mut a, mut b) = (1u32, 0u32);
for &byte in data {
a = (a + byte as u32) % 65521;
b = (b + a) % 65521;
}
out.extend_from_slice(&((b << 16) | a).to_be_bytes());
out
}
struct BannerOpts<'a> {
bg_color: &'a str,
banner_width: i64,
banner_height: i64,
logo_width: i64,
logo_height: i64,
logo_x_offset: i64,
logo_y_offset: i64,
}
fn build_header_banner_xml(image_rel_id: &str, opts: &BannerOpts) -> Vec<u8> {
let mut xml = String::with_capacity(2048);
write!(
xml,
r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>"#
)
.unwrap();
write!(xml, r#"<w:hdr "#).unwrap();
write!(
xml,
r#"xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" "#
)
.unwrap();
write!(
xml,
r#"xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" "#
)
.unwrap();
write!(
xml,
r#"xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" "#
)
.unwrap();
write!(
xml,
r#"xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" "#
)
.unwrap();
write!(
xml,
r#"xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" "#
)
.unwrap();
write!(
xml,
r#"xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" "#
)
.unwrap();
write!(
xml,
r#"xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" "#
)
.unwrap();
write!(
xml,
r#"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">"#
)
.unwrap();
write!(xml, r#"<w:p><w:pPr><w:pStyle w:val="Header"/></w:pPr>"#).unwrap();
write!(xml, r#"<w:r><w:rPr><w:noProof/></w:rPr>"#).unwrap();
write!(
xml,
r#"<mc:AlternateContent><mc:Choice Requires="wpg"><w:drawing>"#
)
.unwrap();
write!(
xml,
r#"<wp:anchor distT="0" distB="0" distL="0" distR="0" "#
)
.unwrap();
write!(
xml,
r#"simplePos="0" relativeHeight="251658240" behindDoc="0" "#
)
.unwrap();
write!(
xml,
r#"locked="0" layoutInCell="1" hidden="0" allowOverlap="1">"#
)
.unwrap();
write!(xml, r#"<wp:simplePos x="0" y="0"/>"#).unwrap();
write!(
xml,
r#"<wp:positionH relativeFrom="page"><wp:posOffset>0</wp:posOffset></wp:positionH>"#
)
.unwrap();
write!(
xml,
r#"<wp:positionV relativeFrom="page"><wp:posOffset>0</wp:posOffset></wp:positionV>"#
)
.unwrap();
write!(
xml,
r#"<wp:extent cx="{}" cy="{}"/>"#,
opts.banner_width, opts.banner_height
)
.unwrap();
write!(
xml,
r#"<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:wrapNone/>"#
)
.unwrap();
write!(
xml,
r#"<wp:docPr id="1" name="Header Banner"/><wp:cNvGraphicFramePr/>"#
)
.unwrap();
write!(xml, r#"<a:graphic><a:graphicData uri="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup">"#).unwrap();
write!(xml, r#"<wpg:wgp><wpg:cNvGrpSpPr/><wpg:grpSpPr><a:xfrm>"#).unwrap();
write!(
xml,
r#"<a:off x="0" y="0"/><a:ext cx="{w}" cy="{h}"/>"#,
w = opts.banner_width,
h = opts.banner_height
)
.unwrap();
write!(
xml,
r#"<a:chOff x="0" y="0"/><a:chExt cx="{w}" cy="{h}"/>"#,
w = opts.banner_width,
h = opts.banner_height
)
.unwrap();
write!(xml, r#"</a:xfrm></wpg:grpSpPr>"#).unwrap();
write!(
xml,
r#"<wps:wsp><wps:cNvPr id="2" name="BG"/><wps:cNvSpPr/><wps:spPr>"#
)
.unwrap();
write!(
xml,
r#"<a:xfrm><a:off x="0" y="0"/><a:ext cx="{w}" cy="{h}"/></a:xfrm>"#,
w = opts.banner_width,
h = opts.banner_height
)
.unwrap();
write!(xml, r#"<a:prstGeom prst="rect"><a:avLst/></a:prstGeom>"#).unwrap();
write!(
xml,
r#"<a:solidFill><a:srgbClr val="{}"/></a:solidFill>"#,
opts.bg_color
)
.unwrap();
write!(
xml,
r#"<a:ln><a:noFill/></a:ln></wps:spPr><wps:bodyPr/></wps:wsp>"#
)
.unwrap();
write!(
xml,
r#"<pic:pic><pic:nvPicPr><pic:cNvPr id="3" name="Logo"/><pic:cNvPicPr/></pic:nvPicPr>"#
)
.unwrap();
write!(xml, r#"<pic:blipFill><a:blip r:embed="{}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>"#, image_rel_id).unwrap();
write!(
xml,
r#"<pic:spPr><a:xfrm><a:off x="{}" y="{}"/><a:ext cx="{}" cy="{}"/></a:xfrm>"#,
opts.logo_x_offset, opts.logo_y_offset, opts.logo_width, opts.logo_height
)
.unwrap();
write!(xml, r#"<a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln></pic:spPr></pic:pic>"#).unwrap();
write!(xml, r#"</wpg:wgp></a:graphicData></a:graphic>"#).unwrap();
write!(
xml,
r#"</wp:anchor></w:drawing></mc:Choice></mc:AlternateContent>"#
)
.unwrap();
write!(xml, r#"</w:r></w:p></w:hdr>"#).unwrap();
xml.into_bytes()
}