flams_stex/quickparse/latex/
directives.rs1use 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}