summaryrefslogtreecommitdiff
path: root/src/func
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-01-24 16:23:57 +0100
committerLaurenz <laurmaedje@gmail.com>2020-01-24 16:23:57 +0100
commit0a087cd28bbee5fcdffbb9d49b0ba9f413ad7f92 (patch)
treefe00c96969ed2ee69e6d3b42de8ff2558f792edd /src/func
parent03fddaf3aea778057aedd74dbcb27bae971ec22f (diff)
Reorganize modules 🧱
Diffstat (limited to 'src/func')
-rw-r--r--src/func/macros.rs136
-rw-r--r--src/func/mod.rs129
2 files changed, 0 insertions, 265 deletions
diff --git a/src/func/macros.rs b/src/func/macros.rs
deleted file mode 100644
index 764f0836..00000000
--- a/src/func/macros.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-//! Helper types and macros for creating custom functions.
-
-
-#[macro_export]
-macro_rules! function {
- // Entry point.
- ($(#[$outer:meta])* $v:vis $storage:ident $name:ident $($r:tt)*) => {
- function!(@def($name) $(#[$outer])* $v $storage $name $($r)*);
- };
- (@def($name:ident) $definition:item $($r:tt)*) => {
- $definition
- function!(@meta($name) $($r)*);
- };
-
- // Metadata.
- (@meta($name:ident) type Meta = $meta:ty; $($r:tt)*) => {
- function!(@parse($name, $meta) $($r)*);
- };
- (@meta($name:ident) $($r:tt)*) => {
- function!(@parse($name, ()) $($r)*);
- };
-
- // Parse trait.
- (@parse($($a:tt)*) parse(default) $($r:tt)*) => {
- function!(@parse($($a)*) parse(_h, _b, _c, _e, _d, _m) {Default::default() } $($r)*);
- };
- (@parse($($a:tt)*) parse($h:ident, $b:ident, $c:ident, $e:ident, $d:ident) $($r:tt)* ) => {
- function!(@parse($($a)*) parse($h, $b, $c, $e, $d, _metadata) $($r)*);
- };
- (@parse($name:ident, $meta:ty) parse(
- $header:ident,
- $body:ident,
- $ctx:ident,
- $errors:ident,
- $decos:ident,
- $metadata:ident
- ) $code:block $($r:tt)*) => {
- impl $crate::func::Parse for $name {
- type Meta = $meta;
-
- fn parse(
- #[allow(unused)] mut header: FuncHeader,
- #[allow(unused)] $body: Option<Spanned<&str>>,
- #[allow(unused)] $ctx: ParseContext,
- #[allow(unused)] $metadata: Self::Meta,
- ) -> Parsed<Self> where Self: Sized {
- let mut errors = vec![];
- let mut decorations = vec![];
- #[allow(unused)] let $header = &mut header;
- #[allow(unused)] let $errors = &mut errors;
- #[allow(unused)] let $decos = &mut decorations;
- let output = $code;
-
- for arg in header.args.into_iter() {
- errors.push(err!(arg.span(); "unexpected argument"));
- }
-
- $crate::syntax::Parsed { output, errors, decorations }
- }
- }
-
- function!(@layout($name) $($r)*);
- };
-
- (@layout($name:ident) layout($this:ident, $ctx:ident, $errors:ident) $code:block) => {
- impl $crate::syntax::Model for $name {
- fn layout<'a, 'b, 'c, 't>(
- #[allow(unused)] &'a $this,
- #[allow(unused)] mut $ctx: $crate::layout::LayoutContext<'b, 'c>,
- ) -> $crate::syntax::DynFuture<'t, $crate::layout::Layouted<$crate::func::Commands<'a>>>
- where
- 'a: 't,
- 'b: 't,
- 'c: 't,
- Self: 't,
- {
- Box::pin(async move {
- let mut errors = vec![];
- #[allow(unused)] let $errors = &mut errors;
- let output = $code;
- $crate::layout::Layouted { output, errors }
- })
- }
- }
- };
-}
-
-/// Parse the body of a function.
-///
-/// - If the function does not expect a body, use `parse!(nope: body, errors)`.
-/// - If the function can have a body, use `parse!(opt: body, ctx, errors, decos)`.
-#[macro_export]
-macro_rules! body {
- (opt: $body:expr, $ctx:expr, $errors:expr, $decos:expr) => ({
- $body.map(|body| {
- // Since the body span starts at the opening bracket of the body, we
- // need to add 1 column to find out the start position of body
- // content.
- let start = body.span.start + Position::new(0, 1);
- let parsed = $crate::syntax::parse(start, body.v, $ctx);
- $errors.extend(parsed.errors);
- $decos.extend(parsed.decorations);
- parsed.output
- })
- });
-
- (nope: $body:expr, $errors:expr) => {
- if let Some(body) = $body {
- $errors.push($crate::err!(body.span; "unexpected body"));
- }
- };
-}
-
-/// Construct an error with optional severity and span.
-///
-/// # Examples
-/// ```
-/// err!(span; "the wrong {}", value);
-/// err!(@Warning: span; "non-fatal!");
-/// err!("no spans here ...");
-/// ```
-#[macro_export]
-macro_rules! err {
- (@$severity:ident: $span:expr; $($args:tt)*) => {
- $crate::syntax::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)*) };
-}
diff --git a/src/func/mod.rs b/src/func/mod.rs
deleted file mode 100644
index b3721d91..00000000
--- a/src/func/mod.rs
+++ /dev/null
@@ -1,129 +0,0 @@
-//! Dynamic typesetting functions.
-
-use std::collections::HashMap;
-use std::fmt::{self, Debug, Formatter};
-
-use self::prelude::*;
-
-#[macro_use]
-mod macros;
-
-/// Useful imports for creating your own functions.
-pub mod prelude {
- pub use super::{Scope, Parse, Command, Commands};
- pub use crate::error::Error;
- pub use crate::layout::prelude::*;
- pub use crate::syntax::prelude::*;
- pub use crate::size::{Size, Size2D, SizeBox, ValueBox, ScaleSize, FSize, PSize};
- pub use crate::style::{LayoutStyle, PageStyle, TextStyle};
- pub use Command::*;
-}
-
-/// Parse a function from source code.
-pub trait Parse {
- type Meta: Clone;
-
- /// Parse the header and body into this function given a context.
- fn parse(
- header: FuncHeader,
- body: Option<Spanned<&str>>,
- ctx: ParseContext,
- metadata: Self::Meta,
- ) -> Parsed<Self> where Self: Sized;
-}
-
-/// A function which parses the source of a function into a model type which
-/// implements [`Model`].
-type Parser = dyn Fn(
- FuncHeader,
- Option<Spanned<&str>>,
- ParseContext,
-) -> Parsed<Box<dyn Model>>;
-
-/// A sequence of layouting commands.
-pub type Commands<'a> = Vec<Command<'a>>;
-
-/// Layouting commands from functions to the typesetting engine.
-#[derive(Debug)]
-pub enum Command<'a> {
- LayoutSyntaxModel(&'a SyntaxModel),
-
- Add(Layout),
- AddMultiple(MultiLayout),
- AddSpacing(Size, SpacingKind, GenericAxis),
-
- FinishLine,
- FinishSpace,
- BreakParagraph,
- BreakPage,
-
- SetTextStyle(TextStyle),
- SetPageStyle(PageStyle),
- SetAlignment(LayoutAlignment),
- SetAxes(LayoutAxes),
-}
-
-/// A map from identifiers to function parsers.
-pub struct Scope {
- parsers: HashMap<String, Box<Parser>>,
- fallback: Box<Parser>
-}
-
-impl Scope {
- /// Create a new empty scope with a fallback parser that is invoked when no
- /// match is found.
- pub fn new<F>() -> Scope
- where F: Parse<Meta=()> + Model + 'static {
- Scope {
- parsers: HashMap::new(),
- fallback: parser::<F>(()),
- }
- }
-
- /// Create a new scope with the standard functions contained.
- pub fn with_std() -> Scope {
- crate::library::std()
- }
-
- /// Associate the given name with a type that is parseable into a function.
- pub fn add<F>(&mut self, name: &str)
- where F: Parse<Meta=()> + Model + 'static {
- self.add_with_meta::<F>(name, ());
- }
-
- /// Add a parseable type with additional metadata that is given to the
- /// parser (other than the default of `()`).
- pub fn add_with_meta<F>(&mut self, name: &str, metadata: <F as Parse>::Meta)
- where F: Parse + Model + 'static {
- self.parsers.insert(
- name.to_owned(),
- parser::<F>(metadata),
- );
- }
-
- /// Return the parser with the given name if there is one.
- pub fn get_parser(&self, name: &str) -> Result<&Parser, &Parser> {
- self.parsers.get(name)
- .map(|x| &**x)
- .ok_or_else(|| &*self.fallback)
- }
-
- /// Return the fallback parser.
- pub fn get_fallback_parser(&self) -> &Parser {
- &*self.fallback
- }
-}
-
-impl Debug for Scope {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "Scope ")?;
- write!(f, "{:?}", self.parsers.keys())
- }
-}
-
-fn parser<F>(metadata: <F as Parse>::Meta) -> Box<Parser> where F: Parse + Model + 'static {
- Box::new(move |h, b, c| {
- F::parse(h, b, c, metadata.clone())
- .map(|model| Box::new(model) as Box<dyn Model>)
- })
-}