about summary refs log tree commit diff stats
path: root/apps
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-05-31 01:07:32 -0700
committerKartik Agaram <vc@akkartik.com>2020-05-31 01:07:32 -0700
commit2f16a74783d830caf2cc01bd67996317195c94c9 (patch)
treeaa8c4cc251d86e4e6221796d58e10326d60af4a5 /apps
parent972ca2c9345e51dde2ed5c2caac12b8a03191b6f (diff)
downloadmu-2f16a74783d830caf2cc01bd67996317195c94c9.tar.gz
6455 - abortive second attempt at parsing headings
This 'OO' approach seems more scalable, but I need to first wrestle with
a parsing issue: this text has a heading:

  abc *def
  # ghi*

Ugh, so I can't do this translation in a single pass.

Then again, maybe I should just keep going and not try to be compatible
with GitHub-Flavored Markdown. Require that new headings are also new paragraphs.
Diffstat (limited to 'apps')
-rw-r--r--apps/browse.mu199
1 files changed, 146 insertions, 53 deletions
diff --git a/apps/browse.mu b/apps/browse.mu
index 3cffdc4c..353c49b4 100644
--- a/apps/browse.mu
+++ b/apps/browse.mu
@@ -10,12 +10,15 @@ fn main args: (addr array (addr array byte)) -> exit-status/ebx: int {
   var filename/eax: (addr array byte) <- first-arg args
   var file/esi: (addr buffered-file) <- load-file filename
   enable-screen-grid-mode
+  enable-keyboard-immediate-mode
   var nrows/eax: int <- copy 0
   var ncols/ecx: int <- copy 0
   nrows, ncols <- screen-size
-  enable-keyboard-immediate-mode
+  var display-state-storage: display-state
+  var display-state: (addr display-state) = address display-state-storage
+  init-display-state display-state, nrows, ncols
   {
-    render file, nrows, ncols
+    render file, display-state
     var key/eax: byte <- read-key
     compare key, 0x71  # 'q'
     loop-if-!=
@@ -25,12 +28,143 @@ fn main args: (addr array (addr array byte)) -> exit-status/ebx: int {
   exit-status <- copy 0
 }
 
-type render-state {
-  current-state: int  # enum 0: normal, 1: bold, 2: heading
-  start-of-line?: boolean
-  num-hashes-seen?: int
+type display-state {
+  nrows: int  # const
+  ncols: int  # const
+  toprow: int
+  botrow: int
+  leftcol: int
+  rightcol: int
+  row: int
+  col: int
+}
+
+fn render in: (addr buffered-file), state: (addr display-state) {
+  start-drawing state
+  render-normal in, state
+}
+
+fn render-normal in: (addr buffered-file), state: (addr display-state) {
+  {
+    # if done-drawing?(state) break
+    var done?/eax: boolean <- done-drawing? state
+    compare done?, 0
+    break-if-!=
+    #
+    var c/eax: byte <- read-byte-buffered in
+    # if (c == EOF) break
+    compare c, 0xffffffff  # EOF marker
+    break-if-=
+    # if (c == '*') start-bold, render-until-asterisk(in, state), reset
+    # else if (c == '_') start-bold, render-until-underscore(in, state), reset
+    # else if (c == '#') compute-color, start color, render-header-line(in, state), reset
+    # else add-char(state, c)
+  }
+}
+
+fn render-until-asterisk in: (addr buffered-file), state: (addr display-state) {
+  {
+    # if done-drawing?(state) break
+    var done?/eax: boolean <- done-drawing? state
+    compare done?, 0
+    break-if-!=
+    #
+    var c/eax: byte <- read-byte-buffered in
+    # if (c == EOF) break
+    compare c, 0xffffffff  # EOF marker
+    break-if-=
+    # if (c == '*') break
+    # else add-char(state, c)
+  }
+}
+
+fn render-until-underscore in: (addr buffered-file), state: (addr display-state) {
+  {
+    # if done-drawing?(state) break
+    var done?/eax: boolean <- done-drawing? state
+    compare done?, 0
+    break-if-!=
+    #
+    var c/eax: byte <- read-byte-buffered in
+    # if (c == EOF) break
+    compare c, 0xffffffff  # EOF marker
+    break-if-=
+    # if (c == '_') break
+    # else add-char(state, c)
+  }
+}
+
+fn render-header-line in: (addr buffered-file), state: (addr display-state) {
+  {
+    # if done-drawing?(state) break
+    var done?/eax: boolean <- done-drawing? state
+    compare done?, 0
+    break-if-!=
+    #
+    var c/eax: byte <- read-byte-buffered in
+    # if (c == EOF) break
+    compare c, 0xffffffff  # EOF marker
+    break-if-=
+    # if (c == '*') break
+    # else add-char(state, c)
+  }
 }
 
+fn init-display-state self: (addr display-state), nrows: int, ncols: int {
+  # hardcoded parameters:
+  #   top-margin
+  #   page-margin
+  #   text-width
+  var dest/eax: (addr int) <- copy 0
+  # self->nrows = nrows
+  # self->ncols = ncols
+  # self->toprow = top-margin
+  # self->botrow = nrows
+  # self->leftcol = page-margin
+  # self->rightcol = self->leftcol + text-width
+  # start-drawing(self)
+}
+
+fn start-drawing self: (addr display-state) {
+  # self->row = toprow
+  # self->col = leftcol
+}
+
+fn add-char self: (addr display-state), c: byte {
+  # print c
+  # self->col++
+  # if (self->col > self->rightcol) next-line(self)
+}
+
+fn next-line self: (addr display-state) {
+  # self->row++
+  # if (self->row > self->botrow) next-page(self)
+}
+
+fn next-page self: (addr display-state) {
+  # self->leftcol = self->rightcol + 5
+  # self->rightcol = self->leftcol + text-width
+}
+
+fn done-drawing? self: (addr display-state) -> result/eax: boolean {
+  # self->rightcol >= self->ncols
+}
+
+# screen manipulation:
+#   properties: width, height
+#   reset attributes
+#   clear
+#   color
+#   bold
+#   underline
+#   print char
+
+# pages:
+#   properties: screen, row, col
+# methods for new pages
+#   new page
+#   new line
+
 # decide how to lay out pages on screen
 fn render in: (addr buffered-file), nrows: int, ncols: int {
   # Fit multiple pages on screen on separate columns, each wide enough to read
@@ -42,11 +176,6 @@ fn render in: (addr buffered-file), nrows: int, ncols: int {
   #   top-margin
   #   page-margin
   #   text-width
-  var _r: render-state
-  var r/edi: (addr render-state) <- address _r
-  # r->start-of-line? = true
-  var s/eax: (addr boolean) <- get r, start-of-line?
-  copy-to *s, 1  # true
   var toprow/eax: int <- copy 2  # top-margin
   var botrow/ecx: int <- copy nrows
   var leftcol/edx: int <- copy 5  # page-margin
@@ -56,7 +185,8 @@ fn render in: (addr buffered-file), nrows: int, ncols: int {
   {
     compare rightcol, ncols
     break-if->=
-    render-page in, toprow, leftcol, botrow, rightcol, r
+    clear toprow, leftcol, botrow, rightcol
+    render-page in, toprow, leftcol, botrow, rightcol
     leftcol <- copy rightcol
     leftcol <- add 5  # page-margin
     rightcol <- copy leftcol
@@ -65,11 +195,7 @@ fn render in: (addr buffered-file), nrows: int, ncols: int {
   }
 }
 
-fn render-page in: (addr buffered-file), toprow: int, leftcol: int, botrow: int, rightcol: int, _r: (addr render-state) {
-  var r/edi: (addr render-state) <- copy _r
-  var state/esi: (addr int) <- get r, current-state
-  clear toprow, leftcol, botrow, rightcol
-  # render screen rows
+fn render-page in: (addr buffered-file), toprow: int, leftcol: int, botrow: int, rightcol: int {
   var row/ecx: int <- copy toprow
 $line-loop: {
     compare row, botrow
@@ -102,20 +228,6 @@ $change-state: {
             copy-to *state, 1
             break $change-state
           }
-          compare c, 0x23  # '#'
-          {
-            break-if-!=
-            var s/eax: (addr boolean) <- get r, start-of-line?
-            compare *s, 1
-            {
-              break-if-!=
-              # r->current-state == 0 && c == '#' && at start of line => count '#'s
-              var h/eax: (addr int) <- get r, num-hashes-seen?
-              increment *h
-              break $change-state
-            }
-            break $change-state
-          }
           break $change-state
         }
         compare *state, 1  # bold
@@ -135,9 +247,9 @@ $change-state: {
           compare c, 0x5f  # '_'
           {
             break-if-!=
-            # r->current-state == 1 && c == '_' => print c, then normal text
             print-byte c
             col <- increment
+            # r->current-state == 1 && c == '_' => print c, then normal text
             reset-formatting
             start-color 0xec, 7  # 236 = darkish gray
             copy-to *state, 0
@@ -145,28 +257,9 @@ $change-state: {
           }
           break $change-state
         }
-      }  # $change-state
-      # update a few attributes of the state based on c without changing the state itself
-      compare c, 0xa  # newline
-      {
-        break-if-!=
-        # c is newline
-        var s/eax: (addr boolean) <- get r, start-of-line?
-        copy-to *s, 1  # true
-        # switch to normal text
-        reset-formatting
-        start-color 0xec, 7  # 236 = darkish gray
-        # no need to print newlines
-        break $char-loop
       }
-      compare c, 0x20  # space
-      {
-        break-if-=
-        # c is not newline or space
-        var s/eax: (addr boolean) <- get r, start-of-line?
-        copy-to *s, 0  # false
-      }
-      # print c
+      compare c, 0xa  # newline
+      break-if-=  # no need to print newlines
       print-byte c
       col <- increment
       loop