use core::fmt::Write;
use crate::{
env::LatexEnvironment,
fmt::{LatexFormatter, write_latex, WriteAsLatex},
lin_sys::{env::CasesEnvironment, unknowns::Unknowns, LinSys}, latex_modes::{CategorizedLatexModeKindExt, MathLatexMode, CategoryEnumVariantExt, MathLatexModeKind, ControlSeqDelimited, CategorizedLatexModeKind},
};
use nalgebra::{Dim, RawStorage};
pub struct PlainLinSysFormatter;
pub struct CasesLinSysFormatter;
impl<IM,OM,T,R,C,S,U> LatexFormatter<IM,OM,LinSys<T, R, C, S, U>> for PlainLinSysFormatter
where
IM: CategorizedLatexModeKindExt,
OM: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind>,
T: WriteAsLatex<OM>,
R: Dim,
C: Dim,
S: RawStorage<T, R, C>,
U: Unknowns,
{
fn write_latex<W: Write>(
dest: &mut W,
input: &LinSys<T, R, C, S, U>,
) -> Result<(), core::fmt::Error> {
let nrows = input.matrix.nrows();
let ncols = input.matrix.ncols();
for i in 0..nrows {
for j in 0..ncols {
input.matrix[(i, j)].write_as_latex(dest)?;
unsafe { input.unknowns.write_latex_for_ith_unchecked::<OM,_>(dest, j) }?;
if j != ncols - 1 {
write!(dest, "+")?;
}
}
if i != nrows - 1 {
write!(dest, r"\\")?;
}
}
Ok(())
}
}
impl<IM,OM,T,R,C,S,U> LatexFormatter<IM,OM,LinSys<T, R, C, S, U>> for CasesLinSysFormatter
where
IM: CategorizedLatexModeKindExt,
OM: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind> + ControlSeqDelimited + CategorizedLatexModeKindExt,
T: WriteAsLatex<OM>,
R: Dim,
C: Dim,
S: RawStorage<T, R, C>,
U: Unknowns,
{
fn write_latex<W: core::fmt::Write>(
dest: &mut W,
input: &LinSys<T, R, C, S, U>,
) -> Result<(), core::fmt::Error> {
use CategorizedLatexModeKind::*;
let is_delimiting_required = match IM::CATEGORIZED_KIND {
eq if eq == Math(OM::CATEGORY_ENUM_VARIANT) => Ok(false),
Math(_) => Err(core::fmt::Error),
_ => Ok(true),
}?;
if is_delimiting_required {
OM::write_opening_control_seq(dest)?;
}
CasesEnvironment::write_opening_tag(dest)?;
write_latex::<PlainLinSysFormatter,OM,OM,_,_>(dest, input)?;
CasesEnvironment::write_closing_tag(dest)?;
if is_delimiting_required {
OM::write_closing_control_seq(dest)?;
}
Ok(())
}
}