render.texi (6964B)
1 @node render 2 @chapter Rendering 3 4 Every node whose bytecode includes a @code{HALT} statement @strong{MUST} define a rendering template. 5 6 Templates may be either static or dynamic. 7 8 9 @anchor{dynamic_templates} 10 @section Dynamic templates 11 12 Using placeholders, the content behind @code{MAP} calls in the current executing node may be embedded in the template. 13 14 Placeholders have the following format: 15 @verbatim 16 {{.symbol}} 17 @end verbatim 18 where @code{symbol} is the corresponding argument to @code{MAP}. 19 20 Note that @code{MAP} can only be called on symbols who have a corresponding @code{LOAD} on the same level or futher up the stack. 21 22 @subsection Examples 23 24 Consider the following instruction sequence: 25 26 @example 27 LOAD foo 32 28 MAP foo 29 HALT 30 @end example 31 32 If the template contains the placeholder @code{foo}, the contents of that placeholder will be replaced by the cached result of the @code{LOAD foo} external symbol. 33 34 However: 35 36 @example 37 LOAD foo 32 38 HALT 39 @end example 40 41 This will not work for the same template, because the @code{foo} symbol has not been exposed with a @code{MAP} call. 42 43 44 @example 45 LOAD foo 32 46 MOVE bar 47 # (bar bytecode follows) 48 MAP foo 49 HALT 50 @end example 51 52 If the template for the node @code{bar} contains the placeholder @code{foo}, the contents of that placeholder will be replaced by the cached result of the @code{LOAD foo} external symbol. 53 54 This works because the @code{MAP} is encountered further down the node execution stack than where the @code{LOAD} was encountered. 55 56 However: 57 58 @example 59 LOAD foo 32 60 MOVE bar 61 # (bar bytecode follows) 62 MAP foo 63 MOVE baz 64 # (baz bytecode follows) 65 HALT 66 @end example 67 68 Here, if the template for @code{baz} contains the placeholder @code{foo}, the execution will fail because the @code{MAP} in @code{bar} was invalidated by the @code{MOVE} to @code{baz}. 69 70 71 @section Rendering pipeline 72 73 The pipeline starts with the loading of the template corresponding to the current execution node. 74 75 From there, three branches are possible: 76 77 @enumerate 78 @item No @emph{sink} has been defined. 79 @item One of the encountered @code{MAP} symbols resolves to a @emph{sink}. 80 @item @code{MSINK} has been encountered. 81 @end enumerate 82 83 If the resulting output from any of these branches is larger than the output size, failure ensues and execution is terminated. 84 85 86 @subsection No sink 87 88 @enumerate 89 @item Expand all placeholders in the template. 90 @item Expand all menu items 91 @end enumerate 92 93 94 @anchor{map_sink} 95 @subsection MAP sink 96 97 @enumerate 98 @item Expand all non-sink placeholders in the template. 99 @item Expand all menu items. 100 @item Group sink items up to the remaining output size. 101 @item If any item alone exceeds the remaining output size, fail and terminate execution. 102 @item If any item together with the lateral navigation menu items exceed the remaining output size, fail and terminate execution. 103 @item Check the page navigation index (see @ref{lateral_navigation, Lateral navigation}). 104 @item Replace sink symbol result with group item corresponding to navigation index. 105 @item Expand all sink placeholders in the template. 106 @item Expand all menu items (including lateral navigation). 107 @end enumerate 108 109 110 @subsection Menu sink 111 112 @enumerate 113 @item Remove all menu items (any following menu expansion will only contain lateral navigation items, when and if they apply). 114 @item Copy menu items to sink placeholder. 115 @item Continue from @ref{map_sink, MAP sink}. 116 @end enumerate 117 118 119 @anchor{render_multi} 120 @section Multiple-page rendering 121 122 As indicated above, multiple-page rendering is activated when a @code{MAP} is issued to a symbol that is loaded with @code{0} size. (@code{LOAD <symbol> 0}). 123 124 The result is split into rows using newline (@code{0x0a}) as separator. 125 126 127 @subsection Missing navigation 128 129 If no @emph{lateral navigation} has been activated, any sinks will still be processed. 130 131 The sink placeholder will then be replaced with the first item in the group. 132 133 134 @subsection Multi-page example 135 136 Consider the following instruction sequence: 137 138 @example 139 LOAD foo 8 140 LOAD bar 16 141 LOAD baz 0 142 MAP foo 143 MAP bar 144 MAP baz 145 MOUT to_foo 0 146 MOUT to_bar 1 147 MNEXT to_next 11 148 MPREV to_prev 22 149 HALT 150 INCMP foo 0 151 INCMP bar 1 152 INCMP > 11 153 INCMP < 22 154 @end example 155 156 ... and the following template (14 bytes, without the placeholders, including line break): 157 158 @verbatim 159 This is {{.foo}} and {{.bar}} 160 {{.baz}} 161 @end verbatim 162 163 164 @subsubsection Data accounting 165 166 Then consider that the symbols resolve as follows: 167 168 @multitable @columnfractions .10 .25 .50 .15 169 @headitem symbol 170 @tab returned value 171 @tab rendered value 172 @tab bytes 173 @item @code{foo} 174 @tab @code{foobar} 175 @tab @code{foobar} 176 @tab 6 177 @item @code{bar} 178 @tab @code{barbarbar} 179 @tab @code{barbarbar} 180 @tab 9 181 @item @code{baz} 182 @tab @verbatim 183 FOO 42 184 BAR 13 185 BAZ 666 186 XYZZY 1984 187 INKY 1 188 PINKY 22 189 BLINKY 333 190 CLYDE 4444 191 @end verbatim 192 @tab (deferred) 193 @tab (71) 194 @item @code{to_foo} 195 @tab @code{go to foo} 196 @tab @code{0:go to foo} 197 @tab 11 198 @item @code{to_bar} 199 @tab @code{visit the bar} 200 @tab @code{1:visit the bar} 201 @tab 15 202 @item @code{to_next} 203 @tab @code{next page} 204 @tab @code{11:next page} 205 @tab 12 206 @item @code{to_prev} 207 @tab @code{go back} 208 @tab @code{22:go back} 209 @tab 10 210 @end multitable 211 212 Given an output size limit of 94, static part of the template (14 bytes). this results in the following render possibilities for the sink content: 213 214 @multitable @columnfractions .33 .33 .33 215 @headitem navigation case 216 @tab bytes left for sink 217 @item no navigation 218 @tab 39 219 @item next 220 @tab 27 221 @item previous 222 @tab 29 223 @item next + previous 224 @tab 17 225 @end multitable 226 227 228 @subsubsection Rendering logic 229 230 The total sink byte count is 72, whereas the maximum available sink capacity is 39. At least one extra page is needed. 231 232 The first page (with @code{next}) has 27 bytes available, which covers the 3 first sink items (22 bytes, include line break). This results in the following output: 233 234 @example 235 This is foobar and barbarbar 236 FOO 42 237 BAR 13 238 BAZ 666 239 0:go to foo 240 1:visit the bar 241 11:next page 242 @end example 243 244 Any page that is not first page has maximum 29 bytes available. There are 49 bytes left to render from the sink. This means that more pages are needed, and therefore both @code{next} and @code{previous} are needed, leaving a capacity of 17 bytes. This is only sufficient for the next item (11 bytes, with line break), resulting in the following output: 245 246 @example 247 This is foobar and barbarbar 248 XYZZY 1984 249 0:go to foo 250 1:visit the bar 251 11:next page 252 22:go back 253 @end example 254 255 For the next page we again compare with the maximum of 29 bytes. There are 38 bytes left to render. Another intermediate page is required, with the two next entries (16 bytes) fitting inside the capacity (17 bytes). The page then looks like this: 256 257 @example 258 This is foobar and barbarbar 259 INKY 1 260 PINKY 22 261 0:go to foo 262 1:visit the bar 263 11:next page 264 22:go back 265 @end example 266 267 Lastly, with 22 bytes left to go, we can render within the maximum available space of 29 bytes (only using @code{previous}). Thus: 268 269 270 @example 271 This is foobar and barbarbar 272 BLINKY 333 273 CLYDE 4444 274 0:go to foo 275 1:visit the bar 276 22:go back 277 @end example