rtf_parser_tt/
paragraph.rs

1/// Define the paragraph related structs and enums
2use serde::{Deserialize, Serialize};
3
4#[cfg(feature = "jsbindings")]
5use tsify::Tsify;
6#[cfg(feature = "jsbindings")]
7use wasm_bindgen::prelude::wasm_bindgen;
8
9use crate::tokens::ControlWord;
10
11#[derive(Debug, Default, Clone, Copy, PartialEq, Hash, Deserialize, Serialize)]
12#[cfg_attr(feature = "jsbindings", wasm_bindgen)]
13pub struct Paragraph {
14    pub alignment: Alignment,
15    pub spacing: Spacing,
16    pub indent: Indentation,
17    pub tab_width: i32,
18}
19
20/// Alignement of a paragraph (left, right, center, justify)
21#[derive(Debug, Default, Clone, Copy, PartialEq, Hash, Deserialize, Serialize)]
22#[cfg_attr(feature = "jsbindings", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
23pub enum Alignment {
24    #[default]
25    LeftAligned, // \ql
26    RightAligned, // \qr
27    Center,       // \qc
28    Justify,      // \qj
29}
30
31impl From<&ControlWord<'_>> for Alignment {
32    fn from(cw: &ControlWord) -> Self {
33        return match cw {
34            ControlWord::LeftAligned  => Alignment::LeftAligned,
35            ControlWord::RightAligned => Alignment::RightAligned,
36            ControlWord::Center       => Alignment::Center,
37            ControlWord::Justify      => Alignment::Justify,
38            _  /* default */          => Alignment::LeftAligned,
39        };
40    }
41}
42
43/// The vertical margin before / after a block of text
44#[derive(Debug, Default, Clone, Copy, PartialEq, Hash, Deserialize, Serialize)]
45#[cfg_attr(feature = "jsbindings", wasm_bindgen)]
46pub struct Spacing {
47    pub before: i32,
48    pub after: i32,
49    pub between_line: SpaceBetweenLine,
50    pub line_multiplier: i32,
51}
52
53#[derive(Default, Debug, Clone, Copy, PartialEq, Hash, Deserialize, Serialize)]
54#[cfg_attr(feature = "jsbindings", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
55pub enum SpaceBetweenLine {
56    Value(i32),
57    #[default]
58    Auto,
59    Invalid,
60}
61
62/// Space between lines.
63// If this control word is missing or if \sl1000 is used, the line spacing is automatically determined by the tallest character in the line;
64// if N is a positive value, this size is used only if it is taller than the tallest character (otherwise, the tallest character is used);
65// if N is a negative value, the absolute value of N is used, even if it is shorter than the tallest character.
66impl From<i32> for SpaceBetweenLine {
67    fn from(value: i32) -> Self {
68        return match value {
69            1000 => SpaceBetweenLine::Auto,
70            val if val < 0 => SpaceBetweenLine::Value(val.abs()),
71            val => SpaceBetweenLine::Value(val),
72        };
73    }
74}
75
76// This struct can not be an enum because left-indent and right-ident can both be defined at the same time
77#[derive(Default, Debug, Clone, Copy, PartialEq, Hash, Deserialize, Serialize)]
78#[cfg_attr(feature = "jsbindings", wasm_bindgen)]
79pub struct Indentation {
80    pub left: i32,
81    pub right: i32,
82    pub first_line: i32,
83}