Skip to main content

common/parser_tools/
docx_options.rs

1//! Page geometry + base typography for DOCX export.
2//!
3//! `TextDocument::to_docx` writes with docx-rs's built-in defaults (US-Letter, the default
4//! font, single-spaced, 1" margins). [`DocxExportOptions`] lets a caller override that with a
5//! *manuscript* style: page size, margins, body font, line spacing, first-line indent,
6//! paragraph spacing, alignment, and an optional page-number header. **Everything is in DOCX
7//! units** — twips (1/1440 inch) for lengths, half-points for the font size — so this crate
8//! stays free of any point/inch or preset semantics; the caller (e.g. skribisto's compiler)
9//! does the conversion.
10//!
11//! Per-block **RTL is not an option here**: it is read from each block's own `fmt_direction`
12//! (set on the model) and emitted as a paragraph-level `<w:bidi/>`. A document that mixes LTR
13//! and RTL scenes is therefore handled per paragraph, independently of these options.
14
15use serde::{Deserialize, Serialize};
16
17/// Page geometry + base typography overrides for a DOCX export. Every field is optional; the
18/// [`Default`] is "no overrides" — exactly what plain `to_docx` produces.
19#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
20pub struct DocxExportOptions {
21    /// Page width in twips (1/1440"). `None` ⇒ docx default. Pair with [`page_height_twips`].
22    ///
23    /// [`page_height_twips`]: Self::page_height_twips
24    pub page_width_twips: Option<u32>,
25    /// Page height in twips. `None` ⇒ docx default.
26    pub page_height_twips: Option<u32>,
27    /// Top page margin in twips. `None` ⇒ docx default for that edge.
28    pub margin_top_twips: Option<i32>,
29    /// Bottom page margin in twips.
30    pub margin_bottom_twips: Option<i32>,
31    /// Left page margin in twips.
32    pub margin_left_twips: Option<i32>,
33    /// Right page margin in twips.
34    pub margin_right_twips: Option<i32>,
35    /// Base body font family, applied as the document default (ascii + complex-script slots, so
36    /// it also covers RTL runs). `None` ⇒ docx default.
37    pub font_family: Option<String>,
38    /// Base body font size in half-points (24 = 12 pt). `None` ⇒ docx default.
39    pub font_half_points: Option<usize>,
40    /// Body line spacing in twips (240 = single, 360 = 1.5×, 480 = double), applied per body
41    /// paragraph — headings keep their own style's spacing. `None` ⇒ default.
42    pub line_spacing_twips: Option<i32>,
43    /// First-line indent for body paragraphs, in twips. `None`/`0` ⇒ none.
44    pub first_line_indent_twips: Option<i32>,
45    /// Space after each body paragraph, in twips (pt × 20). `None`/`0` ⇒ none.
46    pub paragraph_spacing_after_twips: Option<i32>,
47    /// Justify body text; otherwise it is left-aligned (ragged), or right-aligned in an RTL
48    /// block.
49    pub justify: bool,
50    /// Emit a running header carrying the page number (right-aligned) — the manuscript staple.
51    pub page_numbers: bool,
52    /// Optional running-header text shown before the page number (e.g. `"Lastname / TITLE"`).
53    /// Only used when [`page_numbers`](Self::page_numbers) is set.
54    pub running_header: Option<String>,
55}
56
57impl DocxExportOptions {
58    /// docx-rs's built-in defaults — no manuscript styling (what plain `to_docx` uses).
59    pub fn plain() -> Self {
60        Self::default()
61    }
62}