1#[macro_export]
7macro_rules! Font {
8 ($($key:ident => $value:expr_2021),*) => (
9 Some(Font { $($key: $value.into_font_field(),)* .. Font::default() })
10)}
11
12#[macro_export]
15macro_rules! FontDirective {
16 ($($key:ident => $value:expr_2021),*) => (
17 Some(FontDirective::Asset(Rc::new(
18 Font { $($key: $value.into_font_field(),)* .. Font::default() }
19 ))))
20}
21
22#[macro_export]
25macro_rules! NewDefault {
26 ($name:ident, $($key:ident => $value:expr_2021),*) => ($name {
27 $($key: $value,)*
28 ..$name::default()
29 })
30}
31
32#[macro_export]
34macro_rules! NewDefaultV {
35 ($name:ident, $($key:ident => $value:expr_2021),*) => ($name {
36 $($key: $value.into_option(),)*
37 ..$name::default()
38 })
39}
40
41#[macro_export]
51macro_rules! transfer_opt_default {
52 ($val:ident, $struct_source:ident, $receiver:ident) => {
53 if let Some(ref tval) = $struct_source.$val {
54 $receiver
55 .entry(stringify!($val).to_owned())
56 .or_insert(tval.to_string());
57 }
58 };
59}
60
61#[macro_export]
65macro_rules! before_digest {
66 ($(sub)? $body:block) => {
67 vec![before_digest_single!($body)]
68 };
69}
70
71#[macro_export]
72macro_rules! before_digest_single {
73 ($body:block) => {
74 Rc::new(move || $body.into_digested_result())
75 };
76}
77
78#[macro_export]
79macro_rules! before_digest_simple {
80 ($body:block) => {
81 Rc::new(move || $body.into_digested_result())
82 };
83}
84
85#[macro_export]
86macro_rules! tagsub {
87 ($document:ident, $node:ident, $body:block) => {
89 vec![Rc::new(
90 |$document: &mut Document, mut $node: &mut Node, _whatsit: Option<&Digested>| -> Result<()> {
91 $body
92 Ok(())
93 },
94 )]
95 };
96 ($document:ident, $node:ident, $whatsit:ident, $body:block) => {
99 vec![Rc::new(
100 |$document: &mut Document, mut $node: &mut Node, $whatsit: Option<&Digested>| -> Result<()> {
101 $body
102 Ok(())
103 },
104 )]
105 };
106}
107
108#[macro_export]
109macro_rules! sizersub {
110 ($whatsit:ident, $body:block) => {
111 Rc::new(
112 |$whatsit: &Whatsit| -> Result<(Dimension, Dimension, Dimension)> {
113 let macro_out = $body;
114 macro_out
115 },
116 )
117 };
118}
119
120#[macro_export]
121macro_rules! rewrite_replace_sub {
122 ($document:ident, $nodes:ident, $body:block) => {
123 Some(Rc::new(
124 |$document: &mut Document, mut $nodes: Vec<&mut Node>| -> Result<()> {
125 $body
126 Ok(())
127 },
128 ))
129 };
130}
131
132#[macro_export]
133macro_rules! noreplacement {
134 () => {
135 |doc, whatsit, props| Ok(())
136 };
137}
138
139#[macro_export]
140macro_rules! replacement {
141 ($doc:ident, $args:ident, $props:ident, $body:block) => (
142 move |$doc:&mut Document,$args: &Vec<Option<Digested>>,
143 $props: &SymHashMap<Stored>| -> Result<()> {
144 $body
145 Ok(())
146 })
147}
148
149#[macro_export]
150macro_rules! construct {
151 ($doc:ident, $whatsit:ident, $body:block) => {
152 vec![Rc::new(
153 move |$doc: &mut Document, $whatsit: &Whatsit| -> Result<()> {
154 $body
155 Ok(())
156 }
157 )]
158}}
159
160#[macro_export]
161macro_rules! properties {
162 (sub [$args:ident] $body:block) => {
163 properties!($args, $body)
164 };
165 ($args:ident, $body:block) => {
166 Rc::new(move |mut $args: &Vec<Option<Digested>>| -> Result<SymHashMap<Stored>> { $body })
167 };
168 ($(sub)? $body:block) => {
169 Rc::new(
170 move |_args: &Vec<Option<Digested>>| -> Result<SymHashMap<Stored>> {
171 $body.into_properties_result()
172 },
173 )
174 };
175 ($value:expr_2021) => {
176 Rc::new(
177 move |_args: &Vec<Option<Digested>>| -> Result<SymHashMap<Stored>> { Ok($value.clone()) },
178 )
179 };
180}
181
182#[macro_export]
183macro_rules! after_digest {
184 ($(sub)? $body:block) => {
185 vec![after_digest_single!(_whatsit, $body)]
186 };
187 ($whatsit:ident, $body:block) => {
188 vec![after_digest_single!($whatsit, $body)]
189 };
190}
191
192#[macro_export]
193macro_rules! after_digest_single {
194 ($whatsit:ident, $body:block) => {
195 Rc::new(move |$whatsit: &mut Whatsit| -> Result<Vec<Digested>> { $body.into_digested_result() })
196 };
197}
198#[macro_export]
199macro_rules! after_digest_simple {
200 ($whatsit:ident, $body:block) => {
201 Rc::new(move |$whatsit: &mut Whatsit| -> Result<Vec<Digested>> { $body.into_digested_result() })
202 };
203}
204
205#[macro_export]
206macro_rules! reader {
207 ($inner:ident, $extra:ident, $body:block) => {
208 Rc::new(
209 |$inner: Option<&Parameters>, $extra: &[Tokens]| -> Result<ArgWrap> {
210 $body.into_result_argwrap()
211 },
212 )
213 };
214}
215
216#[macro_export]
217macro_rules! predigest {
218 ($arg:ident, $body:block) => {
219 Some(Rc::new(
220 |$arg: ArgWrap, _: &[Tokens]| -> Result<Option<Digested>> {
221 $body.into_digested_option_result()
222 },
223 ))
224 };
225 ($arg:ident, $extra:ident, $body:block) => {
226 Some(Rc::new(
227 |$arg: ArgWrap, $extra: &[Tokens]| -> Result<Option<Digested>> {
228 $body.into_digested_option_result()
229 },
230 ))
231 };
232}
233
234#[macro_export]
236macro_rules! getter {
237 ($args: ident, $body:block) => {
238 Some(Rc::new(
239 move |mut $args: Vec<ArgWrap>| -> Option<RegisterValue> {
240 $body.into_register_value_option()
241 },
242 ))
243 };
244}
245
246#[macro_export]
247macro_rules! setter {
248 ($value:ident, $args: ident, $body:block) => {
249 Some(Rc::new(
250 move |$value: RegisterValue, _scope: Option<Scope>, mut $args: Vec<ArgWrap>| $body,
251 ))
252 };
253 ($value:ident, $scope:ident, $args: ident, $body:block) => {
254 Some(Rc::new(
255 move |$value: RegisterValue, $scope: Option<Scope>, mut $args: Vec<ArgWrap>| $body,
256 ))
257 };
258}
259
260#[macro_export]
261macro_rules! reversion {
262 ($arg:ident, $inner:ident, $extra:ident, $body:block) => {
263 Some(Rc::new(
264 |mut $arg: Vec<Token>, $inner: Option<&Parameters>, $extra: &[Tokens]| -> Result<Tokens> {
265 $body
266 },
267 ))
268 };
269}
270
271#[macro_export]
272macro_rules! reversion_digested {
273 ($whatsit:ident, $args:ident, $body:block) => {
274 Some(Reversion::Closure(Rc::new(
275 move |$whatsit: &Whatsit, $args: &Vec<Option<Digested>>| -> Result<Tokens> { $body },
276 )))
277 };
278}
279
280#[macro_export]
286macro_rules! prop_digested {
287 ($props:ident, $key:expr_2021) => {
288 match $props.get($key) {
289 Some(Stored::VecDigested(vd)) => vd.iter().collect::<Vec<&Digested>>(),
290 Some(Stored::Digested(d)) => vec![&*d],
291 Some(Stored::String(s)) => panic!(
292 "prop_digested! called on a string property {:?} with value {:?}.",
293 $key, s
294 ),
295 None => Vec::new(),
296 other => {
297 $crate::common::error::emit_warn(
298 "unimplemented",
299 "prop_digested",
300 &format!("Please extend the api_macros::prop_digested macro to support: {other:?}"),
301 );
302 Vec::new()
304 },
305 }
306 };
307}
308
309#[macro_export]
319macro_rules! prop_str {
320 ($props:ident, $key:expr_2021) => {
321 match $props.get($key) {
322 Some(&Stored::String(ref id)) => *id,
323 _ => pin!(""),
324 }
325 };
326}
327
328#[macro_export]
329macro_rules! prop_string {
330 ($props:ident, $key:expr_2021) => {
331 match $props.get($key) {
332 Some(&Stored::String(id)) => arena::to_string(id),
333 _ => String::new(),
334 }
335 };
336}
337
338#[macro_export]
339macro_rules! prop_whatsit {
340 ($props:ident, $key:expr_2021) => {
341 match $props.get($key) {
342 Some(&Stored::Digested(ref rc)) => (**rc).clone(),
344 _ => Digested::Whatsit(Rc::new(RefCell::new(Whatsit::default()))),
345 }
346 };
347}
348
349#[macro_export]
350macro_rules! prop_bool {
351 ($props:ident, $key:expr_2021) => {
352 match $props.get($key) {
353 Some(&Stored::Bool(v)) => v,
354 _ => false,
355 }
356 };
357}
358
359#[macro_export]
362macro_rules! unref {
363 ($args:ident => $var:ident) => (count_unpack_ref!(0usize, $args => $var));
364 ($args:ident => $var:ident,$($tail:ident),*) => (
365 count_unpack_ref!(0usize,$args => $var,$($tail),*))
366}
367#[macro_export]
368macro_rules! count_unpack_ref {
369 ($index:expr_2021, $args:ident => $var:ident) => {
370 let $var = $args[$index].as_ref().unwrap();
371 };
372 ($index:expr_2021, $args:ident => $var:ident,$($tail:ident),*) => {
373 count_unpack_ref!($index,$args => $var);
374 count_unpack_ref!(1usize+$index, $args => $($tail),*)
375 };
376}
377
378#[macro_export]
380macro_rules! unpack_opt {
381 ($args:ident => $arg1:ident) => {
382 let [$arg1]: [_; 1] = $args.try_into().unwrap();
383 };
384 ($args:ident => $arg1:ident,$arg2:ident) => {
385 let [$arg1, $arg2]: [_; 2] = $args.try_into().unwrap();
386 };
387 ($args:ident => $arg1:ident,$arg2:ident,$arg3:ident) => {
388 let [$arg1, $arg2, $arg3]: [_; 3] = $args.try_into().unwrap();
389 };
390 ($args:ident => $arg1:ident,$arg2:ident,$arg3:ident,$arg4:ident) => {
391 let [$arg1, $arg2, $arg3, $arg4]: [_; 4] = $args.try_into().unwrap();
392 };
393 ($args:ident => $arg1:ident,$arg2:ident,$arg3:ident,$arg4:ident,$arg5:ident) => {
394 let [$arg1, $arg2, $arg3, $arg4, $arg5]: [_; 5] = $args.try_into().unwrap();
395 };
396}
397
398#[macro_export]
400macro_rules! unpack_opt_ref {
401 ($args:ident => $arg1:ident) => {
402 let [$arg1]: &[_; 1] = $args[..1].try_into().unwrap();
403 };
404 ($args:ident => $arg1:ident,$arg2:ident) => {
405 let [$arg1, $arg2]: &[_; 2] = $args[..2].try_into().unwrap();
406 };
407 ($args:ident => $arg1:ident,$arg2:ident,$arg3:ident) => {
408 let [$arg1, $arg2, $arg3]: &[_; 3] = $args[..3].try_into().unwrap();
409 };
410 ($args:ident => $arg1:ident,$arg2:ident,$arg3:ident,$arg4:ident) => {
411 let [$arg1, $arg2, $arg3, $arg4]: &[_; 4] = $args[..4].try_into().unwrap();
412 };
413 ($args:ident => $arg1:ident,$arg2:ident,$arg3:ident,$arg4:ident,$arg5:ident) => {
414 let [$arg1, $arg2, $arg3, $arg4, $arg5]: &[_; 5] = $args[..5].try_into().unwrap();
415 };
416}
417
418#[macro_export]
420macro_rules! roman {
421 ($stuff:expr_2021) => {
422 Tokens::new(ExplodeText!(roman_aux($stuff as i64)))
423 };
424}
425#[macro_export]
427macro_rules! Roman {
428 ($stuff:expr_2021) => {
429 Tokens::new(ExplodeText!(roman_aux($stuff as i64).to_ascii_uppercase()))
430 };
431}
432
433#[macro_export]
434macro_rules! requireMath {
435 ($cs_name:expr_2021) => {
436 if !$crate::state::lookup_bool_sym($crate::pin!("IN_MATH")) {
437 let message = s!("{} should only appear in math mode", $cs_name);
438 Warn!("unexpected", "mode", message);
439 }
440 };
441}
442#[macro_export]
443macro_rules! forbidMath {
444 ($cs_name:expr_2021) => {
445 if $crate::state::lookup_bool_sym($crate::pin!("IN_MATH")) {
446 let message = s!("{} should not appear in math mode", $cs_name);
447 Warn!("unexpected", "mode", message);
448 }
449 };
450}
451
452#[macro_export]
453macro_rules! AssignRegister {
454 ($cs:literal, $value:expr_2021) => {
455 AssignRegister!($cs, $value, Vec::new())
456 };
457 ($cs:literal, $value:expr_2021, $args:expr_2021) => {
458 let value_ident = { $value };
459 if let Some(defn) = state::lookup_register_definition(&T_CS!($cs)) {
460 (*defn).set_value(value_ident, None, $args);
461 } else {
462 let message = s!("The control sequence {} is not a register", $cs);
463 Warn!("expected", "register", message);
464 }
465 };
466}
467
468#[macro_export]
469macro_rules! SetCounter {
470 ($ctr:expr_2021 => $value:expr_2021) => {
471 SetCounter!($ctr, $value)
472 };
473 ($ctr:expr_2021, $value:expr_2021) => {
474 state::assign_register(
475 &s!("\\c@{}", $ctr),
476 $value.into(),
477 Some(Scope::Global),
478 Vec::new(),
479 )?;
480 after_assignment();
481 def_macro(
482 T_CS!(s!("\\@{}@ID", $ctr)),
483 None,
484 Tokens::new(Explode!($value.value_of())),
485 Some(ExpandableOptions {
486 scope: Some(Scope::Global),
487 ..ExpandableOptions::default()
488 }),
489 )?;
490 };
491}