Tidying up 🧹

This commit is contained in:
Laurenz 2019-12-12 22:19:38 +01:00
parent 3c0496bb61
commit ff107cf3e7
13 changed files with 88 additions and 104 deletions

View File

@ -1,67 +1,49 @@
use std::env; use std::fs::{File, read_to_string};
use std::error::Error; use std::io::BufWriter;
use std::fs::File;
use std::io::{BufWriter, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process;
use typstc::export::pdf::PdfExporter;
use typstc::toddle::query::FileSystemFontProvider;
use typstc::Typesetter; use typstc::Typesetter;
use typstc::toddle::query::FileSystemFontProvider;
use typstc::export::pdf::PdfExporter;
fn main() { fn main() {
if let Err(err) = run() { if let Err(err) = run() {
eprintln!("error: {}", err); eprintln!("error: {}", err);
process::exit(1); std::process::exit(1);
} }
} }
fn run() -> Result<(), Box<dyn Error>> { fn run() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = std::env::args().collect();
if args.len() < 2 || args.len() > 3 { if args.len() < 2 || args.len() > 3 {
help_and_quit(); println!("usage: {} source [destination]",
args.first().map(|s| s.as_str()).unwrap_or("typst"));
std::process::exit(0);
} }
let source_path = Path::new(&args[1]); let source = Path::new(&args[1]);
let dest_path = if args.len() <= 2 { let dest = if args.len() <= 2 {
source_path.with_extension("pdf") source.with_extension("pdf")
} else { } else {
PathBuf::from(&args[2]) PathBuf::from(&args[2])
}; };
if dest_path == source_path { if source == dest {
return err("source and destination path are the same"); Err("source and destination path are the same")?;
} }
let mut source_file = File::open(source_path) let src = read_to_string(source)
.map_err(|_| "failed to open source file")?;
let mut src = String::new();
source_file
.read_to_string(&mut src)
.map_err(|_| "failed to read from source file")?; .map_err(|_| "failed to read from source file")?;
let mut typesetter = Typesetter::new(); let mut typesetter = Typesetter::new();
let provider = FileSystemFontProvider::from_listing("fonts/fonts.toml").unwrap(); let provider = FileSystemFontProvider::from_listing("fonts/fonts.toml").unwrap();
typesetter.add_font_provider(provider); typesetter.add_font_provider(provider);
let document = typesetter.typeset(&src)?; let layouts = typesetter.typeset(&src)?;
let exporter = PdfExporter::new(); let exporter = PdfExporter::new();
let dest_file = File::create(&dest_path)?; let writer = BufWriter::new(File::create(&dest)?);
exporter.export(&document, typesetter.loader(), BufWriter::new(dest_file))?; exporter.export(&layouts, typesetter.loader(), writer)?;
Ok(()) Ok(())
} }
/// Construct an error `Result` from a message.
fn err<S: Into<String>, T>(message: S) -> Result<T, Box<dyn Error>> {
Err(message.into().into())
}
/// Print a usage message and exit the process.
fn help_and_quit() {
let name = env::args().next().unwrap_or("typst".to_string());
println!("usage: {} source [destination]", name);
process::exit(0);
}

View File

@ -3,19 +3,23 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::io::{self, Write}; use std::io::{self, Write};
use tide::{PdfWriter, Rect, Ref, Trailer, Version};
use tide::content::Content; use tide::content::Content;
use tide::doc::{Catalog, Page, PageTree, Resource, Text}; use tide::doc::{Catalog, Page, PageTree, Resource, Text};
use tide::font::{CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags, Type0Font}; use tide::font::{
use tide::font::{CMap, CMapEncoding, FontStream, GlyphUnit, WidthRecord}; CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags, Type0Font,
use tide::{PdfWriter, Rect, Ref, Trailer, Version}; CMap, CMapEncoding, FontStream, GlyphUnit, WidthRecord
};
use toddle::Error as FontError;
use toddle::font::OwnedFont; use toddle::font::OwnedFont;
use toddle::query::SharedFontLoader; use toddle::query::SharedFontLoader;
use toddle::tables::{CharMap, Header, HorizontalMetrics, MacStyleFlags}; use toddle::tables::{
use toddle::tables::{Name, NameEntry, Post, OS2}; CharMap, Header, HorizontalMetrics, MacStyleFlags,
use toddle::Error as FontError; Name, NameEntry, Post, OS2
};
use crate::layout::{Layout, LayoutAction, MultiLayout}; use crate::layout::{MultiLayout, Layout, LayoutAction};
use crate::size::Size; use crate::size::Size;
/// Exports layouts into _PDFs_. /// Exports layouts into _PDFs_.

View File

