Support for wrap

This commit is contained in:
Laurenz 2022-01-28 22:32:53 +01:00
parent 9c906f92c5
commit 5c53b9ff60
3 changed files with 69 additions and 40 deletions

View File

@ -178,16 +178,31 @@ impl Eval for Markup {
type Output = Node; type Output = Node;
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> { fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
process_nodes(ctx, &mut self.nodes())
}
}
/// Evaluate a stream of nodes.
fn process_nodes(
ctx: &mut EvalContext,
nodes: &mut impl Iterator<Item = MarkupNode>,
) -> TypResult<Node> {
let prev = mem::take(&mut ctx.styles); let prev = mem::take(&mut ctx.styles);
let nodes = self.nodes(); let mut seq = Vec::with_capacity(nodes.size_hint().1.unwrap_or_default());
let upper = nodes.size_hint().1.unwrap_or_default(); while let Some(piece) = nodes.next() {
let mut seq = Vec::with_capacity(upper); // Need to deal with wrap here.
for piece in nodes { let node = if let MarkupNode::Expr(Expr::Wrap(wrap)) = piece {
seq.push(Styled::new(piece.eval(ctx)?, ctx.styles.clone())); let tail = process_nodes(ctx, nodes)?;
ctx.scopes.def_mut(wrap.binding().take(), tail);
wrap.body().eval(ctx)?.show()
} else {
piece.eval(ctx)?
};
seq.push(Styled::new(node, ctx.styles.clone()));
} }
ctx.styles = prev; ctx.styles = prev;
Ok(Node::Sequence(seq)) Ok(Node::Sequence(seq))
}
} }
impl Eval for MarkupNode { impl Eval for MarkupNode {
@ -265,8 +280,8 @@ impl RawNode {
sequence.push(Styled::bare(Node::Linebreak)); sequence.push(Styled::bare(Node::Linebreak));
} }
for (style, line) in highlighter.highlight(line, &SYNTAXES) { for (style, piece) in highlighter.highlight(line, &SYNTAXES) {
sequence.push(Self::styled_piece(style, line, foreground)); sequence.push(style_piece(piece, foreground, style));
} }
} }
} }
@ -279,11 +294,7 @@ impl RawNode {
red.as_ref(), red.as_ref(),
&highlighter, &highlighter,
&mut |range, style| { &mut |range, style| {
sequence.push(Self::styled_piece( sequence.push(style_piece(&self.text[range], foreground, style));
style,
&self.text[range],
foreground,
));
}, },
) )
} }
@ -291,8 +302,10 @@ impl RawNode {
Node::Sequence(sequence).monospaced() Node::Sequence(sequence).monospaced()
} }
}
fn styled_piece(style: SynStyle, piece: &str, foreground: Paint) -> Styled<Node> { /// Style a piece of text with a syntect style.
fn style_piece(piece: &str, foreground: Paint, style: SynStyle) -> Styled<Node> {
let paint = style.foreground.into(); let paint = style.foreground.into();
let node = Node::Text(piece.into()); let node = Node::Text(piece.into());
@ -315,7 +328,6 @@ impl RawNode {
} }
Styled::new(node, styles) Styled::new(node, styles)
}
} }
impl Eval for MathNode { impl Eval for MathNode {
@ -776,7 +788,7 @@ impl Eval for WrapExpr {
type Output = Value; type Output = Value;
fn eval(&self, _: &mut EvalContext) -> TypResult<Self::Output> { fn eval(&self, _: &mut EvalContext) -> TypResult<Self::Output> {
Err("wrap is not yet implemented").at(self.span()) Err("wrap is only allowed directly in markup").at(self.span())
} }
} }

BIN
tests/ref/style/wrap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,6 +1,23 @@
// Test wrap. // Test wrap.
// Ref: false
--- ---
// Error: 1-31 wrap is not yet implemented #set page(height: 130pt)
#set text(70%)
#align(center)[
#text(130%)[*Essay on typography*] \
T. Ypst
]
#wrap body in columns(2, body) #wrap body in columns(2, body)
Great typography is at the essence of great storytelling. It is the medium that
transports meaning from parchment to reader, the wave that sparks a flame
in booklovers and the great fulfiller of human need.
---
// Test wrap in template.
A [_B #wrap c in [*#c*]; C] D
---
// Error: 6-17 wrap is only allowed directly in markup
{1 + wrap x in y}