Skip to main content

flams_stex/quickparse/latex/
directives.rs

1use std::borrow::Cow;
2
3use flams_utils::{
4    parsing::{SourceParser, StringOrStr},
5    sourcerefs::StringPosition,
6};
7
8use crate::quickparse::stex::DiagnosticLevel;
9
10use super::{
11    AnyEnv, AnyMacro, Environment, EnvironmentResult, FromLaTeXToken, LaTeXParser, Macro,
12    MacroResult, ParserState,
13    rules::{DynEnv, DynMacro},
14};
15
16#[allow(clippy::needless_pass_by_value)]
17pub fn copycmd<
18    'a,
19    Pos: StringPosition,
20    T: FromLaTeXToken<'a, Pos>,
21    State: ParserState<'a, Pos, T>,
22>(
23    parser: &mut LaTeXParser<'a, Pos, T, State>,
24    args: &'a str,
25) {
26    if let Some((a, b)) = args.split_once(' ') {
27        let a = a.trim();
28        let b = b.trim();
29        let old = parser.macro_rules.get(b);
30        parser.add_macro_rule(Cow::Owned(a.to_string()), old.cloned());
31    }
32}
33
34#[allow(clippy::needless_pass_by_value)]
35pub fn verbcmd<
36    'a,
37    Pos: StringPosition,
38    T: FromLaTeXToken<'a, Pos>,
39    State: ParserState<'a, Pos, T>,
40>(
41    parser: &mut LaTeXParser<'a, Pos, T, State>,
42    args: &'a str,
43) {
44    if !args.is_empty() {
45        parser.add_macro_rule(
46            args.trim().as_cow(),
47            Some(AnyMacro::Ptr(super::rules::lstinline as _)),
48        );
49    }
50}
51
52#[allow(clippy::needless_pass_by_value)]
53pub fn verbenv<
54    'a,
55    Pos: StringPosition,
56    T: FromLaTeXToken<'a, Pos>,
57    State: ParserState<'a, Pos, T>,
58>(
59    parser: &mut LaTeXParser<'a, Pos, T, State>,
60    args: &'a str,
61) {
62    if !args.is_empty() {
63        parser.add_environment_rule(
64            args.trim().as_cow(),
65            Some(AnyEnv::Ptr((
66                super::rules::general_listing_open as _,
67                super::rules::general_listing_close as _,
68            ))),
69        );
70    }
71}
72
73pub fn macro_dir<
74    'a,
75    Pos: StringPosition,
76    T: FromLaTeXToken<'a, Pos>,
77    State: ParserState<'a, Pos, T>,
78>(
79    parser: &mut LaTeXParser<'a, Pos, T, State>,
80    args: &'a str,
81) {
82    if !args.is_empty()
83        && let Some((m, _)) = args.split_once(' ')
84    {
85        let len = m.len();
86        let (m, mut spec) = args.split_n(len);
87        spec.trim_ws();
88        parser.add_macro_rule(
89            m.trim().as_cow(),
90            Some(AnyMacro::Str(DynMacro {
91                ptr: do_macro_dir as _,
92                arg: spec,
93            })),
94        );
95    }
96}
97
98fn do_macro_dir<
99    'a,
100    Pos: StringPosition,
101    T: FromLaTeXToken<'a, Pos>,
102    State: ParserState<'a, Pos, T>,
103>(
104    arg: &&'a str,
105    mut m: Macro<'a, Pos>,
106    parser: &mut LaTeXParser<'a, Pos, T, State>,
107) -> MacroResult<'a, Pos, T> {
108    do_spec(arg, &mut m, parser);
109    MacroResult::Simple(m)
110}
111
112#[inline]
113fn do_spec<'a, Pos: StringPosition, T: FromLaTeXToken<'a, Pos>, State: ParserState<'a, Pos, T>>(
114    spec: &str,
115    m: &mut Macro<'a, Pos>,
116    parser: &mut LaTeXParser<'a, Pos, T, State>,
117) {
118    for c in spec.as_bytes() {
119        match *c {
120            b'v' => parser.skip_arg(m),
121            _ => parser.tokenizer.problem(
122                m.range.start,
123                format!("Unknown arg spec {c}"),
124                DiagnosticLevel::Error,
125            ),
126        }
127    }
128}
129
130pub fn env_dir<
131    'a,
132    Pos: StringPosition,
133    T: FromLaTeXToken<'a, Pos>,
134    State: ParserState<'a, Pos, T>,
135>(
136    parser: &mut LaTeXParser<'a, Pos, T, State>,
137    args: &'a str,
138) {
139    if !args.is_empty()
140        && let Some((m, _)) = args.split_once(' ')
141    {
142        let len = m.len();
143        let (m, mut spec) = args.split_n(len);
144        spec.trim_ws();
145        parser.add_environment_rule(
146            m.as_cow(),
147            Some(AnyEnv::Str(DynEnv {
148                open: do_env_dir as _,
149                close: do_env_dir_close as _,
150                arg: spec,
151            })),
152        );
153    }
154}
155
156fn do_env_dir<
157    'a,
158    'b,
159    'c,
160    Pos: StringPosition,
161    T: FromLaTeXToken<'a, Pos>,
162    State: ParserState<'a, Pos, T>,
163>(
164    arg: &&'a str,
165    e: &'b mut Environment<'a, Pos, T>,
166    parser: &'c mut LaTeXParser<'a, Pos, T, State>,
167) {
168    do_spec(arg, &mut e.begin, parser);
169}
170
171const fn do_env_dir_close<
172    'a,
173    'b,
174    Pos: StringPosition,
175    T: FromLaTeXToken<'a, Pos>,
176    State: ParserState<'a, Pos, T>,
177>(
178    e: Environment<'a, Pos, T>,
179    _: &'b mut LaTeXParser<'a, Pos, T, State>,
180) -> EnvironmentResult<'a, Pos, T> {
181    EnvironmentResult::Simple(e)
182}
183
184pub fn nolint<
185    'a,
186    Pos: StringPosition,
187    T: FromLaTeXToken<'a, Pos>,
188    State: ParserState<'a, Pos, T>,
189>(
190    parser: &mut LaTeXParser<'a, Pos, T, State>,
191    _: &'a str,
192) {
193    parser.tokenizer.reader.read_until_str("%%STEXIDE dolint");
194}
195
196#[inline]
197pub const fn dolint<
198    'a,
199    Pos: StringPosition,
200    T: FromLaTeXToken<'a, Pos>,
201    State: ParserState<'a, Pos, T>,
202>(
203    _: &mut LaTeXParser<'a, Pos, T, State>,
204    _: &'a str,
205) {
206}