Browse Source

Add pretty-printing

David Peter 2 years ago
parent
commit
eefafa8e24
4 changed files with 78 additions and 20 deletions
  1. 16 0
      numbat-wasm/Cargo.lock
  2. 1 0
      numbat-wasm/Cargo.toml
  3. 23 15
      numbat-wasm/src/jquery_terminal_formatter.rs
  4. 38 5
      numbat-wasm/src/lib.rs

+ 16 - 0
numbat-wasm/Cargo.lock

@@ -104,6 +104,15 @@ dependencies = [
  "unicode-segmentation",
 ]
 
+[[package]]
+name = "html-escape"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476"
+dependencies = [
+ "utf8-width",
+]
+
 [[package]]
 name = "http"
 version = "0.2.9"
@@ -247,6 +256,7 @@ name = "numbat-wasm"
 version = "0.1.0"
 dependencies = [
  "console_error_panic_hook",
+ "html-escape",
  "numbat",
  "wasm-bindgen",
  "wasm-bindgen-test",
@@ -477,6 +487,12 @@ dependencies = [
  "percent-encoding",
 ]
 
+[[package]]
+name = "utf8-width"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1"
+
 [[package]]
 name = "wasm-bindgen"
 version = "0.2.87"

+ 1 - 0
numbat-wasm/Cargo.toml

@@ -25,6 +25,7 @@ console_error_panic_hook = { version = "0.1.6", optional = true }
 wee_alloc = { version = "0.4.5", optional = true }
 
 numbat = { path = "../numbat" }
+html-escape = "0.2.13"
 
 [dev-dependencies]
 wasm-bindgen-test = "0.3.13"

+ 23 - 15
numbat-wasm/src/jquery_terminal_formatter.rs

@@ -2,11 +2,19 @@ use numbat::markup::{FormatType, FormattedString, Formatter};
 
 pub struct JqueryTerminalFormatter;
 
-pub fn jt_format(class: &str, content: &str) -> String {
+pub fn jt_format(class: Option<&str>, content: &str) -> String {
     if content.is_empty() {
-        "".into()
-    } else {
+        return "".into();
+    }
+
+    let content = html_escape::encode_text(content)
+        .replace("[", "&#91;")
+        .replace("]", "&#93;");
+
+    if let Some(class) = class {
         format!("[[;;;hl-{class}]{content}]")
+    } else {
+        content.into()
     }
 }
 
@@ -16,18 +24,18 @@ impl Formatter for JqueryTerminalFormatter {
         FormattedString(_output_type, format_type, s): &FormattedString,
     ) -> String {
         let css_class = match format_type {
-            FormatType::Whitespace => return s.clone(),
-            FormatType::Dimmed => "dimmed",
-            FormatType::Text => return s.clone(),
-            FormatType::String => "string",
-            FormatType::Keyword => "keyword",
-            FormatType::Value => "value",
-            FormatType::Unit => "unit",
-            FormatType::Identifier => "identifier",
-            FormatType::TypeIdentifier => "type-identifier",
-            FormatType::Operator => "operator",
-            FormatType::Decorator => "decorator",
+            FormatType::Whitespace => None,
+            FormatType::Dimmed => Some("dimmed"),
+            FormatType::Text => None,
+            FormatType::String => Some("string"),
+            FormatType::Keyword => Some("keyword"),
+            FormatType::Value => Some("value"),
+            FormatType::Unit => Some("unit"),
+            FormatType::Identifier => Some("identifier"),
+            FormatType::TypeIdentifier => Some("type-identifier"),
+            FormatType::Operator => Some("operator"),
+            FormatType::Decorator => Some("decorator"),
         };
-        jt_format(&css_class, s)
+        jt_format(css_class, s)
     }
 }

+ 38 - 5
numbat-wasm/src/lib.rs

@@ -5,10 +5,10 @@ mod wasm_importer;
 use std::sync::{Arc, Mutex};
 
 use jquery_terminal_formatter::{jt_format, JqueryTerminalFormatter};
-use numbat::markup as m;
 use numbat::markup::Formatter;
 use numbat::pretty_print::PrettyPrint;
 use numbat::resolver::CodeSource;
+use numbat::{markup as m, Type};
 use numbat::{Context, InterpreterResult, InterpreterSettings};
 
 use wasm_bindgen::prelude::*;
@@ -42,6 +42,8 @@ impl Numbat {
     pub fn interpret(&mut self, code: &str) -> String {
         let mut output = String::new();
 
+        let registry = self.ctx.dimension_registry().clone();
+
         let fmt = JqueryTerminalFormatter {};
 
         let to_be_printed: Arc<Mutex<Vec<m::Markup>>> = Arc::new(Mutex::new(vec![]));
@@ -56,18 +58,49 @@ impl Numbat {
             .ctx
             .interpret_with_settings(&mut settings, &code, CodeSource::Text)
         {
-            Ok((_, result)) => {
+            Ok((statements, result)) => {
+                // Pretty print
+                output.push_str("\n");
+                for statement in &statements {
+                    output.push_str(&fmt.format(&statement.pretty_print(), true));
+                    output.push_str("\n\n");
+                }
+
+                // print(…) and type(…) results
                 for content in to_be_printed.lock().unwrap().iter() {
                     output.push_str(&fmt.format(content, true));
                 }
 
                 match result {
-                    InterpreterResult::Value(q) => {
-                        output.push_str(&fmt.format(&q.pretty_print(), true))
+                    InterpreterResult::Value(value) => {
+                        // TODO: the following statement is copied from numbat-cli. Move this to the numbat crate
+                        // to avoid duplication.
+                        let type_ = statements.last().map_or(m::empty(), |s| {
+                            if let numbat::Statement::Expression(e) = s {
+                                let type_ = e.get_type();
+
+                                if type_ == Type::scalar() {
+                                    m::empty()
+                                } else {
+                                    m::dimmed("    [")
+                                        + e.get_type().to_readable_type(&registry)
+                                        + m::dimmed("]")
+                                }
+                            } else {
+                                m::empty()
+                            }
+                        });
+
+                        let markup = m::whitespace("    ")
+                            + m::operator("=")
+                            + m::space()
+                            + value.pretty_print()
+                            + type_;
+                        output.push_str(&fmt.format(&markup, true));
                     }
                     InterpreterResult::Continue => {}
                     InterpreterResult::Exit(_) => {
-                        output.push_str(&jt_format("error", "Error!".into()))
+                        output.push_str(&jt_format(Some("error"), "Error!".into()))
                     }
                 }