@ -2,14 +2,10 @@
use std::io::{self, Write}; use std::io::{self, Write};
use smallvec::SmallVec; use smallvec::SmallVec;
use toddle::query::SharedFontLoader;
use toddle::query::{FontClass, SharedFontLoader};
use crate::TypesetResult;
use crate::func::Command;
use crate::size::{Size, Size2D, SizeBox}; use crate::size::{Size, Size2D, SizeBox};
use crate::style::{LayoutStyle, TextStyle}; use crate::style::LayoutStyle;
use crate::syntax::{Node, SyntaxTree, FuncCall};
mod actions; mod actions;
mod tree; mod tree;
@ -25,8 +21,11 @@ pub mod layouters {
pub use super::text::{layout_text, TextContext}; pub use super::text::{layout_text, TextContext};
} }
pub use actions::{LayoutAction, LayoutActions}; pub use self::actions::{LayoutAction, LayoutActions};
pub use layouters::*; pub use self::layouters::*;
/// The result type for layouting.
pub type LayoutResult<T> = crate::TypesetResult<T>;
/// A collection of layouts. /// A collection of layouts.
pub type MultiLayout = Vec<Layout>; pub type MultiLayout = Vec<Layout>;
@ -368,8 +367,8 @@ pub enum SpacingKind {
/// The standard spacing kind used for paragraph spacing. /// The standard spacing kind used for paragraph spacing.
const PARAGRAPH_KIND: SpacingKind = SpacingKind::Soft(1); const PARAGRAPH_KIND: SpacingKind = SpacingKind::Soft(1);
/// The standard spacing kind used for normal spaces between boxes. /// The standard spacing kind used for line spacing.
const SPACE_KIND: SpacingKind = SpacingKind::Soft(2); const LINE_KIND: SpacingKind = SpacingKind::Soft(2);
/// The last appeared spacing. /// The last appeared spacing.
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -416,6 +415,3 @@ impl Serialize for MultiLayout {
Ok(()) Ok(())
} }
} }
/// The result type for layouting.
pub type LayoutResult<T> = TypesetResult<T>;

View File

@ -1,8 +1,9 @@
use toddle::query::{SharedFontLoader, FontQuery, FontClass}; use toddle::query::{SharedFontLoader, FontQuery, FontClass};
use toddle::tables::{CharMap, Header, HorizontalMetrics}; use toddle::tables::{CharMap, Header, HorizontalMetrics};
use super::*;
use crate::size::{Size, Size2D}; use crate::size::{Size, Size2D};
use crate::style::TextStyle;
use super::*;
/// The context for text layouting. /// The context for text layouting.
/// ///

View File

@ -1,4 +1,9 @@
use smallvec::smallvec; use smallvec::smallvec;
use toddle::query::FontClass;
use crate::func::Command;
use crate::syntax::{SyntaxTree, Node, FuncCall};
use crate::style::TextStyle;
use super::*; use super::*;
/// Layout a syntax tree into a multibox. /// Layout a syntax tree into a multibox.

View File

@ -8,11 +8,13 @@
//! - **Layouting:** The next step is to transform the syntax tree into a //! - **Layouting:** The next step is to transform the syntax tree into a
//! portable representation of the typesetted document. Types for these can be //! portable representation of the typesetted document. Types for these can be
//! found in the [layout] module. A finished layout reading for exporting is a //! found in the [layout] module. A finished layout reading for exporting is a
//! [multi layout](crate::layout::MultiLayout) consisting of multiple boxes (or //! [multi-layout](crate::layout::MultiLayout) consisting of multiple boxes
//! pages). //! (or pages).
//! - **Exporting:** The finished document can finally be exported into a supported //! - **Exporting:** The finished layout can then be exported into a supported
//! format. Submodules for these formats are located in the [export](crate::export) //! format. Submodules for these formats are located in the
//! module. Currently, the only supported output format is _PDF_. //! [export](crate::export) module. Currently, the only supported output
//! format is _PDF_. Alternatively, the layout can be serialized to pass it to
//! a suitable renderer.
#![allow(unused)] #![allow(unused)]
@ -25,9 +27,8 @@ use toddle::query::{FontLoader, FontProvider, SharedFontLoader};
use toddle::Error as FontError; use toddle::Error as FontError;
use crate::func::Scope; use crate::func::Scope;
use crate::layout::{layout_tree, MultiLayout, LayoutContext}; use crate::layout::{layout_tree, MultiLayout, LayoutContext, LayoutResult};
use crate::layout::{LayoutAxes, LayoutAlignment}; use crate::layout::{LayoutSpace, LayoutExpansion, LayoutAxes, LayoutAlignment};
use crate::layout::{LayoutResult, LayoutSpace, LayoutExpansion};
use crate::syntax::{parse, SyntaxTree, ParseContext, Span, ParseResult}; use crate::syntax::{parse, SyntaxTree, ParseContext, Span, ParseResult};
use crate::style::{LayoutStyle, PageStyle, TextStyle}; use crate::style::{LayoutStyle, PageStyle, TextStyle};
@ -38,9 +39,9 @@ pub mod export;
pub mod func; pub mod func;
pub mod layout; pub mod layout;
pub mod library; pub mod library;
pub mod syntax;
pub mod size; pub mod size;
pub mod style; pub mod style;
pub mod syntax;
/// Transforms source code into typesetted layouts. /// Transforms source code into typesetted layouts.
/// ///

