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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/// 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
/// use rust_texas::*;
/// fn dummy() -> Result<(), Box<dyn std::error::Error>> {
///     let mut doc = document!("article");
///     command!(doc, "<your command/macro name>", "<appropriate arguments to the command>");
///     Ok(())
/// }
/// ```
///
/// doc-tests need all the stuff above to pass
#[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
/// use rust_texas::prelude::*;
/// package!("amsmath", "<whatever options you want, as literals>");
/// ```
#[macro_export]
macro_rules! package {
    ($pkg:literal$(,)? $( $opt:literal ),*) => {{
        #[allow(unused_mut)]
        let mut package = Package::new($pkg);
        $(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:expr, $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))
    };
}

// Cannot think of a way to do this cleanly. Ideas would be nice. Hit up the issues page.
#[macro_export]
macro_rules! builtin {
    ($arg:expr) => {
        Component::Builtin(Builtin::new($arg))
    };
}

#[macro_export]
macro_rules! frame {
    ($title:expr) => {
        Component::Frame(Frame::new($title))
    };
}

#[macro_export]
macro_rules! label {
    ($label:literal) => {
        Component::Label(<&str as Into<Label>>::into($label))
    };
}

#[macro_export]
macro_rules! reference {
    ($reference:literal) => {
        Component::Reference(<&str as Into<Reference>>::into($reference))
    };
}