1use std::char;
4use std::convert::TryInto;
5use texlang::traits::*;
6use texlang::*;
7
8pub const THE_DOC: &str = "Output text describing some inputted tokens";
9
10pub fn get_the<S: TexlangState>() -> command::BuiltIn<S> {
12 command::BuiltIn::new_expansion(the_primitive_fn)
13}
14
15fn the_primitive_fn<S: TexlangState>(
16 the_token: token::Token,
17 input: &mut vm::ExpansionInput<S>,
18) -> command::Result<Vec<token::Token>> {
19 let token = match input.next()? {
21 None => return Err(error::SimpleEndOfInputError::new(input.vm(), "TODO").into()),
22 Some(token) => token,
23 };
24 Ok(match &token.value() {
25 token::Value::ControlSequence(name) => {
26 if let Some(command::Command::Variable(cmd)) = input.commands_map().get_command(name) {
27 match cmd.clone().value(token, input.as_mut())? {
28 variable::ValueRef::Int(i) => int_to_tokens(the_token, *i),
29 variable::ValueRef::CatCode(i) => int_to_tokens(the_token, (*i as u8).into()),
30 }
31 } else {
32 vec![token]
34 }
35 }
36 _ => vec![token],
38 })
39}
40
41fn int_to_tokens(the_token: token::Token, mut i: i32) -> Vec<token::Token> {
42 if i == 0 {
43 return vec![token::Token::new_other('0', the_token.trace_key())];
44 }
45 let negative = i < 0;
46 let mut tokens = Vec::new();
49 while i != 0 {
50 let digit = (i % 10).abs();
51 tokens.push(token::Token::new_other(
52 char::from_digit(digit.try_into().unwrap(), 10).unwrap(),
53 the_token.trace_key(),
54 ));
55 i /= 10;
56 }
57 if negative {
58 tokens.push(token::Token::new_other('-', the_token.trace_key()));
59 }
60 tokens.reverse();
61 tokens
62}