diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-03-11 22:15:34 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-03-11 22:15:34 +0100 |
| commit | 107450ee5ca8e7e0bc03cf6ce9f59268aa20e9f6 (patch) | |
| tree | 4d9df95eb410d7dab96cb7182d6c981ff27f9273 /src/lib.rs | |
| parent | 0511979942625e0b1aa77f090621e4f35a2cf242 (diff) | |
Restructure typeset crate ✈
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 151 |
1 files changed, 138 insertions, 13 deletions
@@ -5,7 +5,7 @@ //! # Example //! This is an example of compiling a really simple document into _PDF_. //! ``` -//! use typeset::{parsing::ParseTree, engine::Typeset, write::WritePdf}; +//! use typeset::Compiler; //! //! // Create an output file. //! # /* @@ -13,22 +13,147 @@ //! # */ //! # let mut file = std::fs::File::create("../target/typeset-hello.pdf").unwrap(); //! -//! // Parse the source and then generate the document. -//! let src = "Hello World from Typeset‼"; -//! let doc = src.parse_tree().unwrap().typeset().unwrap(); +//! // Create a compiler and export a PDF. +//! let src = "Hello World from Typeset!"; +//! let compiler = Compiler::new(src); //! -//! // Write the document into file as PDF. -//! file.write_pdf(&doc).unwrap(); +//! // Write the document into a file as a PDF. +//! compiler.write_pdf(&mut file).unwrap(); //! ``` -mod pdf; -mod utility; -pub mod parsing; +pub mod syntax; pub mod doc; -pub mod engine; pub mod font; +mod parsing; +mod engine; +mod pdf; +mod utility; + +pub use crate::parsing::{Tokens, Parser, ParseError}; +pub use crate::engine::{Engine, TypesetError}; +pub use crate::pdf::{PdfCreator, PdfWritingError}; + +use std::error; +use std::fmt; +use std::io::Write; +use crate::syntax::SyntaxTree; +use crate::doc::Document; + + +/// Emits various compiled intermediates from source code. +pub struct Compiler<'s> { + /// The source code of the document. + source: &'s str, +} + +impl<'s> Compiler<'s> { + /// Create a new compiler from a document. + #[inline] + pub fn new(source: &'s str) -> Compiler<'s> { + Compiler { source } + } + + /// Return an iterator over the tokens of the document. + #[inline] + pub fn tokenize(&self) -> Tokens<'s> { + Tokens::new(self.source) + } + + /// Return the abstract syntax tree representation of the document. + #[inline] + pub fn parse(&self) -> Result<SyntaxTree<'s>, Error> { + Parser::new(self.tokenize()).parse().map_err(Into::into) + } + + /// Return the abstract typesetted representation of the document. + #[inline] + pub fn typeset(&self) -> Result<Document, Error> { + Engine::new(self.parse()?).typeset().map_err(Into::into) + } + + /// Write the document as a _PDF_, returning how many bytes were written. + pub fn write_pdf<W: Write>(&self, target: &mut W) -> Result<usize, Error> { + PdfCreator::new(target, &self.typeset()?)?.write().map_err(Into::into) + } +} + +/// The error type for compilation. +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum Error { + /// An error that occured while transforming source code into + /// an abstract syntax tree. + Parse(ParseError), + /// An error that occured while typesetting into an abstract document. + Typeset(TypesetError), + /// An error that occured while writing the document as a _PDF_. + PdfWrite(PdfWritingError) +} + +impl error::Error for Error { + #[inline] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Error::Parse(err) => Some(err), + Error::Typeset(err) => Some(err), + Error::PdfWrite(err) => Some(err), + } + } +} + +impl fmt::Display for Error { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Parse(err) => write!(f, "parse error: {}", err), + Error::Typeset(err) => write!(f, "typeset error: {}", err), + Error::PdfWrite(err) => write!(f, "typeset error: {}", err), + } + } +} + +impl From<ParseError> for Error { + #[inline] + fn from(err: ParseError) -> Error { + Error::Parse(err) + } +} + +impl From<TypesetError> for Error { + #[inline] + fn from(err: TypesetError) -> Error { + Error::Typeset(err) + } +} + +impl From<PdfWritingError> for Error { + #[inline] + fn from(err: PdfWritingError) -> Error { + Error::PdfWrite(err) + } +} + + +#[cfg(test)] +mod test { + use crate::Compiler; + + /// Create a pdf with a name from the source code. + fn test(name: &str, src: &str) { + let path = format!("../target/typeset-pdf-{}.pdf", name); + let mut file = std::fs::File::create(path).unwrap(); + Compiler::new(src).write_pdf(&mut file).unwrap(); + } -/// Writing of documents into supported formats. -pub mod write { - pub use crate::pdf::{WritePdf, PdfWritingError}; + #[test] + fn pdf() { + test("unicode", "∑mbe∂∂ed font with Unicode!"); + test("parentheses", "Text with ) and ( or (enclosed) works."); + test("composite-glyph", "Composite character‼"); + test("multiline"," + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed + diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed + diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. + Stet clita kasd gubergren, no sea takimata sanctus est. + "); + } } |
