summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-03-11 22:15:34 +0100
committerLaurenz <laurmaedje@gmail.com>2019-03-11 22:15:34 +0100
commit107450ee5ca8e7e0bc03cf6ce9f59268aa20e9f6 (patch)
tree4d9df95eb410d7dab96cb7182d6c981ff27f9273 /src/lib.rs
parent0511979942625e0b1aa77f090621e4f35a2cf242 (diff)
Restructure typeset crate ✈
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs151
1 files changed, 138 insertions, 13 deletions
diff --git a/src/lib.rs b/src/lib.rs
index f2c9b5eb..e9d0b1b4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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.
+ ");
+ }
}