about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--browse-slack/environment.mu154
1 files changed, 144 insertions, 10 deletions
diff --git a/browse-slack/environment.mu b/browse-slack/environment.mu
index 736b62f4..dc2360bd 100644
--- a/browse-slack/environment.mu
+++ b/browse-slack/environment.mu
@@ -223,10 +223,7 @@ fn draw-json-stream-wrapping-right-then-down screen: (addr screen), stream: (add
       compare g, 0x5c/backslash
       {
         break-if-!=
-        var next-g/ebx: grapheme <- read-json-grapheme stream
-        compare next-g, 0xffffffff/end-of-file
-        break-if-=  # just draw a final backslash
-        xcurr, ycurr <- render-json-escaped-grapheme screen, next-g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+        xcurr, ycurr <- render-json-escaped-grapheme screen, stream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
         break $draw-json-stream-wrapping-right-then-down:render-grapheme
       }
       xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
@@ -243,23 +240,160 @@ fn read-json-grapheme stream: (addr stream byte) -> _/ebx: grapheme {
   return result
 }
 
-fn render-json-escaped-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
+# '\' encountered
+fn render-json-escaped-grapheme screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
+  var g/ebx: grapheme <- read-json-grapheme stream
+  compare g, 0xffffffff/end-of-file
+  {
+    break-if-!=
+    return xcurr, ycurr
+  }
+  # \n = newline
   compare g, 0x6e/n
   var x/eax: int <- copy xcurr
   {
     break-if-!=
-    # minimum effort to clear cursor
-    draw-code-point screen, 0x20/space, xcurr, ycurr, color, background-color
-    x <- copy xmin
     increment ycurr
-    return x, ycurr
+    return xmin, ycurr
+  }
+  # ignore \t \r \f \b
+  {
+    compare g, 0x74/t
+    break-if-!=
+    return xcurr, ycurr
+  }
+  {
+    compare g, 0x72/r
+    break-if-!=
+    return xcurr, ycurr
+  }
+  {
+    compare g, 0x66/f
+    break-if-!=
+    return xcurr, ycurr
+  }
+  {
+    compare g, 0x62/b
+    break-if-!=
+    return xcurr, ycurr
   }
-  # most characters escape to themselves
   var y/ecx: int <- copy 0
+  # \u = Unicode
+  {
+    compare g, 0x75/u
+    break-if-!=
+    x, y <- render-json-escaped-unicode-grapheme screen, stream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # most characters escape to themselves
   x, y <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
   return x, y
 }
 
+# '\u' encountered
+fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
+  var ustream-storage: (stream byte 4)
+  var ustream/esi: (addr stream byte) <- address ustream-storage
+  # slurp 4 bytes exactly
+  var b/eax: byte <- read-byte stream
+  var b-int/eax: int <- copy b
+  append-byte ustream, b-int
+  var b/eax: byte <- read-byte stream
+  var b-int/eax: int <- copy b
+  append-byte ustream, b-int
+  var b/eax: byte <- read-byte stream
+  var b-int/eax: int <- copy b
+  append-byte ustream, b-int
+  var b/eax: byte <- read-byte stream
+  var b-int/eax: int <- copy b
+  append-byte ustream, b-int
+  # \u2013 = -
+  {
+    var endash?/eax: boolean <- stream-data-equal? ustream, "2013"
+    compare endash?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x2d/dash, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u2014 = -
+  {
+    var emdash?/eax: boolean <- stream-data-equal? ustream, "2014"
+    compare emdash?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x2d/dash, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u2018 = '
+  {
+    var left-quote?/eax: boolean <- stream-data-equal? ustream, "2018"
+    compare left-quote?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x27/quote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u2019 = '
+  {
+    var right-quote?/eax: boolean <- stream-data-equal? ustream, "2019"
+    compare right-quote?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x27/quote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u201c = "
+  {
+    var left-dquote?/eax: boolean <- stream-data-equal? ustream, "201c"
+    compare left-dquote?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x22/dquote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u201d = "
+  {
+    var right-dquote?/eax: boolean <- stream-data-equal? ustream, "201d"
+    compare right-dquote?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x22/dquote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u2022 = *
+  {
+    var bullet?/eax: boolean <- stream-data-equal? ustream, "2022"
+    compare bullet?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- render-grapheme screen, 0x2a/asterisk, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # \u2026 = ...
+  {
+    var ellipses?/eax: boolean <- stream-data-equal? ustream, "2026"
+    compare ellipses?, 0/false
+    break-if-=
+    var x/eax: int <- copy 0
+    var y/ecx: int <- copy 0
+    x, y <- draw-text-wrapping-right-then-down screen, "...", xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+    return x, y
+  }
+  # TODO: rest of Unicode
+  var x/eax: int <- copy 0
+  var y/ecx: int <- copy 0
+  x, y <- draw-stream-wrapping-right-then-down screen, ustream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
+  return x, y
+}
+
 ### Edit
 
 fn update-environment env: (addr environment), key: byte, items: (addr item-list) {