diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-01-28 22:32:53 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-01-28 22:32:53 +0100 |
| commit | 5c53b9ff606f927bf0f2e4c40daf19d50ece09d9 (patch) | |
| tree | 4c71142789415e1d0c1a7952eb3ed9f70898b9d1 /src/eval/mod.rs | |
| parent | 9c906f92c50d453822b12896d29b7883802ea567 (diff) | |
Support for `wrap`
Diffstat (limited to 'src/eval/mod.rs')
| -rw-r--r-- | src/eval/mod.rs | 82 |
1 files changed, 47 insertions, 35 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()) } } |
