├── .gitignore ├── .vscode ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── assets ├── giphy.gif ├── giphy2.gif ├── giphy3.gif ├── logo.png ├── s00-diff.png ├── test.md ├── test.rs ├── test2.md └── test_table.md ├── example.ron └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .DS_Store -------------------------------------------------------------------------------- /.vscode: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "addr2line" 5 | version = "0.12.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "456d75cbb82da1ad150c8a9d97285ffcd21c9931dcb11e995903e7d75141b38b" 8 | dependencies = [ 9 | "gimli", 10 | ] 11 | 12 | [[package]] 13 | name = "adler32" 14 | version = "1.0.4" 15 | source = "registry+https://github.com/rust-lang/crates.io-index" 16 | checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" 17 | 18 | [[package]] 19 | name = "aho-corasick" 20 | version = "0.7.10" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" 23 | dependencies = [ 24 | "memchr", 25 | ] 26 | 27 | [[package]] 28 | name = "ansi_term" 29 | version = "0.11.0" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 32 | dependencies = [ 33 | "winapi 0.3.8", 34 | ] 35 | 36 | [[package]] 37 | name = "arc-swap" 38 | version = "0.4.6" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62" 41 | 42 | [[package]] 43 | name = "atty" 44 | version = "0.2.14" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 47 | dependencies = [ 48 | "hermit-abi", 49 | "libc", 50 | "winapi 0.3.8", 51 | ] 52 | 53 | [[package]] 54 | name = "autocfg" 55 | version = "1.0.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 58 | 59 | [[package]] 60 | name = "backtrace" 61 | version = "0.3.47" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "a5393cb2f40a6fae0014c9af00018e95846f3b241b331a6b7733c326d3e58108" 64 | dependencies = [ 65 | "addr2line", 66 | "cfg-if", 67 | "libc", 68 | "object", 69 | "rustc-demangle", 70 | ] 71 | 72 | [[package]] 73 | name = "base64" 74 | version = "0.10.1" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 77 | dependencies = [ 78 | "byteorder", 79 | ] 80 | 81 | [[package]] 82 | name = "bincode" 83 | version = "1.2.1" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" 86 | dependencies = [ 87 | "byteorder", 88 | "serde", 89 | ] 90 | 91 | [[package]] 92 | name = "bindgen" 93 | version = "0.50.1" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "cb0e5a5f74b2bafe0b39379f616b5975e08bcaca4e779c078d5c31324147e9ba" 96 | dependencies = [ 97 | "bitflags", 98 | "cexpr", 99 | "cfg-if", 100 | "clang-sys", 101 | "clap", 102 | "env_logger", 103 | "fxhash", 104 | "lazy_static", 105 | "log", 106 | "peeking_take_while", 107 | "proc-macro2 0.4.30", 108 | "quote 0.6.13", 109 | "regex", 110 | "shlex", 111 | "which", 112 | ] 113 | 114 | [[package]] 115 | name = "bitflags" 116 | version = "1.2.1" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 119 | 120 | [[package]] 121 | name = "byteorder" 122 | version = "1.3.4" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 125 | 126 | [[package]] 127 | name = "cc" 128 | version = "1.0.52" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" 131 | 132 | [[package]] 133 | name = "cexpr" 134 | version = "0.3.6" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" 137 | dependencies = [ 138 | "nom", 139 | ] 140 | 141 | [[package]] 142 | name = "cfg-if" 143 | version = "0.1.10" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 146 | 147 | [[package]] 148 | name = "chrono" 149 | version = "0.4.11" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" 152 | dependencies = [ 153 | "num-integer", 154 | "num-traits", 155 | ] 156 | 157 | [[package]] 158 | name = "clang-sys" 159 | version = "0.28.1" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" 162 | dependencies = [ 163 | "glob", 164 | "libc", 165 | "libloading", 166 | ] 167 | 168 | [[package]] 169 | name = "clap" 170 | version = "2.33.1" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" 173 | dependencies = [ 174 | "ansi_term", 175 | "atty", 176 | "bitflags", 177 | "strsim", 178 | "textwrap", 179 | "unicode-width", 180 | "vec_map", 181 | ] 182 | 183 | [[package]] 184 | name = "cloudabi" 185 | version = "0.0.3" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 188 | dependencies = [ 189 | "bitflags", 190 | ] 191 | 192 | [[package]] 193 | name = "crc32fast" 194 | version = "1.2.0" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 197 | dependencies = [ 198 | "cfg-if", 199 | ] 200 | 201 | [[package]] 202 | name = "crossbeam" 203 | version = "0.7.3" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" 206 | dependencies = [ 207 | "cfg-if", 208 | "crossbeam-channel", 209 | "crossbeam-deque", 210 | "crossbeam-epoch", 211 | "crossbeam-queue", 212 | "crossbeam-utils", 213 | ] 214 | 215 | [[package]] 216 | name = "crossbeam-channel" 217 | version = "0.4.2" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" 220 | dependencies = [ 221 | "crossbeam-utils", 222 | "maybe-uninit", 223 | ] 224 | 225 | [[package]] 226 | name = "crossbeam-deque" 227 | version = "0.7.3" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 230 | dependencies = [ 231 | "crossbeam-epoch", 232 | "crossbeam-utils", 233 | "maybe-uninit", 234 | ] 235 | 236 | [[package]] 237 | name = "crossbeam-epoch" 238 | version = "0.8.2" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 241 | dependencies = [ 242 | "autocfg", 243 | "cfg-if", 244 | "crossbeam-utils", 245 | "lazy_static", 246 | "maybe-uninit", 247 | "memoffset", 248 | "scopeguard", 249 | ] 250 | 251 | [[package]] 252 | name = "crossbeam-queue" 253 | version = "0.2.1" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" 256 | dependencies = [ 257 | "cfg-if", 258 | "crossbeam-utils", 259 | ] 260 | 261 | [[package]] 262 | name = "crossbeam-utils" 263 | version = "0.7.2" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 266 | dependencies = [ 267 | "autocfg", 268 | "cfg-if", 269 | "lazy_static", 270 | ] 271 | 272 | [[package]] 273 | name = "crossterm" 274 | version = "0.17.4" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "2a880035bfe4707e344da9acf50cc94d003fe337f50afd94c8722c1bb4e0a933" 277 | dependencies = [ 278 | "bitflags", 279 | "crossterm_winapi", 280 | "lazy_static", 281 | "libc", 282 | "mio", 283 | "parking_lot", 284 | "signal-hook", 285 | "winapi 0.3.8", 286 | ] 287 | 288 | [[package]] 289 | name = "crossterm_winapi" 290 | version = "0.6.1" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "057b7146d02fb50175fd7dbe5158f6097f33d02831f43b4ee8ae4ddf67b68f5c" 293 | dependencies = [ 294 | "winapi 0.3.8", 295 | ] 296 | 297 | [[package]] 298 | name = "env_logger" 299 | version = "0.6.2" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" 302 | dependencies = [ 303 | "atty", 304 | "humantime", 305 | "log", 306 | "regex", 307 | "termcolor", 308 | ] 309 | 310 | [[package]] 311 | name = "failure" 312 | version = "0.1.8" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 315 | dependencies = [ 316 | "backtrace", 317 | ] 318 | 319 | [[package]] 320 | name = "figlet-rs" 321 | version = "0.1.3" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "59893843a423e9726b35a3110cd2be573bc9deddc553b0ff286107189b02d1aa" 324 | 325 | [[package]] 326 | name = "flate2" 327 | version = "1.0.14" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 330 | dependencies = [ 331 | "cfg-if", 332 | "crc32fast", 333 | "libc", 334 | "miniz_oxide", 335 | ] 336 | 337 | [[package]] 338 | name = "fnv" 339 | version = "1.0.6" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 342 | 343 | [[package]] 344 | name = "fuchsia-zircon" 345 | version = "0.3.3" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 348 | dependencies = [ 349 | "bitflags", 350 | "fuchsia-zircon-sys", 351 | ] 352 | 353 | [[package]] 354 | name = "fuchsia-zircon-sys" 355 | version = "0.3.3" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 358 | 359 | [[package]] 360 | name = "fxhash" 361 | version = "0.2.1" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 364 | dependencies = [ 365 | "byteorder", 366 | ] 367 | 368 | [[package]] 369 | name = "gimli" 370 | version = "0.21.0" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" 373 | 374 | [[package]] 375 | name = "glob" 376 | version = "0.3.0" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 379 | 380 | [[package]] 381 | name = "hermit-abi" 382 | version = "0.1.12" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" 385 | dependencies = [ 386 | "libc", 387 | ] 388 | 389 | [[package]] 390 | name = "humantime" 391 | version = "1.3.0" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 394 | dependencies = [ 395 | "quick-error", 396 | ] 397 | 398 | [[package]] 399 | name = "indexmap" 400 | version = "1.3.2" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" 403 | dependencies = [ 404 | "autocfg", 405 | ] 406 | 407 | [[package]] 408 | name = "iovec" 409 | version = "0.1.4" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 412 | dependencies = [ 413 | "libc", 414 | ] 415 | 416 | [[package]] 417 | name = "itoa" 418 | version = "0.4.5" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 421 | 422 | [[package]] 423 | name = "kernel32-sys" 424 | version = "0.2.2" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 427 | dependencies = [ 428 | "winapi 0.2.8", 429 | "winapi-build", 430 | ] 431 | 432 | [[package]] 433 | name = "lazy_static" 434 | version = "1.4.0" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 437 | 438 | [[package]] 439 | name = "lazycell" 440 | version = "1.2.1" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" 443 | 444 | [[package]] 445 | name = "libc" 446 | version = "0.2.70" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" 449 | 450 | [[package]] 451 | name = "libloading" 452 | version = "0.5.2" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" 455 | dependencies = [ 456 | "cc", 457 | "winapi 0.3.8", 458 | ] 459 | 460 | [[package]] 461 | name = "line-wrap" 462 | version = "0.1.1" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" 465 | dependencies = [ 466 | "safemem", 467 | ] 468 | 469 | [[package]] 470 | name = "linked-hash-map" 471 | version = "0.5.3" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" 474 | 475 | [[package]] 476 | name = "lock_api" 477 | version = "0.3.4" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 480 | dependencies = [ 481 | "scopeguard", 482 | ] 483 | 484 | [[package]] 485 | name = "log" 486 | version = "0.4.8" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 489 | dependencies = [ 490 | "cfg-if", 491 | ] 492 | 493 | [[package]] 494 | name = "maybe-uninit" 495 | version = "2.0.0" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 498 | 499 | [[package]] 500 | name = "memchr" 501 | version = "2.3.3" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 504 | 505 | [[package]] 506 | name = "memoffset" 507 | version = "0.5.4" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" 510 | dependencies = [ 511 | "autocfg", 512 | ] 513 | 514 | [[package]] 515 | name = "minimad" 516 | version = "0.6.4" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "8a208cf4e8311b21538dd3fd63218ffcb102bf1ef1ce6fabbfb44e2237763ce5" 519 | dependencies = [ 520 | "lazy_static", 521 | ] 522 | 523 | [[package]] 524 | name = "miniz_oxide" 525 | version = "0.3.6" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" 528 | dependencies = [ 529 | "adler32", 530 | ] 531 | 532 | [[package]] 533 | name = "mio" 534 | version = "0.6.22" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" 537 | dependencies = [ 538 | "cfg-if", 539 | "fuchsia-zircon", 540 | "fuchsia-zircon-sys", 541 | "iovec", 542 | "kernel32-sys", 543 | "libc", 544 | "log", 545 | "miow", 546 | "net2", 547 | "slab", 548 | "winapi 0.2.8", 549 | ] 550 | 551 | [[package]] 552 | name = "miow" 553 | version = "0.2.1" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 556 | dependencies = [ 557 | "kernel32-sys", 558 | "net2", 559 | "winapi 0.2.8", 560 | "ws2_32-sys", 561 | ] 562 | 563 | [[package]] 564 | name = "net2" 565 | version = "0.2.34" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" 568 | dependencies = [ 569 | "cfg-if", 570 | "libc", 571 | "winapi 0.3.8", 572 | ] 573 | 574 | [[package]] 575 | name = "nom" 576 | version = "4.2.3" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" 579 | dependencies = [ 580 | "memchr", 581 | "version_check", 582 | ] 583 | 584 | [[package]] 585 | name = "num-integer" 586 | version = "0.1.42" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" 589 | dependencies = [ 590 | "autocfg", 591 | "num-traits", 592 | ] 593 | 594 | [[package]] 595 | name = "num-traits" 596 | version = "0.2.11" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" 599 | dependencies = [ 600 | "autocfg", 601 | ] 602 | 603 | [[package]] 604 | name = "object" 605 | version = "0.19.0" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" 608 | 609 | [[package]] 610 | name = "onig" 611 | version = "5.0.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "e4e723fc996fff1aeab8f62205f3e8528bf498bdd5eadb2784d2d31f30077947" 614 | dependencies = [ 615 | "bitflags", 616 | "lazy_static", 617 | "libc", 618 | "onig_sys", 619 | ] 620 | 621 | [[package]] 622 | name = "onig_sys" 623 | version = "69.2.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "0a8d4efbf5f59cece01f539305191485b651acb3785b9d5eef05749f0496514e" 626 | dependencies = [ 627 | "bindgen", 628 | "cc", 629 | "pkg-config", 630 | ] 631 | 632 | [[package]] 633 | name = "parking_lot" 634 | version = "0.10.2" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" 637 | dependencies = [ 638 | "lock_api", 639 | "parking_lot_core", 640 | ] 641 | 642 | [[package]] 643 | name = "parking_lot_core" 644 | version = "0.7.2" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" 647 | dependencies = [ 648 | "cfg-if", 649 | "cloudabi", 650 | "libc", 651 | "redox_syscall", 652 | "smallvec", 653 | "winapi 0.3.8", 654 | ] 655 | 656 | [[package]] 657 | name = "peeking_take_while" 658 | version = "0.1.2" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 661 | 662 | [[package]] 663 | name = "pkg-config" 664 | version = "0.3.17" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 667 | 668 | [[package]] 669 | name = "plist" 670 | version = "0.5.5" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "9b59eb8d91dfa89208ec74a920e3b55f840476cf46568026c18dbaa2999e0d48" 673 | dependencies = [ 674 | "base64", 675 | "chrono", 676 | "indexmap", 677 | "line-wrap", 678 | "serde", 679 | "xml-rs", 680 | ] 681 | 682 | [[package]] 683 | name = "presentui" 684 | version = "0.1.0" 685 | dependencies = [ 686 | "clap", 687 | "crossterm", 688 | "figlet-rs", 689 | "ron", 690 | "serde", 691 | "syntect", 692 | "termimad", 693 | ] 694 | 695 | [[package]] 696 | name = "proc-macro2" 697 | version = "0.4.30" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 700 | dependencies = [ 701 | "unicode-xid 0.1.0", 702 | ] 703 | 704 | [[package]] 705 | name = "proc-macro2" 706 | version = "1.0.12" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" 709 | dependencies = [ 710 | "unicode-xid 0.2.0", 711 | ] 712 | 713 | [[package]] 714 | name = "quick-error" 715 | version = "1.2.3" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 718 | 719 | [[package]] 720 | name = "quote" 721 | version = "0.6.13" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 724 | dependencies = [ 725 | "proc-macro2 0.4.30", 726 | ] 727 | 728 | [[package]] 729 | name = "quote" 730 | version = "1.0.5" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e" 733 | dependencies = [ 734 | "proc-macro2 1.0.12", 735 | ] 736 | 737 | [[package]] 738 | name = "redox_syscall" 739 | version = "0.1.56" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 742 | 743 | [[package]] 744 | name = "regex" 745 | version = "1.3.7" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" 748 | dependencies = [ 749 | "aho-corasick", 750 | "memchr", 751 | "regex-syntax", 752 | "thread_local", 753 | ] 754 | 755 | [[package]] 756 | name = "regex-syntax" 757 | version = "0.6.17" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" 760 | 761 | [[package]] 762 | name = "ron" 763 | version = "0.5.1" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5" 766 | dependencies = [ 767 | "base64", 768 | "bitflags", 769 | "serde", 770 | ] 771 | 772 | [[package]] 773 | name = "rustc-demangle" 774 | version = "0.1.16" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 777 | 778 | [[package]] 779 | name = "ryu" 780 | version = "1.0.4" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" 783 | 784 | [[package]] 785 | name = "safemem" 786 | version = "0.3.3" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" 789 | 790 | [[package]] 791 | name = "same-file" 792 | version = "1.0.6" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 795 | dependencies = [ 796 | "winapi-util", 797 | ] 798 | 799 | [[package]] 800 | name = "scopeguard" 801 | version = "1.1.0" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 804 | 805 | [[package]] 806 | name = "serde" 807 | version = "1.0.110" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" 810 | dependencies = [ 811 | "serde_derive", 812 | ] 813 | 814 | [[package]] 815 | name = "serde_derive" 816 | version = "1.0.110" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" 819 | dependencies = [ 820 | "proc-macro2 1.0.12", 821 | "quote 1.0.5", 822 | "syn", 823 | ] 824 | 825 | [[package]] 826 | name = "serde_json" 827 | version = "1.0.53" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" 830 | dependencies = [ 831 | "itoa", 832 | "ryu", 833 | "serde", 834 | ] 835 | 836 | [[package]] 837 | name = "shlex" 838 | version = "0.1.1" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" 841 | 842 | [[package]] 843 | name = "signal-hook" 844 | version = "0.1.15" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "8ff2db2112d6c761e12522c65f7768548bd6e8cd23d2a9dae162520626629bd6" 847 | dependencies = [ 848 | "libc", 849 | "mio", 850 | "signal-hook-registry", 851 | ] 852 | 853 | [[package]] 854 | name = "signal-hook-registry" 855 | version = "1.2.0" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" 858 | dependencies = [ 859 | "arc-swap", 860 | "libc", 861 | ] 862 | 863 | [[package]] 864 | name = "slab" 865 | version = "0.4.2" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 868 | 869 | [[package]] 870 | name = "smallvec" 871 | version = "1.4.0" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" 874 | 875 | [[package]] 876 | name = "strsim" 877 | version = "0.8.0" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 880 | 881 | [[package]] 882 | name = "syn" 883 | version = "1.0.21" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "4696caa4048ac7ce2bcd2e484b3cef88c1004e41b8e945a277e2c25dc0b72060" 886 | dependencies = [ 887 | "proc-macro2 1.0.12", 888 | "quote 1.0.5", 889 | "unicode-xid 0.2.0", 890 | ] 891 | 892 | [[package]] 893 | name = "syntect" 894 | version = "4.1.1" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "6bc79276a4d38e39fbeb83c5fd9c23fbd027eeec7c50ee6a3d07deee33d7f621" 897 | dependencies = [ 898 | "bincode", 899 | "bitflags", 900 | "flate2", 901 | "fnv", 902 | "lazy_static", 903 | "lazycell", 904 | "onig", 905 | "plist", 906 | "regex-syntax", 907 | "serde", 908 | "serde_derive", 909 | "serde_json", 910 | "walkdir", 911 | "yaml-rust", 912 | ] 913 | 914 | [[package]] 915 | name = "termcolor" 916 | version = "1.1.0" 917 | source = "registry+https://github.com/rust-lang/crates.io-index" 918 | checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" 919 | dependencies = [ 920 | "winapi-util", 921 | ] 922 | 923 | [[package]] 924 | name = "termimad" 925 | version = "0.8.21" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "51367f0411c477a02b8a3f0061bda3dba2c81710e51d4aa7f421f1225bb7311a" 928 | dependencies = [ 929 | "crossbeam", 930 | "crossterm", 931 | "lazy_static", 932 | "minimad", 933 | "thiserror", 934 | ] 935 | 936 | [[package]] 937 | name = "textwrap" 938 | version = "0.11.0" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 941 | dependencies = [ 942 | "unicode-width", 943 | ] 944 | 945 | [[package]] 946 | name = "thiserror" 947 | version = "1.0.17" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "467e5ff447618a916519a4e0d62772ab14f434897f3d63f05d8700ef1e9b22c1" 950 | dependencies = [ 951 | "thiserror-impl", 952 | ] 953 | 954 | [[package]] 955 | name = "thiserror-impl" 956 | version = "1.0.17" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "e63c1091225b9834089b429bc4a2e01223470e3183e891582909e9d1c4cb55d9" 959 | dependencies = [ 960 | "proc-macro2 1.0.12", 961 | "quote 1.0.5", 962 | "syn", 963 | ] 964 | 965 | [[package]] 966 | name = "thread_local" 967 | version = "1.0.1" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 970 | dependencies = [ 971 | "lazy_static", 972 | ] 973 | 974 | [[package]] 975 | name = "unicode-width" 976 | version = "0.1.7" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" 979 | 980 | [[package]] 981 | name = "unicode-xid" 982 | version = "0.1.0" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 985 | 986 | [[package]] 987 | name = "unicode-xid" 988 | version = "0.2.0" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 991 | 992 | [[package]] 993 | name = "vec_map" 994 | version = "0.8.2" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 997 | 998 | [[package]] 999 | name = "version_check" 1000 | version = "0.1.5" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1003 | 1004 | [[package]] 1005 | name = "walkdir" 1006 | version = "2.3.1" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1009 | dependencies = [ 1010 | "same-file", 1011 | "winapi 0.3.8", 1012 | "winapi-util", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "which" 1017 | version = "2.0.1" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" 1020 | dependencies = [ 1021 | "failure", 1022 | "libc", 1023 | ] 1024 | 1025 | [[package]] 1026 | name = "winapi" 1027 | version = "0.2.8" 1028 | source = "registry+https://github.com/rust-lang/crates.io-index" 1029 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1030 | 1031 | [[package]] 1032 | name = "winapi" 1033 | version = "0.3.8" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1036 | dependencies = [ 1037 | "winapi-i686-pc-windows-gnu", 1038 | "winapi-x86_64-pc-windows-gnu", 1039 | ] 1040 | 1041 | [[package]] 1042 | name = "winapi-build" 1043 | version = "0.1.1" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1046 | 1047 | [[package]] 1048 | name = "winapi-i686-pc-windows-gnu" 1049 | version = "0.4.0" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1052 | 1053 | [[package]] 1054 | name = "winapi-util" 1055 | version = "0.1.5" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1058 | dependencies = [ 1059 | "winapi 0.3.8", 1060 | ] 1061 | 1062 | [[package]] 1063 | name = "winapi-x86_64-pc-windows-gnu" 1064 | version = "0.4.0" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1067 | 1068 | [[package]] 1069 | name = "ws2_32-sys" 1070 | version = "0.2.1" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1073 | dependencies = [ 1074 | "winapi 0.2.8", 1075 | "winapi-build", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "xml-rs" 1080 | version = "0.8.3" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" 1083 | 1084 | [[package]] 1085 | name = "yaml-rust" 1086 | version = "0.4.3" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" 1089 | dependencies = [ 1090 | "linked-hash-map", 1091 | ] 1092 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "presentui" 3 | version = "0.1.0" 4 | authors = ["Stephan Dilly "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | termimad = "0.8" 9 | crossterm = "0.17" 10 | syntect = "4.1" 11 | ron = "0.5" 12 | figlet-rs = "0.1" 13 | serde = { version = "1.0", features = ["serde_derive"] } 14 | clap = "2.33" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Stephan Dilly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # presentui 2 | 3 | a small and simple terminal presentation tool. 4 | checkout the `example.ron` and the `assets` folder. 5 | 6 | ## realworld example 7 | 8 | See my [gitui](https://github.com/extrawurst/gitui) presentation for @RustBerlin made using `presentui`: https://github.com/extrawurst/gitui-presentation 9 | 10 | # usage 11 | 12 | simply run by: 13 | ``` 14 | cargo run -- -f example.ron 15 | ``` 16 | Navigate using `up`/`down` keys. 17 | Open the current slide using system viewer: `enter`. 18 | Exit using `Esc`. 19 | -------------------------------------------------------------------------------- /assets/giphy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrawurst/presentui/73eb6216a038c3396914998b000ab702613f2b67/assets/giphy.gif -------------------------------------------------------------------------------- /assets/giphy2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrawurst/presentui/73eb6216a038c3396914998b000ab702613f2b67/assets/giphy2.gif -------------------------------------------------------------------------------- /assets/giphy3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrawurst/presentui/73eb6216a038c3396914998b000ab702613f2b67/assets/giphy3.gif -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrawurst/presentui/73eb6216a038c3396914998b000ab702613f2b67/assets/logo.png -------------------------------------------------------------------------------- /assets/s00-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrawurst/presentui/73eb6216a038c3396914998b000ab702613f2b67/assets/s00-diff.png -------------------------------------------------------------------------------- /assets/test.md: -------------------------------------------------------------------------------- 1 | # Title 2 | 3 | ## Subtitle 4 | 5 | * lorem ipsum dolores 6 | * foo bar baz fui bai -------------------------------------------------------------------------------- /assets/test.rs: -------------------------------------------------------------------------------- 1 | enum FileTypes<'a> { 2 | Markdown(&'a str), 3 | Image(&'a str), 4 | GifAnimation(&'a str), 5 | Open(&'a str), 6 | Print(&'a str), 7 | FIGlet(&'a str), 8 | Code(&'a str), 9 | } 10 | -------------------------------------------------------------------------------- /assets/test2.md: -------------------------------------------------------------------------------- 1 | ``` 2 | _ _ _ 3 | __ _(_) |_ _ _(_) 4 | / _` | | __| | | | | 5 | | (_| | | |_| |_| | | 6 | \__, |_|\__|\__,_|_| 7 | |___/ 8 | ``` -------------------------------------------------------------------------------- /assets/test_table.md: -------------------------------------------------------------------------------- 1 | # test table 2 | 3 | |:-:|:-:|- 4 | |**feature**|**supported**|**details**| 5 | |-:|:-:|- 6 | | tables | yes | pipe based, with or without alignments 7 | | italic, bold | yes | star based | 8 | | inline code | yes | `with backquotes` (it works in tables too) 9 | | code bloc | yes |with tabs or code fences 10 | | syntax coloring | no | 11 | | crossed text | ~~not yet~~ | wait... now it works `~~like this~~` bla bla bla very long line 12 | | horizontal rule | yes | Use 3 or more dashes (`---`) 13 | | lists | yes|* unordered lists supported 14 | | | |* ordered lists *not* supported 15 | | quotes | yes |> What a wonderful time to be alive! 16 | | links | no | (but your terminal already handles raw URLs) 17 | |- -------------------------------------------------------------------------------- /example.ron: -------------------------------------------------------------------------------- 1 | ( 2 | files:[ 3 | Print("hello world"), 4 | Code("assets/test.rs"), 5 | Markdown("assets/test2.md"), 6 | Markdown("assets/test_table.md"), 7 | FIGlet("hello world"), 8 | GifAnimation("assets/giphy3.gif"), 9 | Markdown("assets/test.md"), 10 | Image("assets/logo.png"), 11 | Open("assets/s00-diff.png"), 12 | GifAnimation("assets/giphy.gif"), 13 | Print("end"), 14 | ] 15 | ) -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use crossterm::{ 2 | cursor::{Hide, MoveTo, Show, self}, 3 | event::{self, Event, KeyCode, KeyEvent}, 4 | queue, 5 | terminal::{self, disable_raw_mode, enable_raw_mode, Clear, ClearType}, 6 | QueueableCommand, Result, 7 | }; 8 | use figlet_rs::FIGfont; 9 | use fs::File; 10 | use io::stderr; 11 | use ron::de::from_reader; 12 | use serde::Deserialize; 13 | use clap::{Arg, App}; 14 | use std::{ 15 | fs, 16 | io::{self, Write}, 17 | path::Path, 18 | process::Command, 19 | }; 20 | use syntect::easy::HighlightLines; 21 | use syntect::highlighting::{Style, ThemeSet}; 22 | use syntect::parsing::SyntaxSet; 23 | use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings}; 24 | use termimad::{Area, MadSkin}; 25 | 26 | #[derive(Debug, Deserialize)] 27 | enum FileTypes { 28 | Markdown(String), 29 | Image(String), 30 | GifAnimation(String), 31 | Open(String), 32 | Print(String), 33 | FIGlet(String), 34 | Code(String), 35 | } 36 | 37 | fn text_size(s: &str) -> (usize,usize) { 38 | let w = 1 + s.lines().fold(0, |acc, l| acc.max(l.len())); 39 | 40 | (w,s.lines().count()) 41 | } 42 | 43 | impl FileTypes { 44 | fn action(&self, _w: &mut impl Write) -> Result<()> { 45 | match self { 46 | FileTypes::Open(path) | FileTypes::Image(path) => { 47 | #[cfg(target_os = "linux")] 48 | Command::new("xdg-open").arg(path).output()?; 49 | #[cfg(target_os = "macos")] 50 | Command::new("open") 51 | .arg("-W") 52 | .arg("-F") 53 | .arg("-n") 54 | .arg(path) 55 | .output()?; 56 | } 57 | FileTypes::GifAnimation(path) => { 58 | disable_raw_mode()?; 59 | Command::new("viu").arg("-1").arg(path).status()?; 60 | enable_raw_mode()?; 61 | } 62 | _ => (), 63 | } 64 | 65 | Ok(()) 66 | } 67 | 68 | fn write_text(w: &mut impl Write, txt:&String) -> Result<()> { 69 | let (width, height) = terminal::size().unwrap(); 70 | let top = height.saturating_sub(txt.lines().count() as u16) /2; 71 | 72 | for (idx,l) in txt.lines().enumerate() { 73 | let x = width.saturating_sub(l.len() as u16) /2; 74 | w.queue(cursor::MoveTo(x,top + idx as u16))?; 75 | w.write_all(l.as_bytes())?; 76 | } 77 | 78 | w.flush()?; 79 | 80 | Ok(()) 81 | } 82 | 83 | fn show(&self, w: &mut impl Write, margin: usize) -> Result<()> { 84 | match self { 85 | FileTypes::GifAnimation(path) => { 86 | disable_raw_mode()?; 87 | Command::new("viu").arg("-s").arg(path).status()?; 88 | enable_raw_mode()?; 89 | } 90 | FileTypes::Image(path) => { 91 | disable_raw_mode()?; 92 | let (w, h) = terminal::size()?; 93 | Command::new("viu") 94 | .arg(format!("-w{}", w)) 95 | .arg(format!("-h{}", h)) 96 | .arg(path) 97 | .status()?; 98 | enable_raw_mode()?; 99 | } 100 | FileTypes::Print(txt) => { 101 | Self::write_text(w,txt)?; 102 | } 103 | FileTypes::Markdown(path) => { 104 | let (width, height) = terminal::size().unwrap(); 105 | let markdown = fs::read_to_string(Path::new(path))?; 106 | let (text_w,_) = text_size(markdown.as_str()); 107 | 108 | let area_w = text_w.min(width as usize- (margin*2)) as u16; 109 | let area_h = height - (margin as u16 * 2); 110 | 111 | let x = 0.max((width - area_w) / 2); 112 | let y = 0.max((height - area_h) / 2); 113 | 114 | MadSkin::default() 115 | .write_in_area(&markdown, &Area::new(x, y, area_w, area_h)) 116 | .unwrap(); 117 | } 118 | FileTypes::Open(path) => { 119 | let txt = format!("External file:\n{}\n\npress enter to open",path); 120 | Self::write_text(w, &txt)?; 121 | } 122 | FileTypes::Code(path) => { 123 | let (width, height) = terminal::size().unwrap(); 124 | let content = fs::read_to_string(Path::new(path))?; 125 | let text_size = text_size(content.as_str()); 126 | let x = (width - text_size.0 as u16)/2; 127 | let y = (height - text_size.1 as u16)/2; 128 | 129 | // Load these once at the start of your program 130 | let ps = SyntaxSet::load_defaults_newlines(); 131 | let ts = ThemeSet::load_defaults(); 132 | 133 | let syntax = ps.find_syntax_by_extension("rs").unwrap(); 134 | let mut highlighter = HighlightLines::new(syntax, &ts.themes["Solarized (light)"]); 135 | 136 | for (idx,line) in LinesWithEndings::from(content.as_str()).enumerate() { 137 | let ranges: Vec<(Style, &str)> = highlighter.highlight(line, &ps); 138 | let escaped = as_24_bit_terminal_escaped(&ranges[..], false); 139 | w.queue(cursor::MoveTo(x,y+idx as u16))?; 140 | w.write_all(escaped.to_string().as_bytes())?; 141 | } 142 | 143 | w.queue(cursor::MoveTo(0,0))?; 144 | w.flush()?; 145 | } 146 | FileTypes::FIGlet(txt) => { 147 | //TODO: draw manually to allow centering 148 | let standard_font = FIGfont::standand().unwrap(); 149 | let figure = standard_font.convert(txt).unwrap(); 150 | disable_raw_mode()?; 151 | w.write_all(figure.to_string().as_bytes())?; 152 | enable_raw_mode()?; 153 | } 154 | } 155 | 156 | Ok(()) 157 | } 158 | } 159 | 160 | fn present(w: &mut impl Write, slides: &Slides) -> Result<()> { 161 | let mut idx = 0_usize; 162 | let mut margin = 2_usize; 163 | 164 | loop { 165 | w.queue(Clear(ClearType::All))?.queue(MoveTo(0, 0))?; 166 | w.flush()?; 167 | 168 | if let Some(file) = slides.files.get(idx) { 169 | file.show(w, margin)?; 170 | } else { 171 | break; 172 | } 173 | 174 | w.flush()?; 175 | 176 | match read_input()? { 177 | Input::Quit => { 178 | break; 179 | } 180 | Input::Previous => idx = idx.saturating_sub(1), 181 | Input::Next => idx = idx.saturating_add(1), 182 | Input::Margin(plus) => { 183 | if plus { 184 | margin = margin.saturating_add(1) 185 | } else { 186 | margin = margin.saturating_sub(1) 187 | } 188 | } 189 | Input::Action => { 190 | if let Some(file) = slides.files.get(idx) { 191 | file.action(w)?; 192 | } 193 | }, 194 | Input::None => (), 195 | } 196 | } 197 | 198 | Ok(()) 199 | } 200 | 201 | enum Input { 202 | None, 203 | Previous, 204 | Next, 205 | Margin(bool), 206 | Action, 207 | Quit, 208 | } 209 | 210 | fn read_input() -> Result { 211 | let ev = event::read()?; 212 | 213 | if let Event::Key(ev) = ev { 214 | return match ev { 215 | KeyEvent { 216 | code: KeyCode::Down, 217 | .. 218 | } => Ok(Input::Next), 219 | KeyEvent { 220 | code: KeyCode::Up, .. 221 | } => Ok(Input::Previous), 222 | KeyEvent { 223 | code: KeyCode::Char('+'), 224 | .. 225 | } => Ok(Input::Margin(true)), 226 | KeyEvent { 227 | code: KeyCode::Char('-'), 228 | .. 229 | } => Ok(Input::Margin(false)), 230 | KeyEvent { 231 | code: KeyCode::Esc, .. 232 | } => Ok(Input::Quit), 233 | KeyEvent { 234 | code: KeyCode::Enter, .. 235 | } => Ok(Input::Action), 236 | 237 | _ => Ok(Input::None), 238 | }; 239 | } 240 | 241 | Ok(Input::None) 242 | } 243 | 244 | #[derive(Debug, Deserialize)] 245 | struct Slides { 246 | files: Vec, 247 | } 248 | 249 | fn main() -> Result<()> { 250 | let matches = App::new("presentui") 251 | .version("0.1.0") 252 | .author("Stephan D. ") 253 | .about("terminal presenting") 254 | .arg(Arg::with_name("file") 255 | .short("f") 256 | .long("file") 257 | .takes_value(true) 258 | .required(true) 259 | .help("input file (*.ron)")) 260 | .get_matches(); 261 | 262 | let f = File::open(matches.value_of("file").unwrap()).expect("Failed opening file"); 263 | let slides: Slides = from_reader(f).expect("Failed to parse ron"); 264 | 265 | let mut w = stderr(); 266 | 267 | enable_raw_mode()?; 268 | queue!(w, Hide)?; 269 | 270 | present(&mut w, &slides)?; 271 | 272 | queue!(w, Show)?; 273 | disable_raw_mode()?; 274 | 275 | Ok(()) 276 | } 277 | --------------------------------------------------------------------------------