summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs111
1 files changed, 87 insertions, 24 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6f2aaa53..59a6a279 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,24 +1,50 @@
-//! Typeset is a library for compiling documents written in the
-//! corresponding typesetting language into a typesetted document in an
-//! output format like _PDF_.
+//! The compiler for the _Typeset_ typesetting language 📜.
+//!
+//! # Compilation
+//! - **Parsing:** The parsing step first transforms a plain string into an
+//! [iterator of tokens](Tokens). Then the parser operates on that to
+//! construct an abstract syntax tree. The structures describing the tree
+//! can be found in the [`syntax`](syntax) module.
+//! - **Typesetting:** The next step is to transform the syntax tree into an
+//! abstract document representation. Types for these can be found in the
+//! [`doc`](doc) module. This representation contains already the finished
+//! layout, but is still portable.
+//! - **Exporting:** The abstract document can then be exported into supported
+//! formats. Currently the only supported format is _PDF_. In this step
+//! the text is finally encoded into glyph indices and font data is
+//! subsetted.
+//!
+//! # Fonts
+//! To do the typesetting, the compiler needs font data. To be highly portable
+//! the compiler assumes nothing about the environment. To still work with fonts,
+//! the consumer of this library has to add _font providers_ to their compiler
+//! instance. These can be queried for font data given a flexible font configuration
+//! specifying font families and styles. A font provider is a type implementing the
+//! [`FontProvider`](crate::font::FontProvider) trait. For convenience there exists
+//! the [`FileFontProvider`](crate::font::FileFontProvider) to serve fonts from a
+//! local folder.
//!
//! # Example
-//! This is an example of compiling a really simple document into _PDF_.
//! ```
-//! use typeset::Compiler;
+//! use std::fs::File;
+//! use typeset::{Compiler, font::FileFontProvider, file_font};
//!
-//! // Minimal source code for our document.
-//! let src = "Hello World from Typeset!";
+//! // Simple example source code.
+//! let source = "Hello World from Typeset!";
//!
-//! // Create an output file.
+//! // Create a compiler with a font provider that provides one font.
+//! let mut compiler = Compiler::new();
+//! compiler.add_font_provider(FileFontProvider::new("../fonts", vec![
+//! // Font family name, generic families, file, bold, italic
+//! file_font!("NotoSans", [SansSerif], "NotoSans-Regular.ttf", false, false),
+//! ]));
+//!
+//! // Open an output file, compile and write to the file.
//! # /*
-//! let mut file = std::fs::File::create("hello-typeset.pdf").unwrap();
+//! let mut file = File::create("hello-typeset.pdf").unwrap();
//! # */
-//! # let mut file = std::fs::File::create("../target/typeset-hello.pdf").unwrap();
-//!
-//! // Create a compiler and write the document into a file as a PDF.
-//! let compiler = Compiler::new();
-//! compiler.write_pdf(src, &mut file).unwrap();
+//! # let mut file = File::create("../target/typeset-hello.pdf").unwrap();
+//! compiler.write_pdf(source, &mut file).unwrap();
//! ```
pub mod syntax;
@@ -36,33 +62,51 @@ pub use crate::pdf::PdfError;
use std::error;
use std::fmt;
use std::io::Write;
-use crate::parsing::Parser;
use crate::syntax::SyntaxTree;
-use crate::engine::Engine;
+use crate::parsing::Parser;
use crate::doc::{Document, Style};
+use crate::font::FontProvider;
+use crate::engine::Engine;
use crate::pdf::PdfCreator;
/// Compiles source code into typesetted documents allowing to
/// retrieve results at various stages.
-pub struct Compiler {
+pub struct Compiler<'p> {
+ context: Context<'p>,
+}
+
+struct Context<'p> {
/// Style for typesetting.
style: Style,
+ /// Font providers.
+ font_providers: Vec<Box<dyn FontProvider + 'p>>,
}
-impl Compiler {
+impl<'p> Compiler<'p> {
/// Create a new compiler from a document.
#[inline]
- pub fn new() -> Compiler {
+ pub fn new() -> Compiler<'p> {
Compiler {
- style: Style::default(),
+ context: Context {
+ style: Style::default(),
+ font_providers: Vec::new(),
+ }
}
}
/// Set the default style for typesetting.
#[inline]
pub fn style(&mut self, style: Style) -> &mut Self {
- self.style = style;
+ self.context.style = style;
+ self
+ }
+
+ /// Add a font provider.
+ #[inline]
+ pub fn add_font_provider<P: 'p>(&mut self, provider: P) -> &mut Self
+ where P: FontProvider {
+ self.context.font_providers.push(Box::new(provider));
self
}
@@ -82,7 +126,7 @@ impl Compiler {
#[inline]
pub fn typeset(&self, source: &str) -> Result<Document, Error> {
let tree = self.parse(source)?;
- Engine::new(&tree, self.style.clone()).typeset().map_err(Into::into)
+ Engine::new(&tree, &self.context).typeset().map_err(Into::into)
}
/// Write the document as a _PDF_, returning how many bytes were written.
@@ -156,13 +200,32 @@ impl From<PdfError> for Error {
#[cfg(test)]
mod test {
+ use std::fs::File;
use crate::Compiler;
+ use crate::font::FileFontProvider;
/// Create a pdf with a name from the source code.
fn test(name: &str, src: &str) {
+ // Create compiler
+ let mut compiler = Compiler::new();
+ let provider = FileFontProvider::new("../fonts", vec![
+ // Font family name, generic families, file, bold, italic
+ file_font!("NotoSans", [SansSerif], "NotoSans-Regular.ttf", false, false),
+ file_font!("NotoSans", [SansSerif], "NotoSans-Bold.ttf", true, false),
+ file_font!("NotoSans", [SansSerif], "NotoSans-Italic.ttf", false, true),
+ file_font!("NotoSans", [SansSerif], "NotoSans-BoldItalic.ttf", true, true),
+ file_font!("NotoSansMath", [SansSerif], "NotoSansMath-Regular.ttf", false, false),
+ file_font!("NotoEmoji", [SansSerif, Serif, Monospace],
+ "NotoEmoji-Regular.ttf", false, false),
+ ]);
+ compiler.add_font_provider(provider);
+
+ // Open output file;
let path = format!("../target/typeset-pdf-{}.pdf", name);
- let mut file = std::fs::File::create(path).unwrap();
- Compiler::new().write_pdf(src, &mut file).unwrap();
+ let mut file = File::create(path).unwrap();
+
+ // Compile and output
+ compiler.write_pdf(src, &mut file).unwrap();
}
#[test]