|
| 1 | +# RiveScript Deparse |
| 2 | + |
| 3 | +This example purely consists of additional documentation and examples of the |
| 4 | +`deparse()` method of RiveScript. |
| 5 | + |
| 6 | +## Relevant Methods |
| 7 | + |
| 8 | +* `rs.deparse()` |
| 9 | + |
| 10 | + This method exports the current in-memory representation of the RiveScript |
| 11 | + brain as a JSON-serializable data structure. See [Schema](#schema) for the |
| 12 | + format of this data structure. |
| 13 | + |
| 14 | +* `rs.write(fh[, deparsed])` |
| 15 | + |
| 16 | + This method converts a data structure like the one from `deparse()` into plain |
| 17 | + text RiveScript source code and writes it to the file-like object ``fh``. |
| 18 | + |
| 19 | + By default this will use the current in-memory representation of the |
| 20 | + RiveScript brain. For example, if you loaded a directory of RiveScript files |
| 21 | + and then called `write()` you would get a large text blob that contains |
| 22 | + all the source code of all the files from that directory. Note, however, that |
| 23 | + the formatting of the original reply data might be lost because the output |
| 24 | + from `write()` is working backwards from the in-memory representation, so |
| 25 | + for example, comments in the original source code aren't preserved and places |
| 26 | + where `^Continue` was used will instead result in one single line of code |
| 27 | + in the output. |
| 28 | + |
| 29 | + If you pass in a data structure formatted the same way as the one `deparse()` |
| 30 | + returns, you can write that code instead. This way you could |
| 31 | + programmatically generate RiveScript data (for example, from a custom user |
| 32 | + interface for authoring bots) and convert it into valid RiveScript source code |
| 33 | + using this method. |
| 34 | + |
| 35 | +## Schema |
| 36 | + |
| 37 | +The data structure returned by `deparse()` looks like this, annotated: |
| 38 | + |
| 39 | +```yaml |
| 40 | +begin: |
| 41 | + global: map of key/value pairs for `! global` global variable definitions |
| 42 | + var: map of key/value pairs for `! var` bot variable definitions |
| 43 | + sub: map of key/value pairs for `! sub` substitution definitions |
| 44 | + person: map of key/value pairs for `! person` substitution definitions |
| 45 | + array: map of `! array` names to arrays of their values |
| 46 | + triggers: array of trigger data (see below) |
| 47 | +topics: map of topic names -> array of trigger data under that topic |
| 48 | + $name: [] |
| 49 | +``` |
| 50 | +
|
| 51 | +The trigger data is stored in arrays underneath `begin.triggers` (for those in |
| 52 | +the `> begin` block) and `topics.$NAME` for triggers under a particular topic, |
| 53 | +with the default topic being named "random". |
| 54 | + |
| 55 | +Each trigger is an object with the following schema: |
| 56 | + |
| 57 | +```yaml |
| 58 | +trigger: the plain text trigger |
| 59 | +reply: array of the plain text `-Reply` commands, or `[]` |
| 60 | +condition: array of the plain text `*Condition` commands, or `[]` |
| 61 | +redirect: the text of the `@Redirect` command, or `null` |
| 62 | +previous: the text of the `%Previous` command, or `null` |
| 63 | +``` |
| 64 | +
|
| 65 | +## Examples |
| 66 | +
|
| 67 | +Here are some example code snippets that show what the deparsed data structure |
| 68 | +looks like. |
| 69 | +
|
| 70 | +Python Code (`example.py`) |
| 71 | + |
| 72 | +```python |
| 73 | +from rivescript import RiveScript |
| 74 | +import json |
| 75 | +
|
| 76 | +bot = RiveScript() |
| 77 | +bot.load_file("example.rive") |
| 78 | +
|
| 79 | +dep = bot.deparse() |
| 80 | +print(json.dumps(dep, indent=2)) |
| 81 | +``` |
| 82 | + |
| 83 | +RiveScript Code (`example.rive`) |
| 84 | + |
| 85 | +```rivescript |
| 86 | +! version = 1.0 |
| 87 | +
|
| 88 | +! var name = Aiden |
| 89 | +! var age = 5 |
| 90 | +
|
| 91 | +! sub what's = what is |
| 92 | +
|
| 93 | +! array colors = red blue green yellow cyan magenta black white |
| 94 | +
|
| 95 | +> begin |
| 96 | + + request |
| 97 | + - {ok} |
| 98 | +< begin |
| 99 | +
|
| 100 | ++ hello bot |
| 101 | +- Hello human. |
| 102 | +
|
| 103 | ++ hi robot |
| 104 | +@ hello bot |
| 105 | +
|
| 106 | ++ my name is * |
| 107 | +- <set name=<formal>>Nice to meet you, <get name>. |
| 108 | +- <set name=<formal>>Hello, <get name>. |
| 109 | +
|
| 110 | ++ what is my name |
| 111 | +* <get name> != undefined => Your name is <get name>. |
| 112 | +- You didn't tell me your name. |
| 113 | +
|
| 114 | +> topic game-global |
| 115 | + + help |
| 116 | + - How to play... |
| 117 | +< topic |
| 118 | +
|
| 119 | +> topic game-room-1 inherits game-global |
| 120 | + + look |
| 121 | + - You're in a room labeled "1". |
| 122 | +< topic |
| 123 | +
|
| 124 | +> object reverse javascript |
| 125 | + var msg = args.join(" "); |
| 126 | + return msg.split("").reverse().join(""); |
| 127 | +< object |
| 128 | +
|
| 129 | ++ say * in reverse |
| 130 | +- <call>reverse <star></call> |
| 131 | +``` |
| 132 | + |
| 133 | +JSON output: |
| 134 | + |
| 135 | +```javascript |
| 136 | +{ |
| 137 | + "begin": { |
| 138 | + "global": {}, |
| 139 | + "var": { |
| 140 | + "name": "Aiden", |
| 141 | + "age": "5" |
| 142 | + }, |
| 143 | + "sub": { |
| 144 | + "what's": "what is" |
| 145 | + }, |
| 146 | + "person": {}, |
| 147 | + "array": { |
| 148 | + "colors": [ |
| 149 | + "red", |
| 150 | + "blue", |
| 151 | + "green", |
| 152 | + "yellow", |
| 153 | + "cyan", |
| 154 | + "magenta", |
| 155 | + "black", |
| 156 | + "white" |
| 157 | + ] |
| 158 | + }, |
| 159 | + "triggers": [ |
| 160 | + { |
| 161 | + "trigger": "request", |
| 162 | + "reply": [ |
| 163 | + "{ok}" |
| 164 | + ], |
| 165 | + "condition": [], |
| 166 | + "redirect": null, |
| 167 | + "previous": null |
| 168 | + } |
| 169 | + ] |
| 170 | + }, |
| 171 | + "topics": { |
| 172 | + "random": { |
| 173 | + "triggers": [ |
| 174 | + { |
| 175 | + "trigger": "hello bot", |
| 176 | + "reply": [ |
| 177 | + "Hello human." |
| 178 | + ], |
| 179 | + "condition": [], |
| 180 | + "redirect": null, |
| 181 | + "previous": null |
| 182 | + }, |
| 183 | + { |
| 184 | + "trigger": "hi robot", |
| 185 | + "reply": [], |
| 186 | + "condition": [], |
| 187 | + "redirect": "hello bot", |
| 188 | + "previous": null |
| 189 | + }, |
| 190 | + { |
| 191 | + "trigger": "my name is *", |
| 192 | + "reply": [ |
| 193 | + "<set name=<formal>>Nice to meet you, <get name>.", |
| 194 | + "<set name=<formal>>Hello, <get name>." |
| 195 | + ], |
| 196 | + "condition": [], |
| 197 | + "redirect": null, |
| 198 | + "previous": null |
| 199 | + }, |
| 200 | + { |
| 201 | + "trigger": "what is my name", |
| 202 | + "reply": [ |
| 203 | + "You didn't tell me your name." |
| 204 | + ], |
| 205 | + "condition": [ |
| 206 | + "<get name> != undefined => Your name is <get name>." |
| 207 | + ], |
| 208 | + "redirect": null, |
| 209 | + "previous": null |
| 210 | + }, |
| 211 | + { |
| 212 | + "trigger": "say * in reverse", |
| 213 | + "reply": [ |
| 214 | + "<call>reverse <star></call>" |
| 215 | + ], |
| 216 | + "condition": [], |
| 217 | + "redirect": null, |
| 218 | + "previous": null |
| 219 | + } |
| 220 | + ], |
| 221 | + "includes": {}, |
| 222 | + "inherits": {} |
| 223 | + }, |
| 224 | + "game-global": { |
| 225 | + "triggers": [ |
| 226 | + { |
| 227 | + "trigger": "help", |
| 228 | + "reply": [ |
| 229 | + "How to play..." |
| 230 | + ], |
| 231 | + "condition": [], |
| 232 | + "redirect": null, |
| 233 | + "previous": null |
| 234 | + } |
| 235 | + ], |
| 236 | + "includes": {}, |
| 237 | + "inherits": {} |
| 238 | + }, |
| 239 | + "game-room-1": { |
| 240 | + "triggers": [ |
| 241 | + { |
| 242 | + "trigger": "look", |
| 243 | + "reply": [ |
| 244 | + "You're in a room labeled \"1\"." |
| 245 | + ], |
| 246 | + "condition": [], |
| 247 | + "redirect": null, |
| 248 | + "previous": null |
| 249 | + } |
| 250 | + ], |
| 251 | + "includes": {}, |
| 252 | + "inherits": { |
| 253 | + "game-global": 1 |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | +} |
| 258 | +``` |
0 commit comments