├── .github └── workflows │ ├── build.yml │ ├── format.yml │ ├── lint.yml │ └── test.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── book ├── .gitignore ├── book.toml └── src │ ├── SUMMARY.md │ ├── assets │ ├── example.gif │ └── logo.svg │ └── guide.md └── src ├── bin └── mdbook-iced.rs ├── compiler.rs ├── compiler ├── Cargo.toml.template ├── embed.html └── library.html └── lib.rs /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push, pull_request] 3 | jobs: 4 | book: 5 | runs-on: ${{ matrix.os }} 6 | env: 7 | RUSTFLAGS: --deny warnings 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest, windows-latest, macOS-latest] 11 | steps: 12 | - uses: actions/checkout@master 13 | - uses: hecrj/setup-rust-action@v2 14 | with: 15 | rust-version: stable 16 | - name: Add `wasm32-unknown-unknown` target 17 | run: rustup target add wasm32-unknown-unknown 18 | - name: Install `mdbook` and `wasm-bindgen-cli` 19 | run: cargo install mdbook wasm-bindgen-cli 20 | - name: Install `mdbook-iced` 21 | run: cargo install --path . 22 | - name: Build book 23 | run: cd book && mdbook build 24 | - name: Check iceberg artifacts exist 25 | run: cd book && ls book/.icebergs/* 26 | -------------------------------------------------------------------------------- /.github/workflows/format.yml: -------------------------------------------------------------------------------- 1 | name: Format 2 | on: [push, pull_request] 3 | jobs: 4 | all: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: hecrj/setup-rust-action@v2 8 | with: 9 | components: rustfmt 10 | - uses: actions/checkout@master 11 | - name: Check format 12 | run: cargo fmt --all -- --check --verbose 13 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: [push, pull_request] 3 | jobs: 4 | all: 5 | runs-on: macOS-latest 6 | steps: 7 | - uses: hecrj/setup-rust-action@v2 8 | with: 9 | components: clippy 10 | - uses: actions/checkout@master 11 | - name: Check lints 12 | run: cargo clippy -- -D warnings 13 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push, pull_request] 3 | jobs: 4 | all: 5 | runs-on: ${{ matrix.os }} 6 | env: 7 | RUSTFLAGS: --deny warnings 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest, windows-latest, macOS-latest] 11 | rust: [stable, beta] 12 | steps: 13 | - uses: actions/checkout@master 14 | - uses: hecrj/setup-rust-action@v2 15 | with: 16 | rust-version: ${{ matrix.rust }} 17 | - name: Run tests 18 | run: | 19 | cargo test --verbose --workspace 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "ammonia" 31 | version = "3.3.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "64e6d1c7838db705c9b756557ee27c384ce695a1c51a6fe528784cb1c6840170" 34 | dependencies = [ 35 | "html5ever", 36 | "maplit", 37 | "once_cell", 38 | "tendril", 39 | "url", 40 | ] 41 | 42 | [[package]] 43 | name = "android-tzdata" 44 | version = "0.1.1" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 47 | 48 | [[package]] 49 | name = "android_system_properties" 50 | version = "0.1.5" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 53 | dependencies = [ 54 | "libc", 55 | ] 56 | 57 | [[package]] 58 | name = "anstream" 59 | version = "0.6.13" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" 62 | dependencies = [ 63 | "anstyle", 64 | "anstyle-parse", 65 | "anstyle-query", 66 | "anstyle-wincon", 67 | "colorchoice", 68 | "utf8parse", 69 | ] 70 | 71 | [[package]] 72 | name = "anstyle" 73 | version = "1.0.6" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 76 | 77 | [[package]] 78 | name = "anstyle-parse" 79 | version = "0.2.3" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 82 | dependencies = [ 83 | "utf8parse", 84 | ] 85 | 86 | [[package]] 87 | name = "anstyle-query" 88 | version = "1.0.2" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 91 | dependencies = [ 92 | "windows-sys 0.52.0", 93 | ] 94 | 95 | [[package]] 96 | name = "anstyle-wincon" 97 | version = "3.0.2" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 100 | dependencies = [ 101 | "anstyle", 102 | "windows-sys 0.52.0", 103 | ] 104 | 105 | [[package]] 106 | name = "anyhow" 107 | version = "1.0.81" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" 110 | 111 | [[package]] 112 | name = "autocfg" 113 | version = "1.1.0" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 116 | 117 | [[package]] 118 | name = "backtrace" 119 | version = "0.3.70" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "95d8e92cac0961e91dbd517496b00f7e9b92363dbe6d42c3198268323798860c" 122 | dependencies = [ 123 | "addr2line", 124 | "cc", 125 | "cfg-if", 126 | "libc", 127 | "miniz_oxide", 128 | "object", 129 | "rustc-demangle", 130 | ] 131 | 132 | [[package]] 133 | name = "base64" 134 | version = "0.21.7" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 137 | 138 | [[package]] 139 | name = "bitflags" 140 | version = "1.3.2" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 143 | 144 | [[package]] 145 | name = "bitflags" 146 | version = "2.5.0" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 149 | 150 | [[package]] 151 | name = "block-buffer" 152 | version = "0.10.4" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 155 | dependencies = [ 156 | "generic-array", 157 | ] 158 | 159 | [[package]] 160 | name = "bstr" 161 | version = "1.9.1" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" 164 | dependencies = [ 165 | "memchr", 166 | "regex-automata", 167 | "serde", 168 | ] 169 | 170 | [[package]] 171 | name = "bumpalo" 172 | version = "3.15.4" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" 175 | 176 | [[package]] 177 | name = "byteorder" 178 | version = "1.5.0" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 181 | 182 | [[package]] 183 | name = "bytes" 184 | version = "1.5.0" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 187 | 188 | [[package]] 189 | name = "cc" 190 | version = "1.0.90" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" 193 | 194 | [[package]] 195 | name = "cfg-if" 196 | version = "1.0.0" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 199 | 200 | [[package]] 201 | name = "chrono" 202 | version = "0.4.35" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" 205 | dependencies = [ 206 | "android-tzdata", 207 | "iana-time-zone", 208 | "num-traits", 209 | "windows-targets 0.52.4", 210 | ] 211 | 212 | [[package]] 213 | name = "clap" 214 | version = "4.5.3" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" 217 | dependencies = [ 218 | "clap_builder", 219 | ] 220 | 221 | [[package]] 222 | name = "clap_builder" 223 | version = "4.5.2" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" 226 | dependencies = [ 227 | "anstream", 228 | "anstyle", 229 | "clap_lex", 230 | "strsim", 231 | "terminal_size", 232 | ] 233 | 234 | [[package]] 235 | name = "clap_complete" 236 | version = "4.5.1" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" 239 | dependencies = [ 240 | "clap", 241 | ] 242 | 243 | [[package]] 244 | name = "clap_lex" 245 | version = "0.7.0" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" 248 | 249 | [[package]] 250 | name = "colorchoice" 251 | version = "1.0.0" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 254 | 255 | [[package]] 256 | name = "core-foundation-sys" 257 | version = "0.8.6" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 260 | 261 | [[package]] 262 | name = "cpufeatures" 263 | version = "0.2.12" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 266 | dependencies = [ 267 | "libc", 268 | ] 269 | 270 | [[package]] 271 | name = "crossbeam-channel" 272 | version = "0.5.12" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" 275 | dependencies = [ 276 | "crossbeam-utils", 277 | ] 278 | 279 | [[package]] 280 | name = "crossbeam-deque" 281 | version = "0.8.5" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 284 | dependencies = [ 285 | "crossbeam-epoch", 286 | "crossbeam-utils", 287 | ] 288 | 289 | [[package]] 290 | name = "crossbeam-epoch" 291 | version = "0.9.18" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 294 | dependencies = [ 295 | "crossbeam-utils", 296 | ] 297 | 298 | [[package]] 299 | name = "crossbeam-utils" 300 | version = "0.8.19" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" 303 | 304 | [[package]] 305 | name = "crypto-common" 306 | version = "0.1.6" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 309 | dependencies = [ 310 | "generic-array", 311 | "typenum", 312 | ] 313 | 314 | [[package]] 315 | name = "data-encoding" 316 | version = "2.5.0" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" 319 | 320 | [[package]] 321 | name = "digest" 322 | version = "0.10.7" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 325 | dependencies = [ 326 | "block-buffer", 327 | "crypto-common", 328 | ] 329 | 330 | [[package]] 331 | name = "either" 332 | version = "1.10.0" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" 335 | 336 | [[package]] 337 | name = "elasticlunr-rs" 338 | version = "3.0.2" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "41e83863a500656dfa214fee6682de9c5b9f03de6860fec531235ed2ae9f6571" 341 | dependencies = [ 342 | "regex", 343 | "serde", 344 | "serde_derive", 345 | "serde_json", 346 | ] 347 | 348 | [[package]] 349 | name = "env_filter" 350 | version = "0.1.0" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" 353 | dependencies = [ 354 | "log", 355 | "regex", 356 | ] 357 | 358 | [[package]] 359 | name = "env_logger" 360 | version = "0.11.3" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" 363 | dependencies = [ 364 | "anstream", 365 | "anstyle", 366 | "env_filter", 367 | "humantime", 368 | "log", 369 | ] 370 | 371 | [[package]] 372 | name = "equivalent" 373 | version = "1.0.1" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 376 | 377 | [[package]] 378 | name = "errno" 379 | version = "0.3.8" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 382 | dependencies = [ 383 | "libc", 384 | "windows-sys 0.52.0", 385 | ] 386 | 387 | [[package]] 388 | name = "fastrand" 389 | version = "2.0.1" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 392 | 393 | [[package]] 394 | name = "filetime" 395 | version = "0.2.23" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" 398 | dependencies = [ 399 | "cfg-if", 400 | "libc", 401 | "redox_syscall", 402 | "windows-sys 0.52.0", 403 | ] 404 | 405 | [[package]] 406 | name = "fnv" 407 | version = "1.0.7" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 410 | 411 | [[package]] 412 | name = "form_urlencoded" 413 | version = "1.2.1" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 416 | dependencies = [ 417 | "percent-encoding", 418 | ] 419 | 420 | [[package]] 421 | name = "fsevent-sys" 422 | version = "4.1.0" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" 425 | dependencies = [ 426 | "libc", 427 | ] 428 | 429 | [[package]] 430 | name = "futf" 431 | version = "0.1.5" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" 434 | dependencies = [ 435 | "mac", 436 | "new_debug_unreachable", 437 | ] 438 | 439 | [[package]] 440 | name = "futures-channel" 441 | version = "0.3.30" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 444 | dependencies = [ 445 | "futures-core", 446 | "futures-sink", 447 | ] 448 | 449 | [[package]] 450 | name = "futures-core" 451 | version = "0.3.30" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 454 | 455 | [[package]] 456 | name = "futures-macro" 457 | version = "0.3.30" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 460 | dependencies = [ 461 | "proc-macro2", 462 | "quote", 463 | "syn 2.0.53", 464 | ] 465 | 466 | [[package]] 467 | name = "futures-sink" 468 | version = "0.3.30" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 471 | 472 | [[package]] 473 | name = "futures-task" 474 | version = "0.3.30" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 477 | 478 | [[package]] 479 | name = "futures-util" 480 | version = "0.3.30" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 483 | dependencies = [ 484 | "futures-core", 485 | "futures-macro", 486 | "futures-sink", 487 | "futures-task", 488 | "pin-project-lite", 489 | "pin-utils", 490 | "slab", 491 | ] 492 | 493 | [[package]] 494 | name = "generic-array" 495 | version = "0.14.7" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 498 | dependencies = [ 499 | "typenum", 500 | "version_check", 501 | ] 502 | 503 | [[package]] 504 | name = "getopts" 505 | version = "0.2.21" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" 508 | dependencies = [ 509 | "unicode-width", 510 | ] 511 | 512 | [[package]] 513 | name = "getrandom" 514 | version = "0.2.12" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 517 | dependencies = [ 518 | "cfg-if", 519 | "libc", 520 | "wasi", 521 | ] 522 | 523 | [[package]] 524 | name = "gimli" 525 | version = "0.28.1" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 528 | 529 | [[package]] 530 | name = "globset" 531 | version = "0.4.14" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" 534 | dependencies = [ 535 | "aho-corasick", 536 | "bstr", 537 | "log", 538 | "regex-automata", 539 | "regex-syntax", 540 | ] 541 | 542 | [[package]] 543 | name = "h2" 544 | version = "0.3.25" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" 547 | dependencies = [ 548 | "bytes", 549 | "fnv", 550 | "futures-core", 551 | "futures-sink", 552 | "futures-util", 553 | "http", 554 | "indexmap", 555 | "slab", 556 | "tokio", 557 | "tokio-util", 558 | "tracing", 559 | ] 560 | 561 | [[package]] 562 | name = "handlebars" 563 | version = "5.1.0" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "ab283476b99e66691dee3f1640fea91487a8d81f50fb5ecc75538f8f8879a1e4" 566 | dependencies = [ 567 | "log", 568 | "pest", 569 | "pest_derive", 570 | "serde", 571 | "serde_json", 572 | "thiserror", 573 | ] 574 | 575 | [[package]] 576 | name = "hashbrown" 577 | version = "0.14.3" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 580 | 581 | [[package]] 582 | name = "headers" 583 | version = "0.3.9" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" 586 | dependencies = [ 587 | "base64", 588 | "bytes", 589 | "headers-core", 590 | "http", 591 | "httpdate", 592 | "mime", 593 | "sha1", 594 | ] 595 | 596 | [[package]] 597 | name = "headers-core" 598 | version = "0.2.0" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" 601 | dependencies = [ 602 | "http", 603 | ] 604 | 605 | [[package]] 606 | name = "hermit-abi" 607 | version = "0.3.9" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 610 | 611 | [[package]] 612 | name = "html5ever" 613 | version = "0.26.0" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" 616 | dependencies = [ 617 | "log", 618 | "mac", 619 | "markup5ever", 620 | "proc-macro2", 621 | "quote", 622 | "syn 1.0.109", 623 | ] 624 | 625 | [[package]] 626 | name = "http" 627 | version = "0.2.12" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 630 | dependencies = [ 631 | "bytes", 632 | "fnv", 633 | "itoa", 634 | ] 635 | 636 | [[package]] 637 | name = "http-body" 638 | version = "0.4.6" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 641 | dependencies = [ 642 | "bytes", 643 | "http", 644 | "pin-project-lite", 645 | ] 646 | 647 | [[package]] 648 | name = "httparse" 649 | version = "1.8.0" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 652 | 653 | [[package]] 654 | name = "httpdate" 655 | version = "1.0.3" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 658 | 659 | [[package]] 660 | name = "humantime" 661 | version = "2.1.0" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 664 | 665 | [[package]] 666 | name = "hyper" 667 | version = "0.14.28" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 670 | dependencies = [ 671 | "bytes", 672 | "futures-channel", 673 | "futures-core", 674 | "futures-util", 675 | "h2", 676 | "http", 677 | "http-body", 678 | "httparse", 679 | "httpdate", 680 | "itoa", 681 | "pin-project-lite", 682 | "socket2", 683 | "tokio", 684 | "tower-service", 685 | "tracing", 686 | "want", 687 | ] 688 | 689 | [[package]] 690 | name = "iana-time-zone" 691 | version = "0.1.60" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" 694 | dependencies = [ 695 | "android_system_properties", 696 | "core-foundation-sys", 697 | "iana-time-zone-haiku", 698 | "js-sys", 699 | "wasm-bindgen", 700 | "windows-core", 701 | ] 702 | 703 | [[package]] 704 | name = "iana-time-zone-haiku" 705 | version = "0.1.2" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 708 | dependencies = [ 709 | "cc", 710 | ] 711 | 712 | [[package]] 713 | name = "idna" 714 | version = "0.5.0" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 717 | dependencies = [ 718 | "unicode-bidi", 719 | "unicode-normalization", 720 | ] 721 | 722 | [[package]] 723 | name = "ignore" 724 | version = "0.4.22" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" 727 | dependencies = [ 728 | "crossbeam-deque", 729 | "globset", 730 | "log", 731 | "memchr", 732 | "regex-automata", 733 | "same-file", 734 | "walkdir", 735 | "winapi-util", 736 | ] 737 | 738 | [[package]] 739 | name = "indexmap" 740 | version = "2.2.5" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" 743 | dependencies = [ 744 | "equivalent", 745 | "hashbrown", 746 | ] 747 | 748 | [[package]] 749 | name = "inotify" 750 | version = "0.9.6" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" 753 | dependencies = [ 754 | "bitflags 1.3.2", 755 | "inotify-sys", 756 | "libc", 757 | ] 758 | 759 | [[package]] 760 | name = "inotify-sys" 761 | version = "0.1.5" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" 764 | dependencies = [ 765 | "libc", 766 | ] 767 | 768 | [[package]] 769 | name = "itertools" 770 | version = "0.12.1" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 773 | dependencies = [ 774 | "either", 775 | ] 776 | 777 | [[package]] 778 | name = "itoa" 779 | version = "1.0.10" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 782 | 783 | [[package]] 784 | name = "js-sys" 785 | version = "0.3.69" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 788 | dependencies = [ 789 | "wasm-bindgen", 790 | ] 791 | 792 | [[package]] 793 | name = "kqueue" 794 | version = "1.0.8" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" 797 | dependencies = [ 798 | "kqueue-sys", 799 | "libc", 800 | ] 801 | 802 | [[package]] 803 | name = "kqueue-sys" 804 | version = "1.0.4" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" 807 | dependencies = [ 808 | "bitflags 1.3.2", 809 | "libc", 810 | ] 811 | 812 | [[package]] 813 | name = "libc" 814 | version = "0.2.153" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 817 | 818 | [[package]] 819 | name = "linux-raw-sys" 820 | version = "0.4.13" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 823 | 824 | [[package]] 825 | name = "lock_api" 826 | version = "0.4.11" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 829 | dependencies = [ 830 | "autocfg", 831 | "scopeguard", 832 | ] 833 | 834 | [[package]] 835 | name = "log" 836 | version = "0.4.21" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 839 | 840 | [[package]] 841 | name = "mac" 842 | version = "0.1.1" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" 845 | 846 | [[package]] 847 | name = "maplit" 848 | version = "1.0.2" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 851 | 852 | [[package]] 853 | name = "markup5ever" 854 | version = "0.11.0" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" 857 | dependencies = [ 858 | "log", 859 | "phf", 860 | "phf_codegen", 861 | "string_cache", 862 | "string_cache_codegen", 863 | "tendril", 864 | ] 865 | 866 | [[package]] 867 | name = "mdbook" 868 | version = "0.4.37" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "0c33564061c3c640bed5ace7d6a2a1b65f2c64257d1ac930c15e94ed0fb561d3" 871 | dependencies = [ 872 | "ammonia", 873 | "anyhow", 874 | "chrono", 875 | "clap", 876 | "clap_complete", 877 | "elasticlunr-rs", 878 | "env_logger", 879 | "futures-util", 880 | "handlebars", 881 | "ignore", 882 | "log", 883 | "memchr", 884 | "notify", 885 | "notify-debouncer-mini", 886 | "once_cell", 887 | "opener", 888 | "pathdiff", 889 | "pulldown-cmark", 890 | "regex", 891 | "serde", 892 | "serde_json", 893 | "shlex", 894 | "tempfile", 895 | "tokio", 896 | "toml", 897 | "topological-sort", 898 | "warp", 899 | ] 900 | 901 | [[package]] 902 | name = "mdbook-iced" 903 | version = "0.1.4" 904 | dependencies = [ 905 | "anyhow", 906 | "clap", 907 | "itertools", 908 | "mdbook", 909 | "pulldown-cmark", 910 | "pulldown-cmark-to-cmark", 911 | "semver", 912 | "serde_json", 913 | "sha2", 914 | "toml", 915 | ] 916 | 917 | [[package]] 918 | name = "memchr" 919 | version = "2.7.1" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 922 | 923 | [[package]] 924 | name = "mime" 925 | version = "0.3.17" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 928 | 929 | [[package]] 930 | name = "mime_guess" 931 | version = "2.0.4" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" 934 | dependencies = [ 935 | "mime", 936 | "unicase", 937 | ] 938 | 939 | [[package]] 940 | name = "miniz_oxide" 941 | version = "0.7.2" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 944 | dependencies = [ 945 | "adler", 946 | ] 947 | 948 | [[package]] 949 | name = "mio" 950 | version = "0.8.11" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 953 | dependencies = [ 954 | "libc", 955 | "log", 956 | "wasi", 957 | "windows-sys 0.48.0", 958 | ] 959 | 960 | [[package]] 961 | name = "new_debug_unreachable" 962 | version = "1.0.6" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 965 | 966 | [[package]] 967 | name = "normpath" 968 | version = "1.2.0" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" 971 | dependencies = [ 972 | "windows-sys 0.52.0", 973 | ] 974 | 975 | [[package]] 976 | name = "notify" 977 | version = "6.1.1" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" 980 | dependencies = [ 981 | "bitflags 2.5.0", 982 | "crossbeam-channel", 983 | "filetime", 984 | "fsevent-sys", 985 | "inotify", 986 | "kqueue", 987 | "libc", 988 | "log", 989 | "mio", 990 | "walkdir", 991 | "windows-sys 0.48.0", 992 | ] 993 | 994 | [[package]] 995 | name = "notify-debouncer-mini" 996 | version = "0.4.1" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "5d40b221972a1fc5ef4d858a2f671fb34c75983eb385463dff3780eeff6a9d43" 999 | dependencies = [ 1000 | "crossbeam-channel", 1001 | "log", 1002 | "notify", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "num-traits" 1007 | version = "0.2.18" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 1010 | dependencies = [ 1011 | "autocfg", 1012 | ] 1013 | 1014 | [[package]] 1015 | name = "num_cpus" 1016 | version = "1.16.0" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1019 | dependencies = [ 1020 | "hermit-abi", 1021 | "libc", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "object" 1026 | version = "0.32.2" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 1029 | dependencies = [ 1030 | "memchr", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "once_cell" 1035 | version = "1.19.0" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1038 | 1039 | [[package]] 1040 | name = "opener" 1041 | version = "0.6.1" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" 1044 | dependencies = [ 1045 | "bstr", 1046 | "normpath", 1047 | "winapi", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "parking_lot" 1052 | version = "0.12.1" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1055 | dependencies = [ 1056 | "lock_api", 1057 | "parking_lot_core", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "parking_lot_core" 1062 | version = "0.9.9" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 1065 | dependencies = [ 1066 | "cfg-if", 1067 | "libc", 1068 | "redox_syscall", 1069 | "smallvec", 1070 | "windows-targets 0.48.5", 1071 | ] 1072 | 1073 | [[package]] 1074 | name = "pathdiff" 1075 | version = "0.2.1" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" 1078 | 1079 | [[package]] 1080 | name = "percent-encoding" 1081 | version = "2.3.1" 1082 | source = "registry+https://github.com/rust-lang/crates.io-index" 1083 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1084 | 1085 | [[package]] 1086 | name = "pest" 1087 | version = "2.7.8" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" 1090 | dependencies = [ 1091 | "memchr", 1092 | "thiserror", 1093 | "ucd-trie", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "pest_derive" 1098 | version = "2.7.8" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" 1101 | dependencies = [ 1102 | "pest", 1103 | "pest_generator", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "pest_generator" 1108 | version = "2.7.8" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" 1111 | dependencies = [ 1112 | "pest", 1113 | "pest_meta", 1114 | "proc-macro2", 1115 | "quote", 1116 | "syn 2.0.53", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "pest_meta" 1121 | version = "2.7.8" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" 1124 | dependencies = [ 1125 | "once_cell", 1126 | "pest", 1127 | "sha2", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "phf" 1132 | version = "0.10.1" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" 1135 | dependencies = [ 1136 | "phf_shared", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "phf_codegen" 1141 | version = "0.10.0" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" 1144 | dependencies = [ 1145 | "phf_generator", 1146 | "phf_shared", 1147 | ] 1148 | 1149 | [[package]] 1150 | name = "phf_generator" 1151 | version = "0.10.0" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" 1154 | dependencies = [ 1155 | "phf_shared", 1156 | "rand", 1157 | ] 1158 | 1159 | [[package]] 1160 | name = "phf_shared" 1161 | version = "0.10.0" 1162 | source = "registry+https://github.com/rust-lang/crates.io-index" 1163 | checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" 1164 | dependencies = [ 1165 | "siphasher", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "pin-project" 1170 | version = "1.1.5" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" 1173 | dependencies = [ 1174 | "pin-project-internal", 1175 | ] 1176 | 1177 | [[package]] 1178 | name = "pin-project-internal" 1179 | version = "1.1.5" 1180 | source = "registry+https://github.com/rust-lang/crates.io-index" 1181 | checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" 1182 | dependencies = [ 1183 | "proc-macro2", 1184 | "quote", 1185 | "syn 2.0.53", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "pin-project-lite" 1190 | version = "0.2.13" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1193 | 1194 | [[package]] 1195 | name = "pin-utils" 1196 | version = "0.1.0" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1199 | 1200 | [[package]] 1201 | name = "ppv-lite86" 1202 | version = "0.2.17" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1205 | 1206 | [[package]] 1207 | name = "precomputed-hash" 1208 | version = "0.1.1" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" 1211 | 1212 | [[package]] 1213 | name = "proc-macro2" 1214 | version = "1.0.79" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 1217 | dependencies = [ 1218 | "unicode-ident", 1219 | ] 1220 | 1221 | [[package]] 1222 | name = "pulldown-cmark" 1223 | version = "0.10.0" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7" 1226 | dependencies = [ 1227 | "bitflags 2.5.0", 1228 | "getopts", 1229 | "memchr", 1230 | "pulldown-cmark-escape", 1231 | "unicase", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "pulldown-cmark-escape" 1236 | version = "0.10.0" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b" 1239 | 1240 | [[package]] 1241 | name = "pulldown-cmark-to-cmark" 1242 | version = "13.0.0" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | checksum = "f609795c8d835f79dcfcf768415b9fb57ef1b74891e99f86e73f43a7a257163b" 1245 | dependencies = [ 1246 | "pulldown-cmark", 1247 | ] 1248 | 1249 | [[package]] 1250 | name = "quote" 1251 | version = "1.0.35" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 1254 | dependencies = [ 1255 | "proc-macro2", 1256 | ] 1257 | 1258 | [[package]] 1259 | name = "rand" 1260 | version = "0.8.5" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1263 | dependencies = [ 1264 | "libc", 1265 | "rand_chacha", 1266 | "rand_core", 1267 | ] 1268 | 1269 | [[package]] 1270 | name = "rand_chacha" 1271 | version = "0.3.1" 1272 | source = "registry+https://github.com/rust-lang/crates.io-index" 1273 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1274 | dependencies = [ 1275 | "ppv-lite86", 1276 | "rand_core", 1277 | ] 1278 | 1279 | [[package]] 1280 | name = "rand_core" 1281 | version = "0.6.4" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1284 | dependencies = [ 1285 | "getrandom", 1286 | ] 1287 | 1288 | [[package]] 1289 | name = "redox_syscall" 1290 | version = "0.4.1" 1291 | source = "registry+https://github.com/rust-lang/crates.io-index" 1292 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 1293 | dependencies = [ 1294 | "bitflags 1.3.2", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "regex" 1299 | version = "1.10.3" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" 1302 | dependencies = [ 1303 | "aho-corasick", 1304 | "memchr", 1305 | "regex-automata", 1306 | "regex-syntax", 1307 | ] 1308 | 1309 | [[package]] 1310 | name = "regex-automata" 1311 | version = "0.4.6" 1312 | source = "registry+https://github.com/rust-lang/crates.io-index" 1313 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 1314 | dependencies = [ 1315 | "aho-corasick", 1316 | "memchr", 1317 | "regex-syntax", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "regex-syntax" 1322 | version = "0.8.2" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 1325 | 1326 | [[package]] 1327 | name = "rustc-demangle" 1328 | version = "0.1.23" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1331 | 1332 | [[package]] 1333 | name = "rustix" 1334 | version = "0.38.32" 1335 | source = "registry+https://github.com/rust-lang/crates.io-index" 1336 | checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" 1337 | dependencies = [ 1338 | "bitflags 2.5.0", 1339 | "errno", 1340 | "libc", 1341 | "linux-raw-sys", 1342 | "windows-sys 0.52.0", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "rustls-pemfile" 1347 | version = "1.0.4" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 1350 | dependencies = [ 1351 | "base64", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "ryu" 1356 | version = "1.0.17" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 1359 | 1360 | [[package]] 1361 | name = "same-file" 1362 | version = "1.0.6" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1365 | dependencies = [ 1366 | "winapi-util", 1367 | ] 1368 | 1369 | [[package]] 1370 | name = "scoped-tls" 1371 | version = "1.0.1" 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" 1373 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1374 | 1375 | [[package]] 1376 | name = "scopeguard" 1377 | version = "1.2.0" 1378 | source = "registry+https://github.com/rust-lang/crates.io-index" 1379 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1380 | 1381 | [[package]] 1382 | name = "semver" 1383 | version = "1.0.22" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" 1386 | 1387 | [[package]] 1388 | name = "serde" 1389 | version = "1.0.197" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 1392 | dependencies = [ 1393 | "serde_derive", 1394 | ] 1395 | 1396 | [[package]] 1397 | name = "serde_derive" 1398 | version = "1.0.197" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 1401 | dependencies = [ 1402 | "proc-macro2", 1403 | "quote", 1404 | "syn 2.0.53", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "serde_json" 1409 | version = "1.0.114" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" 1412 | dependencies = [ 1413 | "itoa", 1414 | "ryu", 1415 | "serde", 1416 | ] 1417 | 1418 | [[package]] 1419 | name = "serde_urlencoded" 1420 | version = "0.7.1" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1423 | dependencies = [ 1424 | "form_urlencoded", 1425 | "itoa", 1426 | "ryu", 1427 | "serde", 1428 | ] 1429 | 1430 | [[package]] 1431 | name = "sha1" 1432 | version = "0.10.6" 1433 | source = "registry+https://github.com/rust-lang/crates.io-index" 1434 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1435 | dependencies = [ 1436 | "cfg-if", 1437 | "cpufeatures", 1438 | "digest", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "sha2" 1443 | version = "0.10.8" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1446 | dependencies = [ 1447 | "cfg-if", 1448 | "cpufeatures", 1449 | "digest", 1450 | ] 1451 | 1452 | [[package]] 1453 | name = "shlex" 1454 | version = "1.3.0" 1455 | source = "registry+https://github.com/rust-lang/crates.io-index" 1456 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1457 | 1458 | [[package]] 1459 | name = "siphasher" 1460 | version = "0.3.11" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1463 | 1464 | [[package]] 1465 | name = "slab" 1466 | version = "0.4.9" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1469 | dependencies = [ 1470 | "autocfg", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "smallvec" 1475 | version = "1.13.2" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1478 | 1479 | [[package]] 1480 | name = "socket2" 1481 | version = "0.5.6" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" 1484 | dependencies = [ 1485 | "libc", 1486 | "windows-sys 0.52.0", 1487 | ] 1488 | 1489 | [[package]] 1490 | name = "string_cache" 1491 | version = "0.8.7" 1492 | source = "registry+https://github.com/rust-lang/crates.io-index" 1493 | checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" 1494 | dependencies = [ 1495 | "new_debug_unreachable", 1496 | "once_cell", 1497 | "parking_lot", 1498 | "phf_shared", 1499 | "precomputed-hash", 1500 | "serde", 1501 | ] 1502 | 1503 | [[package]] 1504 | name = "string_cache_codegen" 1505 | version = "0.5.2" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" 1508 | dependencies = [ 1509 | "phf_generator", 1510 | "phf_shared", 1511 | "proc-macro2", 1512 | "quote", 1513 | ] 1514 | 1515 | [[package]] 1516 | name = "strsim" 1517 | version = "0.11.0" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" 1520 | 1521 | [[package]] 1522 | name = "syn" 1523 | version = "1.0.109" 1524 | source = "registry+https://github.com/rust-lang/crates.io-index" 1525 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1526 | dependencies = [ 1527 | "proc-macro2", 1528 | "quote", 1529 | "unicode-ident", 1530 | ] 1531 | 1532 | [[package]] 1533 | name = "syn" 1534 | version = "2.0.53" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" 1537 | dependencies = [ 1538 | "proc-macro2", 1539 | "quote", 1540 | "unicode-ident", 1541 | ] 1542 | 1543 | [[package]] 1544 | name = "tempfile" 1545 | version = "3.10.1" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" 1548 | dependencies = [ 1549 | "cfg-if", 1550 | "fastrand", 1551 | "rustix", 1552 | "windows-sys 0.52.0", 1553 | ] 1554 | 1555 | [[package]] 1556 | name = "tendril" 1557 | version = "0.4.3" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" 1560 | dependencies = [ 1561 | "futf", 1562 | "mac", 1563 | "utf-8", 1564 | ] 1565 | 1566 | [[package]] 1567 | name = "terminal_size" 1568 | version = "0.3.0" 1569 | source = "registry+https://github.com/rust-lang/crates.io-index" 1570 | checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" 1571 | dependencies = [ 1572 | "rustix", 1573 | "windows-sys 0.48.0", 1574 | ] 1575 | 1576 | [[package]] 1577 | name = "thiserror" 1578 | version = "1.0.58" 1579 | source = "registry+https://github.com/rust-lang/crates.io-index" 1580 | checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" 1581 | dependencies = [ 1582 | "thiserror-impl", 1583 | ] 1584 | 1585 | [[package]] 1586 | name = "thiserror-impl" 1587 | version = "1.0.58" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" 1590 | dependencies = [ 1591 | "proc-macro2", 1592 | "quote", 1593 | "syn 2.0.53", 1594 | ] 1595 | 1596 | [[package]] 1597 | name = "tinyvec" 1598 | version = "1.6.0" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1601 | dependencies = [ 1602 | "tinyvec_macros", 1603 | ] 1604 | 1605 | [[package]] 1606 | name = "tinyvec_macros" 1607 | version = "0.1.1" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1610 | 1611 | [[package]] 1612 | name = "tokio" 1613 | version = "1.36.0" 1614 | source = "registry+https://github.com/rust-lang/crates.io-index" 1615 | checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" 1616 | dependencies = [ 1617 | "backtrace", 1618 | "bytes", 1619 | "libc", 1620 | "mio", 1621 | "num_cpus", 1622 | "pin-project-lite", 1623 | "socket2", 1624 | "tokio-macros", 1625 | "windows-sys 0.48.0", 1626 | ] 1627 | 1628 | [[package]] 1629 | name = "tokio-macros" 1630 | version = "2.2.0" 1631 | source = "registry+https://github.com/rust-lang/crates.io-index" 1632 | checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 1633 | dependencies = [ 1634 | "proc-macro2", 1635 | "quote", 1636 | "syn 2.0.53", 1637 | ] 1638 | 1639 | [[package]] 1640 | name = "tokio-stream" 1641 | version = "0.1.15" 1642 | source = "registry+https://github.com/rust-lang/crates.io-index" 1643 | checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" 1644 | dependencies = [ 1645 | "futures-core", 1646 | "pin-project-lite", 1647 | "tokio", 1648 | ] 1649 | 1650 | [[package]] 1651 | name = "tokio-tungstenite" 1652 | version = "0.20.1" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" 1655 | dependencies = [ 1656 | "futures-util", 1657 | "log", 1658 | "tokio", 1659 | "tungstenite", 1660 | ] 1661 | 1662 | [[package]] 1663 | name = "tokio-util" 1664 | version = "0.7.10" 1665 | source = "registry+https://github.com/rust-lang/crates.io-index" 1666 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 1667 | dependencies = [ 1668 | "bytes", 1669 | "futures-core", 1670 | "futures-sink", 1671 | "pin-project-lite", 1672 | "tokio", 1673 | "tracing", 1674 | ] 1675 | 1676 | [[package]] 1677 | name = "toml" 1678 | version = "0.5.11" 1679 | source = "registry+https://github.com/rust-lang/crates.io-index" 1680 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 1681 | dependencies = [ 1682 | "serde", 1683 | ] 1684 | 1685 | [[package]] 1686 | name = "topological-sort" 1687 | version = "0.2.2" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" 1690 | 1691 | [[package]] 1692 | name = "tower-service" 1693 | version = "0.3.2" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1696 | 1697 | [[package]] 1698 | name = "tracing" 1699 | version = "0.1.40" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1702 | dependencies = [ 1703 | "log", 1704 | "pin-project-lite", 1705 | "tracing-core", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "tracing-core" 1710 | version = "0.1.32" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1713 | dependencies = [ 1714 | "once_cell", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "try-lock" 1719 | version = "0.2.5" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1722 | 1723 | [[package]] 1724 | name = "tungstenite" 1725 | version = "0.20.1" 1726 | source = "registry+https://github.com/rust-lang/crates.io-index" 1727 | checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" 1728 | dependencies = [ 1729 | "byteorder", 1730 | "bytes", 1731 | "data-encoding", 1732 | "http", 1733 | "httparse", 1734 | "log", 1735 | "rand", 1736 | "sha1", 1737 | "thiserror", 1738 | "url", 1739 | "utf-8", 1740 | ] 1741 | 1742 | [[package]] 1743 | name = "typenum" 1744 | version = "1.17.0" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1747 | 1748 | [[package]] 1749 | name = "ucd-trie" 1750 | version = "0.1.6" 1751 | source = "registry+https://github.com/rust-lang/crates.io-index" 1752 | checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" 1753 | 1754 | [[package]] 1755 | name = "unicase" 1756 | version = "2.7.0" 1757 | source = "registry+https://github.com/rust-lang/crates.io-index" 1758 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 1759 | dependencies = [ 1760 | "version_check", 1761 | ] 1762 | 1763 | [[package]] 1764 | name = "unicode-bidi" 1765 | version = "0.3.15" 1766 | source = "registry+https://github.com/rust-lang/crates.io-index" 1767 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 1768 | 1769 | [[package]] 1770 | name = "unicode-ident" 1771 | version = "1.0.12" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1774 | 1775 | [[package]] 1776 | name = "unicode-normalization" 1777 | version = "0.1.23" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 1780 | dependencies = [ 1781 | "tinyvec", 1782 | ] 1783 | 1784 | [[package]] 1785 | name = "unicode-width" 1786 | version = "0.1.11" 1787 | source = "registry+https://github.com/rust-lang/crates.io-index" 1788 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 1789 | 1790 | [[package]] 1791 | name = "url" 1792 | version = "2.5.0" 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" 1794 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 1795 | dependencies = [ 1796 | "form_urlencoded", 1797 | "idna", 1798 | "percent-encoding", 1799 | ] 1800 | 1801 | [[package]] 1802 | name = "utf-8" 1803 | version = "0.7.6" 1804 | source = "registry+https://github.com/rust-lang/crates.io-index" 1805 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 1806 | 1807 | [[package]] 1808 | name = "utf8parse" 1809 | version = "0.2.1" 1810 | source = "registry+https://github.com/rust-lang/crates.io-index" 1811 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1812 | 1813 | [[package]] 1814 | name = "version_check" 1815 | version = "0.9.4" 1816 | source = "registry+https://github.com/rust-lang/crates.io-index" 1817 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1818 | 1819 | [[package]] 1820 | name = "walkdir" 1821 | version = "2.5.0" 1822 | source = "registry+https://github.com/rust-lang/crates.io-index" 1823 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 1824 | dependencies = [ 1825 | "same-file", 1826 | "winapi-util", 1827 | ] 1828 | 1829 | [[package]] 1830 | name = "want" 1831 | version = "0.3.1" 1832 | source = "registry+https://github.com/rust-lang/crates.io-index" 1833 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1834 | dependencies = [ 1835 | "try-lock", 1836 | ] 1837 | 1838 | [[package]] 1839 | name = "warp" 1840 | version = "0.3.6" 1841 | source = "registry+https://github.com/rust-lang/crates.io-index" 1842 | checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" 1843 | dependencies = [ 1844 | "bytes", 1845 | "futures-channel", 1846 | "futures-util", 1847 | "headers", 1848 | "http", 1849 | "hyper", 1850 | "log", 1851 | "mime", 1852 | "mime_guess", 1853 | "percent-encoding", 1854 | "pin-project", 1855 | "rustls-pemfile", 1856 | "scoped-tls", 1857 | "serde", 1858 | "serde_json", 1859 | "serde_urlencoded", 1860 | "tokio", 1861 | "tokio-stream", 1862 | "tokio-tungstenite", 1863 | "tokio-util", 1864 | "tower-service", 1865 | "tracing", 1866 | ] 1867 | 1868 | [[package]] 1869 | name = "wasi" 1870 | version = "0.11.0+wasi-snapshot-preview1" 1871 | source = "registry+https://github.com/rust-lang/crates.io-index" 1872 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1873 | 1874 | [[package]] 1875 | name = "wasm-bindgen" 1876 | version = "0.2.92" 1877 | source = "registry+https://github.com/rust-lang/crates.io-index" 1878 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 1879 | dependencies = [ 1880 | "cfg-if", 1881 | "wasm-bindgen-macro", 1882 | ] 1883 | 1884 | [[package]] 1885 | name = "wasm-bindgen-backend" 1886 | version = "0.2.92" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 1889 | dependencies = [ 1890 | "bumpalo", 1891 | "log", 1892 | "once_cell", 1893 | "proc-macro2", 1894 | "quote", 1895 | "syn 2.0.53", 1896 | "wasm-bindgen-shared", 1897 | ] 1898 | 1899 | [[package]] 1900 | name = "wasm-bindgen-macro" 1901 | version = "0.2.92" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 1904 | dependencies = [ 1905 | "quote", 1906 | "wasm-bindgen-macro-support", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "wasm-bindgen-macro-support" 1911 | version = "0.2.92" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 1914 | dependencies = [ 1915 | "proc-macro2", 1916 | "quote", 1917 | "syn 2.0.53", 1918 | "wasm-bindgen-backend", 1919 | "wasm-bindgen-shared", 1920 | ] 1921 | 1922 | [[package]] 1923 | name = "wasm-bindgen-shared" 1924 | version = "0.2.92" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 1927 | 1928 | [[package]] 1929 | name = "winapi" 1930 | version = "0.3.9" 1931 | source = "registry+https://github.com/rust-lang/crates.io-index" 1932 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1933 | dependencies = [ 1934 | "winapi-i686-pc-windows-gnu", 1935 | "winapi-x86_64-pc-windows-gnu", 1936 | ] 1937 | 1938 | [[package]] 1939 | name = "winapi-i686-pc-windows-gnu" 1940 | version = "0.4.0" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1943 | 1944 | [[package]] 1945 | name = "winapi-util" 1946 | version = "0.1.6" 1947 | source = "registry+https://github.com/rust-lang/crates.io-index" 1948 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 1949 | dependencies = [ 1950 | "winapi", 1951 | ] 1952 | 1953 | [[package]] 1954 | name = "winapi-x86_64-pc-windows-gnu" 1955 | version = "0.4.0" 1956 | source = "registry+https://github.com/rust-lang/crates.io-index" 1957 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1958 | 1959 | [[package]] 1960 | name = "windows-core" 1961 | version = "0.52.0" 1962 | source = "registry+https://github.com/rust-lang/crates.io-index" 1963 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 1964 | dependencies = [ 1965 | "windows-targets 0.52.4", 1966 | ] 1967 | 1968 | [[package]] 1969 | name = "windows-sys" 1970 | version = "0.48.0" 1971 | source = "registry+https://github.com/rust-lang/crates.io-index" 1972 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1973 | dependencies = [ 1974 | "windows-targets 0.48.5", 1975 | ] 1976 | 1977 | [[package]] 1978 | name = "windows-sys" 1979 | version = "0.52.0" 1980 | source = "registry+https://github.com/rust-lang/crates.io-index" 1981 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1982 | dependencies = [ 1983 | "windows-targets 0.52.4", 1984 | ] 1985 | 1986 | [[package]] 1987 | name = "windows-targets" 1988 | version = "0.48.5" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1991 | dependencies = [ 1992 | "windows_aarch64_gnullvm 0.48.5", 1993 | "windows_aarch64_msvc 0.48.5", 1994 | "windows_i686_gnu 0.48.5", 1995 | "windows_i686_msvc 0.48.5", 1996 | "windows_x86_64_gnu 0.48.5", 1997 | "windows_x86_64_gnullvm 0.48.5", 1998 | "windows_x86_64_msvc 0.48.5", 1999 | ] 2000 | 2001 | [[package]] 2002 | name = "windows-targets" 2003 | version = "0.52.4" 2004 | source = "registry+https://github.com/rust-lang/crates.io-index" 2005 | checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 2006 | dependencies = [ 2007 | "windows_aarch64_gnullvm 0.52.4", 2008 | "windows_aarch64_msvc 0.52.4", 2009 | "windows_i686_gnu 0.52.4", 2010 | "windows_i686_msvc 0.52.4", 2011 | "windows_x86_64_gnu 0.52.4", 2012 | "windows_x86_64_gnullvm 0.52.4", 2013 | "windows_x86_64_msvc 0.52.4", 2014 | ] 2015 | 2016 | [[package]] 2017 | name = "windows_aarch64_gnullvm" 2018 | version = "0.48.5" 2019 | source = "registry+https://github.com/rust-lang/crates.io-index" 2020 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2021 | 2022 | [[package]] 2023 | name = "windows_aarch64_gnullvm" 2024 | version = "0.52.4" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" 2027 | 2028 | [[package]] 2029 | name = "windows_aarch64_msvc" 2030 | version = "0.48.5" 2031 | source = "registry+https://github.com/rust-lang/crates.io-index" 2032 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2033 | 2034 | [[package]] 2035 | name = "windows_aarch64_msvc" 2036 | version = "0.52.4" 2037 | source = "registry+https://github.com/rust-lang/crates.io-index" 2038 | checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" 2039 | 2040 | [[package]] 2041 | name = "windows_i686_gnu" 2042 | version = "0.48.5" 2043 | source = "registry+https://github.com/rust-lang/crates.io-index" 2044 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2045 | 2046 | [[package]] 2047 | name = "windows_i686_gnu" 2048 | version = "0.52.4" 2049 | source = "registry+https://github.com/rust-lang/crates.io-index" 2050 | checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" 2051 | 2052 | [[package]] 2053 | name = "windows_i686_msvc" 2054 | version = "0.48.5" 2055 | source = "registry+https://github.com/rust-lang/crates.io-index" 2056 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2057 | 2058 | [[package]] 2059 | name = "windows_i686_msvc" 2060 | version = "0.52.4" 2061 | source = "registry+https://github.com/rust-lang/crates.io-index" 2062 | checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" 2063 | 2064 | [[package]] 2065 | name = "windows_x86_64_gnu" 2066 | version = "0.48.5" 2067 | source = "registry+https://github.com/rust-lang/crates.io-index" 2068 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2069 | 2070 | [[package]] 2071 | name = "windows_x86_64_gnu" 2072 | version = "0.52.4" 2073 | source = "registry+https://github.com/rust-lang/crates.io-index" 2074 | checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" 2075 | 2076 | [[package]] 2077 | name = "windows_x86_64_gnullvm" 2078 | version = "0.48.5" 2079 | source = "registry+https://github.com/rust-lang/crates.io-index" 2080 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2081 | 2082 | [[package]] 2083 | name = "windows_x86_64_gnullvm" 2084 | version = "0.52.4" 2085 | source = "registry+https://github.com/rust-lang/crates.io-index" 2086 | checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" 2087 | 2088 | [[package]] 2089 | name = "windows_x86_64_msvc" 2090 | version = "0.48.5" 2091 | source = "registry+https://github.com/rust-lang/crates.io-index" 2092 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2093 | 2094 | [[package]] 2095 | name = "windows_x86_64_msvc" 2096 | version = "0.52.4" 2097 | source = "registry+https://github.com/rust-lang/crates.io-index" 2098 | checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" 2099 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mdbook-iced" 3 | version = "0.2.0" 4 | edition = "2021" 5 | license = "MIT" 6 | description = "An mdBook preprocessor to turn iced code blocks into interactive examples" 7 | repository = "https://github.com/iced-rs/mdbook-iced" 8 | authors = ["Héctor Ramón Jiménez "] 9 | readme = "README.md" 10 | keywords = ["book", "mdbook", "gui", "iced", "interactive"] 11 | exclude = ["*.gif"] 12 | 13 | [dependencies] 14 | mdbook = "0.4" 15 | semver = "1.0" 16 | toml = "0.5" 17 | serde_json = "1.0" 18 | pulldown-cmark = "0.10" 19 | pulldown-cmark-to-cmark = "13.0" 20 | itertools = "0.12" 21 | sha2 = "0.10" 22 | clap = "4.5" 23 | anyhow = "1.0" 24 | 25 | [[bin]] 26 | name = "mdbook-iced" 27 | doc = false 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Héctor Ramón, Iced contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | # mdbook-iced 6 | 7 | [![Documentation](https://docs.rs/mdbook-iced/badge.svg)](https://docs.rs/mdbook-iced) 8 | [![Crates.io](https://img.shields.io/crates/v/mdbook-iced.svg)](https://crates.io/crates/mdbook-iced) 9 | [![License](https://img.shields.io/crates/l/mdbook-iced.svg)](https://github.com/iced-rs/mdbook-iced/blob/master/LICENSE) 10 | [![Downloads](https://img.shields.io/crates/d/mdbook-iced.svg)](https://crates.io/crates/mdbook-iced) 11 | [![Test Status](https://img.shields.io/github/actions/workflow/status/iced-rs/mdbook-iced/test.yml?branch=master&event=push&label=test)](https://github.com/iced-rs/mdbook-iced/actions) 12 | [![Discourse](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fdiscourse.iced.rs%2Fsite%2Fstatistics.json&query=%24.users_count&suffix=%20users&label=discourse&color=5e7ce2)](https://discourse.iced.rs/) 13 | [![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd) 14 | 15 | An mdBook preprocessor to turn [iced] code blocks into interactive examples. 16 | 17 | An interactive example 18 | 19 |
20 | 21 | ## Overview 22 | This is a simple mdBook preprocessor that can add a play button to any [iced] code block. 23 | 24 | Pressing the play button loads and embeds the resulting Wasm application in a fully interactive `` right under the code block. 25 | 26 | It is compatible with any code block that features a `main` function where an [iced] program is run—even if it is hidden! This means 27 | it can be used to create interactive examples even for books completely unrelated to [iced]. 28 | 29 | Currently, this preprocessor is mainly being used in [the official guide] to [iced]. Check it out! 30 | 31 | ## Installation 32 | Install the `mdbook-iced` preprocessor and the [`wasm-bindgen-cli`] tool with `cargo install`: 33 | 34 | ``` 35 | cargo install mdbook-iced wasm-bindgen-cli 36 | ``` 37 | 38 | Also, make sure your toolchain has the `wasm32-unknown-unknown` target: 39 | 40 | ``` 41 | rustup target add wasm32-unknown-unknown 42 | ``` 43 | 44 | ## Usage 45 | Add a `[preprocessor.iced]` entry to your `book.toml` and specify the revision of `iced` your book will use: 46 | 47 | ```toml 48 | [preprocessor.iced] 49 | # You can use a commit hash 50 | rev = "9db6ac8f202ebdc1453edee01da0b30aee0949d8" 51 | # ... a branch 52 | branch = "master" 53 | # ... or a tag! 54 | tag = "0.13.0" # Not yet released! 55 | ``` 56 | 57 | Then, simply add an `iced` label to any executable code block you want to make playable. For instance, the 58 | classical counter: 59 | 60 | ````markdown 61 | # A cool example 62 | 63 | This is an mdBook and here is an iced counter: 64 | 65 | ```rust,ignore,iced 66 | use iced::widget::{button, column, text, Column}; 67 | 68 | pub fn main() -> iced::Result { 69 | iced::run("A counter", update, view) 70 | } 71 | 72 | #[derive(Debug, Clone)] 73 | enum Message { 74 | Increment, 75 | } 76 | 77 | fn update(value: &mut u64, message: Message) { 78 | match message { 79 | Message::Increment => *value += 1, 80 | } 81 | } 82 | 83 | fn view(value: &u64) -> Column { 84 | column![ 85 | text(value), 86 | button("+").on_press(Message::Increment), 87 | ] 88 | } 89 | ``` 90 | ```` 91 | 92 | You can control the height of the embedded application by using `iced(height=)` as a label (e.g. `iced(height=100px)`). 93 | 94 | Check out the [`book`](book) directory for a real mdBook example! 95 | 96 | [iced]: https://github.com/iced-rs/iced 97 | [`wasm-bindgen-cli`]: https://rustwasm.github.io/wasm-bindgen/reference/cli.html 98 | [the official guide]: https://book.iced.rs/ 99 | -------------------------------------------------------------------------------- /book/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | target 3 | .icebergs 4 | -------------------------------------------------------------------------------- /book/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Héctor Ramón Jiménez"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "mdbook-iced" 7 | 8 | [preprocessor.iced] 9 | rev = "441e9237cd1c9c9b61d9b144b5b4dafa236ace28" 10 | -------------------------------------------------------------------------------- /book/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Guide](./guide.md) 4 | -------------------------------------------------------------------------------- /book/src/assets/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iced-rs/mdbook-iced/8436a786b69710bfc7dda47213f0c53a0bf6abb2/book/src/assets/example.gif -------------------------------------------------------------------------------- /book/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /book/src/guide.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | # mdbook-iced 6 | 7 | [![Documentation](https://docs.rs/mdbook-iced/badge.svg)](https://docs.rs/mdbook-iced) 8 | [![Crates.io](https://img.shields.io/crates/v/mdbook-iced.svg)](https://crates.io/crates/mdbook-iced) 9 | [![License](https://img.shields.io/crates/l/mdbook-iced.svg)](https://github.com/iced-rs/mdbook-iced/blob/master/LICENSE) 10 | [![Downloads](https://img.shields.io/crates/d/mdbook-iced.svg)](https://crates.io/crates/mdbook-iced) 11 | [![Test Status](https://img.shields.io/github/actions/workflow/status/iced-rs/mdbook-iced/test.yml?branch=master&event=push&label=test)](https://github.com/iced-rs/mdbook-iced/actions) 12 | [![Discourse](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fdiscourse.iced.rs%2Fsite%2Fstatistics.json&query=%24.users_count&suffix=%20users&label=discourse&color=5e7ce2)](https://discourse.iced.rs/) 13 | [![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd) 14 | 15 | An mdBook preprocessor to turn [iced] code blocks into interactive examples. 16 | 17 | An interactive example 18 | 19 |
20 | 21 | ## Overview 22 | This is a simple mdBook preprocessor that can add a play button to any [iced] code block. 23 | 24 | Pressing the play button loads and embeds the resulting Wasm application in a fully interactive `` right under the code block. 25 | 26 | It is compatible with any code block that features a `main` function where an [iced] program is run—even if it is hidden! This means 27 | it can be used to create interactive examples even for books completely unrelated to [iced]. 28 | 29 | Currently, this preprocessor is mainly being used in [the official guide] to [iced]. Check it out! 30 | 31 | ## Installation 32 | Install the `mdbook-iced` preprocessor and the [`wasm-bindgen-cli`] tool with `cargo install`: 33 | 34 | ``` 35 | cargo install mdbook-iced wasm-bindgen-cli 36 | ``` 37 | 38 | Also, make sure your toolchain has the `wasm32-unknown-unknown` target: 39 | 40 | ``` 41 | rustup target add wasm32-unknown-unknown 42 | ``` 43 | 44 | ## Usage 45 | Add a `[preprocessor.iced]` entry to your `book.toml` and specify the revision of `iced` your book will use: 46 | 47 | ```toml 48 | [preprocessor.iced] 49 | # You can use a commit hash 50 | rev = "9db6ac8f202ebdc1453edee01da0b30aee0949d8" 51 | # ... a branch 52 | branch = "master" 53 | # ... or a tag! 54 | tag = "0.13.0" # Not yet released! 55 | ``` 56 | 57 | Then, simply add an `iced` label to any executable code block you want to make playable. For instance, the 58 | classical counter: 59 | 60 | ````markdown 61 | # A cool example 62 | 63 | This is an mdBook and here is an iced counter: 64 | 65 | ```rust,ignore,iced 66 | # use iced::widget::{button, column, text, Column}; 67 | # 68 | pub fn main() -> iced::Result { 69 | iced::run("A counter", update, view) 70 | } 71 | # 72 | # #[derive(Debug, Clone)] 73 | # enum Message { 74 | # Increment, 75 | # } 76 | # 77 | # fn update(value: &mut u64, message: Message) { 78 | # match message { 79 | # Message::Increment => *value += 1, 80 | # } 81 | # } 82 | # 83 | # fn view(value: &u64) -> Column { 84 | # column![ 85 | # text(value), 86 | # button("+").on_press(Message::Increment), 87 | # ] 88 | # } 89 | ``` 90 | ```` 91 | 92 | This produces the following code block: 93 | 94 | ```rust,ignore,iced 95 | # use iced::widget::{button, column, text, Column}; 96 | # 97 | pub fn main() -> iced::Result { 98 | iced::run("A counter", update, view) 99 | } 100 | # 101 | # #[derive(Debug, Clone)] 102 | # enum Message { 103 | # Increment, 104 | # } 105 | # 106 | # fn update(value: &mut u64, message: Message) { 107 | # match message { 108 | # Message::Increment => *value += 1, 109 | # } 110 | # } 111 | # 112 | # fn view(value: &u64) -> Column { 113 | # column![ 114 | # text(value), 115 | # button("+").on_press(Message::Increment), 116 | # ] 117 | # } 118 | ``` 119 | 120 | You can control the height of the embedded application by using `iced(height=)` as a label (e.g. `iced(height=100px)`). 121 | For instance: 122 | 123 | ```rust,ignore,iced(height=100px) 124 | # use iced::widget::{button, column, text, Column}; 125 | # 126 | pub fn main() -> iced::Result { 127 | iced::run("A counter", update, view) 128 | } 129 | # 130 | # #[derive(Debug, Clone)] 131 | # enum Message { 132 | # Decrement, 133 | # } 134 | # 135 | # fn update(value: &mut i64, message: Message) { 136 | # match message { 137 | # Message::Decrement => *value -= 1, 138 | # } 139 | # } 140 | # 141 | # fn view(value: &i64) -> Column { 142 | # column![ 143 | # text(value), 144 | # button("-").on_press(Message::Decrement), 145 | # ] 146 | # } 147 | ``` 148 | 149 | [iced]: https://github.com/iced-rs/iced 150 | [`wasm-bindgen-cli`]: https://rustwasm.github.io/wasm-bindgen/reference/cli.html 151 | [the official guide]: https://book.iced.rs/ 152 | 153 | -------------------------------------------------------------------------------- /src/bin/mdbook-iced.rs: -------------------------------------------------------------------------------- 1 | use mdbook_iced::{clean, is_supported, run}; 2 | 3 | use clap::{Arg, Command}; 4 | use mdbook::errors::Error; 5 | use mdbook::preprocess::CmdPreprocessor; 6 | 7 | use std::io; 8 | use std::path::PathBuf; 9 | use std::process; 10 | 11 | fn main() -> Result<(), Error> { 12 | let command = Command::new("mdbook-iced") 13 | .about("An mdBook preprocessor to turn iced code blocks into interactive examples.") 14 | .subcommand( 15 | Command::new("supports") 16 | .arg(Arg::new("renderer").required(true)) 17 | .about("Check whether a renderer is supported by this preprocessor."), 18 | ) 19 | .subcommand(Command::new("clean").about( 20 | "Cleans the artifacts and binaries produced by this preprocessor in the current book.", 21 | )); 22 | 23 | let matches = command.get_matches(); 24 | 25 | if let Some(sub_args) = matches.subcommand_matches("supports") { 26 | let renderer = sub_args 27 | .get_one::("renderer") 28 | .expect("Required argument"); 29 | 30 | if !is_supported(renderer) { 31 | process::exit(1); 32 | } 33 | 34 | process::exit(0); 35 | } 36 | 37 | if matches.subcommand_matches("clean").is_some() { 38 | clean(PathBuf::new())?; 39 | 40 | process::exit(0); 41 | } 42 | 43 | let (context, book) = CmdPreprocessor::parse_input(io::stdin())?; 44 | 45 | let processed_book = run(book, &context)?; 46 | serde_json::to_writer(io::stdout(), &processed_book)?; 47 | 48 | Ok(()) 49 | } 50 | -------------------------------------------------------------------------------- /src/compiler.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Error; 2 | 3 | use std::collections::BTreeSet; 4 | use std::fs; 5 | use std::path::{Path, PathBuf}; 6 | use std::process; 7 | use std::sync::atomic::{self, AtomicU64}; 8 | 9 | #[derive(Debug, Clone, PartialEq, Eq)] 10 | pub struct Compiler { 11 | build: PathBuf, 12 | src: PathBuf, 13 | artifacts: PathBuf, 14 | hash: u64, 15 | } 16 | 17 | impl Compiler { 18 | pub fn set_up(root: impl AsRef, reference: Reference) -> Result { 19 | const CARGO_TOML: &str = include_str!("compiler/Cargo.toml.template"); 20 | 21 | let build = root.as_ref().join("target").join("icebergs"); 22 | fs::create_dir_all(&build)?; 23 | 24 | let src = build.join("src"); 25 | fs::create_dir_all(&src)?; 26 | 27 | let artifacts = build.join("target").join("mdbook"); 28 | fs::create_dir_all(&artifacts)?; 29 | 30 | let cargo_config = CARGO_TOML.replace( 31 | "{{ GIT_REFERENCE }}", 32 | &match reference { 33 | Reference::Revision(revision) => format!("rev = \"{revision}\""), 34 | Reference::Branch(branch) => format!("branch = \"{branch}\""), 35 | Reference::Tag(tag) => format!("tag = \"{tag}\""), 36 | }, 37 | ); 38 | fs::write(build.join("Cargo.toml"), cargo_config.trim_start())?; 39 | 40 | let gitignore = root.as_ref().join(".gitignore"); 41 | if let Ok(mut ignored) = fs::read_to_string(&gitignore) { 42 | if !ignored.ends_with('\n') { 43 | ignored.push('\n'); 44 | } 45 | 46 | if !ignored.lines().any(|line| line == "target") { 47 | ignored.push_str("target\n"); 48 | } 49 | 50 | if !ignored.lines().any(|line| line == ".icebergs") { 51 | ignored.push_str(".icebergs\n"); 52 | } 53 | 54 | fs::write(gitignore, ignored)?; 55 | } 56 | 57 | let hash = { 58 | use std::hash::{DefaultHasher, Hash, Hasher}; 59 | 60 | let mut hasher = DefaultHasher::new(); 61 | cargo_config.hash(&mut hasher); 62 | hasher.finish() 63 | }; 64 | 65 | Ok(Self { 66 | build, 67 | src, 68 | artifacts, 69 | hash, 70 | }) 71 | } 72 | 73 | pub fn compile(&self, code: &str) -> Result { 74 | use itertools::Itertools; 75 | use sha2::{Digest, Sha256}; 76 | 77 | let code = code 78 | .lines() 79 | .filter(|&line| line != "#") 80 | .map(|line| line.strip_prefix("# ").unwrap_or(line)) 81 | .join("\n"); 82 | 83 | let hash = Hash( 84 | Sha256::digest(format!("{code}{}", self.hash)) 85 | .into_iter() 86 | .map(|byte| format!("{byte:x}")) 87 | .join(""), 88 | ); 89 | 90 | let artifact_dir = self.artifacts.join(hash.as_str()); 91 | 92 | if artifact_dir.exists() { 93 | return Ok(Iceberg { hash }); 94 | } 95 | 96 | fs::write(self.src.join("main.rs"), code)?; 97 | 98 | let compilation = process::Command::new("cargo") 99 | .args(["build", "--release", "--target", "wasm32-unknown-unknown"]) 100 | .env("RUSTFLAGS", "") 101 | .current_dir(&self.build) 102 | .stdout(process::Stdio::piped()) 103 | .spawn()?; 104 | 105 | std::io::copy( 106 | &mut std::io::BufReader::new(compilation.stdout.expect("Open compilation output")), 107 | &mut std::io::stderr(), 108 | )?; 109 | 110 | process::Command::new("wasm-bindgen") 111 | .args([ 112 | "--target", 113 | "web", 114 | "--no-typescript", 115 | "--out-dir", 116 | artifact_dir.to_str().expect("valid artifact path"), 117 | "target/wasm32-unknown-unknown/release/iceberg.wasm", 118 | ]) 119 | .current_dir(&self.build) 120 | .spawn()? 121 | .wait()?; 122 | 123 | Ok(Iceberg { hash }) 124 | } 125 | 126 | pub fn retain(&self, icebergs: &BTreeSet) -> Result<(), Error> { 127 | clean_dir(&self.artifacts, icebergs)?; 128 | 129 | Ok(()) 130 | } 131 | 132 | pub fn release( 133 | &self, 134 | icebergs: &BTreeSet, 135 | target: impl AsRef, 136 | ) -> Result<(), Error> { 137 | let target = target.as_ref(); 138 | clean_dir(target, icebergs)?; 139 | 140 | for iceberg in icebergs { 141 | let output = target.join(iceberg.hash.as_str()); 142 | 143 | if !output.exists() { 144 | let artifact = self.artifacts.join(iceberg.hash.as_str()); 145 | 146 | copy_dir_all(artifact, output)?; 147 | } 148 | } 149 | 150 | Ok(()) 151 | } 152 | 153 | pub fn clean(root: impl AsRef) -> Result<(), Error> { 154 | let build = root.as_ref().join("target").join("icebergs"); 155 | fs::remove_dir_all(build)?; 156 | 157 | Ok(()) 158 | } 159 | } 160 | 161 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 162 | pub struct Iceberg { 163 | hash: Hash, 164 | } 165 | 166 | impl Iceberg { 167 | pub const LIBRARY: &'static str = include_str!("compiler/library.html"); 168 | pub const EMBED: &'static str = include_str!("compiler/embed.html"); 169 | 170 | pub fn embed(&self, height: Option<&str>) -> String { 171 | static COUNT: AtomicU64 = AtomicU64::new(0); 172 | 173 | Self::EMBED 174 | .replace("{{ HASH }}", self.hash.as_str()) 175 | .replace( 176 | "{{ ID }}", 177 | &COUNT.fetch_add(1, atomic::Ordering::Relaxed).to_string(), 178 | ) 179 | .replace("{{ HEIGHT }}", height.unwrap_or("200px")) 180 | } 181 | } 182 | 183 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] 184 | pub enum Reference { 185 | Revision(String), 186 | Branch(String), 187 | Tag(String), 188 | } 189 | 190 | impl Reference { 191 | pub fn parse(table: &toml::value::Table) -> Result { 192 | if let Some(toml::Value::String(revision)) = table.get("rev") { 193 | return Ok(Self::Revision(revision.clone())); 194 | } 195 | 196 | if let Some(toml::Value::String(branch)) = table.get("branch") { 197 | return Ok(Self::Branch(branch.clone())); 198 | } 199 | 200 | if let Some(toml::Value::String(tag)) = table.get("tag") { 201 | return Ok(Self::Tag(tag.clone())); 202 | } 203 | 204 | Err(Error::msg( 205 | "No Git reference found for `iced` in the preprocessor configuration. \ 206 | Please, specify a `rev`, `branch` or `tag`.", 207 | )) 208 | } 209 | } 210 | 211 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 212 | pub struct Hash(String); 213 | 214 | impl Hash { 215 | fn as_str(&self) -> &str { 216 | &self.0 217 | } 218 | } 219 | 220 | fn clean_dir(dir: impl AsRef, icebergs: &BTreeSet) -> Result<(), Error> { 221 | let deleted = fs::read_dir(dir)? 222 | .filter_map(|entry| entry.ok()) 223 | .filter(|entry| { 224 | !icebergs 225 | .iter() 226 | .any(|iceberg| iceberg.hash.as_str() == entry.file_name()) 227 | }); 228 | 229 | for entry in deleted { 230 | fs::remove_dir_all(entry.path())?; 231 | } 232 | 233 | Ok(()) 234 | } 235 | 236 | fn copy_dir_all(from: impl AsRef, to: impl AsRef) -> Result<(), Error> { 237 | fs::create_dir_all(&to)?; 238 | 239 | for entry in fs::read_dir(from)? { 240 | let entry = entry?; 241 | let target = to.as_ref().join(entry.file_name()); 242 | 243 | if entry.file_type()?.is_dir() { 244 | copy_dir_all(entry.path(), target)?; 245 | } else if !target.exists() { 246 | fs::copy(entry.path(), target)?; 247 | } 248 | } 249 | 250 | Ok(()) 251 | } 252 | -------------------------------------------------------------------------------- /src/compiler/Cargo.toml.template: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "iceberg" 3 | version = "0.0.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [dependencies.iced] 8 | git = "https://github.com/iced-rs/iced.git" 9 | {{ GIT_REFERENCE }} 10 | default-features = false 11 | features = ["wgpu", "webgl", "web-colors", "fira-sans", "auto-detect-theme"] 12 | -------------------------------------------------------------------------------- /src/compiler/embed.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/compiler/library.html: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod compiler; 2 | 3 | use compiler::Compiler; 4 | 5 | use anyhow::Error; 6 | use mdbook::book::{Book, BookItem, Chapter}; 7 | use mdbook::preprocess::PreprocessorContext; 8 | use semver::{Version, VersionReq}; 9 | 10 | use std::collections::BTreeSet; 11 | use std::fs; 12 | use std::path::Path; 13 | 14 | pub fn is_supported(renderer: &str) -> bool { 15 | renderer == "html" 16 | } 17 | 18 | pub fn run(mut book: Book, context: &PreprocessorContext) -> Result { 19 | let book_version = Version::parse(&context.mdbook_version)?; 20 | let version_req = VersionReq::parse(mdbook::MDBOOK_VERSION)?; 21 | 22 | if !version_req.matches(&book_version) { 23 | return Err(Error::msg(format!( 24 | "mdbook-iced plugin version ({}) is not compatible \ 25 | with the book version ({})", 26 | mdbook::MDBOOK_VERSION, 27 | context.mdbook_version 28 | ))); 29 | } 30 | 31 | let config = context 32 | .config 33 | .get_preprocessor("iced") 34 | .ok_or(Error::msg("mdbook-iced configuration not found"))?; 35 | 36 | let reference = compiler::Reference::parse(config)?; 37 | let compiler = Compiler::set_up(&context.root, reference)?; 38 | 39 | let mut icebergs = BTreeSet::new(); 40 | 41 | for section in &mut book.sections { 42 | if let BookItem::Chapter(chapter) = section { 43 | let (content, new_icebergs) = process_chapter(&compiler, chapter)?; 44 | 45 | chapter.content = content; 46 | icebergs.extend(new_icebergs); 47 | } 48 | } 49 | 50 | let target = context.root.join("src").join(".icebergs"); 51 | fs::create_dir_all(&target)?; 52 | 53 | compiler.retain(&icebergs)?; 54 | compiler.release(&icebergs, target)?; 55 | 56 | Ok(book) 57 | } 58 | 59 | fn process_chapter( 60 | compiler: &Compiler, 61 | chapter: &Chapter, 62 | ) -> Result<(String, BTreeSet), Error> { 63 | use itertools::Itertools; 64 | use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag, TagEnd}; 65 | use pulldown_cmark_to_cmark::cmark; 66 | 67 | let events = Parser::new_ext(&chapter.content, Options::all()); 68 | 69 | let mut in_iced_code = false; 70 | 71 | let groups = events.group_by(|event| match event { 72 | Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(label))) 73 | if label.starts_with("rust") 74 | && label 75 | .split(',') 76 | .any(|modifier| modifier.starts_with("iced")) => 77 | { 78 | in_iced_code = true; 79 | true 80 | } 81 | Event::End(TagEnd::CodeBlock) => { 82 | let is_iced_code = in_iced_code; 83 | 84 | in_iced_code = false; 85 | 86 | is_iced_code 87 | } 88 | _ => in_iced_code, 89 | }); 90 | 91 | let mut icebergs = Vec::new(); 92 | let mut heights = Vec::new(); 93 | let mut is_first = true; 94 | 95 | let output = groups.into_iter().flat_map(|(is_iced_code, group)| { 96 | if is_iced_code { 97 | let mut events = Vec::new(); 98 | let mut code = String::new(); 99 | 100 | for event in group { 101 | if let Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(label))) = &event { 102 | let height = label 103 | .split(',') 104 | .find(|modifier| modifier.starts_with("iced")) 105 | .and_then(|modifier| { 106 | Some( 107 | modifier 108 | .strip_prefix("iced(")? 109 | .strip_suffix(')')? 110 | .split_once("height=")? 111 | .1 112 | .to_string(), 113 | ) 114 | }); 115 | 116 | code.clear(); 117 | icebergs.push(None); 118 | heights.push(height); 119 | events.push(event); 120 | } else if let Event::Text(text) = &event { 121 | if !code.ends_with('\n') { 122 | code.push('\n'); 123 | } 124 | 125 | code.push_str(text); 126 | events.push(event); 127 | } else if let Event::End(TagEnd::CodeBlock) = &event { 128 | events.push(event); 129 | 130 | if let Ok(iceberg) = compiler.compile(&code) { 131 | if let Some(last_iceberg) = icebergs.last_mut() { 132 | *last_iceberg = Some(iceberg); 133 | } 134 | } 135 | 136 | if is_first { 137 | is_first = false; 138 | 139 | events.push(Event::InlineHtml(compiler::Iceberg::LIBRARY.into())); 140 | } 141 | 142 | if let Some(iceberg) = icebergs.last().and_then(Option::as_ref) { 143 | events.push(Event::InlineHtml( 144 | iceberg 145 | .embed(heights.last().and_then(Option::as_deref)) 146 | .into(), 147 | )); 148 | } 149 | } else { 150 | events.push(event); 151 | } 152 | } 153 | 154 | Box::new(events.into_iter()) 155 | } else { 156 | Box::new(group) as Box> 157 | } 158 | }); 159 | 160 | let mut content = String::with_capacity(chapter.content.len()); 161 | let _ = cmark(output, &mut content)?; 162 | 163 | Ok((content, icebergs.into_iter().flatten().collect())) 164 | } 165 | 166 | pub fn clean(root: impl AsRef) -> Result<(), Error> { 167 | let book_toml = root.as_ref().join("book.toml"); 168 | if !book_toml.exists() { 169 | return Err(Error::msg( 170 | "book.toml not found in the current directory. This command \ 171 | can only be run in an mdBook project.", 172 | )); 173 | } 174 | 175 | let output = root.as_ref().join("src").join(".icebergs"); 176 | fs::remove_dir_all(output)?; 177 | 178 | Compiler::clean(root)?; 179 | 180 | Ok(()) 181 | } 182 | --------------------------------------------------------------------------------