pub mod tex;
pub mod etex;
pub mod pdftex;
pub mod methods;
use std::fmt::{Debug, Formatter};
use crate::engine::mouth::Mouth;
use crate::engine::state::State;
use crate::tex::catcodes::CategoryCode;
use crate::tex::token::Token;
use crate::utils::errors::TeXError;
use crate::utils::Ptr;
use crate::utils::strings::CharType;
#[derive(Clone,PartialEq)]
pub enum Command<T:Token>{
Def(Def<T>),
Stomach{name:&'static str,index:usize},
AssignableValue{name:&'static str,tp:Assignable},
Value{name:&'static str,index:usize,tp:Assignable},
ValueRegister{index:usize,tp:Assignable},
ValueAssignment{name:&'static str,assignment_index:usize,value_index:usize,tp:Assignable},
Assignment{name:&'static str,index:usize},
Conditional{name:&'static str,index:usize},
Gullet{name:&'static str,index:usize},
Char{char:T::Char,catcode:CategoryCode},
Whatsit {name:&'static str,index:usize},
Relax
}
#[derive(Copy,Clone,Debug,PartialEq)]
pub enum Assignable {
Int,Dim,Glue,MuGlue,Font,Toks
}
impl<T:Token> Debug for Command<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Command::Def(def) => <Def<T> as Debug>::fmt(def,f),
Command::ValueRegister{index,tp} => write!(f, "{:?} register {}",tp, index),
Command::Relax => write!(f, "Relax"),
Command::Stomach {name,..} => write!(f, "Stomach Command {}", name),
Command::ValueAssignment {name,tp,..} => write!(f, "{:?} Assignment {}", tp, name),
Command::Assignment {name,..} => write!(f, "Assignment {}", name),
Command::AssignableValue {name,tp,..} => write!(f, "{:?} Assignment {}",tp,name),
Command::Conditional{name,..} => write!(f, "Conditional {}", name),
Command::Gullet{name,..} => write!(f, "Gullet Command {}", name),
Command::Char{char,catcode} => write!(f, "Character '{}' (catcode {})", (char as &T::Char).char_str(), catcode),
Command::Value {name,tp,..} => write!(f, "{:?} Command {}",tp, name),
Command::Whatsit {name,index} => write!(f,"Whatsit {}",name),
}
}
}
#[derive(Debug,Clone)]
pub struct StomachCommand<T:Token>{pub cause:T,pub cmd:StomachCommandInner<T::Char>}
#[derive(Clone)]
pub enum StomachCommandInner<C:CharType> {
Command{name:&'static str,index:usize},
AssignableValue{name:&'static str,tp:Assignable},
Value{name:&'static str,index:usize,tp:Assignable},
ValueRegister(usize,Assignable),
ValueAssignment{name:&'static str,assignment_index:usize,value_index:usize,tp:Assignable},
Assignment {name:&'static str,index:usize},
Whatsit {name:&'static str,index:usize},
Relax,
Char(C,bool),
Superscript,
Subscript,
Space,
MathShift,
BeginGroup,
EndGroup
}
#[derive(Debug,Clone)]
pub struct GulletCommand<T:Token>{pub cause:T}
impl<C:CharType> Debug for StomachCommandInner<C> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StomachCommandInner::Relax => write!(f,"Relax"),
StomachCommandInner::Command{name,..} => write!(f,"\\{}",name),
StomachCommandInner::ValueAssignment {name,..} => write!(f, "\\{}", name),
StomachCommandInner::Assignment {name,..} => write!(f, "\\{}", name),
StomachCommandInner::Value{name,tp,..} => write!(f,"\\{}",name),
StomachCommandInner::AssignableValue {name,tp,..} => write!(f, "{:?} Assignment {}",tp,name),
StomachCommandInner::ValueRegister(u,tp) => write!(f, "{:?} register {}",tp, u),
StomachCommandInner::Whatsit {name,index} => write!(f,"Whatsit {}",name),
StomachCommandInner::Char(c,_) => write!(f,"Character '{}'",c),
StomachCommandInner::Superscript => write!(f,"Superscript Token"),
StomachCommandInner::Subscript => write!(f,"Subscript Token"),
StomachCommandInner::Space => write!(f,"Space Token"),
StomachCommandInner::MathShift => write!(f,"MathShift Token"),
StomachCommandInner::BeginGroup => write!(f,"BeginGroup Token"),
StomachCommandInner::EndGroup => write!(f,"EndGroup Token")
}
}
}
#[derive(PartialEq,Clone)]
pub struct Def<T:Token>{
pub protected:bool,
pub long:bool,
pub outer:bool,
pub endswithbrace:bool,
pub arity:u8,
pub signature:Vec<ParamToken<T>>,
pub replacement:Vec<ExpToken<T>>
}
impl<T:Token> Def<T>{
pub fn expand<M:Mouth<T>,S:State<T>>(&self, state:&S, mouth:&mut M, cmd:Ptr<Command<T>>, cause:Ptr<T>) -> Result<Vec<T>,Box<dyn TeXError<T>>> {
methods::exand_def(self,state,mouth,cmd,cause)
}
}
impl<T:Token> Debug for Def<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f,"{:?}{{{:?}}}",self.signature,self.replacement)
}
}
#[derive(Clone,PartialEq)]
pub enum ParamToken<T:Token> {
Param,
Token(T)
}
impl<T:Token> Debug for ParamToken<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Param => write!(f,"#i"),
Self::Token(t) => write!(f,"{}",t)
}
}
}
#[derive(Clone,PartialEq)]
pub enum ExpToken<T:Token> {
Param(T,u8),
Token(T),
ParamToken(T)
}
impl<T:Token> Debug for ExpToken<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Param(t,u8) => write!(f,"{}{}",t,u8),
Self::Token(t) => write!(f,"{}",t),
Self::ParamToken(t) => write!(f,"{}{}",t,t)
}
}
}