1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/// Sugar for \part{} creation
#[macro_export]
macro_rules! part {
    ($i:literal) => {
        Component::Part(Part::new($i))
    };
}

/// Sugar for \chapter{} creation
#[macro_export]
macro_rules! chapter {
    ($i:literal) => {
        Component::Chapter(Chapter::new($i))
    };
}

/// Sugar for image creation
#[macro_export]
macro_rules! image {
    ($i:literal) => {
        Component::Image(Image::new($i))
    };
}

/// Sugar for \section{} creation
#[macro_export]
macro_rules! section {
    ($i:literal) => {
        Component::Section(Section::new($i))
    };
}

/// Sugar for environment creation.
#[macro_export]
macro_rules! environment {
    ($i:literal) => {
        Component::Environment(Environment::new($i))
    };
}

/// This could've gotten real ugly if you had to do it yourself.
/// So whenever you've got a latex macro you defined earlier, and want to use it, use this macro.
/// ```rust
/// command!(<your document variable>, "<your command/macro name>", <appropriate arguments to the command>)
/// ```
#[macro_export]
macro_rules! command {
    ($doc:ident, $cmd:literal, $( $x:expr ),*) => {
        Component::Command($doc.get_command($cmd)?.call(vec![$($x, )*])?)
    };
}

/// Sugar for document creation
#[macro_export]
macro_rules! document {
    ($l:literal) => {
        Document::new(DocumentClass::new($l))
    };
}

/// This, too, could've gotten ugly.
/// Package creation with options.
/// ```rust
/// package!("<package name>", <whatever options you want, as _literals_ >)
/// ```
#[macro_export]
macro_rules! package {
    ($pkg:literal$(,)? $( $opt:literal ),*) => {{
        let mut package = Package::new($pkg); // You might get a warning here, please ignore.
        $(package.add_option($opt);)*
        package
    }};
}

/// StackOverflow: https://stackoverflow.com/a/58243493
#[macro_export]
macro_rules! unwrap {
    ($enum:path, $expr:expr) => {{
        if let $enum(item) = $expr {
            item
        } else {
            panic!()
        }
    }};
}

/// Basically `vec![]`
#[macro_export]
macro_rules! row {
    ( $( $item:literal ),* ) => {{
        let mut r = Row::new();
        $(r.attach(textchunk!($item, ""))?;)*
        r
    }};
    ( $( $item:ident ),* ) => {{
        let mut r = Row::new();
        $(r.attach($item);)*
        r
    }};
}

/// Convenient, I hope?
#[macro_export]
macro_rules! textchunk {
    ($txt:literal, $mode:literal) => {{
        let typ = TextType::from($mode);
        Component::TextChunk(TextChunk::new($txt, typ))
    }};
}

/// Sugar for table creation.
/// Different name coz `diesel` uses the `table!()` macro to do some wizardry.
#[macro_export]
macro_rules! tabular {
    ($i:literal, $h:ident) => {
        Component::Table(Table::new($i, $h))
    };
    // ($i:literal, [$($c:literal),*]) => {
    //     Component::Table(Table::new($i, $h))
    // };
}