mirror of
https://github.com/typst/typst
synced 2025-05-15 01:25:28 +08:00
Allow configuration of directions in page and box ↗
This commit is contained in:
parent
91e5120693
commit
ee38c6aa9a
@ -22,7 +22,7 @@ use fontdock::FontStyle;
|
|||||||
|
|
||||||
use crate::diag::Diag;
|
use crate::diag::Diag;
|
||||||
use crate::diag::{Deco, Feedback, Pass};
|
use crate::diag::{Deco, Feedback, Pass};
|
||||||
use crate::geom::{BoxAlign, Flow, Gen, Length, Linear, Relative, Sides, Size};
|
use crate::geom::{BoxAlign, Dir, Flow, Gen, Length, Linear, Relative, Sides, Size};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
Document, Expansion, LayoutNode, Pad, Pages, Par, Softness, Spacing, Stack, Text,
|
Document, Expansion, LayoutNode, Pad, Pages, Par, Softness, Spacing, Stack, Text,
|
||||||
};
|
};
|
||||||
@ -223,6 +223,23 @@ impl EvalContext {
|
|||||||
(group, std::mem::replace(&mut self.inner, outer))
|
(group, std::mem::replace(&mut self.inner, outer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates the flow directions if the resulting main and cross directions
|
||||||
|
/// apply to different axes. Generates an appropriate error, otherwise.
|
||||||
|
pub fn set_flow(&mut self, new: Gen<Option<Spanned<Dir>>>) {
|
||||||
|
let flow = Gen::new(
|
||||||
|
new.main.map(|s| s.v).unwrap_or(self.state.flow.main),
|
||||||
|
new.cross.map(|s| s.v).unwrap_or(self.state.flow.cross),
|
||||||
|
);
|
||||||
|
|
||||||
|
if flow.main.axis() != flow.cross.axis() {
|
||||||
|
self.state.flow = flow;
|
||||||
|
} else {
|
||||||
|
for dir in new.main.iter().chain(new.cross.iter()) {
|
||||||
|
self.diag(error!(dir.span, "aligned axis"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct a text node from the given string based on the active text
|
/// Construct a text node from the given string based on the active text
|
||||||
/// state.
|
/// state.
|
||||||
pub fn make_text_node(&self, text: String) -> Text {
|
pub fn make_text_node(&self, text: String) -> Text {
|
||||||
|
@ -17,7 +17,6 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
/// There may not be two alignment specifications for the same axis.
|
/// There may not be two alignment specifications for the same axis.
|
||||||
pub fn align(mut args: Args, ctx: &mut EvalContext) -> Value {
|
pub fn align(mut args: Args, ctx: &mut EvalContext) -> Value {
|
||||||
let snapshot = ctx.state.clone();
|
let snapshot = ctx.state.clone();
|
||||||
|
|
||||||
let body = args.find::<SynTree>();
|
let body = args.find::<SynTree>();
|
||||||
let first = args.get::<_, Spanned<AlignArg>>(ctx, 0);
|
let first = args.get::<_, Spanned<AlignArg>>(ctx, 0);
|
||||||
let second = args.get::<_, Spanned<AlignArg>>(ctx, 1);
|
let second = args.get::<_, Spanned<AlignArg>>(ctx, 1);
|
||||||
@ -33,13 +32,14 @@ pub fn align(mut args: Args, ctx: &mut EvalContext) -> Value {
|
|||||||
.chain(ver.into_iter().map(|align| (Some(SpecAxis::Vertical), align)));
|
.chain(ver.into_iter().map(|align| (Some(SpecAxis::Vertical), align)));
|
||||||
|
|
||||||
let align = dedup_aligns(ctx, iter);
|
let align = dedup_aligns(ctx, iter);
|
||||||
if align.main != ctx.state.align.main {
|
let ends_par = align.main != ctx.state.align.main;
|
||||||
|
ctx.state.align = align;
|
||||||
|
|
||||||
|
if ends_par {
|
||||||
ctx.end_par_group();
|
ctx.end_par_group();
|
||||||
ctx.start_par_group();
|
ctx.start_par_group();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.state.align = align;
|
|
||||||
|
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
body.eval(ctx);
|
body.eval(ctx);
|
||||||
ctx.state = snapshot;
|
ctx.state = snapshot;
|
||||||
|
@ -9,10 +9,12 @@ use crate::prelude::*;
|
|||||||
/// - `height`: The height of the box (length or relative to parent's height).
|
/// - `height`: The height of the box (length or relative to parent's height).
|
||||||
pub fn boxed(mut args: Args, ctx: &mut EvalContext) -> Value {
|
pub fn boxed(mut args: Args, ctx: &mut EvalContext) -> Value {
|
||||||
let snapshot = ctx.state.clone();
|
let snapshot = ctx.state.clone();
|
||||||
|
|
||||||
let body = args.find::<SynTree>().unwrap_or_default();
|
let body = args.find::<SynTree>().unwrap_or_default();
|
||||||
let width = args.get::<_, Linear>(ctx, "width");
|
let width = args.get::<_, Linear>(ctx, "width");
|
||||||
let height = args.get::<_, Linear>(ctx, "height");
|
let height = args.get::<_, Linear>(ctx, "height");
|
||||||
|
let main = args.get::<_, Spanned<Dir>>(ctx, "main");
|
||||||
|
let cross = args.get::<_, Spanned<Dir>>(ctx, "cross");
|
||||||
|
ctx.set_flow(Gen::new(main, cross));
|
||||||
args.done(ctx);
|
args.done(ctx);
|
||||||
|
|
||||||
let flow = ctx.state.flow;
|
let flow = ctx.state.flow;
|
||||||
|
@ -53,7 +53,6 @@ use crate::prelude::*;
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value {
|
pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value {
|
||||||
let snapshot = ctx.state.clone();
|
let snapshot = ctx.state.clone();
|
||||||
|
|
||||||
let body = args.find::<SynTree>();
|
let body = args.find::<SynTree>();
|
||||||
|
|
||||||
if let Some(linear) = args.find::<Linear>() {
|
if let Some(linear) = args.find::<Linear>() {
|
||||||
@ -67,7 +66,6 @@ pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value {
|
|||||||
|
|
||||||
let mut needs_flattening = false;
|
let mut needs_flattening = false;
|
||||||
let list: Vec<_> = args.find_all::<StringLike>().map(|s| s.to_lowercase()).collect();
|
let list: Vec<_> = args.find_all::<StringLike>().map(|s| s.to_lowercase()).collect();
|
||||||
|
|
||||||
if !list.is_empty() {
|
if !list.is_empty() {
|
||||||
Rc::make_mut(&mut ctx.state.font.families).list = list;
|
Rc::make_mut(&mut ctx.state.font.families).list = list;
|
||||||
needs_flattening = true;
|
needs_flattening = true;
|
||||||
|
@ -17,6 +17,9 @@ use crate::prelude::*;
|
|||||||
/// - `bottom`: The bottom margin (length or relative to height).
|
/// - `bottom`: The bottom margin (length or relative to height).
|
||||||
/// - `flip`: Flips custom or paper-defined width and height (boolean).
|
/// - `flip`: Flips custom or paper-defined width and height (boolean).
|
||||||
pub fn page(mut args: Args, ctx: &mut EvalContext) -> Value {
|
pub fn page(mut args: Args, ctx: &mut EvalContext) -> Value {
|
||||||
|
let snapshot = ctx.state.clone();
|
||||||
|
let body = args.find::<SynTree>();
|
||||||
|
|
||||||
if let Some(paper) = args.find::<Paper>() {
|
if let Some(paper) = args.find::<Paper>() {
|
||||||
ctx.state.page.class = paper.class;
|
ctx.state.page.class = paper.class;
|
||||||
ctx.state.page.size = paper.size();
|
ctx.state.page.size = paper.size();
|
||||||
@ -57,8 +60,19 @@ pub fn page(mut args: Args, ctx: &mut EvalContext) -> Value {
|
|||||||
std::mem::swap(&mut size.width, &mut size.height);
|
std::mem::swap(&mut size.width, &mut size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let main = args.get::<_, Spanned<Dir>>(ctx, "main");
|
||||||
|
let cross = args.get::<_, Spanned<Dir>>(ctx, "cross");
|
||||||
|
ctx.set_flow(Gen::new(main, cross));
|
||||||
|
|
||||||
args.done(ctx);
|
args.done(ctx);
|
||||||
|
|
||||||
|
if let Some(body) = body {
|
||||||
|
ctx.end_page_group();
|
||||||
|
ctx.start_page_group(true);
|
||||||
|
body.eval(ctx);
|
||||||
|
ctx.state = snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
ctx.end_page_group();
|
ctx.end_page_group();
|
||||||
ctx.start_page_group(false);
|
ctx.start_page_group(false);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user