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,18 +178,33 @@ 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> {
let prev = mem::take(&mut ctx.styles); process_nodes(ctx, &mut self.nodes())
let nodes = self.nodes();
let upper = nodes.size_hint().1.unwrap_or_default();
let mut seq = Vec::with_capacity(upper);
for piece in nodes {
seq.push(Styled::new(piece.eval(ctx)?, ctx.styles.clone()));
}
ctx.styles = prev;
Ok(Node::Sequence(seq))
} }
} }
/// 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 mut seq = Vec::with_capacity(nodes.size_hint().1.unwrap_or_default());
while let Some(piece) = nodes.next() {
// Need to deal with wrap here.
let node = if let MarkupNode::Expr(Expr::Wrap(wrap)) = piece {
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;
Ok(Node::Sequence(seq))
}
impl Eval for MarkupNode { impl Eval for MarkupNode {
type Output = Node; type Output = Node;
@ -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,31 +302,32 @@ 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.
let paint = style.foreground.into(); fn style_piece(piece: &str, foreground: Paint, style: SynStyle) -> Styled<Node> {
let node = Node::Text(piece.into()); let paint = style.foreground.into();
let node = Node::Text(piece.into());
let mut styles = StyleMap::new(); let mut styles = StyleMap::new();
if paint != foreground { if paint != foreground {
styles.set(TextNode::FILL, paint); styles.set(TextNode::FILL, paint);
}
if style.font_style.contains(FontStyle::BOLD) {
styles.set(TextNode::STRONG, true);
}
if style.font_style.contains(FontStyle::ITALIC) {
styles.set(TextNode::EMPH, true);
}
if style.font_style.contains(FontStyle::UNDERLINE) {
styles.set(TextNode::LINES, vec![DecoLine::Underline.into()]);
}
Styled::new(node, styles)
} }
if style.font_style.contains(FontStyle::BOLD) {
styles.set(TextNode::STRONG, true);
}
if style.font_style.contains(FontStyle::ITALIC) {
styles.set(TextNode::EMPH, true);
}
if style.font_style.contains(FontStyle::UNDERLINE) {
styles.set(TextNode::LINES, vec![DecoLine::Underline.into()]);
}
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}