aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2017-01-14 19:37:09 -0800
committerbnewbold <bnewbold@robocracy.org>2017-01-14 19:52:56 -0800
commita71465e935a178478d269e828550b7e3fc475fab (patch)
tree62e501dea9e40d9cd50dfc35753654b4c1e0e40e
parent11569fdec123e9c7aeaf38d8a122842c4c758fdf (diff)
downloadmodelthing-a71465e935a178478d269e828550b7e3fc475fab.tar.gz
modelthing-a71465e935a178478d269e828550b7e3fc475fab.zip
basic LaTeX transpiling
-rw-r--r--src/lib.rs1
-rw-r--r--src/transpile_js.rs2
-rw-r--r--src/transpile_latex.rs99
3 files changed, 101 insertions, 1 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 4c32d66..cf88d3b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,6 +11,7 @@ pub extern crate modelica_parser;
pub mod modelica_model;
pub mod transpile_scheme;
pub mod transpile_js;
+pub mod transpile_latex;
use std::path::Path;
use std::fs;
diff --git a/src/transpile_js.rs b/src/transpile_js.rs
index 269e900..4150b12 100644
--- a/src/transpile_js.rs
+++ b/src/transpile_js.rs
@@ -57,7 +57,7 @@ impl TranspileJS for Expr {
BinExpr(op, ref l, ref r) => {
Ok(format!("({} {:?} {})", try!(l.repr_js()), op, try!(r.repr_js())))
}
- Array(_) => bail!("Array unimplemented"),
+ Array(_) => unimplemented!(),
}
}
}
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!(),
+ }
+ }
+}