diff options
| author | bnewbold <bnewbold@robocracy.org> | 2017-01-14 19:37:09 -0800 | 
|---|---|---|
| committer | bnewbold <bnewbold@robocracy.org> | 2017-01-14 19:52:56 -0800 | 
| commit | a71465e935a178478d269e828550b7e3fc475fab (patch) | |
| tree | 62e501dea9e40d9cd50dfc35753654b4c1e0e40e /src/transpile_latex.rs | |
| parent | 11569fdec123e9c7aeaf38d8a122842c4c758fdf (diff) | |
| download | modelthing-a71465e935a178478d269e828550b7e3fc475fab.tar.gz modelthing-a71465e935a178478d269e828550b7e3fc475fab.zip  | |
basic LaTeX transpiling
Diffstat (limited to 'src/transpile_latex.rs')
| -rw-r--r-- | src/transpile_latex.rs | 99 | 
1 files changed, 99 insertions, 0 deletions
diff --git a/src/transpile_latex.rs b/src/transpile_latex.rs new file mode 100644 index 0000000..1c777d2 --- /dev/null +++ b/src/transpile_latex.rs @@ -0,0 +1,99 @@ + +extern crate modelica_parser; + +use self::modelica_parser::*; +use errors::Result; + +pub trait TranspileLaTeX { +    fn repr_latex(&self) -> Result<String>; +} + + +impl TranspileLaTeX for ModelicaModel { +    fn repr_latex(&self) -> Result<String> { + +        let mut result = r#"\begin{array}{rcl}"#.to_string() + "\n"; + +        for eq in &self.equations { +            result += &format!("  {} & = & {} \\\\\n", +                try!(eq.lhs.repr_latex()), +                try!(eq.rhs.repr_latex())); +        } +        result += "\n"; +        result += r#"\end{array}"#; +        Ok(result) +    } +} + +fn is_latexy_ident(s: &str) -> bool { +    let latexy_idents = [ +        "alpha", "Alpha", "beta", "gamma", "Gamma", "delta", "Delta", +        "epsilon", "zeta", "eta", "theta", "Theta", "iota", "kappa", "lambda", +        "Lambda", "mu", "nu", "xi", "Xi", "omicron", "pi", "Pi", "rho", +        "sigma", "Sigma", "tau", "upsilon", "phi", "Phi", "chi", "psi", "Psi", +        "omega", "Omega"]; +    latexy_idents.contains(&s) +} + +impl TranspileLaTeX for Expr { +    fn repr_latex(&self) -> Result<String> { +        use modelica_parser::Expr::*; +        use modelica_parser::MathUnaryFunc::*; +        use modelica_parser::BinOperator::*; +        match *self { +            Integer(e) => Ok(format!("{}", e)), +            Float(e) => Ok(format!("{}", e)), +            Boolean(true) => Ok(format!("true")), +            Boolean(false) => Ok(format!("false")), +            StringLiteral(ref s) => Ok(format!("\\text{{ {} }}", s)), +            // Tries to do script for simple cases ("M_1") +            Ident(ref e) => { +                if e.contains('_') { +                    let split: Vec<&str> = e.splitn(2, '_').collect(); +                    Ok(format!(r"{}{}_{{ {}{} }}", +                        if is_latexy_ident(split[0]) { "\\" } else { "" }, +                        split[0], +                        if is_latexy_ident(split[1]) { "\\" } else { "" }, +                        split[1])) +                } else { +                    Ok(format!("{}{}", +                        if is_latexy_ident(e) { "\\" } else { "" }, +                        e)) +                } +            }, +            // Treate simple derivatives (common case) differently from complex +            // (destructuring with 'box' keyword is still unstable) +            Der(ref e) => +                if let &Ident(_) = e.as_ref() { +                    Ok(format!("\\frac{{ d {} }}{{ dt }}", try!(e.repr_latex()))) +                } else { +                    Ok(format!("\\frac{{ d }}{{ dt }} {}", try!(e.repr_latex()))) +                }, +            Sign(ref e) => Ok(format!("\\sign{{ {} }}", try!(e.repr_latex()))), +            // LaTeX depends on the unary +            MathUnaryExpr(Abs, ref e) => Ok(format!("\\left\\|{}\\right\\|", try!(e.repr_latex()))), +            MathUnaryExpr(Sqrt, ref e) => Ok(format!("\\sqrt{{ {} }}", try!(e.repr_latex()))), +            MathUnaryExpr(Log10, ref e) => Ok(format!("\\log_{{10}}{{ {} }} ", try!(e.repr_latex()))), +            MathUnaryExpr(func, ref e) => Ok(format!("\\{:?}{{ {} }}", func, try!(e.repr_latex()))), +            // LaTeX depends on binexpr +            BinExpr(Divide, ref l, ref r) =>  +                Ok(format!("\\frac{{ {} }}{{ {} }}", +                        try!(l.repr_latex()), +                        try!(r.repr_latex()))), +            BinExpr(Multiply, ref l, ref r) => +                Ok(format!("{} \\cdot {}", +                        try!(l.repr_latex()), +                        try!(r.repr_latex()))), +            BinExpr(Exponentiate, ref l, ref r) => +                Ok(format!("{}^{{ {} }}", +                        try!(l.repr_latex()), +                        try!(r.repr_latex()))), +            BinExpr(op, ref l, ref r) => +                Ok(format!("\\left({} {:?} {}\\right)", +                        try!(l.repr_latex()), +                        op, +                        try!(r.repr_latex()))), +            Array(_) => unimplemented!(), +        } +    } +}  | 
