mod class_list;
mod source_location;
use core::fmt;
use crate::define_environment::EnvSpec;
use crate::define_function::FunctionSpec;
use crate::namespace::KeyMap;
use crate::parser::parse_node::NodeType;
use crate::utils::escape_into;
use rapidhash::HashMapExt as _;
pub use source_location::{LexerInterface, SourceLocation};
use strum::AsRefStr;
use strum::Display;
use strum::EnumCount;
use strum::EnumIter;
use strum::EnumString;
mod parse_error;
pub use parse_error::{ErrorLocationProvider, ParseError, ParseErrorKind};
use strum::FromRepr;
mod tokens;
pub use crate::symbols::Mode;
pub use class_list::ClassList;
pub use tokens::{Token, TokenText};
mod settings;
pub use settings::{
OutputFormat, Settings, StrictFunction, StrictMode, StrictReturn, StrictSetting, TrustContext,
TrustFunction, TrustSetting,
};
pub use source_location::SourceRangeRef;
#[derive(
EnumIter,
Debug,
Copy,
AsRefStr,
PartialEq,
Eq,
Hash,
Clone,
Display,
EnumCount,
FromRepr,
Ord,
PartialOrd,
)]
#[strum(serialize_all = "kebab-case")]
#[repr(u8)]
pub enum CssProperty {
BackgroundColor,
BorderBottomWidth,
BorderColor,
BorderRightStyle,
BorderRightWidth,
BorderTopWidth,
BorderStyle,
BorderWidth,
Bottom,
Color,
Height,
Left,
Margin,
MarginLeft,
MarginRight,
MarginTop,
MinWidth,
PaddingLeft,
Position,
TextShadow,
Top,
Width,
VerticalAlign,
}
#[derive(Clone, PartialEq, Eq, Default)]
pub struct CssStyle {
map: KeyMap<CssProperty, String>,
}
impl fmt::Debug for CssStyle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut ds = f.debug_struct("CssStyle");
let mut entries: Vec<(&CssProperty, &String)> = self.map.iter().collect();
entries.sort_by_key(|(k, _)| *k);
for (key, value) in entries {
ds.field(key.as_ref(), value);
}
ds.finish()
}
}
impl fmt::Display for CssStyle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.write_to(f)
}
}
impl CssStyle {
#[inline]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
map: KeyMap::with_capacity(capacity),
}
}
#[inline]
pub fn insert<T>(&mut self, property: CssProperty, value: T)
where
T: Into<String>,
{
self.map.insert(property, value.into());
}
#[inline]
#[must_use]
pub fn contains_key(&self, property: CssProperty) -> bool {
self.map.contains_key(&property)
}
#[inline]
#[must_use]
pub fn get(&self, property: CssProperty) -> Option<&str> {
self.map.get(&property).map(AsRef::as_ref)
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn write_to<W: fmt::Write>(&self, writer: &mut W) -> fmt::Result {
for (key, value) in &self.map {
writer.write_str(key.as_ref())?;
writer.write_char(':')?;
escape_into(writer, value)?;
writer.write_char(';')?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArgType {
Color,
Size,
Url,
Raw,
Original,
Hbox,
Primitive,
Mode(Mode),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsRefStr)]
#[strum(serialize_all = "lowercase")]
pub enum StyleVariant {
Text,
Display,
Script,
ScriptScript,
}
#[derive(Debug, Clone, PartialEq, Eq, EnumString, AsRefStr)]
pub enum BreakToken {
#[strum(serialize = "]")]
RightBracket,
#[strum(serialize = "}")]
RightBrace,
#[strum(serialize = "\\endgroup")]
EndGroup,
#[strum(serialize = "$")]
Dollar,
#[strum(serialize = "\\)")]
RightParen,
#[strum(serialize = "\\\\")]
DoubleBackslash,
#[strum(serialize = "\\end")]
End,
#[strum(serialize = "EOF")]
Eof,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FontVariant {
Bold,
BoldItalic,
BoldSansSerif,
DoubleStruck,
Fraktur,
Italic,
Monospace,
Normal,
SansSerif,
SansSerifBoldItalic,
SansSerifItalic,
Script,
}
pub trait Spec {
fn num_args(&self) -> usize;
fn num_optional_args(&self) -> usize;
fn arg_types(&self) -> Option<&Vec<ArgType>>;
fn primitive(&self) -> bool;
fn node_type(&self) -> Option<&NodeType>;
}
impl Spec for FunctionSpec {
fn num_args(&self) -> usize {
self.num_args
}
fn num_optional_args(&self) -> usize {
self.num_optional_args
}
fn arg_types(&self) -> Option<&Vec<ArgType>> {
self.arg_types.as_ref()
}
fn primitive(&self) -> bool {
self.primitive
}
fn node_type(&self) -> Option<&NodeType> {
self.node_type.as_ref()
}
}
impl Spec for EnvSpec {
fn num_args(&self) -> usize {
self.num_args
}
fn num_optional_args(&self) -> usize {
self.num_optional_args
}
fn arg_types(&self) -> Option<&Vec<ArgType>> {
self.arg_types.as_ref()
}
fn primitive(&self) -> bool {
false
}
fn node_type(&self) -> Option<&NodeType> {
Some(&self.node_type)
}
}