├── .github ├── dependabot.yml └── workflows │ ├── check.yml │ ├── release-plz.yml │ └── test.yml ├── .gitignore ├── .markdownlint.yaml ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── demo.tape ├── markdown-reader ├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── README.md ├── TEST.md └── src │ ├── app.rs │ ├── events.rs │ ├── logging.rs │ └── main.rs ├── rustfmt.toml └── tui-markdown ├── CHANGELOG.md ├── Cargo.toml ├── README.md └── src ├── lib.rs └── snapshots ├── tui_markdown__tests__highlighted_code-2.snap ├── tui_markdown__tests__highlighted_code.snap ├── tui_markdown__tests__highlighted_code_with_indentation-2.snap ├── tui_markdown__tests__highlighted_code_with_indentation.snap ├── tui_markdown__tests__inline_code.snap ├── tui_markdown__tests__unhighlighted_code-2.snap └── tui_markdown__tests__unhighlighted_code.snap /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "cargo" # See documentation for possible values 13 | directory: "/" # Location of package manifests 14 | schedule: 15 | interval: "weekly" 16 | groups: 17 | cargo-dependencies: 18 | patterns: ["*"] 19 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: Check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | check: 11 | permissions: 12 | checks: write 13 | uses: joshka/github-workflows/.github/workflows/rust-check.yml@main 14 | with: 15 | msrv: 1.82.0 16 | -------------------------------------------------------------------------------- /.github/workflows/release-plz.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | permissions: 4 | pull-requests: write 5 | contents: write 6 | 7 | on: 8 | workflow_dispatch: 9 | push: 10 | branches: 11 | - main 12 | 13 | jobs: 14 | release-plz: 15 | uses: joshka/github-workflows/.github/workflows/rust-release-plz.yml@main 16 | permissions: 17 | pull-requests: write 18 | contents: write 19 | secrets: 20 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | uses: joshka/github-workflows/.github/workflows/rust-test.yml@main 12 | secrets: 13 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | no-inline-html: 2 | allowed_elements: 3 | - br 4 | - details 5 | - summary 6 | line-length: 7 | line_length: 100 8 | heading_line_length: 100 9 | code_block_line_length: 100 10 | code_blocks: true 11 | tables: true 12 | headings: true 13 | strict: false 14 | stern: false 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.cargo.features": "all" 3 | } 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution guidelines 2 | 3 | First off, thank you for considering contributing to tui-markdown / markdown-reader. 4 | 5 | If your contribution is not straightforward, please first discuss the change you 6 | wish to make by creating a new issue before making the change. 7 | 8 | ## Reporting issues 9 | 10 | Before reporting an issue on the 11 | [issue tracker](https://github.com/joshka/tui-markdown/issues), 12 | please check that it has not already been reported by searching for some related 13 | keywords. 14 | 15 | ## Pull requests 16 | 17 | Try to do one pull request per change. 18 | 19 | ## Commit Message Format 20 | 21 | This project adheres to [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). 22 | A specification for adding human and machine readable meaning to commit messages. 23 | 24 | ### Commit Message Header 25 | 26 | ``` 27 | (): 28 | │ │ │ 29 | │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end. 30 | │ │ 31 | │ └─⫸ Commit Scope 32 | │ 33 | └─⫸ Commit Type: feat|fix|build|ci|docs|perf|refactor|test|chore 34 | ``` 35 | 36 | #### Type 37 | 38 | | feat | Features | A new feature | 39 | |----------|--------------------------|--------------------------------------------------------------------------------------------------------| 40 | | fix | Bug Fixes | A bug fix | 41 | | docs | Documentation | Documentation only changes | 42 | | style | Styles | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) | 43 | | refactor | Code Refactoring | A code change that neither fixes a bug nor adds a feature | 44 | | perf | Performance Improvements | A code change that improves performance | 45 | | test | Tests | Adding missing tests or correcting existing tests | 46 | | build | Builds | Changes that affect the build system or external dependencies (example scopes: main, serde) | 47 | | ci | Continuous Integrations | Changes to our CI configuration files and scripts (example scopes: Github Actions) | 48 | | chore | Chores | Other changes that don't modify src or test files | 49 | | revert | Reverts | Reverts a previous commit | 50 | 51 | ## Developing 52 | 53 | ### Set up 54 | 55 | This is no different than other Rust projects. 56 | 57 | ```shell 58 | git clone https://github.com/joshka/tui-markdown 59 | cd tui-markdown 60 | cargo test 61 | ``` 62 | 63 | ### Useful Commands 64 | 65 | - Run Clippy: 66 | 67 | ```shell 68 | cargo clippy --all-targets --all-features --workspace 69 | ``` 70 | 71 | - Run all tests: 72 | 73 | ```shell 74 | cargo test --all-features --workspace 75 | ``` 76 | 77 | - Check to see if there are code formatting issues 78 | 79 | ```shell 80 | cargo fmt --all -- --check 81 | ``` 82 | 83 | - Format the code in the project 84 | 85 | ```shell 86 | cargo fmt --all 87 | ``` 88 | -------------------------------------------------------------------------------- /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.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 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 = "allocator-api2" 31 | version = "0.2.21" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 34 | 35 | [[package]] 36 | name = "ansi-to-tui" 37 | version = "7.0.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "67555e1f1ece39d737e28c8a017721287753af3f93225e4a445b29ccb0f5912c" 40 | dependencies = [ 41 | "nom", 42 | "ratatui", 43 | "simdutf8", 44 | "smallvec", 45 | "thiserror", 46 | ] 47 | 48 | [[package]] 49 | name = "anstream" 50 | version = "0.6.18" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 53 | dependencies = [ 54 | "anstyle", 55 | "anstyle-parse", 56 | "anstyle-query", 57 | "anstyle-wincon", 58 | "colorchoice", 59 | "is_terminal_polyfill", 60 | "utf8parse", 61 | ] 62 | 63 | [[package]] 64 | name = "anstyle" 65 | version = "1.0.10" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 68 | 69 | [[package]] 70 | name = "anstyle-parse" 71 | version = "0.2.6" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 74 | dependencies = [ 75 | "utf8parse", 76 | ] 77 | 78 | [[package]] 79 | name = "anstyle-query" 80 | version = "1.1.2" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 83 | dependencies = [ 84 | "windows-sys 0.59.0", 85 | ] 86 | 87 | [[package]] 88 | name = "anstyle-wincon" 89 | version = "3.0.7" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 92 | dependencies = [ 93 | "anstyle", 94 | "once_cell", 95 | "windows-sys 0.59.0", 96 | ] 97 | 98 | [[package]] 99 | name = "autocfg" 100 | version = "1.4.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 103 | 104 | [[package]] 105 | name = "backtrace" 106 | version = "0.3.75" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 109 | dependencies = [ 110 | "addr2line", 111 | "cfg-if", 112 | "libc", 113 | "miniz_oxide", 114 | "object", 115 | "rustc-demangle", 116 | "windows-targets", 117 | ] 118 | 119 | [[package]] 120 | name = "base64" 121 | version = "0.22.1" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 124 | 125 | [[package]] 126 | name = "bincode" 127 | version = "1.3.3" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 130 | dependencies = [ 131 | "serde", 132 | ] 133 | 134 | [[package]] 135 | name = "bitflags" 136 | version = "1.3.2" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 139 | 140 | [[package]] 141 | name = "bitflags" 142 | version = "2.9.0" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 145 | 146 | [[package]] 147 | name = "cassowary" 148 | version = "0.3.0" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" 151 | 152 | [[package]] 153 | name = "castaway" 154 | version = "0.2.3" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" 157 | dependencies = [ 158 | "rustversion", 159 | ] 160 | 161 | [[package]] 162 | name = "cc" 163 | version = "1.2.21" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" 166 | dependencies = [ 167 | "shlex", 168 | ] 169 | 170 | [[package]] 171 | name = "cfg-if" 172 | version = "1.0.0" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 175 | 176 | [[package]] 177 | name = "clap" 178 | version = "4.5.37" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" 181 | dependencies = [ 182 | "clap_builder", 183 | "clap_derive", 184 | ] 185 | 186 | [[package]] 187 | name = "clap_builder" 188 | version = "4.5.37" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" 191 | dependencies = [ 192 | "anstream", 193 | "anstyle", 194 | "clap_lex", 195 | "strsim", 196 | ] 197 | 198 | [[package]] 199 | name = "clap_derive" 200 | version = "4.5.32" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" 203 | dependencies = [ 204 | "heck", 205 | "proc-macro2", 206 | "quote", 207 | "syn", 208 | ] 209 | 210 | [[package]] 211 | name = "clap_lex" 212 | version = "0.7.4" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 215 | 216 | [[package]] 217 | name = "color-eyre" 218 | version = "0.6.4" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "e6e1761c0e16f8883bbbb8ce5990867f4f06bf11a0253da6495a04ce4b6ef0ec" 221 | dependencies = [ 222 | "backtrace", 223 | "color-spantrace", 224 | "eyre", 225 | "indenter", 226 | "once_cell", 227 | "owo-colors", 228 | "tracing-error", 229 | ] 230 | 231 | [[package]] 232 | name = "color-spantrace" 233 | version = "0.2.2" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "2ddd8d5bfda1e11a501d0a7303f3bfed9aa632ebdb859be40d0fd70478ed70d5" 236 | dependencies = [ 237 | "once_cell", 238 | "owo-colors", 239 | "tracing-core", 240 | "tracing-error", 241 | ] 242 | 243 | [[package]] 244 | name = "colorchoice" 245 | version = "1.0.3" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 248 | 249 | [[package]] 250 | name = "compact_str" 251 | version = "0.8.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" 254 | dependencies = [ 255 | "castaway", 256 | "cfg-if", 257 | "itoa", 258 | "rustversion", 259 | "ryu", 260 | "static_assertions", 261 | ] 262 | 263 | [[package]] 264 | name = "console" 265 | version = "0.15.11" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" 268 | dependencies = [ 269 | "encode_unicode", 270 | "libc", 271 | "once_cell", 272 | "windows-sys 0.59.0", 273 | ] 274 | 275 | [[package]] 276 | name = "convert_case" 277 | version = "0.7.1" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" 280 | dependencies = [ 281 | "unicode-segmentation", 282 | ] 283 | 284 | [[package]] 285 | name = "crc32fast" 286 | version = "1.4.2" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 289 | dependencies = [ 290 | "cfg-if", 291 | ] 292 | 293 | [[package]] 294 | name = "crossterm" 295 | version = "0.28.1" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" 298 | dependencies = [ 299 | "bitflags 2.9.0", 300 | "crossterm_winapi", 301 | "mio", 302 | "parking_lot", 303 | "rustix 0.38.44", 304 | "signal-hook", 305 | "signal-hook-mio", 306 | "winapi", 307 | ] 308 | 309 | [[package]] 310 | name = "crossterm" 311 | version = "0.29.0" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" 314 | dependencies = [ 315 | "bitflags 2.9.0", 316 | "crossterm_winapi", 317 | "derive_more", 318 | "document-features", 319 | "mio", 320 | "parking_lot", 321 | "rustix 1.0.7", 322 | "signal-hook", 323 | "signal-hook-mio", 324 | "winapi", 325 | ] 326 | 327 | [[package]] 328 | name = "crossterm_winapi" 329 | version = "0.9.1" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 332 | dependencies = [ 333 | "winapi", 334 | ] 335 | 336 | [[package]] 337 | name = "darling" 338 | version = "0.20.11" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 341 | dependencies = [ 342 | "darling_core", 343 | "darling_macro", 344 | ] 345 | 346 | [[package]] 347 | name = "darling_core" 348 | version = "0.20.11" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 351 | dependencies = [ 352 | "fnv", 353 | "ident_case", 354 | "proc-macro2", 355 | "quote", 356 | "strsim", 357 | "syn", 358 | ] 359 | 360 | [[package]] 361 | name = "darling_macro" 362 | version = "0.20.11" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 365 | dependencies = [ 366 | "darling_core", 367 | "quote", 368 | "syn", 369 | ] 370 | 371 | [[package]] 372 | name = "deranged" 373 | version = "0.4.0" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" 376 | dependencies = [ 377 | "powerfmt", 378 | ] 379 | 380 | [[package]] 381 | name = "derive_more" 382 | version = "2.0.1" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" 385 | dependencies = [ 386 | "derive_more-impl", 387 | ] 388 | 389 | [[package]] 390 | name = "derive_more-impl" 391 | version = "2.0.1" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" 394 | dependencies = [ 395 | "convert_case", 396 | "proc-macro2", 397 | "quote", 398 | "syn", 399 | ] 400 | 401 | [[package]] 402 | name = "diff" 403 | version = "0.1.13" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" 406 | 407 | [[package]] 408 | name = "document-features" 409 | version = "0.2.11" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" 412 | dependencies = [ 413 | "litrs", 414 | ] 415 | 416 | [[package]] 417 | name = "either" 418 | version = "1.15.0" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 421 | 422 | [[package]] 423 | name = "encode_unicode" 424 | version = "1.0.0" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" 427 | 428 | [[package]] 429 | name = "equivalent" 430 | version = "1.0.2" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 433 | 434 | [[package]] 435 | name = "errno" 436 | version = "0.3.11" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" 439 | dependencies = [ 440 | "libc", 441 | "windows-sys 0.59.0", 442 | ] 443 | 444 | [[package]] 445 | name = "eyre" 446 | version = "0.6.12" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" 449 | dependencies = [ 450 | "indenter", 451 | "once_cell", 452 | ] 453 | 454 | [[package]] 455 | name = "flate2" 456 | version = "1.1.1" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" 459 | dependencies = [ 460 | "crc32fast", 461 | "miniz_oxide", 462 | ] 463 | 464 | [[package]] 465 | name = "fnv" 466 | version = "1.0.7" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 469 | 470 | [[package]] 471 | name = "foldhash" 472 | version = "0.1.5" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" 475 | 476 | [[package]] 477 | name = "futures-core" 478 | version = "0.3.31" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 481 | 482 | [[package]] 483 | name = "futures-macro" 484 | version = "0.3.31" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 487 | dependencies = [ 488 | "proc-macro2", 489 | "quote", 490 | "syn", 491 | ] 492 | 493 | [[package]] 494 | name = "futures-task" 495 | version = "0.3.31" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 498 | 499 | [[package]] 500 | name = "futures-timer" 501 | version = "3.0.3" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" 504 | 505 | [[package]] 506 | name = "futures-util" 507 | version = "0.3.31" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 510 | dependencies = [ 511 | "futures-core", 512 | "futures-macro", 513 | "futures-task", 514 | "pin-project-lite", 515 | "pin-utils", 516 | "slab", 517 | ] 518 | 519 | [[package]] 520 | name = "getopts" 521 | version = "0.2.21" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" 524 | dependencies = [ 525 | "unicode-width 0.1.14", 526 | ] 527 | 528 | [[package]] 529 | name = "gimli" 530 | version = "0.31.1" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 533 | 534 | [[package]] 535 | name = "glob" 536 | version = "0.3.2" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 539 | 540 | [[package]] 541 | name = "hashbrown" 542 | version = "0.15.3" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" 545 | dependencies = [ 546 | "allocator-api2", 547 | "equivalent", 548 | "foldhash", 549 | ] 550 | 551 | [[package]] 552 | name = "heck" 553 | version = "0.5.0" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 556 | 557 | [[package]] 558 | name = "ident_case" 559 | version = "1.0.1" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 562 | 563 | [[package]] 564 | name = "indenter" 565 | version = "0.3.3" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 568 | 569 | [[package]] 570 | name = "indexmap" 571 | version = "2.9.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" 574 | dependencies = [ 575 | "equivalent", 576 | "hashbrown", 577 | ] 578 | 579 | [[package]] 580 | name = "indoc" 581 | version = "2.0.6" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" 584 | 585 | [[package]] 586 | name = "insta" 587 | version = "1.43.1" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371" 590 | dependencies = [ 591 | "console", 592 | "once_cell", 593 | "similar", 594 | ] 595 | 596 | [[package]] 597 | name = "instability" 598 | version = "0.3.7" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" 601 | dependencies = [ 602 | "darling", 603 | "indoc", 604 | "proc-macro2", 605 | "quote", 606 | "syn", 607 | ] 608 | 609 | [[package]] 610 | name = "is_terminal_polyfill" 611 | version = "1.70.1" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 614 | 615 | [[package]] 616 | name = "itertools" 617 | version = "0.13.0" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" 620 | dependencies = [ 621 | "either", 622 | ] 623 | 624 | [[package]] 625 | name = "itertools" 626 | version = "0.14.0" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" 629 | dependencies = [ 630 | "either", 631 | ] 632 | 633 | [[package]] 634 | name = "itoa" 635 | version = "1.0.15" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 638 | 639 | [[package]] 640 | name = "lazy_static" 641 | version = "1.5.0" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 644 | 645 | [[package]] 646 | name = "libc" 647 | version = "0.2.172" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 650 | 651 | [[package]] 652 | name = "linked-hash-map" 653 | version = "0.5.6" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 656 | 657 | [[package]] 658 | name = "linux-raw-sys" 659 | version = "0.4.15" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 662 | 663 | [[package]] 664 | name = "linux-raw-sys" 665 | version = "0.9.4" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 668 | 669 | [[package]] 670 | name = "litrs" 671 | version = "0.4.1" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 674 | 675 | [[package]] 676 | name = "lock_api" 677 | version = "0.4.12" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 680 | dependencies = [ 681 | "autocfg", 682 | "scopeguard", 683 | ] 684 | 685 | [[package]] 686 | name = "log" 687 | version = "0.4.27" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 690 | 691 | [[package]] 692 | name = "lru" 693 | version = "0.12.5" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" 696 | dependencies = [ 697 | "hashbrown", 698 | ] 699 | 700 | [[package]] 701 | name = "markdown-reader" 702 | version = "0.1.25" 703 | dependencies = [ 704 | "clap", 705 | "color-eyre", 706 | "crossterm 0.29.0", 707 | "itertools 0.14.0", 708 | "ratatui", 709 | "time", 710 | "tracing", 711 | "tracing-error", 712 | "tracing-subscriber", 713 | "tui-markdown", 714 | ] 715 | 716 | [[package]] 717 | name = "matchers" 718 | version = "0.1.0" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 721 | dependencies = [ 722 | "regex-automata 0.1.10", 723 | ] 724 | 725 | [[package]] 726 | name = "memchr" 727 | version = "2.7.4" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 730 | 731 | [[package]] 732 | name = "minimal-lexical" 733 | version = "0.2.1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 736 | 737 | [[package]] 738 | name = "miniz_oxide" 739 | version = "0.8.8" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 742 | dependencies = [ 743 | "adler2", 744 | ] 745 | 746 | [[package]] 747 | name = "mio" 748 | version = "1.0.3" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 751 | dependencies = [ 752 | "libc", 753 | "log", 754 | "wasi", 755 | "windows-sys 0.52.0", 756 | ] 757 | 758 | [[package]] 759 | name = "nom" 760 | version = "7.1.3" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 763 | dependencies = [ 764 | "memchr", 765 | "minimal-lexical", 766 | ] 767 | 768 | [[package]] 769 | name = "nu-ansi-term" 770 | version = "0.46.0" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 773 | dependencies = [ 774 | "overload", 775 | "winapi", 776 | ] 777 | 778 | [[package]] 779 | name = "num-conv" 780 | version = "0.1.0" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 783 | 784 | [[package]] 785 | name = "object" 786 | version = "0.36.7" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 789 | dependencies = [ 790 | "memchr", 791 | ] 792 | 793 | [[package]] 794 | name = "once_cell" 795 | version = "1.21.3" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 798 | 799 | [[package]] 800 | name = "onig" 801 | version = "6.4.0" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" 804 | dependencies = [ 805 | "bitflags 1.3.2", 806 | "libc", 807 | "once_cell", 808 | "onig_sys", 809 | ] 810 | 811 | [[package]] 812 | name = "onig_sys" 813 | version = "69.8.1" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" 816 | dependencies = [ 817 | "cc", 818 | "pkg-config", 819 | ] 820 | 821 | [[package]] 822 | name = "overload" 823 | version = "0.1.1" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 826 | 827 | [[package]] 828 | name = "owo-colors" 829 | version = "4.2.0" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" 832 | 833 | [[package]] 834 | name = "parking_lot" 835 | version = "0.12.3" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 838 | dependencies = [ 839 | "lock_api", 840 | "parking_lot_core", 841 | ] 842 | 843 | [[package]] 844 | name = "parking_lot_core" 845 | version = "0.9.10" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 848 | dependencies = [ 849 | "cfg-if", 850 | "libc", 851 | "redox_syscall", 852 | "smallvec", 853 | "windows-targets", 854 | ] 855 | 856 | [[package]] 857 | name = "paste" 858 | version = "1.0.15" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 861 | 862 | [[package]] 863 | name = "pin-project-lite" 864 | version = "0.2.16" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 867 | 868 | [[package]] 869 | name = "pin-utils" 870 | version = "0.1.0" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 873 | 874 | [[package]] 875 | name = "pkg-config" 876 | version = "0.3.32" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 879 | 880 | [[package]] 881 | name = "plist" 882 | version = "1.7.1" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" 885 | dependencies = [ 886 | "base64", 887 | "indexmap", 888 | "quick-xml", 889 | "serde", 890 | "time", 891 | ] 892 | 893 | [[package]] 894 | name = "powerfmt" 895 | version = "0.2.0" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 898 | 899 | [[package]] 900 | name = "pretty_assertions" 901 | version = "1.4.1" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" 904 | dependencies = [ 905 | "diff", 906 | "yansi", 907 | ] 908 | 909 | [[package]] 910 | name = "proc-macro-crate" 911 | version = "3.3.0" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" 914 | dependencies = [ 915 | "toml_edit", 916 | ] 917 | 918 | [[package]] 919 | name = "proc-macro2" 920 | version = "1.0.95" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 923 | dependencies = [ 924 | "unicode-ident", 925 | ] 926 | 927 | [[package]] 928 | name = "pulldown-cmark" 929 | version = "0.13.0" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" 932 | dependencies = [ 933 | "bitflags 2.9.0", 934 | "getopts", 935 | "memchr", 936 | "pulldown-cmark-escape", 937 | "unicase", 938 | ] 939 | 940 | [[package]] 941 | name = "pulldown-cmark-escape" 942 | version = "0.11.0" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" 945 | 946 | [[package]] 947 | name = "quick-xml" 948 | version = "0.32.0" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" 951 | dependencies = [ 952 | "memchr", 953 | ] 954 | 955 | [[package]] 956 | name = "quote" 957 | version = "1.0.40" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 960 | dependencies = [ 961 | "proc-macro2", 962 | ] 963 | 964 | [[package]] 965 | name = "ratatui" 966 | version = "0.29.0" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" 969 | dependencies = [ 970 | "bitflags 2.9.0", 971 | "cassowary", 972 | "compact_str", 973 | "crossterm 0.28.1", 974 | "indoc", 975 | "instability", 976 | "itertools 0.13.0", 977 | "lru", 978 | "paste", 979 | "strum", 980 | "unicode-segmentation", 981 | "unicode-truncate", 982 | "unicode-width 0.2.0", 983 | ] 984 | 985 | [[package]] 986 | name = "redox_syscall" 987 | version = "0.5.12" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" 990 | dependencies = [ 991 | "bitflags 2.9.0", 992 | ] 993 | 994 | [[package]] 995 | name = "regex" 996 | version = "1.11.1" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 999 | dependencies = [ 1000 | "aho-corasick", 1001 | "memchr", 1002 | "regex-automata 0.4.9", 1003 | "regex-syntax 0.8.5", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "regex-automata" 1008 | version = "0.1.10" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1011 | dependencies = [ 1012 | "regex-syntax 0.6.29", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "regex-automata" 1017 | version = "0.4.9" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1020 | dependencies = [ 1021 | "aho-corasick", 1022 | "memchr", 1023 | "regex-syntax 0.8.5", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "regex-syntax" 1028 | version = "0.6.29" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1031 | 1032 | [[package]] 1033 | name = "regex-syntax" 1034 | version = "0.8.5" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1037 | 1038 | [[package]] 1039 | name = "relative-path" 1040 | version = "1.9.3" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" 1043 | 1044 | [[package]] 1045 | name = "rstest" 1046 | version = "0.25.0" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" 1049 | dependencies = [ 1050 | "futures-timer", 1051 | "futures-util", 1052 | "rstest_macros", 1053 | "rustc_version", 1054 | ] 1055 | 1056 | [[package]] 1057 | name = "rstest_macros" 1058 | version = "0.25.0" 1059 | source = "registry+https://github.com/rust-lang/crates.io-index" 1060 | checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" 1061 | dependencies = [ 1062 | "cfg-if", 1063 | "glob", 1064 | "proc-macro-crate", 1065 | "proc-macro2", 1066 | "quote", 1067 | "regex", 1068 | "relative-path", 1069 | "rustc_version", 1070 | "syn", 1071 | "unicode-ident", 1072 | ] 1073 | 1074 | [[package]] 1075 | name = "rustc-demangle" 1076 | version = "0.1.24" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1079 | 1080 | [[package]] 1081 | name = "rustc_version" 1082 | version = "0.4.1" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 1085 | dependencies = [ 1086 | "semver", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "rustix" 1091 | version = "0.38.44" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 1094 | dependencies = [ 1095 | "bitflags 2.9.0", 1096 | "errno", 1097 | "libc", 1098 | "linux-raw-sys 0.4.15", 1099 | "windows-sys 0.59.0", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "rustix" 1104 | version = "1.0.7" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" 1107 | dependencies = [ 1108 | "bitflags 2.9.0", 1109 | "errno", 1110 | "libc", 1111 | "linux-raw-sys 0.9.4", 1112 | "windows-sys 0.59.0", 1113 | ] 1114 | 1115 | [[package]] 1116 | name = "rustversion" 1117 | version = "1.0.20" 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" 1119 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 1120 | 1121 | [[package]] 1122 | name = "ryu" 1123 | version = "1.0.20" 1124 | source = "registry+https://github.com/rust-lang/crates.io-index" 1125 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1126 | 1127 | [[package]] 1128 | name = "same-file" 1129 | version = "1.0.6" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1132 | dependencies = [ 1133 | "winapi-util", 1134 | ] 1135 | 1136 | [[package]] 1137 | name = "scopeguard" 1138 | version = "1.2.0" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1141 | 1142 | [[package]] 1143 | name = "semver" 1144 | version = "1.0.26" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" 1147 | 1148 | [[package]] 1149 | name = "serde" 1150 | version = "1.0.219" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1153 | dependencies = [ 1154 | "serde_derive", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "serde_derive" 1159 | version = "1.0.219" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1162 | dependencies = [ 1163 | "proc-macro2", 1164 | "quote", 1165 | "syn", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "serde_json" 1170 | version = "1.0.140" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1173 | dependencies = [ 1174 | "itoa", 1175 | "memchr", 1176 | "ryu", 1177 | "serde", 1178 | ] 1179 | 1180 | [[package]] 1181 | name = "sharded-slab" 1182 | version = "0.1.7" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1185 | dependencies = [ 1186 | "lazy_static", 1187 | ] 1188 | 1189 | [[package]] 1190 | name = "shlex" 1191 | version = "1.3.0" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1194 | 1195 | [[package]] 1196 | name = "signal-hook" 1197 | version = "0.3.17" 1198 | source = "registry+https://github.com/rust-lang/crates.io-index" 1199 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 1200 | dependencies = [ 1201 | "libc", 1202 | "signal-hook-registry", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "signal-hook-mio" 1207 | version = "0.2.4" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" 1210 | dependencies = [ 1211 | "libc", 1212 | "mio", 1213 | "signal-hook", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "signal-hook-registry" 1218 | version = "1.4.5" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" 1221 | dependencies = [ 1222 | "libc", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "simdutf8" 1227 | version = "0.1.5" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" 1230 | 1231 | [[package]] 1232 | name = "similar" 1233 | version = "2.7.0" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" 1236 | 1237 | [[package]] 1238 | name = "slab" 1239 | version = "0.4.9" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1242 | dependencies = [ 1243 | "autocfg", 1244 | ] 1245 | 1246 | [[package]] 1247 | name = "smallvec" 1248 | version = "1.15.0" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 1251 | 1252 | [[package]] 1253 | name = "static_assertions" 1254 | version = "1.1.0" 1255 | source = "registry+https://github.com/rust-lang/crates.io-index" 1256 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1257 | 1258 | [[package]] 1259 | name = "strsim" 1260 | version = "0.11.1" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1263 | 1264 | [[package]] 1265 | name = "strum" 1266 | version = "0.26.3" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" 1269 | dependencies = [ 1270 | "strum_macros", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "strum_macros" 1275 | version = "0.26.4" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" 1278 | dependencies = [ 1279 | "heck", 1280 | "proc-macro2", 1281 | "quote", 1282 | "rustversion", 1283 | "syn", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "syn" 1288 | version = "2.0.101" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 1291 | dependencies = [ 1292 | "proc-macro2", 1293 | "quote", 1294 | "unicode-ident", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "syntect" 1299 | version = "5.2.0" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" 1302 | dependencies = [ 1303 | "bincode", 1304 | "bitflags 1.3.2", 1305 | "flate2", 1306 | "fnv", 1307 | "once_cell", 1308 | "onig", 1309 | "plist", 1310 | "regex-syntax 0.8.5", 1311 | "serde", 1312 | "serde_derive", 1313 | "serde_json", 1314 | "thiserror", 1315 | "walkdir", 1316 | "yaml-rust", 1317 | ] 1318 | 1319 | [[package]] 1320 | name = "thiserror" 1321 | version = "1.0.69" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1324 | dependencies = [ 1325 | "thiserror-impl", 1326 | ] 1327 | 1328 | [[package]] 1329 | name = "thiserror-impl" 1330 | version = "1.0.69" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1333 | dependencies = [ 1334 | "proc-macro2", 1335 | "quote", 1336 | "syn", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "thread_local" 1341 | version = "1.1.8" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1344 | dependencies = [ 1345 | "cfg-if", 1346 | "once_cell", 1347 | ] 1348 | 1349 | [[package]] 1350 | name = "time" 1351 | version = "0.3.41" 1352 | source = "registry+https://github.com/rust-lang/crates.io-index" 1353 | checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" 1354 | dependencies = [ 1355 | "deranged", 1356 | "itoa", 1357 | "num-conv", 1358 | "powerfmt", 1359 | "serde", 1360 | "time-core", 1361 | "time-macros", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "time-core" 1366 | version = "0.1.4" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" 1369 | 1370 | [[package]] 1371 | name = "time-macros" 1372 | version = "0.2.22" 1373 | source = "registry+https://github.com/rust-lang/crates.io-index" 1374 | checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" 1375 | dependencies = [ 1376 | "num-conv", 1377 | "time-core", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "toml_datetime" 1382 | version = "0.6.9" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" 1385 | 1386 | [[package]] 1387 | name = "toml_edit" 1388 | version = "0.22.26" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" 1391 | dependencies = [ 1392 | "indexmap", 1393 | "toml_datetime", 1394 | "winnow", 1395 | ] 1396 | 1397 | [[package]] 1398 | name = "tracing" 1399 | version = "0.1.41" 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" 1401 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1402 | dependencies = [ 1403 | "pin-project-lite", 1404 | "tracing-attributes", 1405 | "tracing-core", 1406 | ] 1407 | 1408 | [[package]] 1409 | name = "tracing-attributes" 1410 | version = "0.1.28" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 1413 | dependencies = [ 1414 | "proc-macro2", 1415 | "quote", 1416 | "syn", 1417 | ] 1418 | 1419 | [[package]] 1420 | name = "tracing-core" 1421 | version = "0.1.33" 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" 1423 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1424 | dependencies = [ 1425 | "once_cell", 1426 | "valuable", 1427 | ] 1428 | 1429 | [[package]] 1430 | name = "tracing-error" 1431 | version = "0.2.1" 1432 | source = "registry+https://github.com/rust-lang/crates.io-index" 1433 | checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" 1434 | dependencies = [ 1435 | "tracing", 1436 | "tracing-subscriber", 1437 | ] 1438 | 1439 | [[package]] 1440 | name = "tracing-log" 1441 | version = "0.2.0" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 1444 | dependencies = [ 1445 | "log", 1446 | "once_cell", 1447 | "tracing-core", 1448 | ] 1449 | 1450 | [[package]] 1451 | name = "tracing-subscriber" 1452 | version = "0.3.19" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" 1455 | dependencies = [ 1456 | "matchers", 1457 | "nu-ansi-term", 1458 | "once_cell", 1459 | "regex", 1460 | "sharded-slab", 1461 | "smallvec", 1462 | "thread_local", 1463 | "tracing", 1464 | "tracing-core", 1465 | "tracing-log", 1466 | ] 1467 | 1468 | [[package]] 1469 | name = "tui-markdown" 1470 | version = "0.3.5" 1471 | dependencies = [ 1472 | "ansi-to-tui", 1473 | "document-features", 1474 | "indoc", 1475 | "insta", 1476 | "itertools 0.14.0", 1477 | "pretty_assertions", 1478 | "pulldown-cmark", 1479 | "ratatui", 1480 | "rstest", 1481 | "syntect", 1482 | "tracing", 1483 | "tracing-subscriber", 1484 | ] 1485 | 1486 | [[package]] 1487 | name = "unicase" 1488 | version = "2.8.1" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" 1491 | 1492 | [[package]] 1493 | name = "unicode-ident" 1494 | version = "1.0.18" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1497 | 1498 | [[package]] 1499 | name = "unicode-segmentation" 1500 | version = "1.12.0" 1501 | source = "registry+https://github.com/rust-lang/crates.io-index" 1502 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 1503 | 1504 | [[package]] 1505 | name = "unicode-truncate" 1506 | version = "1.1.0" 1507 | source = "registry+https://github.com/rust-lang/crates.io-index" 1508 | checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" 1509 | dependencies = [ 1510 | "itertools 0.13.0", 1511 | "unicode-segmentation", 1512 | "unicode-width 0.1.14", 1513 | ] 1514 | 1515 | [[package]] 1516 | name = "unicode-width" 1517 | version = "0.1.14" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 1520 | 1521 | [[package]] 1522 | name = "unicode-width" 1523 | version = "0.2.0" 1524 | source = "registry+https://github.com/rust-lang/crates.io-index" 1525 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 1526 | 1527 | [[package]] 1528 | name = "utf8parse" 1529 | version = "0.2.2" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1532 | 1533 | [[package]] 1534 | name = "valuable" 1535 | version = "0.1.1" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" 1538 | 1539 | [[package]] 1540 | name = "walkdir" 1541 | version = "2.5.0" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 1544 | dependencies = [ 1545 | "same-file", 1546 | "winapi-util", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "wasi" 1551 | version = "0.11.0+wasi-snapshot-preview1" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1554 | 1555 | [[package]] 1556 | name = "winapi" 1557 | version = "0.3.9" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1560 | dependencies = [ 1561 | "winapi-i686-pc-windows-gnu", 1562 | "winapi-x86_64-pc-windows-gnu", 1563 | ] 1564 | 1565 | [[package]] 1566 | name = "winapi-i686-pc-windows-gnu" 1567 | version = "0.4.0" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1570 | 1571 | [[package]] 1572 | name = "winapi-util" 1573 | version = "0.1.9" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 1576 | dependencies = [ 1577 | "windows-sys 0.59.0", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "winapi-x86_64-pc-windows-gnu" 1582 | version = "0.4.0" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1585 | 1586 | [[package]] 1587 | name = "windows-sys" 1588 | version = "0.52.0" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1591 | dependencies = [ 1592 | "windows-targets", 1593 | ] 1594 | 1595 | [[package]] 1596 | name = "windows-sys" 1597 | version = "0.59.0" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1600 | dependencies = [ 1601 | "windows-targets", 1602 | ] 1603 | 1604 | [[package]] 1605 | name = "windows-targets" 1606 | version = "0.52.6" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1609 | dependencies = [ 1610 | "windows_aarch64_gnullvm", 1611 | "windows_aarch64_msvc", 1612 | "windows_i686_gnu", 1613 | "windows_i686_gnullvm", 1614 | "windows_i686_msvc", 1615 | "windows_x86_64_gnu", 1616 | "windows_x86_64_gnullvm", 1617 | "windows_x86_64_msvc", 1618 | ] 1619 | 1620 | [[package]] 1621 | name = "windows_aarch64_gnullvm" 1622 | version = "0.52.6" 1623 | source = "registry+https://github.com/rust-lang/crates.io-index" 1624 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1625 | 1626 | [[package]] 1627 | name = "windows_aarch64_msvc" 1628 | version = "0.52.6" 1629 | source = "registry+https://github.com/rust-lang/crates.io-index" 1630 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1631 | 1632 | [[package]] 1633 | name = "windows_i686_gnu" 1634 | version = "0.52.6" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1637 | 1638 | [[package]] 1639 | name = "windows_i686_gnullvm" 1640 | version = "0.52.6" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1643 | 1644 | [[package]] 1645 | name = "windows_i686_msvc" 1646 | version = "0.52.6" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1649 | 1650 | [[package]] 1651 | name = "windows_x86_64_gnu" 1652 | version = "0.52.6" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1655 | 1656 | [[package]] 1657 | name = "windows_x86_64_gnullvm" 1658 | version = "0.52.6" 1659 | source = "registry+https://github.com/rust-lang/crates.io-index" 1660 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1661 | 1662 | [[package]] 1663 | name = "windows_x86_64_msvc" 1664 | version = "0.52.6" 1665 | source = "registry+https://github.com/rust-lang/crates.io-index" 1666 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1667 | 1668 | [[package]] 1669 | name = "winnow" 1670 | version = "0.7.10" 1671 | source = "registry+https://github.com/rust-lang/crates.io-index" 1672 | checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" 1673 | dependencies = [ 1674 | "memchr", 1675 | ] 1676 | 1677 | [[package]] 1678 | name = "yaml-rust" 1679 | version = "0.4.5" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" 1682 | dependencies = [ 1683 | "linked-hash-map", 1684 | ] 1685 | 1686 | [[package]] 1687 | name = "yansi" 1688 | version = "1.0.1" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" 1691 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["tui-markdown", "markdown-reader"] 4 | 5 | [workspace.package] 6 | rust-version = "1.82.0" 7 | edition = "2021" 8 | license = "MIT OR Apache-2.0" 9 | repository = "https://github.com/joshka/tui-markdown" 10 | authors = ["Joshka"] 11 | 12 | 13 | [workspace.dependencies] 14 | ratatui = { version = "0.29.0", default-features = false } 15 | tui-markdown = { version = "0.3.5", path = "tui-markdown" } 16 | 17 | [patch.crates-io] 18 | # when developing ratatui, uncomment this line to use the local version 19 | # ratatui = { path = "../ratatui" } 20 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Josh McKinney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tui-markdown and Markdown-Reader 2 | 3 | An experimental Proof of Concept Ratatui library and TUI app for rendering Markdown 4 | 5 | - [Tui-markdown README](./tui-markdown/README.md) 6 | - [Markdown-reader README](./markdown-reader/README.md) 7 | 8 | ## License 9 | 10 | Copyright (c) 2024 Josh McKinney 11 | 12 | This project is licensed under either of 13 | 14 | - Apache License, Version 2.0 15 | ([LICENSE-APACHE](./LICENSE-APACHE) or ) 16 | - MIT license 17 | ([LICENSE-MIT](./LICENSE-MIT) or ) 18 | 19 | at your option. 20 | 21 | ## Contribution 22 | 23 | Unless you explicitly state otherwise, any contribution intentionally submitted 24 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 25 | dual licensed as above, without any additional terms or conditions. 26 | 27 | See [CONTRIBUTING.md](./CONTRIBUTING.md). 28 | -------------------------------------------------------------------------------- /demo.tape: -------------------------------------------------------------------------------- 1 | # VHS Tape (see https://github.com/charmbracelet/vhs) 2 | Output "target/demo.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 600 6 | Hide 7 | Type "cargo run -- markdown-reader/TEST.md" 8 | Enter 9 | Sleep 4s 10 | Show 11 | Sleep 4s 12 | Space@4s 4 13 | # Sleep 2s 14 | Type "g" 15 | Hide 16 | Type "q" 17 | Sleep 500ms 18 | -------------------------------------------------------------------------------- /markdown-reader/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /markdown-reader/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [unreleased] 6 | 7 | ## [0.1.25](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.24...markdown-reader-v0.1.25) - 2025-05-07 8 | 9 | ### Other 10 | 11 | - *(deps)* bump the cargo-dependencies group across 1 directory with 5 updates ([#79](https://github.com/joshka/tui-markdown/pull/79)) 12 | 13 | ## [0.1.24](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.23...markdown-reader-v0.1.24) - 2025-05-07 14 | 15 | ### Other 16 | 17 | - add rustfmt and reformat code ([#81](https://github.com/joshka/tui-markdown/pull/81)) 18 | - *(deps)* bump clap in the cargo-dependencies group ([#73](https://github.com/joshka/tui-markdown/pull/73)) 19 | 20 | ## [0.1.23](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.22...markdown-reader-v0.1.23) - 2025-03-11 21 | 22 | ### Other 23 | 24 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#71](https://github.com/joshka/tui-markdown/pull/71)) 25 | 26 | ## [0.1.22](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.21...markdown-reader-v0.1.22) - 2025-03-09 27 | 28 | ### Other 29 | 30 | - *(deps)* bump the cargo-dependencies group across 1 directory with 5 updates ([#70](https://github.com/joshka/tui-markdown/pull/70)) 31 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#66](https://github.com/joshka/tui-markdown/pull/66)) 32 | - *(deps)* bump the cargo-dependencies group across 1 directory with 4 updates ([#64](https://github.com/joshka/tui-markdown/pull/64)) 33 | 34 | ## [0.1.21](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.20...markdown-reader-v0.1.21) - 2024-12-17 35 | 36 | ### Other 37 | 38 | - *(deps)* bump the cargo-dependencies group with 5 updates (#60) 39 | 40 | ## [0.1.20](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.19...markdown-reader-v0.1.20) - 2024-11-20 41 | 42 | ### Other 43 | 44 | - *(deps)* bump the cargo-dependencies group across 1 directory with 3 updates ([#58](https://github.com/joshka/tui-markdown/pull/58)) 45 | 46 | ## [0.1.19](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.18...markdown-reader-v0.1.19) - 2024-10-22 47 | 48 | ### Other 49 | 50 | - update Cargo.lock dependencies 51 | 52 | ## [0.1.18](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.17...markdown-reader-v0.1.18) - 2024-10-13 53 | 54 | ### Added 55 | 56 | - highlight code blocks ([#51](https://github.com/joshka/tui-markdown/pull/51)) 57 | 58 | ### Other 59 | 60 | - *(deps)* bump clap in the cargo-dependencies group ([#52](https://github.com/joshka/tui-markdown/pull/52)) 61 | - *(deps)* bump clap in the cargo-dependencies group ([#48](https://github.com/joshka/tui-markdown/pull/48)) 62 | 63 | ## [0.1.17](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.16...markdown-reader-v0.1.17) - 2024-09-20 64 | 65 | ### Other 66 | 67 | - update readme demo image 68 | 69 | ## [0.1.16](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.15...markdown-reader-v0.1.16) - 2024-09-20 70 | 71 | ### Other 72 | 73 | - add tests, implement more markdown features, don't panic for unimplemented features ([#45](https://github.com/joshka/tui-markdown/pull/45)) 74 | 75 | ## [0.1.15](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.14...markdown-reader-v0.1.15) - 2024-09-20 76 | 77 | ### Other 78 | 79 | - add support for unordered list ([#44](https://github.com/joshka/tui-markdown/pull/44)) 80 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#42](https://github.com/joshka/tui-markdown/pull/42)) 81 | 82 | ## [0.1.14](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.13...markdown-reader-v0.1.14) - 2024-08-06 83 | 84 | ### Other 85 | - use crossterm version re-exported from ratatui 86 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#36](https://github.com/joshka/tui-markdown/pull/36)) 87 | 88 | ## [0.1.13](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.12...markdown-reader-v0.1.13) - 2024-08-02 89 | 90 | ### Other 91 | - *(deps)* bump clap in the cargo-dependencies group ([#34](https://github.com/joshka/tui-markdown/pull/34)) 92 | 93 | ## [0.1.12](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.11...markdown-reader-v0.1.12) - 2024-07-15 94 | 95 | ### Other 96 | - *(deps)* bump clap in the cargo-dependencies group ([#32](https://github.com/joshka/tui-markdown/pull/32)) 97 | 98 | ## [0.1.11](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.10...markdown-reader-v0.1.11) - 2024-07-02 99 | 100 | ### Other 101 | - *(deps)* bump clap in the cargo-dependencies group ([#30](https://github.com/joshka/tui-markdown/pull/30)) 102 | 103 | ## [0.1.10](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.9...markdown-reader-v0.1.10) - 2024-06-24 104 | 105 | ### Other 106 | - *(deps)* bump ratatui in the cargo-dependencies group ([#29](https://github.com/joshka/tui-markdown/pull/29)) 107 | - *(deps)* bump clap in the cargo-dependencies group ([#27](https://github.com/joshka/tui-markdown/pull/27)) 108 | 109 | ## [0.1.9](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.8...markdown-reader-v0.1.9) - 2024-06-08 110 | 111 | ### Fixed 112 | - link to crate pages 113 | 114 | ## [0.1.8](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.7...markdown-reader-v0.1.8) - 2024-05-22 115 | 116 | ### Other 117 | - *(deps)* bump the cargo-dependencies group with 3 updates ([#24](https://github.com/joshka/tui-markdown/pull/24)) 118 | 119 | ## [0.1.7](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.6...markdown-reader-v0.1.7) - 2024-04-24 120 | 121 | ### Other 122 | - *(deps)* bump ratatui from 0.26.1 to 0.26.2 ([#20](https://github.com/joshka/tui-markdown/pull/20)) 123 | - *(deps)* bump time from 0.3.34 to 0.3.36 ([#21](https://github.com/joshka/tui-markdown/pull/21)) 124 | - *(deps)* bump clap from 4.5.3 to 4.5.4 ([#17](https://github.com/joshka/tui-markdown/pull/17)) 125 | - *(deps)* bump color-eyre from 0.6.2 to 0.6.3 ([#14](https://github.com/joshka/tui-markdown/pull/14)) 126 | - *(deps)* bump clap from 4.5.2 to 4.5.3 ([#15](https://github.com/joshka/tui-markdown/pull/15)) 127 | 128 | ## [0.1.6](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.5...markdown-reader-v0.1.6) - 2024-03-12 129 | 130 | ### Other 131 | - *(deps)* bump mio from 0.8.10 to 0.8.11 in /markdown-reader ([#9](https://github.com/joshka/tui-markdown/pull/9)) 132 | - *(deps)* bump clap from 4.5.1 to 4.5.2 ([#11](https://github.com/joshka/tui-markdown/pull/11)) 133 | 134 | ## [0.1.5](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.4...markdown-reader-v0.1.5) - 2024-02-29 135 | 136 | ### Other 137 | - update license info in readme files 138 | - add a note about the experimental state 139 | - bump copyright year 140 | 141 | ## [0.1.4](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.3...markdown-reader-v0.1.4) - 2024-02-27 142 | 143 | ### Other 144 | - make demo less easier to view 145 | 146 | ## [0.1.3](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.2...markdown-reader-v0.1.3) - 2024-02-27 147 | 148 | ### Other 149 | - fix more links / badges 150 | 151 | ## [0.1.2](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.1...markdown-reader-v0.1.2) - 2024-02-27 152 | 153 | ### Added 154 | - add filename and pageUp/Down 155 | 156 | ### Fixed 157 | - urls in cargo.toml 158 | - add pages down and up to scroll 159 | - make scrollbar respect end of file 160 | 161 | ### Other 162 | - make logging scrollable 163 | 164 | ## [0.1.1](https://github.com/joshka/tui-markdown/compare/markdown-reader-v0.1.0...markdown-reader-v0.1.1) - 2024-02-27 165 | 166 | ### Added 167 | 168 | - Initial implementation of lib and tui 169 | 170 | ### Fixed 171 | 172 | - tui-markdown crate dependency for markdown-reader 173 | 174 | ### Other 175 | 176 | - add CHANGELOGs 177 | - add demo for markdown-reader 178 | 179 | 180 | -------------------------------------------------------------------------------- /markdown-reader/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 = "ahash" 22 | version = "0.8.9" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" 25 | dependencies = [ 26 | "cfg-if", 27 | "once_cell", 28 | "version_check", 29 | "zerocopy", 30 | ] 31 | 32 | [[package]] 33 | name = "aho-corasick" 34 | version = "1.1.2" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 37 | dependencies = [ 38 | "memchr", 39 | ] 40 | 41 | [[package]] 42 | name = "allocator-api2" 43 | version = "0.2.16" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" 46 | 47 | [[package]] 48 | name = "anstream" 49 | version = "0.6.12" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" 52 | dependencies = [ 53 | "anstyle", 54 | "anstyle-parse", 55 | "anstyle-query", 56 | "anstyle-wincon", 57 | "colorchoice", 58 | "utf8parse", 59 | ] 60 | 61 | [[package]] 62 | name = "anstyle" 63 | version = "1.0.6" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 66 | 67 | [[package]] 68 | name = "anstyle-parse" 69 | version = "0.2.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 72 | dependencies = [ 73 | "utf8parse", 74 | ] 75 | 76 | [[package]] 77 | name = "anstyle-query" 78 | version = "1.0.2" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 81 | dependencies = [ 82 | "windows-sys 0.52.0", 83 | ] 84 | 85 | [[package]] 86 | name = "anstyle-wincon" 87 | version = "3.0.2" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 90 | dependencies = [ 91 | "anstyle", 92 | "windows-sys 0.52.0", 93 | ] 94 | 95 | [[package]] 96 | name = "autocfg" 97 | version = "1.1.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 100 | 101 | [[package]] 102 | name = "backtrace" 103 | version = "0.3.69" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 106 | dependencies = [ 107 | "addr2line", 108 | "cc", 109 | "cfg-if", 110 | "libc", 111 | "miniz_oxide", 112 | "object", 113 | "rustc-demangle", 114 | ] 115 | 116 | [[package]] 117 | name = "bitflags" 118 | version = "1.3.2" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 121 | 122 | [[package]] 123 | name = "bitflags" 124 | version = "2.4.2" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" 127 | 128 | [[package]] 129 | name = "cassowary" 130 | version = "0.3.0" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" 133 | 134 | [[package]] 135 | name = "castaway" 136 | version = "0.2.2" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" 139 | dependencies = [ 140 | "rustversion", 141 | ] 142 | 143 | [[package]] 144 | name = "cc" 145 | version = "1.0.88" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" 148 | 149 | [[package]] 150 | name = "cfg-if" 151 | version = "1.0.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 154 | 155 | [[package]] 156 | name = "clap" 157 | version = "4.5.2" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" 160 | dependencies = [ 161 | "clap_builder", 162 | "clap_derive", 163 | ] 164 | 165 | [[package]] 166 | name = "clap_builder" 167 | version = "4.5.2" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" 170 | dependencies = [ 171 | "anstream", 172 | "anstyle", 173 | "clap_lex", 174 | "strsim", 175 | ] 176 | 177 | [[package]] 178 | name = "clap_derive" 179 | version = "4.5.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" 182 | dependencies = [ 183 | "heck", 184 | "proc-macro2", 185 | "quote", 186 | "syn 2.0.51", 187 | ] 188 | 189 | [[package]] 190 | name = "clap_lex" 191 | version = "0.7.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" 194 | 195 | [[package]] 196 | name = "color-eyre" 197 | version = "0.6.2" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" 200 | dependencies = [ 201 | "backtrace", 202 | "color-spantrace", 203 | "eyre", 204 | "indenter", 205 | "once_cell", 206 | "owo-colors", 207 | "tracing-error", 208 | ] 209 | 210 | [[package]] 211 | name = "color-spantrace" 212 | version = "0.2.1" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" 215 | dependencies = [ 216 | "once_cell", 217 | "owo-colors", 218 | "tracing-core", 219 | "tracing-error", 220 | ] 221 | 222 | [[package]] 223 | name = "colorchoice" 224 | version = "1.0.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 227 | 228 | [[package]] 229 | name = "compact_str" 230 | version = "0.7.1" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" 233 | dependencies = [ 234 | "castaway", 235 | "cfg-if", 236 | "itoa", 237 | "ryu", 238 | "static_assertions", 239 | ] 240 | 241 | [[package]] 242 | name = "crossterm" 243 | version = "0.27.0" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" 246 | dependencies = [ 247 | "bitflags 2.4.2", 248 | "crossterm_winapi", 249 | "libc", 250 | "mio", 251 | "parking_lot", 252 | "signal-hook", 253 | "signal-hook-mio", 254 | "winapi", 255 | ] 256 | 257 | [[package]] 258 | name = "crossterm_winapi" 259 | version = "0.9.1" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 262 | dependencies = [ 263 | "winapi", 264 | ] 265 | 266 | [[package]] 267 | name = "deranged" 268 | version = "0.3.11" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 271 | dependencies = [ 272 | "powerfmt", 273 | ] 274 | 275 | [[package]] 276 | name = "either" 277 | version = "1.10.0" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" 280 | 281 | [[package]] 282 | name = "eyre" 283 | version = "0.6.12" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" 286 | dependencies = [ 287 | "indenter", 288 | "once_cell", 289 | ] 290 | 291 | [[package]] 292 | name = "getopts" 293 | version = "0.2.21" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" 296 | dependencies = [ 297 | "unicode-width", 298 | ] 299 | 300 | [[package]] 301 | name = "gimli" 302 | version = "0.28.1" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 305 | 306 | [[package]] 307 | name = "hashbrown" 308 | version = "0.14.3" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 311 | dependencies = [ 312 | "ahash", 313 | "allocator-api2", 314 | ] 315 | 316 | [[package]] 317 | name = "heck" 318 | version = "0.4.1" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 321 | 322 | [[package]] 323 | name = "indenter" 324 | version = "0.3.3" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 327 | 328 | [[package]] 329 | name = "indoc" 330 | version = "2.0.4" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" 333 | 334 | [[package]] 335 | name = "itertools" 336 | version = "0.12.1" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 339 | dependencies = [ 340 | "either", 341 | ] 342 | 343 | [[package]] 344 | name = "itoa" 345 | version = "1.0.10" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 348 | 349 | [[package]] 350 | name = "lazy_static" 351 | version = "1.4.0" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 354 | 355 | [[package]] 356 | name = "libc" 357 | version = "0.2.153" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 360 | 361 | [[package]] 362 | name = "lock_api" 363 | version = "0.4.11" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 366 | dependencies = [ 367 | "autocfg", 368 | "scopeguard", 369 | ] 370 | 371 | [[package]] 372 | name = "log" 373 | version = "0.4.20" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 376 | 377 | [[package]] 378 | name = "lru" 379 | version = "0.12.3" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" 382 | dependencies = [ 383 | "hashbrown", 384 | ] 385 | 386 | [[package]] 387 | name = "markdown-reader" 388 | version = "0.1.5" 389 | dependencies = [ 390 | "clap", 391 | "color-eyre", 392 | "crossterm", 393 | "itertools", 394 | "ratatui", 395 | "time", 396 | "tracing", 397 | "tracing-error", 398 | "tracing-subscriber", 399 | "tui-markdown", 400 | ] 401 | 402 | [[package]] 403 | name = "matchers" 404 | version = "0.1.0" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 407 | dependencies = [ 408 | "regex-automata 0.1.10", 409 | ] 410 | 411 | [[package]] 412 | name = "memchr" 413 | version = "2.7.1" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 416 | 417 | [[package]] 418 | name = "miniz_oxide" 419 | version = "0.7.2" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 422 | dependencies = [ 423 | "adler", 424 | ] 425 | 426 | [[package]] 427 | name = "mio" 428 | version = "0.8.11" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 431 | dependencies = [ 432 | "libc", 433 | "log", 434 | "wasi", 435 | "windows-sys 0.48.0", 436 | ] 437 | 438 | [[package]] 439 | name = "nu-ansi-term" 440 | version = "0.46.0" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 443 | dependencies = [ 444 | "overload", 445 | "winapi", 446 | ] 447 | 448 | [[package]] 449 | name = "num-conv" 450 | version = "0.1.0" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 453 | 454 | [[package]] 455 | name = "object" 456 | version = "0.32.2" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 459 | dependencies = [ 460 | "memchr", 461 | ] 462 | 463 | [[package]] 464 | name = "once_cell" 465 | version = "1.19.0" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 468 | 469 | [[package]] 470 | name = "overload" 471 | version = "0.1.1" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 474 | 475 | [[package]] 476 | name = "owo-colors" 477 | version = "3.5.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" 480 | 481 | [[package]] 482 | name = "parking_lot" 483 | version = "0.12.1" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 486 | dependencies = [ 487 | "lock_api", 488 | "parking_lot_core", 489 | ] 490 | 491 | [[package]] 492 | name = "parking_lot_core" 493 | version = "0.9.9" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 496 | dependencies = [ 497 | "cfg-if", 498 | "libc", 499 | "redox_syscall", 500 | "smallvec", 501 | "windows-targets 0.48.5", 502 | ] 503 | 504 | [[package]] 505 | name = "paste" 506 | version = "1.0.14" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 509 | 510 | [[package]] 511 | name = "pin-project-lite" 512 | version = "0.2.13" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 515 | 516 | [[package]] 517 | name = "powerfmt" 518 | version = "0.2.0" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 521 | 522 | [[package]] 523 | name = "proc-macro2" 524 | version = "1.0.78" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" 527 | dependencies = [ 528 | "unicode-ident", 529 | ] 530 | 531 | [[package]] 532 | name = "pulldown-cmark" 533 | version = "0.10.0" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7" 536 | dependencies = [ 537 | "bitflags 2.4.2", 538 | "getopts", 539 | "memchr", 540 | "pulldown-cmark-escape", 541 | "unicase", 542 | ] 543 | 544 | [[package]] 545 | name = "pulldown-cmark-escape" 546 | version = "0.10.0" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b" 549 | 550 | [[package]] 551 | name = "quote" 552 | version = "1.0.35" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 555 | dependencies = [ 556 | "proc-macro2", 557 | ] 558 | 559 | [[package]] 560 | name = "ratatui" 561 | version = "0.26.1" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8" 564 | dependencies = [ 565 | "bitflags 2.4.2", 566 | "cassowary", 567 | "compact_str", 568 | "crossterm", 569 | "indoc", 570 | "itertools", 571 | "lru", 572 | "paste", 573 | "stability", 574 | "strum", 575 | "unicode-segmentation", 576 | "unicode-width", 577 | ] 578 | 579 | [[package]] 580 | name = "redox_syscall" 581 | version = "0.4.1" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 584 | dependencies = [ 585 | "bitflags 1.3.2", 586 | ] 587 | 588 | [[package]] 589 | name = "regex" 590 | version = "1.10.3" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" 593 | dependencies = [ 594 | "aho-corasick", 595 | "memchr", 596 | "regex-automata 0.4.5", 597 | "regex-syntax 0.8.2", 598 | ] 599 | 600 | [[package]] 601 | name = "regex-automata" 602 | version = "0.1.10" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 605 | dependencies = [ 606 | "regex-syntax 0.6.29", 607 | ] 608 | 609 | [[package]] 610 | name = "regex-automata" 611 | version = "0.4.5" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" 614 | dependencies = [ 615 | "aho-corasick", 616 | "memchr", 617 | "regex-syntax 0.8.2", 618 | ] 619 | 620 | [[package]] 621 | name = "regex-syntax" 622 | version = "0.6.29" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 625 | 626 | [[package]] 627 | name = "regex-syntax" 628 | version = "0.8.2" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 631 | 632 | [[package]] 633 | name = "rustc-demangle" 634 | version = "0.1.23" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 637 | 638 | [[package]] 639 | name = "rustversion" 640 | version = "1.0.14" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 643 | 644 | [[package]] 645 | name = "ryu" 646 | version = "1.0.17" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 649 | 650 | [[package]] 651 | name = "scopeguard" 652 | version = "1.2.0" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 655 | 656 | [[package]] 657 | name = "serde" 658 | version = "1.0.197" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 661 | dependencies = [ 662 | "serde_derive", 663 | ] 664 | 665 | [[package]] 666 | name = "serde_derive" 667 | version = "1.0.197" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 670 | dependencies = [ 671 | "proc-macro2", 672 | "quote", 673 | "syn 2.0.51", 674 | ] 675 | 676 | [[package]] 677 | name = "sharded-slab" 678 | version = "0.1.7" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 681 | dependencies = [ 682 | "lazy_static", 683 | ] 684 | 685 | [[package]] 686 | name = "signal-hook" 687 | version = "0.3.17" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 690 | dependencies = [ 691 | "libc", 692 | "signal-hook-registry", 693 | ] 694 | 695 | [[package]] 696 | name = "signal-hook-mio" 697 | version = "0.2.3" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 700 | dependencies = [ 701 | "libc", 702 | "mio", 703 | "signal-hook", 704 | ] 705 | 706 | [[package]] 707 | name = "signal-hook-registry" 708 | version = "1.4.1" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 711 | dependencies = [ 712 | "libc", 713 | ] 714 | 715 | [[package]] 716 | name = "smallvec" 717 | version = "1.13.1" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" 720 | 721 | [[package]] 722 | name = "stability" 723 | version = "0.1.1" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce" 726 | dependencies = [ 727 | "quote", 728 | "syn 1.0.109", 729 | ] 730 | 731 | [[package]] 732 | name = "static_assertions" 733 | version = "1.1.0" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 736 | 737 | [[package]] 738 | name = "strsim" 739 | version = "0.11.0" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" 742 | 743 | [[package]] 744 | name = "strum" 745 | version = "0.26.1" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" 748 | dependencies = [ 749 | "strum_macros", 750 | ] 751 | 752 | [[package]] 753 | name = "strum_macros" 754 | version = "0.26.1" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" 757 | dependencies = [ 758 | "heck", 759 | "proc-macro2", 760 | "quote", 761 | "rustversion", 762 | "syn 2.0.51", 763 | ] 764 | 765 | [[package]] 766 | name = "syn" 767 | version = "1.0.109" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 770 | dependencies = [ 771 | "proc-macro2", 772 | "quote", 773 | "unicode-ident", 774 | ] 775 | 776 | [[package]] 777 | name = "syn" 778 | version = "2.0.51" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" 781 | dependencies = [ 782 | "proc-macro2", 783 | "quote", 784 | "unicode-ident", 785 | ] 786 | 787 | [[package]] 788 | name = "thread_local" 789 | version = "1.1.8" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 792 | dependencies = [ 793 | "cfg-if", 794 | "once_cell", 795 | ] 796 | 797 | [[package]] 798 | name = "time" 799 | version = "0.3.34" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" 802 | dependencies = [ 803 | "deranged", 804 | "itoa", 805 | "num-conv", 806 | "powerfmt", 807 | "serde", 808 | "time-core", 809 | "time-macros", 810 | ] 811 | 812 | [[package]] 813 | name = "time-core" 814 | version = "0.1.2" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 817 | 818 | [[package]] 819 | name = "time-macros" 820 | version = "0.2.17" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" 823 | dependencies = [ 824 | "num-conv", 825 | "time-core", 826 | ] 827 | 828 | [[package]] 829 | name = "tracing" 830 | version = "0.1.40" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 833 | dependencies = [ 834 | "pin-project-lite", 835 | "tracing-attributes", 836 | "tracing-core", 837 | ] 838 | 839 | [[package]] 840 | name = "tracing-attributes" 841 | version = "0.1.27" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 844 | dependencies = [ 845 | "proc-macro2", 846 | "quote", 847 | "syn 2.0.51", 848 | ] 849 | 850 | [[package]] 851 | name = "tracing-core" 852 | version = "0.1.32" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 855 | dependencies = [ 856 | "once_cell", 857 | "valuable", 858 | ] 859 | 860 | [[package]] 861 | name = "tracing-error" 862 | version = "0.2.0" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" 865 | dependencies = [ 866 | "tracing", 867 | "tracing-subscriber", 868 | ] 869 | 870 | [[package]] 871 | name = "tracing-log" 872 | version = "0.2.0" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 875 | dependencies = [ 876 | "log", 877 | "once_cell", 878 | "tracing-core", 879 | ] 880 | 881 | [[package]] 882 | name = "tracing-subscriber" 883 | version = "0.3.18" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 886 | dependencies = [ 887 | "matchers", 888 | "nu-ansi-term", 889 | "once_cell", 890 | "regex", 891 | "sharded-slab", 892 | "smallvec", 893 | "thread_local", 894 | "tracing", 895 | "tracing-core", 896 | "tracing-log", 897 | ] 898 | 899 | [[package]] 900 | name = "tui-markdown" 901 | version = "0.2.2" 902 | dependencies = [ 903 | "itertools", 904 | "pulldown-cmark", 905 | "ratatui", 906 | "tracing", 907 | ] 908 | 909 | [[package]] 910 | name = "unicase" 911 | version = "2.7.0" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 914 | dependencies = [ 915 | "version_check", 916 | ] 917 | 918 | [[package]] 919 | name = "unicode-ident" 920 | version = "1.0.12" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 923 | 924 | [[package]] 925 | name = "unicode-segmentation" 926 | version = "1.11.0" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 929 | 930 | [[package]] 931 | name = "unicode-width" 932 | version = "0.1.11" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 935 | 936 | [[package]] 937 | name = "utf8parse" 938 | version = "0.2.1" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 941 | 942 | [[package]] 943 | name = "valuable" 944 | version = "0.1.0" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 947 | 948 | [[package]] 949 | name = "version_check" 950 | version = "0.9.4" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 953 | 954 | [[package]] 955 | name = "wasi" 956 | version = "0.11.0+wasi-snapshot-preview1" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 959 | 960 | [[package]] 961 | name = "winapi" 962 | version = "0.3.9" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 965 | dependencies = [ 966 | "winapi-i686-pc-windows-gnu", 967 | "winapi-x86_64-pc-windows-gnu", 968 | ] 969 | 970 | [[package]] 971 | name = "winapi-i686-pc-windows-gnu" 972 | version = "0.4.0" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 975 | 976 | [[package]] 977 | name = "winapi-x86_64-pc-windows-gnu" 978 | version = "0.4.0" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 981 | 982 | [[package]] 983 | name = "windows-sys" 984 | version = "0.48.0" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 987 | dependencies = [ 988 | "windows-targets 0.48.5", 989 | ] 990 | 991 | [[package]] 992 | name = "windows-sys" 993 | version = "0.52.0" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 996 | dependencies = [ 997 | "windows-targets 0.52.3", 998 | ] 999 | 1000 | [[package]] 1001 | name = "windows-targets" 1002 | version = "0.48.5" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1005 | dependencies = [ 1006 | "windows_aarch64_gnullvm 0.48.5", 1007 | "windows_aarch64_msvc 0.48.5", 1008 | "windows_i686_gnu 0.48.5", 1009 | "windows_i686_msvc 0.48.5", 1010 | "windows_x86_64_gnu 0.48.5", 1011 | "windows_x86_64_gnullvm 0.48.5", 1012 | "windows_x86_64_msvc 0.48.5", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "windows-targets" 1017 | version = "0.52.3" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" 1020 | dependencies = [ 1021 | "windows_aarch64_gnullvm 0.52.3", 1022 | "windows_aarch64_msvc 0.52.3", 1023 | "windows_i686_gnu 0.52.3", 1024 | "windows_i686_msvc 0.52.3", 1025 | "windows_x86_64_gnu 0.52.3", 1026 | "windows_x86_64_gnullvm 0.52.3", 1027 | "windows_x86_64_msvc 0.52.3", 1028 | ] 1029 | 1030 | [[package]] 1031 | name = "windows_aarch64_gnullvm" 1032 | version = "0.48.5" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1035 | 1036 | [[package]] 1037 | name = "windows_aarch64_gnullvm" 1038 | version = "0.52.3" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" 1041 | 1042 | [[package]] 1043 | name = "windows_aarch64_msvc" 1044 | version = "0.48.5" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1047 | 1048 | [[package]] 1049 | name = "windows_aarch64_msvc" 1050 | version = "0.52.3" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" 1053 | 1054 | [[package]] 1055 | name = "windows_i686_gnu" 1056 | version = "0.48.5" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1059 | 1060 | [[package]] 1061 | name = "windows_i686_gnu" 1062 | version = "0.52.3" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" 1065 | 1066 | [[package]] 1067 | name = "windows_i686_msvc" 1068 | version = "0.48.5" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1071 | 1072 | [[package]] 1073 | name = "windows_i686_msvc" 1074 | version = "0.52.3" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" 1077 | 1078 | [[package]] 1079 | name = "windows_x86_64_gnu" 1080 | version = "0.48.5" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1083 | 1084 | [[package]] 1085 | name = "windows_x86_64_gnu" 1086 | version = "0.52.3" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" 1089 | 1090 | [[package]] 1091 | name = "windows_x86_64_gnullvm" 1092 | version = "0.48.5" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1095 | 1096 | [[package]] 1097 | name = "windows_x86_64_gnullvm" 1098 | version = "0.52.3" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" 1101 | 1102 | [[package]] 1103 | name = "windows_x86_64_msvc" 1104 | version = "0.48.5" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1107 | 1108 | [[package]] 1109 | name = "windows_x86_64_msvc" 1110 | version = "0.52.3" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" 1113 | 1114 | [[package]] 1115 | name = "zerocopy" 1116 | version = "0.7.32" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" 1119 | dependencies = [ 1120 | "zerocopy-derive", 1121 | ] 1122 | 1123 | [[package]] 1124 | name = "zerocopy-derive" 1125 | version = "0.7.32" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" 1128 | dependencies = [ 1129 | "proc-macro2", 1130 | "quote", 1131 | "syn 2.0.51", 1132 | ] 1133 | -------------------------------------------------------------------------------- /markdown-reader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "markdown-reader" 3 | description = "A simple markdown reader that uses ratatui to render markdown files." 4 | version = "0.1.25" 5 | documentation = "https://docs.rs/markdown-reader" 6 | categories = ["command-line-interface"] 7 | keywords = ["cli", "markdown", "ratatui", "terminal", "tui"] 8 | 9 | edition.workspace = true 10 | rust-version.workspace = true 11 | license.workspace = true 12 | repository.workspace = true 13 | authors.workspace = true 14 | 15 | [dependencies] 16 | clap = { version = "4.5.37", features = ["derive"] } 17 | color-eyre = "0.6.4" 18 | crossterm = "0.29.0" 19 | itertools = "0.14.0" 20 | ratatui = { workspace = true, default-features = true, features = ["unstable-widget-ref"] } 21 | tracing = "0.1.41" 22 | tracing-error = "0.2.1" 23 | tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } 24 | time = { version = "0.3.41", features = ["formatting", "macros"] } 25 | tui-markdown.workspace = true 26 | 27 | [[bin]] 28 | name = "mdr" 29 | path = "src/main.rs" 30 | -------------------------------------------------------------------------------- /markdown-reader/README.md: -------------------------------------------------------------------------------- 1 | # Markdown Reader 2 | 3 | [![Crate badge]][markdown-reader] 4 | [![Deps.rs Badge]][Dependency Status] 5 | [![License Badge]](../LICENSE-MIT) 6 | [![Codecov.io Badge]][Code Coverage] 7 | [![Discord Badge]][Ratatui Discord] 8 | 9 | [GitHub Repository] · [Changelog] · [Contributing] 10 | 11 | An experimental Proof of Concept markdown reader that uses [Ratatui] to render markdown files. The 12 | primary purpose of this crate is to test the [tui-markdown] crate. It is not ready for any sort of 13 | real world use. 14 | 15 | ![Demo](https://vhs.charm.sh/vhs-160G5PeWh0TMoxBph87WXZ.gif) 16 | 17 | ## Installation 18 | 19 | To install the markdown reader application (mdr): 20 | 21 | ```shell 22 | cargo install --locked markdown-reader 23 | ``` 24 | 25 | ## Usage 26 | 27 | ```shell 28 | mdr --help 29 | 30 | A simple markdown reader that uses ratatui to render markdown files. 31 | 32 | Usage: mdr [PATH] 33 | 34 | Arguments: 35 | [PATH] The path to the markdown file to read [default: README.md] 36 | 37 | Options: 38 | -h, --help Print help 39 | -V, --version Print version 40 | ``` 41 | 42 | ## Status 43 | 44 | This is working code, but not every markdown feature is supported. PRs welcome! 45 | 46 | - [x] Headings 47 | - [ ] Heading attributes / classes / anchors 48 | - [x] Normal paragraphs 49 | - [x] Block quotes 50 | - [x] Nested block quotes 51 | - [x] Bold (strong) 52 | - [x] Italic (emphasis) 53 | - [x] Strikethrough 54 | - [x] Ordered lists 55 | - [x] Unordered lists 56 | - [ ] Code blocks 57 | - [ ] Html 58 | - [ ] Footnotes 59 | - [ ] Tables 60 | - [ ] Linebreak handling 61 | - [ ] Rule 62 | - [ ] Tasklists 63 | - [ ] Links 64 | - [ ] Images 65 | - [ ] Metadata blocks 66 | - [ ] Superscript 67 | - [ ] Subscript 68 | 69 | ## License 70 | 71 | Copyright (c) 2024 Josh McKinney 72 | 73 | This project is licensed under either of 74 | 75 | - Apache License, Version 2.0 76 | ([LICENSE-APACHE](../LICENSE-APACHE) or ) 77 | - MIT license 78 | ([LICENSE-MIT](../LICENSE-MIT) or ) 79 | 80 | at your option. 81 | 82 | ## Contribution 83 | 84 | Unless you explicitly state otherwise, any contribution intentionally submitted 85 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 86 | dual licensed as above, without any additional terms or conditions. 87 | 88 | See [CONTRIBUTING.md](../CONTRIBUTING.md). 89 | 90 | [tui-markdown]: https://crates.io/crates/tui-markdown 91 | [markdown-reader]: https://crates.io/crates/markdown-reader 92 | [Ratatui]: https://crates.io/crates/ratatui 93 | 94 | [Crate badge]: https://img.shields.io/crates/v/markdown-reader?logo=rust&style=for-the-badge 95 | [Deps.rs Badge]: https://deps.rs/repo/github/joshka/tui-markdown/status.svg?path=markdown-reader&style=for-the-badge 96 | [License Badge]: https://img.shields.io/crates/l/markdown-reader?style=for-the-badge 97 | [Codecov.io Badge]: https://img.shields.io/codecov/c/github/joshka/markdown-reader?logo=codecov&style=for-the-badge&token=BAQ8SOKEST 98 | [Discord Badge]: https://img.shields.io/discord/1070692720437383208?label=ratatui+discord&logo=discord&style=for-the-badge 99 | 100 | [Dependency Status]: https://deps.rs/crate/markdown-reader 101 | [Code Coverage]: https://app.codecov.io/gh/joshka/tui-markdown 102 | [Ratatui Discord]: https://discord.gg/pMCEU9hNEj 103 | 104 | [GitHub Repository]: https://github.com/joshka/tui-markdown 105 | [Changelog]: https://github.com/joshka/tui-markdown/blob/main/markdown-reader/CHANGELOG.md 106 | [Contributing]: https://github.com/joshka/tui-markdown/blob/main/CONTRIBUTING.md 107 | -------------------------------------------------------------------------------- /markdown-reader/TEST.md: -------------------------------------------------------------------------------- 1 | # Markdown Reader 2 | 3 | This is a test file to check that how markdown renders 4 | 5 | ## Heading 2 6 | 7 | ### Heading 3 8 | 9 | #### Heading 4 10 | 11 | ##### Heading 5 12 | 13 | ###### Heading 6 14 | 15 | ## Emphasis 16 | 17 | This text will be *italic* 18 | 19 | This text will be **bold** 20 | 21 | *You **can** combine them* 22 | 23 | This is a ~~complicated~~ *very simple* example. 24 | 25 | ## Lists 26 | 27 | ### Unordered 28 | 29 | - Item 1 30 | - Item 2 31 | - Item 2a 32 | - Item 2b 33 | 34 | ### Ordered 35 | 36 | 1. Item 1 37 | 2. Item 2 38 | 3. Item 3 39 | 1. Item 3a 40 | 2. Item 3b 41 | 42 | ## Block Quotes 43 | 44 | > A blockquote 45 | 46 | After the quote 47 | 48 | > Multiline 49 | > quote 50 | 51 | After the quote 52 | 53 | > Multi paragraph 54 | > 55 | > quote 56 | 57 | After the quote 58 | 59 | > Multi indent 60 | > 61 | >> quote 62 | 63 | ```plain 64 | plain 65 | code 66 | ``` 67 | 68 | ```rust 69 | fn rust_code() { 70 | println!("hello world"); 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /markdown-reader/src/app.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | 3 | use color_eyre::Result; 4 | use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; 5 | use ratatui::buffer::Buffer; 6 | use ratatui::layout::{Constraint, Layout, Rect}; 7 | use ratatui::style::{Color, Modifier}; 8 | use ratatui::text::{Line, Span, Text}; 9 | use ratatui::widgets::{ 10 | ListState, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState, StatefulWidget, 11 | StatefulWidgetRef, Widget, Wrap, 12 | }; 13 | use ratatui::DefaultTerminal; 14 | 15 | use crate::events::{CrosstermEvent, Event, Events}; 16 | use crate::logging::LogEvents; 17 | 18 | #[derive(Debug)] 19 | pub struct App<'a> { 20 | text: Text<'a>, 21 | path: &'a Path, 22 | events: Events, 23 | log_events: LogEvents, 24 | show_logs: bool, 25 | } 26 | 27 | impl<'a> App<'a> { 28 | pub fn new(text: Text<'a>, path: &'a Path, events: Events, log_events: LogEvents) -> App<'a> { 29 | App { 30 | text, 31 | path, 32 | events, 33 | log_events, 34 | show_logs: false, 35 | } 36 | } 37 | 38 | pub fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> { 39 | let mut state = ScrollState::new(self.text.height()); 40 | self.draw(&mut terminal, &mut state)?; 41 | while let Ok(event) = self.events.next() { 42 | match event { 43 | Event::Crossterm(event) => self.handle_crossterm(event, &mut state)?, 44 | Event::Exit => break, 45 | }; 46 | self.draw(&mut terminal, &mut state)?; 47 | } 48 | Ok(()) 49 | } 50 | 51 | fn handle_crossterm(&mut self, event: CrosstermEvent, state: &mut ScrollState) -> Result<()> { 52 | match event { 53 | CrosstermEvent::Key(key) if key.kind == KeyEventKind::Press => { 54 | self.handle_key(key, state); 55 | } 56 | _ => {} 57 | } 58 | Ok(()) 59 | } 60 | 61 | fn handle_key(&mut self, key: KeyEvent, state: &mut ScrollState) { 62 | use KeyCode::*; 63 | match (key.modifiers, key.code) { 64 | (_, Char('q') | Esc) | (KeyModifiers::CONTROL, Char('c')) => { 65 | self.events.send(Event::Exit) 66 | } 67 | (_, Char('k') | Up) => state.scroll_up(), 68 | (_, Char('j') | Down) => state.scroll_down(), 69 | (_, Char('g') | Home) => state.scroll_top(), 70 | (_, Char('G') | End) => state.scroll_bottom(), 71 | (_, Char('b') | PageUp) | (KeyModifiers::SHIFT, Char(' ')) => state.scroll_page_up(), 72 | (_, Char('f') | PageDown) | (KeyModifiers::NONE, Char(' ')) => state.scroll_page_down(), 73 | (_, Char('l')) => self.toggle_logs(), 74 | _ => {} 75 | } 76 | } 77 | 78 | fn draw(&self, terminal: &mut DefaultTerminal, state: &mut ScrollState) -> Result<()> { 79 | terminal.draw(|frame| { 80 | frame.render_stateful_widget_ref(self, frame.area(), state); 81 | })?; 82 | Ok(()) 83 | } 84 | 85 | fn toggle_logs(&mut self) { 86 | self.show_logs = !self.show_logs 87 | } 88 | } 89 | 90 | /// necessary as ScrollbarState fields are private 91 | #[derive(Debug, Clone, Copy)] 92 | pub struct ScrollState { 93 | pub position: usize, 94 | pub view_size: usize, 95 | pub max: usize, 96 | } 97 | 98 | impl ScrollState { 99 | fn new(max: usize) -> ScrollState { 100 | ScrollState { 101 | position: 0, 102 | view_size: 1, 103 | max, 104 | } 105 | } 106 | 107 | fn scroll_down(&mut self) { 108 | self.position = self.position.saturating_add(1); 109 | } 110 | 111 | fn scroll_up(&mut self) { 112 | self.position = self.position.saturating_sub(1); 113 | } 114 | 115 | fn scroll_page_down(&mut self) { 116 | self.position = self.position.saturating_add(self.view_size); 117 | } 118 | 119 | fn scroll_page_up(&mut self) { 120 | self.position = self.position.saturating_sub(self.view_size); 121 | } 122 | 123 | fn scroll_top(&mut self) { 124 | self.position = 0; 125 | } 126 | 127 | fn scroll_bottom(&mut self) { 128 | self.position = self.max.saturating_sub(self.view_size); 129 | } 130 | } 131 | 132 | impl From<&mut ScrollState> for ScrollbarState { 133 | fn from(state: &mut ScrollState) -> ScrollbarState { 134 | ScrollbarState::new(state.max.saturating_sub(state.view_size)).position(state.position) 135 | } 136 | } 137 | 138 | impl From<&mut ScrollState> for ListState { 139 | fn from(state: &mut ScrollState) -> ListState { 140 | ListState::default().with_selected(Some(state.position)) 141 | } 142 | } 143 | 144 | impl StatefulWidgetRef for &App<'_> { 145 | type State = ScrollState; 146 | fn render_ref(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { 147 | let logs_height = if self.show_logs { 1 } else { 0 }; 148 | let [header, body, log] = Layout::vertical([ 149 | Constraint::Length(1), 150 | Constraint::Fill(2), 151 | Constraint::Fill(logs_height), 152 | ]) 153 | .areas(area); 154 | 155 | let [body, scrollbar] = 156 | Layout::horizontal([Constraint::Fill(1), Constraint::Length(1)]).areas(body); 157 | state.view_size = body.height as usize; 158 | // state.position = state 159 | // .position 160 | // .min(self.text.height().saturating_sub(state.view_size)); 161 | let header_line = Line::from(vec![ 162 | Span::raw("File: "), 163 | Span::styled(self.path.to_string_lossy(), (Color::White, Modifier::BOLD)), 164 | ]); 165 | Paragraph::new(header_line).render(header, buf); 166 | let position = state 167 | .position 168 | .min(self.text.height().saturating_sub(state.view_size)) as u16; 169 | Paragraph::new(self.text.clone()) 170 | .scroll((position, 0)) 171 | .wrap(Wrap { trim: false }) 172 | .render(body, buf); 173 | let mut scrollbar_state = state.into(); 174 | Scrollbar::new(ScrollbarOrientation::VerticalRight).render( 175 | scrollbar, 176 | buf, 177 | &mut scrollbar_state, 178 | ); 179 | 180 | let mut list_state = state.into(); 181 | self.log_events.render_ref(log, buf, &mut list_state); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /markdown-reader/src/events.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::{channel, Receiver, Sender}; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | use color_eyre::eyre::Context; 6 | use color_eyre::Result; 7 | use crossterm::event; 8 | 9 | pub type CrosstermEvent = crossterm::event::Event; 10 | 11 | pub enum Event { 12 | Crossterm(CrosstermEvent), 13 | Exit, 14 | } 15 | 16 | #[derive(Debug)] 17 | pub struct Events { 18 | pub event_rx: Receiver, 19 | pub event_tx: Sender, 20 | } 21 | 22 | impl Events { 23 | pub fn new() -> Result { 24 | let (event_tx, event_rx) = channel(); 25 | let crossterm_tx = event_tx.clone(); 26 | thread::spawn(move || poll_crossterm_events(crossterm_tx)); 27 | Ok(Events { event_rx, event_tx }) 28 | } 29 | 30 | pub fn send(&self, event: Event) { 31 | self.event_tx.send(event).unwrap(); 32 | } 33 | 34 | pub fn next(&self) -> Result { 35 | self.event_rx.recv().wrap_err("Done receiving events") 36 | } 37 | } 38 | 39 | fn poll_crossterm_events(event_tx: Sender) { 40 | loop { 41 | if event::poll(Duration::from_millis(100)).unwrap() { 42 | if let Ok(event) = event::read() { 43 | event_tx.send(Event::Crossterm(event)).unwrap(); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /markdown-reader/src/logging.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{Arc, RwLock}; 2 | use std::{fmt, iter, vec}; 3 | 4 | use color_eyre::Result; 5 | use itertools::Itertools; 6 | use ratatui::buffer::Buffer; 7 | use ratatui::layout::Rect; 8 | use ratatui::style::{Color, Modifier, Style, Stylize}; 9 | use ratatui::text::{Line, Span}; 10 | use ratatui::widgets::{ 11 | Block, Borders, List, ListItem, ListState, StatefulWidget, StatefulWidgetRef, 12 | }; 13 | use time::macros::format_description; 14 | use time::OffsetDateTime; 15 | use tracing::field::{Field, Visit}; 16 | use tracing::{Event, Level, Subscriber}; 17 | use tracing_error::ErrorLayer; 18 | use tracing_subscriber::layer::Context; 19 | use tracing_subscriber::prelude::*; 20 | use tracing_subscriber::{EnvFilter, Layer}; 21 | 22 | /// A logging layer that collects log messages 23 | #[derive(Debug, Default)] 24 | struct LogCollector { 25 | log_events: LogEvents, 26 | } 27 | 28 | /// A thread safe collection of log messages that can be rendered as a widget 29 | #[derive(Debug, Default, Clone)] 30 | pub struct LogEvents { 31 | logs: Arc>>, 32 | } 33 | 34 | /// A log message with a timestamp, target, level, message, and fields 35 | #[derive(Debug)] 36 | pub struct LogEvent { 37 | pub timestamp: OffsetDateTime, 38 | pub target: String, 39 | pub level: Level, 40 | pub message: String, 41 | pub fields: Vec<(String, String)>, 42 | } 43 | 44 | /// Initialize the logger with an optional log level and return the log message widget 45 | pub fn init_logger>>(log_level: T) -> Result { 46 | let log_collector = LogCollector::default(); 47 | let logs = log_collector.log_events.clone(); 48 | let mut env_filter = EnvFilter::from_default_env(); 49 | // Set the log level from the command line argument 50 | if let Some(log_level) = log_level.into() { 51 | env_filter = env_filter.add_directive(log_level.into()); 52 | } 53 | tracing_subscriber::registry() 54 | .with(log_collector) 55 | .with(env_filter) 56 | .with(ErrorLayer::default()) // capture span traces for color_eyre 57 | .try_init()?; 58 | Ok(logs) 59 | } 60 | 61 | impl Layer for LogCollector { 62 | fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) { 63 | let log_event = LogEvent::from(event); 64 | self.log_events.push(log_event); 65 | } 66 | } 67 | 68 | impl LogEvents { 69 | fn push(&self, log: LogEvent) { 70 | self.logs.write().unwrap().push(log); 71 | } 72 | } 73 | 74 | impl From<&Event<'_>> for LogEvent { 75 | /// Convert a tracing event into a log message 76 | fn from(event: &Event) -> Self { 77 | let metadata = event.metadata(); 78 | let target = metadata.target(); 79 | let level = metadata.level(); 80 | let mut log_message = LogEvent { 81 | timestamp: OffsetDateTime::now_utc(), 82 | target: target.to_string(), 83 | level: *level, 84 | message: String::new(), 85 | fields: Vec::new(), 86 | }; 87 | event.record(&mut log_message); 88 | log_message 89 | } 90 | } 91 | 92 | impl Visit for LogEvent { 93 | /// Extract the message and fields from the tracing event into the log message 94 | fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { 95 | if field.name() == "message" { 96 | self.message = format!("{:?}", value); 97 | } else { 98 | let name = field.name().to_string(); 99 | let value = format!("{:?}", value); 100 | self.fields.push((name, value)); 101 | } 102 | } 103 | } 104 | 105 | impl StatefulWidgetRef for LogEvents { 106 | type State = ListState; 107 | fn render_ref(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { 108 | let logs = self.logs.read().unwrap(); 109 | let block = Block::default().borders(Borders::ALL).title("Logs"); 110 | let list = List::new(logs.iter()).block(block); 111 | StatefulWidget::render(list, area, buf, state); 112 | } 113 | } 114 | 115 | impl<'a> From<&'a LogEvent> for ListItem<'a> { 116 | /// Convert a log message into a list item with the timestamp, log level, target, message, and 117 | /// fields 118 | /// 119 | /// ```plain 120 | /// 02:32:25 [DEBUG] counter_app_events::events handling event 121 | /// event=Redraw 122 | /// ```` 123 | fn from(log: &'a LogEvent) -> Self { 124 | let message_line = Line::from(vec![ 125 | timestamp_span(log.timestamp), 126 | log_level_span(log.level), 127 | format!(" {}", log.target).dim(), 128 | format!(" {}", log.message).white(), 129 | ]); 130 | let field_lines = log.fields.iter().map(field_line); 131 | let lines = iter::once(message_line).chain(field_lines).collect_vec(); 132 | ListItem::new(lines) 133 | } 134 | } 135 | 136 | /// Create a span with the log level colored based on the log level 137 | fn log_level_span(log_level: Level) -> Span<'static> { 138 | Span::styled( 139 | format!(" [{:5}]", log_level), 140 | Style::default().fg(match log_level { 141 | Level::ERROR => Color::Red, 142 | Level::WARN => Color::Yellow, 143 | Level::INFO => Color::Green, 144 | Level::DEBUG => Color::Blue, 145 | Level::TRACE => Color::Magenta, 146 | }), 147 | ) 148 | } 149 | 150 | /// Create a span with the timestamp formatted as "hour:minute:second" 151 | fn timestamp_span(timestamp: OffsetDateTime) -> Span<'static> { 152 | let format = format_description!("[hour]:[minute]:[second]"); 153 | timestamp.format(&format).unwrap().dim() 154 | } 155 | 156 | /// Create an indented line with a field name and value 157 | fn field_line((name, value): &(String, String)) -> Line<'_> { 158 | Line::styled( 159 | format!(" {:}={}", name, value), 160 | (Color::LightBlue, Modifier::ITALIC | Modifier::DIM), 161 | ) 162 | } 163 | -------------------------------------------------------------------------------- /markdown-reader/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{BufReader, Read}; 3 | use std::path::{Path, PathBuf}; 4 | 5 | use clap::builder::styling::AnsiColor; 6 | use clap::builder::Styles; 7 | use clap::Parser; 8 | use color_eyre::eyre::{eyre, Ok, WrapErr}; 9 | use color_eyre::Result; 10 | use tracing::{debug, info, Level}; 11 | 12 | use crate::app::App; 13 | use crate::events::Events; 14 | 15 | mod app; 16 | mod events; 17 | mod logging; 18 | 19 | fn main() -> Result<()> { 20 | color_eyre::install()?; 21 | let terminal = ratatui::init(); 22 | let log_events = logging::init_logger(Level::DEBUG)?; 23 | 24 | let args = Cli::parse(); 25 | let path = args.path; 26 | let events = Events::new()?; 27 | info!("Reading file {:?}", path); 28 | let markdown = read_file(&path)?; 29 | let text = tui_markdown::from_str(&markdown); 30 | let _height = text.height(); 31 | let app = App::new(text, &path, events, log_events); 32 | let result = app.run(terminal); 33 | ratatui::restore(); 34 | result 35 | } 36 | 37 | fn read_file(path: &Path) -> Result { 38 | debug!("Reading file {:?}", path); 39 | let input = File::open(path).wrap_err_with(|| eyre!("Could not open {:?}", path))?; 40 | let mut reader = BufReader::new(input); 41 | let mut buf = String::new(); 42 | reader 43 | .read_to_string(&mut buf) 44 | .wrap_err("Could not read file")?; 45 | Ok(buf) 46 | } 47 | 48 | const HELP_STYLES: Styles = Styles::styled() 49 | .header(AnsiColor::Blue.on_default().bold()) 50 | .usage(AnsiColor::Blue.on_default().bold()) 51 | .literal(AnsiColor::White.on_default()) 52 | .placeholder(AnsiColor::Green.on_default()); 53 | 54 | #[derive(Debug, Parser)] 55 | #[command(author, version, about, styles = HELP_STYLES)] 56 | struct Cli { 57 | /// The path to the markdown file to read 58 | #[arg(default_value = "README.md")] 59 | path: PathBuf, 60 | } 61 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | # configuration for https://rust-lang.github.io/rustfmt/ 2 | 3 | use_field_init_shorthand = true 4 | 5 | # unstable options 6 | comment_width = 100 7 | format_code_in_doc_comments = true 8 | format_macro_matchers = true 9 | group_imports = "StdExternalCrate" 10 | imports_granularity = "Module" 11 | normalize_doc_attributes = true 12 | wrap_comments = true 13 | -------------------------------------------------------------------------------- /tui-markdown/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [unreleased] 6 | 7 | ## [0.3.5](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.3.4...tui-markdown-v0.3.5) - 2025-05-07 8 | 9 | ### Other 10 | 11 | - *(deps)* bump the cargo-dependencies group across 1 directory with 5 updates ([#79](https://github.com/joshka/tui-markdown/pull/79)) 12 | 13 | ## [0.3.4](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.3.3...tui-markdown-v0.3.4) - 2025-05-07 14 | 15 | ### Other 16 | 17 | - remove unnecessary allowed lints ([#82](https://github.com/joshka/tui-markdown/pull/82)) 18 | - add rustfmt and reformat code ([#81](https://github.com/joshka/tui-markdown/pull/81)) 19 | 20 | ## [0.3.3](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.3.2...tui-markdown-v0.3.3) - 2025-03-11 21 | 22 | ### Other 23 | 24 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#71](https://github.com/joshka/tui-markdown/pull/71)) 25 | 26 | ## [0.3.2](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.3.1...tui-markdown-v0.3.2) - 2025-03-09 27 | 28 | ### Other 29 | 30 | - *(deps)* bump the cargo-dependencies group across 1 directory with 5 updates ([#70](https://github.com/joshka/tui-markdown/pull/70)) 31 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#66](https://github.com/joshka/tui-markdown/pull/66)) 32 | - *(deps)* bump the cargo-dependencies group across 1 directory with 4 updates ([#64](https://github.com/joshka/tui-markdown/pull/64)) 33 | 34 | ## [0.3.1](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.3.0...tui-markdown-v0.3.1) - 2024-12-17 35 | 36 | ### Added 37 | 38 | - Add support for links by replacing inner value (#62) 39 | 40 | ### Other 41 | 42 | - *(deps)* bump the cargo-dependencies group with 5 updates (#60) 43 | 44 | ## [0.3.0](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.12...tui-markdown-v0.3.0) - 2024-11-20 45 | 46 | ### Other 47 | 48 | - *(deps)* bump the cargo-dependencies group across 1 directory with 3 updates ([#58](https://github.com/joshka/tui-markdown/pull/58)) 49 | 50 | ## [0.2.12](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.11...tui-markdown-v0.2.12) - 2024-10-22 51 | 52 | ### Other 53 | 54 | - *(deps)* bump pulldown-cmark in the cargo-dependencies group ([#54](https://github.com/joshka/tui-markdown/pull/54)) 55 | 56 | ## [0.2.11](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.10...tui-markdown-v0.2.11) - 2024-10-13 57 | 58 | ### Added 59 | 60 | - highlight code blocks ([#51](https://github.com/joshka/tui-markdown/pull/51)) 61 | 62 | ### Other 63 | 64 | - *(deps)* bump rstest in the cargo-dependencies group ([#50](https://github.com/joshka/tui-markdown/pull/50)) 65 | 66 | ## [0.2.10](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.9...tui-markdown-v0.2.10) - 2024-09-20 67 | 68 | ### Other 69 | 70 | - add tests, implement more markdown features, don't panic for unimplemented features ([#45](https://github.com/joshka/tui-markdown/pull/45)) 71 | 72 | ## [0.2.9](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.8...tui-markdown-v0.2.9) - 2024-09-20 73 | 74 | ### Other 75 | 76 | - add support for unordered list ([#44](https://github.com/joshka/tui-markdown/pull/44)) 77 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#42](https://github.com/joshka/tui-markdown/pull/42)) 78 | 79 | ## [0.2.8](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.7...tui-markdown-v0.2.8) - 2024-09-02 80 | 81 | ### Other 82 | 83 | - *(deps)* bump the cargo-dependencies group across 1 directory with 3 updates ([#41](https://github.com/joshka/tui-markdown/pull/41)) 84 | - *(deps)* bump the cargo-dependencies group with 2 updates ([#38](https://github.com/joshka/tui-markdown/pull/38)) 85 | 86 | ## [0.2.7](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.6...tui-markdown-v0.2.7) - 2024-08-06 87 | 88 | ### Other 89 | 90 | - use crossterm version re-exported from ratatui 91 | 92 | ## [0.2.6](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.5...tui-markdown-v0.2.6) - 2024-06-24 93 | 94 | ### Other 95 | 96 | - *(deps)* bump ratatui in the cargo-dependencies group ([#29](https://github.com/joshka/tui-markdown/pull/29)) 97 | 98 | ## [0.2.5](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.4...tui-markdown-v0.2.5) - 2024-06-08 99 | 100 | ### Fixed 101 | 102 | - link to crate pages 103 | 104 | ## [0.2.4](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.3...tui-markdown-v0.2.4) - 2024-05-22 105 | 106 | ### Other 107 | 108 | - *(deps)* bump the cargo-dependencies group with 3 updates ([#24](https://github.com/joshka/tui-markdown/pull/24)) 109 | 110 | ## [0.2.3](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.2...tui-markdown-v0.2.3) - 2024-04-24 111 | 112 | ### Other 113 | 114 | - *(deps)* bump pulldown-cmark ([#23](https://github.com/joshka/tui-markdown/pull/23)) 115 | - *(deps)* bump ratatui from 0.26.1 to 0.26.2 ([#20](https://github.com/joshka/tui-markdown/pull/20)) 116 | - *(deps)* bump pulldown-cmark from 0.10.0 to 0.10.2 ([#19](https://github.com/joshka/tui-markdown/pull/19)) 117 | 118 | ## [0.2.2](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.1...tui-markdown-v0.2.2) - 2024-02-29 119 | 120 | ### Other 121 | 122 | - update license info in readme files 123 | - add a note about the experimental state 124 | 125 | ## [0.2.1](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.2.0...tui-markdown-v0.2.1) - 2024-02-27 126 | 127 | ### Other 128 | 129 | - fix more links / badges 130 | - fmt 131 | 132 | ## [0.2.0](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.1.1...tui-markdown-v0.2.0) - 2024-02-27 133 | 134 | ### Added 135 | 136 | - add filename and pageUp/Down 137 | - support code blocks in tui-markdown 138 | 139 | ### Fixed 140 | 141 | - Update urls in Cargo.toml ([#4](https://github.com/joshka/tui-markdown/pull/4)) 142 | 143 | ### Other 144 | 145 | - add note about newlines 146 | 147 | ## [0.1.1](https://github.com/joshka/tui-markdown/compare/tui-markdown-v0.1.0...tui-markdown-v0.1.1) - 2024-02-27 148 | 149 | ### Other 150 | 151 | - add CHANGELOGs 152 | 153 | ### 🚀 Features 154 | 155 | - Initial implementation of lib and tui 156 | 157 | ### 🐛 Bug Fixes 158 | 159 | - Tui-markdown crate dependency for markdown-reader 160 | 161 | ### 📚 Documentation 162 | 163 | - Add demo for markdown-reader 164 | 165 | ### ⚙️ Miscellaneous Tasks 166 | 167 | - Add ci and release workflows 168 | 169 | 170 | -------------------------------------------------------------------------------- /tui-markdown/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tui-markdown" 3 | description = "A simple library for converting markdown to a Rataui Text value" 4 | version = "0.3.5" 5 | documentation = "https://docs.rs/tui-markdown" 6 | categories = ["command-line-interface"] 7 | keywords = ["cli", "markdown", "ratatui", "terminal", "tui"] 8 | 9 | edition.workspace = true 10 | rust-version.workspace = true 11 | license.workspace = true 12 | repository.workspace = true 13 | authors.workspace = true 14 | 15 | [features] 16 | default = ["highlight-code"] 17 | 18 | ## Enable syntax highlighting using syntect and ansi-to-tui 19 | highlight-code = ["dep:syntect", "dep:ansi-to-tui"] 20 | 21 | [package.metadata.docs.rs] 22 | all-features = true 23 | # see https://doc.rust-lang.org/nightly/rustdoc/scraped-examples.html 24 | cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] 25 | rustdoc-args = ["--cfg", "docsrs"] 26 | 27 | [dependencies] 28 | ansi-to-tui = { version = "7.0.0", optional = true } 29 | document-features = { version = "0.2.11", optional = true } 30 | itertools = "0.14.0" 31 | pretty_assertions = "1.4.1" 32 | pulldown-cmark = "0.13.0" 33 | ratatui.workspace = true 34 | rstest = "0.25.0" 35 | syntect = { version = "5.2.0", optional = true } 36 | tracing = "0.1.41" 37 | 38 | [dev-dependencies] 39 | indoc = "2.0.6" 40 | insta = "1.43.1" 41 | tracing-subscriber = "0.3.19" 42 | -------------------------------------------------------------------------------- /tui-markdown/README.md: -------------------------------------------------------------------------------- 1 | # Tui-markdown 2 | 3 | An experimental Proof of Concept library for converting markdown content to a [Ratatui] `Text` 4 | value. See [Markdown-reader] for an example application that uses this library. 5 | 6 | [![Crate badge]][tui-markdown] 7 | [![Docs.rs Badge]][API Docs] 8 | [![Deps.rs Badge]][Dependency Status] 9 | [![License Badge]](../LICENSE-MIT) 10 | [![Codecov.io Badge]][Code Coverage] 11 | [![Discord Badge]][Ratatui Discord] 12 | 13 | [GitHub Repository] · [API Docs] · [Examples] · [Changelog] · [Contributing] 14 | 15 | ## Installation 16 | 17 | ```shell 18 | cargo add tui-markdown 19 | ``` 20 | 21 | ## Usage 22 | 23 | ```rust 24 | let input = "# Heading\n\n**bold**"; // this can come from whereever 25 | let text = tui_markdown::from_str(input); 26 | text.render(area, &mut buf); 27 | ``` 28 | 29 | ## Status 30 | 31 | This is working code, but not every markdown feature is supported. PRs welcome! 32 | 33 | - [x] Headings 34 | - [ ] Heading attributes / classes / anchors 35 | - [x] Normal paragraphs 36 | - [x] Block quotes 37 | - [x] Nested block quotes 38 | - [x] Bold (strong) 39 | - [x] Italic (emphasis) 40 | - [x] Strikethrough 41 | - [x] Ordered lists 42 | - [x] Unordered lists 43 | - [x] Code blocks 44 | - [ ] Html 45 | - [ ] Footnotes 46 | - [ ] Tables 47 | - [ ] Linebreak handling 48 | - [ ] Rule 49 | - [ ] Tasklists 50 | - [ ] Links 51 | - [ ] Images 52 | - [ ] Metadata blocks 53 | - [ ] Superscript 54 | - [ ] Subscript 55 | 56 | ## License 57 | 58 | Copyright (c) 2024 Josh McKinney 59 | 60 | This project is licensed under either of 61 | 62 | - Apache License, Version 2.0 63 | ([LICENSE-APACHE](../LICENSE-APACHE) or ) 64 | - MIT license 65 | ([LICENSE-MIT](../LICENSE-MIT) or ) 66 | 67 | at your option. 68 | 69 | ## Contribution 70 | 71 | Unless you explicitly state otherwise, any contribution intentionally submitted 72 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 73 | dual licensed as above, without any additional terms or conditions. 74 | 75 | See [CONTRIBUTING.md](../CONTRIBUTING.md). 76 | 77 | [tui-markdown]: https://crates.io/crates/tui-markdown 78 | [markdown-reader]: https://crates.io/crates/markdown-reader 79 | [Ratatui]: https://crates.io/crates/ratatui 80 | 81 | [Crate badge]: https://img.shields.io/crates/v/tui-markdown?logo=rust&style=for-the-badge 82 | [Docs.rs Badge]: https://img.shields.io/docsrs/tui-markdown?logo=rust&style=for-the-badge 83 | [Deps.rs Badge]: https://deps.rs/repo/github/joshka/tui-markdown/status.svg?path=tui-markdown&style=for-the-badge 84 | [License Badge]: https://img.shields.io/crates/l/tui-markdown?style=for-the-badge 85 | [Codecov.io Badge]: https://img.shields.io/codecov/c/github/joshka/tui-markdown?logo=codecov&style=for-the-badge&token=BAQ8SOKEST 86 | [Discord Badge]: https://img.shields.io/discord/1070692720437383208?label=ratatui+discord&logo=discord&style=for-the-badge 87 | 88 | [API Docs]: https://docs.rs/crate/tui-markdown/ 89 | [Dependency Status]: https://deps.rs/crate/tui-markdown 90 | [Code Coverage]: https://app.codecov.io/gh/joshka/tui-markdown 91 | [Ratatui Discord]: https://discord.gg/pMCEU9hNEj 92 | 93 | [GitHub Repository]: https://github.com/joshka/tui-markdown 94 | [Changelog]: https://github.com/joshka/tui-markdown/blob/main/tui-markdown/CHANGELOG.md 95 | [Contributing]: https://github.com/joshka/tui-markdown/blob/main/CONTRIBUTING.md 96 | -------------------------------------------------------------------------------- /tui-markdown/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A simple markdown renderer widget for Ratatui. 2 | //! 3 | //! This module provides a simple markdown renderer widget for Ratatui. It uses the `pulldown-cmark` 4 | //! crate to parse markdown and convert it to a `Text` widget. The `Text` widget can then be 5 | //! rendered to the terminal using the 'Ratatui' library. 6 | #![cfg_attr(feature = "document-features", doc = "\n# Features")] 7 | #![cfg_attr(feature = "document-features", doc = document_features::document_features!())] 8 | //! # Example 9 | //! 10 | //! ~~~ 11 | //! use ratatui::text::Text; 12 | //! use tui_markdown::from_str; 13 | //! 14 | //! # fn draw(frame: &mut ratatui::Frame) { 15 | //! let markdown = r#" 16 | //! This is a simple markdown renderer for Ratatui. 17 | //! 18 | //! - List item 1 19 | //! - List item 2 20 | //! 21 | //! ```rust 22 | //! fn main() { 23 | //! println!("Hello, world!"); 24 | //! } 25 | //! ``` 26 | //! "#; 27 | //! 28 | //! let text = from_str(markdown); 29 | //! frame.render_widget(text, frame.area()); 30 | //! # } 31 | //! ~~~ 32 | 33 | use std::sync::LazyLock; 34 | use std::vec; 35 | 36 | #[cfg(feature = "highlight-code")] 37 | use ansi_to_tui::IntoText; 38 | use itertools::{Itertools, Position}; 39 | use pulldown_cmark::{ 40 | BlockQuoteKind, CodeBlockKind, CowStr, Event, HeadingLevel, Options, Parser, Tag, TagEnd, 41 | }; 42 | use ratatui::style::{Style, Stylize}; 43 | use ratatui::text::{Line, Span, Text}; 44 | #[cfg(feature = "highlight-code")] 45 | use syntect::{ 46 | easy::HighlightLines, 47 | highlighting::ThemeSet, 48 | parsing::SyntaxSet, 49 | util::{as_24_bit_terminal_escaped, LinesWithEndings}, 50 | }; 51 | use tracing::{debug, instrument, warn}; 52 | 53 | pub fn from_str(input: &str) -> Text { 54 | let mut options = Options::empty(); 55 | options.insert(Options::ENABLE_STRIKETHROUGH); 56 | let parser = Parser::new_ext(input, options); 57 | let mut writer = TextWriter::new(parser); 58 | writer.run(); 59 | writer.text 60 | } 61 | 62 | struct TextWriter<'a, I> { 63 | /// Iterator supplying events. 64 | iter: I, 65 | 66 | /// Text to write to. 67 | text: Text<'a>, 68 | 69 | /// Current style. 70 | /// 71 | /// This is a stack of styles, with the top style being the current style. 72 | inline_styles: Vec