summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-10-13 13:10:21 +0200
committerLaurenz <laurmaedje@gmail.com>2019-10-13 13:10:21 +0200
commit7c0899b5373cdc4f1083a0a8515856207c431423 (patch)
treeee1ecade4022f1fa3f666feb55097f7bdcae69ed /src
parent5c04185892947969005ffcf6412d7190dafb3a79 (diff)
Run rustfmt 🚿
Diffstat (limited to 'src')
-rw-r--r--src/bin/main.rs20
-rw-r--r--src/export/pdf.rs149
-rw-r--r--src/func.rs50
-rw-r--r--src/layout/actions.rs26
-rw-r--r--src/layout/flex.rs13
-rw-r--r--src/layout/mod.rs45
-rw-r--r--src/layout/stacked.rs12
-rw-r--r--src/layout/text.rs10
-rw-r--r--src/lib.rs48
-rw-r--r--src/library/align.rs11
-rw-r--r--src/library/mod.rs13
-rw-r--r--src/library/styles.rs1
-rw-r--r--src/parsing/mod.rs104
-rw-r--r--src/parsing/tokens.rs57
-rw-r--r--src/size.rs114
-rw-r--r--src/style.rs12
-rw-r--r--src/syntax.rs21
17 files changed, 431 insertions, 275 deletions
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 5ae20f4a..58b2c00e 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -1,14 +1,13 @@
use std::env;
use std::error::Error;
use std::fs::File;
-use std::io::{Read, BufWriter};
+use std::io::{BufWriter, Read};
use std::path::{Path, PathBuf};
use std::process;
-use typst::Typesetter;
use typst::export::pdf::PdfExporter;
use typst::toddle::query::FileSystemFontProvider;
-
+use typst::Typesetter;
fn main() {
if let Err(err) = run() {
@@ -26,11 +25,16 @@ fn run() -> Result<(), Box<dyn Error>> {
let source_path = Path::new(&args[1]);
- // Compute the output filename from the input filename by replacing the extension.
+ // Compute the output filename from the input filename by replacing the
+ // extension.
let dest_path = if args.len() <= 2 {
- let stem = source_path.file_stem().ok_or_else(|| "missing destation file name")?;
+ let stem = source_path
+ .file_stem()
+ .ok_or_else(|| "missing destation file name")?;
- let base = source_path.parent().ok_or_else(|| "missing destation folder")?;
+ let base = source_path
+ .parent()
+ .ok_or_else(|| "missing destation folder")?;
base.join(format!("{}.pdf", stem.to_string_lossy()))
} else {
@@ -43,7 +47,9 @@ fn run() -> Result<(), Box<dyn Error>> {
let mut src = String::new();
let mut source_file = File::open(source_path).map_err(|_| "failed to open source file")?;
- source_file.read_to_string(&mut src).map_err(|_| "failed to read from source file")?;
+ source_file
+ .read_to_string(&mut src)
+ .map_err(|_| "failed to read from source file")?;
// Create a typesetter with a font provider that provides the default fonts.
let mut typesetter = Typesetter::new();
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index 78e48e81..b7ad21c7 100644
--- a/src/export/pdf.rs
+++ b/src/export/pdf.rs
@@ -3,21 +3,22 @@
use std::collections::{HashMap, HashSet};
use std::io::{self, Write};
-use tide::{PdfWriter, Ref, Rect, Version, Trailer};
use tide::content::Content;
-use tide::doc::{Catalog, PageTree, Page, Resource, Text};
-use tide::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags};
-use tide::font::{GlyphUnit, CMap, CMapEncoding, WidthRecord, FontStream};
+use tide::doc::{Catalog, Page, PageTree, Resource, Text};
+use tide::font::{CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags, Type0Font};
+use tide::font::{CMap, CMapEncoding, FontStream, GlyphUnit, WidthRecord};
+use tide::{PdfWriter, Rect, Ref, Trailer, Version};
-use toddle::tables::{Header, Post, OS2, HorizontalMetrics, CharMap, Name, NameEntry, MacStyleFlags};
use toddle::font::OwnedFont;
use toddle::query::SharedFontLoader;
+use toddle::tables::{
+ CharMap, Header, HorizontalMetrics, MacStyleFlags, Name, NameEntry, Post, OS2,
+};
use toddle::Error as FontError;
-use crate::layout::{MultiLayout, Layout, LayoutAction};
+use crate::layout::{Layout, LayoutAction, MultiLayout};
use crate::size::{Size, Size2D};
-
/// Exports layouts into _PDFs_.
#[derive(Debug)]
pub struct PdfExporter {}
@@ -29,10 +30,16 @@ impl PdfExporter {
PdfExporter {}
}
- /// Export a finished layouts into a writer. Returns how many bytes were written.
+ /// Export a finished layouts into a writer. Returns how many bytes were
+ /// written.
#[inline]
- pub fn export<W: Write>(&self, layout: &MultiLayout, loader: &SharedFontLoader, target: W)
- -> PdfResult<usize> {
+ pub fn export<W: Write>(
+ &self,
+ layout: &MultiLayout,
+ loader: &SharedFontLoader,
+ target: W,
+ ) -> PdfResult<usize>
+ {
let mut engine = PdfEngine::new(layout, loader, target)?;
engine.write()
}
@@ -59,8 +66,12 @@ struct Offsets {
impl<'d, W: Write> PdfEngine<'d, W> {
/// Create a new _PDF_ engine.
- fn new(layout: &'d MultiLayout, loader: &SharedFontLoader, target: W)
- -> PdfResult<PdfEngine<'d, W>> {
+ fn new(
+ layout: &'d MultiLayout,
+ loader: &SharedFontLoader,
+ target: W,
+ ) -> PdfResult<PdfEngine<'d, W>>
+ {
// Create a subsetted PDF font for each font in the layout.
let mut font_remap = HashMap::new();
let fonts = {
@@ -71,24 +82,26 @@ impl<'d, W: Write> PdfEngine<'d, W> {
for boxed in &layout.layouts {
for action in &boxed.actions {
match action {
- LayoutAction::WriteText(string) => {
- chars.entry(font)
- .or_insert_with(HashSet::new)
- .extend(string.chars())
- },
+ LayoutAction::WriteText(string) => chars
+ .entry(font)
+ .or_insert_with(HashSet::new)
+ .extend(string.chars()),
LayoutAction::SetFont(id, _) => {
font = *id;
let new_id = font_remap.len();
font_remap.entry(font).or_insert(new_id);
- },
- _ => {},
+ }
+ _ => {}
}
}
}
// Collect the fonts into a vector in the order of the values in the remapping.
let mut loader = loader.borrow_mut();
- let mut order = font_remap.iter().map(|(&old, &new)| (old, new)).collect::<Vec<_>>();
+ let mut order = font_remap
+ .iter()
+ .map(|(&old, &new)| (old, new))
+ .collect::<Vec<_>>();
order.sort_by_key(|&(_, new)| new);
let mut fonts = vec![];
@@ -96,8 +109,10 @@ impl<'d, W: Write> PdfEngine<'d, W> {
let font = loader.get_with_index(index);
let subsetted = font.subsetted(
chars[&index].iter().cloned(),
- &["name", "OS/2", "post", "head", "hhea", "hmtx", "maxp",
- "cmap", "cvt ", "fpgm", "prep", "loca", "glyf"][..]
+ &[
+ "name", "OS/2", "post", "head", "hhea", "hmtx", "maxp", "cmap", "cvt ",
+ "fpgm", "prep", "loca", "glyf",
+ ][..],
)?;
fonts.push(OwnedFont::from_bytes(subsetted)?);
}
@@ -111,7 +126,13 @@ impl<'d, W: Write> PdfEngine<'d, W> {
let pages = (page_tree + 1, page_tree + layout.layouts.len() as Ref);
let contents = (pages.1 + 1, pages.1 + layout.layouts.len() as Ref);
let font_offsets = (contents.1 + 1, contents.1 + 5 * fonts.len() as Ref);
- let offsets = Offsets { catalog, page_tree, pages, contents, fonts: font_offsets };
+ let offsets = Offsets {
+ catalog,
+ page_tree,
+ pages,
+ contents,
+ fonts: font_offsets,
+ };
Ok(PdfEngine {
writer: PdfWriter::new(target),
@@ -129,32 +150,43 @@ impl<'d, W: Write> PdfEngine<'d, W> {
self.write_pages()?;
self.write_fonts()?;
self.writer.write_xref_table()?;
- self.writer.write_trailer(Trailer::new(self.offsets.catalog))?;
+ self.writer
+ .write_trailer(Trailer::new(self.offsets.catalog))?;
Ok(self.writer.written())
}
/// Write the document catalog and page tree.
fn write_page_tree(&mut self) -> PdfResult<()> {
// The document catalog
- self.writer.write_obj(self.offsets.catalog, &Catalog::new(self.offsets.page_tree))?;
+ self.writer
+ .write_obj(self.offsets.catalog, &Catalog::new(self.offsets.page_tree))?;
// The font resources
let offset = self.offsets.fonts.0;
- let fonts = (0 .. self.fonts.len())
- .map(|i| Resource::Font((i + 1) as u32, offset + 5 * i as u32));
+ let fonts =
+ (0..self.fonts.len()).map(|i| Resource::Font((i + 1) as u32, offset + 5 * i as u32));
// The root page tree
- self.writer.write_obj(self.offsets.page_tree, PageTree::new()
- .kids(ids(self.offsets.pages))
- .resources(fonts)
+ self.writer.write_obj(
+ self.offsets.page_tree,
+ PageTree::new()
+ .kids(ids(self.offsets.pages))
+ .resources(fonts),
)?;
// The page objects
for (id, page) in ids(self.offsets.pages).zip(&self.layout.layouts) {
- let rect = Rect::new(0.0, 0.0, page.dimensions.x.to_pt(), page.dimensions.y.to_pt());
- self.writer.write_obj(id, Page::new(self.offsets.page_tree)
- .media_box(rect)
- .contents(ids(self.offsets.contents))
+ let rect = Rect::new(
+ 0.0,
+ 0.0,
+ page.dimensions.x.to_pt(),
+ page.dimensions.y.to_pt(),
+ );
+ self.writer.write_obj(
+ id,
+ Page::new(self.offsets.page_tree)
+ .media_box(rect)
+ .contents(ids(self.offsets.contents)),
)?;
}
@@ -202,8 +234,8 @@ impl<'d, W: Write> PdfEngine<'d, W> {
// Write the text.
text.tj(self.fonts[active_font.0].encode_text(&string)?);
- },
- LayoutAction::DebugBox(_, _) => {},
+ }
+ LayoutAction::DebugBox(_, _) => {}
}
}
@@ -217,18 +249,21 @@ impl<'d, W: Write> PdfEngine<'d, W> {
let mut id = self.offsets.fonts.0;
for font in &mut self.fonts {
- let name = font.read_table::<Name>()?
+ let name = font
+ .read_table::<Name>()?
.get_decoded(NameEntry::PostScriptName)
.unwrap_or_else(|| "unknown".to_string());
let base_font = format!("ABCDEF+{}", name);
// Write the base font object referencing the CID font.
- self.writer.write_obj(id,
+ self.writer.write_obj(
+ id,
Type0Font::new(
base_font.clone(),
CMapEncoding::Predefined("Identity-H".to_owned()),
- id + 1
- ).to_unicode(id + 3)
+ id + 1,
+ )
+ .to_unicode(id + 3),
)?;
// Extract information from the head table.
@@ -252,19 +287,22 @@ impl<'d, W: Write> PdfEngine<'d, W> {
// Transform the width into PDF units.
let widths: Vec<_> = font
.read_table::<HorizontalMetrics>()?
- .metrics.iter()
+ .metrics
+ .iter()
.map(|m| font_unit_to_glyph_unit(m.advance_width as f32))
.collect();
// Write the CID font referencing the font descriptor.
let system_info = CIDSystemInfo::new("Adobe", "Identity", 0);
- self.writer.write_obj(id + 1,
+ self.writer.write_obj(
+ id + 1,
CIDFont::new(
CIDFontType::Type2,
base_font.clone(),
system_info.clone(),
id + 2,
- ).widths(vec![WidthRecord::start(0, widths)])
+ )
+ .widths(vec![WidthRecord::start(0, widths)]),
)?;
// Extract information from the post table.
@@ -284,24 +322,31 @@ impl<'d, W: Write> PdfEngine<'d, W> {
let os2 = font.read_table::<OS2>()?;
// Write the font descriptor (contains the global information about the font).
- self.writer.write_obj(id + 2,
+ self.writer.write_obj(
+ id + 2,
FontDescriptor::new(base_font, flags, italic_angle)
.font_bbox(bounding_box)
.ascent(font_unit_to_glyph_unit(os2.s_typo_ascender as f32))
.descent(font_unit_to_glyph_unit(os2.s_typo_descender as f32))
- .cap_height(font_unit_to_glyph_unit(os2.s_cap_height.unwrap_or(os2.s_typo_ascender) as f32))
+ .cap_height(font_unit_to_glyph_unit(
+ os2.s_cap_height.unwrap_or(os2.s_typo_ascender) as f32,
+ ))
.stem_v((10.0 + 0.244 * (os2.us_weight_class as f32 - 50.0)) as GlyphUnit)
- .font_file_2(id + 4)
+ .font_file_2(id + 4),
)?;
// Write the CMap, which maps glyphs to unicode codepoints.
- let mapping = font.read_table::<CharMap>()?
- .mapping.iter()
+ let mapping = font
+ .read_table::<CharMap>()?
+ .mapping
+ .iter()
.map(|(&c, &cid)| (cid, c));
- self.writer.write_obj(id + 3, &CMap::new("Custom", system_info, mapping))?;
+ self.writer
+ .write_obj(id + 3, &CMap::new("Custom", system_info, mapping))?;
// Finally write the subsetted font program.
- self.writer.write_obj(id + 4, &FontStream::new(font.data().get_ref()))?;
+ self.writer
+ .write_obj(id + 4, &FontStream::new(font.data().get_ref()))?;
id += 5;
}
@@ -311,8 +356,8 @@ impl<'d, W: Write> PdfEngine<'d, W> {
}
/// Create an iterator from a reference pair.
-fn ids((start, end): (Ref, Ref)) -> impl Iterator<Item=Ref> {
- start ..= end
+fn ids((start, end): (Ref, Ref)) -> impl Iterator<Item = Ref> {
+ start..=end
}
/// The error type for _PDF_ creation.
diff --git a/src/func.rs b/src/func.rs
index cbe7a31a..1f1b928d 100644
--- a/src/func.rs
+++ b/src/func.rs
@@ -6,27 +6,27 @@ use std::fmt::{self, Debug, Formatter};
use toddle::query::FontClass;
-use crate::layout::{Layout, MultiLayout , LayoutContext, LayoutResult};
+use crate::layout::{Layout, LayoutContext, LayoutResult, MultiLayout};
use crate::parsing::{ParseContext, ParseResult};
-use crate::syntax::{SyntaxTree, FuncHeader};
-
+use crate::syntax::{FuncHeader, SyntaxTree};
/// Typesetting function types.
///
-/// These types have to be able to parse tokens into themselves and store the relevant information
-/// from the parsing to do their role in typesetting later.
+/// These types have to be able to parse tokens into themselves and store the
+/// relevant information from the parsing to do their role in typesetting later.
///
-/// The trait `FunctionBounds` is automatically implemented for types which can be used as
-/// functions, that is they fulfill the bounds `Debug + PartialEq + 'static`.
+/// The trait `FunctionBounds` is automatically implemented for types which can
+/// be used as functions, that is they fulfill the bounds `Debug + PartialEq +
+/// 'static`.
pub trait Function: FunctionBounds {
/// Parse the header and body into this function given a context.
- fn parse(header: &FuncHeader, body: Option<&str>, ctx: ParseContext)
- -> ParseResult<Self> where Self: Sized;
+ fn parse(header: &FuncHeader, body: Option<&str>, ctx: ParseContext) -> ParseResult<Self>
+ where Self: Sized;
/// Layout this function given a context.
///
- /// Returns optionally the resulting layout and a new context if changes to the context should
- /// be made.
+ /// Returns optionally the resulting layout and a new context if changes to
+ /// the context should be made.
fn layout(&self, ctx: LayoutContext) -> LayoutResult<FuncCommands>;
}
@@ -39,15 +39,13 @@ impl PartialEq for dyn Function {
/// A sequence of commands requested for execution by a function.
#[derive(Debug)]
pub struct FuncCommands<'a> {
- pub commands: Vec<Command<'a>>
+ pub commands: Vec<Command<'a>>,
}
impl<'a> FuncCommands<'a> {
/// Create an empty command list.
pub fn new() -> FuncCommands<'a> {
- FuncCommands {
- commands: vec![],
- }
+ FuncCommands { commands: vec![] }
}
/// Add a command to the sequence.
@@ -79,10 +77,11 @@ pub enum Command<'a> {
ToggleStyleClass(FontClass),
}
-/// A helper trait that describes requirements for types that can implement [`Function`].
+/// A helper trait that describes requirements for types that can implement
+/// [`Function`].
///
-/// Automatically implemented for all types which fulfill to the bounds `Debug + PartialEq +
-/// 'static`. There should be no need to implement this manually.
+/// Automatically implemented for all types which fulfill to the bounds `Debug +
+/// PartialEq + 'static`. There should be no need to implement this manually.
pub trait FunctionBounds: Debug {
/// Cast self into `Any`.
fn help_cast_as_any(&self) -> &dyn Any;
@@ -91,7 +90,9 @@ pub trait FunctionBounds: Debug {
fn help_eq(&self, other: &dyn Function) -> bool;
}
-impl<T> FunctionBounds for T where T: Debug + PartialEq + 'static {
+impl<T> FunctionBounds for T
+where T: Debug + PartialEq + 'static
+{
fn help_cast_as_any(&self) -> &dyn Any {
self
}
@@ -111,13 +112,14 @@ pub struct Scope {
}
/// A function which parses a function invocation into a function type.
-type ParseFunc = dyn Fn(&FuncHeader, Option<&str>, ParseContext)
- -> ParseResult<Box<dyn Function>>;
+type ParseFunc = dyn Fn(&FuncHeader, Option<&str>, ParseContext) -> ParseResult<Box<dyn Function>>;
impl Scope {
/// Create a new empty scope.
pub fn new() -> Scope {
- Scope { parsers: HashMap::new() }
+ Scope {
+ parsers: HashMap::new(),
+ }
}
/// Create a new scope with the standard functions contained.
@@ -129,9 +131,7 @@ impl Scope {
pub fn add<F: Function + 'static>(&mut self, name: &str) {
self.parsers.insert(
name.to_owned(),
- Box::new(|h, b, c| {
- F::parse(h, b, c).map(|func| Box::new(func) as Box<dyn Function>)
- })
+ Box::new(|h, b, c| F::parse(h, b, c).map(|func| Box::new(func) as Box<dyn Function>)),
);
}
diff --git a/src/layout/actions.rs b/src/layout/actions.rs
index 069c3f7c..3eb4fb7f 100644
--- a/src/layout/actions.rs
+++ b/src/layout/actions.rs
@@ -3,11 +3,10 @@
use std::fmt::{self, Display, Formatter};
use std::io::{self, Write};
-use crate::size::Size2D;
use super::Layout;
+use crate::size::Size2D;
use LayoutAction::*;
-
/// A layouting action.
#[derive(Clone)]
pub enum LayoutAction {
@@ -30,8 +29,14 @@ impl LayoutAction {
MoveAbsolute(s) => write!(f, "m {:.4} {:.4}", s.x.to_pt(), s.y.to_pt()),
SetFont(i, s) => write!(f, "f {} {}", i, s),
WriteText(s) => write!(f, "w {}", s),
- DebugBox(p, s) => write!(f, "b {} {} {} {}",
- p.x.to_pt(), p.y.to_pt(), s.x.to_pt(), s.y.to_pt())
+ DebugBox(p, s) => write!(
+ f,
+ "b {} {} {} {}",
+ p.x.to_pt(),
+ p.y.to_pt(),
+ s.x.to_pt(),
+ s.y.to_pt()
+ ),
}
}
}
@@ -81,7 +86,7 @@ impl LayoutActionList {
SetFont(index, size) if (index, size) != self.active_font => {
self.next_font = Some((index, size));
- },
+ }
_ => {
if let Some(target) = self.next_pos.take() {
@@ -92,19 +97,21 @@ impl LayoutActionList {
}
self.actions.push(action);
- },
+ }
}
}
/// Add a series of actions.
- pub fn extend<I>(&mut self, actions: I) where I: IntoIterator<Item=LayoutAction> {
+ pub fn extend<I>(&mut self, actions: I)
+ where I: IntoIterator<Item = LayoutAction> {
for action in actions.into_iter() {
self.add(action);
}
}
/// Add all actions from a box layout at a position. A move to the position
- /// is generated and all moves inside the box layout are translated as necessary.
+ /// is generated and all moves inside the box layout are translated as
+ /// necessary.
pub fn add_box(&mut self, position: Size2D, layout: Layout) {
if let Some(target) = self.next_pos.take() {
self.actions.push(MoveAbsolute(target));
@@ -114,7 +121,8 @@ impl LayoutActionList {
self.origin = position;
if layout.debug_render {
- self.actions.push(LayoutAction::DebugBox(position, layout.dimensions));
+ self.actions
+ .push(LayoutAction::DebugBox(position, layout.dimensions));
}
self.extend(layout.actions);
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 704281d3..ab1f066e 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -1,6 +1,5 @@
use super::*;
-
/// Finishes a flex layout by justifying the positions of the individual boxes.
#[derive(Debug)]
pub struct FlexLayouter {
@@ -32,7 +31,8 @@ enum FlexUnit {
/// A content unit to be arranged flexibly.
Boxed(Layout),
/// A unit which acts as glue between two [`FlexUnit::Boxed`] units and
- /// is only present if there was no flow break in between the two surrounding boxes.
+ /// is only present if there was no flow break in between the two
+ /// surrounding boxes.
Glue(Layout),
}
@@ -107,7 +107,9 @@ impl FlexLayouter {
/// Layout the box.
fn boxed(&mut self, boxed: Layout) -> LayoutResult<()> {
- let last_glue_x = self.last_glue.as_ref()
+ let last_glue_x = self
+ .last_glue
+ .as_ref()
.map(|g| g.dimensions.x)
.unwrap_or(Size::zero());
@@ -157,7 +159,7 @@ impl FlexLayouter {
// Right align everything by shifting it right by the
// amount of space left to the right of the line.
cursor + remaining_space
- },
+ }
};
self.actions.add_box(position, layout);
@@ -173,7 +175,8 @@ impl FlexLayouter {
self.dimensions.y += self.line_metrics.y;
- // Reset the cursor the left and move down by the line and the inter-line spacing.
+ // Reset the cursor the left and move down by the line and the inter-line
+ // spacing.
self.cursor.x = self.ctx.space.padding.left;
self.cursor.y += self.line_metrics.y + self.ctx.flex_spacing;
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index c8d10141..14aa6417 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -4,24 +4,23 @@ use std::borrow::Cow;
use std::io::{self, Write};
use std::mem;
-use toddle::query::{SharedFontLoader, FontClass};
+use toddle::query::{FontClass, SharedFontLoader};
use toddle::Error as FontError;
use crate::func::Command;
use crate::size::{Size, Size2D, SizeBox};
-use crate::syntax::{SyntaxTree, Node, FuncCall};
use crate::style::TextStyle;
+use crate::syntax::{FuncCall, Node, SyntaxTree};
-mod text;
-mod stacked;
-mod flex;
mod actions;
+mod flex;
+mod stacked;
+mod text;
pub use actions::{LayoutAction, LayoutActionList};
+pub use flex::{FlexContext, FlexLayouter};
+pub use stacked::{StackContext, StackLayouter};
pub use text::{layout_text, TextContext};
-pub use flex::{FlexLayouter, FlexContext};
-pub use stacked::{StackLayouter, StackContext};
-
/// A box layout has a fixed width and height and composes of actions.
#[derive(Debug, Clone)]
@@ -37,7 +36,12 @@ pub struct Layout {
impl Layout {
/// Serialize this layout into an output buffer.
pub fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
- writeln!(f, "{:.4} {:.4}", self.dimensions.x.to_pt(), self.dimensions.y.to_pt())?;
+ writeln!(
+ f,
+ "{:.4} {:.4}",
+ self.dimensions.x.to_pt(),
+ self.dimensions.y.to_pt()
+ )?;
for action in &self.actions {
action.serialize(f)?;
writeln!(f)?;
@@ -55,9 +59,7 @@ pub struct MultiLayout {
impl MultiLayout {
/// Create an empty multibox layout.
pub fn new() -> MultiLayout {
- MultiLayout {
- layouts: vec![],
- }
+ MultiLayout { layouts: vec![] }
}
/// Extract a single sublayout and panic if this layout does not have
@@ -158,7 +160,7 @@ impl<'a, 'p> Layouter<'a, 'p> {
},
flex_spacing: (ctx.style.line_spacing - 1.0) * Size::pt(ctx.style.font_size),
}),
- style: Cow::Borrowed(ctx.style)
+ style: Cow::Borrowed(ctx.style),
}
}
@@ -175,7 +177,7 @@ impl<'a, 'p> Layouter<'a, 'p> {
if !self.flex_layouter.is_empty() {
self.layout_text(" ", true)?;
}
- },
+ }
// Finish the current flex layout and add it to the box layouter.
Node::Newline => {
@@ -186,7 +188,7 @@ impl<'a, 'p> Layouter<'a, 'p> {
let size = Size::pt(self.style.font_size)
* (self.style.line_spacing * self.style.paragraph_spacing - 1.0);
self.stack_layouter.add_space(size)?;
- },
+ }
// Toggle the text styles.
Node::ToggleItalics => self.style.to_mut().toggle_class(FontClass::Italic),
@@ -208,16 +210,19 @@ impl<'a, 'p> Layouter<'a, 'p> {
}
Ok(MultiLayout {
- layouts: vec![self.stack_layouter.finish()]
+ layouts: vec![self.stack_layouter.finish()],
})
}
/// Layout a piece of text into a box.
fn layout_text(&mut self, text: &str, glue: bool) -> LayoutResult<()> {
- let boxed = layout_text(text, TextContext {
- loader: &self.ctx.loader,
- style: &self.style,
- })?;
+ let boxed = layout_text(
+ text,
+ TextContext {
+ loader: &self.ctx.loader,
+ style: &self.style,
+ },
+ )?;
if glue {
self.flex_layouter.add_glue(boxed);
diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs
index 312681ac..5ca32970 100644
--- a/src/layout/stacked.rs
+++ b/src/layout/stacked.rs
@@ -1,6 +1,5 @@
use super::*;
-
/// Layouts boxes block-style.
#[derive(Debug)]
pub struct StackLayouter {
@@ -29,10 +28,13 @@ impl StackLayouter {
Alignment::Right => Size2D::with_x(space.usable().x),
},
usable: space.usable(),
- cursor: Size2D::new(match ctx.space.alignment {
- Alignment::Left => space.padding.left,
- Alignment::Right => space.dimensions.x - space.padding.right,
- }, space.padding.top),
+ cursor: Size2D::new(
+ match ctx.space.alignment {
+ Alignment::Left => space.padding.left,
+ Alignment::Right => space.dimensions.x - space.padding.right,
+ },
+ space.padding.top,
+ ),
}
}
diff --git a/src/layout/text.rs b/src/layout/text.rs
index cf258029..27b65d56 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -1,9 +1,8 @@
use toddle::query::{FontQuery, SharedFontLoader};
-use toddle::tables::{Header, CharMap, HorizontalMetrics};
+use toddle::tables::{CharMap, Header, HorizontalMetrics};
-use crate::size::{Size, Size2D};
use super::*;
-
+use crate::size::{Size, Size2D};
/// The context for text layouting.
#[derive(Copy, Clone)]
@@ -53,7 +52,8 @@ pub fn layout_text(text: &str, ctx: TextContext) -> LayoutResult<Layout> {
let font_unit_to_size = |x| Size::pt(font_unit_ratio * x);
// Add the char width to the total box width.
- let glyph = font.read_table::<CharMap>()?
+ let glyph = font
+ .read_table::<CharMap>()?
.get(character)
.expect("layout text: font should have char");
@@ -61,7 +61,7 @@ pub fn layout_text(text: &str, ctx: TextContext) -> LayoutResult<Layout> {
font.read_table::<HorizontalMetrics>()?
.get(glyph)
.expect("layout text: font should have glyph")
- .advance_width as f32
+ .advance_width as f32,
);
let char_width = glyph_width * ctx.style.font_size;
diff --git a/src/lib.rs b/src/lib.rs
index 00ed9e29..fe9d32a6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,26 +1,28 @@
//! The compiler for the _Typst_ typesetting language.
//!
//! # Steps
-//! - **Parsing:** The parsing step first transforms a plain string into an [iterator of
-//! tokens](crate::parsing::Tokens). Then parser constructs a syntax tree from the token stream.
-//! The structures describing the tree can be found in the [syntax]. Dynamic functions parse
-//! their own bodies themselves.
-//! - **Layouting:** The next step is to transform the syntax tree into a portable representation of
-//! the typesetted document. Types for these can be found in the [layout] module.
-//! - **Exporting:** The finished document can then be exported into supported formats. Submodules
-//! for the supported formats are located in the [export] module. Currently the only supported
-//! format is _PDF_.
+//! - **Parsing:** The parsing step first transforms a plain string into an
+//! [iterator of tokens](crate::parsing::Tokens). Then parser constructs a
+//! syntax tree from the token stream. The structures describing the tree can
+//! be found in the [syntax]. Dynamic functions parse their own bodies
+//! themselves.
+//! - **Layouting:** The next step is to transform the syntax tree into a
+//! portable representation of the typesetted document. Types for these can be
+//! found in the [layout] module.
+//! - **Exporting:** The finished document can then be exported into supported
+//! formats. Submodules for the supported formats are located in the [export]
+//! module. Currently the only supported format is _PDF_.
pub extern crate toddle;
use std::cell::RefCell;
-use toddle::query::{FontLoader, SharedFontLoader, FontProvider};
+use toddle::query::{FontLoader, FontProvider, SharedFontLoader};
use crate::func::Scope;
-use crate::parsing::{parse, ParseContext, ParseResult, ParseError};
use crate::layout::{layout_tree, LayoutContext, MultiLayout};
-use crate::layout::{LayoutSpace, Alignment, LayoutError, LayoutResult};
+use crate::layout::{Alignment, LayoutError, LayoutResult, LayoutSpace};
+use crate::parsing::{parse, ParseContext, ParseError, ParseResult};
use crate::style::{PageStyle, TextStyle};
use crate::syntax::SyntaxTree;
@@ -29,12 +31,11 @@ mod macros;
pub mod export;
pub mod func;
pub mod layout;
+pub mod library;
pub mod parsing;
pub mod size;
pub mod style;
pub mod syntax;
-pub mod library;
-
/// Transforms source code into typesetted documents.
///
@@ -73,7 +74,8 @@ impl<'p> Typesetter<'p> {
/// Add a font provider to the context of this typesetter.
#[inline]
- pub fn add_font_provider<P: 'p>(&mut self, provider: P) where P: FontProvider {
+ pub fn add_font_provider<P: 'p>(&mut self, provider: P)
+ where P: FontProvider {
self.loader.get_mut().add_provider(provider);
}
@@ -98,12 +100,15 @@ impl<'p> Typesetter<'p> {
shrink_to_fit: false,
};
- let pages = layout_tree(&tree, LayoutContext {
- loader: &self.loader,
- style: &self.text_style,
- space,
- extra_space: Some(space),
- })?;
+ let pages = layout_tree(
+ &tree,
+ LayoutContext {
+ loader: &self.loader,
+ style: &self.text_style,
+ space,
+ extra_space: Some(space),
+ },
+ )?;
Ok(pages)
}
@@ -116,7 +121,6 @@ impl<'p> Typesetter<'p> {
}
}
-
/// The general error type for typesetting.
pub enum TypesetError {
/// An error that occured while parsing.
diff --git a/src/library/align.rs b/src/library/align.rs
index 322a9efa..4dc5f53c 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -1,7 +1,6 @@
use super::prelude::*;
use crate::layout::Alignment;
-
/// Allows to align content in different ways.
#[derive(Debug, PartialEq)]
pub struct AlignFunc {
@@ -10,9 +9,8 @@ pub struct AlignFunc {
}
impl Function for AlignFunc {
- fn parse(header: &FuncHeader, body: Option<&str>, ctx: ParseContext)
- -> ParseResult<Self> where Self: Sized {
-
+ fn parse(header: &FuncHeader, body: Option<&str>, ctx: ParseContext) -> ParseResult<Self>
+ where Self: Sized {
if header.args.len() != 1 || !header.kwargs.is_empty() {
return err("expected exactly one positional argument specifying the alignment");
}
@@ -24,7 +22,10 @@ impl Function for AlignFunc {
s => return err(format!("invalid alignment specifier: '{}'", s)),
}
} else {
- return err(format!("expected alignment specifier, found: '{}'", header.args[0]));
+ return err(format!(
+ "expected alignment specifier, found: '{}'",
+ header.args[0]
+ ));
};
let body = if let Some(body) = body {
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 848ba847..f3156b4a 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -7,11 +7,11 @@ mod styles;
/// Useful imports for creating your own functions.
pub mod prelude {
- pub use crate::syntax::{SyntaxTree, FuncHeader, Expression};
- pub use crate::parsing::{parse, ParseContext, ParseResult, ParseError};
- pub use crate::layout::{layout_tree, LayoutContext, MultiLayout, Layout};
- pub use crate::layout::{LayoutResult, LayoutError};
- pub use crate::func::{Function, Command, FuncCommands};
+ pub use crate::func::{Command, FuncCommands, Function};
+ pub use crate::layout::{layout_tree, Layout, LayoutContext, MultiLayout};
+ pub use crate::layout::{LayoutError, LayoutResult};
+ pub use crate::parsing::{parse, ParseContext, ParseError, ParseResult};
+ pub use crate::syntax::{Expression, FuncHeader, SyntaxTree};
pub fn err<S: Into<String>, T>(message: S) -> ParseResult<T> {
Err(ParseError::new(message))
@@ -19,8 +19,7 @@ pub mod prelude {
}
pub use align::AlignFunc;
-pub use styles::{ItalicFunc, BoldFunc, MonospaceFunc};
-
+pub use styles::{BoldFunc, ItalicFunc, MonospaceFunc};
/// Create a scope with all standard functions.
pub fn std() -> Scope {
diff --git a/src/library/styles.rs b/src/library/styles.rs
index c588ac5e..666c8975 100644
--- a/src/library/styles.rs
+++ b/src/library/styles.rs
@@ -2,7 +2,6 @@ use toddle::query::FontClass;
use super::prelude::*;
-
macro_rules! style_func {
(
$(#[$outer:meta])*
diff --git a/src/parsing/mod.rs b/src/parsing/mod.rs
index fa71270e..0f5ca0f8 100644
--- a/src/parsing/mod.rs
+++ b/src/parsing/mod.rs
@@ -5,14 +5,13 @@ use std::collections::HashMap;
use unicode_xid::UnicodeXID;
use crate::func::{Function, Scope};
-use crate::syntax::*;
use crate::size::Size;
+use crate::syntax::*;
mod tokens;
pub use tokens::{tokenize, Tokens};
-
/// Parses source code into a syntax tree given a context.
#[inline]
pub fn parse(src: &str, ctx: ParseContext) -> ParseResult<SyntaxTree> {
@@ -105,10 +104,7 @@ impl<'s> Parser<'s> {
let body = self.parse_func_body(&header)?;
// Finally this function is parsed to the end.
- self.append(Node::Func(FuncCall {
- header,
- body,
- }));
+ self.append(Node::Func(FuncCall { header, body }));
Ok(self.switch(ParserState::Body))
}
@@ -124,7 +120,7 @@ impl<'s> Parser<'s> {
} else {
Err(ParseError::new(format!("invalid identifier: '{}'", word)))
}
- },
+ }
_ => Err(ParseError::new("expected identifier")),
}?;
@@ -138,13 +134,17 @@ impl<'s> Parser<'s> {
// Check for arguments
match self.tokens.next() {
- Some(Token::RightBracket) => {},
+ Some(Token::RightBracket) => {}
Some(Token::Colon) => {
let (args, kwargs) = self.parse_func_args()?;
header.args = args;
header.kwargs = kwargs;
- },
- _ => return Err(ParseError::new("expected function arguments or closing bracket")),
+ }
+ _ => {
+ return Err(ParseError::new(
+ "expected function arguments or closing bracket",
+ ))
+ }
}
// Store the header information of the function invocation.
@@ -164,16 +164,16 @@ impl<'s> Parser<'s> {
Some(Token::Text(_)) | Some(Token::Quoted(_)) if !comma => {
args.push(self.parse_expression()?);
comma = true;
- },
+ }
Some(Token::Comma) if comma => {
self.advance();
comma = false
- },
+ }
Some(Token::RightBracket) => {
self.advance();
- break
- },
+ break;
+ }
_ if comma => return Err(ParseError::new("expected comma or closing bracket")),
_ => return Err(ParseError::new("expected closing bracket")),
@@ -197,7 +197,7 @@ impl<'s> Parser<'s> {
} else {
Expression::Ident(text.to_owned())
}
- },
+ }
_ => return Err(ParseError::new("expected expression")),
})
}
@@ -211,19 +211,25 @@ impl<'s> Parser<'s> {
}
// Now we want to parse this function dynamically.
- let parser = self.ctx.scope.get_parser(&header.name)
+ let parser = self
+ .ctx
+ .scope
+ .get_parser(&header.name)
.ok_or_else(|| ParseError::new(format!("unknown function: '{}'", &header.name)))?;
// Do the parsing dependent on whether the function has a body.
Ok(if has_body {
// Find out the string which makes the body of this function.
- let (start, end) = self.tokens.current_index().and_then(|index| {
- find_closing_bracket(&self.src[index..])
- .map(|end| (index, index + end))
- }).ok_or_else(|| ParseError::new("expected closing bracket"))?;
+ let (start, end) = self
+ .tokens
+ .current_index()
+ .and_then(|index| {
+ find_closing_bracket(&self.src[index..]).map(|end| (index, index + end))
+ })
+ .ok_or_else(|| ParseError::new("expected closing bracket"))?;
// Parse the body.
- let body_string = &self.src[start .. end];
+ let body_string = &self.src[start..end];
let body = parser(&header, Some(body_string), self.ctx)?;
// Skip to the end of the function in the token stream.
@@ -246,12 +252,12 @@ impl<'s> Parser<'s> {
Token::Newline => {
self.append_consumed(Node::Newline);
self.switch(ParserState::WroteNewline);
- },
+ }
Token::Space => self.append_space_consumed(),
_ => {
self.append_space();
self.switch(ParserState::Body);
- },
+ }
},
ParserState::WroteNewline => match token {
Token::Newline | Token::Space => self.append_space_consumed(),
@@ -263,17 +269,17 @@ impl<'s> Parser<'s> {
Token::Newline => {
self.advance();
self.switch(ParserState::FirstNewline);
- },
+ }
// Comments
Token::LineComment(_) | Token::BlockComment(_) => self.advance(),
Token::StarSlash => {
return Err(ParseError::new("unexpected end of block comment"));
- },
+ }
// Anything else skips out of the function.
_ => break,
- }
+ },
}
}
@@ -284,8 +290,9 @@ impl<'s> Parser<'s> {
fn skip_white(&mut self) {
while let Some(token) = self.tokens.peek() {
match token {
- Token::Space | Token::Newline
- | Token::LineComment(_) | Token::BlockComment(_) => self.advance(),
+ Token::Space | Token::Newline | Token::LineComment(_) | Token::BlockComment(_) => {
+ self.advance()
+ }
_ => break,
}
}
@@ -335,19 +342,19 @@ fn find_closing_bracket(src: &str) -> Option<usize> {
'\\' => {
escaped = !escaped;
continue;
- },
+ }
']' if !escaped && parens == 0 => return Some(index),
'[' if !escaped => parens += 1,
']' if !escaped => parens -= 1,
- _ => {},
+ _ => {}
}
escaped = false;
}
None
}
-/// A peekable iterator for tokens which allows access to the original iterator inside this module
-/// (which is needed by the parser).
+/// A peekable iterator for tokens which allows access to the original iterator
+/// inside this module (which is needed by the parser).
#[derive(Debug, Clone)]
struct PeekableTokens<'s> {
tokens: Tokens<'s>,
@@ -411,7 +418,6 @@ fn is_identifier(string: &str) -> bool {
true
}
-
/// The error type for parsing.
pub struct ParseError(String);
@@ -430,17 +436,16 @@ error_type! {
show: f => f.write_str(&err.0),
}
-
#[cfg(test)]
mod tests {
use super::*;
- use crate::func::{Function, FuncCommands, Scope};
+ use crate::func::{FuncCommands, Function, Scope};
use crate::layout::{LayoutContext, LayoutResult};
- use Node::{Space as S, Newline as N, Func as F};
use funcs::*;
+ use Node::{Func as F, Newline as N, Space as S};
- /// Two test functions, one which parses it's body as another syntax tree and another one which
- /// does not expect a body.
+ /// Two test functions, one which parses it's body as another syntax tree
+ /// and another one which does not expect a body.
mod funcs {
use super::*;
@@ -449,8 +454,8 @@ mod tests {
pub struct TreeFn(pub SyntaxTree);
impl Function for TreeFn {
- fn parse(_: &FuncHeader, body: Option<&str>, ctx: ParseContext)
- -> ParseResult<Self> where Self: Sized {
+ fn parse(_: &FuncHeader, body: Option<&str>, ctx: ParseContext) -> ParseResult<Self>
+ where Self: Sized {
if let Some(src) = body {
parse(src, ctx).map(|tree| TreeFn(tree))
} else {
@@ -468,8 +473,8 @@ mod tests {
pub struct BodylessFn;
impl Function for BodylessFn {
- fn parse(_: &FuncHeader, body: Option<&str>, _: ParseContext)
- -> ParseResult<Self> where Self: Sized {
+ fn parse(_: &FuncHeader, body: Option<&str>, _: ParseContext) -> ParseResult<Self>
+ where Self: Sized {
if body.is_none() {
Ok(BodylessFn)
} else {
@@ -485,7 +490,9 @@ mod tests {
/// Test if the source code parses into the syntax tree.
fn test(src: &str, tree: SyntaxTree) {
- let ctx = ParseContext { scope: &Scope::new() };
+ let ctx = ParseContext {
+ scope: &Scope::new(),
+ };
assert_eq!(parse(src, ctx).unwrap(), tree);
}
@@ -497,7 +504,9 @@ mod tests {
/// Test if the source parses into the error.
fn test_err(src: &str, err: &str) {
- let ctx = ParseContext { scope: &Scope::new() };
+ let ctx = ParseContext {
+ scope: &Scope::new(),
+ };
assert_eq!(parse(src, ctx).unwrap_err().to_string(), err);
}
@@ -509,9 +518,12 @@ mod tests {
/// Create a text node.
#[allow(non_snake_case)]
- fn T(s: &str) -> Node { Node::Text(s.to_owned()) }
+ fn T(s: &str) -> Node {
+ Node::Text(s.to_owned())
+ }
- /// Shortcut macro to create a syntax tree. Is `vec`-like and the elements are the nodes.
+ /// Shortcut macro to create a syntax tree. Is `vec`-like and the elements
+ /// are the nodes.
macro_rules! tree {
($($x:expr),*) => (
SyntaxTree { nodes: vec![$($x),*] }
diff --git a/src/parsing/tokens.rs b/src/parsing/tokens.rs
index 869e3821..295b13d8 100644
--- a/src/parsing/tokens.rs
+++ b/src/parsing/tokens.rs
@@ -4,7 +4,6 @@ use smallvec::SmallVec;
use crate::syntax::*;
-
/// Builds an iterator over the tokens of the source code.
#[inline]
pub fn tokenize(src: &str) -> Tokens {
@@ -15,7 +14,7 @@ pub fn tokenize(src: &str) -> Tokens {
#[derive(Debug, Clone)]
pub struct Tokens<'s> {
src: &'s str,
- pub(in super) chars: PeekableChars<'s>,
+ pub(super) chars: PeekableChars<'s>,
state: TokensState,
stack: SmallVec<[TokensState; 1]>,
}
@@ -56,7 +55,7 @@ impl<'s> Tokens<'s> {
/// Go back to the top-of-stack state.
fn unswitch(&mut self) {
- self.state = self.stack.pop().unwrap_or(TokensState::Body);
+ self.state = self.stack.pop().unwrap_or(TokensState::Body);
}
/// Advance and return the given token.
@@ -67,7 +66,7 @@ impl<'s> Tokens<'s> {
/// Returns a word containing the string bounded by the given indices.
fn text(&self, start: usize, end: usize) -> Token<'s> {
- Token::Text(&self.src[start .. end])
+ Token::Text(&self.src[start..end])
}
}
@@ -78,7 +77,8 @@ impl<'s> Iterator for Tokens<'s> {
fn next(&mut self) -> Option<Token<'s>> {
use TokensState as TU;
- // Go to the body state if the function has a body or return to the top-of-stack state.
+ // Go to the body state if the function has a body or return to the top-of-stack
+ // state.
if self.state == TU::MaybeBody {
if self.chars.peek()?.1 == '[' {
self.state = TU::Body;
@@ -97,7 +97,7 @@ impl<'s> Iterator for Tokens<'s> {
'[' => {
self.switch(TU::Function);
Token::LeftBracket
- },
+ }
']' => {
if self.state == TU::Function {
self.state = TU::MaybeBody;
@@ -105,7 +105,7 @@ impl<'s> Iterator for Tokens<'s> {
self.unswitch();
}
Token::RightBracket
- },
+ }
// Line comment
'/' if afterwards == Some('/') => {
@@ -121,8 +121,8 @@ impl<'s> Iterator for Tokens<'s> {
}
let end = end.0 + end.1.len_utf8();
- Token::LineComment(&self.src[start .. end])
- },
+ Token::LineComment(&self.src[start..end])
+ }
// Block comment
'/' if afterwards == Some('*') => {
@@ -133,17 +133,26 @@ impl<'s> Iterator for Tokens<'s> {
while let Some((index, c)) = self.chars.next() {
let after = self.chars.peek().map(|p| p.1);
match (c, after) {
- ('*', Some('/')) if nested == 0 => { self.advance(); break },
- ('/', Some('*')) => { self.advance(); nested += 1 },
- ('*', Some('/')) => { self.advance(); nested -= 1 },
- _ => {},
+ ('*', Some('/')) if nested == 0 => {
+ self.advance();
+ break;
+ }
+ ('/', Some('*')) => {
+ self.advance();
+ nested += 1
+ }
+ ('*', Some('/')) => {
+ self.advance();
+ nested -= 1
+ }
+ _ => {}
}
end = (index, c);
}
let end = end.0 + end.1.len_utf8();
- Token::BlockComment(&self.src[start .. end])
- },
+ Token::BlockComment(&self.src[start..end])
+ }
// Unexpected end of block comment
'*' if afterwards == Some('/') => self.consumed(Token::StarSlash),
@@ -189,7 +198,7 @@ impl<'s> Iterator for Tokens<'s> {
}
let end_pos = end.0 + end.1.len_utf8();
- Token::Quoted(&self.src[next_pos + 1 .. end_pos])
+ Token::Quoted(&self.src[next_pos + 1..end_pos])
}
// Escaping
@@ -207,7 +216,7 @@ impl<'s> Iterator for Tokens<'s> {
}
Token::Text("\\")
- },
+ }
// Normal text
_ => {
@@ -241,7 +250,7 @@ impl<'s> Iterator for Tokens<'s> {
let end_pos = end.0 + end.1.len_utf8();
self.text(next_pos, end_pos)
- },
+ }
})
}
}
@@ -328,20 +337,20 @@ impl Iterator for PeekableChars<'_> {
Some(value) => {
self.peek1 = self.peek2.take();
value
- },
+ }
None => self.next_inner(),
}
}
}
-
#[cfg(test)]
mod tests {
use super::*;
- use Token::{Space as S, Newline as N, LeftBracket as L, RightBracket as R,
- Colon as C, Equals as E, Quoted as Q, Underscore as TU, Star as TS,
- Backtick as TB, Text as T, LineComment as LC, BlockComment as BC,
- StarSlash as SS};
+ use Token::{
+ Backtick as TB, BlockComment as BC, Colon as C, Equals as E, LeftBracket as L,
+ LineComment as LC, Newline as N, Quoted as Q, RightBracket as R, Space as S, Star as TS,
+ StarSlash as SS, Text as T, Underscore as TU,
+ };
/// Test if the source code tokenizes to the tokens.
fn test(src: &str, tokens: Vec<Token>) {
diff --git a/src/size.rs b/src/size.rs
index f2e44e47..e837a639 100644
--- a/src/size.rs
+++ b/src/size.rs
@@ -6,7 +6,6 @@ use std::iter::Sum;
use std::ops::*;
use std::str::FromStr;
-
/// A general spacing type.
#[derive(Copy, Clone, PartialEq, Default)]
pub struct Size {
@@ -39,57 +38,89 @@ pub struct SizeBox {
impl Size {
/// Create a zeroed size.
#[inline]
- pub fn zero() -> Size { Size::default() }
+ pub fn zero() -> Size {
+ Size::default()
+ }
/// Create a size from an amount of points.
#[inline]
- pub fn pt(points: f32) -> Size { Size { points } }
+ pub fn pt(points: f32) -> Size {
+ Size { points }
+ }
/// Create a size from an amount of millimeters.
#[inline]
- pub fn mm(mm: f32) -> Size { Size { points: 2.83465 * mm } }
+ pub fn mm(mm: f32) -> Size {
+ Size {
+ points: 2.83465 * mm,
+ }
+ }
/// Create a size from an amount of centimeters.
#[inline]
- pub fn cm(cm: f32) -> Size { Size { points: 28.3465 * cm } }
+ pub fn cm(cm: f32) -> Size {
+ Size {
+ points: 28.3465 * cm,
+ }
+ }
/// Create a size from an amount of inches.
#[inline]
- pub fn inches(inches: f32) -> Size { Size { points: 72.0 * inches } }
+ pub fn inches(inches: f32) -> Size {
+ Size {
+ points: 72.0 * inches,
+ }
+ }
/// Convert this size into points.
#[inline]
- pub fn to_pt(&self) -> f32 { self.points }
+ pub fn to_pt(&self) -> f32 {
+ self.points
+ }
/// Convert this size into millimeters.
#[inline]
- pub fn to_mm(&self) -> f32 { self.points * 0.352778 }
+ pub fn to_mm(&self) -> f32 {
+ self.points * 0.352778
+ }
/// Convert this size into centimeters.
#[inline]
- pub fn to_cm(&self) -> f32 { self.points * 0.0352778 }
+ pub fn to_cm(&self) -> f32 {
+ self.points * 0.0352778
+ }
/// Convert this size into inches.
#[inline]
- pub fn to_inches(&self) -> f32 { self.points * 0.0138889 }
+ pub fn to_inches(&self) -> f32 {
+ self.points * 0.0138889
+ }
}
impl Size2D {
/// Create a new vector from two sizes.
#[inline]
- pub fn new(x: Size, y: Size) -> Size2D { Size2D { x, y } }
+ pub fn new(x: Size, y: Size) -> Size2D {
+ Size2D { x, y }
+ }
/// Create a vector with all set to zero.
#[inline]
- pub fn zero() -> Size2D { Size2D::default() }
+ pub fn zero() -> Size2D {
+ Size2D::default()
+ }
/// Create a new vector with `y` set to zero and `x` to a value.
#[inline]
- pub fn with_x(x: Size) -> Size2D { Size2D { x, y: Size::zero() } }
+ pub fn with_x(x: Size) -> Size2D {
+ Size2D { x, y: Size::zero() }
+ }
/// Create a new vector with `x` set to zero and `y` to a value.
#[inline]
- pub fn with_y(y: Size) -> Size2D { Size2D { x: Size::zero(), y } }
+ pub fn with_y(y: Size) -> Size2D {
+ Size2D { x: Size::zero(), y }
+ }
/// Return a [`Size2D`] padded by the paddings of the given box.
#[inline]
@@ -105,7 +136,12 @@ impl SizeBox {
/// Create a new box from four sizes.
#[inline]
pub fn new(left: Size, top: Size, right: Size, bottom: Size) -> SizeBox {
- SizeBox { left, top, right, bottom }
+ SizeBox {
+ left,
+ top,
+ right,
+ bottom,
+ }
}
/// Create a box with all set to zero.
@@ -117,12 +153,20 @@ impl SizeBox {
/// The maximum of two sizes.
pub fn max(a: Size, b: Size) -> Size {
- if a >= b { a } else { b }
+ if a >= b {
+ a
+ } else {
+ b
+ }
}
/// The minimum of two sizes.
pub fn min(a: Size, b: Size) -> Size {
- if a <= b { a } else { b }
+ if a <= b {
+ a
+ } else {
+ b
+ }
}
//------------------------------------------------------------------------------------------------//
@@ -146,10 +190,11 @@ impl FromStr for Size {
return Err(ParseSizeError);
}
- let value = src[.. src.len() - 2].parse::<f32>()
+ let value = src[..src.len() - 2]
+ .parse::<f32>()
.map_err(|_| ParseSizeError)?;
- Ok(match &src[src.len() - 2 ..] {
+ Ok(match &src[src.len() - 2..] {
"pt" => Size::pt(value),
"mm" => Size::mm(value),
"cm" => Size::cm(value),
@@ -171,13 +216,16 @@ impl Neg for Size {
#[inline]
fn neg(self) -> Size {
- Size { points: -self.points }
+ Size {
+ points: -self.points,
+ }
}
}
impl Sum for Size {
#[inline]
- fn sum<I>(iter: I) -> Size where I: Iterator<Item=Size> {
+ fn sum<I>(iter: I) -> Size
+ where I: Iterator<Item = Size> {
iter.fold(Size::zero(), Add::add)
}
}
@@ -189,7 +237,9 @@ macro_rules! impl_reflexive {
#[inline]
fn $func(self, other: Size) -> Size {
- Size { points: $trait::$func(self.points, other.points) }
+ Size {
+ points: $trait::$func(self.points, other.points),
+ }
}
}
@@ -209,7 +259,9 @@ macro_rules! impl_num_back {
#[inline]
fn $func(self, other: $ty) -> Size {
- Size { points: $trait::$func(self.points, other as f32) }
+ Size {
+ points: $trait::$func(self.points, other as f32),
+ }
}
}
@@ -231,7 +283,9 @@ macro_rules! impl_num_both {
#[inline]
fn $func(self, other: Size) -> Size {
- Size { points: $trait::$func(self as f32, other.points) }
+ Size {
+ points: $trait::$func(self as f32, other.points),
+ }
}
}
};
@@ -257,7 +311,10 @@ impl Neg for Size2D {
#[inline]
fn neg(self) -> Size2D {
- Size2D { x: -self.x, y: -self.y }
+ Size2D {
+ x: -self.x,
+ y: -self.y,
+ }
}
}
@@ -336,8 +393,11 @@ impl_num_back2d!(Div, div, DivAssign, div_assign, i32);
impl Display for SizeBox {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "[left: {}, top: {}, right: {}, bottom: {}]",
- self.left, self.top, self.right, self.bottom)
+ write!(
+ f,
+ "[left: {}, top: {}, right: {}, bottom: {}]",
+ self.left, self.top, self.right, self.bottom
+ )
}
}
diff --git a/src/style.rs b/src/style.rs
index b9c37790..3bc1e33f 100644
--- a/src/style.rs
+++ b/src/style.rs
@@ -4,14 +4,13 @@ use toddle::query::FontClass;
use crate::size::{Size, Size2D, SizeBox};
-
/// Default styles for text.
#[derive(Debug, Clone)]
pub struct TextStyle {
/// The classes the font we want has to be part of.
pub classes: Vec<FontClass>,
- /// A sequence of classes. We need the font to be part of at least one of these
- /// and preferably the leftmost possible.
+ /// A sequence of classes. We need the font to be part of at least one of
+ /// these and preferably the leftmost possible.
pub fallback: Vec<FontClass>,
/// The font size.
pub font_size: f32,
@@ -26,13 +25,14 @@ impl TextStyle {
///
/// If the class was one of _italic_ or _bold_, then:
/// - If it was not present, the _regular_ class will be removed.
- /// - If it was present, the _regular_ class will be added in case the
- /// other style class is not present.
+ /// - If it was present, the _regular_ class will be added in case the other
+ /// style class is not present.
pub fn toggle_class(&mut self, class: FontClass) {
if self.classes.contains(&class) {
self.classes.retain(|x| x != &class);
if (class == FontClass::Italic && !self.classes.contains(&FontClass::Bold))
- || (class == FontClass::Bold && !self.classes.contains(&FontClass::Italic)) {
+ || (class == FontClass::Bold && !self.classes.contains(&FontClass::Italic))
+ {
self.classes.push(FontClass::Regular);
}
} else {
diff --git a/src/syntax.rs b/src/syntax.rs
index b2140642..9c7e4908 100644
--- a/src/syntax.rs
+++ b/src/syntax.rs
@@ -6,24 +6,26 @@ use std::fmt::{self, Display, Formatter};
use crate::func::Function;
use crate::size::Size;
-
/// A logical unit of the incoming text stream.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Token<'s> {
/// One or more whitespace (non-newline) codepoints.
Space,
- /// A line feed (`\n`, `\r\n` and some more as defined by the Unicode standard).
+ /// A line feed (`\n`, `\r\n` and some more as defined by the Unicode
+ /// standard).
Newline,
/// A left bracket: `[`.
LeftBracket,
/// A right bracket: `]`.
RightBracket,
- /// A colon (`:`) indicating the beginning of function arguments (Function header only).
+ /// A colon (`:`) indicating the beginning of function arguments (Function
+ /// header only).
///
- /// If a colon occurs outside of a function header, it will be tokenized as a
- /// [Word](Token::Word).
+ /// If a colon occurs outside of a function header, it will be tokenized as
+ /// a [Word](Token::Word).
Colon,
- /// An equals (`=`) sign assigning a function argument a value (Function header only).
+ /// An equals (`=`) sign assigning a function argument a value (Function
+ /// header only).
Equals,
/// A comma (`,`) separating two function arguments (Function header only).
Comma,
@@ -39,8 +41,9 @@ pub enum Token<'s> {
LineComment(&'s str),
/// A block comment.
BlockComment(&'s str),
- /// A star followed by a slash unexpectedly ending a block comment (the comment was not started
- /// before, otherwise a [BlockComment](Token::BlockComment) would be returned).
+ /// A star followed by a slash unexpectedly ending a block comment (the
+ /// comment was not started before, otherwise a
+ /// [BlockComment](Token::BlockComment) would be returned).
StarSlash,
/// Everything else is just text.
Text(&'s str),
@@ -98,7 +101,7 @@ impl PartialEq for FuncCall {
pub struct FuncHeader {
pub name: String,
pub args: Vec<Expression>,
- pub kwargs: HashMap<String, Expression>
+ pub kwargs: HashMap<String, Expression>,
}
/// A value expression.