diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000000..784fc28593 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,66 @@ +name: Build & Test + +on: + push: + branches: ["*"] + +env: + # Cross-compilation for aarch64 requires a different linker + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc + +permissions: + contents: read + +jobs: + Tests: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + target: + - x86_64-unknown-linux-gnu + - aarch64-unknown-linux-gnu + - x86_64-pc-windows-msvc + - x86_64-apple-darwin + - aarch64-apple-darwin + rustup_toolchain: [stable] + include: + - os: windows-2022 + target: x86_64-pc-windows-msvc + - os: ubuntu-20.04 + target: x86_64-unknown-linux-gnu + - os: ubuntu-20.04 + target: aarch64-unknown-linux-gnu + - os: macos-13 + target: x86_64-apple-darwin + - os: macos-14 + target: aarch64-apple-darwin + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ matrix.rustup_toolchain }} + + - name: Install Rust crosscompile tools + if: ${{ contains(matrix.target, 'aarch64-unknown-linux-gnu') }} + run: | + sudo apt-get update -y + sudo apt-get install -y make g++ libssl-dev gcc-aarch64-linux-gnu + rustup target add aarch64-unknown-linux-gnu + + - name: Cargo build (Native TLS) + run: | + cargo build --all --no-default-features --features=native-tls + cargo clean + + - name: Cargo build (Rust TLS) + run: cargo build --all + + - name: Cargo test + run: cargo test --all + + - name: Cargo fmt + run: cargo fmt --check diff --git a/.github/workflows/cd-workflow.yml b/.github/workflows/cd-workflow.yml deleted file mode 100644 index 6d20ea7664..0000000000 --- a/.github/workflows/cd-workflow.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Mostly copied from https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#publishing-a-package-using-an-action -# Main difference is the push filter on the tag. -# -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -name: Create and publish a Docker image - -on: - push: - tags: [ 'v*.*.*' ] - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - -jobs: - build-and-push-image: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Log in to the Container registry - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - flavor: latest=false - - - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1f1db2fb77..ba06fdeccf 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,7 +20,7 @@ jobs: env: BUILD_DIR: docs/ BUILD_ONLY: true - + build_and_deploy: runs-on: ubuntu-latest if: github.ref == 'refs/heads/master' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..ae79c850ba --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,165 @@ +name: Release + +on: + push: + tags: ["v*.*.*"] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + # Cross-compilation for aarch64 requires a different linker + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc + +permissions: + contents: read + +jobs: + Release-Build: + runs-on: ${{ matrix.os }} + permissions: + contents: read + attestations: write + id-token: write + strategy: + matrix: + target: + - x86_64-unknown-linux-gnu + - aarch64-unknown-linux-gnu + - x86_64-pc-windows-msvc + - x86_64-apple-darwin + - aarch64-apple-darwin + rustup_toolchain: [stable] + include: + - os: windows-2022 + target: x86_64-pc-windows-msvc + - os: ubuntu-20.04 + target: x86_64-unknown-linux-gnu + - os: ubuntu-20.04 + target: aarch64-unknown-linux-gnu + - os: macos-13 + target: x86_64-apple-darwin + - os: macos-14 + target: aarch64-apple-darwin + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ matrix.rustup_toolchain }} + + - name: Install Rust crosscompile tools + if: ${{ contains(matrix.target, 'aarch64-unknown-linux-gnu') }} + run: | + sudo apt-get update -y + sudo apt-get install -y make g++ libssl-dev gcc-aarch64-linux-gnu + rustup target add aarch64-unknown-linux-gnu + + - name: Cargo build + run: cargo build --release --target ${{ matrix.target }} + + - name: Archive (UNIX) + run: | + mkdir -p artifacts + cp -av target/${{ matrix.target }}/release/zola . + tar -czf ${{ github.event.repository.name }}-${{ github.ref_name }}-${{ matrix.target }}.tar.gz zola + if: ${{ ! startsWith(matrix.os, 'windows') }} + + - name: Archive (Windows) + run: | + mkdir -p artifacts + cp target/${{ matrix.target }}/release/zola.exe . + Compress-Archive zola.exe ${{ github.event.repository.name }}-${{ github.ref_name }}-${{ matrix.target }}.zip + if: ${{ startsWith(matrix.os, 'windows') }} + + - name: Attest Build Provenance + uses: actions/attest-build-provenance@v1 + continue-on-error: true + with: + subject-path: ${{ github.event.repository.name }}-${{ github.ref_name }}-${{ matrix.target }}.* + + - uses: actions/upload-artifact@v4 + with: + name: ${{ github.event.repository.name }}-${{ github.ref_name }}-${{ matrix.target }} + path: ${{ github.event.repository.name }}-${{ github.ref_name }}-${{ matrix.target }}.* + if-no-files-found: error + retention-days: 7 + + Release: + needs: [Release-Build] + runs-on: ubuntu-22.04 + permissions: + contents: write + + steps: + - name: Ensure artifacts dir exists + run: mkdir -p artifacts + + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: true + + - name: Release + uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 + with: + name: ${{ github.ref_name }} + tag_name: ${{ github.ref_name }} + generate_release_notes: true + fail_on_unmatched_files: true + body: | + Welcome to this new release of Zola ${{ github.ref_name }}! + + All artifacts are signed with this repos identity using Sigstore. + You can verify the signatures using the `GitHub` CLI. + + ```shell + gh attestation verify --owner ${{ github.repository_owner }} + ``` + token: ${{ secrets.GITHUB_TOKEN }} + prerelease: ${{ contains(github.ref, '-pre') }} + files: artifacts/* + + Release-Container-Image: + needs: [Release] + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + flavor: latest=false + + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + context: . + push: true + build-args: | + USE_GH_RELEASE=true + ZOLA_RELEASE_VERSION=${{ github.ref_name }} + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitmodules b/.gitmodules index aba5d052a8..19bd59a65c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,78 +1,78 @@ [submodule "sublime/syntaxes/Packages"] - path = sublime/syntaxes/Packages + path = components/config/sublime/syntaxes/Packages url = https://github.com/sublimehq/Packages.git [submodule "sublime/syntaxes/awk-sublime"] - path = sublime/syntaxes/extra/awk-sublime + path = components/config/sublime/syntaxes/extra/awk-sublime url = https://github.com/JohnNilsson/awk-sublime.git [submodule "sublime/syntaxes/AsciiDoc"] path = sublime/syntaxes/AsciiDoc url = https://github.com/SublimeText/AsciiDoc.git [submodule "sublime/syntaxes/Sublime-CMakeLists"] - path = sublime/syntaxes/extra/Sublime-CMakeLists + path = components/config/sublime/syntaxes/extra/Sublime-CMakeLists url = https://github.com/zyxar/Sublime-CMakeLists.git [submodule "sublime/syntaxes/SublimeTextLinkerSyntax"] - path = sublime/syntaxes/extra/SublimeTextLinkerSyntax + path = components/config/sublime/syntaxes/extra/SublimeTextLinkerSyntax url = https://github.com/jbw3/SublimeTextLinkerSyntax [submodule "sublime/syntaxes/Docker.tmbundle"] - path = sublime/syntaxes/extra/Docker.tmbundle + path = components/config/sublime/syntaxes/extra/Docker.tmbundle url = https://github.com/asbjornenge/Docker.tmbundle.git [submodule "sublime/syntaxes/Sublime-VimL"] path = sublime/syntaxes/Sublime-VimL url = https://github.com/SalGnt/Sublime-VimL.git [submodule "sublime/syntaxes/elixir-sublime-syntax"] - path = sublime/syntaxes/extra/elixir-sublime-syntax + path = components/config/sublime/syntaxes/extra/elixir-sublime-syntax url = https://github.com/princemaple/elixir-sublime-syntax.git [submodule "sublime/syntaxes/SublimeElmLanguageSupport"] - path = sublime/syntaxes/extra/SublimeElmLanguageSupport + path = components/config/sublime/syntaxes/extra/SublimeElmLanguageSupport url = https://github.com/elm-community/SublimeElmLanguageSupport.git [submodule "sublime/syntaxes/sublimetext-fsharp"] - path = sublime/syntaxes/extra/sublimetext-fsharp + path = components/config/sublime/syntaxes/extra/sublimetext-fsharp url = https://github.com/hoest/sublimetext-fsharp.git [submodule "sublime/syntaxes/sublime-fish"] - path = sublime/syntaxes/extra/sublime-fish + path = components/config/sublime/syntaxes/extra/sublime-fish url = https://github.com/Phidica/sublime-fish.git [submodule "sublime/syntaxes/SublimeFortran"] - path = sublime/syntaxes/extra/SublimeFortran + path = components/config/sublime/syntaxes/extra/SublimeFortran url = https://github.com/315234/SublimeFortran.git [submodule "sublime/syntaxes/GraphQL-SublimeText3"] - path = sublime/syntaxes/extra/GraphQL-SublimeText3 + path = components/config/sublime/syntaxes/extra/GraphQL-SublimeText3 url = https://github.com/dncrews/GraphQL-SublimeText3.git [submodule "sublime/syntaxes/Sublime-GenericConfig"] - path = sublime/syntaxes/extra/Sublime-GenericConfig + path = components/config/sublime/syntaxes/extra/Sublime-GenericConfig url = https://github.com/skozlovf/Sublime-GenericConfig.git [submodule "sublime/syntaxes/sublime-jinja2"] - path = sublime/syntaxes/extra/sublime-jinja2 + path = components/config/sublime/syntaxes/extra/sublime-jinja2 url = https://github.com/Martin819/sublime-jinja2.git [submodule "sublime/syntaxes/Julia-sublime"] - path = sublime/syntaxes/extra/Julia-sublime + path = components/config/sublime/syntaxes/extra/Julia-sublime url = https://github.com/JuliaEditorSupport/Julia-sublime.git [submodule "sublime/syntaxes/LESS-sublime"] - path = sublime/syntaxes/extra/LESS-sublime + path = components/config/sublime/syntaxes/extra/LESS-sublime url = https://github.com/danro/LESS-sublime.git [submodule "sublime/syntaxes/sublime-purescript-syntax"] - path = sublime/syntaxes/extra/sublime-purescript-syntax + path = components/config/sublime/syntaxes/extra/sublime-purescript-syntax url = https://github.com/tellnobody1/sublime-purescript-syntax.git [submodule "sublime/syntaxes/SublimeSass"] - path = sublime/syntaxes/extra/SublimeSass + path = components/config/sublime/syntaxes/extra/SublimeSass url = https://github.com/braver/SublimeSass.git [submodule "sublime/syntaxes/sublime_toml_highlighting"] - path = sublime/syntaxes/extra/sublime_toml_highlighting + path = components/config/sublime/syntaxes/extra/sublime_toml_highlighting url = https://github.com/jasonwilliams/sublime_toml_highlighting.git [submodule "sublime/syntaxes/vue-syntax-highlight"] - path = sublime/syntaxes/extra/vue-syntax-highlight + path = components/config/sublime/syntaxes/extra/vue-syntax-highlight url = https://github.com/vuejs/vue-syntax-highlight.git [submodule "sublime/syntaxes/sublime-glsl"] - path = sublime/syntaxes/extra/sublime-glsl + path = components/config/sublime/syntaxes/extra/sublime-glsl url = https://github.com/euler0/sublime-glsl.git [submodule "sublime/syntaxes/GDScript-sublime"] - path = sublime/syntaxes/extra/GDScript-sublime + path = components/config/sublime/syntaxes/extra/GDScript-sublime url = https://github.com/beefsack/GDScript-sublime.git [submodule "sublime/syntaxes/extra/sublime-clojure"] - path = sublime/syntaxes/extra/sublime-clojure + path = components/config/sublime/syntaxes/extra/sublime-clojure url = https://github.com/tonsky/sublime-clojure.git [submodule "sublime/syntaxes/extra/sublime-zig-language"] - path = sublime/syntaxes/extra/sublime-zig-language + path = components/config/sublime/syntaxes/extra/sublime-zig-language url = https://github.com/ziglang/sublime-zig-language.git [submodule "sublime/syntaxes/extra/protobuf-syntax-highlighting"] - path = sublime/syntaxes/extra/protobuf-syntax-highlighting + path = components/config/sublime/syntaxes/extra/protobuf-syntax-highlighting url = https://github.com/VcamX/protobuf-syntax-highlighting.git diff --git a/CHANGELOG.md b/CHANGELOG.md index b446f55c3d..23093248ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 0.20.0 (unreleased) + +- Add `name` annotation for codeblock +- Add argument to `zola serve` to watch additional directories +- Disable JS minification when minifying HTML, it can result in broken JS +- Add external links class option to Markdown configuration +- Improve accessibility by nesting bottom footnotes inside footer element +- Add pagination info to sections +- Exclude paginated pages in sitemap by default +- Allow treating a missing highlight language as error +- Handle more editors with change detection in `zola serve` +- Add argument to `zola serve` to write HTML files to disk (`--store-html`) +- Add optional parsing of Markdown definition lists + + ## 0.19.2 (2024-08-15) - Fix some of YAML date parsing diff --git a/Cargo.lock b/Cargo.lock index 402de69959..09264fddaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -65,6 +65,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "ammonia" version = "4.0.0" @@ -95,9 +101,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -110,36 +116,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -150,15 +156,15 @@ checksum = "70033777eb8b5124a81a1889416543dddef2de240019b674c81285a2635a7e1e" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" [[package]] name = "arg_enum_proc_macro" @@ -168,14 +174,14 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert-json-diff" @@ -187,6 +193,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -200,9 +212,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "av1-grain" @@ -220,34 +232,28 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" dependencies = [ "arrayvec", ] [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -286,15 +292,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "bitstream-io" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac55ccd165b210af261b1812cf29a0b9e6303b480ff0df603c037129ff357fe" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" [[package]] name = "bitvec" @@ -340,9 +346,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "serde", @@ -356,9 +362,9 @@ checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7" [[package]] name = "built" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" [[package]] name = "bumpalo" @@ -402,9 +408,9 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.16.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder" @@ -430,19 +436,19 @@ dependencies = [ [[package]] name = "bytes" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.0.99" +version = "1.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "ad0cf6e91fde44c773c6ee7ec6bba798504641a8bc2eb7e37a04ffbf4dfaa55a" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -478,21 +484,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "pure-rust-locales", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -503,7 +509,7 @@ checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" dependencies = [ "chrono", "chrono-tz-build", - "phf 0.11.2", + "phf", ] [[package]] @@ -513,8 +519,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" dependencies = [ "parse-zoneinfo", - "phf 0.11.2", - "phf_codegen 0.11.2", + "phf", + "phf_codegen", ] [[package]] @@ -536,33 +542,33 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.7" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", - "clap_derive 4.5.5", + "clap_derive 4.5.24", ] [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.1", + "clap_lex 0.7.4", "strsim 0.11.1", ] [[package]] name = "clap_complete" -version = "4.5.5" +version = "4.5.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4" +checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0" dependencies = [ - "clap 4.5.7", + "clap 4.5.26", ] [[package]] @@ -580,14 +586,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -601,9 +607,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "codemap" @@ -619,18 +625,18 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -653,14 +659,14 @@ dependencies = [ [[package]] name = "console" -version = "0.15.8" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] @@ -693,11 +699,21 @@ dependencies = [ "markdown", "serde", "tempfile", + "templates", "test-case", "time", "utils", ] +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -710,15 +726,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -741,20 +757,11 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -771,9 +778,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -800,7 +807,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf", "smallvec", ] @@ -820,14 +827,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] name = "csv" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -846,12 +853,12 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.4" +version = "3.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" dependencies = [ "nix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -918,13 +925,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -950,9 +957,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elasticlunr-rs" @@ -972,9 +979,9 @@ dependencies = [ [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding" @@ -1040,15 +1047,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "env_logger" version = "0.9.3" @@ -1068,14 +1066,24 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1087,12 +1095,11 @@ dependencies = [ [[package]] name = "exr" -version = "1.72.0" +version = "1.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" dependencies = [ "bit_field", - "flume", "half", "lebe", "miniz_oxide", @@ -1109,59 +1116,50 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] [[package]] name = "file-id" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6584280525fb2059cba3db2c04abf947a1a29a45ddae89f3870f8281704fafc9" +checksum = "6bc904b9bbefcadbd8e3a9fb0d464a9b979de6324c03b3c663e8994f46a5be36" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1235,45 +1233,47 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -1339,7 +1339,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb8adf61df288369c9d1c6bb142f61db30c18619a71f64915d64e916f23c8c37" dependencies = [ - "phf 0.11.2", + "phf", "regex", ] @@ -1355,21 +1355,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick 1.1.3", "bstr", @@ -1384,16 +1384,16 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "ignore", "walkdir", ] [[package]] name = "grass" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46def7216d331efa51a6aa796ef777bfdfe9605378382827a553344b7e5eefc" +checksum = "f7a68216437ef68f0738e48d6c7bb9e6e6a92237e001b03d838314b068f33c94" dependencies = [ "getrandom 0.2.15", "grass_compiler", @@ -1401,15 +1401,15 @@ dependencies = [ [[package]] name = "grass_compiler" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f39216c1843182f78541276fec96f88406861f16aa19cc9f8add70f8e67b7577" +checksum = "2d9e3df7f0222ce5184154973d247c591d9aadc28ce7a73c6cd31100c9facff6" dependencies = [ "codemap", - "indexmap 2.2.6", + "indexmap 2.7.0", "lasso", "once_cell", - "phf 0.11.2", + "phf", "rand 0.8.5", ] @@ -1419,13 +1419,32 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes 1.6.0", + "bytes 1.9.0", "fnv", "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.2.6", + "http 0.2.12", + "indexmap 2.7.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes 1.9.0", + "fnv", + "futures-core", + "futures-sink", + "http 1.2.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -1466,6 +1485,16 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1499,7 +1528,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -1508,7 +1537,18 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.6.0", + "bytes 1.9.0", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes 1.9.0", "fnv", "itoa", ] @@ -1519,16 +1559,39 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes 1.6.0", - "http", + "bytes 1.9.0", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes 1.9.0", + "http 1.2.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes 1.9.0", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1553,17 +1616,17 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.29" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ - "bytes 1.6.0", + "bytes 1.9.0", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1575,38 +1638,85 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +dependencies = [ + "bytes 1.9.0", + "futures-channel", + "futures-util", + "h2 0.4.7", + "http 1.2.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.2.0", + "hyper 1.5.2", + "hyper-util", "rustls", + "rustls-pki-types", "tokio", "tokio-rustls", + "tower-service", + "webpki-roots", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes 1.6.0", - "hyper", + "bytes 1.9.0", + "http-body-util", + "hyper 1.5.2", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes 1.9.0", + "futures-channel", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", + "hyper 1.5.2", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1696,9 +1806,9 @@ checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] name = "icu_properties" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", "icu_collections", @@ -1740,26 +1850,35 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] name = "idna" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "icu_normalizer", - "icu_properties", + "idna_adapter", "smallvec", "utf8_iter", ] +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", @@ -1773,12 +1892,12 @@ dependencies = [ [[package]] name = "image" -version = "0.25.1" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", - "byteorder", + "byteorder-lite", "color_quant", "exr", "gif", @@ -1796,12 +1915,12 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" dependencies = [ "byteorder-lite", - "thiserror", + "quick-error", ] [[package]] @@ -1819,9 +1938,9 @@ dependencies = [ [[package]] name = "imgref" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" [[package]] name = "indexmap" @@ -1835,21 +1954,22 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", + "serde", ] [[package]] name = "inotify" -version = "0.9.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.7.0", "inotify-sys", "libc", ] @@ -1865,13 +1985,13 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "6513e4067e16e69ed1db5ab56048ed65db32d10ba5fc1217f5393f8f17d8b5a5" dependencies = [ - "console 0.15.8", - "lazy_static", + "console 0.15.10", "linked-hash-map", + "once_cell", "similar", ] @@ -1883,7 +2003,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -1897,9 +2017,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is-docker" @@ -1922,9 +2042,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -1946,9 +2066,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jieba-rs" @@ -1960,16 +2080,16 @@ dependencies = [ "fxhash", "hashbrown 0.14.5", "lazy_static", - "phf 0.11.2", - "phf_codegen 0.11.2", + "phf", + "phf_codegen", "regex", ] [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -1982,18 +2102,19 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "kamadak-exif" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4fc70d0ab7e5b6bafa30216a6b48705ea964cdfc29c050f2412295eba58077" +checksum = "1130d80c7374efad55a117d715a3af9368f0fa7a2c54573afc15a188cd984837" dependencies = [ "mutate_once", ] @@ -2030,18 +2151,18 @@ dependencies = [ [[package]] name = "lasso" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4644821e1c3d7a560fe13d842d13f587c07348a1a05d3a797152d41c90c56df2" +checksum = "6e14eda50a3494b3bf7b9ce51c52434a761e383d7238ce1dd5dcec2fbc13e9fb" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.14.5", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -2066,26 +2187,36 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" dependencies = [ "arbitrary", "cc", - "once_cell", ] [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.7.0", + "libc", + "redox_syscall", +] [[package]] name = "libs" @@ -2094,7 +2225,7 @@ dependencies = [ "ahash 0.8.11", "ammonia", "atty", - "base64 0.22.1", + "base64", "csv", "elasticlunr-rs", "filetime", @@ -2125,7 +2256,7 @@ dependencies = [ "tera", "termcolor", "time", - "toml 0.8.14", + "toml 0.8.19", "unic-langid", "unicode-segmentation", "url", @@ -2135,9 +2266,9 @@ dependencies = [ [[package]] name = "libwebp-sys" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829b6b604f31ed6d2bccbac841fe0788de93dbd87e4eb1ba2c4adfe8c012a838" +checksum = "54cd30df7c7165ce74a456e4ca9732c603e8dc5e60784558c1c6dc047f876733" dependencies = [ "cc", "glob", @@ -2145,20 +2276,22 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.57" +version = "1.0.0-alpha.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bc10261f46b8df263b80e7779d1748b1880488cd951fbb9e096430cead10e6" +checksum = "8a75fcbcdbcc84fc1ae7c60c31f99337560b620757a9bfc1c9f84df3cff8ac24" dependencies = [ "ahash 0.8.11", - "bitflags 2.5.0", + "bitflags 2.7.0", "const-str", "cssparser", "cssparser-color", "dashmap", "data-encoding", "getrandom 0.2.15", + "indexmap 2.7.0", "itertools 0.10.5", "lazy_static", + "lightningcss-derive", "parcel_selectors", "parcel_sourcemap", "paste", @@ -2168,6 +2301,18 @@ dependencies = [ "smallvec", ] +[[package]] +name = "lightningcss-derive" +version = "1.0.0-alpha.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12744d1279367caed41739ef094c325d53fb0ffcd4f9b84a368796f870252" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "lindera" version = "0.14.0" @@ -2187,7 +2332,7 @@ dependencies = [ "lindera-unidic-builder", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2222,7 +2367,7 @@ dependencies = [ "encoding", "log", "serde", - "thiserror", + "thiserror 1.0.69", "yada", ] @@ -2325,12 +2470,6 @@ dependencies = [ "yada", ] -[[package]] -name = "line-wrap" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" - [[package]] name = "link_checker" version = "0.1.0" @@ -2350,15 +2489,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -2372,9 +2511,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d" +dependencies = [ + "value-bag", +] [[package]] name = "loop9" @@ -2429,8 +2571,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" dependencies = [ "log", - "phf 0.11.2", - "phf_codegen 0.11.2", + "phf", + "phf_codegen", "string_cache", "string_cache_codegen", "tendril", @@ -2466,9 +2608,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -2496,7 +2638,7 @@ dependencies = [ "minify-html-common", "minify-js", "once_cell", - "rustc-hash", + "rustc-hash 1.1.0", ] [[package]] @@ -2509,7 +2651,7 @@ dependencies = [ "itertools 0.12.1", "lazy_static", "memchr", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", ] @@ -2532,11 +2674,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -2561,14 +2703,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2597,20 +2739,26 @@ dependencies = [ [[package]] name = "mockito" -version = "0.31.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f9fece9bd97ab74339fe19f4bcaf52b76dcc18e5364c7977c1838f76b38de9" +checksum = "652cd6d169a36eaf9d1e6bce1a221130439a966d7f27858af66a33a66e9c4ee2" dependencies = [ "assert-json-diff", + "bytes 1.9.0", "colored", - "httparse", - "lazy_static", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.2", + "hyper-util", "log", "rand 0.8.5", "regex", "serde_json", "serde_urlencoded", "similar", + "tokio", ] [[package]] @@ -2655,11 +2803,11 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "cfg-if 1.0.0", "cfg_aliases", "libc", @@ -2727,42 +2875,47 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "notify" -version = "6.1.1" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.5.0", - "crossbeam-channel", + "bitflags 2.7.0", "filetime", "fsevent-sys", "inotify", "kqueue", "libc", "log", - "mio 0.8.11", + "mio 1.0.3", + "notify-types", "walkdir", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "notify-debouncer-full" -version = "0.3.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f5dab59c348b9b50cf7f261960a20e389feb2713636399cd9082cd4b536154" +checksum = "d2d88b1a7538054351c8258338df7c931a590513fb3745e8c15eb9ff4199b8d1" dependencies = [ - "crossbeam-channel", "file-id", "log", "notify", - "parking_lot", + "notify-types", "walkdir", ] +[[package]] +name = "notify-types" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" + [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -2782,7 +2935,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -2835,18 +2988,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.0" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "onig" @@ -2878,9 +3031,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "open" -version = "5.1.4" +version = "5.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388" +checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" dependencies = [ "is-wsl", "libc", @@ -2889,11 +3042,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "cfg-if 1.0.0", "foreign-types", "libc", @@ -2910,7 +3063,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -2921,9 +3074,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -2945,17 +3098,17 @@ checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" [[package]] name = "parcel_selectors" -version = "0.26.5" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce9c47a67c66fee4a5a42756f9784d92941bd0ab2b653539a9e90521a44b66f0" +checksum = "dccbc6fb560df303a44e511618256029410efbc87779018f751ef12c488271fe" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "cssparser", - "fxhash", "log", - "phf 0.10.1", - "phf_codegen 0.10.0", + "phf", + "phf_codegen", "precomputed-hash", + "rustc-hash 2.1.0", "smallvec", ] @@ -2991,9 +3144,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.5.2", + "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -3032,9 +3185,9 @@ checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "percent-encoding" @@ -3044,20 +3197,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.10" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror", + "thiserror 2.0.11", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.10" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -3065,22 +3218,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.10" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] name = "pest_meta" -version = "2.7.10" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -3089,41 +3242,22 @@ dependencies = [ [[package]] name = "phf" -version = "0.10.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared 0.10.0", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", - "phf_shared 0.11.2", + "phf_shared 0.11.3", ] [[package]] name = "phf_codegen" -version = "0.10.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_codegen" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", + "phf_generator 0.11.3", + "phf_shared 0.11.3", ] [[package]] @@ -3138,25 +3272,25 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared 0.11.2", + "phf_shared 0.11.3", "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", + "phf_generator 0.11.3", + "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -3165,23 +3299,23 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ - "siphasher", + "siphasher 0.3.11", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher", + "siphasher 1.0.1", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -3191,29 +3325,28 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plist" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ - "base64 0.21.7", - "indexmap 2.2.6", - "line-wrap", - "quick-xml 0.31.0", + "base64", + "indexmap 2.7.0", + "quick-xml 0.32.0", "serde", "time", ] [[package]] name = "png" -version = "0.17.13" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3230,9 +3363,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "precomputed-hash" @@ -3266,30 +3402,30 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -3314,11 +3450,11 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" +checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "memchr", "pulldown-cmark-escape", "unicase", @@ -3362,9 +3498,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" dependencies = [ "memchr", ] @@ -3382,11 +3518,63 @@ dependencies = [ "serde_json", ] +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes 1.9.0", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.0", + "rustls", + "socket2", + "thiserror 2.0.11", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes 1.9.0", + "getrandom 0.2.15", + "rand 0.8.5", + "ring", + "rustc-hash 2.1.0", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.11", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -3498,16 +3686,16 @@ dependencies = [ "rand_chacha 0.3.1", "simd_helpers", "system-deps", - "thiserror", + "thiserror 1.0.69", "v_frame", "wasm-bindgen", ] [[package]] name = "ravif" -version = "0.11.7" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67376f469e7e7840d0040bbf4b9b3334005bb167f814621326e4c7ab8cd6e944" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" dependencies = [ "avif-serialize", "imgref", @@ -3540,27 +3728,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" -dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick 1.1.3", "memchr", @@ -3570,9 +3749,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick 1.1.3", "memchr", @@ -3581,9 +3760,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relative-path" @@ -3602,21 +3781,22 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ - "base64 0.21.7", - "bytes 1.6.0", - "encoding_rs", + "base64", + "bytes 1.9.0", + "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "http 1.2.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.2", "hyper-rustls", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log", @@ -3625,33 +3805,32 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", "rustls", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", + "tower", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "windows-registry", ] [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" -dependencies = [ - "bytemuck", -] +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" [[package]] name = "ring" @@ -3670,13 +3849,13 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", - "bytes 1.6.0", + "bytes 1.9.0", "hashbrown 0.12.3", "ptr_meta", "rend", @@ -3688,9 +3867,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -3725,47 +3904,65 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" + [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ - "log", + "once_cell", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.21.7", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +dependencies = [ + "web-time", ] [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] @@ -3786,11 +3983,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3799,16 +3996,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "seahash" version = "4.1.0" @@ -3828,11 +4015,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.7.0", "core-foundation", "core-foundation-sys", "libc", @@ -3841,9 +4028,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -3851,41 +4038,51 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", +] + +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.0", "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -3908,7 +4105,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -3938,6 +4135,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "simd-abstraction" version = "0.7.1" @@ -3964,15 +4167,15 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "siphasher" @@ -3980,6 +4183,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "site" version = "0.1.0" @@ -4010,9 +4219,9 @@ dependencies = [ [[package]] name = "slug" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" dependencies = [ "deunicode", "wasm-bindgen", @@ -4026,9 +4235,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4039,9 +4248,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "stable_deref_trait" @@ -4087,6 +4293,90 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "sval" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" + +[[package]] +name = "sval_buffer" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" +dependencies = [ + "serde", + "sval", + "sval_nested", +] + [[package]] name = "svg_metadata" version = "0.5.1" @@ -4112,9 +4402,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -4123,9 +4413,12 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -4135,7 +4428,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -4155,32 +4448,11 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror", + "thiserror 1.0.69", "walkdir", "yaml-rust", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "system-deps" version = "6.2.2" @@ -4190,7 +4462,7 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.8.14", + "toml 0.8.19", "version-compare", ] @@ -4202,9 +4474,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.41" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -4213,20 +4485,22 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if 1.0.0", "fastrand", + "getrandom 0.2.15", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4304,7 +4578,7 @@ dependencies = [ "cfg-if 1.0.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -4315,7 +4589,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "test-case-core", ] @@ -4327,22 +4601,42 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", ] [[package]] @@ -4358,9 +4652,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -4381,9 +4675,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -4401,9 +4695,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -4416,17 +4710,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", - "bytes 1.6.0", + "bytes 1.9.0", "libc", - "mio 0.8.11", + "mio 1.0.3", + "parking_lot", "pin-project-lite", "socket2", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4441,9 +4736,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", "tokio", @@ -4451,11 +4746,11 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ - "bytes 1.6.0", + "bytes 1.9.0", "futures-core", "futures-sink", "pin-project-lite", @@ -4473,9 +4768,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -4485,37 +4780,58 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", "winnow", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-core", @@ -4523,9 +4839,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -4536,6 +4852,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + [[package]] name = "typenum" version = "1.17.0" @@ -4544,9 +4866,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unic-char-property" @@ -4618,24 +4940,21 @@ dependencies = [ [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unsafe-libyaml" @@ -4651,9 +4970,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -4697,9 +5016,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.8.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4" [[package]] name = "v_frame" @@ -4712,6 +5031,42 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -4726,9 +5081,9 @@ checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vlq" @@ -4769,46 +5124,47 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if 1.0.0", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if 1.0.0", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4816,28 +5172,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -4855,9 +5221,12 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "weezl" @@ -4895,11 +5264,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4914,167 +5283,130 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-targets 0.48.5", + "windows-result", + "windows-strings", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-result", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.52.5" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows-targets", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - [[package]] name = "winres" version = "0.1.12" @@ -5135,9 +5467,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909" dependencies = [ "libc", "linux-raw-sys", @@ -5161,9 +5493,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -5173,62 +5505,69 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zerovec" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ "yoke", "zerofrom", @@ -5237,25 +5576,25 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] name = "zola" version = "0.19.2" dependencies = [ - "clap 4.5.7", + "clap 4.5.26", "clap_complete", "console 0.1.0", "ctrlc", "errors", - "hyper", + "hyper 0.14.32", "libs", "mime", "mime_guess", @@ -5288,9 +5627,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index 20af0f8413..00fa1794a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ clap_complete = "4" hyper = { version = "0.14.1", default-features = false, features = ["runtime", "server", "http2", "http1"] } tokio = { version = "1.0.1", default-features = false, features = ["rt", "fs", "time"] } time = { version = "0.3", features = ["formatting", "macros", "local-offset"] } -notify-debouncer-full = "0.3" +notify-debouncer-full = "0.5" ws = "0.9" ctrlc = "3" open = "5" diff --git a/Dockerfile b/Dockerfile index 87b3ec247b..0741cc93c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,26 @@ FROM rust:slim-bookworm AS builder +ARG USE_GH_RELEASE=false +ARG ZOLA_RELEASE_VERSION=latest RUN apt-get update -y && \ - apt-get install -y make g++ libssl-dev && \ - rustup target add x86_64-unknown-linux-gnu + apt-get install -y pkg-config make g++ libssl-dev curl jq tar gzip WORKDIR /app COPY . . -RUN cargo build --release --target x86_64-unknown-linux-gnu - +RUN if [ "${USE_GH_RELEASE}" = "true" ]; then \ + if [ "${ZOLA_RELEASE_VERSION}" = "latest" ]; then \ + export ZOLA_VERSION=$(curl -sL https://api.github.com/repos/getzola/zola/releases/latest | jq -r .name); \ + else \ + export ZOLA_VERSION="${ZOLA_RELEASE_VERSION}"; \ + fi && \ + curl -sL --fail --output zola.tar.gz https://github.com/getzola/zola/releases/download/${ZOLA_VERSION}/zola-${ZOLA_VERSION}-$(uname -m)-unknown-linux-gnu.tar.gz && \ + tar -xzvf zola.tar.gz zola; \ + else \ + cargo build --release && \ + cp target/$(uname -m)-unknown-linux-gnu/release/zola zola; \ + fi && ./zola --version FROM gcr.io/distroless/cc-debian12 -COPY --from=builder /app/target/x86_64-unknown-linux-gnu/release/zola /bin/zola +COPY --from=builder /app/zola /bin/zola ENTRYPOINT [ "/bin/zola" ] diff --git a/components/config/src/config/markup.rs b/components/config/src/config/markup.rs index 580a665ae6..398ef8a3b4 100644 --- a/components/config/src/config/markup.rs +++ b/components/config/src/config/markup.rs @@ -27,6 +27,8 @@ pub struct ThemeCss { pub struct Markdown { /// Whether to highlight all code blocks found in markdown files. Defaults to false pub highlight_code: bool, + /// Emit an error for missing highlight languages. Defaults to false + pub error_on_missing_highlight: bool, /// Which themes to use for code highlighting. See Readme for supported themes /// Defaults to "base16-ocean-dark" pub highlight_theme: String, @@ -34,6 +36,8 @@ pub struct Markdown { pub highlight_themes_css: Vec, /// Whether to render emoji aliases (e.g.: :smile: => 😄) in the markdown files pub render_emoji: bool, + /// CSS class to add to external links + pub external_links_class: Option, /// Whether external links are to be opened in a new tab /// If this is true, a `rel="noopener"` will always automatically be added for security reasons pub external_links_target_blank: bool, @@ -43,6 +47,8 @@ pub struct Markdown { pub external_links_no_referrer: bool, /// Whether smart punctuation is enabled (changing quotes, dashes, dots etc in their typographic form) pub smart_punctuation: bool, + /// Whether parsing of definition lists is enabled + pub definition_list: bool, /// Whether footnotes are rendered at the bottom in the style of GitHub. pub bottom_footnotes: bool, /// A list of directories to search for additional `.sublime-syntax` and `.tmTheme` files in. @@ -58,6 +64,16 @@ pub struct Markdown { } impl Markdown { + pub fn validate_external_links_class(&self) -> Result<()> { + // Validate external link class doesn't contain quotes which would break HTML and aren't valid in CSS + if let Some(class) = &self.external_links_class { + if class.contains('"') || class.contains('\'') { + bail!("External link class '{}' cannot contain quotes", class) + } + } + Ok(()) + } + /// Gets the configured highlight theme from the THEME_SET or the config's extra_theme_set /// Returns None if the configured highlighting theme is set to use css pub fn get_highlight_theme(&self) -> Option<&Theme> { @@ -166,6 +182,7 @@ impl Markdown { self.external_links_target_blank || self.external_links_no_follow || self.external_links_no_referrer + || self.external_links_class.is_some() } pub fn construct_external_link_tag(&self, url: &str, title: &str) -> String { @@ -173,6 +190,11 @@ impl Markdown { let mut target = "".to_owned(); let title = if title.is_empty() { "".to_owned() } else { format!("title=\"{}\" ", title) }; + let class = self + .external_links_class + .as_ref() + .map_or("".to_owned(), |c| format!("class=\"{}\" ", c)); + if self.external_links_target_blank { // Security risk otherwise rel_opts.push("noopener"); @@ -190,7 +212,7 @@ impl Markdown { format!("rel=\"{}\" ", rel_opts.join(" ")) }; - format!("", rel, target, title, url) + format!("", class, rel, target, title, url) } } @@ -198,13 +220,16 @@ impl Default for Markdown { fn default() -> Markdown { Markdown { highlight_code: false, + error_on_missing_highlight: false, highlight_theme: DEFAULT_HIGHLIGHT_THEME.to_owned(), highlight_themes_css: Vec::new(), render_emoji: false, + external_links_class: None, external_links_target_blank: false, external_links_no_follow: false, external_links_no_referrer: false, smart_punctuation: false, + definition_list: false, bottom_footnotes: false, extra_syntaxes_and_themes: vec![], extra_syntax_set: None, diff --git a/components/config/src/config/mod.rs b/components/config/src/config/mod.rs index 88d949fc21..b8deb6c44f 100644 --- a/components/config/src/config/mod.rs +++ b/components/config/src/config/mod.rs @@ -19,7 +19,7 @@ use utils::globs::build_ignore_glob_set; use utils::slugs::slugify_paths; // We want a default base url for tests -static DEFAULT_BASE_URL: &str = "http://a-website.com"; +const DEFAULT_BASE_URL: &str = "http://a-website.com"; #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] @@ -29,6 +29,13 @@ pub enum Mode { Check, } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ExcludePaginatedPagesInSitemap { + None, + All, +} + #[derive(Clone, Debug, Deserialize)] #[serde(default, deny_unknown_fields)] pub struct Config { @@ -102,6 +109,8 @@ pub struct Config { pub generate_sitemap: bool, /// Enables the generation of robots.txt pub generate_robots_txt: bool, + /// Whether to exclude paginated pages in sitemap; can take values "none", "all" + pub exclude_paginated_pages_in_sitemap: ExcludePaginatedPagesInSitemap, } #[derive(Serialize)] @@ -123,6 +132,7 @@ pub struct SerializedConfig<'a> { search: search::SerializedSearch<'a>, generate_sitemap: bool, generate_robots_txt: bool, + exclude_paginated_pages_in_sitemap: ExcludePaginatedPagesInSitemap, } impl Config { @@ -176,6 +186,7 @@ impl Config { // this is the step at which missing extra syntax and highlighting themes are raised as errors config.markdown.init_extra_syntaxes_and_highlight_themes(config_dir)?; + config.markdown.validate_external_links_class()?; Ok(config) } @@ -287,6 +298,10 @@ impl Config { self.mode == Mode::Check } + pub fn should_exclude_paginated_pages_in_sitemap(&self) -> bool { + self.exclude_paginated_pages_in_sitemap == ExcludePaginatedPagesInSitemap::All + } + pub fn enable_serve_mode(&mut self) { self.mode = Mode::Serve; } @@ -340,6 +355,7 @@ impl Config { search: self.search.serialize(), generate_sitemap: self.generate_sitemap, generate_robots_txt: self.generate_robots_txt, + exclude_paginated_pages_in_sitemap: self.exclude_paginated_pages_in_sitemap, } } } @@ -405,6 +421,7 @@ impl Default for Config { extra: HashMap::new(), generate_sitemap: true, generate_robots_txt: true, + exclude_paginated_pages_in_sitemap: ExcludePaginatedPagesInSitemap::None, } } } @@ -1066,4 +1083,6 @@ base_url = "example.com" let config = Config::parse(config).unwrap(); assert!(config.generate_robots_txt); } + + // TODO: add a test for excluding paginated pages } diff --git a/components/config/src/highlighting.rs b/components/config/src/highlighting.rs index 03cfc95d19..ff50d2258b 100644 --- a/components/config/src/highlighting.rs +++ b/components/config/src/highlighting.rs @@ -9,10 +9,10 @@ use crate::config::Config; pub const CLASS_STYLE: ClassStyle = ClassStyle::SpacedPrefixed { prefix: "z-" }; pub static SYNTAX_SET: Lazy = - Lazy::new(|| from_binary(include_bytes!("../../../sublime/syntaxes/newlines.packdump"))); + Lazy::new(|| from_binary(include_bytes!("../sublime/syntaxes/newlines.packdump"))); pub static THEME_SET: Lazy = - Lazy::new(|| from_binary(include_bytes!("../../../sublime/themes/all.themedump"))); + Lazy::new(|| from_binary(include_bytes!("../sublime/themes/all.themedump"))); #[derive(Clone, Debug, PartialEq, Eq)] pub enum HighlightSource { diff --git a/sublime/syntaxes/Packages b/components/config/sublime/syntaxes/Packages similarity index 100% rename from sublime/syntaxes/Packages rename to components/config/sublime/syntaxes/Packages diff --git a/sublime/syntaxes/extra/Assembly x86.sublime-syntax b/components/config/sublime/syntaxes/extra/Assembly x86.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Assembly x86.sublime-syntax rename to components/config/sublime/syntaxes/extra/Assembly x86.sublime-syntax diff --git a/sublime/syntaxes/extra/CSV.sublime-syntax b/components/config/sublime/syntaxes/extra/CSV.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/CSV.sublime-syntax rename to components/config/sublime/syntaxes/extra/CSV.sublime-syntax diff --git a/sublime/syntaxes/extra/Crystal.sublime-syntax b/components/config/sublime/syntaxes/extra/Crystal.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Crystal.sublime-syntax rename to components/config/sublime/syntaxes/extra/Crystal.sublime-syntax diff --git a/sublime/syntaxes/extra/Dart.sublime-syntax b/components/config/sublime/syntaxes/extra/Dart.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Dart.sublime-syntax rename to components/config/sublime/syntaxes/extra/Dart.sublime-syntax diff --git a/sublime/syntaxes/extra/Docker.tmbundle b/components/config/sublime/syntaxes/extra/Docker.tmbundle similarity index 100% rename from sublime/syntaxes/extra/Docker.tmbundle rename to components/config/sublime/syntaxes/extra/Docker.tmbundle diff --git a/sublime/syntaxes/extra/GDScript-sublime b/components/config/sublime/syntaxes/extra/GDScript-sublime similarity index 100% rename from sublime/syntaxes/extra/GDScript-sublime rename to components/config/sublime/syntaxes/extra/GDScript-sublime diff --git a/sublime/syntaxes/extra/GraphQL-SublimeText3 b/components/config/sublime/syntaxes/extra/GraphQL-SublimeText3 similarity index 100% rename from sublime/syntaxes/extra/GraphQL-SublimeText3 rename to components/config/sublime/syntaxes/extra/GraphQL-SublimeText3 diff --git a/sublime/syntaxes/extra/Handlebars.sublime-syntax b/components/config/sublime/syntaxes/extra/Handlebars.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Handlebars.sublime-syntax rename to components/config/sublime/syntaxes/extra/Handlebars.sublime-syntax diff --git a/sublime/syntaxes/extra/Julia-sublime b/components/config/sublime/syntaxes/extra/Julia-sublime similarity index 100% rename from sublime/syntaxes/extra/Julia-sublime rename to components/config/sublime/syntaxes/extra/Julia-sublime diff --git a/sublime/syntaxes/extra/Kotlin.sublime-syntax b/components/config/sublime/syntaxes/extra/Kotlin.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Kotlin.sublime-syntax rename to components/config/sublime/syntaxes/extra/Kotlin.sublime-syntax diff --git a/sublime/syntaxes/extra/LESS-sublime b/components/config/sublime/syntaxes/extra/LESS-sublime similarity index 100% rename from sublime/syntaxes/extra/LESS-sublime rename to components/config/sublime/syntaxes/extra/LESS-sublime diff --git a/sublime/syntaxes/extra/MZN.sublime-syntax b/components/config/sublime/syntaxes/extra/MZN.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/MZN.sublime-syntax rename to components/config/sublime/syntaxes/extra/MZN.sublime-syntax diff --git a/sublime/syntaxes/extra/Nim.sublime-syntax b/components/config/sublime/syntaxes/extra/Nim.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Nim.sublime-syntax rename to components/config/sublime/syntaxes/extra/Nim.sublime-syntax diff --git a/sublime/syntaxes/extra/Nix.sublime-syntax b/components/config/sublime/syntaxes/extra/Nix.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Nix.sublime-syntax rename to components/config/sublime/syntaxes/extra/Nix.sublime-syntax diff --git a/sublime/syntaxes/extra/PowerShell.sublime-syntax b/components/config/sublime/syntaxes/extra/PowerShell.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/PowerShell.sublime-syntax rename to components/config/sublime/syntaxes/extra/PowerShell.sublime-syntax diff --git a/sublime/syntaxes/extra/Prolog.sublime-syntax b/components/config/sublime/syntaxes/extra/Prolog.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Prolog.sublime-syntax rename to components/config/sublime/syntaxes/extra/Prolog.sublime-syntax diff --git a/sublime/syntaxes/extra/README.md b/components/config/sublime/syntaxes/extra/README.md similarity index 100% rename from sublime/syntaxes/extra/README.md rename to components/config/sublime/syntaxes/extra/README.md diff --git a/sublime/syntaxes/extra/Racket.sublime-syntax b/components/config/sublime/syntaxes/extra/Racket.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Racket.sublime-syntax rename to components/config/sublime/syntaxes/extra/Racket.sublime-syntax diff --git a/sublime/syntaxes/extra/Reason.sublime-syntax b/components/config/sublime/syntaxes/extra/Reason.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Reason.sublime-syntax rename to components/config/sublime/syntaxes/extra/Reason.sublime-syntax diff --git a/sublime/syntaxes/extra/Stylus.sublime-syntax b/components/config/sublime/syntaxes/extra/Stylus.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Stylus.sublime-syntax rename to components/config/sublime/syntaxes/extra/Stylus.sublime-syntax diff --git a/sublime/syntaxes/extra/Sublime-CMakeLists b/components/config/sublime/syntaxes/extra/Sublime-CMakeLists similarity index 100% rename from sublime/syntaxes/extra/Sublime-CMakeLists rename to components/config/sublime/syntaxes/extra/Sublime-CMakeLists diff --git a/sublime/syntaxes/extra/Sublime-GenericConfig b/components/config/sublime/syntaxes/extra/Sublime-GenericConfig similarity index 100% rename from sublime/syntaxes/extra/Sublime-GenericConfig rename to components/config/sublime/syntaxes/extra/Sublime-GenericConfig diff --git a/sublime/syntaxes/extra/SublimeElmLanguageSupport b/components/config/sublime/syntaxes/extra/SublimeElmLanguageSupport similarity index 100% rename from sublime/syntaxes/extra/SublimeElmLanguageSupport rename to components/config/sublime/syntaxes/extra/SublimeElmLanguageSupport diff --git a/sublime/syntaxes/extra/SublimeFortran b/components/config/sublime/syntaxes/extra/SublimeFortran similarity index 100% rename from sublime/syntaxes/extra/SublimeFortran rename to components/config/sublime/syntaxes/extra/SublimeFortran diff --git a/sublime/syntaxes/extra/SublimeSass b/components/config/sublime/syntaxes/extra/SublimeSass similarity index 100% rename from sublime/syntaxes/extra/SublimeSass rename to components/config/sublime/syntaxes/extra/SublimeSass diff --git a/sublime/syntaxes/extra/SublimeTextLinkerSyntax b/components/config/sublime/syntaxes/extra/SublimeTextLinkerSyntax similarity index 100% rename from sublime/syntaxes/extra/SublimeTextLinkerSyntax rename to components/config/sublime/syntaxes/extra/SublimeTextLinkerSyntax diff --git a/sublime/syntaxes/extra/Swift.sublime-syntax b/components/config/sublime/syntaxes/extra/Swift.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/Swift.sublime-syntax rename to components/config/sublime/syntaxes/extra/Swift.sublime-syntax diff --git a/sublime/syntaxes/extra/TypeScript.sublime-syntax b/components/config/sublime/syntaxes/extra/TypeScript.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/TypeScript.sublime-syntax rename to components/config/sublime/syntaxes/extra/TypeScript.sublime-syntax diff --git a/sublime/syntaxes/extra/TypeScriptReact.sublime-syntax b/components/config/sublime/syntaxes/extra/TypeScriptReact.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/TypeScriptReact.sublime-syntax rename to components/config/sublime/syntaxes/extra/TypeScriptReact.sublime-syntax diff --git a/sublime/syntaxes/extra/VimL.sublime-syntax b/components/config/sublime/syntaxes/extra/VimL.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/VimL.sublime-syntax rename to components/config/sublime/syntaxes/extra/VimL.sublime-syntax diff --git a/sublime/syntaxes/extra/awk-sublime b/components/config/sublime/syntaxes/extra/awk-sublime similarity index 100% rename from sublime/syntaxes/extra/awk-sublime rename to components/config/sublime/syntaxes/extra/awk-sublime diff --git a/sublime/syntaxes/extra/elixir-sublime-syntax b/components/config/sublime/syntaxes/extra/elixir-sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/elixir-sublime-syntax rename to components/config/sublime/syntaxes/extra/elixir-sublime-syntax diff --git a/sublime/syntaxes/extra/lrc.sublime-syntax b/components/config/sublime/syntaxes/extra/lrc.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/lrc.sublime-syntax rename to components/config/sublime/syntaxes/extra/lrc.sublime-syntax diff --git a/sublime/syntaxes/extra/protobuf-syntax-highlighting b/components/config/sublime/syntaxes/extra/protobuf-syntax-highlighting similarity index 100% rename from sublime/syntaxes/extra/protobuf-syntax-highlighting rename to components/config/sublime/syntaxes/extra/protobuf-syntax-highlighting diff --git a/sublime/syntaxes/extra/srt.sublime-syntax b/components/config/sublime/syntaxes/extra/srt.sublime-syntax similarity index 100% rename from sublime/syntaxes/extra/srt.sublime-syntax rename to components/config/sublime/syntaxes/extra/srt.sublime-syntax diff --git a/sublime/syntaxes/extra/sublime-clojure b/components/config/sublime/syntaxes/extra/sublime-clojure similarity index 100% rename from sublime/syntaxes/extra/sublime-clojure rename to components/config/sublime/syntaxes/extra/sublime-clojure diff --git a/sublime/syntaxes/extra/sublime-fish b/components/config/sublime/syntaxes/extra/sublime-fish similarity index 100% rename from sublime/syntaxes/extra/sublime-fish rename to components/config/sublime/syntaxes/extra/sublime-fish diff --git a/sublime/syntaxes/extra/sublime-glsl b/components/config/sublime/syntaxes/extra/sublime-glsl similarity index 100% rename from sublime/syntaxes/extra/sublime-glsl rename to components/config/sublime/syntaxes/extra/sublime-glsl diff --git a/sublime/syntaxes/extra/sublime-jinja2 b/components/config/sublime/syntaxes/extra/sublime-jinja2 similarity index 100% rename from sublime/syntaxes/extra/sublime-jinja2 rename to components/config/sublime/syntaxes/extra/sublime-jinja2 diff --git a/sublime/syntaxes/extra/sublime-purescript-syntax b/components/config/sublime/syntaxes/extra/sublime-purescript-syntax similarity index 100% rename from sublime/syntaxes/extra/sublime-purescript-syntax rename to components/config/sublime/syntaxes/extra/sublime-purescript-syntax diff --git a/sublime/syntaxes/extra/sublime-zig-language b/components/config/sublime/syntaxes/extra/sublime-zig-language similarity index 100% rename from sublime/syntaxes/extra/sublime-zig-language rename to components/config/sublime/syntaxes/extra/sublime-zig-language diff --git a/sublime/syntaxes/extra/sublime_toml_highlighting b/components/config/sublime/syntaxes/extra/sublime_toml_highlighting similarity index 100% rename from sublime/syntaxes/extra/sublime_toml_highlighting rename to components/config/sublime/syntaxes/extra/sublime_toml_highlighting diff --git a/sublime/syntaxes/extra/sublimetext-fsharp b/components/config/sublime/syntaxes/extra/sublimetext-fsharp similarity index 100% rename from sublime/syntaxes/extra/sublimetext-fsharp rename to components/config/sublime/syntaxes/extra/sublimetext-fsharp diff --git a/sublime/syntaxes/extra/vue-syntax-highlight b/components/config/sublime/syntaxes/extra/vue-syntax-highlight similarity index 100% rename from sublime/syntaxes/extra/vue-syntax-highlight rename to components/config/sublime/syntaxes/extra/vue-syntax-highlight diff --git a/sublime/syntaxes/newlines.packdump b/components/config/sublime/syntaxes/newlines.packdump similarity index 100% rename from sublime/syntaxes/newlines.packdump rename to components/config/sublime/syntaxes/newlines.packdump diff --git a/sublime/themes/1337.tmTheme b/components/config/sublime/themes/1337.tmTheme similarity index 100% rename from sublime/themes/1337.tmTheme rename to components/config/sublime/themes/1337.tmTheme diff --git a/sublime/themes/OneHalfDark.tmTheme b/components/config/sublime/themes/OneHalfDark.tmTheme similarity index 100% rename from sublime/themes/OneHalfDark.tmTheme rename to components/config/sublime/themes/OneHalfDark.tmTheme diff --git a/sublime/themes/OneHalfLight.tmTheme b/components/config/sublime/themes/OneHalfLight.tmTheme similarity index 100% rename from sublime/themes/OneHalfLight.tmTheme rename to components/config/sublime/themes/OneHalfLight.tmTheme diff --git a/sublime/themes/Tomorrow.tmTheme b/components/config/sublime/themes/Tomorrow.tmTheme similarity index 100% rename from sublime/themes/Tomorrow.tmTheme rename to components/config/sublime/themes/Tomorrow.tmTheme diff --git a/sublime/themes/agola-dark.tmTheme b/components/config/sublime/themes/agola-dark.tmTheme similarity index 100% rename from sublime/themes/agola-dark.tmTheme rename to components/config/sublime/themes/agola-dark.tmTheme diff --git a/sublime/themes/all.themedump b/components/config/sublime/themes/all.themedump similarity index 100% rename from sublime/themes/all.themedump rename to components/config/sublime/themes/all.themedump diff --git a/sublime/themes/ascetic-white.tmTheme b/components/config/sublime/themes/ascetic-white.tmTheme similarity index 100% rename from sublime/themes/ascetic-white.tmTheme rename to components/config/sublime/themes/ascetic-white.tmTheme diff --git a/sublime/themes/axar.tmTheme b/components/config/sublime/themes/axar.tmTheme similarity index 100% rename from sublime/themes/axar.tmTheme rename to components/config/sublime/themes/axar.tmTheme diff --git a/sublime/themes/ayu-dark.tmTheme b/components/config/sublime/themes/ayu-dark.tmTheme similarity index 100% rename from sublime/themes/ayu-dark.tmTheme rename to components/config/sublime/themes/ayu-dark.tmTheme diff --git a/sublime/themes/ayu-light.tmTheme b/components/config/sublime/themes/ayu-light.tmTheme similarity index 100% rename from sublime/themes/ayu-light.tmTheme rename to components/config/sublime/themes/ayu-light.tmTheme diff --git a/sublime/themes/ayu-mirage.tmTheme b/components/config/sublime/themes/ayu-mirage.tmTheme similarity index 100% rename from sublime/themes/ayu-mirage.tmTheme rename to components/config/sublime/themes/ayu-mirage.tmTheme diff --git a/sublime/themes/base16-atelierdune-light.tmTheme b/components/config/sublime/themes/base16-atelierdune-light.tmTheme similarity index 100% rename from sublime/themes/base16-atelierdune-light.tmTheme rename to components/config/sublime/themes/base16-atelierdune-light.tmTheme diff --git a/sublime/themes/base16-ocean-dark.tmTheme b/components/config/sublime/themes/base16-ocean-dark.tmTheme similarity index 100% rename from sublime/themes/base16-ocean-dark.tmTheme rename to components/config/sublime/themes/base16-ocean-dark.tmTheme diff --git a/sublime/themes/base16-ocean-light.tmTheme b/components/config/sublime/themes/base16-ocean-light.tmTheme similarity index 100% rename from sublime/themes/base16-ocean-light.tmTheme rename to components/config/sublime/themes/base16-ocean-light.tmTheme diff --git a/sublime/themes/bbedit.tmTheme b/components/config/sublime/themes/bbedit.tmTheme similarity index 100% rename from sublime/themes/bbedit.tmTheme rename to components/config/sublime/themes/bbedit.tmTheme diff --git a/sublime/themes/boron.tmTheme b/components/config/sublime/themes/boron.tmTheme similarity index 100% rename from sublime/themes/boron.tmTheme rename to components/config/sublime/themes/boron.tmTheme diff --git a/sublime/themes/charcoal.tmTheme b/components/config/sublime/themes/charcoal.tmTheme similarity index 100% rename from sublime/themes/charcoal.tmTheme rename to components/config/sublime/themes/charcoal.tmTheme diff --git a/sublime/themes/cheerfully-light.tmTheme b/components/config/sublime/themes/cheerfully-light.tmTheme similarity index 100% rename from sublime/themes/cheerfully-light.tmTheme rename to components/config/sublime/themes/cheerfully-light.tmTheme diff --git a/sublime/themes/classic-modified.tmTheme b/components/config/sublime/themes/classic-modified.tmTheme similarity index 100% rename from sublime/themes/classic-modified.tmTheme rename to components/config/sublime/themes/classic-modified.tmTheme diff --git a/sublime/themes/demain.tmTheme b/components/config/sublime/themes/demain.tmTheme similarity index 100% rename from sublime/themes/demain.tmTheme rename to components/config/sublime/themes/demain.tmTheme diff --git a/sublime/themes/dimmed-fluid.tmTheme b/components/config/sublime/themes/dimmed-fluid.tmTheme similarity index 100% rename from sublime/themes/dimmed-fluid.tmTheme rename to components/config/sublime/themes/dimmed-fluid.tmTheme diff --git a/sublime/themes/dracula.tmTheme b/components/config/sublime/themes/dracula.tmTheme similarity index 100% rename from sublime/themes/dracula.tmTheme rename to components/config/sublime/themes/dracula.tmTheme diff --git a/sublime/themes/gray-matter-dark.tmTheme b/components/config/sublime/themes/gray-matter-dark.tmTheme similarity index 100% rename from sublime/themes/gray-matter-dark.tmTheme rename to components/config/sublime/themes/gray-matter-dark.tmTheme diff --git a/sublime/themes/green.tmTheme b/components/config/sublime/themes/green.tmTheme similarity index 100% rename from sublime/themes/green.tmTheme rename to components/config/sublime/themes/green.tmTheme diff --git a/sublime/themes/gruvbox-dark.tmTheme b/components/config/sublime/themes/gruvbox-dark.tmTheme similarity index 100% rename from sublime/themes/gruvbox-dark.tmTheme rename to components/config/sublime/themes/gruvbox-dark.tmTheme diff --git a/sublime/themes/gruvbox-light.tmTheme b/components/config/sublime/themes/gruvbox-light.tmTheme similarity index 100% rename from sublime/themes/gruvbox-light.tmTheme rename to components/config/sublime/themes/gruvbox-light.tmTheme diff --git a/sublime/themes/idle.tmTheme b/components/config/sublime/themes/idle.tmTheme similarity index 100% rename from sublime/themes/idle.tmTheme rename to components/config/sublime/themes/idle.tmTheme diff --git a/sublime/themes/inspired-github.tmTheme b/components/config/sublime/themes/inspired-github.tmTheme similarity index 100% rename from sublime/themes/inspired-github.tmTheme rename to components/config/sublime/themes/inspired-github.tmTheme diff --git a/sublime/themes/ir-white.tmTheme b/components/config/sublime/themes/ir-white.tmTheme similarity index 100% rename from sublime/themes/ir-white.tmTheme rename to components/config/sublime/themes/ir-white.tmTheme diff --git a/sublime/themes/kronuz.tmTheme b/components/config/sublime/themes/kronuz.tmTheme similarity index 100% rename from sublime/themes/kronuz.tmTheme rename to components/config/sublime/themes/kronuz.tmTheme diff --git a/sublime/themes/material-dark.tmTheme b/components/config/sublime/themes/material-dark.tmTheme similarity index 100% rename from sublime/themes/material-dark.tmTheme rename to components/config/sublime/themes/material-dark.tmTheme diff --git a/sublime/themes/material-light.tmTheme b/components/config/sublime/themes/material-light.tmTheme similarity index 100% rename from sublime/themes/material-light.tmTheme rename to components/config/sublime/themes/material-light.tmTheme diff --git a/sublime/themes/monokai.tmTheme b/components/config/sublime/themes/monokai.tmTheme similarity index 100% rename from sublime/themes/monokai.tmTheme rename to components/config/sublime/themes/monokai.tmTheme diff --git a/sublime/themes/nord.tmTheme b/components/config/sublime/themes/nord.tmTheme similarity index 100% rename from sublime/themes/nord.tmTheme rename to components/config/sublime/themes/nord.tmTheme diff --git a/sublime/themes/nyx-bold.tmTheme b/components/config/sublime/themes/nyx-bold.tmTheme similarity index 100% rename from sublime/themes/nyx-bold.tmTheme rename to components/config/sublime/themes/nyx-bold.tmTheme diff --git a/sublime/themes/one-dark.tmTheme b/components/config/sublime/themes/one-dark.tmTheme similarity index 100% rename from sublime/themes/one-dark.tmTheme rename to components/config/sublime/themes/one-dark.tmTheme diff --git a/sublime/themes/railsbase16-green-screen-dark.tmTheme b/components/config/sublime/themes/railsbase16-green-screen-dark.tmTheme similarity index 100% rename from sublime/themes/railsbase16-green-screen-dark.tmTheme rename to components/config/sublime/themes/railsbase16-green-screen-dark.tmTheme diff --git a/sublime/themes/solarized-dark.tmTheme b/components/config/sublime/themes/solarized-dark.tmTheme similarity index 100% rename from sublime/themes/solarized-dark.tmTheme rename to components/config/sublime/themes/solarized-dark.tmTheme diff --git a/sublime/themes/solarized-light.tmTheme b/components/config/sublime/themes/solarized-light.tmTheme similarity index 100% rename from sublime/themes/solarized-light.tmTheme rename to components/config/sublime/themes/solarized-light.tmTheme diff --git a/sublime/themes/subway-madrid.tmTheme b/components/config/sublime/themes/subway-madrid.tmTheme similarity index 100% rename from sublime/themes/subway-madrid.tmTheme rename to components/config/sublime/themes/subway-madrid.tmTheme diff --git a/sublime/themes/subway-moscow.tmTheme b/components/config/sublime/themes/subway-moscow.tmTheme similarity index 100% rename from sublime/themes/subway-moscow.tmTheme rename to components/config/sublime/themes/subway-moscow.tmTheme diff --git a/sublime/themes/two-dark.tmTheme b/components/config/sublime/themes/two-dark.tmTheme similarity index 100% rename from sublime/themes/two-dark.tmTheme rename to components/config/sublime/themes/two-dark.tmTheme diff --git a/sublime/themes/visual-studio-dark.tmTheme b/components/config/sublime/themes/visual-studio-dark.tmTheme similarity index 100% rename from sublime/themes/visual-studio-dark.tmTheme rename to components/config/sublime/themes/visual-studio-dark.tmTheme diff --git a/sublime/themes/zenburn.tmTheme b/components/config/sublime/themes/zenburn.tmTheme similarity index 100% rename from sublime/themes/zenburn.tmTheme rename to components/config/sublime/themes/zenburn.tmTheme diff --git a/components/content/Cargo.toml b/components/content/Cargo.toml index df99263b12..8de3328244 100644 --- a/components/content/Cargo.toml +++ b/components/content/Cargo.toml @@ -18,3 +18,4 @@ markdown = { path = "../markdown" } [dev-dependencies] test-case = "3" # TODO: can we solve that usecase in src/page.rs in a simpler way? A custom macro_rules! maybe tempfile = "3.3.0" +templates = { path = "../templates" } diff --git a/components/content/src/front_matter/section.rs b/components/content/src/front_matter/section.rs index 76c51461c2..bed9cd0758 100644 --- a/components/content/src/front_matter/section.rs +++ b/components/content/src/front_matter/section.rs @@ -8,7 +8,7 @@ use utils::types::InsertAnchor; use crate::front_matter::split::RawFrontMatter; use crate::SortBy; -static DEFAULT_PAGINATE_PATH: &str = "page"; +const DEFAULT_PAGINATE_PATH: &str = "page"; /// The front matter of every section #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/components/content/src/page.rs b/components/content/src/page.rs index 041ab981da..a860ee50d8 100644 --- a/components/content/src/page.rs +++ b/components/content/src/page.rs @@ -302,8 +302,8 @@ mod tests { use std::path::{Path, PathBuf}; use libs::globset::{Glob, GlobSetBuilder}; - use libs::tera::Tera; use tempfile::tempdir; + use templates::ZOLA_TERA; use crate::Page; use config::{Config, LanguageOptions}; @@ -325,7 +325,7 @@ Hello world"#; let mut page = res.unwrap(); page.render_markdown( &HashMap::default(), - &Tera::default(), + &ZOLA_TERA, &config, InsertAnchor::None, &HashMap::new(), @@ -353,7 +353,7 @@ Hello world"#; let mut page = res.unwrap(); page.render_markdown( &HashMap::default(), - &Tera::default(), + &ZOLA_TERA, &config, InsertAnchor::None, &HashMap::new(), @@ -523,13 +523,13 @@ Hello world let mut page = res.unwrap(); page.render_markdown( &HashMap::default(), - &Tera::default(), + &ZOLA_TERA, &config, InsertAnchor::None, &HashMap::new(), ) .unwrap(); - assert_eq!(page.summary, Some("

