1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//! A crate for generating LaTeX documents programatically. //! //! The main purpose of this library is to make the job of programatically //! generating LaTeX reports and documents (which will probably then be //! compiled to PDF) as easy as possible. //! //! This library tries to use Rust's powerful type system to give your document //! additional semantic meaning and compile-time typesafety. For example, //! [`Element::ClearPage`] could easily be implemented using //! `Element::UserDefined(r"\clearpage")`, however it is common enough to //! justify its own variant to make the generating code easier to read. //! //! //! # Examples //! //! Here's how to create a basic document containing a title page, a table of //! contents, and two sections. //! //! ```rust //! use latex::{DocumentClass, Element, Document, Section, Renderable}; //! //! # fn run() -> latex::Result<()> { //! let mut doc = Document::new(DocumentClass::Article); //! //! // Set some metadata for the document //! doc.preamble.title("My Fancy Document"); //! doc.preamble.author("Michael-F-Bryan"); //! //! doc.push(Element::TitlePage) //! .push(Element::ClearPage) //! .push(Element::TableOfContents) //! .push(Element::ClearPage); //! //! let mut section_1 = Section::new("Section 1"); //! section_1.push("Here is some text which will be put in paragraph 1.") //! .push("And here is some more text for paragraph 2."); //! doc.push(section_1); //! //! let mut section_2 = Section::new("Section 2"); //! section_2.push("More text..."); //! doc.push(section_2); //! //! let mut buffer = Vec::new(); //! doc.render(&mut buffer)?; //! //! let rendered = String::from_utf8(buffer)?; //! # Ok(()) //! # } //! # fn main() { //! # run().unwrap(); //! # } //! ``` //! //! This will generate the LaTeX source for you, so all you need to do now is //! write it to a file and then run your favourite tex build tool on it (I //! personally use [latexmk]). //! //! ```rust,no_run //! use std::fs::File; //! use std::io::Write; //! use std::process::Command; //! //! # fn run() -> latex::Result<()> { //! # let rendered = String::new(); //! // Write our rendered text to a file //! let mut f = File::open("report.tex")?; //! write!(f, "{}", rendered)?; //! //! // Then call latexmk on it //! let exit_status = Command::new("latexmk").arg("report.tex").status()?; //! //! assert!(exit_status.success()); //! # Ok(()) //! # } //! # fn main() { //! # run().unwrap(); //! # } //! ``` //! //! [latexmk]: http://mg.readthedocs.io/latexmk.html //! [`ClearPage`]: enum.Element.html #![deny(missing_docs)] #[macro_use] extern crate error_chain; mod paragraph; mod document; mod section; mod lists; mod equations; pub use errors::*; pub use document::{Document, DocumentClass, Element, Preamble}; pub use paragraph::{Paragraph, ParagraphElement}; pub use section::Section; pub use lists::{List, ListKind}; pub use equations::{Align, Equation}; use std::io::Write; mod errors { error_chain!{ foreign_links{ Io(::std::io::Error) #[doc = "Wrapper around `std::io::Error`"]; Fmt(::std::fmt::Error) #[doc = "A formatting error"]; UtfError(::std::string::FromUtf8Error) #[doc = "A UTF8 conversion error"]; } } } /// A generic trait for rendering AST nodes to some `Writer`. pub trait Renderable { /// Render the item. fn render<W>(&self, writer: &mut W) -> Result<()> where W: Write; }