Skip to main content

common/parser_tools/
latex_options.rs

1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Preamble + image policy for LaTeX export.
5//!
6//! LaTeX was, until M-T3, the last export format in this crate still taking its knobs as bare
7//! positional arguments (`to_latex(document_class, include_preamble)` /
8//! `to_latex_with_options(document_class, include_preamble, omit_images)`) instead of an options
9//! struct — every sibling already had one: `DjotExportOptions`, `DocxExportOptions`,
10//! `EpubExportOptions`, `HtmlExportOptions`, `MarkdownExportOptions`, `OdtExportOptions`,
11//! `PdfExportOptions`, `PlainTextExportOptions`. [`LatexExportOptions`] closes that gap: the same
12//! three knobs, the same defaults, now named fields on a struct so a fourth knob never means
13//! renumbering every call site's positional argument list.
14//!
15//! Unlike [`super::docx_options::DocxExportOptions`] or [`super::odt_options::OdtExportOptions`],
16//! **LaTeX carries no comment support, and this struct never will**: there is no LaTeX importer
17//! anywhere in this crate (or planned — a `.tex` file is an arbitrary macro-expansion target, not
18//! a document format this crate can read back), so an anchored comment thread round-tripped into
19//! LaTeX would be structurally one-way, editorial notes going in and never coming back out. That
20//! was a deliberate scope cut in the comment-export feature, not an oversight here — do not add a
21//! `comments` field to this struct.
22//!
23//! LaTeX also has no page geometry or base-typography knobs the way DOCX/ODT do:
24//! `\documentclass` and its own options already own page size and base font (`article`,
25//! `report`, `book`, or a caller's own class), so there is nothing here to mirror
26//! `DocxExportOptions`' twips/half-points fields — a caller who wants those characteristics picks
27//! a document class that has them, or supplies its own preamble around the body this crate
28//! returns when [`include_preamble`](LatexExportOptions::include_preamble) is `false`.
29
30use serde::{Deserialize, Serialize};
31
32/// The three export-time choices `to_latex`/`to_latex_with_options` have always taken: which
33/// `\documentclass` to open with, whether to wrap the rendered body in a full compilable
34/// document at all, and whether inline images are emitted or dropped.
35///
36/// [`Default`] reproduces exactly what bare `to_latex(document_class, include_preamble)` always
37/// did: an empty [`document_class`](Self::document_class) falls back to `"article"` inside the
38/// writer (`document_io::use_cases::export_latex_uc::ExportLatexUseCase::execute`), and
39/// [`omit_images`](Self::omit_images) is `false` — images are emitted as
40/// `\includegraphics{src}` unless a caller opts out.
41#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
42pub struct LatexExportOptions {
43    /// The `\documentclass{…}` to open the document with, used only when
44    /// [`include_preamble`](Self::include_preamble) is set. Empty ⇒ `"article"` — the writer's
45    /// fallback, not this struct's: an empty string round-trips through serde the same way
46    /// `None` would on an `Option<String>` field, without making this the one options struct in
47    /// the crate that special-cases an empty string as an error.
48    ///
49    /// Ignored when `include_preamble` is `false`: a body-only fragment has no `\documentclass`
50    /// line to open.
51    pub document_class: String,
52    /// Wrap the rendered body in `\documentclass{…} … \begin{document} … \end{document}`, plus
53    /// the small fixed preamble the writer needs for hyperlinks, strikeout, images, and line
54    /// spacing, with `secnumdepth` forced to `-1` so LaTeX's own section counters never print
55    /// beside a heading this crate already numbered (see `export_latex_uc`'s own doc comment for
56    /// the full package list and reasoning). `false` returns just the body — for a caller
57    /// embedding the result inside a larger LaTeX document that owns its own preamble and
58    /// section-numbering policy.
59    pub include_preamble: bool,
60    /// Drop inline images instead of emitting `\includegraphics{…}`.
61    ///
62    /// LaTeX resolves a graphic against the filesystem when the document is compiled, so a
63    /// caller that will not place the files beside the `.tex` is choosing between a build error
64    /// and a missing picture. `false` (the historical default) still emits the reference — this
65    /// crate writes no image files itself, for LaTeX or any other format, so nothing here ever
66    /// changes that; it only changes whether the reference is written at all.
67    #[serde(default)]
68    pub omit_images: bool,
69}