├── .formatter.exs ├── .github └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── Makefile.win ├── README.md ├── RELEASE.md ├── c_src └── lazy_html.cpp ├── config └── config.exs ├── lib ├── lazy_html.ex └── lazy_html │ ├── nif.ex │ └── tree.ex ├── mix.exs ├── mix.lock └── test ├── lazy_html └── tree_test.exs ├── lazy_html_test.exs └── test_helper.exs /.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: 5 | - "v*.*.*" 6 | permissions: 7 | contents: write 8 | jobs: 9 | linux: 10 | runs-on: ubuntu-22.04 11 | env: 12 | MIX_ENV: prod 13 | ELIXIR_VERSION: "1.15.3" 14 | strategy: 15 | matrix: 16 | otp_version: ["25.3"] 17 | name: Linux x86_64 (${{ matrix.otp_version }}) 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: erlef/setup-beam@v1 21 | with: 22 | otp-version: ${{ matrix.otp_version }} 23 | elixir-version: ${{ env.ELIXIR_VERSION }} 24 | - name: Install system dependencies 25 | run: | 26 | sudo apt-get update 27 | sudo apt-get install -y build-essential automake autoconf pkg-config bc m4 unzip zip \ 28 | gcc g++ \ 29 | gcc-i686-linux-gnu g++-i686-linux-gnu \ 30 | gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ 31 | gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf \ 32 | gcc-riscv64-linux-gnu g++-riscv64-linux-gnu \ 33 | gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu \ 34 | gcc-s390x-linux-gnu g++-s390x-linux-gnu 35 | - name: Precompile 36 | run: | 37 | export ELIXIR_MAKE_CACHE_DIR=$(pwd)/cache 38 | mkdir -p "${ELIXIR_MAKE_CACHE_DIR}" 39 | mix deps.get 40 | mix elixir_make.precompile 41 | - uses: softprops/action-gh-release@v2 42 | if: startsWith(github.ref, 'refs/tags/') 43 | with: 44 | draft: true 45 | files: | 46 | cache/*.tar.gz 47 | cache/*.sha256 48 | 49 | macos: 50 | runs-on: macos-13 51 | env: 52 | MIX_ENV: prod 53 | ELIXIR_VERSION: "1.15.3" 54 | strategy: 55 | matrix: 56 | otp_version: ["25.3"] 57 | name: macOS x86_64 (${{ matrix.otp_version }}) 58 | steps: 59 | - uses: actions/checkout@v4 60 | - run: | 61 | curl -fsSO https://elixir-lang.org/install.sh 62 | sh install.sh elixir@${{ env.ELIXIR_VERSION }} otp@${{ matrix.otp_version }} 63 | otp_bin=($HOME/.elixir-install/installs/otp/*/bin) 64 | elixir_bin=($HOME/.elixir-install/installs/elixir/*/bin) 65 | echo "$otp_bin" >> "$GITHUB_PATH" 66 | echo "$elixir_bin" >> "$GITHUB_PATH" 67 | - name: Precompile 68 | run: | 69 | export ELIXIR_MAKE_CACHE_DIR=$(pwd)/cache 70 | mkdir -p "${ELIXIR_MAKE_CACHE_DIR}" 71 | mix deps.get 72 | mix elixir_make.precompile 73 | - uses: softprops/action-gh-release@v2 74 | if: startsWith(github.ref, 'refs/tags/') 75 | with: 76 | draft: true 77 | files: | 78 | cache/*.tar.gz 79 | cache/*.sha256 80 | 81 | windows: 82 | runs-on: windows-2022 83 | env: 84 | MIX_ENV: prod 85 | ELIXIR_VERSION: "1.15.3" 86 | strategy: 87 | matrix: 88 | otp_version: ["25.3"] 89 | name: Windows x86_64 (${{ matrix.otp_version }}) 90 | steps: 91 | - uses: actions/checkout@v4 92 | - uses: erlef/setup-beam@v1 93 | with: 94 | otp-version: ${{ matrix.otp_version }} 95 | elixir-version: ${{ env.ELIXIR_VERSION }} 96 | - uses: ilammy/msvc-dev-cmd@v1 97 | - name: Precompile 98 | shell: bash 99 | run: | 100 | export ELIXIR_MAKE_CACHE_DIR=$(pwd)/cache 101 | mkdir -p "${ELIXIR_MAKE_CACHE_DIR}" 102 | mix deps.get 103 | mix elixir_make.precompile 104 | - uses: softprops/action-gh-release@v2 105 | if: startsWith(github.ref, 'refs/tags/') 106 | with: 107 | draft: true 108 | files: | 109 | cache/*.tar.gz 110 | cache/*.sha256 111 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - main 7 | - "v*.*" 8 | jobs: 9 | linux: 10 | runs-on: ubuntu-22.04 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | include: 15 | - pair: { elixir: "1.15.8", otp: "25.3" } 16 | - pair: { elixir: "1.18.3", otp: "27.2" } 17 | lint: true 18 | env: 19 | MIX_ENV: test 20 | name: Linux x86_64 (${{ matrix.pair.elixir }}, ${{ matrix.pair.otp }}) 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: erlef/setup-beam@v1 24 | with: 25 | otp-version: ${{ matrix.pair.otp }} 26 | elixir-version: ${{ matrix.pair.elixir }} 27 | - uses: actions/cache@v4 28 | with: 29 | path: | 30 | deps 31 | _build 32 | key: ${{ runner.os }}-mix-${{ matrix.pair.elixir }}-${{ matrix.pair.otp }}-${{ hashFiles('**/mix.lock') }} 33 | restore-keys: | 34 | ${{ runner.os }}-mix-${{ matrix.pair.elixir }}-${{ matrix.pair.otp }}- 35 | - run: mix deps.get 36 | - run: mix format --check-formatted 37 | if: ${{ matrix.lint }} 38 | - run: mix deps.unlock --check-unused 39 | if: ${{ matrix.lint }} 40 | - run: mix deps.compile 41 | - run: mix compile --warnings-as-errors 42 | if: ${{ matrix.lint }} 43 | - run: mix test 44 | 45 | windows: 46 | runs-on: windows-2022 47 | strategy: 48 | fail-fast: false 49 | matrix: 50 | include: 51 | - pair: { elixir: "1.15.8", otp: "25.3" } 52 | - pair: { elixir: "1.18.3", otp: "27.2" } 53 | env: 54 | MIX_ENV: test 55 | name: Windows x86_64 (${{ matrix.pair.elixir }}, ${{ matrix.pair.otp }}) 56 | steps: 57 | - run: git config --global core.autocrlf input 58 | - uses: actions/checkout@v4 59 | - uses: erlef/setup-beam@v1 60 | with: 61 | otp-version: ${{ matrix.pair.otp }} 62 | elixir-version: ${{ matrix.pair.elixir }} 63 | - uses: actions/cache@v4 64 | with: 65 | path: | 66 | deps 67 | _build 68 | key: ${{ runner.os }}-mix-${{ matrix.pair.elixir }}-${{ matrix.pair.otp }}-${{ hashFiles('**/mix.lock') }} 69 | restore-keys: | 70 | ${{ runner.os }}-mix-${{ matrix.pair.elixir }}-${{ matrix.pair.otp }}- 71 | - uses: ilammy/msvc-dev-cmd@v1 72 | - run: mix deps.get 73 | - run: mix deps.compile 74 | - run: mix test 75 | 76 | macos: 77 | runs-on: macos-13 78 | strategy: 79 | fail-fast: false 80 | matrix: 81 | include: 82 | - pair: { elixir: "1.15.8", otp: "25.3" } 83 | - pair: { elixir: "1.18.3", otp: "27.2" } 84 | env: 85 | MIX_ENV: test 86 | name: macOS x86_64 (${{ matrix.pair.elixir }}, ${{ matrix.pair.otp }}) 87 | steps: 88 | - uses: actions/checkout@v4 89 | - run: | 90 | curl -fsSO https://elixir-lang.org/install.sh 91 | sh install.sh elixir@${{ matrix.pair.elixir }} otp@${{ matrix.pair.otp }} 92 | otp_bin=($HOME/.elixir-install/installs/otp/*/bin) 93 | elixir_bin=($HOME/.elixir-install/installs/elixir/*/bin) 94 | echo "$otp_bin" >> "$GITHUB_PATH" 95 | echo "$elixir_bin" >> "$GITHUB_PATH" 96 | - uses: actions/cache@v4 97 | with: 98 | path: | 99 | deps 100 | _build 101 | key: ${{ runner.os }}-mix-${{ matrix.pair.elixir }}-${{ matrix.pair.otp }}-${{ hashFiles('**/mix.lock') }} 102 | restore-keys: | 103 | ${{ runner.os }}-mix-${{ matrix.pair.elixir }}-${{ matrix.pair.otp }}- 104 | - run: mix deps.get 105 | - run: mix deps.compile 106 | - run: mix test 107 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # If the VM crashes, it generates a dump, let's ignore it too. 14 | erl_crash.dump 15 | 16 | # Also ignore archive artifacts (built via "mix archive.build"). 17 | *.ez 18 | 19 | # Ignore package tarball (built via "mix hex.build"). 20 | lazy_html-*.tar 21 | 22 | # Temporary files, for example, from tests. 23 | /tmp/ 24 | 25 | # Checksums for precompile binaries. 26 | /checksum.exs 27 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 6 | 7 | ## [v0.1.1](https://github.com/dashbitco/lazy_html/tree/v0.1.1) (2025-05-24) 8 | 9 | ### Fixed 10 | 11 | - Fix `