diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-29 13:37:25 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-29 14:18:13 +0100 |
| commit | 0efe669278a5e1c3f2985eba2f3360e91159c54a (patch) | |
| tree | 502712857c48f0decb5e698257c0a96d358a436e /library | |
| parent | 836692e73cff0356e409a9ba5b4887b86809d4ca (diff) | |
Reorganize library and tests
Diffstat (limited to 'library')
| -rw-r--r-- | library/src/basics/heading.rs (renamed from library/src/structure/heading.rs) | 0 | ||||
| -rw-r--r-- | library/src/basics/list.rs (renamed from library/src/structure/list.rs) | 6 | ||||
| -rw-r--r-- | library/src/basics/mod.rs | 9 | ||||
| -rw-r--r-- | library/src/basics/table.rs (renamed from library/src/structure/table.rs) | 0 | ||||
| -rw-r--r-- | library/src/compute/calc.rs (renamed from library/src/base/calc.rs) | 0 | ||||
| -rw-r--r-- | library/src/compute/create.rs (renamed from library/src/base/create.rs) | 6 | ||||
| -rw-r--r-- | library/src/compute/data.rs (renamed from library/src/base/data.rs) | 0 | ||||
| -rw-r--r-- | library/src/compute/foundations.rs (renamed from library/src/base/mod.rs) | 19 | ||||
| -rw-r--r-- | library/src/compute/mod.rs | 13 | ||||
| -rw-r--r-- | library/src/compute/utility.rs (renamed from library/src/base/numbering.rs) | 18 | ||||
| -rw-r--r-- | library/src/layout/align.rs | 2 | ||||
| -rw-r--r-- | library/src/layout/flow.rs | 3 | ||||
| -rw-r--r-- | library/src/layout/hide.rs (renamed from library/src/graphics/hide.rs) | 0 | ||||
| -rw-r--r-- | library/src/layout/mod.rs | 15 | ||||
| -rw-r--r-- | library/src/layout/par.rs (renamed from library/src/text/par.rs) | 33 | ||||
| -rw-r--r-- | library/src/layout/repeat.rs | 25 | ||||
| -rw-r--r-- | library/src/layout/stack.rs | 3 | ||||
| -rw-r--r-- | library/src/lib.rs | 164 | ||||
| -rw-r--r-- | library/src/meta/document.rs (renamed from library/src/structure/document.rs) | 2 | ||||
| -rw-r--r-- | library/src/meta/link.rs (renamed from library/src/text/link.rs) | 2 | ||||
| -rw-r--r-- | library/src/meta/mod.rs | 9 | ||||
| -rw-r--r-- | library/src/meta/reference.rs (renamed from library/src/structure/reference.rs) | 0 | ||||
| -rw-r--r-- | library/src/structure/mod.rs | 13 | ||||
| -rw-r--r-- | library/src/text/deco.rs | 4 | ||||
| -rw-r--r-- | library/src/text/misc.rs | 146 | ||||
| -rw-r--r-- | library/src/text/mod.rs | 179 | ||||
| -rw-r--r-- | library/src/text/quotes.rs | 20 | ||||
| -rw-r--r-- | library/src/text/shaping.rs | 7 | ||||
| -rw-r--r-- | library/src/visualize/image.rs (renamed from library/src/graphics/image.rs) | 2 | ||||
| -rw-r--r-- | library/src/visualize/line.rs (renamed from library/src/graphics/line.rs) | 0 | ||||
| -rw-r--r-- | library/src/visualize/mod.rs (renamed from library/src/graphics/mod.rs) | 4 | ||||
| -rw-r--r-- | library/src/visualize/shape.rs (renamed from library/src/graphics/shape.rs) | 2 |
32 files changed, 363 insertions, 343 deletions
diff --git a/library/src/structure/heading.rs b/library/src/basics/heading.rs index b251f27b..b251f27b 100644 --- a/library/src/structure/heading.rs +++ b/library/src/basics/heading.rs diff --git a/library/src/structure/list.rs b/library/src/basics/list.rs index b51284a8..c73ffea6 100644 --- a/library/src/structure/list.rs +++ b/library/src/basics/list.rs @@ -1,7 +1,7 @@ -use crate::base::NumberingPattern; -use crate::layout::{BlockNode, GridNode, HNode, Spacing, TrackSizing}; +use crate::compute::NumberingPattern; +use crate::layout::{BlockNode, GridNode, HNode, ParNode, Spacing, TrackSizing}; use crate::prelude::*; -use crate::text::{ParNode, SpaceNode, TextNode}; +use crate::text::{SpaceNode, TextNode}; /// An unordered (bulleted) or ordered (numbered) list. #[derive(Debug, Hash)] diff --git a/library/src/basics/mod.rs b/library/src/basics/mod.rs new file mode 100644 index 00000000..5916df6b --- /dev/null +++ b/library/src/basics/mod.rs @@ -0,0 +1,9 @@ +//! Common document elements. + +mod heading; +mod list; +mod table; + +pub use self::heading::*; +pub use self::list::*; +pub use self::table::*; diff --git a/library/src/structure/table.rs b/library/src/basics/table.rs index bb900f3d..bb900f3d 100644 --- a/library/src/structure/table.rs +++ b/library/src/basics/table.rs diff --git a/library/src/base/calc.rs b/library/src/compute/calc.rs index 3541e08c..3541e08c 100644 --- a/library/src/base/calc.rs +++ b/library/src/compute/calc.rs diff --git a/library/src/base/create.rs b/library/src/compute/create.rs index be8e822f..4fd27499 100644 --- a/library/src/base/create.rs +++ b/library/src/compute/create.rs @@ -106,12 +106,6 @@ pub fn str(_: &Vm, args: &mut Args) -> SourceResult<Value> { })) } -/// Create a blind text string. -pub fn lorem(_: &Vm, args: &mut Args) -> SourceResult<Value> { - let words: usize = args.expect("number of words")?; - Ok(Value::Str(lipsum::lipsum(words).into())) -} - /// Create a label from a string. pub fn label(_: &Vm, args: &mut Args) -> SourceResult<Value> { Ok(Value::Label(Label(args.expect("string")?))) diff --git a/library/src/base/data.rs b/library/src/compute/data.rs index 4f6e3b67..4f6e3b67 100644 --- a/library/src/base/data.rs +++ b/library/src/compute/data.rs diff --git a/library/src/base/mod.rs b/library/src/compute/foundations.rs index 501edd71..3e410185 100644 --- a/library/src/base/mod.rs +++ b/library/src/compute/foundations.rs @@ -1,20 +1,9 @@ -//! Foundational functions. - -mod calc; -mod create; -mod data; -mod numbering; - -pub use self::calc::*; -pub use self::create::*; -pub use self::data::*; -pub use self::numbering::*; +use crate::prelude::*; use comemo::Track; -use typst::model::{self, Route, Vm}; -use typst::syntax::Source; -use crate::prelude::*; +use typst::model; +use typst::syntax::Source; /// The name of a value's type. pub fn type_(_: &Vm, args: &mut Args) -> SourceResult<Value> { @@ -39,7 +28,7 @@ pub fn assert(_: &Vm, args: &mut Args) -> SourceResult<Value> { pub fn eval(vm: &Vm, args: &mut Args) -> SourceResult<Value> { let Spanned { v: text, span } = args.expect::<Spanned<String>>("source")?; let source = Source::synthesized(text, span); - let route = Route::default(); + let route = model::Route::default(); let module = model::eval(vm.world(), route.track(), &source)?; Ok(Value::Content(module.content)) } diff --git a/library/src/compute/mod.rs b/library/src/compute/mod.rs new file mode 100644 index 00000000..70690d44 --- /dev/null +++ b/library/src/compute/mod.rs @@ -0,0 +1,13 @@ +//! Computational functions. + +mod calc; +mod create; +mod data; +mod foundations; +mod utility; + +pub use self::calc::*; +pub use self::create::*; +pub use self::data::*; +pub use self::foundations::*; +pub use self::utility::*; diff --git a/library/src/base/numbering.rs b/library/src/compute/utility.rs index ea45fbc6..2b04dfd6 100644 --- a/library/src/base/numbering.rs +++ b/library/src/compute/utility.rs @@ -4,6 +4,12 @@ use unscanny::Scanner; use crate::prelude::*; +/// Create a blind text string. +pub fn lorem(_: &Vm, args: &mut Args) -> SourceResult<Value> { + let words: usize = args.expect("number of words")?; + Ok(Value::Str(lipsum::lipsum(words).into())) +} + /// Apply a numbering pattern to a number. pub fn numbering(_: &Vm, args: &mut Args) -> SourceResult<Value> { let number = args.expect::<usize>("number")?; @@ -11,7 +17,15 @@ pub fn numbering(_: &Vm, args: &mut Args) -> SourceResult<Value> { Ok(Value::Str(pattern.apply(number).into())) } -/// A numbering pattern for lists or headings. +/// How to turn a number into text. +/// +/// A pattern consists of a prefix, followed by one of `1`, `a`, `A`, `i`, `I` +/// or `*`, and then a suffix. +/// +/// Examples of valid patterns: +/// - `1)` +/// - `a.` +/// - `(I)` #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct NumberingPattern { prefix: EcoString, @@ -60,7 +74,7 @@ castable! { /// Different kinds of numberings. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum NumberingKind { +enum NumberingKind { Arabic, Letter, Roman, diff --git a/library/src/layout/align.rs b/library/src/layout/align.rs index d8b6d92e..a06f7edb 100644 --- a/library/src/layout/align.rs +++ b/library/src/layout/align.rs @@ -1,5 +1,5 @@ +use super::{HorizontalAlign, ParNode}; use crate::prelude::*; -use crate::text::{HorizontalAlign, ParNode}; /// Align content along the layouting axes. #[derive(Debug, Hash)] diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs index 07c3e012..b644d73f 100644 --- a/library/src/layout/flow.rs +++ b/library/src/layout/flow.rs @@ -1,8 +1,7 @@ use typst::model::Style; -use super::{AlignNode, BlockNode, ColbreakNode, PlaceNode, Spacing, VNode}; +use super::{AlignNode, BlockNode, ColbreakNode, ParNode, PlaceNode, Spacing, VNode}; use crate::prelude::*; -use crate::text::ParNode; /// Arrange spacing, paragraphs and block-level nodes into a flow. /// diff --git a/library/src/graphics/hide.rs b/library/src/layout/hide.rs index 64cbee64..64cbee64 100644 --- a/library/src/graphics/hide.rs +++ b/library/src/layout/hide.rs diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs index 7edc88ad..8f9337ba 100644 --- a/library/src/layout/mod.rs +++ b/library/src/layout/mod.rs @@ -5,9 +5,12 @@ mod columns; mod container; mod flow; mod grid; +mod hide; mod pad; mod page; +mod par; mod place; +mod repeat; mod spacing; mod stack; mod transform; @@ -17,9 +20,12 @@ pub use self::columns::*; pub use self::container::*; pub use self::flow::*; pub use self::grid::*; +pub use self::hide::*; pub use self::pad::*; pub use self::page::*; +pub use self::par::*; pub use self::place::*; +pub use self::repeat::*; pub use self::spacing::*; pub use self::stack::*; pub use self::transform::*; @@ -36,14 +42,11 @@ use typst::model::{ }; use typst::World; +use crate::basics::{DescNode, EnumNode, ListItem, ListNode, DESC, ENUM, LIST}; +use crate::meta::DocumentNode; use crate::prelude::*; use crate::shared::BehavedBuilder; -use crate::structure::{ - DescNode, DocumentNode, EnumNode, ListItem, ListNode, DESC, ENUM, LIST, -}; -use crate::text::{ - LinebreakNode, ParNode, ParbreakNode, SmartQuoteNode, SpaceNode, TextNode, -}; +use crate::text::{LinebreakNode, SmartQuoteNode, SpaceNode, TextNode}; /// Root-level layout. #[capability] diff --git a/library/src/text/par.rs b/library/src/layout/par.rs index 3c722d84..82bea1b5 100644 --- a/library/src/text/par.rs +++ b/library/src/layout/par.rs @@ -4,12 +4,11 @@ use xi_unicode::LineBreakIterator; use typst::model::Key; -use super::{ - shape, Lang, LinebreakNode, Quoter, Quotes, ShapedText, SmartQuoteNode, SpaceNode, - TextNode, -}; -use crate::layout::{HNode, Spacing}; +use super::{HNode, RepeatNode, Spacing}; use crate::prelude::*; +use crate::text::{ + shape, LinebreakNode, Quoter, Quotes, ShapedText, SmartQuoteNode, SpaceNode, TextNode, +}; /// Arrange text, spacing and inline-level nodes into a paragraph. #[derive(Hash)] @@ -129,30 +128,6 @@ impl ParbreakNode { impl Unlabellable for ParbreakNode {} -/// Repeats content to fill a line. -#[derive(Debug, Hash)] -pub struct RepeatNode(pub Content); - -#[node(Layout, Inline)] -impl RepeatNode { - fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { - Ok(Self(args.expect("body")?).pack()) - } -} - -impl Layout for RepeatNode { - fn layout( - &self, - world: Tracked<dyn World>, - styles: StyleChain, - regions: &Regions, - ) -> SourceResult<Fragment> { - self.0.layout(world, styles, regions) - } -} - -impl Inline for RepeatNode {} - /// Range of a substring of text. type Range = std::ops::Range<usize>; diff --git a/library/src/layout/repeat.rs b/library/src/layout/repeat.rs new file mode 100644 index 00000000..d9323e1d --- /dev/null +++ b/library/src/layout/repeat.rs @@ -0,0 +1,25 @@ +use crate::prelude::*; + +/// Repeats content to fill a line. +#[derive(Debug, Hash)] +pub struct RepeatNode(pub Content); + +#[node(Layout, Inline)] +impl RepeatNode { + fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { + Ok(Self(args.expect("body")?).pack()) + } +} + +impl Layout for RepeatNode { + fn layout( + &self, + world: Tracked<dyn World>, + styles: StyleChain, + regions: &Regions, + ) -> SourceResult<Fragment> { + self.0.layout(world, styles, regions) + } +} + +impl Inline for RepeatNode {} diff --git a/library/src/layout/stack.rs b/library/src/layout/stack.rs index 7de1d34a..c1073b26 100644 --- a/library/src/layout/stack.rs +++ b/library/src/layout/stack.rs @@ -1,8 +1,7 @@ use typst::model::StyledNode; -use super::{AlignNode, Spacing}; +use super::{AlignNode, ParNode, Spacing}; use crate::prelude::*; -use crate::text::ParNode; /// Arrange content and spacing along an axis. #[derive(Debug, Hash)] diff --git a/library/src/lib.rs b/library/src/lib.rs index cf8cb490..e1540133 100644 --- a/library/src/lib.rs +++ b/library/src/lib.rs @@ -1,13 +1,14 @@ //! Typst's standard library. -pub mod base; -pub mod graphics; +pub mod basics; +pub mod compute; pub mod layout; pub mod math; +pub mod meta; pub mod prelude; pub mod shared; -pub mod structure; pub mod text; +pub mod visualize; use typst::geom::{Align, Color, Dir, GenAlign}; use typst::model::{LangItems, Library, Node, NodeId, Scope, StyleMap}; @@ -15,7 +16,7 @@ use typst::model::{LangItems, Library, Node, NodeId, Scope, StyleMap}; use self::layout::LayoutRoot; /// Construct the standard library. -pub fn new() -> Library { +pub fn build() -> Library { Library { scope: scope(), styles: styles(), items: items() } } @@ -23,97 +24,102 @@ pub fn new() -> Library { fn scope() -> Scope { let mut std = Scope::new(); + // Basics. + std.def_node::<basics::HeadingNode>("heading"); + std.def_node::<basics::ListNode>("list"); + std.def_node::<basics::EnumNode>("enum"); + std.def_node::<basics::DescNode>("desc"); + std.def_node::<basics::TableNode>("table"); + // Text. + std.def_node::<text::TextNode>("text"); std.def_node::<text::LinebreakNode>("linebreak"); std.def_node::<text::SmartQuoteNode>("smartquote"); - std.def_node::<text::TextNode>("text"); - std.def_node::<text::ParNode>("par"); - std.def_node::<text::ParbreakNode>("parbreak"); std.def_node::<text::StrongNode>("strong"); std.def_node::<text::EmphNode>("emph"); - std.def_node::<text::RawNode>("raw"); - std.def_node::<text::UnderlineNode>("underline"); - std.def_node::<text::StrikethroughNode>("strike"); - std.def_node::<text::OverlineNode>("overline"); - std.def_node::<text::SuperNode>("super"); - std.def_node::<text::SubNode>("sub"); - std.def_node::<text::LinkNode>("link"); - std.def_node::<text::RepeatNode>("repeat"); std.def_fn("lower", text::lower); std.def_fn("upper", text::upper); std.def_fn("smallcaps", text::smallcaps); + std.def_node::<text::SubNode>("sub"); + std.def_node::<text::SuperNode>("super"); + std.def_node::<text::UnderlineNode>("underline"); + std.def_node::<text::StrikeNode>("strike"); + std.def_node::<text::OverlineNode>("overline"); + std.def_node::<text::RawNode>("raw"); - // Structure. - std.def_node::<structure::DocumentNode>("document"); - std.def_node::<structure::RefNode>("ref"); - std.def_node::<structure::HeadingNode>("heading"); - std.def_node::<structure::ListNode>("list"); - std.def_node::<structure::EnumNode>("enum"); - std.def_node::<structure::DescNode>("desc"); - std.def_node::<structure::TableNode>("table"); + // Math. + std.def_node::<math::MathNode>("math"); + std.def_node::<math::AtomNode>("atom"); + std.def_node::<math::FracNode>("frac"); + std.define("sum", "∑"); + std.define("in", "∈"); + std.define("arrow", "→"); + std.define("NN", "ℕ"); + std.define("RR", "ℝ"); // Layout. std.def_node::<layout::PageNode>("page"); std.def_node::<layout::PagebreakNode>("pagebreak"); - std.def_node::<layout::HNode>("h"); + std.def_node::<layout::FlowNode>("flow"); std.def_node::<layout::VNode>("v"); + std.def_node::<layout::ParNode>("par"); + std.def_node::<layout::ParbreakNode>("parbreak"); + std.def_node::<layout::HNode>("h"); std.def_node::<layout::BoxNode>("box"); std.def_node::<layout::BlockNode>("block"); - std.def_node::<layout::AlignNode>("align"); - std.def_node::<layout::PadNode>("pad"); std.def_node::<layout::StackNode>("stack"); std.def_node::<layout::GridNode>("grid"); std.def_node::<layout::ColumnsNode>("columns"); std.def_node::<layout::ColbreakNode>("colbreak"); std.def_node::<layout::PlaceNode>("place"); + std.def_node::<layout::AlignNode>("align"); + std.def_node::<layout::PadNode>("pad"); + std.def_node::<layout::RepeatNode>("repeat"); std.def_node::<layout::MoveNode>("move"); std.def_node::<layout::ScaleNode>("scale"); std.def_node::<layout::RotateNode>("rotate"); - - // Graphics. - std.def_node::<graphics::ImageNode>("image"); - std.def_node::<graphics::LineNode>("line"); - std.def_node::<graphics::RectNode>("rect"); - std.def_node::<graphics::SquareNode>("square"); - std.def_node::<graphics::EllipseNode>("ellipse"); - std.def_node::<graphics::CircleNode>("circle"); - std.def_node::<graphics::HideNode>("hide"); - - // Math. - std.def_node::<math::MathNode>("math"); - std.define("sum", "∑"); - std.define("in", "∈"); - std.define("arrow", "→"); - std.define("NN", "ℕ"); - std.define("RR", "ℝ"); - - // Base. - std.def_fn("type", base::type_); - std.def_fn("repr", base::repr); - std.def_fn("assert", base::assert); - std.def_fn("eval", base::eval); - std.def_fn("int", base::int); - std.def_fn("float", base::float); - std.def_fn("luma", base::luma); - std.def_fn("rgb", base::rgb); - std.def_fn("cmyk", base::cmyk); - std.def_fn("str", base::str); - std.def_fn("lorem", base::lorem); - std.def_fn("label", base::label); - std.def_fn("regex", base::regex); - std.def_fn("range", base::range); - std.def_fn("numbering", base::numbering); - std.def_fn("abs", base::abs); - std.def_fn("min", base::min); - std.def_fn("max", base::max); - std.def_fn("even", base::even); - std.def_fn("odd", base::odd); - std.def_fn("mod", base::mod_); - std.def_fn("csv", base::csv); - std.def_fn("json", base::json); - std.def_fn("xml", base::xml); - - // Predefined colors. + std.def_node::<layout::HideNode>("hide"); + + // Visualize. + std.def_node::<visualize::ImageNode>("image"); + std.def_node::<visualize::LineNode>("line"); + std.def_node::<visualize::RectNode>("rect"); + std.def_node::<visualize::SquareNode>("square"); + std.def_node::<visualize::EllipseNode>("ellipse"); + std.def_node::<visualize::CircleNode>("circle"); + + // Meta. + std.def_node::<meta::DocumentNode>("document"); + std.def_node::<meta::RefNode>("ref"); + std.def_node::<meta::LinkNode>("link"); + + // Compute. + std.def_fn("type", compute::type_); + std.def_fn("repr", compute::repr); + std.def_fn("assert", compute::assert); + std.def_fn("eval", compute::eval); + std.def_fn("int", compute::int); + std.def_fn("float", compute::float); + std.def_fn("luma", compute::luma); + std.def_fn("rgb", compute::rgb); + std.def_fn("cmyk", compute::cmyk); + std.def_fn("str", compute::str); + std.def_fn("label", compute::label); + std.def_fn("regex", compute::regex); + std.def_fn("range", compute::range); + std.def_fn("abs", compute::abs); + std.def_fn("min", compute::min); + std.def_fn("max", compute::max); + std.def_fn("even", compute::even); + std.def_fn("odd", compute::odd); + std.def_fn("mod", compute::mod_); + std.def_fn("csv", compute::csv); + std.def_fn("json", compute::json); + std.def_fn("xml", compute::xml); + std.def_fn("lorem", compute::lorem); + std.def_fn("numbering", compute::numbering); + + // Colors. std.define("black", Color::BLACK); std.define("gray", Color::GRAY); std.define("silver", Color::SILVER); @@ -167,7 +173,7 @@ fn items() -> LangItems { text_id: NodeId::of::<text::TextNode>(), text_str: |content| Some(&content.to::<text::TextNode>()?.0), smart_quote: |double| text::SmartQuoteNode { double }.pack(), - parbreak: || text::ParbreakNode.pack(), + parbreak: || layout::ParbreakNode.pack(), strong: |body| text::StrongNode(body).pack(), emph: |body| text::EmphNode(body).pack(), raw: |text, lang, block| { @@ -177,15 +183,13 @@ fn items() -> LangItems { None => content, } }, - link: |url| text::LinkNode::from_url(url).pack(), - ref_: |target| structure::RefNode(target).pack(), - heading: |level, body| structure::HeadingNode { level, body }.pack(), - list_item: |body| structure::ListItem::List(Box::new(body)).pack(), - enum_item: |number, body| { - structure::ListItem::Enum(number, Box::new(body)).pack() - }, + link: |url| meta::LinkNode::from_url(url).pack(), + ref_: |target| meta::RefNode(target).pack(), + heading: |level, body| basics::HeadingNode { level, body }.pack(), + list_item: |body| basics::ListItem::List(Box::new(body)).pack(), + enum_item: |number, body| basics::ListItem::Enum(number, Box::new(body)).pack(), desc_item: |term, body| { - structure::ListItem::Desc(Box::new(structure::DescItem { term, body })).pack() + basics::ListItem::Desc(Box::new(basics::DescItem { term, body })).pack() }, math: |children, display| math::MathNode { children, display }.pack(), math_atom: |atom| math::AtomNode(atom).pack(), diff --git a/library/src/structure/document.rs b/library/src/meta/document.rs index e52c92ad..309e1bda 100644 --- a/library/src/structure/document.rs +++ b/library/src/meta/document.rs @@ -1,7 +1,7 @@ use crate::layout::{LayoutRoot, PageNode}; use crate::prelude::*; -/// The root node of the model. +/// The root node that represents a full document. #[derive(Hash)] pub struct DocumentNode(pub StyleVec<PageNode>); diff --git a/library/src/text/link.rs b/library/src/meta/link.rs index 1b87def2..44da9c5d 100644 --- a/library/src/text/link.rs +++ b/library/src/meta/link.rs @@ -1,5 +1,5 @@ -use super::TextNode; use crate::prelude::*; +use crate::text::TextNode; /// Link text and other elements to a destination. #[derive(Debug, Hash)] diff --git a/library/src/meta/mod.rs b/library/src/meta/mod.rs new file mode 100644 index 00000000..31a69ccc --- /dev/null +++ b/library/src/meta/mod.rs @@ -0,0 +1,9 @@ +//! Interaction between document parts. + +mod document; +mod link; +mod reference; + +pub use self::document::*; +pub use self::link::*; +pub use self::reference::*; diff --git a/library/src/structure/reference.rs b/library/src/meta/reference.rs index 948aa6f6..948aa6f6 100644 --- a/library/src/structure/reference.rs +++ b/library/src/meta/reference.rs diff --git a/library/src/structure/mod.rs b/library/src/structure/mod.rs deleted file mode 100644 index a1c27eed..00000000 --- a/library/src/structure/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Document structuring. - -mod document; -mod heading; -mod list; -mod reference; -mod table; - -pub use self::document::*; -pub use self::heading::*; -pub use self::list::*; -pub use self::reference::*; -pub use self::table::*; diff --git a/library/src/text/deco.rs b/library/src/text/deco.rs index 33c13e90..e81b219c 100644 --- a/library/src/text/deco.rs +++ b/library/src/text/deco.rs @@ -12,7 +12,7 @@ pub struct DecoNode<const L: DecoLine>(pub Content); pub type UnderlineNode = DecoNode<UNDERLINE>; /// Typeset stricken-through text. -pub type StrikethroughNode = DecoNode<STRIKETHROUGH>; +pub type StrikeNode = DecoNode<STRIKETHROUGH>; /// Typeset overlined text. pub type OverlineNode = DecoNode<OVERLINE>; @@ -65,7 +65,7 @@ impl<const L: DecoLine> Show for DecoNode<L> { /// /// For more details, see [`DecoNode`]. #[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub(super) struct Decoration { +pub struct Decoration { pub line: DecoLine, pub stroke: PartialStroke<Abs>, pub offset: Smart<Abs>, diff --git a/library/src/text/misc.rs b/library/src/text/misc.rs new file mode 100644 index 00000000..15ef9a63 --- /dev/null +++ b/library/src/text/misc.rs @@ -0,0 +1,146 @@ +use super::TextNode; +use crate::prelude::*; + +/// A text space. +#[derive(Debug, Hash)] +pub struct SpaceNode; + +#[node(Unlabellable, Behave)] +impl SpaceNode { + fn construct(_: &Vm, _: &mut Args) -> SourceResult<Content> { + Ok(Self.pack()) + } +} + +impl Unlabellable for SpaceNode {} + +impl Behave for SpaceNode { + fn behaviour(&self) -> Behaviour { + Behaviour::Weak(2) + } +} + +/// A line break. +#[derive(Debug, Hash)] +pub struct LinebreakNode { + pub justify: bool, +} + +#[node(Behave)] +impl LinebreakNode { + fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { + let justify = args.named("justify")?.unwrap_or(false); + Ok(Self { justify }.pack()) + } +} + +impl Behave for LinebreakNode { + fn behaviour(&self) -> Behaviour { + Behaviour::Destructive + } +} + +/// Strong content, rendered in boldface by default. +#[derive(Debug, Hash)] +pub struct StrongNode(pub Content); + +#[node(Show)] +impl StrongNode { + fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { + Ok(Self(args.expect("body")?).pack()) + } + + fn field(&self, name: &str) -> Option<Value> { + match name { + "body" => Some(Value::Content(self.0.clone())), + _ => None, + } + } +} + +impl Show for StrongNode { + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> Content { + self.0.clone().styled(TextNode::BOLD, Toggle) + } +} + +/// Emphasized content, rendered with an italic font by default. +#[derive(Debug, Hash)] +pub struct EmphNode(pub Content); + +#[node(Show)] +impl EmphNode { + fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { + Ok(Self(args.expect("body")?).pack()) + } + + fn field(&self, name: &str) -> Option<Value> { + match name { + "body" => Some(Value::Content(self.0.clone())), + _ => None, + } + } +} + +impl Show for EmphNode { + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> Content { + self.0.clone().styled(TextNode::ITALIC, Toggle) + } +} + +/// A toggle that turns on and off alternatingly if folded. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct Toggle; + +impl Fold for Toggle { + type Output = bool; + + fn fold(self, outer: Self::Output) -> Self::Output { + !outer + } +} + +/// Convert a string or content to lowercase. +pub fn lower(_: &Vm, args: &mut Args) -> SourceResult<Value> { + case(Case::Lower, args) +} + +/// Convert a string or content to uppercase. +pub fn upper(_: &Vm, args: &mut Args) -> SourceResult<Value> { + case(Case::Upper, args) +} + +/// Change the case of text. +fn case(case: Case, args: &mut Args) -> SourceResult<Value> { + let Spanned { v, span } = args.expect("string or content")?; + Ok(match v { + Value::Str(v) => Value::Str(case.apply(&v).into()), + Value::Content(v) => Value::Content(v.styled(TextNode::CASE, Some(case))), + v => bail!(span, "expected string or content, found {}", v.type_name()), + }) +} + +/// A case transformation on text. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub enum Case { + /// Everything is lowercased. + Lower, + /// Everything is uppercased. + Upper, +} + +impl Case { + /// Apply the case to a string. + pub fn apply(self, text: &str) -> String { + match self { + Self::Lower => text.to_lowercase(), + Self::Upper => text.to_uppercase(), + } + } +} + +/// Display text in small capitals. +pub fn smallcaps(_: &Vm, args: &mut Args) -> SourceResult<Value> { + let body: Content = args.expect("content")?; + Ok(Value::Content(body.styled(TextNode::SMALLCAPS, true))) +} diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs index 3fd30e9e..c9298fee 100644 --- a/library/src/text/mod.rs +++ b/library/src/text/mod.rs @@ -1,16 +1,15 @@ -//! Text handling and paragraph layout. +//! Text handling. mod deco; -mod link; -mod par; +mod misc; mod quotes; mod raw; mod shaping; mod shift; pub use self::deco::*; -pub use self::link::*; -pub use self::par::*; +pub use self::misc::*; +pub use self::quotes::*; pub use self::raw::*; pub use self::shaping::*; pub use self::shift::*; @@ -21,7 +20,7 @@ use rustybuzz::Tag; use typst::font::{FontMetrics, FontStretch, FontStyle, FontWeight, VerticalFontMetric}; use typst::util::EcoString; -use self::quotes::*; +use crate::layout::ParNode; use crate::prelude::*; /// A single run of text with the same style. @@ -114,19 +113,19 @@ impl TextNode { /// Whether the font weight should be increased by 300. #[property(skip, fold)] - const BOLD: Toggle = false; + pub const BOLD: Toggle = false; /// Whether the font style should be inverted. #[property(skip, fold)] - const ITALIC: Toggle = false; + pub const ITALIC: Toggle = false; /// A case transformation that should be applied to the text. #[property(skip)] - const CASE: Option<Case> = None; + pub const CASE: Option<Case> = None; /// Whether small capital glyphs should be used. ("smcp") #[property(skip)] - const SMALLCAPS: bool = false; + pub const SMALLCAPS: bool = false; /// Decorative lines. #[property(skip, fold)] - const DECO: Decoration = vec![]; + pub const DECO: Decoration = vec![]; fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { // The text constructor is special: It doesn't create a text node. @@ -409,161 +408,3 @@ impl Fold for FontFeatures { self } } - -/// A text space. -#[derive(Debug, Hash)] -pub struct SpaceNode; - -#[node(Unlabellable, Behave)] -impl SpaceNode { - fn construct(_: &Vm, _: &mut Args) -> SourceResult<Content> { - Ok(Self.pack()) - } -} - -impl Unlabellable for SpaceNode {} - -impl Behave for SpaceNode { - fn behaviour(&self) -> Behaviour { - Behaviour::Weak(2) - } -} - -/// A line break. -#[derive(Debug, Hash)] -pub struct LinebreakNode { - pub justify: bool, -} - -#[node(Behave)] -impl LinebreakNode { - fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { - let justify = args.named("justify")?.unwrap_or(false); - Ok(Self { justify }.pack()) - } -} - -impl Behave for LinebreakNode { - fn behaviour(&self) -> Behaviour { - Behaviour::Destructive - } -} - -/// A smart quote. -#[derive(Debug, Hash)] -pub struct SmartQuoteNode { - pub double: bool, -} - -#[node] -impl SmartQuoteNode { - fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { - let double = args.named("double")?.unwrap_or(true); - Ok(Self { double }.pack()) - } -} - -/// Convert a string or content to lowercase. -pub fn lower(_: &Vm, args: &mut Args) -> SourceResult<Value> { - case(Case::Lower, args) -} - -/// Convert a string or content to uppercase. -pub fn upper(_: &Vm, args: &mut Args) -> SourceResult<Value> { - case(Case::Upper, args) -} - -/// Change the case of text. -fn case(case: Case, args: &mut Args) -> SourceResult<Value> { - let Spanned { v, span } = args.expect("string or content")?; - Ok(match v { - Value::Str(v) => Value::Str(case.apply(&v).into()), - Value::Content(v) => Value::Content(v.styled(TextNode::CASE, Some(case))), - v => bail!(span, "expected string or content, found {}", v.type_name()), - }) -} - -/// A case transformation on text. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum Case { - /// Everything is uppercased. - Upper, - /// Everything is lowercased. - Lower, -} - -impl Case { - /// Apply the case to a string. - pub fn apply(self, text: &str) -> String { - match self { - Self::Upper => text.to_uppercase(), - Self::Lower => text.to_lowercase(), - } - } -} - -/// Display text in small capitals. -pub fn smallcaps(_: &Vm, args: &mut Args) -> SourceResult<Value> { - let body: Content = args.expect("content")?; - Ok(Value::Content(body.styled(TextNode::SMALLCAPS, true))) -} - -/// Strong content, rendered in boldface by default. -#[derive(Debug, Hash)] -pub struct StrongNode(pub Content); - -#[node(Show)] -impl StrongNode { - fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { - Ok(Self(args.expect("body")?).pack()) - } - - fn field(&self, name: &str) -> Option<Value> { - match name { - "body" => Some(Value::Content(self.0.clone())), - _ => None, - } - } -} - -impl Show for StrongNode { - fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> Content { - self.0.clone().styled(TextNode::BOLD, Toggle) - } -} - -/// Emphasized content, rendered with an italic font by default. -#[derive(Debug, Hash)] -pub struct EmphNode(pub Content); - -#[node(Show)] -impl EmphNode { - fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { - Ok(Self(args.expect("body")?).pack()) - } - - fn field(&self, name: &str) -> Option<Value> { - match name { - "body" => Some(Value::Content(self.0.clone())), - _ => None, - } - } -} - -impl Show for EmphNode { - fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> Content { - self.0.clone().styled(TextNode::ITALIC, Toggle) - } -} - -/// A toggle that turns on and off alternatingly if folded. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct Toggle; - -impl Fold for Toggle { - type Output = bool; - - fn fold(self, outer: Self::Output) -> Self::Output { - !outer - } -} diff --git a/library/src/text/quotes.rs b/library/src/text/quotes.rs index 87a965af..95cf1ad9 100644 --- a/library/src/text/quotes.rs +++ b/library/src/text/quotes.rs @@ -1,10 +1,24 @@ use typst::syntax::is_newline; -use super::{Lang, Region}; +use crate::prelude::*; + +/// A smart quote. +#[derive(Debug, Hash)] +pub struct SmartQuoteNode { + pub double: bool, +} + +#[node] +impl SmartQuoteNode { + fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { + let double = args.named("double")?.unwrap_or(true); + Ok(Self { double }.pack()) + } +} /// State machine for smart quote subtitution. #[derive(Debug, Clone)] -pub(super) struct Quoter { +pub struct Quoter { /// How many quotes have been opened. quote_depth: usize, /// Whether an opening quote might follow. @@ -68,7 +82,7 @@ fn is_opening_bracket(c: char) -> bool { } /// Decides which quotes to subtitute smart quotes with. -pub(super) struct Quotes<'s> { +pub struct Quotes<'s> { /// The opening single quote. pub single_open: &'s str, /// The closing single quote. diff --git a/library/src/text/shaping.rs b/library/src/text/shaping.rs index 6ce4d671..687f2a87 100644 --- a/library/src/text/shaping.rs +++ b/library/src/text/shaping.rs @@ -6,6 +6,7 @@ use typst::font::{Font, FontVariant}; use typst::util::SliceExt; use super::*; +use crate::meta::LinkNode; use crate::prelude::*; /// The result of shaping text. @@ -13,7 +14,7 @@ use crate::prelude::*; /// This type contains owned or borrowed shaped text runs, which can be /// measured, used to reshape substrings more quickly and converted into a /// frame. -pub(super) struct ShapedText<'a> { +pub struct ShapedText<'a> { /// The text that was shaped. pub text: &'a str, /// The text direction. @@ -32,7 +33,7 @@ pub(super) struct ShapedText<'a> { /// A single glyph resulting from shaping. #[derive(Debug, Clone)] -pub(super) struct ShapedGlyph { +pub struct ShapedGlyph { /// The font the glyph is contained in. pub font: Font, /// The glyph's index in the font. @@ -314,7 +315,7 @@ struct ShapingContext<'a> { } /// Shape text into [`ShapedText`]. -pub(super) fn shape<'a>( +pub fn shape<'a>( world: Tracked<dyn World>, text: &'a str, styles: StyleChain<'a>, diff --git a/library/src/graphics/image.rs b/library/src/visualize/image.rs index 2c58496c..6e8b6147 100644 --- a/library/src/graphics/image.rs +++ b/library/src/visualize/image.rs @@ -2,8 +2,8 @@ use std::ffi::OsStr; use typst::image::{Image, ImageFormat, RasterFormat, VectorFormat}; +use crate::meta::LinkNode; use crate::prelude::*; -use crate::text::LinkNode; /// Show a raster or vector graphic. #[derive(Debug, Hash)] diff --git a/library/src/graphics/line.rs b/library/src/visualize/line.rs index 8acf5bb6..8acf5bb6 100644 --- a/library/src/graphics/line.rs +++ b/library/src/visualize/line.rs diff --git a/library/src/graphics/mod.rs b/library/src/visualize/mod.rs index d77dfe36..1c87eeb3 100644 --- a/library/src/graphics/mod.rs +++ b/library/src/visualize/mod.rs @@ -1,11 +1,9 @@ -//! Graphical elements and effects. +//! Drawing and visualization. -mod hide; mod image; mod line; mod shape; -pub use self::hide::*; pub use self::image::*; pub use self::line::*; pub use self::shape::*; diff --git a/library/src/graphics/shape.rs b/library/src/visualize/shape.rs index 114182e5..daecd580 100644 --- a/library/src/graphics/shape.rs +++ b/library/src/visualize/shape.rs @@ -1,7 +1,7 @@ use std::f64::consts::SQRT_2; +use crate::meta::LinkNode; use crate::prelude::*; -use crate::text::LinkNode; /// A sizable and fillable shape with optional content. #[derive(Debug, Hash)] |