Hello world

\n".to_string())); + assert_eq!(page.summary, Some("

Hello world

".to_string())); } #[test] @@ -557,7 +557,7 @@ And here's another. [^3] let mut page = res.unwrap(); page.render_markdown( &HashMap::default(), - &Tera::default(), + &ZOLA_TERA, &config, InsertAnchor::None, &HashMap::new(), @@ -565,7 +565,7 @@ And here's another. [^3] .unwrap(); assert_eq!( page.summary, - Some("

This page use 1.5 and has footnotes, here\'s one.

\n

Here's another.

\n".to_string()) + Some("

This page use 1.5 and has footnotes, here\'s one.

\n

Here's another.

".to_string()) ); } diff --git a/components/content/src/ser.rs b/components/content/src/ser.rs index 919d0d1bb6..d77a43dd16 100644 --- a/components/content/src/ser.rs +++ b/components/content/src/ser.rs @@ -162,6 +162,8 @@ pub struct SerializingSection<'a> { backlinks: Vec>, generate_feeds: bool, transparent: bool, + paginate_by: &'a Option, + paginate_reversed: bool, } #[derive(Debug)] @@ -226,6 +228,8 @@ impl<'a> SerializingSection<'a> { subsections, translations, backlinks, + paginate_by: §ion.meta.paginate_by, + paginate_reversed: section.meta.paginate_reversed, } } } diff --git a/components/imageproc/Cargo.toml b/components/imageproc/Cargo.toml index 7f05f975b1..ad4c6c48f0 100644 --- a/components/imageproc/Cargo.toml +++ b/components/imageproc/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] serde = { version = "1", features = ["derive"] } -kamadak-exif = "0.5.4" +kamadak-exif = "0.6" errors = { path = "../errors" } utils = { path = "../utils" } diff --git a/components/imageproc/src/meta.rs b/components/imageproc/src/meta.rs index 8ee83c335f..33c03facd8 100644 --- a/components/imageproc/src/meta.rs +++ b/components/imageproc/src/meta.rs @@ -1,5 +1,5 @@ use errors::{anyhow, Context, Result}; -use libs::image::io::Reader as ImgReader; +use libs::image::ImageReader; use libs::image::{ImageFormat, ImageResult}; use libs::svg_metadata::Metadata as SvgMetadata; use serde::Serialize; @@ -16,7 +16,7 @@ pub struct ImageMeta { impl ImageMeta { pub fn read(path: &Path) -> ImageResult { - let reader = ImgReader::open(path).and_then(ImgReader::with_guessed_format)?; + let reader = ImageReader::open(path).and_then(ImageReader::with_guessed_format)?; let format = reader.format(); let size = reader.into_dimensions()?; diff --git a/components/imageproc/src/processor.rs b/components/imageproc/src/processor.rs index 577aeb1f3e..8cf2ef59ff 100644 --- a/components/imageproc/src/processor.rs +++ b/components/imageproc/src/processor.rs @@ -18,7 +18,7 @@ use crate::format::Format; use crate::helpers::get_processed_filename; use crate::{fix_orientation, ImageMeta, ResizeInstructions, ResizeOperation}; -pub static RESIZED_SUBDIR: &str = "processed_images"; +pub const RESIZED_SUBDIR: &str = "processed_images"; /// Holds all data needed to perform a resize operation #[derive(Debug, PartialEq, Eq, Hash)] diff --git a/components/imageproc/tests/resize_image.rs b/components/imageproc/tests/resize_image.rs index 41114abf50..9ec17362ce 100644 --- a/components/imageproc/tests/resize_image.rs +++ b/components/imageproc/tests/resize_image.rs @@ -16,7 +16,7 @@ fn assert_processed_path_matches(path: &str, prefix: &str, extension: &str) { assert!(filename.ends_with(&suffix), "Path `{}` doesn't end with `{}`", path, suffix); } -static CONFIG: &str = r#" +const CONFIG: &str = r#" title = "imageproc integration tests" base_url = "https://example.com" compile_sass = false diff --git a/components/libs/Cargo.toml b/components/libs/Cargo.toml index ea3c82463c..8c5a8f3b2e 100644 --- a/components/libs/Cargo.toml +++ b/components/libs/Cargo.toml @@ -21,13 +21,13 @@ nom-bibtex = "0.5" num-format = "0.4" once_cell = "1" percent-encoding = "2" -pulldown-cmark = { version = "0.11", default-features = false, features = ["html", "simd"] } +pulldown-cmark = { version = "0.12.2", default-features = false, features = ["html", "simd"] } pulldown-cmark-escape = { version = "0.11", default-features = false } quickxml_to_serde = "0.6" rayon = "1" regex = "1" relative-path = "1" -reqwest = { version = "0.11", default-features = false, features = ["blocking"] } +reqwest = { version = "0.12", default-features = false, features = ["blocking"] } grass = {version = "0.13", default-features = false, features = ["random"]} serde_json = "1" serde_yaml = "0.9" diff --git a/components/link_checker/Cargo.toml b/components/link_checker/Cargo.toml index 8a5e9720ae..745c176a8f 100644 --- a/components/link_checker/Cargo.toml +++ b/components/link_checker/Cargo.toml @@ -10,4 +10,4 @@ utils = { path = "../utils" } libs = { path = "../libs" } [dev-dependencies] -mockito = "0.31" +mockito = "1.6" diff --git a/components/link_checker/src/lib.rs b/components/link_checker/src/lib.rs index ab44259217..eac70c5de7 100644 --- a/components/link_checker/src/lib.rs +++ b/components/link_checker/src/lib.rs @@ -124,7 +124,6 @@ mod tests { check_page_for_anchor, check_url, has_anchor, is_valid, message, LinkChecker, LINKS, }; use libs::reqwest::StatusCode; - use mockito::mock; // NOTE: HTTP mock paths below are randomly generated to avoid name // collisions. Mocks with the same path can sometimes bleed between tests @@ -133,8 +132,10 @@ mod tests { #[test] fn can_validate_ok_links() { - let url = format!("{}{}", mockito::server_url(), "/ekbtwxfhjw"); - let _m = mock("GET", "/ekbtwxfhjw") + let mut server = mockito::Server::new(); + let url = format!("{}{}", server.url(), "/ekbtwxfhjw"); + let _m = server + .mock("GET", "/ekbtwxfhjw") .with_header("Content-Type", "text/html") .with_body(format!( r#" @@ -159,19 +160,22 @@ mod tests { #[test] fn can_follow_301_links() { - let _m1 = mock("GET", "/c7qrtrv3zz") + let mut server = mockito::Server::new(); + let _m1 = server + .mock("GET", "/c7qrtrv3zz") .with_status(301) .with_header("Content-Type", "text/plain") - .with_header("Location", format!("{}/rbs5avjs8e", mockito::server_url()).as_str()) + .with_header("Location", format!("{}/rbs5avjs8e", server.url()).as_str()) .with_body("Redirecting...") .create(); - let _m2 = mock("GET", "/rbs5avjs8e") + let _m2 = server + .mock("GET", "/rbs5avjs8e") .with_header("Content-Type", "text/plain") .with_body("Test") .create(); - let url = format!("{}{}", mockito::server_url(), "/c7qrtrv3zz"); + let url = format!("{}{}", server.url(), "/c7qrtrv3zz"); let res = check_url(&url, &LinkChecker::default()); assert!(is_valid(&res)); assert!(res.is_ok()); @@ -180,14 +184,16 @@ mod tests { #[test] fn set_default_user_agent() { + let mut server = mockito::Server::new(); let user_agent = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); - let _m1 = mock("GET", "/C4Szbfnvj6M0LoPk") + let _m1 = server + .mock("GET", "/C4Szbfnvj6M0LoPk") .match_header("User-Agent", user_agent) .with_status(200) .with_body("Test") .create(); - let url = format!("{}{}", mockito::server_url(), "/C4Szbfnvj6M0LoPk"); + let url = format!("{}{}", server.url(), "/C4Szbfnvj6M0LoPk"); let res = check_url(&url, &LinkChecker::default()); assert!(is_valid(&res)); assert_eq!(res.unwrap(), StatusCode::OK); @@ -195,20 +201,23 @@ mod tests { #[test] fn can_fail_301_to_404_links() { - let _m1 = mock("GET", "/cav9vibhsc") + let mut server = mockito::Server::new(); + let _m1 = server + .mock("GET", "/cav9vibhsc") .with_status(301) .with_header("Content-Type", "text/plain") - .with_header("Location", format!("{}/72zmfg4smd", mockito::server_url()).as_str()) + .with_header("Location", format!("{}/72zmfg4smd", server.url()).as_str()) .with_body("Redirecting...") .create(); - let _m2 = mock("GET", "/72zmfg4smd") + let _m2 = server + .mock("GET", "/72zmfg4smd") .with_status(404) .with_header("Content-Type", "text/plain") .with_body("Not Found") .create(); - let url = format!("{}{}", mockito::server_url(), "/cav9vibhsc"); + let url = format!("{}{}", server.url(), "/cav9vibhsc"); let res = check_url(&url, &LinkChecker::default()); assert!(!is_valid(&res)); assert!(res.is_err()); @@ -217,13 +226,15 @@ mod tests { #[test] fn can_fail_404_links() { - let _m = mock("GET", "/nlhab9c1vc") + let mut server = mockito::Server::new(); + let _m = server + .mock("GET", "/nlhab9c1vc") .with_status(404) .with_header("Content-Type", "text/plain") .with_body("Not Found") .create(); - let url = format!("{}{}", mockito::server_url(), "/nlhab9c1vc"); + let url = format!("{}{}", server.url(), "/nlhab9c1vc"); let res = check_url(&url, &LinkChecker::default()); assert!(!is_valid(&res)); assert!(res.is_err()); @@ -232,13 +243,15 @@ mod tests { #[test] fn can_fail_500_links() { - let _m = mock("GET", "/qdbrssazes") + let mut server = mockito::Server::new(); + let _m = server + .mock("GET", "/qdbrssazes") .with_status(500) .with_header("Content-Type", "text/plain") .with_body("Internal Server Error") .create(); - let url = format!("{}{}", mockito::server_url(), "/qdbrssazes"); + let url = format!("{}{}", server.url(), "/qdbrssazes"); let res = check_url(&url, &LinkChecker::default()); assert!(!is_valid(&res)); assert!(res.is_err()); @@ -329,10 +342,12 @@ mod tests { #[test] fn skip_anchor_prefixes() { - let ignore_url = format!("{}{}", mockito::server_url(), "/ignore/"); + let mut server = mockito::Server::new(); + let ignore_url = format!("{}{}", server.url(), "/ignore/"); let config = LinkChecker { skip_anchor_prefixes: vec![ignore_url], ..Default::default() }; - let _m1 = mock("GET", "/ignore/i30hobj1cy") + let _m1 = server + .mock("GET", "/ignore/i30hobj1cy") .with_header("Content-Type", "text/html") .with_body( r#" @@ -349,10 +364,11 @@ mod tests { .create(); // anchor check is ignored because the url matches the prefix - let ignore = format!("{}{}", mockito::server_url(), "/ignore/i30hobj1cy#nonexistent"); + let ignore = format!("{}{}", server.url(), "/ignore/i30hobj1cy#nonexistent"); assert!(is_valid(&check_url(&ignore, &config))); - let _m2 = mock("GET", "/guvqcqwmth") + let _m2 = server + .mock("GET", "/guvqcqwmth") .with_header("Content-Type", "text/html") .with_body( r#" @@ -369,10 +385,10 @@ mod tests { .create(); // other anchors are checked - let existent = format!("{}{}", mockito::server_url(), "/guvqcqwmth#existent"); + let existent = format!("{}{}", server.url(), "/guvqcqwmth#existent"); assert!(is_valid(&check_url(&existent, &config))); - let nonexistent = format!("{}{}", mockito::server_url(), "/guvqcqwmth#nonexistent"); + let nonexistent = format!("{}{}", server.url(), "/guvqcqwmth#nonexistent"); assert!(!is_valid(&check_url(&nonexistent, &config))); } } diff --git a/components/markdown/benches/all.rs b/components/markdown/benches/all.rs index 5b4f915792..ffec285088 100644 --- a/components/markdown/benches/all.rs +++ b/components/markdown/benches/all.rs @@ -8,7 +8,7 @@ use libs::tera::Tera; use markdown::{render_content, RenderContext}; use utils::types::InsertAnchor; -static CONTENT: &str = r#" +const CONTENT: &str = r#" # Modus cognitius profanam ne duae virtutis mundi ## Ut vita @@ -147,6 +147,7 @@ fn bench_render_content_with_emoji(b: &mut test::Bencher) { let tera = Tera::default(); let content2 = CONTENT.replace(r#"{{ youtube(id="my_youtube_id") }}"#, ""); let mut config = Config::default_for_test(); + config.markdown.highlight_code = false; config.markdown.render_emoji = true; let permalinks_ctx = HashMap::new(); diff --git a/components/markdown/src/codeblock/fence.rs b/components/markdown/src/codeblock/fence.rs index 3658ce54ed..eb3208613b 100644 --- a/components/markdown/src/codeblock/fence.rs +++ b/components/markdown/src/codeblock/fence.rs @@ -24,6 +24,7 @@ pub struct FenceSettings<'a> { pub line_number_start: usize, pub highlight_lines: Vec>, pub hide_lines: Vec>, + pub name: Option<&'a str>, } impl<'a> FenceSettings<'a> { @@ -34,6 +35,7 @@ impl<'a> FenceSettings<'a> { line_number_start: 1, highlight_lines: Vec::new(), hide_lines: Vec::new(), + name: None, }; for token in FenceIter::new(fence_info) { @@ -43,6 +45,7 @@ impl<'a> FenceSettings<'a> { FenceToken::InitialLineNumber(l) => me.line_number_start = l, FenceToken::HighlightLines(lines) => me.highlight_lines.extend(lines), FenceToken::HideLines(lines) => me.hide_lines.extend(lines), + FenceToken::Name(n) => me.name = Some(n), } } @@ -57,6 +60,7 @@ enum FenceToken<'a> { InitialLineNumber(usize), HighlightLines(Vec>), HideLines(Vec>), + Name(&'a str), } struct FenceIter<'a> { @@ -103,7 +107,16 @@ impl<'a> Iterator for FenceIter<'a> { let ranges = Self::parse_ranges(tok_split.next()); return Some(FenceToken::HideLines(ranges)); } + "name" => { + if let Some(n) = tok_split.next() { + return Some(FenceToken::Name(n)); + } + } lang => { + if tok_split.next().is_some() { + eprintln!("Warning: Unknown annotation {}", lang); + continue; + } return Some(FenceToken::Language(lang)); } } diff --git a/components/markdown/src/codeblock/mod.rs b/components/markdown/src/codeblock/mod.rs index 5e297926ff..004538bb9f 100644 --- a/components/markdown/src/codeblock/mod.rs +++ b/components/markdown/src/codeblock/mod.rs @@ -3,6 +3,7 @@ mod highlight; use std::ops::RangeInclusive; +use errors::{bail, Result}; use libs::syntect::util::LinesWithEndings; use crate::codeblock::highlight::SyntaxHighlighter; @@ -12,6 +13,7 @@ pub(crate) use fence::FenceSettings; fn opening_html( language: Option<&str>, + name: Option<&str>, pre_style: Option, pre_class: Option, line_numbers: bool, @@ -32,6 +34,12 @@ fn opening_html( html.push('"'); } + if let Some(name) = name { + html.push_str(" data-name=\""); + html.push_str(name); + html.push('"'); + } + if let Some(styles) = pre_style { html.push_str(" style=\""); html.push_str(styles.as_str()); @@ -56,6 +64,12 @@ fn opening_html( html.push_str(lang); html.push('"'); } + + if let Some(name) = name { + html.push_str(" data-name=\""); + html.push_str(name); + html.push('"'); + } html.push('>'); html } @@ -75,25 +89,31 @@ impl<'config> CodeBlock<'config> { config: &'config Config, // path to the current file if there is one, to point where the error is path: Option<&'config str>, - ) -> (Self, String) { + ) -> Result<(Self, String)> { let syntax_and_theme = resolve_syntax_and_theme(fence.language, config); if syntax_and_theme.source == HighlightSource::NotFound && config.markdown.highlight_code { let lang = fence.language.unwrap(); - if let Some(p) = path { - eprintln!("Warning: Highlight language {} not found in {}", lang, p); + let msg = if let Some(p) = path { + format!("Highlight language {} not found in {}", lang, p) + } else { + format!("Highlight language {} not found", lang) + }; + if config.markdown.error_on_missing_highlight { + bail!(msg); } else { - eprintln!("Warning: Highlight language {} not found", lang); + eprintln!("Warning: {}", msg); } } let highlighter = SyntaxHighlighter::new(config.markdown.highlight_code, syntax_and_theme); let html_start = opening_html( fence.language, + fence.name, highlighter.pre_style(), highlighter.pre_class(), fence.line_numbers, ); - ( + Ok(( Self { highlighter, line_numbers: fence.line_numbers, @@ -102,7 +122,7 @@ impl<'config> CodeBlock<'config> { hide_lines: fence.hide_lines, }, html_start, - ) + )) } pub fn highlight(&mut self, content: &str) -> String { diff --git a/components/markdown/src/content.pest b/components/markdown/src/content.pest index fcf8c1b5b3..d706656123 100644 --- a/components/markdown/src/content.pest +++ b/components/markdown/src/content.pest @@ -55,9 +55,9 @@ ignored_sc_body_end = !{ "{%/*" ~ "end" ~ "*/%}" } shortcode_with_body = !{ sc_body_start ~ text_in_body_sc ~ sc_body_end } ignored_shortcode_with_body = { ignored_sc_body_start ~ text_in_ignored_body_sc ~ ignored_sc_body_end } -text_in_body_sc = ${ (!(sc_body_end) ~ ANY)+ } -text_in_ignored_body_sc = ${ (!(ignored_sc_body_end) ~ ANY)+ } -text = ${ (!(inline_shortcode | ignored_inline_shortcode | shortcode_with_body | ignored_shortcode_with_body) ~ ANY)+ } +text_in_body_sc = ${ (!(sc_body_end) ~ content)+ } +text_in_ignored_body_sc = ${ (!(ignored_sc_body_end) ~ content)+ } +text = ${ (!(inline_shortcode | ignored_inline_shortcode | sc_body_start | ignored_sc_body_start | sc_body_end | ignored_sc_body_end) ~ ANY)+ } content = _{ ignored_inline_shortcode | diff --git a/components/markdown/src/markdown.rs b/components/markdown/src/markdown.rs index 8bdc778e22..bd69efa93e 100644 --- a/components/markdown/src/markdown.rs +++ b/components/markdown/src/markdown.rs @@ -24,6 +24,7 @@ use crate::codeblock::{CodeBlock, FenceSettings}; use crate::shortcode::{Shortcode, SHORTCODE_PLACEHOLDER}; const CONTINUE_READING: &str = ""; +const SUMMARY_CUTOFF_TEMPLATE: &str = "summary-cutoff.html"; const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html"; static EMOJI_REPLACER: Lazy = Lazy::new(EmojiReplacer::new); @@ -277,7 +278,7 @@ fn convert_footnotes_to_github_style(old_events: &mut Vec) { // nr is a number of references to this footnote let (n, nr) = footnote_numbers.entry(name.clone()).or_insert((n, 0usize)); *nr += 1; - let reference = Event::Html(format!(r##"
[{n}]"##).into()); + let reference = Event::Html(format!(r##"{n}"##).into()); if footnote_bodies_stack.is_empty() { // we are in the main text, just output the reference @@ -304,7 +305,8 @@ fn convert_footnotes_to_github_style(old_events: &mut Vec) { return; } - old_events.push(Event::Html("
    \n".into())); + old_events + .push(Event::Html("
    \n
      \n".into())); // Step 2: retain only footnotes which was actually referenced footnotes.retain(|f| match f.first() { @@ -341,7 +343,7 @@ fn convert_footnotes_to_github_style(old_events: &mut Vec) { // // HTML: // - //

      five [1].

      + //

      five 1.

      // //
        //
      1. @@ -394,7 +396,7 @@ fn convert_footnotes_to_github_style(old_events: &mut Vec) { }); old_events.extend(footnotes); - old_events.push(Event::Html("
      \n".into())); + old_events.push(Event::Html("
    \n
    \n".into())); } pub fn markdown_to_html( @@ -438,6 +440,9 @@ pub fn markdown_to_html( if context.config.markdown.smart_punctuation { opts.insert(Options::ENABLE_SMART_PUNCTUATION); } + if context.config.markdown.definition_list { + opts.insert(Options::ENABLE_DEFINITION_LIST); + } // we reverse their order so we can pop them easily in order let mut html_shortcodes: Vec<_> = html_shortcodes.into_iter().rev().collect(); @@ -559,7 +564,13 @@ pub fn markdown_to_html( cmark::CodeBlockKind::Fenced(fence_info) => FenceSettings::new(fence_info), _ => FenceSettings::new(""), }; - let (block, begin) = CodeBlock::new(fence, context.config, path); + let (block, begin) = match CodeBlock::new(fence, context.config, path) { + Ok(cb) => cb, + Err(e) => { + error = Some(e); + break; + } + }; code_block = Some(block); events.push(Event::Html(begin.into())); } @@ -684,7 +695,9 @@ pub fn markdown_to_html( event }); } - Event::Html(text) if !has_summary && MORE_DIVIDER_RE.is_match(text.as_ref()) => { + Event::Html(text) | Event::InlineHtml(text) + if !has_summary && MORE_DIVIDER_RE.is_match(text.as_ref()) => + { has_summary = true; events.push(Event::Html(CONTINUE_READING.into())); } @@ -787,6 +800,19 @@ pub fn markdown_to_html( .position(|e| matches!(e, Event::Html(CowStr::Borrowed(CONTINUE_READING)))) .unwrap_or(events.len()); + // determine closing tags missing from summary + let mut tags = Vec::new(); + for event in &events[..continue_reading] { + match event { + Event::Start(Tag::HtmlBlock) | Event::End(TagEnd::HtmlBlock) => (), + Event::Start(tag) => tags.push(tag.to_end()), + Event::End(tag) => { + tags.truncate(tags.iter().rposition(|t| *t == *tag).unwrap_or(0)); + } + _ => (), + } + } + let mut events = events.into_iter(); // emit everything up to summary @@ -794,8 +820,30 @@ pub fn markdown_to_html( if has_summary { // remove footnotes - let summary_html = FOOTNOTES_RE.replace_all(&html, "").into_owned(); - summary = Some(summary_html) + let mut summary_html = FOOTNOTES_RE.replace_all(&html, "").into_owned(); + + // truncate trailing whitespace + summary_html.truncate(summary_html.trim_end().len()); + + // add cutoff template + if !tags.is_empty() { + let mut c = tera::Context::new(); + c.insert("summary", &summary_html); + c.insert("lang", &context.lang); + let summary_cutoff = utils::templates::render_template( + SUMMARY_CUTOFF_TEMPLATE, + &context.tera, + c, + &None, + ) + .context("Failed to render summary cutoff template")?; + summary_html.push_str(&summary_cutoff); + } + + // close remaining tags + cmark::html::push_html(&mut summary_html, tags.into_iter().rev().map(Event::End)); + + summary = Some(summary_html); } // emit everything after summary @@ -820,6 +868,7 @@ mod tests { use super::*; use config::Config; use insta::assert_snapshot; + use templates::ZOLA_TERA; #[test] fn insert_many_works() { @@ -875,7 +924,8 @@ mod tests { let mores = ["", "", "", "", ""]; let config = Config::default(); - let context = RenderContext::from_config(&config); + let mut context = RenderContext::from_config(&config); + context.tera.to_mut().extend(&ZOLA_TERA).unwrap(); for more in mores { let content = format!("{top}\n\n{more}\n\n{bottom}"); let rendered = markdown_to_html(&content, &context, vec![]).unwrap(); diff --git a/components/markdown/src/shortcode/mod.rs b/components/markdown/src/shortcode/mod.rs index 4239ed4d37..dd13aff20b 100644 --- a/components/markdown/src/shortcode/mod.rs +++ b/components/markdown/src/shortcode/mod.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; -use errors::{Error, Result}; +use errors::Result; use libs::tera; -use utils::templates::{ShortcodeDefinition, ShortcodeFileType}; +use utils::templates::{ShortcodeDefinition, ShortcodeFileType, ShortcodeInvocationCounter}; mod parser; @@ -13,14 +13,11 @@ pub fn extract_shortcodes( source: &str, definitions: &HashMap, ) -> Result<(String, Vec)> { - let (out, mut shortcodes) = parse_for_shortcodes(source)?; + let (out, mut shortcodes) = + parse_for_shortcodes(source, &mut ShortcodeInvocationCounter::new())?; for sc in &mut shortcodes { - if let Some(def) = definitions.get(&sc.name) { - sc.tera_name = def.tera_name.clone(); - } else { - return Err(Error::msg(format!("Found usage of a shortcode named `{}` but we do not know about. Make sure it's not a typo and that a field name `{}.{{html,md}} exists in the `templates/shortcodes` directory.", sc.name, sc.name))); - } + sc.fill_tera_name(definitions)?; } Ok((out, shortcodes)) @@ -79,6 +76,7 @@ mod tests { span: 0..SHORTCODE_PLACEHOLDER.len(), body: None, nth: 1, + inner: Vec::new(), tera_name: "shortcodes/a.md".to_owned(), }, Shortcode { @@ -87,6 +85,7 @@ mod tests { span: SHORTCODE_PLACEHOLDER.len()..(2 * SHORTCODE_PLACEHOLDER.len()), body: None, nth: 2, + inner: Vec::new(), tera_name: "shortcodes/a.md".to_owned(), } ], @@ -107,7 +106,35 @@ mod tests { span: 9..(9 + SHORTCODE_PLACEHOLDER.len()), body: Some("Content of the body".to_owned()), nth: 1, + inner: Vec::new(), + tera_name: "shortcodes/bodied.md".to_owned(), + },], + &tera_context, + &tera + ) + .unwrap() + .0, + "Much wow Content of the body".to_string() + ); + assert_eq!( + insert_md_shortcodes( + format!("Much wow {}", SHORTCODE_PLACEHOLDER), + vec![Shortcode { + name: "bodied".to_string(), + args: to_value(&HashMap::::new()).unwrap(), + span: 9..(9 + SHORTCODE_PLACEHOLDER.len()), + body: Some(format!("Content of {SHORTCODE_PLACEHOLDER}")), + nth: 1, + inner: vec![Shortcode { + name: "bodied".to_string(), + args: to_value(&HashMap::::new()).unwrap(), + span: 11..(11 + SHORTCODE_PLACEHOLDER.len()), + body: Some("the body".to_owned()), + nth: 1, + inner: Vec::new(), + tera_name: "shortcodes/bodied.md".to_owned(), + },], tera_name: "shortcodes/bodied.md".to_owned(), },], &tera_context, diff --git a/components/markdown/src/shortcode/parser.rs b/components/markdown/src/shortcode/parser.rs index 4ce30b7bd7..479e2b5586 100644 --- a/components/markdown/src/shortcode/parser.rs +++ b/components/markdown/src/shortcode/parser.rs @@ -1,12 +1,11 @@ -use std::ops::Range; +use std::{collections::HashMap, ops::Range}; use errors::{bail, Context as ErrorContext, Result}; use libs::tera::{to_value, Context, Map, Tera, Value}; use pest::iterators::Pair; use pest::Parser; use pest_derive::Parser; -use std::collections::HashMap; -use utils::templates::ShortcodeFileType; +use utils::templates::{ShortcodeDefinition, ShortcodeFileType, ShortcodeInvocationCounter}; pub const SHORTCODE_PLACEHOLDER: &str = "@@ZOLA_SC_PLACEHOLDER@@"; @@ -14,14 +13,34 @@ pub const SHORTCODE_PLACEHOLDER: &str = "@@ZOLA_SC_PLACEHOLDER@@"; pub struct Shortcode { pub(crate) name: String, pub(crate) args: Value, + // In practice, span.len() is always equal to SHORTCODE_PLACEHOLDER.len() pub(crate) span: Range, pub(crate) body: Option, pub(crate) nth: usize, + pub(crate) inner: Vec, // set later down the line, for quick access without needing the definitions pub(crate) tera_name: String, } impl Shortcode { + /// Attempts to fill the `tera_name` field from the provided definitions for self and all of self.inner. + /// + /// This returns an error if the definitions do not have this shortcode. + pub fn fill_tera_name( + &mut self, + definitions: &HashMap, + ) -> Result<()> { + if let Some(def) = definitions.get(&self.name) { + self.tera_name = def.tera_name.clone(); + } else { + return Err(errors::anyhow!("Found usage of a shortcode named `{}` but we do not know about. Make sure it's not a typo and that a field name `{}.{{html,md}}` exists in the `templates/shortcodes` directory.", self.name, self.name)); + } + for inner_sc in self.inner.iter_mut() { + inner_sc.fill_tera_name(definitions)?; + } + Ok(()) + } + pub fn file_type(&self) -> ShortcodeFileType { if self.tera_name.ends_with("md") { ShortcodeFileType::Markdown @@ -30,7 +49,34 @@ impl Shortcode { } } - pub fn render(self, tera: &Tera, context: &Context) -> Result { + /// Expands all inner-shortcodes and leaves self.inner empty. + /// + /// This function has no effect with shortcodes without bodies. + pub fn render_inner_shortcodes(&mut self, tera: &Tera, context: &Context) -> Result<()> { + let Some(body) = &mut self.body else { + return Ok(()); + }; + for inner_sc in std::mem::take(&mut self.inner).into_iter().rev() { + // We're not considering the file_type of the inner shortcodes. + // - HTML SC invokes HTML SC: works as expected. + // - MD SC invokes HTML SC: MD can do inline-html, it is assumed that this is intentional. + // - MD SC invokes MD SC: works as expected. + // - HTML SC invokes MD SC: HTML SC's with MD bodies usually use the "markdown" filter. + let inner_sc_span = inner_sc.span.clone(); + let inner_sc_result = inner_sc.render(tera, context)?; + body.replace_range(inner_sc_span, &inner_sc_result); + } + Ok(()) + } + + pub fn render(mut self, tera: &Tera, context: &Context) -> Result { + // This function gets called under the following circumstances + // 1. as an .md shortcode, the resulting body is inserted into the document _before_ MD -> HTML conversion + // 2. as an .html shortcode, the result is inserted into the document _during_ MD -> HTML conversion. (The HTML + // is injected into cmark's AST) + // 3. As an inner-part of a shortcode which is being flattened. The file_type is not considered. + self.render_inner_shortcodes(tera, context)?; + let name = self.name; let tpl_name = self.tera_name; let mut new_context = Context::from_value(self.args)?; @@ -49,6 +95,7 @@ impl Shortcode { Ok(res) } + /// Shifts `self.span` by `(rendered_length - sc_span.len())` pub fn update_range(&mut self, sc_span: &Range, rendered_length: usize) { if self.span.start < sc_span.start { return; @@ -152,14 +199,11 @@ fn parse_shortcode_call(pair: Pair) -> (String, Value) { (name.unwrap(), Value::Object(args)) } -pub fn parse_for_shortcodes(content: &str) -> Result<(String, Vec)> { +pub fn parse_for_shortcodes( + content: &str, + invocation_counter: &mut ShortcodeInvocationCounter, +) -> Result<(String, Vec)> { let mut shortcodes = Vec::new(); - let mut nths = HashMap::new(); - let mut get_invocation_count = |name: &str| { - let nth = nths.entry(String::from(name)).or_insert(0); - *nth += 1; - *nth - }; let mut output = String::with_capacity(content.len()); let mut pairs = match ContentParser::parse(Rule::page, content) { @@ -207,13 +251,14 @@ pub fn parse_for_shortcodes(content: &str) -> Result<(String, Vec)> { Rule::inline_shortcode => { let start = output.len(); let (name, args) = parse_shortcode_call(p); - let nth = get_invocation_count(&name); + let nth = invocation_counter.get(&name); shortcodes.push(Shortcode { name, args, span: start..(start + SHORTCODE_PLACEHOLDER.len()), body: None, nth, + inner: Vec::new(), tera_name: String::new(), }); output.push_str(SHORTCODE_PLACEHOLDER); @@ -224,14 +269,18 @@ pub fn parse_for_shortcodes(content: &str) -> Result<(String, Vec)> { // 3 items in inner: call, body, end // we don't care about the closing tag let (name, args) = parse_shortcode_call(inner.next().unwrap()); - let body = inner.next().unwrap().as_span().as_str().trim(); - let nth = get_invocation_count(&name); + let nth = invocation_counter.get(&name); + let (body, inner) = parse_for_shortcodes( + inner.next().unwrap().as_span().as_str().trim(), + invocation_counter, + )?; shortcodes.push(Shortcode { name, args, span: start..(start + SHORTCODE_PLACEHOLDER.len()), - body: Some(body.to_string()), + body: Some(body), nth, + inner, tera_name: String::new(), }); output.push_str(SHORTCODE_PLACEHOLDER) @@ -374,6 +423,7 @@ mod tests { span: 10..20, body: None, nth: 0, + inner: Vec::new(), tera_name: String::new(), }; // 6 -> 10 in length so +4 on both sides of the range @@ -393,6 +443,7 @@ mod tests { span: 42..65, body: None, nth: 0, + inner: Vec::new(), tera_name: String::new(), }; sc.update_range(&(9..32), 3); @@ -403,6 +454,7 @@ mod tests { fn can_extract_basic_inline_shortcode_with_args() { let (out, shortcodes) = parse_for_shortcodes( "Inline shortcode: {{ hello(string='hey', int=1, float=2.1, bool=true, array=[true, false]) }} hey", + &mut ShortcodeInvocationCounter::new(), ) .unwrap(); assert_eq!(out, format!("Inline shortcode: {} hey", SHORTCODE_PLACEHOLDER)); @@ -423,8 +475,11 @@ mod tests { #[test] fn can_unignore_ignored_inline_shortcode() { - let (out, shortcodes) = - parse_for_shortcodes("Hello World {{/* youtube() */}} hey").unwrap(); + let (out, shortcodes) = parse_for_shortcodes( + "Hello World {{/* youtube() */}} hey", + &mut ShortcodeInvocationCounter::new(), + ) + .unwrap(); assert_eq!(out, "Hello World {{ youtube() }} hey"); assert_eq!(shortcodes.len(), 0); } @@ -433,6 +488,7 @@ mod tests { fn can_extract_shortcode_with_body() { let (out, shortcodes) = parse_for_shortcodes( "Body shortcode\n {% quote(author='Bobby', array=[[true]]) %}DROP TABLES;{% end %} \n hey", + &mut ShortcodeInvocationCounter::new() ) .unwrap(); assert_eq!(out, format!("Body shortcode\n {} \n hey", SHORTCODE_PLACEHOLDER)); @@ -451,9 +507,11 @@ mod tests { #[test] fn can_unignore_ignored_shortcode_with_body() { - let (out, shortcodes) = - parse_for_shortcodes("Hello World {%/* youtube() */%} Somebody {%/* end */%} hey") - .unwrap(); + let (out, shortcodes) = parse_for_shortcodes( + "Hello World {%/* youtube() */%} Somebody {%/* end */%} hey", + &mut ShortcodeInvocationCounter::new(), + ) + .unwrap(); assert_eq!(out, "Hello World {% youtube() %} Somebody {% end %} hey"); assert_eq!(shortcodes.len(), 0); } @@ -462,6 +520,7 @@ mod tests { fn can_extract_multiple_shortcodes_and_increment_nth() { let (out, shortcodes) = parse_for_shortcodes( "Hello World {% youtube() %} Somebody {% end %} {{ hello() }}\n {{hello()}}", + &mut ShortcodeInvocationCounter::new(), ) .unwrap(); assert_eq!( @@ -477,6 +536,21 @@ mod tests { assert_eq!(shortcodes[2].nth, 2); } + #[test] + fn can_extract_nested_shortcode_bodies_and_increment_nth() { + let (out, shortcodes) = parse_for_shortcodes( + "Hello World {% i_am_gonna_nest() %} Somebody {% i_am_gonna_nest() %} Somebody {% end %} {% end %}!!", + &mut ShortcodeInvocationCounter::new(), + ) + .unwrap(); + assert_eq!(out, format!("Hello World {}!!", SHORTCODE_PLACEHOLDER,)); + assert_eq!(shortcodes.len(), 1); + assert_eq!(shortcodes[0].inner.len(), 1); + assert_eq!(shortcodes[0].nth, 1); + assert_eq!(shortcodes[0].inner[0].nth, 2); + assert_eq!(shortcodes[0].body, Some(format!("Somebody {SHORTCODE_PLACEHOLDER}"))); + } + #[test] fn can_handle_multiple_shortcodes() { let (_, shortcodes) = parse_for_shortcodes( @@ -486,6 +560,7 @@ mod tests { {{ vimeo(id="210073083#hello", n_a_me="hello") }} {{ streamable(id="c0ic", n1=true) }} {{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }}"#, + &mut ShortcodeInvocationCounter::new(), ) .unwrap(); assert_eq!(shortcodes.len(), 5); diff --git a/components/markdown/src/snapshots/markdown__markdown__tests__def_before_use.snap b/components/markdown/src/snapshots/markdown__markdown__tests__def_before_use.snap index 57e3a922ad..39dca0a91b 100644 --- a/components/markdown/src/snapshots/markdown__markdown__tests__def_before_use.snap +++ b/components/markdown/src/snapshots/markdown__markdown__tests__def_before_use.snap @@ -2,9 +2,11 @@ source: components/markdown/src/markdown.rs expression: html --- -

    There is footnote definition?[1]

    -
      +

      There is footnote definition?1

      +
      +
      1. It's before the reference.

      +
      diff --git a/components/markdown/src/snapshots/markdown__markdown__tests__footnote_inside_footnote.snap b/components/markdown/src/snapshots/markdown__markdown__tests__footnote_inside_footnote.snap index 6b5e28d476..2572a62c68 100644 --- a/components/markdown/src/snapshots/markdown__markdown__tests__footnote_inside_footnote.snap +++ b/components/markdown/src/snapshots/markdown__markdown__tests__footnote_inside_footnote.snap @@ -2,12 +2,14 @@ source: components/markdown/src/markdown.rs expression: html --- -

      This text has a footnote[1]

      -
        +

        This text has a footnote1

        +
        +
        1. -

          But the footnote has another footnote[2].

          +

          But the footnote has another footnote2.

        2. That's it.

        +
        diff --git a/components/markdown/src/snapshots/markdown__markdown__tests__multiple_refs.snap b/components/markdown/src/snapshots/markdown__markdown__tests__multiple_refs.snap index 1f7eaff186..bde7c95a7e 100644 --- a/components/markdown/src/snapshots/markdown__markdown__tests__multiple_refs.snap +++ b/components/markdown/src/snapshots/markdown__markdown__tests__multiple_refs.snap @@ -2,9 +2,11 @@ source: components/markdown/src/markdown.rs expression: html --- -

        This text has two[1] identical footnotes[1]

        -
          +

          This text has two1 identical footnotes1

          + diff --git a/components/markdown/src/snapshots/markdown__markdown__tests__reordered_footnotes.snap b/components/markdown/src/snapshots/markdown__markdown__tests__reordered_footnotes.snap index 865a344e5c..490f53ad03 100644 --- a/components/markdown/src/snapshots/markdown__markdown__tests__reordered_footnotes.snap +++ b/components/markdown/src/snapshots/markdown__markdown__tests__reordered_footnotes.snap @@ -2,8 +2,9 @@ source: components/markdown/src/markdown.rs expression: html --- -

          This text has two[1] footnotes[2]

          -
            +

            This text has two1 footnotes2

            +
            +
            1. But they are

            2. @@ -11,3 +12,4 @@ expression: html

              not sorted.

            +
            diff --git a/components/markdown/src/snapshots/markdown__markdown__tests__single_footnote.snap b/components/markdown/src/snapshots/markdown__markdown__tests__single_footnote.snap index 34a7f2d3e6..98761285a5 100644 --- a/components/markdown/src/snapshots/markdown__markdown__tests__single_footnote.snap +++ b/components/markdown/src/snapshots/markdown__markdown__tests__single_footnote.snap @@ -2,9 +2,11 @@ source: components/markdown/src/markdown.rs expression: html --- -

            This text has a footnote[1]

            -
              +

              This text has a footnote1

              +
              +
              1. But it is meaningless.

              +
              diff --git a/components/markdown/tests/common.rs b/components/markdown/tests/common.rs index aaef9784cc..6cf6198f97 100644 --- a/components/markdown/tests/common.rs +++ b/components/markdown/tests/common.rs @@ -41,6 +41,8 @@ fn configurable_render( .unwrap(); tera.add_raw_template("shortcodes/a.html", "

              a: {{ nth }}

              ").unwrap(); tera.add_raw_template("shortcodes/b.html", "

              b: {{ nth }}

              ").unwrap(); + tera.add_raw_template("shortcodes/a_md.md", "**a: {{ nth }}**").unwrap(); + tera.add_raw_template("shortcodes/b_md.md", "**b: {{ nth }}**").unwrap(); tera.add_raw_template("shortcodes/quote.html", "{{body}}").unwrap(); tera.add_raw_template("shortcodes/pre.html", "
              {{body}}
              ").unwrap(); tera.add_raw_template("shortcodes/four_spaces.html", " no highlight\n or there").unwrap(); @@ -51,6 +53,7 @@ fn configurable_render( ) .unwrap(); tera.add_raw_template("shortcodes/md_passthrough.md", "{{body}}").unwrap(); + tera.add_raw_template("shortcodes/nth.html", "{{ nth }}").unwrap(); let mut permalinks = HashMap::new(); permalinks.insert("pages/about.md".to_owned(), "https://getzola.org/about/".to_owned()); diff --git a/components/markdown/tests/markdown.rs b/components/markdown/tests/markdown.rs index e8cdcd42c2..6797b8e6f6 100644 --- a/components/markdown/tests/markdown.rs +++ b/components/markdown/tests/markdown.rs @@ -125,6 +125,25 @@ fn can_customise_anchor_template() { insta::assert_snapshot!(body); } +#[test] +fn can_customise_summary_template() { + let mut tera = Tera::default(); + tera.extend(&ZOLA_TERA).unwrap(); + tera.add_raw_template("summary-cutoff.html", " (in {{ lang }})").unwrap(); + let permalinks_ctx = HashMap::new(); + let config = Config::default_for_test(); + let context = RenderContext::new( + &tera, + &config, + &config.default_language, + "", + &permalinks_ctx, + InsertAnchor::Right, + ); + let summary = render_content("Hello World!", &context).unwrap().summary.unwrap(); + insta::assert_snapshot!(summary); +} + #[test] fn can_use_smart_punctuation() { let mut config = Config::default_for_test(); @@ -133,37 +152,75 @@ fn can_use_smart_punctuation() { insta::assert_snapshot!(body); } +#[test] +fn can_use_definition_list() { + let mut config = Config::default_for_test(); + config.markdown.definition_list = true; + let content = r#" +term +: definition + "#; + let body = common::render_with_config(content, config).unwrap().body; + insta::assert_snapshot!(body); +} + +#[test] +fn can_use_external_links_class() { + let mut config = Config::default_for_test(); + + // external link class only + config.markdown.external_links_class = Some("external".to_string()); + let body = common::render_with_config("", config.clone()).unwrap().body; + insta::assert_snapshot!("external_link_class", body); + + // internal link (should not add class) + let body = + common::render_with_config("[about](@/pages/about.md)", config.clone()).unwrap().body; + insta::assert_snapshot!("internal_link_no_class", body); + + // reset class, set target blank only + config.markdown.external_links_class = None; + config.markdown.external_links_target_blank = true; + let body = common::render_with_config("", config.clone()).unwrap().body; + insta::assert_snapshot!("external_link_target_blank", body); + + // both class and target blank + config.markdown.external_links_class = Some("external".to_string()); + let body = common::render_with_config("", config).unwrap().body; + insta::assert_snapshot!("external_link_class_and_target_blank", body); +} + #[test] fn can_use_external_links_options() { let mut config = Config::default_for_test(); // no options let body = common::render("").unwrap().body; - insta::assert_snapshot!(body); + insta::assert_snapshot!("external_link_no_options", body); // target blank config.markdown.external_links_target_blank = true; let body = common::render_with_config("", config.clone()).unwrap().body; - insta::assert_snapshot!(body); + insta::assert_snapshot!("external_link_target_blank", body); // no follow config.markdown.external_links_target_blank = false; config.markdown.external_links_no_follow = true; let body = common::render_with_config("", config.clone()).unwrap().body; - insta::assert_snapshot!(body); + insta::assert_snapshot!("external_link_no_follow", body); // no referrer config.markdown.external_links_no_follow = false; config.markdown.external_links_no_referrer = true; let body = common::render_with_config("", config.clone()).unwrap().body; - insta::assert_snapshot!(body); + insta::assert_snapshot!("external_link_no_referrer", body); // all of them config.markdown.external_links_no_follow = true; config.markdown.external_links_target_blank = true; config.markdown.external_links_no_referrer = true; let body = common::render_with_config("", config).unwrap().body; - insta::assert_snapshot!(body); + insta::assert_snapshot!("external_link_all_options", body); } #[test] diff --git a/components/markdown/tests/shortcodes.rs b/components/markdown/tests/shortcodes.rs index 5b63811bc1..6da64d64c1 100644 --- a/components/markdown/tests/shortcodes.rs +++ b/components/markdown/tests/shortcodes.rs @@ -323,3 +323,77 @@ Here is {{ ex1(page="") }} example. .body; insta::assert_snapshot!(body); } + +#[test] +fn can_render_markdown_in_nested_shortcodes_with_bodies() { + let config = Config::default_for_test(); + let body = common::render_with_config( + r#" +# Begin level 0 + +{% render_md() %} + +## Begin level 1 + +{% render_md() %} + +### Begin level 2 + +{{ a_md() }}, {{ a_md() }}, {{ b_md() }}, {{ b_md() }} + +### End level 2 + +{% end %} + +## End level 1 + +{% end %} + +# End level 0 + "#, + config, + ) + .unwrap() + .body; + insta::assert_snapshot!(body); +} + +#[test] +fn can_render_nested_shortcodes_with_bodies_with_nth() { + let config = Config::default_for_test(); + let body = common::render_with_config( + r#" +{{ a_md() }} + +{{ a_md() }} + +{% render_md() %} + +{{ a_md() }} + +{{ a_md() }} + +{% render_md() %} + +{{ a_md() }} + +{{ a_md() }} + +{% end %} + +{{ a_md() }} + +{{ a_md() }} + +{% end %} + +{{ a_md() }} + +{{ a_md() }} + "#, + config, + ) + .unwrap() + .body; + insta::assert_snapshot!(body); +} diff --git a/components/markdown/tests/snapshots/markdown__can_customise_summary_template.snap b/components/markdown/tests/snapshots/markdown__can_customise_summary_template.snap new file mode 100644 index 0000000000..491852d4a4 --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__can_customise_summary_template.snap @@ -0,0 +1,5 @@ +--- +source: components/markdown/tests/markdown.rs +expression: summary +--- +

              Hello (in en)

              diff --git a/components/markdown/tests/snapshots/markdown__can_use_definition_list.snap b/components/markdown/tests/snapshots/markdown__can_use_definition_list.snap new file mode 100644 index 0000000000..eaa5c1e7e5 --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__can_use_definition_list.snap @@ -0,0 +1,8 @@ +--- +source: components/markdown/tests/markdown.rs +expression: body +--- +
              +
              term
              +
              definition
              +
              diff --git a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-5.snap b/components/markdown/tests/snapshots/markdown__external_link_all_options.snap similarity index 66% rename from components/markdown/tests/snapshots/markdown__can_use_external_links_options-5.snap rename to components/markdown/tests/snapshots/markdown__external_link_all_options.snap index 40edd8ddb2..0949ee0ea1 100644 --- a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-5.snap +++ b/components/markdown/tests/snapshots/markdown__external_link_all_options.snap @@ -1,8 +1,6 @@ --- -source: components/rendering/tests/markdown.rs -assertion_line: 168 +source: components/markdown/tests/markdown.rs expression: body - +snapshot_kind: text ---

              https://google.com

              - diff --git a/components/markdown/tests/snapshots/markdown__external_link_class.snap b/components/markdown/tests/snapshots/markdown__external_link_class.snap new file mode 100644 index 0000000000..ab22c3f7f7 --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__external_link_class.snap @@ -0,0 +1,6 @@ +--- +source: components/markdown/tests/markdown.rs +expression: body +snapshot_kind: text +--- +

              https://google.com

              diff --git a/components/markdown/tests/snapshots/markdown__external_link_class_and_target_blank.snap b/components/markdown/tests/snapshots/markdown__external_link_class_and_target_blank.snap new file mode 100644 index 0000000000..da6b5de88e --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__external_link_class_and_target_blank.snap @@ -0,0 +1,6 @@ +--- +source: components/markdown/tests/markdown.rs +expression: body +snapshot_kind: text +--- +

              https://google.com

              diff --git a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-3.snap b/components/markdown/tests/snapshots/markdown__external_link_no_follow.snap similarity index 58% rename from components/markdown/tests/snapshots/markdown__can_use_external_links_options-3.snap rename to components/markdown/tests/snapshots/markdown__external_link_no_follow.snap index 27a53f5693..ce7424825c 100644 --- a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-3.snap +++ b/components/markdown/tests/snapshots/markdown__external_link_no_follow.snap @@ -1,8 +1,6 @@ --- -source: components/rendering/tests/markdown.rs -assertion_line: 155 +source: components/markdown/tests/markdown.rs expression: body - +snapshot_kind: text ---

              https://google.com

              - diff --git a/components/markdown/tests/snapshots/markdown__can_use_external_links_options.snap b/components/markdown/tests/snapshots/markdown__external_link_no_options.snap similarity index 54% rename from components/markdown/tests/snapshots/markdown__can_use_external_links_options.snap rename to components/markdown/tests/snapshots/markdown__external_link_no_options.snap index 4f539aa00b..b184b12c36 100644 --- a/components/markdown/tests/snapshots/markdown__can_use_external_links_options.snap +++ b/components/markdown/tests/snapshots/markdown__external_link_no_options.snap @@ -1,8 +1,6 @@ --- -source: components/rendering/tests/markdown.rs -assertion_line: 144 +source: components/markdown/tests/markdown.rs expression: body - +snapshot_kind: text ---

              https://google.com

              - diff --git a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-4.snap b/components/markdown/tests/snapshots/markdown__external_link_no_referrer.snap similarity index 59% rename from components/markdown/tests/snapshots/markdown__can_use_external_links_options-4.snap rename to components/markdown/tests/snapshots/markdown__external_link_no_referrer.snap index ef73ab0bce..78e9bfbab0 100644 --- a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-4.snap +++ b/components/markdown/tests/snapshots/markdown__external_link_no_referrer.snap @@ -1,8 +1,6 @@ --- -source: components/rendering/tests/markdown.rs -assertion_line: 161 +source: components/markdown/tests/markdown.rs expression: body - +snapshot_kind: text ---

              https://google.com

              - diff --git a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-2.snap b/components/markdown/tests/snapshots/markdown__external_link_target_blank.snap similarity index 62% rename from components/markdown/tests/snapshots/markdown__can_use_external_links_options-2.snap rename to components/markdown/tests/snapshots/markdown__external_link_target_blank.snap index ae1b79e732..16af5ca410 100644 --- a/components/markdown/tests/snapshots/markdown__can_use_external_links_options-2.snap +++ b/components/markdown/tests/snapshots/markdown__external_link_target_blank.snap @@ -1,8 +1,6 @@ --- -source: components/rendering/tests/markdown.rs -assertion_line: 149 +source: components/markdown/tests/markdown.rs expression: body - +snapshot_kind: text ---

              https://google.com

              - diff --git a/components/markdown/tests/snapshots/markdown__github_style_footnotes.snap b/components/markdown/tests/snapshots/markdown__github_style_footnotes.snap index de55e63fb7..56cf3e2944 100644 --- a/components/markdown/tests/snapshots/markdown__github_style_footnotes.snap +++ b/components/markdown/tests/snapshots/markdown__github_style_footnotes.snap @@ -2,13 +2,14 @@ source: components/markdown/tests/markdown.rs expression: body --- -

              This text has a footnote[1]

              -

              This text has two[2] footnotes[3].

              -

              There is footnote definition?[4]

              -

              This text has two[5] identical footnotes[5]

              -

              This text has a footnote[6]

              -

              Footnotes can also be referenced with identifiers[8].

              -
                +

                This text has a footnote1

                +

                This text has two2 footnotes3.

                +

                There is footnote definition?4

                +

                This text has two5 identical footnotes5

                +

                This text has a footnote6

                +

                Footnotes can also be referenced with identifiers8.

                +
                +
                1. But it is meaningless.

                2. @@ -25,7 +26,7 @@ expression: body

                  So one is present. ↩2

                3. -

                  But the footnote has another footnote[7].

                  +

                  But the footnote has another footnote7.

                4. That's it.

                  @@ -34,3 +35,4 @@ expression: body

                  Like this: [^first].

                +
                diff --git a/components/markdown/tests/snapshots/markdown__internal_link_no_class.snap b/components/markdown/tests/snapshots/markdown__internal_link_no_class.snap new file mode 100644 index 0000000000..1d1e334d58 --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__internal_link_no_class.snap @@ -0,0 +1,6 @@ +--- +source: components/markdown/tests/markdown.rs +expression: body +snapshot_kind: text +--- +

                about

                diff --git a/components/markdown/tests/snapshots/markdown__internal_link_without_class.snap.new b/components/markdown/tests/snapshots/markdown__internal_link_without_class.snap.new new file mode 100644 index 0000000000..02f5f43eaa --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__internal_link_without_class.snap.new @@ -0,0 +1,6 @@ +--- +source: components/markdown/tests/markdown.rs +assertion_line: 148 +expression: body +--- +

                about

                diff --git a/components/markdown/tests/snapshots/shortcodes__can_render_markdown_in_nested_shortcodes_with_bodies.snap b/components/markdown/tests/snapshots/shortcodes__can_render_markdown_in_nested_shortcodes_with_bodies.snap new file mode 100644 index 0000000000..0bc32408e9 --- /dev/null +++ b/components/markdown/tests/snapshots/shortcodes__can_render_markdown_in_nested_shortcodes_with_bodies.snap @@ -0,0 +1,13 @@ +--- +source: components/markdown/tests/shortcodes.rs +assertion_line: 358 +expression: body +--- +

                Begin level 0

                +

                Begin level 1

                +

                Begin level 2

                +

                a: 1, a: 2, b: 1, b: 2

                +

                End level 2

                +
                +

                End level 1

                +

                End level 0

                diff --git a/components/markdown/tests/snapshots/shortcodes__can_render_nested_shortcodes_with_bodies_with_nth.snap b/components/markdown/tests/snapshots/shortcodes__can_render_nested_shortcodes_with_bodies_with_nth.snap new file mode 100644 index 0000000000..8d258a84df --- /dev/null +++ b/components/markdown/tests/snapshots/shortcodes__can_render_nested_shortcodes_with_bodies_with_nth.snap @@ -0,0 +1,17 @@ +--- +source: components/markdown/tests/shortcodes.rs +assertion_line: 398 +expression: body +--- +

                a: 1

                +

                a: 2

                +

                a: 3

                +

                a: 4

                +

                a: 5

                +

                a: 6

                +
                +

                a: 7

                +

                a: 8

                +
                +

                a: 9

                +

                a: 10

                diff --git a/components/markdown/tests/snapshots/summary__no_truncated_summary.snap b/components/markdown/tests/snapshots/summary__no_truncated_summary.snap deleted file mode 100644 index 70c632d63f..0000000000 --- a/components/markdown/tests/snapshots/summary__no_truncated_summary.snap +++ /dev/null @@ -1,10 +0,0 @@ ---- -source: components/markdown/tests/summary.rs -expression: rendered.body ---- -

                Things to do:

                -
                  -
                • Program something
                • -
                • Eat
                • -
                • Sleep
                • -
                diff --git a/components/markdown/tests/snapshots/summary__truncated_summary.snap b/components/markdown/tests/snapshots/summary__truncated_summary.snap new file mode 100644 index 0000000000..7f8574a483 --- /dev/null +++ b/components/markdown/tests/snapshots/summary__truncated_summary.snap @@ -0,0 +1,9 @@ +--- +source: components/markdown/tests/summary.rs +expression: body +--- +

                Things to do:

                +
                  +
                • Program… +
                • +
                diff --git a/components/markdown/tests/summary.rs b/components/markdown/tests/summary.rs index 39dae40996..95eca3a5b9 100644 --- a/components/markdown/tests/summary.rs +++ b/components/markdown/tests/summary.rs @@ -22,7 +22,7 @@ Hello world! And some content after - "#, + "#, ); insta::assert_snapshot!(body); } @@ -48,8 +48,8 @@ And some content after } #[test] -fn no_truncated_summary() { - let rendered = get_rendered( +fn truncated_summary() { + let body = get_summary( r#" Things to do: * Program something @@ -57,8 +57,7 @@ Things to do: * Sleep "#, ); - assert!(rendered.summary.is_none()); - insta::assert_snapshot!(rendered.body); + insta::assert_snapshot!(body); } #[test] diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index cd48c219e4..60c982ee37 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -38,6 +38,8 @@ pub enum BuildMode { Disk, /// In memory for the content -> `zola serve` Memory, + /// Both on the filesystem and in memory + Both, } #[derive(Debug)] @@ -65,6 +67,8 @@ pub struct Site { include_drafts: bool, build_mode: BuildMode, shortcode_definitions: HashMap, + /// Whether to check external links + check_external_links: bool, } impl Site { @@ -108,16 +112,17 @@ impl Site { library: Arc::new(RwLock::new(Library::default())), build_mode: BuildMode::Disk, shortcode_definitions, + check_external_links: true, }; Ok(site) } /// Enable some `zola serve` related options - pub fn enable_serve_mode(&mut self) { + pub fn enable_serve_mode(&mut self, build_mode: BuildMode) { SITE_CONTENT.write().unwrap().clear(); self.config.enable_serve_mode(); - self.build_mode = BuildMode::Memory; + self.build_mode = build_mode; } /// Set the site to load the drafts. @@ -126,6 +131,11 @@ impl Site { self.include_drafts = true; } + /// Set the site checker to skip external links check. + pub fn skip_external_links_check(&mut self) { + self.check_external_links = false; + } + /// The index sections are ALWAYS at those paths /// There are one index section for the default language + 1 per language fn index_section_paths(&self) -> Vec<(PathBuf, Option<&str>)> { @@ -344,7 +354,7 @@ impl Site { } // check external links, log the results, and error out if needed - if self.config.is_in_check_mode() { + if self.config.is_in_check_mode() && self.check_external_links { let external_link_messages = link_checking::check_external_links(self); if !external_link_messages.is_empty() { let messages: Vec = external_link_messages @@ -660,16 +670,20 @@ impl Site { }; match self.build_mode { - BuildMode::Disk => { + BuildMode::Disk | BuildMode::Both => { let end_path = current_path.join(filename); create_file(&end_path, &final_content)?; } - BuildMode::Memory => { + _ => (), + } + match self.build_mode { + BuildMode::Memory | BuildMode::Both => { let site_path = if filename != "index.html" { site_path.join(filename) } else { site_path }; SITE_CONTENT.write().unwrap().insert(site_path, final_content); } + _ => (), } Ok(current_path) diff --git a/components/site/src/link_checking.rs b/components/site/src/link_checking.rs index aff8879b73..5af10c4917 100644 --- a/components/site/src/link_checking.rs +++ b/components/site/src/link_checking.rs @@ -282,7 +282,7 @@ pub fn check_external_links(site: &Site) -> Vec { for (page_path, link, check_res) in errors { messages.push(format!( - "Broken link in {} to {}: {}", + "Broken link in {} to {} : {}", page_path.to_string_lossy(), link, link_checker::message(&check_res) diff --git a/components/site/src/minify.rs b/components/site/src/minify.rs index 7c613299e9..3b0c348e5c 100644 --- a/components/site/src/minify.rs +++ b/components/site/src/minify.rs @@ -5,7 +5,7 @@ pub fn html(html: String) -> Result { let mut cfg = Cfg::spec_compliant(); cfg.keep_html_and_head_opening_tags = true; cfg.minify_css = true; - cfg.minify_js = true; + cfg.minify_js = false; let minified = minify(html.as_bytes(), &cfg); match std::str::from_utf8(&minified) { @@ -114,6 +114,8 @@ mod tests { } // https://github.com/getzola/zola/issues/1765 + // https://github.com/getzola/zola/issues/2731 + #[ignore] #[test] fn can_minify_js() { let input = r#" diff --git a/components/site/src/sitemap.rs b/components/site/src/sitemap.rs index 2d9960741b..d6c94ecd5a 100644 --- a/components/site/src/sitemap.rs +++ b/components/site/src/sitemap.rs @@ -83,10 +83,12 @@ pub fn find_entries<'a>( } if let Some(paginate_by) = s.paginate_by() { - let number_pagers = (s.pages.len() as f64 / paginate_by as f64).ceil() as isize; - for i in 1..=number_pagers { - let permalink = format!("{}{}/{}/", s.permalink, s.meta.paginate_path, i); - entries.insert(SitemapEntry::new(Cow::Owned(permalink), &None)); + if !config.should_exclude_paginated_pages_in_sitemap() { + let number_pagers = (s.pages.len() as f64 / paginate_by as f64).ceil() as isize; + for i in 1..=number_pagers { + let permalink = format!("{}{}/{}/", s.permalink, s.meta.paginate_path, i); + entries.insert(SitemapEntry::new(Cow::Owned(permalink), &None)); + } } } } @@ -100,7 +102,7 @@ pub fn find_entries<'a>( for item in &taxonomy.items { entries.insert(SitemapEntry::new(Cow::Borrowed(&item.permalink), &None)); - if taxonomy.kind.is_paginated() { + if taxonomy.kind.is_paginated() && !config.should_exclude_paginated_pages_in_sitemap() { let number_pagers = (item.pages.len() as f64 / taxonomy.kind.paginate_by.unwrap() as f64) .ceil() as isize; diff --git a/components/site/tests/site.rs b/components/site/tests/site.rs index bf0811e15a..f141583c05 100644 --- a/components/site/tests/site.rs +++ b/components/site/tests/site.rs @@ -851,6 +851,32 @@ fn panics_on_invalid_external_domain() { site.load().expect("link check test_site"); } +#[test] +fn external_links_ignored_on_check() { + let (mut site, _tmp_dir, _public) = build_site("test_site"); + + // remove the invalid domain skip prefix + let i = site + .config + .link_checker + .skip_prefixes + .iter() + .position(|prefix| prefix == "http://invaliddomain") + .unwrap(); + site.config.link_checker.skip_prefixes.remove(i); + + // confirm the invalid domain skip prefix was removed + assert_eq!(site.config.link_checker.skip_prefixes, vec!["http://[2001:db8::]/"]); + + // set a flag to skip external links check + site.skip_external_links_check(); + + // check the test site with all external links (including invalid domain) skipped, which should + // not cause a panic + site.config.enable_check_mode(); + site.load().expect("link check test_site"); +} + #[test] fn can_find_site_and_page_authors() { let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); diff --git a/components/templates/Cargo.toml b/components/templates/Cargo.toml index 147fed89b0..b25058da3e 100644 --- a/components/templates/Cargo.toml +++ b/components/templates/Cargo.toml @@ -14,5 +14,5 @@ libs = { path = "../libs" } [dev-dependencies] -mockito = "0.31" +mockito = "1.6" tempfile = "3" diff --git a/components/templates/src/builtins/summary-cutoff.html b/components/templates/src/builtins/summary-cutoff.html new file mode 100644 index 0000000000..41681d3d82 --- /dev/null +++ b/components/templates/src/builtins/summary-cutoff.html @@ -0,0 +1 @@ +… diff --git a/components/templates/src/global_fns/images.rs b/components/templates/src/global_fns/images.rs index 2ac74b0ebb..c4541b8221 100644 --- a/components/templates/src/global_fns/images.rs +++ b/components/templates/src/global_fns/images.rs @@ -26,8 +26,8 @@ impl ResizeImage { } } -static DEFAULT_OP: &str = "fill"; -static DEFAULT_FMT: &str = "auto"; +const DEFAULT_OP: &str = "fill"; +const DEFAULT_FMT: &str = "auto"; impl TeraFn for ResizeImage { fn call(&self, args: &HashMap) -> Result { diff --git a/components/templates/src/global_fns/load_data.rs b/components/templates/src/global_fns/load_data.rs index c719495f70..d848257cf2 100644 --- a/components/templates/src/global_fns/load_data.rs +++ b/components/templates/src/global_fns/load_data.rs @@ -18,7 +18,7 @@ use utils::fs::{get_file_time, read_file}; use crate::global_fns::helpers::search_for_file; -static GET_DATA_ARGUMENT_ERROR_MESSAGE: &str = +const GET_DATA_ARGUMENT_ERROR_MESSAGE: &str = "`load_data`: requires EITHER a `path`, `url`, or `literal` argument"; #[derive(Debug, PartialEq, Clone, Copy, Hash)] @@ -579,7 +579,6 @@ mod tests { use crate::global_fns::load_data::Method; use libs::serde_json::json; use libs::tera::{self, to_value, Function}; - use mockito::mock; use std::fs::{copy, create_dir_all}; use tempfile::tempdir; @@ -610,17 +609,20 @@ mod tests { #[test] fn can_load_remote_data_using_post_method() { - let _mg = mock("GET", "/kr1zdgbm4y") + let mut server = mockito::Server::new(); + let _mg = server + .mock("GET", "/kr1zdgbm4y") .with_header("content-type", "text/plain") .with_body("GET response") .expect(0) .create(); - let _mp = mock("POST", "/kr1zdgbm4y") + let _mp = server + .mock("POST", "/kr1zdgbm4y") .with_header("content-type", "text/plain") .with_body("POST response") .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -636,19 +638,22 @@ mod tests { #[test] fn can_load_remote_data_using_post_method_with_content_type_header() { - let _mjson = mock("POST", "/kr1zdgbm4yw") + let mut server = mockito::Server::new(); + let _mjson = server + .mock("POST", "/kr1zdgbm4yw") .match_header("content-type", "application/json") .with_header("content-type", "application/json") .with_body("{i_am:'json'}") .expect(0) .create(); - let _mtext = mock("POST", "/kr1zdgbm4yw") + let _mtext = server + .mock("POST", "/kr1zdgbm4yw") .match_header("content-type", "text/plain") .with_header("content-type", "text/plain") .with_body("POST response text") .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4yw"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4yw"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -665,19 +670,22 @@ mod tests { #[test] fn can_load_remote_data_using_post_method_with_body() { - let _mjson = mock("POST", "/kr1zdgbm4y") + let mut server = mockito::Server::new(); + let _mjson = server + .mock("POST", "/kr1zdgbm4y") .match_body("qwerty") .with_header("content-type", "application/json") .with_body("{i_am:'json'}") .expect(0) .create(); - let _mtext = mock("POST", "/kr1zdgbm4y") + let _mtext = server + .mock("POST", "/kr1zdgbm4y") .match_body("this is a match") .with_header("content-type", "text/plain") .with_body("POST response text") .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -840,7 +848,9 @@ mod tests { #[test] fn can_load_remote_data() { - let _m = mock("GET", "/zpydpkjj67") + let mut server = mockito::Server::new(); + let _m = server + .mock("GET", "/zpydpkjj67") .with_header("content-type", "application/json") .with_body( r#"{ @@ -852,7 +862,7 @@ mod tests { ) .create(); - let url = format!("{}{}", mockito::server_url(), "/zpydpkjj67"); + let url = format!("{}{}", server.url(), "/zpydpkjj67"); let static_fn = LoadData::new(PathBuf::new(), None, PathBuf::new()); let mut args = HashMap::new(); args.insert("url".to_string(), to_value(&url).unwrap()); @@ -863,13 +873,15 @@ mod tests { #[test] fn fails_when_request_404s() { - let _m = mock("GET", "/aazeow0kog") + let mut server = mockito::Server::new(); + let _m = server + .mock("GET", "/aazeow0kog") .with_status(404) .with_header("content-type", "text/plain") .with_body("Not Found") .create(); - let url = format!("{}{}", mockito::server_url(), "/aazeow0kog"); + let url = format!("{}{}", server.url(), "/aazeow0kog"); let static_fn = LoadData::new(PathBuf::new(), None, PathBuf::new()); let mut args = HashMap::new(); args.insert("url".to_string(), to_value(&url).unwrap()); @@ -884,13 +896,15 @@ mod tests { #[test] fn doesnt_fail_when_request_404s_is_not_required() { - let _m = mock("GET", "/aazeow0kog") + let mut server = mockito::Server::new(); + let _m = server + .mock("GET", "/aazeow0kog") .with_status(404) .with_header("content-type", "text/plain") .with_body("Not Found") .create(); - let url = format!("{}{}", mockito::server_url(), "/aazeow0kog"); + let url = format!("{}{}", server.url(), "/aazeow0kog"); let static_fn = LoadData::new(PathBuf::new(), None, PathBuf::new()); let mut args = HashMap::new(); args.insert("url".to_string(), to_value(&url).unwrap()); @@ -903,8 +917,10 @@ mod tests { #[test] fn set_default_user_agent() { + let mut server = mockito::Server::new(); let user_agent = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); - let _m = mock("GET", "/chu8aizahBiy") + let _m = server + .mock("GET", "/chu8aizahBiy") .match_header("User-Agent", user_agent) .with_header("content-type", "application/json") .with_body( @@ -917,7 +933,7 @@ mod tests { ) .create(); - let url = format!("{}{}", mockito::server_url(), "/chu8aizahBiy"); + let url = format!("{}{}", server.url(), "/chu8aizahBiy"); let static_fn = LoadData::new(PathBuf::new(), None, PathBuf::new()); let mut args = HashMap::new(); args.insert("url".to_string(), to_value(&url).unwrap()); @@ -1116,12 +1132,14 @@ mod tests { #[test] fn is_load_remote_data_using_post_method_with_different_body_not_cached() { - let _mjson = mock("POST", "/kr1zdgbm4y3") + let mut server = mockito::Server::new(); + let _mjson = server + .mock("POST", "/kr1zdgbm4y3") .with_header("content-type", "application/json") .with_body("{i_am:'json'}") .expect(2) .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y3"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y3"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -1147,13 +1165,15 @@ mod tests { #[test] fn is_load_remote_data_using_post_method_with_same_body_cached() { - let _mjson = mock("POST", "/kr1zdgbm4y2") + let mut server = mockito::Server::new(); + let _mjson = server + .mock("POST", "/kr1zdgbm4y2") .match_body("this is a match") .with_header("content-type", "application/json") .with_body("{i_am:'json'}") .expect(1) .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y2"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y2"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -1179,14 +1199,16 @@ mod tests { #[test] fn is_custom_headers_working() { - let _mjson = mock("POST", "/kr1zdgbm4y4") + let mut server = mockito::Server::new(); + let _mjson = server + .mock("POST", "/kr1zdgbm4y4") .with_header("content-type", "application/json") .match_header("accept", "text/plain") .match_header("x-custom-header", "some-values") .with_body("{i_am:'json'}") .expect(1) .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y4"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y4"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -1204,7 +1226,8 @@ mod tests { #[test] fn is_custom_headers_working_with_multiple_values() { - let _mjson = mock("POST", "/kr1zdgbm4y5") + let mut server = mockito::Server::new(); + let _mjson = server.mock("POST", "/kr1zdgbm4y5") .with_status(201) .with_header("content-type", "application/json") .match_header("authorization", "Bearer 123") @@ -1216,7 +1239,7 @@ mod tests { .with_body("I am a server that needs authentication and returns HTML with Accept set to JSON") .expect(1) .create(); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y5"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y5"); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); let mut args = HashMap::new(); @@ -1243,9 +1266,10 @@ mod tests { #[test] fn fails_when_specifying_invalid_headers() { - let _mjson = mock("GET", "/kr1zdgbm4y6").with_status(204).expect(0).create(); + let mut server = mockito::Server::new(); + let _mjson = server.mock("GET", "/kr1zdgbm4y6").with_status(204).expect(0).create(); let static_fn = LoadData::new(PathBuf::from("../utils"), None, PathBuf::new()); - let url = format!("{}{}", mockito::server_url(), "/kr1zdgbm4y6"); + let url = format!("{}{}", server.url(), "/kr1zdgbm4y6"); let mut args = HashMap::new(); args.insert("url".to_string(), to_value(&url).unwrap()); args.insert("format".to_string(), to_value("plain").unwrap()); diff --git a/components/templates/src/lib.rs b/components/templates/src/lib.rs index 59ab2abaf9..1053b4259d 100644 --- a/components/templates/src/lib.rs +++ b/components/templates/src/lib.rs @@ -23,6 +23,7 @@ pub static ZOLA_TERA: Lazy = Lazy::new(|| { include_str!("builtins/split_sitemap_index.xml"), ), ("__zola_builtins/anchor-link.html", include_str!("builtins/anchor-link.html")), + ("__zola_builtins/summary-cutoff.html", include_str!("builtins/summary-cutoff.html")), ("internal/alias.html", include_str!("builtins/internal/alias.html")), ]) .unwrap(); @@ -44,7 +45,7 @@ pub fn render_redirect_template(url: &str, tera: &Tera) -> Result { pub fn load_tera(path: &Path, config: &Config) -> Result { let tpl_glob = - format!("{}/{}", path.to_string_lossy().replace('\\', "/"), "templates/**/*.{*ml,md}"); + format!("{}/{}", path.to_string_lossy().replace('\\', "/"), "templates/**/*.{*ml,md,txt}"); // Only parsing as we might be extending templates from themes and that would error // as we haven't loaded them yet diff --git a/components/utils/src/templates.rs b/components/utils/src/templates.rs index b51206bac5..a6d54f0d58 100644 --- a/components/utils/src/templates.rs +++ b/components/utils/src/templates.rs @@ -4,7 +4,7 @@ use libs::tera::{Context, Tera}; use errors::{bail, Result}; -static DEFAULT_TPL: &str = include_str!("default_tpl.html"); +const DEFAULT_TPL: &str = include_str!("default_tpl.html"); macro_rules! render_default_tpl { ($filename: expr, $url: expr) => {{ @@ -34,6 +34,24 @@ impl ShortcodeDefinition { } } +#[derive(Debug, Default, Clone)] +pub struct ShortcodeInvocationCounter { + amounts: HashMap, +} +impl ShortcodeInvocationCounter { + pub fn new() -> Self { + Self::default() + } + pub fn get(&mut self, str: &str) -> usize { + let nth = self.amounts.entry(str.into()).or_insert(0); + *nth += 1; + return *nth; + } + pub fn reset(&mut self) { + self.amounts.clear(); + } +} + /// Fetches all the shortcodes from the Tera instances pub fn get_shortcodes(tera: &Tera) -> HashMap { let mut shortcode_definitions = HashMap::new(); diff --git a/docs/content/documentation/content/page.md b/docs/content/documentation/content/page.md index aed2de14b0..faff548a07 100644 --- a/docs/content/documentation/content/page.md +++ b/docs/content/documentation/content/page.md @@ -162,3 +162,13 @@ available separately in the A span element in this position with a `continue-reading` id is created, so you can link directly to it if needed. For example: `Continue Reading`. + +The `` marker can also exist in the middle of a line, and it will ensure that this does not emit unclosed HTML tags. +You can use the `summary-cutoff.html` to show text after the summary (but before these closing tags) based +upon the summary before the cutoff. + +By default, it will show an ellipsis (…) regardless of the content of the summary, but you can use a different template if you want to only show an ellipsis if the summary does not end in any punctuation: + +```jinja +{% if summary is matching("\PP$") %}…{% endif %} +``` diff --git a/docs/content/documentation/content/syntax-highlighting.md b/docs/content/documentation/content/syntax-highlighting.md index e84eb16539..da18fa4cf5 100644 --- a/docs/content/documentation/content/syntax-highlighting.md +++ b/docs/content/documentation/content/syntax-highlighting.md @@ -302,7 +302,7 @@ highlight(code); - `hide_lines` to hide lines. You must specify a list of inclusive ranges of lines to hide, separated by ` ` (whitespace). Ranges are 1-indexed. - + ```` ```rust,hide_lines=1-2 use highlighter::highlight; @@ -311,6 +311,16 @@ highlight(code); ``` ```` +- `name` to specify a name the code block is associated with. + +```` +```rust,name=mod.rs +use highlighter::highlight; +let code = "..."; +highlight(code); +``` +```` + ## Styling codeblocks Depending on the annotations used, some codeblocks will be hard to read without any CSS. We recommend using the following diff --git a/docs/content/documentation/getting-started/cli-usage.md b/docs/content/documentation/getting-started/cli-usage.md index b8d98637ae..9795b7f2fb 100644 --- a/docs/content/documentation/getting-started/cli-usage.md +++ b/docs/content/documentation/getting-started/cli-usage.md @@ -114,6 +114,8 @@ The check subcommand will try to build all pages just like the build command wou results to disk. Additionally, it will also check all external links in Markdown files by trying to fetch them (links in the template files are not checked). +You can skip link checking for all the external links by `--skip-external-links` flag. + By default, drafts are not loaded. If you wish to include them, pass the `--drafts` flag. ## Colored output diff --git a/docs/content/documentation/getting-started/configuration.md b/docs/content/documentation/getting-started/configuration.md index 2565e0913f..51c4ad63e0 100644 --- a/docs/content/documentation/getting-started/configuration.md +++ b/docs/content/documentation/getting-started/configuration.md @@ -67,6 +67,9 @@ ignored_static = [] # When set to "true", a feed is automatically generated. generate_feeds = false +# When set to "all", paginated pages are not a part of the sitemap, default is "none" +exclude_paginated_pages_in_sitemap = "none" + # The filenames to use for the feeds. Used as the template filenames, too. # Defaults to ["atom.xml"], which has a built-in template that renders an Atom 1.0 feed. # There is also a built-in template "rss.xml" that renders an RSS 2.0 feed. @@ -111,6 +114,9 @@ generate_robots_txt = true # When set to "true", all code blocks are highlighted. highlight_code = false +# When set to "true", missing highlight languages are treated as errors. Defaults to false. +error_on_missing_highlight = false + # A list of directories used to search for additional `.sublime-syntax` and `.tmTheme` files. extra_syntaxes_and_themes = [] @@ -122,6 +128,9 @@ highlight_theme = "base16-ocean-dark" # Unicode emoji equivalent in the rendered Markdown files. (e.g.: :smile: => 😄) render_emoji = false +# CSS class to add to external links (e.g. "external-link") +external_links_class = + # Whether external links are to be opened in a new tab # If this is true, a `rel="noopener"` will always automatically be added for security reasons external_links_target_blank = false @@ -136,6 +145,9 @@ external_links_no_referrer = false # For example, `...` into `…`, `"quote"` into `“curly”` etc smart_punctuation = false +# Whether parsing of definition lists is enabled +definition_list = false + # Whether to set decoding="async" and loading="lazy" for all images # When turned on, the alt text must be plain text. # For example, `![xx](...)` is ok but `![*x*x](...)` isn’t ok diff --git a/docs/content/documentation/templates/pages-sections.md b/docs/content/documentation/templates/pages-sections.md index 97f9559614..1061796f48 100644 --- a/docs/content/documentation/templates/pages-sections.md +++ b/docs/content/documentation/templates/pages-sections.md @@ -112,8 +112,16 @@ backlinks: Array<{permalink: String, title: String?}>; generate_feeds: bool; // Whether this section is transparent. Taken from the front-matter if set transparent: bool; +// How many items per pager (if defined) +paginate_by: Number?; +// If items order is reversed in the pagination (defaults to false) +paginate_reversed: bool; ``` +Information about pagination is useful when using the `get_section` Tera function for which the `paginator` is not available. + +See [pagination template documentation](@/documentation/templates/pagination.md) for more information on the `paginator` variable. + ## Table of contents Both page and section templates have a `toc` variable that corresponds to an array of `Header`. diff --git a/docs/content/documentation/templates/pagination.md b/docs/content/documentation/templates/pagination.md index e1851bdce4..ad4c956cca 100644 --- a/docs/content/documentation/templates/pagination.md +++ b/docs/content/documentation/templates/pagination.md @@ -52,6 +52,12 @@ A paginated taxonomy gets two variables aside from the `paginator` variable: See the [taxonomies page](@/documentation/templates/taxonomies.md) for a detailed version of the types. +## SEO + +It is preferable to not include paginated pages in sitemap since they are non-canonical pages. +To exclude paginated pages in sitemap, set the +`exclude_paginated_pages_in_sitemap` as `all` in `config.toml`. + ## Example Here is an example from a theme on how to use pagination on a page (`index.html` in this case): diff --git a/docs/content/documentation/templates/robots.md b/docs/content/documentation/templates/robots.md index c93ff73bbb..98cb4374a8 100644 --- a/docs/content/documentation/templates/robots.md +++ b/docs/content/documentation/templates/robots.md @@ -15,3 +15,14 @@ Disallow: Allow: / Sitemap: {{/* get_url(path="sitemap.xml") */}} ``` + +The file can be extended & expanded like other templates using e.g. Tera's `include` tag: + +```jinja2 +User-agent: * +Disallow: +Allow: / +Sitemap: {{/* get_url(path="sitemap.xml") */}} + +{% include "path/to/other/robots.txt" %} +``` diff --git a/src/cli.rs b/src/cli.rs index 1329edff4d..a7d3ce7d33 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -82,6 +82,10 @@ pub enum Command { #[clap(short = 'O', long)] open: bool, + /// Also store HTML in the public/ folder (by default HTML is only stored in-memory) + #[clap(long)] + store_html: bool, + /// Only rebuild the minimum on change - useful when working on a specific page/section #[clap(short = 'f', long)] fast: bool, @@ -89,6 +93,10 @@ pub enum Command { /// Default append port to the base url. #[clap(long)] no_port_append: bool, + + /// Extra path to watch for changes, relative to the project root. + #[clap(long)] + extra_watch_path: Vec, }, /// Try to build the project without rendering it. Checks links @@ -96,6 +104,9 @@ pub enum Command { /// Include drafts when loading the site #[clap(long)] drafts: bool, + /// Skip external links + #[clap(long)] + skip_external_links: bool, }, /// Generate shell completion diff --git a/src/cmd/check.rs b/src/cmd/check.rs index 46522deab9..2a021ce46a 100644 --- a/src/cmd/check.rs +++ b/src/cmd/check.rs @@ -11,6 +11,7 @@ pub fn check( base_path: Option<&str>, base_url: Option<&str>, include_drafts: bool, + skip_external_links: bool, ) -> Result<()> { let bp = base_path.map(PathBuf::from).unwrap_or_else(|| PathBuf::from(root_dir)); let mut site = Site::new(bp, config_file)?; @@ -22,6 +23,9 @@ pub fn check( if include_drafts { site.include_drafts(); } + if skip_external_links { + site.skip_external_links_check(); + } site.load()?; messages::check_site_summary(&site); messages::warn_about_ignored_pages(&site); diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index eb2b75dd26..d4285e3fee 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -42,12 +42,12 @@ use time::{OffsetDateTime, UtcOffset}; use libs::percent_encoding; use libs::relative_path::{RelativePath, RelativePathBuf}; use libs::serde_json; -use notify_debouncer_full::{new_debouncer, notify::RecursiveMode, notify::Watcher}; +use notify_debouncer_full::{new_debouncer, notify::RecursiveMode}; use ws::{Message, Sender, WebSocket}; use errors::{anyhow, Context, Error, Result}; use site::sass::compile_sass; -use site::{Site, SITE_CONTENT}; +use site::{BuildMode, Site, SITE_CONTENT}; use utils::fs::{clean_site_output_folder, copy_file, create_directory}; use crate::fs_utils::{filter_events, ChangeKind, SimpleFileSystemEventKind}; @@ -61,8 +61,8 @@ enum WatchMode { Condition(bool), } -static METHOD_NOT_ALLOWED_TEXT: &[u8] = b"Method Not Allowed"; -static NOT_FOUND_TEXT: &[u8] = b"Not Found"; +const METHOD_NOT_ALLOWED_TEXT: &[u8] = b"Method Not Allowed"; +const NOT_FOUND_TEXT: &[u8] = b"Not Found"; // This is dist/livereload.min.js from the LiveReload.js v3.2.4 release const LIVE_RELOAD: &str = include_str!("livereload.js"); @@ -367,6 +367,7 @@ fn create_new_site( base_url: Option<&str>, config_file: &Path, include_drafts: bool, + store_html: bool, mut no_port_append: bool, ws_port: Option, ) -> Result<(Site, SocketAddr, String)> { @@ -390,7 +391,7 @@ fn create_new_site( constructed_base_url.truncate(constructed_base_url.len() - 1); } - site.enable_serve_mode(); + site.enable_serve_mode(if store_html { BuildMode::Both } else { BuildMode::Memory }); site.set_base_url(constructed_base_url.clone()); if let Some(output_dir) = output_dir { if !force && output_dir.exists() { @@ -427,9 +428,11 @@ pub fn serve( config_file: &Path, open: bool, include_drafts: bool, + store_html: bool, fast_rebuild: bool, no_port_append: bool, utc_offset: UtcOffset, + extra_watch_paths: Vec, ) -> Result<()> { let start = Instant::now(); let (mut site, bind_address, constructed_base_url) = create_new_site( @@ -441,6 +444,7 @@ pub fn serve( base_url, config_file, include_drafts, + store_html, no_port_append, None, )?; @@ -462,8 +466,8 @@ pub fn serve( // An array of (path, WatchMode, RecursiveMode) where the path is watched for changes, // the WatchMode value indicates whether this path must exist for zola serve to operate, // and the RecursiveMode value indicates whether to watch nested directories. - let watch_this = vec![ - // The first entry is ultimtely to watch config.toml in a more robust manner on Linux when + let mut watch_this = vec![ + // The first entry is ultimately to watch config.toml in a more robust manner on Linux when // the file changes by way of a caching strategy used by editors such as vim. // https://github.com/getzola/zola/issues/2266 (root_dir_str, WatchMode::Required, RecursiveMode::NonRecursive), @@ -473,6 +477,11 @@ pub fn serve( ("templates", WatchMode::Optional, RecursiveMode::Recursive), ("themes", WatchMode::Condition(site.config.theme.is_some()), RecursiveMode::Recursive), ]; + watch_this.extend( + extra_watch_paths + .iter() + .map(|path| (path.as_str(), WatchMode::Required, RecursiveMode::Recursive)), + ); // Setup watchers let (tx, rx) = channel(); @@ -492,7 +501,7 @@ pub fn serve( WatchMode::Condition(b) => b && watch_path.exists(), }; if should_watch { - debouncer.watcher() + debouncer .watch(&root_dir.join(entry), recursive_mode) .with_context(|| format!("Can't watch `{}` for changes in folder `{}`. Does it exist, and do you have correct permissions?", entry, root_dir.display()))?; watchers.push(entry.to_string()); @@ -666,6 +675,7 @@ pub fn serve( base_url, config_file, include_drafts, + store_html, no_port_append, ws_port, ) { @@ -810,6 +820,23 @@ pub fn serve( site = s; } } + ChangeKind::ExtraPath => { + let full_paths: Vec<&PathBuf> = + change_group.iter().map(|(_, p, _)| p).collect(); + let combined_paths = full_paths + .iter() + .map(|p| p.display().to_string()) + .collect::>() + .join(", "); + console::info(&format!( + "-> {combined_paths} changed. Recreating whole site." + )); + + // We can't know exactly what to update when a user provides the path. + if let Some(s) = recreate_site() { + site = s; + } + } }; messages::report_elapsed_time(start); } @@ -893,6 +920,7 @@ mod tests { base_url.as_deref(), &config_file, include_drafts, + false, no_port_append, ws_port, ) diff --git a/src/fs_utils.rs b/src/fs_utils.rs index 9cd3da8a75..421380a226 100644 --- a/src/fs_utils.rs +++ b/src/fs_utils.rs @@ -17,6 +17,8 @@ pub enum ChangeKind { StaticFiles, Sass, Config, + /// A change in one of the extra paths to watch provided by the user. + ExtraPath, } /// This enum abstracts over the fine-grained group of enums in `notify`. @@ -35,6 +37,10 @@ pub type MeaningfulEvent = (PathBuf, PathBuf, SimpleFileSystemEventKind); /// return `None`. fn get_relevant_event_kind(event_kind: &EventKind) -> Option { match event_kind { + // Nova on macOS reports this as it's final event on change + EventKind::Modify(ModifyKind::Name(RenameMode::Any)) => { + Some(SimpleFileSystemEventKind::Modify) + } EventKind::Create(CreateKind::File) | EventKind::Create(CreateKind::Folder) => { Some(SimpleFileSystemEventKind::Create) } @@ -156,7 +162,7 @@ fn detect_change_kind(pwd: &Path, path: &Path, config_path: &Path) -> (ChangeKin } else if path == config_path { ChangeKind::Config } else { - unreachable!("Got a change in an unexpected path: {}", partial_path.display()); + ChangeKind::ExtraPath }; (change_kind, partial_path) diff --git a/src/main.rs b/src/main.rs index 4e96a73253..ec520fed41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -84,8 +84,10 @@ fn main() { base_url, drafts, open, + store_html, fast, no_port_append, + extra_watch_path, } => { if port != 1111 && !port_is_available(port) { console::error("The requested port is not available"); @@ -111,19 +113,21 @@ fn main() { &config_file, open, drafts, + store_html, fast, no_port_append, UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC), + extra_watch_path, ) { messages::unravel_errors("Failed to serve the site", &e); std::process::exit(1); } } - Command::Check { drafts } => { + Command::Check { drafts, skip_external_links } => { console::info("Checking site..."); let start = Instant::now(); let (root_dir, config_file) = get_config_file_path(&cli_dir, &cli.config); - match cmd::check(&root_dir, &config_file, None, None, drafts) { + match cmd::check(&root_dir, &config_file, None, None, drafts, skip_external_links) { Ok(()) => messages::report_elapsed_time(start), Err(e) => { messages::unravel_errors("Failed to check the site", &e);