Adapt for tonty and fix a few bugs 🚧

This commit is contained in:
Laurenz 2020-02-04 11:22:00 +01:00
parent f655656fb8
commit 5c11aa7223
8 changed files with 64 additions and 63 deletions

View File

@ -1,9 +1,10 @@
use std::error::Error;
use std::fs::{File, read_to_string}; use std::fs::{File, read_to_string};
use std::io::BufWriter; use std::io::BufWriter;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use futures_executor::block_on; use futures_executor::block_on;
use typstc::{Typesetter, DynErrorProvider}; use typstc::{Typesetter, DebugErrorProvider};
use typstc::toddle::query::fs::EagerFsProvider; use typstc::toddle::query::fs::EagerFsProvider;
use typstc::export::pdf; use typstc::export::pdf;
@ -15,7 +16,7 @@ fn main() {
} }
} }
fn run() -> Result<(), Box<dyn std::error::Error>> { fn run() -> Result<(), Box<dyn Error>> {
let args: Vec<String> = std::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 {
println!("usage: {} source [destination]", println!("usage: {} source [destination]",
@ -38,7 +39,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
.map_err(|_| "failed to read from source file")?; .map_err(|_| "failed to read from source file")?;
let (fs, entries) = EagerFsProvider::from_index("../fonts", "index.json")?; let (fs, entries) = EagerFsProvider::from_index("../fonts", "index.json")?;
let provider = DynErrorProvider::new(fs); let provider = DebugErrorProvider::new(fs);
let typesetter = Typesetter::new((Box::new(provider), entries)); let typesetter = Typesetter::new((Box::new(provider), entries));
let layouts = block_on(typesetter.typeset(&src)); let layouts = block_on(typesetter.typeset(&src));

View File

@ -35,3 +35,38 @@ impl Error {
Error { message: message.into(), severity } Error { message: message.into(), severity }
} }
} }
/// Construct an error with formatted message and optionally severity and / or
/// span.
///
/// # Examples
/// ```
/// # use typstc::err;
/// # use typstc::syntax::span::Span;
/// # let span = Span::ZERO;
/// # let value = 0;
///
/// // With span and default severity `Error`.
/// err!(span; "the wrong {}", value);
///
/// // With no span and severity `Warning`.
/// err!(@Warning: span; "non-fatal!");
///
/// // Without span and default severity.
/// err!("no spans here ...");
/// ```
#[macro_export]
macro_rules! err {
(@$severity:ident: $span:expr; $($args:tt)*) => {
$crate::syntax::span::Spanned { v: err!(@$severity: $($args)*), span: $span }
};
(@$severity:ident: $($args:tt)*) => {
$crate::error::Error {
message: format!($($args)*),
severity: $crate::error::Severity::$severity,
}
};
($($tts:tt)*) => { err!(@Error: $($tts)*) };
}

View File

@ -198,38 +198,3 @@ macro_rules! body {
} }
}; };
} }
/// Construct an error with formatted message and optionally severity and / or
/// span.
///
/// # Examples
/// ```
/// # use typstc::err;
/// # use typstc::syntax::span::Span;
/// # let span = Span::ZERO;
/// # let value = 0;
///
/// // With span and default severity `Error`.
/// err!(span; "the wrong {}", value);
///
/// // With no span and severity `Warning`.
/// err!(@Warning: span; "non-fatal!");
///
/// // Without span and default severity.
/// err!("no spans here ...");
/// ```
#[macro_export]
macro_rules! err {
(@$severity:ident: $span:expr; $($args:tt)*) => {
$crate::syntax::span::Spanned { v: err!(@Error: $($args)*), span: $span }
};
(@$severity:ident: $($args:tt)*) => {
$crate::error::Error {
message: format!($($args)*),
severity: $crate::error::Severity::$severity,
}
};
($($tts:tt)*) => { err!(@Error: $($tts)*) };
}

View File

@ -19,7 +19,7 @@
pub use toddle; pub use toddle;
use std::cell::RefCell; use std::cell::RefCell;
use std::error::Error; use std::fmt::Debug;
use async_trait::async_trait; use async_trait::async_trait;
use smallvec::smallvec; use smallvec::smallvec;
@ -40,6 +40,7 @@ macro_rules! pub_use_mod {
}; };
} }
#[macro_use]
pub mod error; pub mod error;
pub mod export; pub mod export;
#[macro_use] #[macro_use]
@ -71,7 +72,7 @@ pub struct Typesetter {
pub type GlobalFontLoader = SharedFontLoader<GlobalProvider>; pub type GlobalFontLoader = SharedFontLoader<GlobalProvider>;
/// The provider type of font loaders used in the [`Typesetter`]. /// The provider type of font loaders used in the [`Typesetter`].
pub type GlobalProvider = Box<dyn FontProvider<Data=OwnedData, Error=Box<dyn Error>>>; pub type GlobalProvider = Box<dyn FontProvider<Data=OwnedData, Error=Box<dyn Debug>>>;
impl Typesetter { impl Typesetter {
/// Create a new typesetter. /// Create a new typesetter.
@ -135,29 +136,30 @@ impl Typesetter {
} }
} }
/// Wraps a font provider and transforms its errors into boxed trait objects. /// Wraps a font provider and transforms its errors into boxed [`Debug`] trait
/// This enables font providers that do not return boxed errors to be used with /// objects. This enables font providers that do not return these boxed errors
/// the typesetter. /// to be used with the typesetter.
#[derive(Debug)] #[derive(Debug)]
pub struct DynErrorProvider<P> { pub struct DebugErrorProvider<P> {
provider: P, provider: P,
} }
impl<P> DynErrorProvider<P> impl<P> DebugErrorProvider<P>
where P: FontProvider, P::Error: Error + 'static { where P: FontProvider, P::Error: Debug + 'static {
/// Create a new dynamic error provider from any provider. /// Create a new debug error provider from any provider.
pub fn new(provider: P) -> DynErrorProvider<P> { pub fn new(provider: P) -> DebugErrorProvider<P> {
DynErrorProvider { provider } DebugErrorProvider { provider }
} }
} }
#[async_trait(?Send)] #[async_trait(?Send)]
impl<P> FontProvider for DynErrorProvider<P> impl<P> FontProvider for DebugErrorProvider<P>
where P: FontProvider, P::Error: Error + 'static { where P: FontProvider, P::Error: Debug + 'static {
type Data = P::Data; type Data = P::Data;
type Error = Box<dyn Error>; type Error = Box<dyn Debug>;
async fn load(&self, index: usize, variant: usize) -> Result<Font<P::Data>, Self::Error> { async fn load(&self, index: usize, variant: usize) -> Result<Font<P::Data>, Self::Error> {
Ok(self.provider.load(index, variant).await?) self.provider.load(index, variant).await
.map_err(|d| Box::new(d) as Box<dyn Debug>)
} }
} }

