summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-01-28 22:32:53 +0100
committerLaurenz <laurmaedje@gmail.com>2022-01-28 22:32:53 +0100
commit5c53b9ff606f927bf0f2e4c40daf19d50ece09d9 (patch)
tree4c71142789415e1d0c1a7952eb3ed9f70898b9d1
parent9c906f92c50d453822b12896d29b7883802ea567 (diff)
Support for `wrap`
-rw-r--r--src/eval/mod.rs82
-rw-r--r--tests/ref/style/wrap.pngbin0 -> 10612 bytes
-rw-r--r--tests/typ/style/wrap.typ21
3 files changed, 66 insertions, 37 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index a8c6c688..d459ba6e 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -178,16 +178,31 @@ impl Eval for Markup {
type Output = Node;
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
- let prev = mem::take(&mut ctx.styles);
- 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))
+ 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 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 {
@@ -265,8 +280,8 @@ impl RawNode {
sequence.push(Styled::bare(Node::Linebreak));
}
- for (style, line) in highlighter.highlight(line, &SYNTAXES) {
- sequence.push(Self::styled_piece(style, line, foreground));
+ for (style, piece) in highlighter.highlight(line, &SYNTAXES) {
+ sequence.push(style_piece(piece, foreground, style));
}
}
}
@@ -279,11 +294,7 @@ impl RawNode {
red.as_ref(),
&highlighter,
&mut |range, style| {
- sequence.push(Self::styled_piece(
- style,
- &self.text[range],
- foreground,
- ));
+ sequence.push(style_piece(&self.text[range], foreground, style));
},
)
}
@@ -291,31 +302,32 @@ impl RawNode {
Node::Sequence(sequence).monospaced()
}
+}
- fn styled_piece(style: SynStyle, piece: &str, foreground: Paint) -> Styled<Node> {
- let paint = style.foreground.into();
- let node = Node::Text(piece.into());
-
- let mut styles = StyleMap::new();
+/// 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 node = Node::Text(piece.into());
- if paint != foreground {
- styles.set(TextNode::FILL, paint);
- }
+ let mut styles = StyleMap::new();
- if style.font_style.contains(FontStyle::BOLD) {
- styles.set(TextNode::STRONG, true);
- }
+ if paint != foreground {
+ styles.set(TextNode::FILL, paint);
+ }
- if style.font_style.contains(FontStyle::ITALIC) {
- styles.set(TextNode::EMPH, true);
- }
+ if style.font_style.contains(FontStyle::BOLD) {
+ styles.set(TextNode::STRONG, true);
+ }
- if style.font_style.contains(FontStyle::UNDERLINE) {
- styles.set(TextNode::LINES, vec![DecoLine::Underline.into()]);
- }
+ if style.font_style.contains(FontStyle::ITALIC) {
+ styles.set(TextNode::EMPH, true);
+ }
- Styled::new(node, styles)
+ if style.font_style.contains(FontStyle::UNDERLINE) {
+ styles.set(TextNode::LINES, vec![DecoLine::Underline.into()]);
}
+
+ Styled::new(node, styles)
}
impl Eval for MathNode {
@@ -776,7 +788,7 @@ impl Eval for WrapExpr {
type Output = Value;
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())
}
}
diff --git a/tests/ref/style/wrap.png b/tests/ref/style/wrap.png
new file mode 100644
index 00000000..346da53f
--- /dev/null
+++ b/tests/ref/style/wrap.png
Binary files differ
diff --git a/tests/typ/style/wrap.typ b/tests/typ/style/wrap.typ
index c665a9d2..5e0fdd0d 100644
--- a/tests/typ/style/wrap.typ
+++ b/tests/typ/style/wrap.typ
@@ -1,6 +1,23 @@
// 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)
+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}