View File

@ -3,7 +3,7 @@ use super::maps::ConsistentMap;
use super::keys::AxisKey; use super::keys::AxisKey;
function! { function! {
/// `direction`: Sets the directions for the layouting axes. /// `direction`: Sets the directions of the layouting axes.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Direction { pub struct Direction {
body: Option<SyntaxTree>, body: Option<SyntaxTree>,

View File

@ -1,18 +1,17 @@
//! The standard library for the _Typst_ language. //! The standard library.
use crate::func::prelude::*;
use toddle::query::FontClass; use toddle::query::FontClass;
use keys::*; use crate::func::prelude::*;
use maps::*; use self::keys::*;
use self::maps::*;
pub_use_mod!(align);
pub_use_mod!(boxed);
pub_use_mod!(direction);
pub mod maps; pub mod maps;
pub mod keys; pub mod keys;
pub_use_mod!(align);
pub_use_mod!(boxed);
pub_use_mod!(direction);
/// Create a scope with all standard functions. /// Create a scope with all standard functions.
pub fn std() -> Scope { pub fn std() -> Scope {
@ -100,7 +99,7 @@ function! {
} }
function! { function! {
/// `page.margins`: Set the margins of pages. /// `page.margins`: Sets the page margins.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct PageMargins { pub struct PageMargins {
map: PaddingMap, map: PaddingMap,
@ -121,7 +120,7 @@ function! {
} }
function! { function! {
/// `spacing`, `h`, `v`: Add spacing along an axis. /// `spacing`, `h`, `v`: Adds spacing along an axis.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Spacing { pub struct Spacing {
axis: AxisKey, axis: AxisKey,
@ -192,7 +191,7 @@ function! {
} }
function! { function! {
/// `font.size`: Set the font size. /// `font.size`: Sets the font size.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct FontSize { pub struct FontSize {
body: Option<SyntaxTree>, body: Option<SyntaxTree>,
@ -206,7 +205,7 @@ function! {
} }
} }
layout(self, mut ctx) { layout(self, ctx) {
let mut style = ctx.style.text.clone(); let mut style = ctx.style.text.clone();
style.font_size = self.size; style.font_size = self.size;

View File

@ -1,12 +1,11 @@
//! Different-dimensional spacing types. //! Different-dimensional spacing types.
use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use std::iter::Sum; use std::iter::Sum;
use std::ops::*; use std::ops::*;
use std::str::FromStr; use std::str::FromStr;
use crate::layout::{LayoutAxes, LayoutAlignment, Axis, GenericAxisKind, Alignment}; use crate::layout::{LayoutAxes, Axis, GenericAxisKind, LayoutAlignment, Alignment};
/// A general spacing type. /// A general spacing type.

View File

@ -2,6 +2,7 @@
use toddle::query::FontClass; use toddle::query::FontClass;
use FontClass::*; use FontClass::*;
use crate::size::{Size, Size2D, SizeBox}; use crate::size::{Size, Size2D, SizeBox};
/// Defines properties of pages and text. /// Defines properties of pages and text.
@ -58,8 +59,8 @@ impl TextStyle {
} else { } else {
// If we add an Italic or Bold class, we remove // If we add an Italic or Bold class, we remove
// the Regular class. // the Regular class.
if class == FontClass::Italic || class == FontClass::Bold { if class == Italic || class == Bold {
self.classes.retain(|x| x != &FontClass::Regular); self.classes.retain(|x| x != &Regular);
} }
self.classes.push(class); self.classes.push(class);

View File

@ -6,14 +6,9 @@ use unicode_xid::UnicodeXID;
use crate::func::LayoutFunc; use crate::func::LayoutFunc;
use crate::size::{Size, ScaleSize}; use crate::size::{Size, ScaleSize};
mod tokens; pub_use_mod!(tokens);
#[macro_use] pub_use_mod!(parsing);
mod parsing; pub_use_mod!(span);
mod span;
pub use span::{Span, Spanned};
pub use tokens::{tokenize, Tokens};
pub use parsing::{parse, ParseContext, ParseResult};
/// A logical unit of the incoming text stream. /// A logical unit of the incoming text stream.
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
@ -185,6 +180,7 @@ impl FuncArgs {
} }
} }
/// Extract the option expression kind from the option or return an error.
fn expect<E: ExpressionKind>(opt: ParseResult<Option<Spanned<E>>>) -> ParseResult<Spanned<E>> { fn expect<E: ExpressionKind>(opt: ParseResult<Option<Spanned<E>>>) -> ParseResult<Spanned<E>> {
match opt { match opt {
Ok(Some(spanned)) => Ok(spanned), Ok(Some(spanned)) => Ok(spanned),

View File

@ -1,10 +1,12 @@
//! Parsing of token streams into syntax trees. //! Parsing of token streams into syntax trees.
use crate::TypesetResult;
use crate::func::Scope; use crate::func::Scope;
use crate::size::Size; use crate::size::Size;
use super::*; use super::*;
/// The result type for parsing.
pub type ParseResult<T> = crate::TypesetResult<T>;
/// Parses source code into a syntax tree given a context. /// Parses source code into a syntax tree given a context.
pub fn parse(src: &str, ctx: ParseContext) -> ParseResult<SyntaxTree> { pub fn parse(src: &str, ctx: ParseContext) -> ParseResult<SyntaxTree> {
Parser::new(src, ctx).parse() Parser::new(src, ctx).parse()
@ -404,9 +406,6 @@ impl<'s> Iterator for PeekableTokens<'s> {
} }
} }
/// The result type for parsing.
pub type ParseResult<T> = TypesetResult<T>;
#[cfg(test)] #[cfg(test)]
#[allow(non_snake_case)] #[allow(non_snake_case)]

View File

@ -1,5 +1,6 @@
use std::str::CharIndices; use std::str::CharIndices;
use smallvec::SmallVec; use smallvec::SmallVec;
use super::*; use super::*;
/// Builds an iterator over the tokens of the source code. /// Builds an iterator over the tokens of the source code.
@ -266,7 +267,7 @@ fn is_newline_char(character: char) -> bool {
/// A (index, char) iterator with double lookahead. /// A (index, char) iterator with double lookahead.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PeekableChars<'s> { struct PeekableChars<'s> {
string: &'s str, string: &'s str,
chars: CharIndices<'s>, chars: CharIndices<'s>,
peeked: SmallVec<[Option<(usize, char)>; 2]>, peeked: SmallVec<[Option<(usize, char)>; 2]>,
@ -276,7 +277,7 @@ pub struct PeekableChars<'s> {
impl<'s> PeekableChars<'s> { impl<'s> PeekableChars<'s> {
/// Create a new iterator from a string. /// Create a new iterator from a string.
pub fn new(string: &'s str) -> PeekableChars<'s> { fn new(string: &'s str) -> PeekableChars<'s> {
PeekableChars { PeekableChars {
string, string,
chars: string.char_indices(), chars: string.char_indices(),
@ -287,17 +288,17 @@ impl<'s> PeekableChars<'s> {
} }
/// Peek at the next element. /// Peek at the next element.
pub fn peek(&mut self) -> Option<(usize, char)> { fn peek(&mut self) -> Option<(usize, char)> {
self.peekn(0) self.peekn(0)
} }
/// Peek at the char of the next element. /// Peek at the char of the next element.
pub fn peekc(&mut self) -> Option<char> { fn peekc(&mut self) -> Option<char> {
self.peekn(0).map(|p| p.1) self.peekn(0).map(|p| p.1)
} }
/// Peek at the element after the next element. /// Peek at the element after the next element.
pub fn peekn(&mut self, n: usize) -> Option<(usize, char)> { fn peekn(&mut self, n: usize) -> Option<(usize, char)> {
while self.peeked.len() <= n { while self.peeked.len() <= n {
let next = self.next_inner(); let next = self.next_inner();
self.peeked.push(next); self.peeked.push(next);
@ -307,15 +308,15 @@ impl<'s> PeekableChars<'s> {
} }
/// Return the next value of the inner iterator mapped with the offset. /// Return the next value of the inner iterator mapped with the offset.
pub fn next_inner(&mut self) -> Option<(usize, char)> { fn next_inner(&mut self) -> Option<(usize, char)> {
self.chars.next().map(|(i, c)| (self.base + i, c)) self.chars.next().map(|(i, c)| (self.base + i, c))
} }
pub fn string_index(&mut self) -> usize { fn string_index(&mut self) -> usize {
self.index self.index
} }
pub fn set_string_index(&mut self, index: usize) { fn set_string_index(&mut self, index: usize) {
self.chars = self.string[index..].char_indices(); self.chars = self.string[index..].char_indices();
self.base = index; self.base = index;
self.index = 0; self.index = 0;