texlang/parse/
keyword.rs

1use crate::prelude as txl;
2use crate::token;
3use crate::traits::*;
4use crate::vm;
5
6/// Parses a keyword from the input stream.
7///
8/// TeX.2021.407 scan_keyword
9pub fn parse_keyword<S: TexlangState>(
10    input: &mut vm::ExpandedStream<S>,
11    keyword: &str,
12) -> txl::Result<bool> {
13    let Some(c) = keyword.chars().next() else {
14        // keyword is empty
15        return Ok(true);
16    };
17    let Some(token) = input.next()? else {
18        // input ended, keyword does not match
19        return Ok(false);
20    };
21    if token.value() != token::Value::Letter(c.to_ascii_lowercase())
22        && token.value() != token::Value::Letter(c.to_ascii_uppercase())
23    {
24        input.back(token);
25        return Ok(false);
26    }
27    // this character matched; now try to match the result of keyword
28    let result = parse_keyword(input, &keyword[c.len_utf8()..]);
29    if let Ok(false) = result {
30        // some later character did not match, reverse consuming the token.
31        input.back(token);
32    }
33    result
34}