|
| 1 | +use man::prelude::*; |
| 2 | +use std::path::Path; |
| 3 | + |
| 4 | +fn main() { |
| 5 | + let page = Manual::new("batdoc") |
| 6 | + .about("cat(1) for doc, docx, xls, xlsx, pptx, and pdf — renders to markdown with bat") |
| 7 | + .author(Author::new("Damon Petta").email("d@disassemble.net")) |
| 8 | + .flag( |
| 9 | + Flag::new() |
| 10 | + .short("-p") |
| 11 | + .long("--plain") |
| 12 | + .help("Force plain text output (no colors, no decorations)."), |
| 13 | + ) |
| 14 | + .flag( |
| 15 | + Flag::new() |
| 16 | + .short("-m") |
| 17 | + .long("--markdown") |
| 18 | + .help("Output as markdown (default when terminal detected)."), |
| 19 | + ) |
| 20 | + .flag(Flag::new().short("-i").long("--images").help( |
| 21 | + "Embed images as inline base64 data URIs in markdown output. \ |
| 22 | + Extracts embedded images from .docx, .pptx, and .xlsx files. \ |
| 23 | + Most useful when piping to a file \ |
| 24 | + (batdoc --images report.docx > out.md). \ |
| 25 | + Ignored in plain text mode and for formats without image \ |
| 26 | + support (.doc, .xls, .pdf).", |
| 27 | + )) |
| 28 | + .flag( |
| 29 | + Flag::new() |
| 30 | + .short("-h") |
| 31 | + .long("--help") |
| 32 | + .help("Show help information."), |
| 33 | + ) |
| 34 | + .arg(Arg::new("[FILE...]")) |
| 35 | + .custom( |
| 36 | + Section::new("description") |
| 37 | + .paragraph( |
| 38 | + "batdoc reads Office documents and PDFs and dumps their contents \ |
| 39 | + to the terminal as markdown. It is a spiritual successor to \ |
| 40 | + catdoc(1) — cat had catdoc, bat gets batdoc.", |
| 41 | + ) |
| 42 | + .paragraph( |
| 43 | + "Format is detected by magic bytes (file signature), not file \ |
| 44 | + extension. Supported formats: .doc (OLE2 Word 97+), .docx \ |
| 45 | + (OOXML), .xls (BIFF8 Excel 97+), .xlsx (OOXML), .pptx \ |
| 46 | + (OOXML), and .pdf.", |
| 47 | + ) |
| 48 | + .paragraph( |
| 49 | + "When stdout is a terminal, output is pretty-printed as \ |
| 50 | + syntax-highlighted markdown via bat(1) with paging. When \ |
| 51 | + piped, plain text is emitted.", |
| 52 | + ) |
| 53 | + .paragraph( |
| 54 | + "Multiple files can be specified and will be processed in \ |
| 55 | + order. Use \\fB-\\fR to read from stdin explicitly. Maximum \ |
| 56 | + input size is 256 MiB.", |
| 57 | + ), |
| 58 | + ) |
| 59 | + .example( |
| 60 | + Example::new() |
| 61 | + .text("View a Word document in the terminal") |
| 62 | + .command("batdoc report.docx"), |
| 63 | + ) |
| 64 | + .example( |
| 65 | + Example::new() |
| 66 | + .text("Extract a spreadsheet as plain-text TSV") |
| 67 | + .command("batdoc --plain data.xlsx > data.tsv"), |
| 68 | + ) |
| 69 | + .example( |
| 70 | + Example::new() |
| 71 | + .text("Convert a presentation to markdown with embedded images") |
| 72 | + .command("batdoc --images slides.pptx > slides.md"), |
| 73 | + ) |
| 74 | + .example( |
| 75 | + Example::new() |
| 76 | + .text("Read from stdin") |
| 77 | + .command("curl -sL https://example.com/file.docx | batdoc"), |
| 78 | + ) |
| 79 | + .custom( |
| 80 | + Section::new("environment") |
| 81 | + .paragraph( |
| 82 | + "batdoc respects the \\fBNO_COLOR\\fR environment variable. \ |
| 83 | + When set, colored output is suppressed even on a terminal.", |
| 84 | + ) |
| 85 | + .paragraph( |
| 86 | + "The \\fBPAGER\\fR environment variable controls which pager \ |
| 87 | + is used when output is displayed on a terminal.", |
| 88 | + ), |
| 89 | + ) |
| 90 | + .custom(Section::new("see also").paragraph("bat(1), catdoc(1), pdftotext(1)")) |
| 91 | + .render(); |
| 92 | + |
| 93 | + // Write to OUT_DIR (standard cargo output directory) |
| 94 | + let out_dir = std::env::var("OUT_DIR").unwrap(); |
| 95 | + let out_path = Path::new(&out_dir).join("batdoc.1"); |
| 96 | + std::fs::write(&out_path, &page).unwrap(); |
| 97 | + |
| 98 | + // Also write to target/man/ so packaging scripts have a stable path |
| 99 | + // that doesn't depend on the hash-based OUT_DIR. |
| 100 | + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); |
| 101 | + let man_dir = Path::new(&manifest_dir).join("target").join("man"); |
| 102 | + std::fs::create_dir_all(&man_dir).unwrap(); |
| 103 | + std::fs::write(man_dir.join("batdoc.1"), &page).unwrap(); |
| 104 | + |
| 105 | + println!("cargo::rerun-if-changed=build.rs"); |
| 106 | +} |
0 commit comments