| 1 | module main |
| 2 | ## Description |
| 3 | |
| 4 | This is an example of a an .md file, used for adding more rich text |
| 5 | documentation in a project or module. |
| 6 | |
| 7 | This is a [link](https://vlang.io/) to the main V site. |
| 8 | |
| 9 | This is a <b>bold text</b>. |
| 10 | |
| 11 | This is a script `<script>console.log('hi from README.md');</script>` . |
| 12 | |
| 13 | ## Examples |
| 14 | |
| 15 | ### Functions that return different literals: |
| 16 | |
| 17 | Example of a function returning boolean: |
| 18 | ```v |
| 19 | fn is_odd(x int) bool { |
| 20 | if x % 2 == 0 { |
| 21 | return false |
| 22 | } |
| 23 | return true |
| 24 | } |
| 25 | ``` |
| 26 | |
| 27 | Another example of a function returning a string: |
| 28 | ```v |
| 29 | fn answer() string { |
| 30 | return '42' |
| 31 | } |
| 32 | ``` |
| 33 | |
| 34 | This example shows a function returning a string with interpolation: |
| 35 | ```v |
| 36 | fn str_with_interplation() string { |
| 37 | return 'this string has ${42:6} interpolation in it.' |
| 38 | } |
| 39 | ``` |
| 40 | |
| 41 | ### Processing command line args |
| 42 | |
| 43 | ```v |
| 44 | import os |
| 45 | |
| 46 | fn main() { |
| 47 | dump(os.args) |
| 48 | dump(os.args.len) |
| 49 | assert os.args.len > 0 |
| 50 | |
| 51 | // Test escape characters like for `&` and `<` |
| 52 | mut arr := [1, 2, 3] |
| 53 | mut ref := &arr |
| 54 | arr << 4 |
| 55 | |
| 56 | ch := chan bool{cap: 1} |
| 57 | ch <- true |
| 58 | } |
| 59 | ``` |
| 60 | |
| 61 | ### A JWT example (test syntax highlighting) |
| 62 | |
| 63 | ```v |
| 64 | import crypto.hmac |
| 65 | import crypto.sha256 |
| 66 | import encoding.base64 |
| 67 | import json |
| 68 | import time |
| 69 | |
| 70 | struct JwtHeader { |
| 71 | alg string |
| 72 | typ string |
| 73 | } |
| 74 | |
| 75 | struct JwtPayload { |
| 76 | sub string |
| 77 | name string |
| 78 | iat int |
| 79 | } |
| 80 | |
| 81 | fn main() { |
| 82 | sw := time.new_stopwatch() |
| 83 | secret := 'your-256-bit-secret' |
| 84 | token := make_token(secret) |
| 85 | ok := auth_verify(secret, token) |
| 86 | dt := sw.elapsed().microseconds() |
| 87 | println('token: ${token}') |
| 88 | println('auth_verify(secret, token): ${ok}') |
| 89 | println('Elapsed time: ${dt} uS') |
| 90 | } |
| 91 | |
| 92 | fn make_token(secret string) string { |
| 93 | header := base64.url_encode(json.encode(JwtHeader{'HS256', 'JWT'}).bytes()) |
| 94 | payload := base64.url_encode(json.encode(JwtPayload{'1234567890', 'John Doe', 1516239022}).bytes()) |
| 95 | signature := base64.url_encode(hmac.new(secret.bytes(), '${header}.${payload}'.bytes(), |
| 96 | sha256.sum, sha256.block_size)) |
| 97 | jwt := '${header}.${payload}.${signature}' |
| 98 | return jwt |
| 99 | } |
| 100 | |
| 101 | fn auth_verify(secret string, token string) bool { |
| 102 | token_split := token.split('.') |
| 103 | signature_mirror := hmac.new(secret.bytes(), '${token_split[0]}.${token_split[1]}'.bytes(), |
| 104 | sha256.sum, sha256.block_size) |
| 105 | signature_from_token := base64.url_decode(token_split[2]) |
| 106 | return hmac.equal(signature_from_token, signature_mirror) |
| 107 | } |
| 108 | ``` |
| 109 | |
| 110 | ### Other language specifiers |
| 111 | |
| 112 | ```cpp |
| 113 | #include <iostream> |
| 114 | #include <map> |
| 115 | |
| 116 | std::map<std::string, int> my_map { |
| 117 | {"KEY_1", 0}, |
| 118 | {"KEY_2", 10}, |
| 119 | }; |
| 120 | |
| 121 | for (const auto &[key, value] : my_map) { |
| 122 | std::cout << key << ": " << value << ", "; |
| 123 | } |
| 124 | std::cout << "\n"; |
| 125 | ``` |
| 126 | |
| 127 | ```v ignore |
| 128 | doc1 := toml.parse_text(<string content>) or { panic(err) } |
| 129 | doc2 := toml.parse_file(<file path>) or { panic(err) } |
| 130 | ``` |
| 131 | |
| 132 | ### Escape html in strings |
| 133 | |
| 134 | ```v |
| 135 | const html = '<!DOCTYPE html> |
| 136 | <html lang="en"> |
| 137 | <head> |
| 138 | <style> |
| 139 | body { |
| 140 | background: linear-gradient(to right, #274060, #1B2845); |
| 141 | color: GhostWhite; |
| 142 | font-family: sans-serif; |
| 143 | text-align: center; |
| 144 | } |
| 145 | </style> |
| 146 | </head> |
| 147 | <body> |
| 148 | <h1>Your App Content!</h1> |
| 149 | <button onclick="callV()">Call V!</button> |
| 150 | </body> |
| 151 | <script> |
| 152 | async function callV() { |
| 153 | // Call a V function that takes an argument and returns a value. |
| 154 | const res = await window.my_v_func(\'Hello from JS!\'); |
| 155 | console.log(res); |
| 156 | } |
| 157 | </script> |
| 158 | </html>' |
| 159 | ``` |
| 160 | |
| 161 | - Regular markdown list point 1 |
| 162 | - List point 2 |
| 163 | - List point 3 |
| 164 | |
| 165 | 1. Numbered markdown list point 1 |
| 166 | 2. List point 2 |
| 167 | 3. List point 3 |
| 168 | |
| 169 | A code block without a specific language should be rendered verbatim: |
| 170 | ``` |
| 171 | . |
| 172 | ├── static/ |
| 173 | │ ├── css/ |
| 174 | │ │ └── main.css |
| 175 | │ └── js/ |
| 176 | │ └── main.js |
| 177 | └── main.v |
| 178 | ``` |
| 179 | |
| 180 | The s tags here in the code block, should be rendered verbatim, not interpreted as HTML ones: |
| 181 | ``` |
| 182 | h:m:s // 5:02:33 |
| 183 | m:s.mi<s> // 2:33.015 |
| 184 | s.mi<s> // 33.015s |
| 185 | mi.mc<ms> // 15.007ms |
| 186 | mc.ns<ns> // 7.234us |
| 187 | ns<ns> // 234ns |
| 188 | ``` |
| 189 | |
| 190 | The End. |
| 191 | |
| 192 | |
| 193 | const omega = 3 // should be first |
| 194 | const alpha = 5 // should be in the middle |
| 195 | const beta = 2 // should be at the end |
| 196 | fn abc() |
| 197 | abc - should be last |
| 198 | fn def() |
| 199 | def - should be first |
| 200 | fn xyz() |
| 201 | xyz - should be in the middle a small script <script>console.log('hello');</script> bold text <b>bold</b> end underlined text <u>underline</u> end a link [main v repo](https://github.com/vlang/v) |
| 202 | fn MyXMLDocument.abc(text string) ?(string, int) |
| 203 | MyXMLDocument.abc does something too... I just do not know what. |
| 204 | fn MyXMLDocument.from_file(path string) !MyXMLDocument |
| 205 | MyXMLDocument.from_text processes the file path, and returns an error |
| 206 | fn MyXMLDocument.from_text(text string) ?MyXMLDocument |
| 207 | MyXMLDocument.from_text processes text and produces none |
| 208 | struct MyXMLDocument { |
| 209 | path string |
| 210 | } |
| 211 | MyXMLDocument is here just to test the different combinations of methods/output types |
| 212 | fn (x &MyXMLDocument) instance_from_file(path string) !MyXMLDocument |
| 213 | instance_from_file does stuff with path |
| 214 | fn (x &MyXMLDocument) instance_from_text(text string) ?MyXMLDocument |
| 215 | instance_from_text does stuff with text |
| 216 | fn (x &MyXMLDocument) instance_abc(text string) ?(string, int) |
| 217 | instance_abc does stuff too |
| 218 | fn (x &MyXMLDocument) instance_void() |
| 219 | instance_void does stuff too |
| 220 | fn (x &MyXMLDocument) instance_int() int |
| 221 | instance_int does stuff too |
| 222 | fn (x &MyXMLDocument) instance_result() ! |
| 223 | instance_error does stuff too |
| 224 | fn (x &MyXMLDocument) instance_option() ? |
| 225 | instance_option does stuff too |
| 226 | |