sim.texi (5967B)
1 @node sim 2 @chapter An example vise implementation 3 4 5 Consider the following interaction: 6 7 @example 8 This is the root page 9 You have visited 1 time. 10 0:foo 11 1:bar 12 13 $ 1 14 Please visit foo first. 15 Any input to return. 16 17 $ x 18 This is the root page. 19 You have visited 2 times. 20 0:foo 21 1:bar 22 23 $ 0 24 Welcome to page foo. 25 Please write seomthing. 26 27 $ blah blah blah 28 This is the root page. 29 You have visited 3 times. 30 0:foo 31 1:bar 32 33 $ 1 34 Thanks for visiting foo and bar. 35 You have written: 36 blah blah blah 37 @end example 38 39 The simple interface above involves four different menu nodes. 40 41 In order to engineer these using vise, three types of components are involved: 42 43 @itemize 44 @item An assembly-like menu handling script. 45 @item A display template. 46 @item External code handlers for the counter and the "something" input. 47 @end itemize 48 49 50 51 The nodes are: 52 53 @table @code 54 @item root 55 The first page. 56 @item foo 57 The "foo" page. 58 @item bar 59 The "bar" page after "foo" has been visited. 60 @item ouch 61 The "bar" page before "foo" has been visited. 62 @end table 63 64 65 @section Templates 66 67 Each page has a template that may or may not contain dynamic elements. 68 69 In this example the @code{root} and @code{bar} nodes contains dynamic content. 70 71 @subsection root 72 73 @verbatim 74 This is the root page 75 You have visited {{.count}}. 76 @end verbatim 77 78 @subsection foo 79 80 @verbatim 81 Welcome to page foo. 82 Please write something. 83 @end verbatim 84 85 @subsection bar 86 87 @verbatim 88 Thanks for visiting foo and bar. 89 You wrote "{{.something}}" in foo. 90 @end verbatim 91 92 @subsection ouch 93 94 @verbatim 95 Please visit foo first. 96 Any input to return. 97 @end verbatim 98 99 100 @section Scripts 101 102 The scripts are responsible for defining menus, handling navigation flow control, and triggering external code handlers. 103 104 @subsection root 105 106 @verbatim 107 LOAD count 8 # trigger external code handler "count" 108 LOAD something 0 # trigger external code handler "something" 109 RELOAD count # explicitly trigger "count" every time this code is executed. 110 MAP count # make the result from "count" available to the template renderer 111 MOUT foo 0 # menu item 112 MOUT bar 1 # menu item 113 HALT # render template and wait for input 114 INCMP foo 0 # match menu selection 0, move to node "foo" on match 115 INCMP bar 1 # match menu selection 1, move to node "bar" on match 116 @end verbatim 117 118 @subsection foo 119 120 @verbatim 121 HALT # render template and wait for input 122 RELOAD something # pass input to the "something" external code handler. 123 # The input will be appended to the stored value. 124 # The "HAVESOMETHING" flag (8) will be set. 125 MOVE _ # move up one level 126 @end verbatim 127 128 129 @subsection bar 130 131 @verbatim 132 CATCH ouch 8 0 # if the "HAVESOMETHING" (8) flag has NOT (0) been set, move to "ouch" 133 MNEXT next 11 # menu choice to display for advancing one page 134 MPREV back 22 # menu choice to display for going back to the previous page 135 MAP something # make the result from "something" available to the template renderer 136 HALT # render template and wait for input 137 INCMP > 11 # handle the "next" menu choice 138 INCMP < 22 # handle to "back" menu choice 139 INCMP _ * # move to the root node on any input 140 @end verbatim 141 142 143 @subsection ouch 144 145 @verbatim 146 HALT # render template and wait for input 147 INCMP ^ * # move to the root node on any input 148 @end verbatim 149 150 151 @section External code handlers 152 153 The script code contains @code{LOAD} instructions for two different methods. 154 155 @verbatim 156 import ( 157 "context" 158 "fmt" 159 "path" 160 "strings" 161 162 163 testdataloader "github.com/peteole/testdata-loader" 164 165 "git.defalsify.org/vise.git/state" 166 "git.defalsify.org/vise.git/resource" 167 ) 168 169 const ( 170 USERFLAG_HAVESOMETHING = iota + state.FLAG_USERSTART 171 ) 172 173 var ( 174 baseDir = testdataloader.GetBasePath() 175 scriptDir = path.Join(baseDir, "examples", "intro") 176 ) 177 178 type introResource struct { 179 *resource.FsResource 180 c int64 181 v []string 182 } 183 184 func newintroResource() introResource { 185 fs := resource.NewFsResource(scriptDir) 186 return introResource{fs, 0, []string{}} 187 } 188 189 // increment counter. 190 // return a string representing the current value of the counter. 191 func(c *introResource) count(ctx context.Context, sym string, input []byte) (resource.Result, error) { 192 s := "%v time" 193 if c.c != 1 { 194 s += "s" 195 } 196 r := resource.Result{ 197 Content: fmt.Sprintf(s, c.c), 198 } 199 c.c += 1 200 return r, nil 201 } 202 203 // if input is suppled, append it to the stored string vector and set the HAVESOMETHING flag. 204 // return the stored string vector value, one string per line. 205 func(c *introResource) something(ctx context.Context, sym string, input []byte) (resource.Result, error) { 206 c.v = append(c.v, string(input)) 207 r := resource.Result{ 208 Content: strings.Join(c.v, "\n"), 209 } 210 if len(input) > 0 { 211 r.FlagSet = []uint32{USERFLAG_HAVESOMETHING} 212 } 213 return r, nil 214 } 215 @end verbatim 216 217 218 @anchor{long_values} 219 @section Handling long values 220 221 In the above example, the more times the @code{foo} page is supplied with a value, the longer the vector of values that need to be displayed by the @code{bar} page will be. 222 223 A core feature of @code{vise} is to magically create browseable pages from these values, from a pre-defined maximum output capacity for each page. 224 225 Consider the case where the contents of the @code{something} symbol has become: 226 227 @verbatim 228 foo bar 229 baz bazbaz 230 inky pinky 231 blinky 232 clyde 233 @end verbatim 234 235 Given a size constaint of 90 characters, the display will be split into two pages: 236 237 @verbatim 238 Thanks for visiting foo and bar. 239 You have written: 240 foo bar 241 baz bazbaz 242 11:next 243 @end verbatim 244 245 @verbatim 246 Thanks for visiting foo and bar. 247 You have written: 248 inky pinky 249 blinky 250 clyde 251 22:back 252 @end verbatim 253 254 255 @section Working example 256 257 In the source code repository, a full working example of this menu can be found in @file{examples/intro}. 258 259 To run it: 260 261 @example 262 make -B intro 263 go run ./examples/intro 264 @end example 265 266 Use @code{go run -tags logtrace ...} to peek at what is going on under the hood. 267 268 To play the @ref{long_values, Long Values} case above, limit the output size by adding @code{-s 90}.