View File

@ -15,7 +15,7 @@ function! {
FontFamilyFunc { FontFamilyFunc {
body: body!(opt: body, ctx, errors, decos), body: body!(opt: body, ctx, errors, decos),
list: header.args.pos.get_all::<StringLike>(errors) list: header.args.pos.get_all::<StringLike>(errors)
.map(Into::into) .map(|s| s.0.to_lowercase())
.collect(), .collect(),
} }
} }

View File

@ -105,7 +105,7 @@ key!(AxisKey,
/// A key which is equivalent to a [`AxisKey`] but uses typical extent keywords /// A key which is equivalent to a [`AxisKey`] but uses typical extent keywords
/// instead of axis keywords, e.g. `width` instead of `horizontal`. /// instead of axis keywords, e.g. `width` instead of `horizontal`.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct ExtentKey(AxisKey); pub struct ExtentKey(pub AxisKey);
key!(ExtentKey, key!(ExtentKey,
"width" | "w" => ExtentKey(Specific(Horizontal)), "width" | "w" => ExtentKey(Specific(Horizontal)),

View File

@ -87,7 +87,7 @@ value!(ScaleSize, "number or size",
/// A value type that matches [`Expr::Ident`] and [`Expr::Str`] and implements /// A value type that matches [`Expr::Ident`] and [`Expr::Str`] and implements
/// `Into<String>`. /// `Into<String>`.
pub struct StringLike(String); pub struct StringLike(pub String);
value!(StringLike, "identifier or string", value!(StringLike, "identifier or string",
Expr::Ident(Ident(s)) => StringLike(s), Expr::Ident(Ident(s)) => StringLike(s),
@ -117,7 +117,7 @@ impl From<StringLike> for String {
/// [func: size=default] => None /// [func: size=default] => None
/// [func: size=2cm] => Some(Size::cm(2.0)) /// [func: size=2cm] => Some(Size::cm(2.0))
/// ``` /// ```
pub struct Defaultable<V>(Option<V>); pub struct Defaultable<V>(pub Option<V>);
impl<V: Value> Value for Defaultable<V> { impl<V: Value> Value for Defaultable<V> {
fn parse(expr: Spanned<Expr>) -> Result<Self, Error> { fn parse(expr: Spanned<Expr>) -> Result<Self, Error> {

View File

@ -8,7 +8,7 @@ use std::process::Command;
use futures_executor::block_on; use futures_executor::block_on;
use typstc::{Typesetter, DynErrorProvider}; use typstc::{Typesetter, DebugErrorProvider};
use typstc::layout::{MultiLayout, Serialize}; use typstc::layout::{MultiLayout, Serialize};
use typstc::size::{Size, Size2D, ValueBox}; use typstc::size::{Size, Size2D, ValueBox};
use typstc::style::{PageStyle, PaperClass}; use typstc::style::{PageStyle, PaperClass};
@ -65,8 +65,8 @@ fn test(name: &str, src: &str) -> DynResult<()> {
println!("Testing: {}.", name); println!("Testing: {}.", name);
let (fs, entries) = EagerFsProvider::from_index("../fonts", "index.json")?; let (fs, entries) = EagerFsProvider::from_index("../fonts", "index.json")?;
let paths = fs.paths(); let files = fs.files().to_vec();
let provider = DynErrorProvider::new(fs); let provider = DebugErrorProvider::new(fs);
let mut typesetter = Typesetter::new((Box::new(provider), entries)); let mut typesetter = Typesetter::new((Box::new(provider), entries));
typesetter.set_page_style(PageStyle { typesetter.set_page_style(PageStyle {
@ -84,14 +84,12 @@ fn test(name: &str, src: &str) -> DynResult<()> {
// Compute the font's paths. // Compute the font's paths.
let mut fonts = HashMap::new(); let mut fonts = HashMap::new();
let loader = typesetter.loader().borrow();
for layout in &layouts { for layout in &layouts {
for index in layout.find_used_fonts() { for index in layout.find_used_fonts() {
fonts.entry(index) fonts.entry(index)
.or_insert_with(|| &paths[index.id][index.variant]); .or_insert_with(|| &files[index.id][index.variant]);
} }
} }
drop(loader);
// Write the serialized layout file. // Write the serialized layout file.
let path = format!("tests/cache/{}.serialized", name); let path = format!("tests/cache/{}.serialized", name);