flams_stex/quickparse/latex/
directives.rs

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