diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 596ceb501..3cf978606 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -118,6 +118,7 @@ impl Eval for Expr { Self::Binary(v) => v.eval(ctx), Self::Let(v) => v.eval(ctx), Self::If(v) => v.eval(ctx), + Self::While(v) => v.eval(ctx), Self::For(v) => v.eval(ctx), } } @@ -403,24 +404,56 @@ impl Eval for ExprIf { fn eval(&self, ctx: &mut EvalContext) -> Self::Output { let condition = self.condition.eval(ctx); - - if let Value::Bool(boolean) = condition { - return if boolean { + if let Value::Bool(condition) = condition { + if condition { self.if_body.eval(ctx) } else if let Some(expr) = &self.else_body { expr.eval(ctx) } else { Value::None - }; - } else if condition != Value::Error { - ctx.diag(error!( - self.condition.span(), - "expected boolean, found {}", - condition.type_name(), - )); + } + } else { + if condition != Value::Error { + ctx.diag(error!( + self.condition.span(), + "expected boolean, found {}", + condition.type_name(), + )); + } + Value::Error } + } +} - Value::Error +impl Eval for ExprWhile { + type Output = Value; + + fn eval(&self, ctx: &mut EvalContext) -> Self::Output { + let mut output = vec![]; + loop { + let condition = self.condition.eval(ctx); + if let Value::Bool(condition) = condition { + if condition { + match self.body.eval(ctx) { + Value::Template(v) => output.extend(v), + Value::Str(v) => output.push(TemplateNode::Str(v)), + Value::Error => return Value::Error, + _ => {} + } + } else { + return Value::Template(output); + } + } else { + if condition != Value::Error { + ctx.diag(error!( + self.condition.span(), + "expected boolean, found {}", + condition.type_name(), + )); + } + return Value::Error; + } + } } } @@ -438,7 +471,8 @@ impl Eval for ExprFor { $(ctx.scopes.def_mut($binding.as_str(), $value);)* match self.body.eval(ctx) { - Value::Template(new) => output.extend(new), + Value::Template(v) => output.extend(v), + Value::Str(v) => output.push(TemplateNode::Str(v)), Value::Error => { ctx.scopes.pop(); return Value::Error; diff --git a/src/eval/value.rs b/src/eval/value.rs index 2a91cf8a8..d910155a1 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -586,7 +586,11 @@ primitive! { Color: "color", Value::Color } primitive! { String: "string", Value::Str } primitive! { ValueArray: "array", Value::Array } primitive! { ValueDict: "dictionary", Value::Dict } -primitive! { ValueTemplate: "template", Value::Template } +primitive! { + ValueTemplate: "template", + Value::Template, + Value::Str(v) => vec![TemplateNode::Str(v)], +} primitive! { ValueFunc: "function", Value::Func } primitive! { ValueArgs: "arguments", Value::Args } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 8d6958cf8..d4cf90c75 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -71,7 +71,7 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option { Token::UnicodeEscape(t) => Node::Text(unicode_escape(p, t)), // Hashtag + keyword / identifier. - Token::Ident(_) | Token::Let | Token::If | Token::For => { + Token::Ident(_) | Token::Let | Token::If | Token::While | Token::For => { *at_start = false; let stmt = token == Token::Let; let group = if stmt { Group::Stmt } else { Group::Expr }; @@ -191,6 +191,7 @@ fn primary(p: &mut Parser) -> Option { // Keywords. Some(Token::Let) => expr_let(p), Some(Token::If) => expr_if(p), + Some(Token::While) => expr_while(p), Some(Token::For) => expr_for(p), // Structures. @@ -382,6 +383,25 @@ fn expr_if(p: &mut Parser) -> Option { expr_if } +/// Parse a while expresion. +fn expr_while(p: &mut Parser) -> Option { + let start = p.start(); + p.assert(Token::While); + + let mut expr_while = None; + if let Some(condition) = expr(p) { + if let Some(body) = body(p) { + expr_while = Some(Expr::While(ExprWhile { + span: p.span(start), + condition: Box::new(condition), + body: Box::new(body), + })); + } + } + + expr_while +} + /// Parse a for expression. fn expr_for(p: &mut Parser) -> Option { let start = p.start(); diff --git a/src/pretty.rs b/src/pretty.rs index de910b99a..0899824ac 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -221,6 +221,7 @@ impl Pretty for Expr { Self::Call(v) => v.pretty(p), Self::Let(v) => v.pretty(p), Self::If(v) => v.pretty(p), + Self::While(v) => v.pretty(p), Self::For(v) => v.pretty(p), } } @@ -413,6 +414,15 @@ impl Pretty for ExprIf { } } +impl Pretty for ExprWhile { + fn pretty(&self, p: &mut Printer) { + p.push_str("while "); + self.condition.pretty(p); + p.push(' '); + self.body.pretty(p); + } +} + impl Pretty for ExprFor { fn pretty(&self, p: &mut Printer) { p.push_str("for "); @@ -718,9 +728,10 @@ mod tests { // Keywords. roundtrip("#let x = 1 + 2"); + test_parse("#if x [y] #else [z]", "#if x [y] else [z]"); + roundtrip("#while x {y}"); roundtrip("#for x in y {z}"); roundtrip("#for k, x in y {z}"); - test_parse("#if x [y] #else [z]", "#if x [y] else [z]"); } #[test] diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 5b37bb568..638d9dd31 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -19,19 +19,21 @@ pub enum Expr { Template(ExprTemplate), /// A grouped expression: `(1 + 2)`. Group(ExprGroup), - /// A block expression: `{ #let x = 1; x + 2 }`. + /// A block expression: `{ let x = 1; x + 2 }`. Block(ExprBlock), /// A unary operation: `-x`. Unary(ExprUnary), /// A binary operation: `a + b`. Binary(ExprBinary), - /// An invocation of a function: `foo(...)`, `#[foo ...]`. + /// An invocation of a function: `foo(...)`. Call(ExprCall), - /// A let expression: `#let x = 1`. + /// A let expression: `let x = 1`. Let(ExprLet), - /// An if expression: `#if x { y } #else { z }`. + /// An if expression: `if x { y } else { z }`. If(ExprIf), - /// A for expression: `#for x #in y { z }`. + /// A while expression: `while x { y }`. + While(ExprWhile), + /// A for expression: `for x in y { z }`. For(ExprFor), } @@ -51,6 +53,7 @@ impl Expr { Self::Call(v) => v.span, Self::Let(v) => v.span, Self::If(v) => v.span, + Self::While(v) => v.span, Self::For(v) => v.span, } } @@ -62,6 +65,7 @@ impl Expr { | Expr::Call(_) | Expr::Let(_) | Expr::If(_) + | Expr::While(_) | Expr::For(_) ) } @@ -154,7 +158,7 @@ pub struct ExprGroup { pub expr: Box, } -/// A block expression: `{ #let x = 1; x + 2 }`. +/// A block expression: `{ let x = 1; x + 2 }`. #[derive(Debug, Clone, PartialEq)] pub struct ExprBlock { /// The source code location. @@ -365,7 +369,7 @@ pub enum Associativity { Right, } -/// An invocation of a function: `foo(...)`, `#[foo ...]`. +/// An invocation of a function: `foo(...)`. #[derive(Debug, Clone, PartialEq)] pub struct ExprCall { /// The source code location. @@ -407,7 +411,7 @@ impl ExprArg { } } -/// A let expression: `#let x = 1`. +/// A let expression: `let x = 1`. #[derive(Debug, Clone, PartialEq)] pub struct ExprLet { /// The source code location. @@ -418,7 +422,7 @@ pub struct ExprLet { pub init: Option>, } -/// An if expression: `#if x { y } #else { z }`. +/// An if expression: `if x { y } else { z }`. #[derive(Debug, Clone, PartialEq)] pub struct ExprIf { /// The source code location. @@ -431,7 +435,18 @@ pub struct ExprIf { pub else_body: Option>, } -/// A for expression: `#for x #in y { z }`. +/// A while expression: `while x { y }`. +#[derive(Debug, Clone, PartialEq)] +pub struct ExprWhile { + /// The source code location. + pub span: Span, + /// The condition which selects whether to evaluate the body. + pub condition: Box, + /// The expression to evaluate while the condition is true. + pub body: Box, +} + +/// A for expression: `for x in y { z }`. #[derive(Debug, Clone, PartialEq)] pub struct ExprFor { /// The source code location. @@ -447,9 +462,9 @@ pub struct ExprFor { /// A pattern in a for loop. #[derive(Debug, Clone, PartialEq)] pub enum ForPattern { - /// A value pattern: `#for v #in array`. + /// A value pattern: `for v in array`. Value(Ident), - /// A key-value pattern: `#for k, v #in dict`. + /// A key-value pattern: `for k, v in dict`. KeyValue(Ident, Ident), } diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs index 2d3c683f8..1bf260c76 100644 --- a/src/syntax/visit.rs +++ b/src/syntax/visit.rs @@ -61,6 +61,7 @@ visit! { Expr::Call(e) => v.visit_call(e), Expr::Let(e) => v.visit_let(e), Expr::If(e) => v.visit_if(e), + Expr::While(e) => v.visit_while(e), Expr::For(e) => v.visit_for(e), } } @@ -132,6 +133,11 @@ visit! { } } + fn visit_while(v, node: &ExprWhile) { + v.visit_expr(&node.condition); + v.visit_expr(&node.body); + } + fn visit_for(v, node: &ExprFor) { v.visit_expr(&node.iter); v.visit_expr(&node.body); diff --git a/tests/ref/control/for-invalid.png b/tests/ref/control/for-invalid.png deleted file mode 100644 index d758aa95a..000000000 Binary files a/tests/ref/control/for-invalid.png and /dev/null differ diff --git a/tests/ref/control/for-value.png b/tests/ref/control/for-value.png deleted file mode 100644 index fa323edcd..000000000 Binary files a/tests/ref/control/for-value.png and /dev/null differ diff --git a/tests/ref/control/for.png b/tests/ref/control/for.png index 2f13985ad..cfbc8d08d 100644 Binary files a/tests/ref/control/for.png and b/tests/ref/control/for.png differ diff --git a/tests/ref/control/if-invalid.png b/tests/ref/control/if-invalid.png deleted file mode 100644 index 319fbdbdf..000000000 Binary files a/tests/ref/control/if-invalid.png and /dev/null differ diff --git a/tests/ref/control/if.png b/tests/ref/control/if.png index 75a20d000..7db3a8aec 100644 Binary files a/tests/ref/control/if.png and b/tests/ref/control/if.png differ diff --git a/tests/ref/control/invalid.png b/tests/ref/control/invalid.png new file mode 100644 index 000000000..9a1190883 Binary files /dev/null and b/tests/ref/control/invalid.png differ diff --git a/tests/ref/control/let-invalid.png b/tests/ref/control/let-invalid.png deleted file mode 100644 index 19d4d545d..000000000 Binary files a/tests/ref/control/let-invalid.png and /dev/null differ diff --git a/tests/ref/control/let-terminated.png b/tests/ref/control/let.png similarity index 100% rename from tests/ref/control/let-terminated.png rename to tests/ref/control/let.png diff --git a/tests/ref/control/while.png b/tests/ref/control/while.png new file mode 100644 index 000000000..f0baf0afd Binary files /dev/null and b/tests/ref/control/while.png differ diff --git a/tests/ref/spacing.png b/tests/ref/spacing.png index 5c3acf9b2..fb102e66f 100644 Binary files a/tests/ref/spacing.png and b/tests/ref/spacing.png differ diff --git a/tests/typ/control/for-invalid.typ b/tests/typ/control/for-invalid.typ deleted file mode 100644 index c8bdebdd2..000000000 --- a/tests/typ/control/for-invalid.typ +++ /dev/null @@ -1,32 +0,0 @@ -// Test invalid for loop syntax. - ---- -// Error: 5-5 expected identifier -#for - -// Error: 7-7 expected keyword `in` -#for v - -// Error: 10-10 expected expression -#for v in - -// Error: 15-15 expected body -#for v in iter - ---- -// Should output `v in iter`. -// Error: 5 expected identifier -#for -v in iter {} - -// Should output `A thing`. -// Error: 7-10 expected identifier, found string -A#for "v" thing. - -// Should output `in iter`. -// Error: 6-9 expected identifier, found string -#for "v" in iter {} - -// Should output `+ b in iter`. -// Error: 7 expected keyword `in` -#for a + b in iter {} diff --git a/tests/typ/control/for-value.typ b/tests/typ/control/for-value.typ deleted file mode 100644 index 3ab807160..000000000 --- a/tests/typ/control/for-value.typ +++ /dev/null @@ -1,20 +0,0 @@ -// Test return value of for loops. - ---- -// Template body yields template. -// Should output `234`. -#for v in (1, 2, 3, 4) [#if v >= 2 [{v}]] - ---- -// Block body yields template. -// Should output `[1st, 2nd, 3rd, 4th, 5th, 6th]`. -{ - "[" + for v in (1, 2, 3, 4, 5, 6) { - (if v > 1 [, ] - + [{v}] - + if v == 1 [st] - + if v == 2 [nd] - + if v == 3 [rd] - + if v >= 4 [th]) - } + "]" -} diff --git a/tests/typ/control/for.typ b/tests/typ/control/for.typ index 294345b51..36bce447b 100644 --- a/tests/typ/control/for.typ +++ b/tests/typ/control/for.typ @@ -1,11 +1,10 @@ // Test for loops. -// Ref: false --- +// Empty array. +#for x in () [Nope] + // Array. - -#for x in () {} - #let sum = 0 #for x in (1, 2, 3, 4, 5) { sum += x @@ -13,14 +12,12 @@ #test(sum, 15) ---- -// Dictionary. -// Ref: true -(\ #for k, v in (name: "Typst", age: 2) [ - #h(0.5cm) {k}: {v}, \ -]) +// Dictionary is not traversed in insertion order. +// Should output `age: 1, name: Typst,`. +#for k, v in (name: "Typst", age: 2) [ + {k}: {v}, \ +] ---- // String. { let out = "" @@ -36,6 +33,33 @@ } --- +// Block body. +// Should output `[1st, 2nd, 3rd, 4th, 5th, 6th]`. +{ + "[" + for v in (1, 2, 3, 4, 5, 6) { + (if v > 1 [, ] + + [{v}] + + if v == 1 [st] + + if v == 2 [nd] + + if v == 3 [rd] + + if v >= 4 [th]) + } + "]" +} + +// Template body. +// Should output `234`. +#for v in (1, 2, 3, 4, 5, 6, 7) [#if v >= 2 and v <= 5 { repr(v) }] + +--- +// Value of for loops. +// Ref: false +#test(type(for v in () {}), "template") +#test(type(for v in () []), "template") + +--- +// Error: 14-19 unknown variable +#let error = error + // Uniterable expression. // Error: 11-15 cannot loop over boolean #for v in true {} @@ -44,9 +68,7 @@ // Error: 11-18 cannot add integer and string #for v in 1 + "2" {} -// Error: 14-17 cannot apply '-' to string -#let error = -"" -#let result = for v in (1, 2, 3) { +// A single error stops iteration. +#test(error, for v in (1, 2, 3) { if v < 2 [Ok] else {error} -} -#test(result, error) +}) diff --git a/tests/typ/control/if-invalid.typ b/tests/typ/control/if-invalid.typ deleted file mode 100644 index 6d2deab15..000000000 --- a/tests/typ/control/if-invalid.typ +++ /dev/null @@ -1,28 +0,0 @@ -// Test invalid if syntax. - ---- -// Error: 4 expected expression -#if - -// Error: 4 expected expression -{if} - -// Error: 6 expected body -#if x - -// Error: 1-6 unexpected keyword `else` -#else {} - ---- -// Should output `x`. -// Error: 4 expected expression -#if -x {} - -// Should output `something`. -// Error: 6 expected body -#if x something - -// Should output `A thing.` -// Error: 20 expected body -A#if false {} #else thing diff --git a/tests/typ/control/if-value.typ b/tests/typ/control/if-value.typ deleted file mode 100644 index d7124255f..000000000 --- a/tests/typ/control/if-value.typ +++ /dev/null @@ -1,21 +0,0 @@ -// Test return value of if expressions. -// Ref: false - ---- -{ - let x = 1 - let y = 2 - let z - - // Returns if branch. - z = if x < y { "ok" } - test(z, "ok") - - // Returns else branch. - z = if x > y { "bad" } else { "ok" } - test(z, "ok") - - // Missing else evaluates to none. - z = if x > y { "bad" } - test(z, none) -} diff --git a/tests/typ/control/if.typ b/tests/typ/control/if.typ index 4ed6b6496..8d07e9b82 100644 --- a/tests/typ/control/if.typ +++ b/tests/typ/control/if.typ @@ -3,35 +3,61 @@ --- // Test condition evaluation. #if 1 < 2 [ - Ok. + One. ] #if true == false [ - Bad, but we {dont-care}! + {Bad}, but we {dont-care}! ] --- -// Brace in condition. +// Braced condition. #if {true} [ - Ok. + One. +] + +// Template in condition. +#if [] != none [ + Two. ] // Multi-line condition with parens. #if ( 1 + 1 == 1 -) { - nope -} #else { - "Ok." +) [ + Nope. +] #else { + "Three." } // Multiline. #if false [ Bad. ] #else { - let pt = "." - "Ok" + pt + let point = "." + "Four" + point +} + +--- +// Value of if expressions. +// Ref: false +{ + let x = 1 + let y = 2 + let z + + // Returns if branch. + z = if x < y { "ok" } + test(z, "ok") + + // Returns else branch. + z = if x > y { "bad" } else { "ok" } + test(z, "ok") + + // Missing else evaluates to none. + z = if x > y { "bad" } + test(z, none) } --- diff --git a/tests/typ/control/invalid.typ b/tests/typ/control/invalid.typ new file mode 100644 index 000000000..49158a688 --- /dev/null +++ b/tests/typ/control/invalid.typ @@ -0,0 +1,100 @@ +// Test invalid control syntax. + +--- +// Error: 5 expected identifier +#let + +// Error: 5 expected identifier +{let} + +// Error: 6-9 expected identifier, found string +#let "v" + +// Should output `1`. +// Error: 7 expected semicolon or line break +#let v 1 + +// Error: 9 expected expression +#let v = + +// Should output `= 1`. +// Error: 6-9 expected identifier, found string +#let "v" = 1 + +--- +// Error: 4 expected expression +#if + +// Error: 4 expected expression +{if} + +// Error: 6 expected body +#if x + +// Error: 1-6 unexpected keyword `else` +#else {} + +// Should output `x`. +// Error: 4 expected expression +#if +x {} + +// Should output `something`. +// Error: 6 expected body +#if x something + +// Should output `A thing.` +// Error: 20 expected body +A#if false {} #else thing + +--- +// Error: 7 expected expression +#while + +// Error: 7 expected expression +{while} + +// Error: 9 expected body +#while x + +// Should output `x`. +// Error: 7 expected expression +#while +x {} + +// Should output `something`. +// Error: 9 expected body +#while x something + +--- +// Error: 5 expected identifier +#for + +// Error: 5 expected identifier +{for} + +// Error: 7 expected keyword `in` +#for v + +// Error: 10 expected expression +#for v in + +// Error: 15 expected body +#for v in iter + +// Should output `v in iter`. +// Error: 5 expected identifier +#for +v in iter {} + +// Should output `A thing`. +// Error: 7-10 expected identifier, found string +A#for "v" thing + +// Should output `in iter`. +// Error: 6-9 expected identifier, found string +#for "v" in iter {} + +// Should output `+ b in iter`. +// Error: 7 expected keyword `in` +#for a + b in iter {} diff --git a/tests/typ/control/let-invalid.typ b/tests/typ/control/let-invalid.typ deleted file mode 100644 index f29353edf..000000000 --- a/tests/typ/control/let-invalid.typ +++ /dev/null @@ -1,20 +0,0 @@ -// Test invalid let binding syntax. - ---- -// Error: 5 expected identifier -#let - -// Error: 6-9 expected identifier, found string -#let "v" - -// Should output `1`. -// Error: 7 expected semicolon or line break -#let v 1 - -// Error: 9 expected expression -#let v = - ---- -// Should output `= 1`. -// Error: 6-9 expected identifier, found string -#let "v" = 1 diff --git a/tests/typ/control/let-terminated.typ b/tests/typ/control/let-terminated.typ deleted file mode 100644 index 623265e05..000000000 --- a/tests/typ/control/let-terminated.typ +++ /dev/null @@ -1,28 +0,0 @@ -// Test termination of let statements. - ---- -// Terminated by line break. -#let v1 = 1 -One - -// Terminated by semicolon. -#let v2 = 2; Two - -// Terminated by semicolon and line break. -#let v3 = 3; -Three - -// Terminated because expression ends. -// Error: 12 expected semicolon or line break -#let v4 = 4 Four - -// Terminated by semicolon even though we are in a paren group. -// Error: 2:19 expected expression -// Error: 1:19 expected closing paren -#let v5 = (1, 2 + ; Five - -#test(v1, 1) -#test(v2, 2) -#test(v3, 3) -#test(v4, 4) -#test(v5, (1, 2)) diff --git a/tests/typ/control/let.typ b/tests/typ/control/let.typ index e609d3a9c..8df29b116 100644 --- a/tests/typ/control/let.typ +++ b/tests/typ/control/let.typ @@ -1,7 +1,8 @@ // Test let bindings. -// Ref: false --- +// Ref: false + // Automatically initialized with none. #let x #test(x, none) @@ -9,3 +10,32 @@ // Manually initialized with one. #let x = 1 #test(x, 1) + +--- +// Termination. + +// Terminated by line break. +#let v1 = 1 +One + +// Terminated by semicolon. +#let v2 = 2; Two + +// Terminated by semicolon and line break. +#let v3 = 3; +Three + +// Terminated because expression ends. +// Error: 12 expected semicolon or line break +#let v4 = 4 Four + +// Terminated by semicolon even though we are in a paren group. +// Error: 2:19 expected expression +// Error: 1:19 expected closing paren +#let v5 = (1, 2 + ; Five + +#test(v1, 1) +#test(v2, 2) +#test(v3, 3) +#test(v4, 4) +#test(v5, (1, 2)) diff --git a/tests/typ/control/while.typ b/tests/typ/control/while.typ new file mode 100644 index 000000000..7ad703720 --- /dev/null +++ b/tests/typ/control/while.typ @@ -0,0 +1,46 @@ +// Test while expressions. + +--- +// Should output `2 4 6 8 10`. +#let i = 0 +#while i < 10 [ + { i += 2 } + #i +] + +// Should output `Hi`. +#let iter = true +#while iter { + iter = false + "Hi." +} + +#while false { + dont-care +} + +--- +// Value of while loops. +// Ref: false +#test(type(while false {}), "template") +#test(type(while false []), "template") + +--- +// Error: 14-19 unknown variable +#let error = error + +// Condition must be boolean. +// Error: 8-14 expected boolean, found template +#while [nope] [nope] + +// Make sure that we don't complain twice. +// Error: 8-15 unknown variable +#while nothing {} + +// A single error stops iteration. +#let i = 0 +#test(error, while i < 10 { + i += 1 + if i < 5 [nope] else { error } +}) +#test(i, 5) diff --git a/tests/typ/spacing.typ b/tests/typ/spacing.typ index d44cd84c8..77dac53cc 100644 --- a/tests/typ/spacing.typ +++ b/tests/typ/spacing.typ @@ -19,9 +19,17 @@ A #if true{"B"} C \ A#if false [] #else [B]C \ A#if true [B] #else [] C \ +--- +// Spacing around while loop. + +#let c = true; A#while c [{c = false}B]C \ +#let c = true; A#while c [{c = false}B] C \ +#let c = true; A #while c { c = false; "B" }C \ +#let c = true; A #while c { c = false; "B" } C \ + --- // Spacing around for loop. A#for _ in (none,) [B]C \ A#for _ in (none,) [B] C \ -A #for _ in (none,) [B]C \ +A #for _ in (none,) {"B"}C \ diff --git a/tools/test-helper/extension.js b/tools/test-helper/extension.js index e5325bed8..ad157bcb6 100644 --- a/tools/test-helper/extension.js +++ b/tools/test-helper/extension.js @@ -92,9 +92,9 @@ function getWebviewContent(pngSrc, refSrc, stdout, stderr) {