Full Code of Kozea/WeasyPrint for AI

main 0aea2e12cbfe cached
190 files
2.7 MB
715.3k tokens
2695 symbols
1 requests
Download .txt
Showing preview only (2,858K chars total). Download the full file or copy to clipboard to get everything.
Repository: Kozea/WeasyPrint
Branch: main
Commit: 0aea2e12cbfe
Files: 190
Total size: 2.7 MB

Directory structure:
gitextract_594bexrt/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── doconfly.yml
│       ├── exe.yml
│       ├── release.yml
│       ├── test_pdfa.yml
│       ├── test_pdfua.yml
│       ├── test_samples.yml
│       └── tests.yml
├── .gitignore
├── LICENSE
├── README.rst
├── docs/
│   ├── api_reference.rst
│   ├── changelog.rst
│   ├── common_use_cases.rst
│   ├── conf.py
│   ├── contribute.rst
│   ├── first_steps.rst
│   ├── going_further.rst
│   ├── index.rst
│   ├── manpage.rst
│   └── support.rst
├── pyproject.toml
├── tests/
│   ├── __init__.py
│   ├── conftest.py
│   ├── css/
│   │   ├── __init__.py
│   │   ├── test_common.py
│   │   ├── test_counters.py
│   │   ├── test_descriptors.py
│   │   ├── test_errors.py
│   │   ├── test_expanders.py
│   │   ├── test_fonts.py
│   │   ├── test_layers.py
│   │   ├── test_math.py
│   │   ├── test_nesting.py
│   │   ├── test_pages.py
│   │   ├── test_target.py
│   │   ├── test_ua.py
│   │   ├── test_validation.py
│   │   └── test_variables.py
│   ├── draw/
│   │   ├── __init__.py
│   │   ├── svg/
│   │   │   ├── __init__.py
│   │   │   ├── test_bounding_box.py
│   │   │   ├── test_clip.py
│   │   │   ├── test_defs.py
│   │   │   ├── test_gradients.py
│   │   │   ├── test_images.py
│   │   │   ├── test_markers.py
│   │   │   ├── test_opacity.py
│   │   │   ├── test_paths.py
│   │   │   ├── test_patterns.py
│   │   │   ├── test_shapes.py
│   │   │   ├── test_text.py
│   │   │   ├── test_transform.py
│   │   │   ├── test_units.py
│   │   │   └── test_visibility.py
│   │   ├── test_absolute.py
│   │   ├── test_background.py
│   │   ├── test_before_after.py
│   │   ├── test_box.py
│   │   ├── test_cmyk_color_profiles.py
│   │   ├── test_column.py
│   │   ├── test_current_color.py
│   │   ├── test_float.py
│   │   ├── test_footnote.py
│   │   ├── test_footnote_column.py
│   │   ├── test_gradient.py
│   │   ├── test_image.py
│   │   ├── test_leader.py
│   │   ├── test_list.py
│   │   ├── test_opacity.py
│   │   ├── test_overflow.py
│   │   ├── test_page.py
│   │   ├── test_table.py
│   │   ├── test_text.py
│   │   ├── test_transform.py
│   │   ├── test_visibility.py
│   │   └── test_whitespace.py
│   ├── layout/
│   │   ├── __init__.py
│   │   ├── test_block.py
│   │   ├── test_column.py
│   │   ├── test_flex.py
│   │   ├── test_float.py
│   │   ├── test_footnotes.py
│   │   ├── test_grid.py
│   │   ├── test_image.py
│   │   ├── test_inline.py
│   │   ├── test_inline_block.py
│   │   ├── test_list.py
│   │   ├── test_logical.py
│   │   ├── test_page.py
│   │   ├── test_position.py
│   │   ├── test_preferred.py
│   │   └── test_table.py
│   ├── resources/
│   │   ├── acid2-reference.html
│   │   ├── acid2-test.html
│   │   ├── cmyk.icc
│   │   ├── doc1.html
│   │   ├── doc1_UTF-16BE.html
│   │   ├── latin1-test.css
│   │   ├── mini_ua.css
│   │   ├── sheet2.css
│   │   ├── sub_directory/
│   │   │   └── sheet1.css
│   │   ├── tests_ua.css
│   │   ├── user.css
│   │   ├── utf8-test.css
│   │   ├── weasyprint.otb
│   │   └── weasyprint.otf
│   ├── test_acid2.py
│   ├── test_api.py
│   ├── test_boxes.py
│   ├── test_fonts.py
│   ├── test_pdf.py
│   ├── test_presentational_hints.py
│   ├── test_stacking.py
│   ├── test_text.py
│   ├── test_unicode.py
│   ├── test_url.py
│   └── testing_utils.py
└── weasyprint/
    ├── __init__.py
    ├── __main__.py
    ├── anchors.py
    ├── css/
    │   ├── __init__.py
    │   ├── computed_values.py
    │   ├── counters.py
    │   ├── functions.py
    │   ├── html5_ph.css
    │   ├── html5_ua.css
    │   ├── html5_ua_form.css
    │   ├── media_queries.py
    │   ├── properties.py
    │   ├── targets.py
    │   ├── tokens.py
    │   ├── units.py
    │   └── validation/
    │       ├── __init__.py
    │       ├── descriptors.py
    │       ├── expanders.py
    │       └── properties.py
    ├── document.py
    ├── draw/
    │   ├── __init__.py
    │   ├── border.py
    │   ├── color.py
    │   └── text.py
    ├── formatting_structure/
    │   ├── boxes.py
    │   └── build.py
    ├── html.py
    ├── images.py
    ├── layout/
    │   ├── __init__.py
    │   ├── absolute.py
    │   ├── background.py
    │   ├── block.py
    │   ├── column.py
    │   ├── flex.py
    │   ├── float.py
    │   ├── grid.py
    │   ├── inline.py
    │   ├── leader.py
    │   ├── min_max.py
    │   ├── page.py
    │   ├── percent.py
    │   ├── preferred.py
    │   ├── replaced.py
    │   └── table.py
    ├── logger.py
    ├── matrix.py
    ├── pdf/
    │   ├── __init__.py
    │   ├── anchors.py
    │   ├── debug.py
    │   ├── fonts.py
    │   ├── metadata.py
    │   ├── pdfa.py
    │   ├── pdfua.py
    │   ├── pdfx.py
    │   ├── sRGB2014.icc
    │   ├── stream.py
    │   └── tags.py
    ├── stacking.py
    ├── svg/
    │   ├── __init__.py
    │   ├── bounding_box.py
    │   ├── css.py
    │   ├── defs.py
    │   ├── images.py
    │   ├── path.py
    │   ├── shapes.py
    │   ├── text.py
    │   └── utils.py
    ├── text/
    │   ├── constants.py
    │   ├── ffi.py
    │   ├── fonts.py
    │   └── line_break.py
    └── urls.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

open_collective: courtbouillon


================================================
FILE: .github/workflows/doconfly.yml
================================================
name: doconfly
on:
  push:
    branches:
      - main
    tags:
      - "*"

jobs:
  doconfly:
    name: doconfly job
    runs-on: ubuntu-latest
    env:
      PORT: ${{ secrets.PORT }}
      SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
      TAKOYAKI: ${{ secrets.TAKOYAKI }}
      USER: ${{ secrets.USER }}
      DOCUMENTATION_PATH: ${{ secrets.DOCUMENTATION_PATH }}
      DOCUMENTATION_URL: ${{ secrets.DOCUMENTATION_URL }}
    steps:
      - run: |
          which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )
          eval $(ssh-agent -s)
          echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          ssh-keyscan -p $PORT $TAKOYAKI >> ~/.ssh/known_hosts
          chmod 644 ~/.ssh/known_hosts
          ssh $USER@$TAKOYAKI -p $PORT "doconfly/doconfly.sh $GITHUB_REPOSITORY $GITHUB_REF $DOCUMENTATION_PATH $DOCUMENTATION_URL"


================================================
FILE: .github/workflows/exe.yml
================================================
name: WeasyPrint’s exe generation
on: [push]

jobs:
  generate:
    name: ${{ matrix.os }}
    runs-on: 'windows-latest'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.13'
      - name: Use absolute imports and install Pango (Windows)
        run: |
          C:\msys64\usr\bin\bash -lc 'pacman -S mingw-w64-x86_64-pango mingw-w64-x86_64-sed --noconfirm'
          C:\msys64\mingw64\bin\sed -i 's/^from \. /from weasyprint /' weasyprint/__main__.py
          C:\msys64\mingw64\bin\sed  -i 's/^from \./from weasyprint\./' weasyprint/__main__.py
          echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH
          rm C:\msys64\mingw64\bin\python.exe
      - name: Install requirements
        run: python -m pip install . pyinstaller
      - name: Generate executable
        run: python -m PyInstaller weasyprint/__main__.py -n weasyprint -F
      - name: Test executable
        run: dist/weasyprint --info
      - name: Store executable
        uses: actions/upload-artifact@v4
        with:
          name: weasyprint-windows
          path: |
            dist/weasyprint
            dist/weasyprint.exe
            README.rst
            LICENSE


================================================
FILE: .github/workflows/release.yml
================================================
name: Release new version
on:
  push:
    tags:
      - v*

jobs:
  pypi-publish:
    name: Upload release to PyPI
    runs-on: ubuntu-latest
    environment:
      name: pypi
      url: https://pypi.org/p/weasyprint
    permissions:
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
      - name: Install requirements
        run: python -m pip install flit
      - name: Build packages
        run: flit build
      - name: Publish package distributions to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
  add-version:
    name: Add version to GitHub
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install requirements
        run: sudo apt-get install pandoc
      - name: Generate content
        run: |
          pandoc docs/changelog.rst -f rst -t gfm | csplit - /##/ "{1}" -f .part
          sed -r "s/^([A-Z].*)\:\$/## \1/" .part01 | sed -r "s/^ *//" | sed -rz "s/([^\n])\n([^\n^-])/\1 \2/g" | tail -n +5 > .body
      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          body_path: .body


================================================
FILE: .github/workflows/test_pdfa.yml
================================================
name: WeasyPrint's PDF/A tests
on: [push, pull_request]

env:
  PDF_FOLDER: 'pdfs'
  VERA_FOLDER: 'vera'

jobs:
  pdf-ua:
    name: Test PDF/A samples
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install requirements
        run: python -m pip install .
      - name: Create output folders
        run: |
          mkdir ${{env.PDF_FOLDER}}
          mkdir ${{env.VERA_FOLDER}}
      - name: Clone samples repository
        run: git clone https://github.com/CourtBouillon/weasyprint-samples.git
      - name: Generate samples
        run: |
          python -m weasyprint --pdf-variant pdf/a-1a weasyprint-samples/book/book.html -s weasyprint-samples/book/book-classical.css ${{env.PDF_FOLDER}}/book-classical.pdf
          python -m weasyprint --pdf-variant pdf/a-2u weasyprint-samples/book/book.html -s weasyprint-samples/book/book.css -s <(echo '* { image-rendering: crisp-edges }') ${{env.PDF_FOLDER}}/book-fancy.pdf
          python -m weasyprint --pdf-variant pdf/a-2b weasyprint-samples/letter/letter.html -s <(echo '* { image-rendering: crisp-edges }') ${{env.PDF_FOLDER}}/letter.pdf
          python -m weasyprint --pdf-variant pdf/a-3a -s <(echo '* { image-rendering: crisp-edges }') weasyprint-samples/report/report.html ${{env.PDF_FOLDER}}/report.pdf
      - name: Install VeraPDF
        run: |
          wget https://software.verapdf.org/releases/verapdf-installer.zip
          unzip verapdf-installer.zip
          java -DINSTALL_PATH=/tmp -jar verapdf-greenfield-*/verapdf-izpack-installer-*.jar -options-system
      - name: Generate VeraPDF reports
        run: |
          /tmp/verapdf -f 1a --format html ${{env.PDF_FOLDER}}/book-classical.pdf > ${{env.VERA_FOLDER}}/book-classical-verapdf.html
          /tmp/verapdf -f 2u --format html ${{env.PDF_FOLDER}}/book-fancy.pdf > ${{env.VERA_FOLDER}}/book-fancy-verapdf.html
          /tmp/verapdf -f 2b --format html ${{env.PDF_FOLDER}}/letter.pdf > ${{env.VERA_FOLDER}}/letter-verapdf.html
          /tmp/verapdf -f 3a --format html ${{env.PDF_FOLDER}}/report.pdf > ${{env.VERA_FOLDER}}/report-verapdf.html
          /tmp/verapdf --format html ${{env.PDF_FOLDER}}/ > ${{env.VERA_FOLDER}}/summary.html
      - name: Archive generated PDFs
        if: ${{ always() }}
        uses: actions/upload-artifact@v4
        with:
          name: vera-results
          path: |
            ${{env.VERA_FOLDER}}
            ${{env.PDF_FOLDER}}
          retention-days: 1


================================================
FILE: .github/workflows/test_pdfua.yml
================================================
name: WeasyPrint's PDF/UA tests
on: [push, pull_request]

env:
  PDF_FOLDER: 'pdfs'
  VERA_FOLDER: 'vera'

jobs:
  pdf-ua:
    name: Test PDF/UA samples
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install requirements
        run: python -m pip install .
      - name: Create output folders
        run: |
          mkdir ${{env.PDF_FOLDER}}
          mkdir ${{env.VERA_FOLDER}}
      - name: Clone samples repository
        run: git clone https://github.com/CourtBouillon/weasyprint-samples.git
      - name: Generate samples
        run: |
          python -m weasyprint --pdf-variant pdf/ua-1 weasyprint-samples/book/book.html -s weasyprint-samples/book/book-classical.css ${{env.PDF_FOLDER}}/book-classical.pdf
          python -m weasyprint --pdf-variant pdf/ua-1 weasyprint-samples/book/book.html -s weasyprint-samples/book/book.css ${{env.PDF_FOLDER}}/book-fancy.pdf
          python -m weasyprint --pdf-variant pdf/ua-1 weasyprint-samples/letter/letter.html ${{env.PDF_FOLDER}}/letter.pdf
          python -m weasyprint --pdf-variant pdf/ua-1 weasyprint-samples/report/report.html ${{env.PDF_FOLDER}}/report.pdf
      - name: Install VeraPDF
        run: |
          wget https://software.verapdf.org/releases/verapdf-installer.zip
          unzip verapdf-installer.zip
          java -DINSTALL_PATH=/tmp -jar verapdf-greenfield-*/verapdf-izpack-installer-*.jar -options-system
      - name: Generate VeraPDF reports
        run: |
          /tmp/verapdf -f ua1 --format html ${{env.PDF_FOLDER}}/book-classical.pdf > ${{env.VERA_FOLDER}}/book-classical-verapdf.html
          /tmp/verapdf -f ua1 --format html ${{env.PDF_FOLDER}}/book-fancy.pdf > ${{env.VERA_FOLDER}}/book-fancy-verapdf.html
          /tmp/verapdf -f ua1 --format html ${{env.PDF_FOLDER}}/letter.pdf > ${{env.VERA_FOLDER}}/letter-verapdf.html
          /tmp/verapdf -f ua1 --format html ${{env.PDF_FOLDER}}/report.pdf > ${{env.VERA_FOLDER}}/report-verapdf.html
          /tmp/verapdf -f ua1 --format html ${{env.PDF_FOLDER}}/ > ${{env.VERA_FOLDER}}/summary.html
      - name: Archive generated PDFs
        if: ${{ always() }}
        uses: actions/upload-artifact@v4
        with:
          name: vera-results
          path: |
            ${{env.VERA_FOLDER}}
            ${{env.PDF_FOLDER}}
          retention-days: 1


================================================
FILE: .github/workflows/test_samples.yml
================================================
name: WeasyPrint's samples tests
on: [push, pull_request]

env:
  REPORTS_FOLDER: 'report'

jobs:
  samples:
    name: Generate samples
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and setuptools
        run: python -m pip install --upgrade pip setuptools
      - name: Install requirements
        run: python -m pip install .
      - name: Clone samples repository
        run: git clone https://github.com/CourtBouillon/weasyprint-samples.git
      - name: Create output folder
        run: mkdir ${{env.REPORTS_FOLDER}}
      - name: Book classical
        run: python -m weasyprint weasyprint-samples/book/book.html -s weasyprint-samples/book/book-classical.css ${{env.REPORTS_FOLDER}}/book-classical.pdf
      - name: Book fancy
        run: python -m weasyprint weasyprint-samples/book/book.html -s weasyprint-samples/book/book.css ${{env.REPORTS_FOLDER}}/book-fancy.pdf
      - name: Invoice
        run: python -m weasyprint weasyprint-samples/invoice/invoice.html ${{env.REPORTS_FOLDER}}/invoice.pdf
      - name: Letter
        run: python -m weasyprint weasyprint-samples/letter/letter.html ${{env.REPORTS_FOLDER}}/letter.pdf
      - name: Poster
        run: python -m weasyprint weasyprint-samples/poster/poster.html -s weasyprint-samples/poster/poster.css ${{env.REPORTS_FOLDER}}/poster.pdf
      - name: Flyer
        run: python -m weasyprint weasyprint-samples/poster/poster.html -s weasyprint-samples/poster/flyer.css ${{env.REPORTS_FOLDER}}/flyer.pdf
      - name: Report
        run: python -m weasyprint weasyprint-samples/report/report.html ${{env.REPORTS_FOLDER}}/report.pdf
      - name: Ticket
        run: python -m weasyprint weasyprint-samples/ticket/ticket.html ${{env.REPORTS_FOLDER}}/ticket.pdf
      - name: Archive generated PDFs
        uses: actions/upload-artifact@v4
        with:
          name: generated-documents
          path: ${{env.REPORTS_FOLDER}}
          retention-days: 1


================================================
FILE: .github/workflows/tests.yml
================================================
name: WeasyPrint's tests
on: [push, pull_request]

jobs:
  tests:
    name: ${{ matrix.os }} - ${{ matrix.python-version }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ['3.14']
        include:
          - os: ubuntu-latest
            python-version: '3.10'
          - os: ubuntu-latest
            python-version: 'pypy-3.11'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install Ghostscript (Ubuntu)
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get update -y && sudo apt-get install ghostscript -y
      - name: Install DejaVu, Pango and Ghostscript (MacOS)
        if: matrix.os == 'macos-latest'
        run: |
          brew update
          brew install --cask font-dejavu
          brew install pango ghostscript
      - name: Install DejaVu, Pango and Ghostscript (Windows)
        if: matrix.os == 'windows-latest'
        run: |
          C:\msys64\usr\bin\bash -lc 'pacman -S mingw-w64-x86_64-ttf-dejavu mingw-w64-x86_64-pango mingw-w64-x86_64-ghostscript --noconfirm'
          xcopy "C:\msys64\mingw64\share\fonts\TTF" "C:\Users\runneradmin\.fonts" /e /i
          echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH
          rm C:\msys64\mingw64\bin\python.exe
      - name: Upgrade pip and setuptools
        run: python -m pip install --upgrade pip setuptools
      - name: Install tests’ requirements
        run: python -m pip install .[test] pytest-xdist
      - name: Launch tests
        run: python -m pytest -n auto
        env:
          DYLD_FALLBACK_LIBRARY_PATH: /opt/homebrew/lib
      - name: Check coding style
        run: python -m ruff check


================================================
FILE: .gitignore
================================================
*.pyc
.cache
/.coverage
/build
/dist
/docs/_build
/pytest_cache
/tests/draw/results
/venv


================================================
FILE: LICENSE
================================================
BSD 3-Clause License

Copyright (c) 2011-2021, Simon Sapin and contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.rst
================================================
**The Awesome Document Factory**

WeasyPrint is a smart solution helping web developers to create PDF
documents. It turns simple HTML pages into gorgeous statistical reports,
invoices, tickets…

From a technical point of view, WeasyPrint is a visual rendering engine for
HTML and CSS that can export to PDF. It aims to support web standards for
printing. WeasyPrint is free software made available under a BSD license.

It is based on various libraries but *not* on a full rendering engine like
WebKit or Gecko. The CSS layout engine is written in Python, designed for
pagination, and meant to be easy to hack on.

* Free software: BSD license
* For Python 3.10+, tested on CPython and PyPy
* Documentation: https://doc.courtbouillon.org/weasyprint
* Examples: https://weasyprint.org/#samples
* Changelog: https://github.com/Kozea/WeasyPrint/releases
* Code, issues, tests: https://github.com/Kozea/WeasyPrint
* Code of conduct: https://www.courtbouillon.org/code-of-conduct
* Professional support: https://www.courtbouillon.org
* Donation: https://opencollective.com/courtbouillon

WeasyPrint has been created and developed by Kozea (https://kozea.fr/).
Professional support, maintenance and community management is provided by
CourtBouillon (https://www.courtbouillon.org/).

Copyrights are retained by their contributors, no copyright assignment is
required to contribute to WeasyPrint. Unless explicitly stated otherwise, any
contribution intentionally submitted for inclusion is licensed under the BSD
3-clause license, without any additional terms or conditions. For full
authorship information, see the version control history.


================================================
FILE: docs/api_reference.rst
================================================
API Reference
=============

.. currentmodule:: weasyprint


This page is for WeasyPrint |version|. See :doc:`changelog </changelog>` for
older versions.


API Stability
-------------

Everything described here is considered “public”: this is what you can rely
on. We will try to maintain backward-compatibility, and we really often do, but
there is no hard promise.

Anything else should not be used outside of WeasyPrint itself. We reserve
the right to change it or remove it at any point. Use it at your own risk,
or have dependency to a specific WeasyPrint version.


Versioning
----------

WeasyPrint provides frequent major releases, and minor releases with only bug
fixes. Versioning is close to what many browsers do, including Firefox and
Chrome: big major numbers, small minor numbers.

Even if each version does not break the API, each version does break the way
documents are rendered, which is what really matters at the end. Providing
minor versions would give the illusion that developers can just update
WeasyPrint without checking that everything works.

Unfortunately, we have the same problem as the other browsers: when a new
version is released, most of the user's websites are rendered exactly the same,
but a small part is not. And the only ways to know that, for web developers,
are to read the changelog and to check that their pages are correctly rendered.

More about this choice can be found in
issue `#900`_.

.. _#900: https://github.com/Kozea/WeasyPrint/issues/900


Command-line API
----------------

.. autofunction:: weasyprint.__main__.main(argv=sys.argv)


Python API
----------

.. autoclass:: HTML(input, **kwargs)
    :members:
.. autoclass:: CSS(input, **kwargs)
.. autoclass:: Attachment(input, **kwargs)
.. autodata:: DEFAULT_OPTIONS

.. module:: weasyprint.document
.. autoclass:: Document
    :members:
.. autoclass:: DocumentMetadata()
    :members:
.. autoclass:: Page()
    :members:
    :exclude-members: paint

.. module:: weasyprint.urls
.. autoclass:: URLFetcher
    :members:
    :member-order: bysource
.. autoclass:: URLFetcherResponse
.. autoclass:: FatalURLFetchingError

.. module:: weasyprint.text.fonts
.. autoclass:: FontConfiguration()

.. module:: weasyprint.css.counters
.. autoclass:: CounterStyle()


Supported Features
------------------


URLs
~~~~

WeasyPrint can read normal files, HTTP, FTP and `data URIs`_. It will follow
HTTP redirects but more advanced features like cookies and authentication
are currently not supported, although a custom :ref:`URL fetcher
<URL Fetchers>` can help.

.. _data URIs: https://en.wikipedia.org/wiki/Data_URI_scheme


HTML
~~~~

Supported HTML Tags
+++++++++++++++++++

Many HTML elements are implemented in CSS through the HTML5
`User-Agent stylesheet`_.

Some elements need special treatment:

* The ``<base>`` element, if present, determines the base for relative URLs.
* CSS stylesheets can be embedded in ``<style>`` elements or linked by
  ``<link rel=stylesheet>`` elements.
* ``<img>``, ``<embed>`` or ``<object>`` elements accept images either
  in raster formats supported by Pillow_ (including PNG, JPEG, GIF, ...)
  or in SVG. SVG images are not rasterized but rendered
  as vectors in the PDF output.

HTML `presentational hints`_ are not supported by default, but most of them can
be supported:

* by using the ``--presentational-hints`` CLI parameter, or
* by setting the ``presentational_hints`` parameter of the ``HTML.render`` or
  ``HTML.write_*`` methods to ``True``.

Presentational hints include a wide array of attributes that direct styling in
HTML, including font ``color`` and ``size``, list attributes like ``type`` and
``start``, various table alignment attributes, and others. If the document
generated by WeasyPrint is missing some of the features you expect from the
HTML, try to enable this option.

.. _User-Agent stylesheet: https://github.com/Kozea/WeasyPrint/blob/main/weasyprint/css/html5_ua.css
.. _presentational hints: https://www.w3.org/TR/html5/rendering.html#presentational-hints
.. _Pillow: https://python-pillow.org/

Stylesheet Origins
++++++++++++++++++

HTML documents are rendered with stylesheets from three *origins*:

* The HTML5 `user agent stylesheet`_ (defines the default appearance
  of HTML elements);
* Author stylesheets embedded in the document in ``<style>`` elements
  or linked by ``<link rel=stylesheet>`` elements;
* User stylesheets provided in the API.

Keep in mind that *user* stylesheets have a lower priority than *author*
stylesheets in the cascade_, unless you use `!important`_ in declarations
to raise their priority.

.. _user agent stylesheet: https://github.com/Kozea/WeasyPrint/blob/main/weasyprint/css/html5_ua.css
.. _cascade: https://www.w3.org/TR/CSS21/cascade.html#cascading-order
.. _!important: https://www.w3.org/TR/CSS21/cascade.html#important-rules


PDF
~~~

In addition to text, raster and vector graphics, WeasyPrint’s PDF files
can contain hyperlinks, bookmarks, attachments and forms.

Hyperlinks will be clickable in PDF viewers that support them. They can
be either internal, to another part of the same document (eg.
``<a href="#pdf">``) or external, to an URL. External links are resolved
to absolute URLs: ``<a href="/blog-articles/">`` on the CourtBouillon website
would always point to https://www.courtbouillon.org/blog-articles/ in PDF
files.

PDF bookmarks are also called outlines and are generally shown in a
sidebar. Clicking on an entry scrolls the matching part of the document
into view. By default all ``<h1>`` to ``<h6>`` titles generate bookmarks,
but this can be controlled with `PDF bookmarks`_.)

Attachments are related files, embedded in the PDF itself. They can be
specified through ``<link rel=attachment>`` elements to add resources globally
or through regular links with ``<a rel=attachment>`` to attach a resource that
can be saved by clicking on said link. The ``title`` attribute can be used as
description of the attachment.

Generated documents can also include PDF forms, using the ``appearance: auto``
CSS property or the ``--pdf-forms`` CLI option.

The generation of PDF/A and PDF/UA documents is supported. However, the
generated documents are not guaranteed to be valid, and users have the
responsibility to check that they follow the rules listed by the related
specifications.


Fonts
~~~~~

WeasyPrint can use any font that Pango_ can find installed on the system. Fonts are
automatically embedded in PDF files and are subset by default to only include the glyphs
used in the PDF. Subsetting is done with hb-subset_ when available on the system,
or by the slower fontTools_ library as a fallback.

Pango_ always uses Fontconfig_ to access fonts, even on Windows and macOS. You
can list the available fonts thanks to the ``fc-list`` command, and know which
font is matched by a given pattern thanks to ``fc-match``. Copying a font file
into the ``~/.local/share/fonts`` directory is generally enough to install a
new font. WeasyPrint should support the major font formats handled by HarfBuzz_.

WeasyPrint follows the Fontconfig_ configuration of the system. This default
configuration is often useful for many cases: font fallbacks for missing glyphs, aliases
for standard font families like "serif" or "monospace", colored variants for emojis,
etc. But some of these default rules can sometimes interfere with CSS rules, and it may
be interesting to disable them if you need to tweak details about font management.

When a Unicode code point is not supported by a font and its fallbacks, the font’s `.notdef glyph`_ is
displayed instead, and a warning is displayed in logs. Because of the way Pango handles
this case, the .notdef glyph may be rendered with an incorrect width (advance), but the layout of
the other glyphs is correct. Text search and selection work as if the glyph was
available.

.. _hb-subset: https://harfbuzz.github.io/harfbuzz-hb-subset.html
.. _fontTools: https://fonttools.readthedocs.io/en/latest/
.. _Pango: https://www.pango.org/
.. _Fontconfig: https://www.freedesktop.org/wiki/Software/fontconfig/
.. _HarfBuzz: https://harfbuzz.github.io/
.. _.notdef glyph: https://en.wikipedia.org/wiki/Notdef_glyph


CSS
~~~

WeasyPrint supports many of the `CSS specifications`_ written by the W3C. You
will find in this chapter a comprehensive list of the specifications or drafts
with at least one feature implemented in WeasyPrint.

.. _CSS specifications: https://www.w3.org/Style/CSS/current-work

CSS Level 2 Revision 1
++++++++++++++++++++++

The `CSS Level 2 Revision 1`_ specification, best known as CSS 2.1, is pretty
well supported by WeasyPrint. Since version 0.11, it passes the famous `Acid2
Test`_.

The CSS 2.1 features listed here are **not** supported:

* On tables: `visibility: collapse`_.
* Minimum and maximum height_ on table-related boxes.
* Minimum and maximum width_ and height_ on page-margin boxes.
* Conforming `font matching algorithm`_. Currently ``font-family``
  is passed as-is to Pango.
* Right-to-left or `bi-directional text`_.
* `System colors`_ and `system fonts`_. The former are deprecated in `CSS Color
  Module Level 3`_.

.. _CSS Level 2 Revision 1: https://www.w3.org/TR/CSS21/
.. _Acid2 Test: https://www.webstandards.org/files/acid2/test.html
.. _empty-cells: https://www.w3.org/TR/CSS21/tables.html#empty-cells
.. _visibility\: collapse: https://www.w3.org/TR/CSS21/tables.html#dynamic-effects
.. _width: https://www.w3.org/TR/CSS21/visudet.html#min-max-widths
.. _height: https://www.w3.org/TR/CSS21/visudet.html#min-max-heights
.. _font matching algorithm: https://www.w3.org/TR/CSS21/fonts.html#algorithm
.. _Bi-directional text: https://www.w3.org/TR/CSS21/visuren.html#direction
.. _System colors: https://www.w3.org/TR/CSS21/ui.html#system-colors
.. _system fonts: https://www.w3.org/TR/CSS21/fonts.html#propdef-font
.. _CSS Color Module Level 3: https://www.w3.org/TR/css-color-3/

To the best of our knowledge, everything else that applies to the
print media **is** supported. Please report a bug if you find this list
incomplete.

Selectors Level 3 / 4
+++++++++++++++++++++

With the exceptions noted here, all `Selectors Level 3`_ are supported.

PDF is generally not interactive. The ``:hover``, ``:active``, ``:focus``,
``:target`` and ``:visited`` pseudo-classes are accepted as valid but
never match anything.

Everything in `Selectors Level 4`_ is supported, except:

- ``:dir``,
- input pseudo-classes (``:valid``, ``:invalid``…),
- column selector (``||``, ``:nth-col()``, ``:nth-last-col()``).

.. _Selectors Level 3: https://www.w3.org/TR/selectors-3/
.. _Selectors Level 4: https://www.w3.org/TR/selectors-4/

CSS Text Module Level 3 / 4
+++++++++++++++++++++++++++

The `CSS Text Module Level 3`_ and `CSS Text Module Level 4`_ are working
drafts defining "properties for text manipulation" and covering "line breaking,
justification and alignment, white space handling, and text transformation".

Among their features, some are already included in CSS 2.1, sometimes with
missing or different values (``text-indent``, ``text-align``,
``letter-spacing``, ``word-spacing``, ``text-transform``, ``white-space``).

New properties defined in Level 3 are supported:

- the ``overflow-wrap`` property replacing ``word-wrap``;
- the ``break-all`` value of the ``word-break`` property (see `#1153`_);
- the ``full-width`` value of the ``text-transform`` property; and
- the ``start``, ``end`` and ``justify-all`` values of the ``text-align`` property;
- the ``text-align-last`` and ``text-justify`` properties; and
- the ``tab-size`` property.

Properties controlling hyphenation_ are supported by WeasyPrint:

- ``hyphens``,
- ``hyphenate-character``,
- ``hyphenate-limit-chars``, and
- ``hyphenate-limit-zone``.

To get automatic hyphenation, you to set it to ``auto``
*and* have the ``lang`` HTML attribute set to one of the languages
`supported by Pyphen`_.

.. code-block:: html

    <!doctype html>
    <html lang=en>
    <style>
      html { hyphens: auto }
    </style>
    …

Automatic hyphenation can be disabled again with the ``manual`` value:

.. code-block:: css

    html { hyphens: auto }
    a[href]::after { content: ' [' attr(href) ']'; hyphens: manual }

The other features provided by `CSS Text Module Level 3`_ are **not**
supported:

- the ``line-break`` property;
- the ``match-parent`` value of the ``text-align`` property;
- the ``text-indent`` and ``hanging-punctuation`` properties.

The other features provided by `CSS Text Module Level 4`_ are **not**
supported:

- the ``text-space-collapse`` and ``text-space-trim`` properties;
- the ``text-wrap``, ``wrap-before``, ``wrap-after`` and ``wrap-inside``
  properties;
- the ``text-align`` property with an alignment character;
- the ``pre-wrap-auto`` value of the ``white-space`` property; and
- the ``text-spacing`` property.

.. _#1153: https://github.com/Kozea/WeasyPrint/issues/1153
.. _supported by Pyphen: https://github.com/Kozea/Pyphen/tree/main/pyphen/dictionaries
.. _hyphenation: https://www.w3.org/TR/css-text-3/#hyphenation
.. _CSS Text Module Level 3: https://www.w3.org/TR/css-text-3/
.. _CSS Text Module Level 4: https://www.w3.org/TR/css-text-4/

CSS Fonts Module Level 3 / 4
++++++++++++++++++++++++++++

The `CSS Fonts Module Level 3`_ is a candidate recommendation describing "how
font properties are specified and how font resources are loaded dynamically".

WeasyPrint supports the ``font-size``, ``font-stretch``, ``font-style`` and
``font-weight`` properties, coming from CSS 2.1.

WeasyPrint also supports the following font features added in Level 3:
- ``font-kerning``,
- ``font-variant-ligatures``,
- ``font-variant-position``,
- ``font-variant-caps``,
- ``font-variant-numeric``,
- ``font-variant-east-asian``,
- ``font-feature-settings``, and
- ``font-language-override``.

``font-family`` is supported. The string is given to Pango that tries to find a
matching font in a way different from what is defined in the recommendation,
but that should not be a problem for common use.

The shorthand ``font`` and ``font-variant`` properties are supported.

WeasyPrint supports the ``@font-face`` rule.

WeasyPrint does **not** support the ``@font-feature-values`` rule and the
values of ``font-variant-alternates`` other than ``normal`` and
``historical-forms``.

From `CSS Fonts Module Level 4`_ we only support the
``font-variation-settings`` property enabling specific font variations.

.. _CSS Fonts Module Level 3: https://www.w3.org/TR/css-fonts-3/
.. _CSS Fonts Module Level 4: https://www.w3.org/TR/css-fonts-4/


CSS Paged Media Module Level 3
++++++++++++++++++++++++++++++

The `CSS Paged Media Module Level 3`_ is a working draft including features for
paged media "describing how:

- page breaks are created and avoided;
- the page properties such as size, orientation, margins, border, and padding
  are specified;
- headers and footers are established within the page margins;
- content such as page counters are placed in the headers and footers; and
- orphans and widows can be controlled."

All the features of this draft are available, including:

- the ``@page`` rule and the ``:left``, ``:right``, ``:first`` and ``:blank``
  selectors;
- the page margin boxes;
- the page-based counters (with known limitations  `#93`_);
- the page ``size``, ``bleed`` and ``marks`` properties;
- the named pages.

.. _CSS Paged Media Module Level 3: https://drafts.csswg.org/css-page-3/
.. _#93: https://github.com/Kozea/WeasyPrint/issues/93

CSS Generated Content for Paged Media Module
++++++++++++++++++++++++++++++++++++++++++++

The `CSS Generated Content for Paged Media Module`_ (GCPM) is a working draft
defining "new properties and values, so that authors may bring new techniques
(running headers and footers, footnotes, page selection) to paged media".

`Page selectors`_ are supported by WeasyPrint. You can select pages according
to their position in the document:

.. code-block:: css

    @page :nth(3) { background: red } /* Third page */
    @page :nth(2n+1) { background: green } /* Odd pages */
    @page :nth(1 of chapter) { background: blue } /* First pages of chapters */

You can also use `running elements`_ to put HTML boxes into the page margins
(but the ``start`` parameter of ``element()`` is not supported).

Footnotes_ are supported. You can put a box in the footnote area using the
``float: footnote`` property. Footnote markers and footnote calls can be
defined using the ``::footnote-marker`` and ``::footnote-call``
pseudo-elements. You can also change the way footnotes are displayed using the
``footnote-display`` property (``compact`` is not supported), and influence
over the rendering of difficult pages with ``footnote-policy``.

.. _CSS Generated Content for Paged Media Module: https://www.w3.org/TR/css-gcpm-3/
.. _Page selectors: https://www.w3.org/TR/css-gcpm-3/#document-page-selectors
.. _running elements: https://www.w3.org/TR/css-gcpm-3/#running-elements
.. _Footnotes: https://www.w3.org/TR/css-gcpm-3/#footnotes

CSS Generated Content Module Level 3
++++++++++++++++++++++++++++++++++++

The `CSS Generated Content Module Level 3`_ is a working draft helping "authors
[who] sometimes want user agents to render content that does not come from the
document tree. One familiar example of this is numbered headings
[…]. Similarly, authors may want the user agent to insert the word "Figure"
before the caption of a figure […], or replacing elements with images or other
multimedia content."

`Named strings`_ are supported by WeasyPrint. You can define strings related to
the first or last element of a type present on a page, and display these
strings in page borders. This feature is really useful to add the title of the
current chapter at the top of the pages of a book for example.

The named strings can embed static strings, counters, cross-references, tag
contents and tag attributes.

.. code-block:: css

    @top-center { content: string(chapter) }
    h2 { string-set: chapter "Current chapter: " content() }

`Cross-references`_ retrieve counter or content values from targets (anchors or
identifiers) in the current document:

.. code-block:: css

    a::after { content: ", on page " target-counter(attr(href), page) }
    a::after { content: ", see " target-text(attr(href)) }

In particular, ``target-counter()`` and ``target-text()`` are useful when it
comes to tables of contents (see `an example`_).

You can also control `PDF bookmarks`_ with WeasyPrint. Using the
``bookmark-level``, ``bookmark-label`` and ``bookmark-state`` properties, you
can add bookmarks that will be available in your PDF reader.

Bookmarks have already been added in the WeasyPrint's `user agent stylesheet`_,
so your generated documents will automatically have bookmarks on headers (from
``<h1>`` to ``<h6>``). But for example, if you have only one top-level ``<h1>``
and do not wish to include it in the bookmarks, add this in your stylesheet:

.. code-block:: css

    h1 { bookmark-level: none }

`Leaders`_ are also supported:

.. code-block:: css

    li a::after {
        content: ' ' leader(dotted) ' ' target-counter(attr(href), page);
    }

The other features of this module are **not** implemented:

- quotes (``content: *-quote``);

.. _CSS Generated Content Module Level 3: https://www.w3.org/TR/css-content-3/
.. _Quotes: https://www.w3.org/TR/css-content-3/#quotes
.. _Named strings: https://www.w3.org/TR/css-content-3/#named-strings
.. _Cross-references: https://www.w3.org/TR/css-content-3/#cross-references
.. _an example: https://github.com/Kozea/WeasyPrint/pull/652#issuecomment-403276559
.. _PDF bookmarks: https://www.w3.org/TR/css-content-3/#bookmark-generation
.. _user agent stylesheet: https://github.com/Kozea/WeasyPrint/blob/main/weasyprint/css/html5_ua.css
.. _Leaders: https://www.w3.org/TR/css-content-3/#leaders

CSS Color Module Level 4 / 5
++++++++++++++++++++++++++++

The `CSS Color Module Level 4`_ is a recommendation defining "CSS properties which allow
authors to specify the foreground color and opacity of the text content of an element".
Its main goal is to specify how colors are defined, including color keywords and many
color notations including ``#rgba``, ``rgb()``, ``hsl()``, ``hwb()``, ``lab()``, etc.
The standard ``color()`` function gives a common way to define colors giving their color
space. Opacity and alpha compositing are also defined in this document.

This recommendation is fully implemented in WeasyPrint, except the deprecated
System Colors.

The `CSS Color Module Level 5`_ is a working draft adding "color modification functions,
custom color spaces (ICC profiles), ``contrast-color()``, ``light-dark()`` and
``device-cmyk()``" to level 4.

WeasyPrint supports the ``light-dark()`` and ``device-cmyk()`` properties, and the
``@color-profile`` at-rule.

WeasyPrint does **not** support the ``color-mix()`` and ``contrast-color()`` properties.

.. _CSS Color Module Level 4: https://www.w3.org/TR/css-color-4/
.. _CSS Color Module Level 5: https://www.w3.org/TR/css-color-5/

CSS Transforms Module Level 1
+++++++++++++++++++++++++++++

The `CSS Transforms Module Level 1`_ working draft "describes a coordinate
system within each element is positioned. This coordinate space can be modified
with the transform property. Using transform, elements can be translated,
rotated and scaled in two or three dimensional space."

WeasyPrint supports the ``transform`` and ``transform-origin`` properties, and
all the 2D transformations (``matrix``, ``rotate``, ``translate``,
``translateX``, ``translateY``, ``scale``, ``scaleX``, ``scaleY``, ``skew``,
``skewX``, ``skewY``).

WeasyPrint does **not** support the ``transform-style``, ``perspective``,
``perspective-origin`` and ``backface-visibility`` properties, and all the 3D
transformations (``matrix3d``, ``rotate3d``, ``rotateX``, ``rotateY``,
``rotateZ``, ``translate3d``, ``translateZ``, ``scale3d``, ``scaleZ``).

.. _CSS Transforms Module Level 1: https://drafts.csswg.org/css-transforms-1/

CSS Backgrounds and Borders Module Level 3
++++++++++++++++++++++++++++++++++++++++++

The `CSS Backgrounds and Borders Module Level 3`_ is a candidate recommendation
defining properties dealing "with the decoration of the border area and with
the background of the content, padding and border areas".

The `border part`_ of this module is supported, as it is already included in
the the CSS 2.1 specification.

WeasyPrint supports the `background part`_ of this module (allowing multiple
background layers per box), including the ``background``, ``background-color``,
``background-image``, ``background-repeat``, ``background-attachment``,
``background-position``, ``background-clip``, ``background-origin`` and
``background-size`` properties.

WeasyPrint also supports the `rounded corners part`_ of this module, including
the ``border-radius`` property.

WeasyPrint also supports the `border images part`_ of this module, including the
``border-image``, ``border-image-source``, ``border-image-slice``,
``border-image-width``, ``border-image-outset`` and ``border-image-repeat``
properties.

WeasyPrint does **not** support the `box shadow part`_ of this module,
including the ``box-shadow`` property. This feature has been implemented in a
`git branch`_ that is not released, as it relies on raster implementation of
shadows.

.. _CSS Backgrounds and Borders Level 3: https://www.w3.org/TR/css-backgrounds-3/
.. _border part: https://www.w3.org/TR/css-backgrounds-3/#borders
.. _background part: https://www.w3.org/TR/css-backgrounds-3/#backgrounds
.. _rounded corners part: https://www.w3.org/TR/css-backgrounds-3/#corners
.. _border images part: https://www.w3.org/TR/css-backgrounds-3/#border-images
.. _box shadow part: https://www.w3.org/TR/css-backgrounds-3/#misc
.. _git branch: https://github.com/Kozea/WeasyPrint/pull/149

CSS Image Values and Replaced Content Module Level 3 / 4
++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The `Image Values and Replaced Content Module Level 3`_ is a candidate
recommendation introducing "additional ways of representing 2D images, for
example as a list of URIs denoting fallbacks, or as a gradient", defining
"several properties for manipulating raster images and for sizing or
positioning replaced elements" and "generic sizing algorithm for replaced
elements".

The `Image Values and Replaced Content Module Level 4`_ is a working draft on
the same subject.

The ``linear-gradient()``, ``radial-gradient()`` and
``repeating-radial-gradient()`` properties are supported as background images.

The the ``url()`` notation is supported, but the ``image()`` notation is
**not** supported for background images.

The ``object-fit`` and ``object-position`` properties are supported.

The ``from-image`` and ``snap`` values of the ``image-resolution`` property are
**not** supported, but the ``resolution`` value is supported.

The ``image-rendering`` and ``image-orientation`` properties are supported.

.. _Image Values and Replaced Content Module Level 3: https://www.w3.org/TR/css-images-3/
.. _Image Values and Replaced Content Module Level 4: https://www.w3.org/TR/css-images-4/

CSS Box Sizing Module Level 3
+++++++++++++++++++++++++++++

The `CSS Box Sizing Module Level 3`_ is a candidate recommendation extending
"the CSS sizing properties with keywords that represent content-based
'intrinsic' sizes and context-based 'extrinsic' sizes."

The new property defined in this document is implemented in WeasyPrint:
``box-sizing``.

The ``min-content``, ``max-content`` and ``fit-content()`` sizing values are
**not** supported.

.. _CSS Box Sizing Module Level 3: https://www.w3.org/TR/css-sizing-3/

CSS Overflow Module Level 3
+++++++++++++++++++++++++++

The `CSS Overflow Module Level 3`_ is a working draft containing "the features
of CSS relating to scrollable overflow handling in visual media."

The ``overflow`` property is supported, as defined in CSS2. ``overflow-x``,
``overflow-y``, ``overflow-clip-margin``, ``overflow-inline`` and
``overflow-block`` are **not** supported.

The ``text-overflow``, ``block-ellipsis``, ``line-clamp``, ``max-lines`` and
``continue`` properties are supported.

.. _CSS Overflow Module Level 3: https://www.w3.org/TR/2020/WD-css-overflow-3-20200603/

CSS Values and Units Module Level 3 / 4
+++++++++++++++++++++++++++++++++++++++

The `CSS Values and Units Module Level 3`_ defines various units and
keywords used in "value definition field of each CSS property".

The `CSS Values and Units Module Level 4`_ adds many new units, unit types and math
functions.

The ``initial`` and ``inherit`` CSS-wide keywords are supported, but the
``unset`` keyword is **not** supported.

Quoted strings, URLs and numeric data types are supported.

Font-relative lengths (``*em``, ``*ex``, ``*ch``, ``*cap``, ``*ic``, ``*lh``),
viewport-relative lengths (``*vw``, ``*vh``, ``*vi``, ``*vb``, ``*vmin``, ``*vmax``),
absolute lengths (``cm``, ``mm``, ``q``, ``in``, ``pt``, ``pc``, ``px``), angles
(``rad``, ``grad``, ``turn``, ``deg``), resolutions (``dpi``, ``dpcm``, ``dppx``, ``x``)
are supported.

Unspecified page-relative units (``pvw``, ``pvh``…) are also supported. They are
relative to the whole page size (including page margins), while all the other units are
relative to the page area size (without page margins).

The ``attr()`` functional notation is allowed in the ``content`` and
``string-set`` properties.

All the mathematical functions (``calc()``…) are supported.

.. _CSS Values and Units Module Level 3: https://www.w3.org/TR/css3-values/
.. _CSS Values and Units Module Level 4: https://www.w3.org/TR/css4-values/

CSS Multi-column Layout Module
++++++++++++++++++++++++++++++

The `CSS Multi-column Layout Module`_ "describes multi-column layouts in CSS, a
style sheet language for the web. Using functionality described in the
specification, content can be flowed into multiple columns with a gap and a
rule between them."

Simple multi-column layouts are supported in WeasyPrint. Features such as
constrained height, spanning columns or column breaks are **not**
supported. Pagination and overflow are not seriously tested.

The ``column-width`` and ``column-count`` properties, and the ``columns``
shorthand property are supported.

The ``column-gap``, ``column-rule-color``, ``column-rule-style`` and
``column-rule-width`` properties, and the ``column-rule`` shorthand property
are supported.

The ``break-before``, ``break-after`` and ``break-inside`` properties are
supported.

The ``column-span`` property is supported for direct children of columns.

The ``column-fill`` property is supported, with a column balancing algorithm
that should be efficient with simple cases.

.. _CSS Multi-column Layout Module: https://www.w3.org/TR/css-multicol-1/

CSS Fragmentation Module Level 3 / 4
++++++++++++++++++++++++++++++++++++

The `CSS Fragmentation Module Level 3`_ "describes the fragmentation model that
partitions a flow into pages, columns, or regions. It builds on the Page model
module and introduces and defines the fragmentation model. It adds
functionality for pagination, breaking variable fragment size and orientation,
widows and orphans."

The `CSS Fragmentation Module Level 4`_ is a working draft on the same subject.

The ``break-before``, ``break-after`` and ``break-inside`` properties are
supported for pages, but **not** for columns and regions. ``page-break-*``
aliases as defined in CSS2 are supported too.

The ``orphans`` and ``widows`` properties are supported.

The ``box-decoration-break`` property is supported, but backgrounds are always
repeated and not extended through the whole box as it should be with 'slice'
value.

The ``margin-break`` property is supported.

.. _CSS Fragmentation Module Level 3: https://www.w3.org/TR/css-break-3/
.. _CSS Fragmentation Module Level 4: https://www.w3.org/TR/css-break-4/

CSS Custom Properties for Cascading Variables Module Level 1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The `CSS Custom Properties for Cascading Variables Module Level 1`_ "introduces
cascading variables as a new primitive value type that is accepted by all CSS
properties, and custom properties for defining them."

The custom properties and the ``var()`` notation are supported.

.. _CSS Custom Properties for Cascading Variables Module Level 1: https://www.w3.org/TR/css-variables/

CSS Text Decoration Module Level 3 / 4
++++++++++++++++++++++++++++++++++++++

The `CSS Text Decoration Module Level 3`_ "contains the features of CSS
relating to text decoration, such as underlines, text shadows, and emphasis
marks."

The `CSS Text Decoration Module Level 4`_ is a working draft on the same subject.

The ``text-decoration-line``, ``text-decoration-style``,
``text-decoration-color``, ``text-decoration-thickness`` and
``text-underline-offset`` properties are supported. The ``text-decoration``
shorthand is also supported.

The other properties (``text-underline-position``, ``text-emphasis-*``,
``text-shadow``) are not supported.

.. _CSS Text Decoration Module Level 3: https://www.w3.org/TR/css-text-decor-3/
.. _CSS Text Decoration Module Level 4: https://www.w3.org/TR/css-text-decor-4/

CSS Flexible Box Layout Module Level 1
++++++++++++++++++++++++++++++++++++++

The `CSS Flexible Box Layout Module Level 1`_ "describes a CSS box model
optimized for user interface design", also known as "flexbox".

This module works for simple use cases but is not deeply tested.

All the ``flex-*``, ``align-*``, ``justify-*`` and ``order`` properties are
supported. The ``flex`` and ``flex-flow`` shorthands are supported too.

.. _CSS Flexible Box Layout Module Level 1: https://www.w3.org/TR/css-flexbox-1/

CSS Grid Layout Module Level 2
++++++++++++++++++++++++++++++

The `CSS Grid Layout Module Level 2`_ "defines a two-dimensional grid-based layout
system, optimized for user interface design".

This module works for simple cases, but has some limitations. Here are
non-exhaustive lists of supported/unsupported features.

Supported:

- ``display: grid``,
- ``grid-auto-*``, ``grid-template-*`` and other ``grid-*`` properties,
- ``grid`` and other ``grid-*`` shorthands,
- flexible lengths (``fr`` unit),
- line names,
- grid areas,
- auto rows and auto columns,
- ``z-index``,
- ``repeat(X, *)``,
- ``minmax()``,
- ``align-*`` and ``justify-*`` alignment properties,
- ``gap`` and ``*-gap`` properties for gutters,
- dense auto flow,
- ``order``,
- margins, borders, padding on grid containers and grid items,
- fragmentation between rows.

Unsupported or untested:

- ``display: inline-grid``,
- auto content size for grid containers,
- ``grid-auto-flow: column``,
- subgrids,
- ``repeat(auto-fill, *)`` and ``repeat(auto-fit, *)``,
- auto margins for grid items,
- ``span`` with line names,
- ``span`` for flexible tracks,
- ``safe`` and ``unsafe`` alignments,
- baseline alignment,
- grid items with intrinsic size (images),
- distribute space beyond limits,
- grid items larger than grid containers,
- ``min-width``, ``max-width``, ``min-height``, ``max-height`` on grid items,
- complex ``min-content`` and ``max-content`` cases,
- absolutely positioned and floating grid items,
- fragmentation in rows.

.. _CSS Grid Layout Module Level 2: https://www.w3.org/TR/css-grid-2/

CSS Basic User Interface Module Level 3/4
+++++++++++++++++++++++++++++++++++++++++

The `CSS Basic User Interface Module Level 3/4`_ "enables authors to style user
interface related properties and values."

The ``outline-width``, ``outline-style``, ``outline-color`` properties and the
``outline`` shorthand are supported. The ``outline-offset`` property is also
supported.

The ``resize``, ``cursor``, ``caret-*`` and ``nav-*`` properties are **not**
supported.

The ``appearance`` property is supported. When set to ``auto``, it displays
form fields as PDF form fields (supported for text inputs, check boxes, text
areas, and select only).

The ``accent-color`` property is **not** supported.


================================================
FILE: docs/changelog.rst
================================================
Changelog
=========


Version 68.1
------------

Released on 2026-02-06.

Bug fixes:

* `#2662 <https://github.com/Kozea/WeasyPrint/issues/2662>`_:
  Don’t crash when SVG clip paths are not in defs tags
* `#2665 <https://github.com/Kozea/WeasyPrint/issues/2665>`_:
  Fix position of box bounding box
* `#2663 <https://github.com/Kozea/WeasyPrint/issues/2663>`_:
  Fix transparency with Acrobat and Edge
* `#2666 <https://github.com/Kozea/WeasyPrint/issues/2666>`_:
  Don’t rely on random default font to define test page size
* `#2670 <https://github.com/Kozea/WeasyPrint/issues/2670>`_:
  Fix pattern detection of URL schemes
* `#2671 <https://github.com/Kozea/WeasyPrint/pull/2671>`_:
  Improve API compatibility between URLFetcherResponse and addinfourl
* `#2672 <https://github.com/Kozea/WeasyPrint/issues/2672>`_:
  Fix charset for old URL fetcher requests
* `#2675 <https://github.com/Kozea/WeasyPrint/pull/2675>`_,
  `#2673 <https://github.com/Kozea/WeasyPrint/issues/2673>`_:
  Fix calc for many properties

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Syslifters
* Kobalt
* Simon Sapin
* Grip Angebotssoftware
* Manuel Barkhau
* Simonsoft
* KontextWork
* Menutech
* TrainingSparkle
* Healthchecks.io
* Method B
* FieldHub
* Hammerbacher
* Yanal-Yves Fargialla
* Morntag
* Piloterr
* Xavid
* Charlie S.
* Prothesis Dental Solutions
* Kai DeLorenzo


Version 68.0
------------

Released on 2026-01-19.

**This is a security update (CVE-2025-68616).**

We strongly recommend to upgrade WeasyPrint to the latest version if you use the
``default_url_fetcher`` function in your custom URL fetcher, or if you use the
``allowed_protocols`` parameter of the ``default_url_fetcher`` function.

Security:

* Always use URL fetcher for HTTP redirects

Python API:

* ``default_url_fetcher()`` is deprecated, use the new ``URLFetcher`` class instead, see
  :ref:`URL Fetchers` for more information about URL fetchers
* ``DocumentMetadata.generate_rdf_metadata`` is now a method that can be overridden
  instead of a parameter, see :ref:`Factur-X / ZUGFeRD (Electronic Invoices)` for
  examples to create e-invoices

Features:

* `#2609 <https://github.com/Kozea/WeasyPrint/pull/2609>`_,
  `#2603 <https://github.com/Kozea/WeasyPrint/issues/2603>`_,
  `#351 <https://github.com/Kozea/WeasyPrint/issues/351>`_:
  Refactor URL fetcher API
* `#2632 <https://github.com/Kozea/WeasyPrint/pull/2632>`_:
  Support legacy 0 value for angles
* `#2627 <https://github.com/Kozea/WeasyPrint/pull/2627>`_:
  Add font-face support to SVG
* `#2646 <https://github.com/Kozea/WeasyPrint/pull/2646>`_,
  `#2255 <https://github.com/Kozea/WeasyPrint/issues/2255>`_:
  Add font shorthand support for SVG text elements
* `#2590 <https://github.com/Kozea/WeasyPrint/pull/2590>`_,
  `#1749 <https://github.com/Kozea/WeasyPrint/issues/1749>`_:
  Honor language-specific rules for text-transform
* `#2645 <https://github.com/Kozea/WeasyPrint/pull/2645>`_,
  `#2613 <https://github.com/Kozea/WeasyPrint/issues/2613>`_:
  Improve SVG and SVG emojis rendering
* `#2658 <https://github.com/Kozea/WeasyPrint/pull/2658>`_,
  `#2583 <https://github.com/Kozea/WeasyPrint/issues/2583>`_:
  Add CLI for Factur-X / ZUGFeRD e-invoices

Bug fixes:

* `#2649 <https://github.com/Kozea/WeasyPrint/issues/2649>`_:
  Refactor URL fetcher API
* `#2643 <https://github.com/Kozea/WeasyPrint/pull/2643>`_,
  `#2628 <https://github.com/Kozea/WeasyPrint/issues/2628>`_:
  Handle box-sizing: border-box in grid layout
* `#2641 <https://github.com/Kozea/WeasyPrint/pull/2641>`_,
  `#1875 <https://github.com/Kozea/WeasyPrint/issues/1875>`_:
  Process whitespace after checking all pending targets
* `#2488 <https://github.com/Kozea/WeasyPrint/pull/2488>`_,
  `#2485 <https://github.com/Kozea/WeasyPrint/issues/2485>`_:
  Preserve page groups during layout repagination
* `#2642 <https://github.com/Kozea/WeasyPrint/pull/2642>`_,
  `#2631 <https://github.com/Kozea/WeasyPrint/issues/2631>`_:
  Don’t use isolated transparency groups
* `#2637 <https://github.com/Kozea/WeasyPrint/issues/2637>`_:
  Fix repeating radial gradients rendering
* `#2622 <https://github.com/Kozea/WeasyPrint/issues/2622>`_:
  Fix validation of colors
* `#2626 <https://github.com/Kozea/WeasyPrint/issues/2626>`_:
  Share grid items rendering advancement between a box and its copies
* `#2621 <https://github.com/Kozea/WeasyPrint/issues/2621>`_:
  Correctly handle fallback values of attr()
* `#2619 <https://github.com/Kozea/WeasyPrint/issues/2619>`_:
  Fix SVG fonts
* `#2629 <https://github.com/Kozea/WeasyPrint/issues/2629>`_:
  Always define extra skip height that may be used after
* `#2648 <https://github.com/Kozea/WeasyPrint/issues/2648>`_:
  Fix numbers validation in font-feature-settings
* `#2648 <https://github.com/Kozea/WeasyPrint/issues/2660>`_:
  Fix keyword values for text-decoration-thickness
* `#2661 <https://github.com/Kozea/WeasyPrint/issues/2661>`_:
  Respect inline images when defining minimum table width

Documentation:

* `#2638 <https://github.com/Kozea/WeasyPrint/pull/2638>`_:
  Update Python command for Windows installation steps

Contributors:

* Guillaume Ayoub
* Jurriaan Pruis
* Mohamed Hamed
* Alexandra Usatenko
* Andrea Corna
* Aoishik Khan
* Joe

Backers and sponsors:

* Spacinov
* Syslifters
* Kobalt
* Simon Sapin
* Grip Angebotssoftware
* Manuel Barkhau
* Simonsoft
* KontextWork
* Menutech
* TrainingSparkle
* Healthchecks.io
* Method B
* FieldHub
* Hammerbacher
* Yanal-Yves Fargialla
* Morntag
* Piloterr
* Xavid
* Charlie S.
* Prothesis Dental Solutions
* Kai DeLorenzo


Version 67.0
------------

Released on 2025-12-02.

Dependencies:

* Python 3.10+ is now needed, Python 3.9 is not supported anymore
* tinycss2 1.5.0+ is now needed
* fontTools 4.59.2+ is now needed

Features:

* `#2560 <https://github.com/Kozea/WeasyPrint/pull/2560>`_,
  `#640 <https://github.com/Kozea/WeasyPrint/issues/640>`_,
  `#844 <https://github.com/Kozea/WeasyPrint/issues/844>`_,
  `#1091 <https://github.com/Kozea/WeasyPrint/issues/1091>`_,
  `#2517 <https://github.com/Kozea/WeasyPrint/issues/2517>`_:
  Support CMYK colors, PDF/X, color profiles and light-dark() function
* `#2558 <https://github.com/Kozea/WeasyPrint/pull/2558>`_,
  `#1175 <https://github.com/Kozea/WeasyPrint/issues/1175>`_:
  Support ::first-line, with financial support from Karte Technology
* `#2552 <https://github.com/Kozea/WeasyPrint/pull/2552>`_:
  Support CSS layers, with financial support from Code & Co.
* `#2564 <https://github.com/Kozea/WeasyPrint/pull/2564>`_,
  `#2599 <https://github.com/Kozea/WeasyPrint/pull/2599>`_,
  `#2397 <https://github.com/Kozea/WeasyPrint/issues/2397>`_:
  Allow page breaks in grid rows, with financial support from Ocean Recap
* `#2568 <https://github.com/Kozea/WeasyPrint/pull/2568>`_,
  `#357 <https://github.com/Kozea/WeasyPrint/issues/357>`_:
  Support calc() and other mathematical functions
* `#2575 <https://github.com/Kozea/WeasyPrint/pull/2575>`_,
  `#2574 <https://github.com/Kozea/WeasyPrint/issues/2574>`_:
  Support PDF/A-1a, PDF/A-2a and PDF/A-3a
* `#2611 <https://github.com/Kozea/WeasyPrint/pull/2611>`_,
  `#2573 <https://github.com/Kozea/WeasyPrint/issues/2573>`_:
  Support PDF/A-4e and PDF/A-4f
* `#2523 <https://github.com/Kozea/WeasyPrint/pull/2523>`_:
  Display tofu for missing glyphs
* `#2581 <https://github.com/Kozea/WeasyPrint/pull/2581>`_:
  Add option to disable protocols in URL resolution
* `#2570 <https://github.com/Kozea/WeasyPrint/pull/2570>`_:
  Support rch, cap, rcap, rex, ic and ric font-relative units
* `#2547 <https://github.com/Kozea/WeasyPrint/pull/2547>`_,
  `#2140 <https://github.com/Kozea/WeasyPrint/issues/2140>`_:
  Support "only" keyword in media queries

Bug fixes:

* `#2516 <https://github.com/Kozea/WeasyPrint/pull/2516>`_,
  `#1510 <https://github.com/Kozea/WeasyPrint/issues/1510>`_:
  Fix rendering of first line of text with nested right float
* `#2510 <https://github.com/Kozea/WeasyPrint/pull/2510>`_,
  `#1073 <https://github.com/Kozea/WeasyPrint/issues/1073>`_,
  `#2507 <https://github.com/Kozea/WeasyPrint/issues/2507>`_:
  Avoid Pango crashes and font mismatches with @font-face rules referencing local fonts
* `#2532 <https://github.com/Kozea/WeasyPrint/pull/2532>`_,
  `#2531 <https://github.com/Kozea/WeasyPrint/issues/2531>`_:
  Use fonttools instancer instead of deprecated mutator API
* `#2541 <https://github.com/Kozea/WeasyPrint/pull/2541>`_:
  Fix syntax of functions
* `#2543 <https://github.com/Kozea/WeasyPrint/pull/2543>`_:
  Allow font-related units to access @font-face fonts
* `#2525 <https://github.com/Kozea/WeasyPrint/pull/2525>`_:
  Respect top margins and avoid overlapping footnotes for columns, with financial support from Code & Co.
* `#2536 <https://github.com/Kozea/WeasyPrint/pull/2536>`_:
  Remove Subtype key from font descriptor
* `#2539 <https://github.com/Kozea/WeasyPrint/pull/2539>`_:
  Fix min width for SVGs with intrinsic ratio but no intrinsic size
* `#2537 <https://github.com/Kozea/WeasyPrint/pull/2537>`_,
  `#2533 <https://github.com/Kozea/WeasyPrint/issues/2533>`_:
  Fix order of operators when drawing SVGs
* `#2538 <https://github.com/Kozea/WeasyPrint/pull/2538>`_:
  Don’t crash with nested unknown functions
* `#2542 <https://github.com/Kozea/WeasyPrint/pull/2542>`_:
  Don’t crash when lh and rlh are used for line height or font size
* `#2540 <https://github.com/Kozea/WeasyPrint/pull/2540>`_,
  `#2528 <https://github.com/Kozea/WeasyPrint/issues/2528>`_:
  Use locale encoding instead of filesystem encoding for font paths
* `#2563 <https://github.com/Kozea/WeasyPrint/pull/2563>`_,
  `#2479 <https://github.com/Kozea/WeasyPrint/issues/2479>`_:
  Don’t avoid float collisions for atomic flex items
* `#2569 <https://github.com/Kozea/WeasyPrint/pull/2569>`_:
  Don’t be case-sensitive for units
* `#2567 <https://github.com/Kozea/WeasyPrint/pull/2567>`_,
  `#2566 <https://github.com/Kozea/WeasyPrint/issues/2566>`_:
  Add x-default attribute for metadata description to be compliant with PDF/A
* `#2586 <https://github.com/Kozea/WeasyPrint/pull/2586>`_,
  `#2571 <https://github.com/Kozea/WeasyPrint/issues/2571>`_:
  Improve formatting contexts management
* `#2600 <https://github.com/Kozea/WeasyPrint/pull/2600>`_:
  Fix SVG image aspect ratio when only width or height is specified
* `#2612 <https://github.com/Kozea/WeasyPrint/pull/2612>`_,
  `#2595 <https://github.com/Kozea/WeasyPrint/pull/2595>`_:
  Clean block layout and fix corner cases
* `#2522 <https://github.com/Kozea/WeasyPrint/issues/2522>`_:
  Ignore preserveAspectRatio when SVG has no viewBox
* `#2544 <https://github.com/Kozea/WeasyPrint/issues/2544>`_:
  Allow to use a variable twice in a function
* `#2555 <https://github.com/Kozea/WeasyPrint/issues/2555>`_:
  Fix flex gap in right-to-left context
* `#2591 <https://github.com/Kozea/WeasyPrint/issues/2591>`_:
  Respect non-auto widths and fix padding of grid items
* `#2601 <https://github.com/Kozea/WeasyPrint/issues/2601>`_:
  Don’t crash when tagged tables are not displayed as tables
* `#2607 <https://github.com/Kozea/WeasyPrint/issues/2607>`_:
  Fix rendering of multiline textareas with PDF forms
* `#2106 <https://github.com/Kozea/WeasyPrint/issues/2106>`_:
  Force variable initialization to avoid crashes during column layout
* `#2618 <https://github.com/Kozea/WeasyPrint/pull/2618>`_,
  `#2617 <https://github.com/Kozea/WeasyPrint/issues/2617>`_:
  Fix rendering of relative grid and flex items

Documentation:

* `#2535 <https://github.com/Kozea/WeasyPrint/pull/2535>`_:
  `#2534 <https://github.com/Kozea/WeasyPrint/issues/2534>`_:
  Removed reference to defunct site

Contributors:

* Guillaume Ayoub
* Fazle Rabbi Ferdaus
* Lucie Anglade
* Luca Vercelli
* ChickenF622
* Ernie Chu
* Mark Pullin
* Malte Laukötter
* Markus Mohanty
* Yvonne Kothmeier
* Jarom Ort
* kuypan

Backers and sponsors:

* Spacinov
* Syslifters
* Kobalt
* Simon Sapin
* Grip Angebotssoftware
* Manuel Barkhau
* Simonsoft
* KontextWork
* Menutech
* TrainingSparkle
* Healthchecks.io
* Method B
* FieldHub
* Hammerbacher
* Yanal-Yves Fargialla
* Morntag
* Piloterr
* Xavid
* Charlie S.
* Prothesis Dental Solutions
* Kai DeLorenzo


Version 66.0
------------

Released on 2025-07-24.

Features:

* `#2475 <https://github.com/Kozea/WeasyPrint/pull/2475>`_:
  Add support for 'lh' and 'rlh' units
* `#2432 <https://github.com/Kozea/WeasyPrint/issues/2432>`_,
  `#2437 <https://github.com/Kozea/WeasyPrint/pull/2437>`_:
  Report footnotes when text overflows because of orphans, with financial support from Code & Co.
* `#2256 <https://github.com/Kozea/WeasyPrint/issues/2256>`_,
  `#2466 <https://github.com/Kozea/WeasyPrint/pull/2466>`_:
  Handle transform-origin in SVG
* `#2445 <https://github.com/Kozea/WeasyPrint/pull/2445>`_:
  Add parameter to have additional HTTP headers for url_fetcher

Bug fixes:

* `#2471 <https://github.com/Kozea/WeasyPrint/pull/2471>`_,
  `#2506 <https://github.com/Kozea/WeasyPrint/pull/2506>`_,
  `#2500 <https://github.com/Kozea/WeasyPrint/issues/2500>`_,
  `#2460 <https://github.com/Kozea/WeasyPrint/issues/2460>`_,
  `#2363 <https://github.com/Kozea/WeasyPrint/issues/2363>`_,
  `#2470 <https://github.com/Kozea/WeasyPrint/issues/2470>`_,
  `#1872 <https://github.com/Kozea/WeasyPrint/issues/1872>`_,
  `#2153 <https://github.com/Kozea/WeasyPrint/issues/2153>`_,
  `#1838 <https://github.com/Kozea/WeasyPrint/issues/1838>`_,
  `#1837 <https://github.com/Kozea/WeasyPrint/issues/1837>`_,
  `#1784 <https://github.com/Kozea/WeasyPrint/issues/1784>`_,
  `#1835 <https://github.com/Kozea/WeasyPrint/issues/1835>`_,
  `#2444 <https://github.com/Kozea/WeasyPrint/issues/2444>`_,
  `#2497 <https://github.com/Kozea/WeasyPrint/issues/2497>`_,
  `#2505 <https://github.com/Kozea/WeasyPrint/issues/2505>`_,
  `#2503 <https://github.com/Kozea/WeasyPrint/issues/2503>`_,
  `#1836 <https://github.com/Kozea/WeasyPrint/issues/1836>`_,
  `#2467 <https://github.com/Kozea/WeasyPrint/issues/2467>`_:
  Improve PDF/UA support, with financial support from NLnet
* `#2425 <https://github.com/Kozea/WeasyPrint/pull/2425>`_,
  `#1557 <https://github.com/Kozea/WeasyPrint/issues/1557>`_:
  Improve position of outside markers
* `#2409 <https://github.com/Kozea/WeasyPrint/pull/2409>`_,
  `#2265 <https://github.com/Kozea/WeasyPrint/issues/2265>`_:
  Draw circles instead of rectangles when drawing dotted borders
* `#2416 <https://github.com/Kozea/WeasyPrint/pull/2416>`_,
  `#2270 <https://github.com/Kozea/WeasyPrint/issues/2270>`_:
  Correctly split words for automatic hyphenation
* `#2439 <https://github.com/Kozea/WeasyPrint/pull/2439>`_,
  `#2426 <https://github.com/Kozea/WeasyPrint/issues/2426>`_:
  Don’t rely on URL protocols outside URL fetcher function
* `#2433 <https://github.com/Kozea/WeasyPrint/pull/2433>`_:
  Disable style for deprecated outline algorithm
* `#2447 <https://github.com/Kozea/WeasyPrint/pull/2447>`_,
  `#2441 <https://github.com/Kozea/WeasyPrint/issues/2441>`_,
  `#2448 <https://github.com/Kozea/WeasyPrint/issues/2448>`_:
  Improve min- and max-content calculation, with financial support from Menutech
* `#2454 <https://github.com/Kozea/WeasyPrint/pull/2454>`_,
  `#2442 <https://github.com/Kozea/WeasyPrint/issues/2442>`_,
  `#2449 <https://github.com/Kozea/WeasyPrint/issues/2449>`_:
  Minor fixes for flex layout
* `#2473 <https://github.com/Kozea/WeasyPrint/pull/2473>`_,
  `#2459 <https://github.com/Kozea/WeasyPrint/issues/2459>`_:
  Include out-of-flow boxes in page layout progress, with financial support from Pathfindr
* `#2458 <https://github.com/Kozea/WeasyPrint/pull/2458>`_:
  Replace deprecated warn logger function
* `#2494 <https://github.com/Kozea/WeasyPrint/pull/2494>`_,
  `#1856 <https://github.com/Kozea/WeasyPrint/issues/1856>`_:
  Fix bug with bottom margins in columns
* `#2435 <https://github.com/Kozea/WeasyPrint/issues/2435>`_:
  Make footnote calls inherit from footnotes
* `#2484 <https://github.com/Kozea/WeasyPrint/issues/2484>`_,
  `#2456 <https://github.com/Kozea/WeasyPrint/issues/2456>`_:
  Allow to avoid page breaks after table-row-group elements
* `#2450 <https://github.com/Kozea/WeasyPrint/issues/2450>`_:
  Draw background and borders for relative grid containers
* `#2453 <https://github.com/Kozea/WeasyPrint/issues/2453>`_:
  Don’t advance position_y for collapsed margins of discarded children
* `#2493 <https://github.com/Kozea/WeasyPrint/issues/2493>`_:
  Fix endless loop with CSS variables referencing each other
* `#2502 <https://github.com/Kozea/WeasyPrint/issues/2502>`_:
  Ignore bottom margin when calculating footnote overflow

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Alvaro Garcia Fernandez
* Emmanuel Ferdman
* Gabriel Corona
* Markus Mohanty
* Luca Vercelli
* Tre Huang

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Simon Sapin
* Manuel Barkhau
* Simonsoft
* Menutech
* KontextWork
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* DocRaptor
* Yanal-Yves Fargialla
* Method B
* FieldHub
* Morntag
* Xavid
* Kai DeLorenzo
* Charlie S.
* Alan Villalobos


Version 65.1
------------

Released on 2025-04-14.

Bug fixes:

* `#2414 <https://github.com/Kozea/WeasyPrint/issues/2414>`_:
  Correctly handle flex columns split between pages
* `1b24ad9 <https://github.com/Kozea/WeasyPrint/commit/1b24ad9>`_:
  Include padding in outer size of item elements
* `#2419 <https://github.com/Kozea/WeasyPrint/issues/2419>`_:
  Set main tag as block by default
* `#2415 <https://github.com/Kozea/WeasyPrint/issues/2415>`_:
  Fix support of replaced block box as flex items
* `83da2fe0 <https://github.com/Kozea/WeasyPrint/commit/83da2fe0>`_:
  Fix margins and padding for rtl lists
* `#2429 <https://github.com/Kozea/WeasyPrint/issues/2429>`_,
  `#1076 <https://github.com/Kozea/WeasyPrint/issues/1076>`_,
  `#2431 <https://github.com/Kozea/WeasyPrint/pull/2431>`_:
  Fix page groups

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Simon Sapin
* Manuel Barkhau
* Simonsoft
* Menutech
* KontextWork
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* DocRaptor
* Yanal-Yves Fargialla
* Method B
* FieldHub
* Morntag
* Xavid
* Kai DeLorenzo
* Charlie S.
* Alan Villalobos


Version 65.0
------------

Released on 2025-03-20.

Dependencies:

* CSSSelect2 0.8.0 is now needed

Features:

* `#1665 <https://github.com/Kozea/WeasyPrint/issues/1665>`_:
  Support gap properties in Flex layout, with financial support from NLnet
* `#378 <https://github.com/Kozea/WeasyPrint/issues/378>`_,
  `#2405 <https://github.com/Kozea/WeasyPrint/pull/2405>`_:
  Handle @font-face unicode-range
* `#2394 <https://github.com/Kozea/WeasyPrint/pull/2394>`_:
  Modernize and improve default user agent stylesheets

Bug fixes:

* `#2362 <https://github.com/Kozea/WeasyPrint/issues/2362>`_,
  `#2387 <https://github.com/Kozea/WeasyPrint/pull/2387>`_,
  `#601 <https://github.com/Kozea/WeasyPrint/issues/601>`_,
  `#1967 <https://github.com/Kozea/WeasyPrint/issues/1967>`_,
  `#1805 <https://github.com/Kozea/WeasyPrint/issues/1805>`_,
  `#2163 <https://github.com/Kozea/WeasyPrint/issues/2163>`_,
  `#2342 <https://github.com/Kozea/WeasyPrint/issues/2342>`_,
  `#2374 <https://github.com/Kozea/WeasyPrint/issues/2374>`_,
  `#1109 <https://github.com/Kozea/WeasyPrint/issues/1109>`_,
  `#1356 <https://github.com/Kozea/WeasyPrint/issues/1356>`_,
  `#1327 <https://github.com/Kozea/WeasyPrint/issues/1327>`_,
  `#1563 <https://github.com/Kozea/WeasyPrint/issues/1563>`_,
  `#1652 <https://github.com/Kozea/WeasyPrint/issues/1652>`_,
  `#2351 <https://github.com/Kozea/WeasyPrint/issues/2351>`_,
  `#2312 <https://github.com/Kozea/WeasyPrint/issues/2312>`_,
  `#2340 <https://github.com/Kozea/WeasyPrint/issues/2340>`_,
  `#1311 <https://github.com/Kozea/WeasyPrint/issues/1311>`_,
  `#2066 <https://github.com/Kozea/WeasyPrint/issues/2066>`_,
  `#2359 <https://github.com/Kozea/WeasyPrint/issues/2359>`_,
  `#2053 <https://github.com/Kozea/WeasyPrint/issues/2053>`_:
  Improve Flex layout, with financial support from NLnet.
* `#1686 <https://github.com/Kozea/WeasyPrint/issues/1686>`_,
  `#2404 <https://github.com/Kozea/WeasyPrint/pull/2404>`_:
  Fix duplicate text selection with right-to-left text
* `#2372 <https://github.com/Kozea/WeasyPrint/issues/2372>`_,
  `#2389 <https://github.com/Kozea/WeasyPrint/pull/2389>`_:
  Fix justification of right-to-left text
* `#2403 <https://github.com/Kozea/WeasyPrint/issues/2403>`_:
  Fix emoji rendering with older versions of Pango
* `#2392 <https://github.com/Kozea/WeasyPrint/issues/2392>`_:
  Fix complex cases involving nested SVG text anchors
* `#2396 <https://github.com/Kozea/WeasyPrint/issues/2396>`_,
  `#2398 <https://github.com/Kozea/WeasyPrint/pull/2398>`_:
  Fix and improve font names in PDF
* `#2269 <https://github.com/Kozea/WeasyPrint/issues/2269>`_,
  `#2390 <https://github.com/Kozea/WeasyPrint/pull/2390>`_:
  Apply justification to non-breaking spaces
* `#2362 <https://github.com/Kozea/WeasyPrint/issues/2362>`_,
  `#2387 <https://github.com/Kozea/WeasyPrint/pull/2387>`_:
  Improve Flex layout, with financial support from NLnet.

Contributors:

* Guillaume Ayoub
* Luca Vercelli

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Simon Sapin
* Manuel Barkhau
* Simonsoft
* Menutech
* KontextWork
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* DocRaptor
* Yanal-Yves Fargialla
* Method B
* FieldHub
* Morntag
* Xavid
* Kai DeLorenzo
* Charlie S.
* Alan Villalobos


Version 64.1
------------

Released on 2025-02-20.

Bug fixes:

* `#2368 <https://github.com/Kozea/WeasyPrint/issues/2368>`_:
  Fix ascent and descent font values
* `#2370 <https://github.com/Kozea/WeasyPrint/issues/2370>`_:
  Avoid endless recursion for variables in nested functions
* `#2275 <https://github.com/Kozea/WeasyPrint/issues/2275>`_:
  Use correct containing block to render waiting children
* `#2375 <https://github.com/Kozea/WeasyPrint/issues/2375>`_:
  Ensure that we handle text-anchor only on text content elements
* `#2090 <https://github.com/Kozea/WeasyPrint/issues/2090>`_:
  Only create font temporary folder when adding fonts
* `#2383 <https://github.com/Kozea/WeasyPrint/issues/2383>`_:
  Fix grid-template-areas validation and allow uppercase identifiers for grid lines

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Simon Sapin
* Manuel Barkhau
* Simonsoft
* Menutech
* KontextWork
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* DocRaptor
* Yanal-Yves Fargialla
* Method B
* FieldHub
* Morntag
* Xavid
* Kai DeLorenzo
* Charlie S.


Version 64.0
------------

Released on 2025-01-30.

Features:

* `#2338 <https://github.com/Kozea/WeasyPrint/pull/2338>`_:
  Allow custom RDF metadata for PDF/A and eInvoices
* `#123 <https://github.com/Kozea/WeasyPrint/issues/123>`_,
  `#2345 <https://github.com/Kozea/WeasyPrint/pull/2345>`_:
  Handle small-caps synthesis
* `#2343 <https://github.com/Kozea/WeasyPrint/issues/2343>`_:
  Support outline-offset
* `#2361 <https://github.com/Kozea/WeasyPrint/pull/2361>`_:
  Support text-underline-offset and text-decoration-thickness
* `#2296 <https://github.com/Kozea/WeasyPrint/issues/2296>`_:
  Don’t crash with tables with rounded corners split between pages

Bug fixes:

* `#2360 <https://github.com/Kozea/WeasyPrint/issues/2360>`_:
  Fix gradients with non-RGB colors
* `#2355 <https://github.com/Kozea/WeasyPrint/issues/2355>`_,
  `#2358 <https://github.com/Kozea/WeasyPrint/pull/2358>`_:
  Align png emojis to the surrounding text
* `#2353 <https://github.com/Kozea/WeasyPrint/issues/2353>`_:
  Fix alignment of SVG text with multiple nested text-anchor values
* `#2350 <https://github.com/Kozea/WeasyPrint/pull/2350>`_:
  Fix logging restoration in capture_logs
* `#2341 <https://github.com/Kozea/WeasyPrint/pull/2341>`_:
  Fix page groups
* `#2314 <https://github.com/Kozea/WeasyPrint/pulls/2314>`_:
  Use CSS 'image-rendering' attribute for images in SVGs
* `#2332 <https://github.com/Kozea/WeasyPrint/issues/2332>`_:
  Fix opacity for translated SVG elements
* `#2329 <https://github.com/Kozea/WeasyPrint/issues/2329>`_:
  Refactor text.line_break.get_log_attrs
* `#2325 <https://github.com/Kozea/WeasyPrint/issues/2325>`_,
  `#2326 <https://github.com/Kozea/WeasyPrint/pull/2326>`_:
  Fix table overflow edge cases

Performance:

* `#2347 <https://github.com/Kozea/WeasyPrint/issues/2347>`_,
  `#2364 <https://github.com/Kozea/WeasyPrint/pull/2364>`_:
  Improve rendering speed for text

Documentation:

* `#2352 <https://github.com/Kozea/WeasyPrint/pull/2352>`_:
  Add more use cases in documentation, use Furo theme

Contributors:

* Guillaume Ayoub
* Kesara Rathnayake
* Xavid Pretzer
* David Tagatac
* Ernesto Ruge
* Niko Abeler
* Noam Kushinsky

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Simon Sapin
* Manuel Barkhau
* Simonsoft
* Menutech
* KontextWork
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* DocRaptor
* Yanal-Yves Fargialla
* Method B
* FieldHub
* Morntag
* Xavid
* Kai DeLorenzo
* Charlie S.


Version 63.1
------------

Released on 2024-12-10.

Dependencies:

* `#2297 <https://github.com/Kozea/WeasyPrint/issues/2297>`_:
  Remove upper bounds for dependencies

Bug fixes:

* `#2300 <https://github.com/Kozea/WeasyPrint/pull/2300>`_,
  `#2292 <https://github.com/Kozea/WeasyPrint/issues/2292>`_:
  Don’t avoid floats for flex items
* `#2301 <https://github.com/Kozea/WeasyPrint/pull/2301>`_,
  `#2293 <https://github.com/Kozea/WeasyPrint/issues/2293>`_:
  Include floats in calculation of minimum cell height
* `#2303 <https://github.com/Kozea/WeasyPrint/pull/2303>`_,
  `#2302 <https://github.com/Kozea/WeasyPrint/issues/2302>`_:
  Set alpha even when current color channels didn’t change
* `#2306 <https://github.com/Kozea/WeasyPrint/issues/2306>`_:
  Don’t try to increase column width when there’s no extra width
* `#2304 <https://github.com/Kozea/WeasyPrint/issues/2304>`_:
  Don’t forget skip stack when drawing flex items
* `#2316 <https://github.com/Kozea/WeasyPrint/issues/2316>`_:
  Don’t crash with SVG symbols
* `#2320 <https://github.com/Kozea/WeasyPrint/issues/2320>`_:
  Fix currentcolor detection when parsing gradient color stops
* `#2322 <https://github.com/Kozea/WeasyPrint/pull/2322>`_,
  `#2289 <https://github.com/Kozea/WeasyPrint/issues/2289>`_:
  Don’t add DLL directories when using Windows executable
* `#2323 <https://github.com/Kozea/WeasyPrint/pull/2323>`_,
  `#2305 <https://github.com/Kozea/WeasyPrint/issues/2305>`_:
  Fix different rendering test

Performance:

* `#2319 <https://github.com/Kozea/WeasyPrint/issues/2319>`_:
  Fix memory leaks

Documentation:

* `#2299 <https://github.com/Kozea/WeasyPrint/pull/2299>`_:
  Update install instructions for Alpine
* `#2321 <https://github.com/Kozea/WeasyPrint/pull/2321>`_:
  Add example invocation of WeasyPrint on the "Contribute" page

Contributors:

* Guillaume Ayoub
* Jó Ágila Bitsch
* Lucie Anglade
* Alexander Gitter
* Luke Cousins

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Simon Sapin
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Advance Insight
* Docraptor
* Method B
* FieldHub
* Yanal-Yves Fargialla
* Morntag
* Xavid


Version 63.0
------------

Released on 2024-10-29.

Dependencies:

* Python 3.13 is now supported
* pydyf 0.11.0+ is now needed
* tinycss2 1.4.0+ is now needed
* tinyhtml5 2.0.0+ is now needed, instead of html5lib

Features:

* `#2252 <https://github.com/Kozea/WeasyPrint/pull/2252>`_,
  `#895 <https://github.com/Kozea/WeasyPrint/issues/895>`_:
  Handle page groups, with financial support from Code & Co.
* `#1630 <https://github.com/Kozea/WeasyPrint/issues/1630>`_,
  `#2286 <https://github.com/Kozea/WeasyPrint/pull/2286>`_:
  Support CSS Color Level 4
* `#2192 <https://github.com/Kozea/WeasyPrint/pull/2192>`_:
  Add PDF variant for debugging purpose
* `#2208 <https://github.com/Kozea/WeasyPrint/pull/2208>`_:
  Support submit inputs in PDF forms
* `#2139 <https://github.com/Kozea/WeasyPrint/pull/2139>`_:
  Support ``mask-border-*`` properties
* `#1831 <https://github.com/Kozea/WeasyPrint/issues/1831>`_,
  `#2143 <https://github.com/Kozea/WeasyPrint/pull/2143>`_:
  Support radio inputs in PDF forms

Bug fixes:

* `#2262 <https://github.com/Kozea/WeasyPrint/issues/2262>`_:
  Avoid integer overflows when converting units from/to doubles
* `#2260 <https://github.com/Kozea/WeasyPrint/pull/2260>`_:
  Avoid float collision with box establishing formatting context
* `#2240 <https://github.com/Kozea/WeasyPrint/issues/2240>`_,
  `#2242 <https://github.com/Kozea/WeasyPrint/pull/2242>`_:
  Handle ``svg`` tags with no size
* `#2231 <https://github.com/Kozea/WeasyPrint/pull/2231>`_,
  `#1171 <https://github.com/Kozea/WeasyPrint/issues/1171>`_,
  `#2222 <https://github.com/Kozea/WeasyPrint/issues/2222>`_,
  `#1208 <https://github.com/Kozea/WeasyPrint/issues/1208>`_:
  Fix several problems related to ``flex-direction: column``
* `#2239 <https://github.com/Kozea/WeasyPrint/issues/2239>`_:
  Don’t fail when SVG markers are undefined references
* `#2230 <https://github.com/Kozea/WeasyPrint/issues/2230>`_,
  `#2238 <https://github.com/Kozea/WeasyPrint/pull/2238>`_:
  Set explicit flags when loading DLLs on Windows
* `#2228 <https://github.com/Kozea/WeasyPrint/issues/2228>`_,
  `#1942 <https://github.com/Kozea/WeasyPrint/issues/1942>`_:
  Store original and PDF stream images in different cache slots
* `#2234 <https://github.com/Kozea/WeasyPrint/issues/2234>`_:
  Apply stylesheet and other basic operations to SVG root tag
* `#2054 <https://github.com/Kozea/WeasyPrint/issues/2054>`_,
  `#2233 <https://github.com/Kozea/WeasyPrint/pull/2233>`_:
  Keep auto margins on flex layout boxes
* `#1883 <https://github.com/Kozea/WeasyPrint/issues/1883>`_:
  Don’t crash with empty list marker strings
* `#2216 <https://github.com/Kozea/WeasyPrint/issues/2216>`_:
  Fix vertical alignment of out-of-flow elements in tables
* `#996 <https://github.com/Kozea/WeasyPrint/issues/996>`_,
  `#2219 <https://github.com/Kozea/WeasyPrint/pull/2219>`_:
  Don’t ignore absolutely positioned elements inside flex boxes
* `#2217 <https://github.com/Kozea/WeasyPrint/issues/2217>`_:
  Don’t crash with ``normal`` column gaps
* `#1817 <https://github.com/Kozea/WeasyPrint/issues/1817>`_:
  Don’t assume that lines break after spaces
* `#1868 <https://github.com/Kozea/WeasyPrint/issues/1868>`_:
  Don’t break rows with atomic cells
* `#2166 <https://github.com/Kozea/WeasyPrint/issues/2166>`_:
  Don’t display bottom border on cells in split rows
* `61852c4 <https://github.com/Kozea/WeasyPrint/commit/61852c4>`_:
  Capture fontTools logs when subsetting fonts
* `#2190 <https://github.com/Kozea/WeasyPrint/pull/2190>`_:
  Don’t use a pattern when drawing backgrounds for no-repeat background images
* `#2185 <https://github.com/Kozea/WeasyPrint/issues/2185>`_:
  Check that Harfbuzz version is at least 4.1.0 to subset fonts
* `#2180 <https://github.com/Kozea/WeasyPrint/issues/2180>`_:
  Store width for all glyphs when font is not subset
* `#2183 <https://github.com/Kozea/WeasyPrint/issues/2183>`_:
  Respect ``break-inside: avoid`` for flex items
* `#2055 <https://github.com/Kozea/WeasyPrint/issues/2055>`_,
  `#2058 <https://github.com/Kozea/WeasyPrint/pull/2058>`_:
  Fix right-to-left tables with collapsed borders
* `#2179 <https://github.com/Kozea/WeasyPrint/pull/2179>`_,
  `#1128 <https://github.com/Kozea/WeasyPrint/issues/1128>`_:
  Handle buggy Adobe Photoshop CMYK JPEGs
* `#2175 <https://github.com/Kozea/WeasyPrint/issues/2175>`_:
  Don’t compress PDF metadata for PDF/A-1
* `#2174 <https://github.com/Kozea/WeasyPrint/issues/2174>`_:
  Fix extra width distribution for auto table layout

Performance:

* `#1155 <https://github.com/Kozea/WeasyPrint/issues/1155>`_:
  Improve rendering speed for large colspan values
* `#2120 <https://github.com/Kozea/WeasyPrint/issues/2120>`_,
  `#2178 <https://github.com/Kozea/WeasyPrint/pull/2178>`_:
  Use Harfbuzz to subset fonts by default

Documentation:

* `#2282 <https://github.com/Kozea/WeasyPrint/issues/2282>`_,
  `#2284 <https://github.com/Kozea/WeasyPrint/pull/2284>`_:
  Simplify Alpine install instructions
* `#2254 <https://github.com/Kozea/WeasyPrint/issues/2254>`_:
  Add warning about antivirus false detection
* `#2220 <https://github.com/Kozea/WeasyPrint/pull/2220>`_:
  Add extra information to debug logs
* `#2211 <https://github.com/Kozea/WeasyPrint/pull/2211>`_:
  Fix link to samples
* `#2195 <https://github.com/Kozea/WeasyPrint/pull/2195>`_:
  Update cache argument documentation
* `#2105 <https://github.com/Kozea/WeasyPrint/issues/2105>`_,
  `#2151 <https://github.com/Kozea/WeasyPrint/pull/2151>`_:
  Use MSYS2 instead of GTK+3 for Windows

Contributors:

* Guillaume Ayoub
* David Huggins-Daines
* Xavid Pretzer
* Yann Trividic
* Kevin Kays
* Alejandro Avilés
* Gianluca Teti
* Gregory Goodson
* Lucie Anglade
* Roman Sirokov

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Syslifters
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Simon Sapin
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Advance Insight
* Docraptor
* Method B
* FieldHub
* Yanal-Yves Fargialla
* Morntag
* Xavid


Version 62.3
------------

Released on 2024-06-21.

Bug fixes:

* `#2174 <https://github.com/Kozea/WeasyPrint/issues/2174>`_:
  Fix extra width distribution for auto table layout
* `#2175 <https://github.com/Kozea/WeasyPrint/issues/2175>`_:
  Don’t compress PDF metadata for PDF/A-1
* `61f8bb3 <https://github.com/Kozea/WeasyPrint/commit/61f8bb3>`_:
  Set default PDF variant values in options before generating PDF
* `2c4351e <https://github.com/Kozea/WeasyPrint/commit/2c4351e>`_:
  Avoid PDF artifacts when drawing 0-width borders
* `d9d7f62 <https://github.com/Kozea/WeasyPrint/commit/d9d7f62>`_:
  Don’t duplicate column when container is split on multiple pages
* `4617b94 <https://github.com/Kozea/WeasyPrint/commit/4617b94>`_:
  Don’t set default Fontconfig values for unset properties
* `4c81663 <https://github.com/Kozea/WeasyPrint/commit/4c81663>`_:
  Fix layout when all footnotes are removed from the footnote area
* `#2184 <https://github.com/Kozea/WeasyPrint/issues/2184>`_:
  Make items overflowing grid wrap to the next row/column
* `#2187 <https://github.com/Kozea/WeasyPrint/issues/2187>`_:
  Don’t append useless tracks when grid elements are positioned

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Simon Sapin
* René Fritz
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Docraptor
* Yanal-Yves Fargialla
* Douwe van Loenen
* Morntag
* Xavid


Version 62.2
------------

Released on 2024-06-04.

Features:

* `#2142 <https://github.com/Kozea/WeasyPrint/issues/2142>`_,
  `#2162 <https://github.com/Kozea/WeasyPrint/pull/2162>`_:
  Support grid-auto-flow: column, with financial support from Menutech

Bug fixes:

* `#2167 <https://github.com/Kozea/WeasyPrint/issues/2167>`_:
  Fix space added by CSS gap at the end
* `#2134 <https://github.com/Kozea/WeasyPrint/issues/2134>`_:
  Remove absolute placeholders from discarded content
* `#2154 <https://github.com/Kozea/WeasyPrint/issues/2154>`_:
  Don’t crash when grid items have auto margins
* `8cdd66f <https://github.com/Kozea/WeasyPrint/commit/8cdd66f>`_:
  Fix CSS nesting for nested selectors with comma
* `3359db5 <https://github.com/Kozea/WeasyPrint/commit/3359db5>`_:
  Fix and test grid shorthand
* `82deda4 <https://github.com/Kozea/WeasyPrint/commit/82deda4>`_:
  Fix wrong resume_at for split floats
* `ff2acf1 <https://github.com/Kozea/WeasyPrint/commit/ff2acf1>`_:
  Ensure that gradient size is positive to please some PDF readers

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Simon Sapin
* René Fritz
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Docraptor
* Yanal-Yves Fargialla
* Douwe van Loenen
* Morntag
* Xavid


Version 62.1
------------

Released on 2024-05-06.

Bug fixes:

* `#2144 <https://github.com/Kozea/WeasyPrint/issues/2144>`_,
  `#2149 <https://github.com/Kozea/WeasyPrint/pull/2149>`_:
  Avoid broken fonts when generating multiple documents
* `c10c6892 <https://github.com/Kozea/WeasyPrint/commit/c10c6892>`_:
  Display at least one grid row on empty pages
* `#2146 <https://github.com/Kozea/WeasyPrint/issues/2146>`_:
  Don’t crash when flex container’s parent’s height is auto

Contributors:

* Guillaume Ayoub
* Claudius Ellsel

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Simon Sapin
* René Fritz
* TrainingSparkle
* Healthchecks.io
* Docraptor
* Yanal-Yves Fargialla
* Douwe van Loenen
* Morntag
* Xavid


Version 62.0
------------

Released on 2024-04-30.

Dependencies:

* Python 3.9+ is now needed, Python 3.7 and 3.8 are not supported anymore
* pydyf 0.10.0+ is now needed
* tinycss2 1.3.0+ is now needed

Features:

* `#543 <https://github.com/Kozea/WeasyPrint/issues/543>`_,
  `#2121 <https://github.com/Kozea/WeasyPrint/pull/2121>`_:
  Support CSS Grid layout
* `#2124 <https://github.com/Kozea/WeasyPrint/issues/2124>`_,
  `#2125 <https://github.com/Kozea/WeasyPrint/pull/2125>`_:
  Support border-image-* properties
* `#2084 <https://github.com/Kozea/WeasyPrint/issues/2084>`_,
  `#2077 <https://github.com/Kozea/WeasyPrint/pull/2077>`_:
  Support CSS nesting
* `#2101 <https://github.com/Kozea/WeasyPrint/issues/2101>`_:
  Support HTML maxlength attribute for form fields
* `#2095 <https://github.com/Kozea/WeasyPrint/pull/2095>`_:
  Apply overflow to replaced boxes
* `245e4f5 <https://github.com/Kozea/WeasyPrint/commit/245e4f5>`_:
  Add support of PDF/A-?u

Bug fixes:

* `#2136 <https://github.com/Kozea/WeasyPrint/issues/2136>`_:
  Don’t clip aligned text in SVG
* `#2135 <https://github.com/Kozea/WeasyPrint/pull/2135>`_:
  Allow column-direction flex containers to use percentage-based heights
* `#2128 <https://github.com/Kozea/WeasyPrint/issues/2128>`_:
  Don’t crash when a FontConfig object is destroyed early
* `#2079 <https://github.com/Kozea/WeasyPrint/issues/2079>`_:
  Fix executable file for some Windows versions
* `#2131 <https://github.com/Kozea/WeasyPrint/issues/2131>`_:
  Fix alpha for images before/after transparent text
* `#2111 <https://github.com/Kozea/WeasyPrint/issues/2111>`_:
  Handle auto and none values for CSS quotes property
* `#2103 <https://github.com/Kozea/WeasyPrint/issues/2103>`_:
  Don’t crash with overconstrained columns
* `#2100 <https://github.com/Kozea/WeasyPrint/issues/2100>`_:
  Fix rounding error when detecting overflows
* `#2093 <https://github.com/Kozea/WeasyPrint/issues/2093>`_,
  `#2097 <https://github.com/Kozea/WeasyPrint/issues/2097>`_,
  `#2094 <https://github.com/Kozea/WeasyPrint/pull/2094>`_:
  Mark use of md5() and sha1() as not for security
* `#1956 <https://github.com/Kozea/WeasyPrint/issues/1956>`_,
  `#2087 <https://github.com/Kozea/WeasyPrint/pull/2087>`_:
  Use CSS table module level 3 to compute widths
* `#2086 <https://github.com/Kozea/WeasyPrint/pull/2086>`_:
  Fix selects with empty values displaying None
* `#1112 <https://github.com/Kozea/WeasyPrint/issues/1112>`_,
  `#2082 <https://github.com/Kozea/WeasyPrint/issues/2082>`_,
  `#2085 <https://github.com/Kozea/WeasyPrint/pull/2085>`_:
  Fix computation for outer min-content width for table cells
* `016bd81 <https://github.com/Kozea/WeasyPrint/commit/016bd81>`_:
  Fix many different bugs with SVG markers

Performance:

* `#2130 <https://github.com/Kozea/WeasyPrint/issues/2130>`_:
  Cache font key instead of whole font content

Documentation:

* `#2108 <https://github.com/Kozea/WeasyPrint/pull/2108>`_:
  Update documentation about CSS leader() function

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Xavid Pretzer
* kygoh
* Germain Gueutier
* Vagner José Nicolodi

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Simon Sapin
* René Fritz
* TrainingSparkle
* Healthchecks.io
* Docraptor
* Yanal-Yves Fargialla
* Douwe van Loenen
* Morntag
* Xavid


Version 61.2
------------

Released on 2024-03-08.

**This is a security update.**

We strongly recommend to upgrade WeasyPrint to the latest version if you use
WeasyPrint 61.0 or 61.1. Older versions are not impacted.

Security:

- Always use URL fetcher for attachments

Contributors:

* Guillaume Ayoub
* Ilia Novoselov

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* René Fritz
* Simon Sapin
* Arcanite
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Docraptor
* Yanal-Yves Fargialla
* Morntag
* NBCO


Version 61.1
------------

Released on 2024-02-26.

Bug fixes:

- `#2075 <https://github.com/Kozea/WeasyPrint/issues/2075>`_:
  Use default value when variable is not defined
- `#2070 <https://github.com/Kozea/WeasyPrint/issues/2070>`_:
  Don’t crash when rendering SVGs with non-text a children
- Don’t crash when SVG file can’t be rendered

Documentation:

- `#2067 <https://github.com/Kozea/WeasyPrint/pull/2067>`_:
  Suggest "dnf" instead of "yum" to install Fedora packages
- Improve documentation for Windows
- Fix required version of TinyCSS2

Contributors:

* Guillaume Ayoub
* Felix Schwarz
* Lucie Anglade

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* René Fritz
* Simon Sapin
* Arcanite
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Docraptor
* Yanal-Yves Fargialla
* Morntag
* NBCO


Version 61.0
------------

Released on 2024-02-12.

Python API:

* ``DocumentMetadata.attachments`` is now a list of ``Attachment`` objects, not
  a list of ``(url, description)`` tuples.

New features:

* `#1219 <https://github.com/Kozea/WeasyPrint/issues/1219>`_,
  `#2017 <https://github.com/Kozea/WeasyPrint/pull/2017>`_:
  Support var() in shorthand and multiple-value functions
* `#1986 <https://github.com/Kozea/WeasyPrint/issues/1986>`_:
  Support percentages for opacity
* `#2050 <https://github.com/Kozea/WeasyPrint/pull/2050>`_:
  Build executable file for Windows
* `#2000 <https://github.com/Kozea/WeasyPrint/pull/2000>`_:
  Support select fields
* `#1993 <https://github.com/Kozea/WeasyPrint/issues/1993>`_:
  Handle background-attachment: fixed to cover the whole page
* `#2023 <https://github.com/Kozea/WeasyPrint/issues/2023>`_,
  `#2022 <https://github.com/Kozea/WeasyPrint/pull/2022>`_:
  Allow text-based file objects for HTML and CSS classes
* `#2014 <https://github.com/Kozea/WeasyPrint/pull/2014>`_:
  Remove warnings for PDF/A and PDF/UA compatibility

Bug fixes:

* `#2052 <https://github.com/Kozea/WeasyPrint/issues/2052>`_,
  `#1869 <https://github.com/Kozea/WeasyPrint/pull/1869>`_:
  Handle attachments for PDF/A documents
* `#2013 <https://github.com/Kozea/WeasyPrint/issues/2013>`_,
  `#2051 <https://github.com/Kozea/WeasyPrint/pull/2051>`_:
  Apply margin to running tables
* `#1278 <https://github.com/Kozea/WeasyPrint/issues/1278>`_,
  `#1884 <https://github.com/Kozea/WeasyPrint/pull/1884>`_:
  Draw collapsed borders of running tables
* `#2029 <https://github.com/Kozea/WeasyPrint/issues/2029>`_:
  Fix page counter in non-root absolute boxes
* `#2043 <https://github.com/Kozea/WeasyPrint/pull/2043>`_:
  Fix text-anchor on SVG tspan elements
* `#1968 <https://github.com/Kozea/WeasyPrint/issues/1968>`_,
  `#2039 <https://github.com/Kozea/WeasyPrint/pull/2039>`_:
  Use cell's border-height to calculate table row height
* `#2030 <https://github.com/Kozea/WeasyPrint/issues/2030>`_:
  Ensure that bounding box is set to invisible text tags
* `#2040 <https://github.com/Kozea/WeasyPrint/issues/2040>`_,
  `#2041 <https://github.com/Kozea/WeasyPrint/pull/2041>`_:
  Don’t crash on malformed URLs
* `#2026 <https://github.com/Kozea/WeasyPrint/issues/2026>`_:
  Don’t break pages when fixed-height elements don’t overflow page
* `#2038 <https://github.com/Kozea/WeasyPrint/issues/2038>`_:
  Don’t mix original streams when drawing transparent text
* `#2016 <https://github.com/Kozea/WeasyPrint/issues/2016>`_:
  Avoid duplication when breaking out-of-flow boxes
* `#2012 <https://github.com/Kozea/WeasyPrint/issues/2012>`_:
  Don’t crash when CSS properties have no value
* `#2010 <https://github.com/Kozea/WeasyPrint/issues/2010>`_,
  `#1287 <https://github.com/Kozea/WeasyPrint/issues/1287>`_:
  Fix many corner cases with CSS variables
* `#1996 <https://github.com/Kozea/WeasyPrint/issues/1996>`_:
  Don’t crash when drawing groove/ridge collapsed borders
* `#1982 <https://github.com/Kozea/WeasyPrint/issues/1982>`_:
  Fix SVG markers size, position and drawing

Documentation:

* `#2021 <https://github.com/Kozea/WeasyPrint/issues/2021>`_,
  `#2048 <https://github.com/Kozea/WeasyPrint/pull/2048>`_:
  Replace non-virtualenv installation instructions with distribution packages

Contributors:

* Guillaume Ayoub
* kygoh
* Lucie Anglade
* Timo Ramsauer
* Alexander Gitter
* Michael Lisitsa
* Vagner José Nicolodi
* Manolis Stamatogiannakis
* Pascal de Bruijn
* Viktor Shevtsov
* Eduardo Gonzalez
* Kesara Rathnayake

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* René Fritz
* Simon Sapin
* Arcanite
* TrainingSparkle
* Healthchecks.io
* Hammerbacher
* Docraptor
* Yanal-Yves Fargialla
* Morntag
* NBCO


Version 60.2
------------

Released on 2023-12-11.

Bug fixes:

* `#1982 <https://github.com/Kozea/WeasyPrint/issues/1982>`_:
  Fix SVG markers size, position and drawing
* `23cfc775 <https://github.com/Kozea/WeasyPrint/commit/23cfc775>`_:
  Draw background behind absolutely positioned replaced boxes
* `fe2f0c69 <https://github.com/Kozea/WeasyPrint/commit/fe2f0c69>`_:
  Don’t crash with bitmap fonts with no "glyf" table
* `14605225 <https://github.com/Kozea/WeasyPrint/commit/14605225>`_:
  Improve SVG text-anchor attribute

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Nicola Auchmuty
* Syslifters
* Hammerbacher
* TrainingSparkle
* Daniel Kucharski
* Healthchecks.io
* Yanal-Yves Fargialla
* WakaTime
* Paheko
* Synapsium
* DocRaptor


Version 60.1
------------

Released on 2023-09-29.

Bug fixes:

* `#1973 <https://github.com/Kozea/WeasyPrint/issues/1973>`_:
  Fix crash caused by wrong UTF-8 indices

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Nicola Auchmuty
* Syslifters
* Hammerbacher
* TrainingSparkle
* Daniel Kucharski
* Healthchecks.io
* Yanal-Yves Fargialla
* WakaTime
* Paheko
* Synapsium
* DocRaptor


Version 60.0
------------

Released on 2023-09-25.

New features:

* `#1903 <https://github.com/Kozea/WeasyPrint/issues/1903>`_:
  Print form fields
* `#1922 <https://github.com/Kozea/WeasyPrint/pull/1922>`_:
  Add support for textLength and lengthAdjust in SVG text elements
* `#1965 <https://github.com/Kozea/WeasyPrint/issues/1965>`_:
  Handle <wbr> tag
* `#1970 <https://github.com/Kozea/WeasyPrint/pull/1970>`_:
  Handle y offset of glyphs
* `#1909 <https://github.com/Kozea/WeasyPrint/issues/1909>`_:
  Add a --timeout option

Bug fixes:

* `#1887 <https://github.com/Kozea/WeasyPrint/pull/1887>`_:
  Fix footnote-call displayed incorrectly for some fonts
* `#1890 <https://github.com/Kozea/WeasyPrint/pull/1890>`_:
  Fix page-margin boxes layout algorithm
* `#1908 <https://github.com/Kozea/WeasyPrint/pull/1908>`_:
  Fix IndexError when rendering PDF version 1.4
* `#1906 <https://github.com/Kozea/WeasyPrint/issues/1906>`_:
  Apply text transformations to first-letter pseudo elements
* `#1915 <https://github.com/Kozea/WeasyPrint/pull/1915>`_:
  Avoid footnote appearing before its call
* `#1934 <https://github.com/Kozea/WeasyPrint/pull/1934>`_:
  Fix balance before "column-span: all"
* `#1935 <https://github.com/Kozea/WeasyPrint/issues/1935>`_:
  Only draw required glyph with OpenType-SVG fonts
* `#1595 <https://github.com/Kozea/WeasyPrint/issues/1595>`_:
  Don’t draw clipPath when defined after reference
* `#1895 <https://github.com/Kozea/WeasyPrint/pull/1895>`_:
  Don’t ignore min-width when computing cell size
* `#1899 <https://github.com/Kozea/WeasyPrint/pull/1899>`_:
  Fix named pages inheritance
* `#1936 <https://github.com/Kozea/WeasyPrint/pull/1936>`_:
  Avoid page breaks caused by children of overflow hidden boxes
* `#1943 <https://github.com/Kozea/WeasyPrint/issues/1943>`_:
  Use bleed area for page’s painting area
* `#1946 <https://github.com/Kozea/WeasyPrint/issues/1946>`_:
  Use margin box of children to define available width for leaders

Contributors:

* Guillaume Ayoub
* Sahil Rohilla
* Azharuddin Syed
* kygoh
* Andy Lenards
* Gaurav Samudra
* Michael Wedl
* Lucie Anglade
* Obeida Shamoun
* Evgeniy Krysanov

Backers and sponsors:

* Spacinov
* Kobalt
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Nicola Auchmuty
* Syslifters
* Hammerbacher
* TrainingSparkle
* Daniel Kucharski
* Healthchecks.io
* Yanal-Yves Fargialla
* WakaTime
* Paheko
* Synapsium
* DocRaptor


Version 59.0
------------

Released on 2023-05-11.

This version also includes the changes from unstable b1 version listed
below.

Bug fixes:

* `#1864 <https://github.com/Kozea/WeasyPrint/issues/1864>`_:
  Handle overflow for svg and symbol tags in SVG images
* `#1867 <https://github.com/Kozea/WeasyPrint/pull/1867>`_:
  Remove duplicate compression of attachments
* `d0ad5c1 <https://github.com/Kozea/WeasyPrint/commit/d0ad5c1>`_:
  Override use tag children instead of drawing their references
* `93df1a5 <https://github.com/Kozea/WeasyPrint/commit/93df1a5>`_:
  Don’t resize the same image twice when the --dpi option is set
* `#1874 <https://github.com/Kozea/WeasyPrint/pull/1874>`_:
  Drawn underline and overline behind text

Contributors:

* Guillaume Ayoub
* Timo Ramsauer
* Alexander Mankuta

Backers and sponsors:

* Castedo Ellerman
* Kobalt
* Spacinov
* Grip Angebotssoftware
* Crisp BV
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Moritz Mahringer
* Yanal-Yves Fargialla
* Piotr Horzycki
* Healthchecks.io
* TrainingSparkle
* Hammerbacher
* Synapsium


Version 59.0b1
--------------

Released on 2023-04-14.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Command-line API:

* The ``--optimize-size`` option and its short equivalent ``-O`` have been
  deprecated. To activate or deactivate different size optimizations, you can
  now use:

  * ``--uncompressed-pdf``,
  * ``--optimize-images``,
  * ``--full-fonts``,
  * ``--hinting``,
  * ``--dpi <resolution>``, and
  * ``--jpeg-quality <quality>``.

* A new ``--cache-folder <folder>`` option has been added to store temporary
  data in the given folder on the disk instead of keeping them in memory.

Python API:

* Global rendering options are now given in ``**options`` instead of dedicated
  parameters, with slightly different names. It means that the signature of the
  ``HTML.render()``, ``HTML.write_pdf()`` and ``Document.write_pdf()`` has
  changed. Here are the steps to port your Python code to v59.0:

  1. Use named parameters for these functions, not positioned parameters.
  2. Rename some the parameters:

     * ``image_cache`` becomes ``cache`` (see below),
     * ``identifier`` becomes ``pdf_identifier``,
     * ``variant`` becomes ``pdf_variant``,
     * ``version`` becomes ``pdf_version``,
     * ``forms`` becomes ``pdf_forms``.

* The ``optimize_size`` parameter of ``HTML.render()``, ``HTML.write_pdf()``
  and ``Document()`` has been removed and will be ignored. You can now use the
  ``uncompressed_pdf``, ``full_fonts``, ``hinting``, ``dpi`` and
  ``jpeg_quality`` parameters that are included in ``**options``.

* The ``cache`` parameter can be included in ``**options`` to replace
  ``image_cache``. If it is a dictionary, this dictionary will be used to store
  temporary data in memory, and can be even shared between multiple documents.
  If it’s a folder Path or string, WeasyPrint stores temporary data in the
  given temporary folder on disk instead of keeping them in memory.

New features:

* `#1853 <https://github.com/Kozea/WeasyPrint/pull/1853>`_,
  `#1854 <https://github.com/Kozea/WeasyPrint/issues/1854>`_:
  Reduce PDF size, with financial support from Code & Co.
* `#1824 <https://github.com/Kozea/WeasyPrint/issues/1824>`_,
  `#1829 <https://github.com/Kozea/WeasyPrint/pull/1829>`_:
  Reduce memory use for images
* `#1858 <https://github.com/Kozea/WeasyPrint/issues/1858>`_:
  Add an option to keep hinting information in embedded fonts

Bug fixes:

* `#1855 <https://github.com/Kozea/WeasyPrint/issues/1855>`_:
  Fix position of emojis in justified text
* `#1852 <https://github.com/Kozea/WeasyPrint/issues/1852>`_:
  Don’t crash when line can be split before trailing spaces
* `#1843 <https://github.com/Kozea/WeasyPrint/issues/1843>`_:
  Fix syntax of dates in metadata
* `#1827 <https://github.com/Kozea/WeasyPrint/issues/1827>`_,
  `#1832 <https://github.com/Kozea/WeasyPrint/pull/1832>`_:
  Fix word-spacing problems with nested tags

Documentation:

* `#1841 <https://github.com/Kozea/WeasyPrint/issues/1841>`_:
  Add a paragraph about unsupported calc() function

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Alex Ch
* whi_ne
* Jonas Castro

Backers and sponsors:

* Castedo Ellerman
* Kobalt
* Spacinov
* Grip Angebotssoftware
* Crisp BV
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Moritz Mahringer
* Yanal-Yves Fargialla
* Piotr Horzycki
* Healthchecks.io
* TrainingSparkle
* Hammerbacher
* Synapsium


Version 58.1
------------

Released on 2023-03-07.

Bug fixes:

* `#1815 <https://github.com/Kozea/WeasyPrint/issues/1815>`_:
  Fix bookmarks coordinates
* `#1822 <https://github.com/Kozea/WeasyPrint/issues/1822>`_,
  `#1823 <https://github.com/Kozea/WeasyPrint/pull/1823>`_:
  Fix vertical positioning for absolute replaced elements

Documentation:

* `#1814 <https://github.com/Kozea/WeasyPrint/pull/1814>`_:
  Fix broken link pointing to samples

Contributors:

* Guillaume Ayoub
* Jonas Castro
* Lucie Anglade
* Menelaos Kotoglou

Backers and sponsors:

* Kobalt
* Grip Angebotssoftware
* Spacinov
* Crisp BV
* Castedo Ellerman
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Moritz Mahringer
* Yanal-Yves Fargialla
* Piotr Horzycki
* Healthchecks.io
* Hammerbacher
* TrainingSparkle
* Synapsium


Version 58.0
------------

Released on 2023-02-17.

This version also includes the changes from unstable b1 version listed
below.

Bug fixes:

* `#1807 <https://github.com/Kozea/WeasyPrint/issues/1807>`_:
  Don’t crash when out-of-flow box is split in out-of-flow parent
* `#1806 <https://github.com/Kozea/WeasyPrint/issues/1806>`_:
  Don’t crash when fixed elements aren’t displayed yet in aborted line
* `#1809 <https://github.com/Kozea/WeasyPrint/issues/1809>`_:
  Fix background drawing for out-of-the-page transformed boxes

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Kobalt
* Grip Angebotssoftware
* Crisp BV
* Spacinov
* Castedo Ellerman
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Moritz Mahringer
* Yanal-Yves Fargialla
* Piotr Horzycki
* Healthchecks.io


Version 58.0b1
--------------

Released on 2023-02-03.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

New features:

* `#61 <https://github.com/Kozea/WeasyPrint/issues/61>`_,
  `#1796 <https://github.com/Kozea/WeasyPrint/pull/1796>`_:
  Support PDF forms, with financial support from Personalkollen
* `#1173 <https://github.com/Kozea/WeasyPrint/issues/1173>`_:
  Add style for form fields

Bug fixes:

* `#1777 <https://github.com/Kozea/WeasyPrint/issues/1777>`_:
  Detect JPEG/MPO images as normal JPEG files
* `#1771 <https://github.com/Kozea/WeasyPrint/pull/1771>`_:
  Improve SVG gradients

Contributors:

* Guillaume Ayoub
* Lucie Anglade

Backers and sponsors:

* Kobalt
* Grip Angebotssoftware
* Crisp BV
* Spacinov
* Castedo Ellerman
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* NCC Group
* René Fritz
* Moritz Mahringer
* Yanal-Yves Fargialla
* Piotr Horzycki
* Healthchecks.io


Version 57.2
------------

Released on 2022-12-23.

Bug fixes:

* `0f2e377 <https://github.com/Kozea/WeasyPrint/commit/0f2e377>`_:
  Print annotations with PDF/A
* `0e9426f <https://github.com/Kozea/WeasyPrint/commit/0e9426f>`_:
  Hide annotations with PDF/UA
* `#1764 <https://github.com/Kozea/WeasyPrint/issues/1764>`_:
  Use reference instead of stream for annotation appearance stream
* `#1783 <https://github.com/Kozea/WeasyPrint/pull/1783>`_:
  Fix multiple font weights for @font-face declarations

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Tom Pohl
* Castedo Ellerman
* Moritz Mahringer
* Piotr Horzycki
* Gábor Nyers
* Sidharth Kapur


Version 57.1
------------

Released on 2022-11-04.

Dependencies:

* `#1754 <https://github.com/Kozea/WeasyPrint/pull/1754>`_:
  Pillow 9.1.0 is now needed

Bug fixes:

* `#1756 <https://github.com/Kozea/WeasyPrint/pull/1756>`_:
  Fix rem font size for SVG images
* `#1755 <https://github.com/Kozea/WeasyPrint/issues/1755>`_:
  Keep format when transposing images
* `#1753 <https://github.com/Kozea/WeasyPrint/issues/1753>`_:
  Don’t use deprecated ``read_text`` function when ``files`` is available
* `#1741 <https://github.com/Kozea/WeasyPrint/issues/1741>`_:
  Generate better manpage
* `#1747 <https://github.com/Kozea/WeasyPrint/issues/1747>`_:
  Correctly set target counters in pages’ absolute elements
* `#1748 <https://github.com/Kozea/WeasyPrint/issues/1748>`_:
  Always set font size when font is changed in line
* `2b05137 <https://github.com/Kozea/WeasyPrint/commit/2b05137>`_:
  Fix stability of font identifiers

Documentation:

* `#1750 <https://github.com/Kozea/WeasyPrint/pull/1750>`_:
  Fix documentation spelling

Contributors:

* Guillaume Ayoub
* Eli Schwartz
* Mikhail Anikin
* Scott Kitterman

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Tom Pohl
* John R Ellis
* Castedo Ellerman
* Moritz Mahringer
* Gábor
* Piotr Horzycki


Version 57.0
------------

Released on 2022-10-18.

This version also includes the changes from unstable b1 version listed
below.

New features:

* `a4fc7a1 <https://github.com/Kozea/WeasyPrint/commit/a4fc7a1>`_:
  Support image-orientation

Bug fixes:

* `#1739 <https://github.com/Kozea/WeasyPrint/issues/1739>`_:
  Set baseline on all flex containers
* `#1740 <https://github.com/Kozea/WeasyPrint/issues/1740>`_:
  Don’t crash when currentColor is set on root svg tag
* `#1718 <https://github.com/Kozea/WeasyPrint/issues/1718>`_:
  Don’t crash with empty bitmap glyphs
* `#1736 <https://github.com/Kozea/WeasyPrint/issues/1736>`_:
  Always use the font’s vector variant when possible
* `eef8b4d <https://github.com/Kozea/WeasyPrint/commit/eef8b4d>`_:
  Always set color and state before drawing
* `#1662 <https://github.com/Kozea/WeasyPrint/issues/1662>`_:
  Use a stable key to store stream fonts
* `#1733 <https://github.com/Kozea/WeasyPrint/issues/1733>`_:
  Don’t remove attachments when adding internal anchors
* `3c4fa50 <https://github.com/Kozea/WeasyPrint/commit/3c4fa50>`_,
  `c215697 <https://github.com/Kozea/WeasyPrint/commit/c215697>`_,
  `d275dac <https://github.com/Kozea/WeasyPrint/commit/d275dac>`_,
  `b04bfff <https://github.com/Kozea/WeasyPrint/commit/b04bfff>`_:
  Fix many bugs related to PDF/UA structure

Performance:

* `dfccf1b <https://github.com/Kozea/WeasyPrint/commit/dfccf1b>`_:
  Use faces as fonts dictionary keys
* `0dc12b6 <https://github.com/Kozea/WeasyPrint/commit/0dc12b6>`_:
  Cache add_font to avoid calling get_face too often
* `75e17bf <https://github.com/Kozea/WeasyPrint/commit/75e17bf>`_:
  Don’t call process_whitespace twice on many children
* `498d3e1 <https://github.com/Kozea/WeasyPrint/commit/498d3e1>`_:
  Optimize __missing__ functions

Documentation:

* `863b3d6 <https://github.com/Kozea/WeasyPrint/commit/863b3d6>`_:
  Update documentation of installation on macOS with Homebrew

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Tom Pohl
* John R Ellis
* Castedo Ellerman
* Moritz Mahringer
* Gábor
* Piotr Horzycki


Version 57.0b1
--------------

Released on 2022-09-22.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

New features:

* `#1704 <https://github.com/Kozea/WeasyPrint/pull/1704>`_:
  Support PDF/UA, with financial support from Novareto
* `#1454 <https://github.com/Kozea/WeasyPrint/issues/1454>`_:
  Support variable fonts

Bug fixes:

* `#1058 <https://github.com/Kozea/WeasyPrint/issues/1058>`_:
  Fix bullet position after page break, with financial support from OpenZeppelin
* `#1707 <https://github.com/Kozea/WeasyPrint/issues/1707>`_:
  Fix footnote positioning in multicolumn layout, with financial support from Code & Co.
* `#1722 <https://github.com/Kozea/WeasyPrint/issues/1722>`_:
  Handle skew transformation with only one parameter
* `#1715 <https://github.com/Kozea/WeasyPrint/issues/1715>`_:
  Don’t crash when images are truncated
* `#1697 <https://github.com/Kozea/WeasyPrint/issues/1697>`_:
  Don’t crash when attr() is used in text-decoration-color
* `#1695 <https://github.com/Kozea/WeasyPrint/pull/1695>`_:
  Include language information in PDF metadata
* `#1612 <https://github.com/Kozea/WeasyPrint/issues/1612>`_:
  Don’t lowercase letters when capitalizing text
* `#1700 <https://github.com/Kozea/WeasyPrint/issues/1700>`_:
  Fix crash when rendering footnote with repagination
* `#1667 <https://github.com/Kozea/WeasyPrint/issues/1667>`_:
  Follow EXIF metadata for image rotation
* `#1669 <https://github.com/Kozea/WeasyPrint/issues/1669>`_:
  Take care of floats when remvoving placeholders
* `#1638 <https://github.com/Kozea/WeasyPrint/issues/1638>`_:
  Use the original box when breaking waiting children

Contributors:

* Guillaume Ayoub
* Konstantin Weddige
* VeteraNovis
* Lucie Anglade

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Tom Pohl
* John R Ellis
* Moritz Mahringer
* Gábor
* Piotr Horzycki
* Andrew Ittner


Version 56.1
------------

Released on 2022-07-24.

Bug fixes:

* `#1674 <https://github.com/Kozea/WeasyPrint/issues/1674>`_:
  Follow max-height on footnot area, with financial support from Code & Co.
* `#1678 <https://github.com/Kozea/WeasyPrint/issues/1678>`_:
  Fix gradients with opacity set

Contributors:

* Guillaume Ayoub
* Lucie Anglade

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki
* Andrew Ittner


Version 56.0
------------

Released on 2022-07-07.

This version also includes the changes from unstable b1 version listed
below.

New features:

* `70f9b62 <https://github.com/Kozea/WeasyPrint/commit/70f9b62>`_:
  Support format 5 for bitmap glyphs

Bug fixes:

* `#1666 <https://github.com/Kozea/WeasyPrint/issues/1666>`_
  Fix reproducible PDF generation with embedded images
* `#1668 <https://github.com/Kozea/WeasyPrint/issues/1668>`_:
  Fix @page:nth() selector
* `3bd9a8e <https://github.com/Kozea/WeasyPrint/commit/3bd9a8e>`_:
  Don’t limit the opacity groups to the original box size
* `cb9540b <https://github.com/Kozea/WeasyPrint/commit/cb9540b>`_,
  `76d174f <https://github.com/Kozea/WeasyPrint/commit/76d174f>`_,
  `9ce6547 <https://github.com/Kozea/WeasyPrint/commit/9ce6547>`_:
  Minor bugfixes for split table rows

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Des images et des mots
* Andreas Zettl
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki


Version 56.0b1
--------------

Released on 2022-06-17.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Dependencies:

* pydyf 0.2.0+ is now needed

New features:

* `#1660 <https://github.com/Kozea/WeasyPrint/pull/1660>`_:
  Support nested line-clamp, with financial support from Expert Germany
* `#1644 <https://github.com/Kozea/WeasyPrint/pull/1644>`_,
  `#1645 <https://github.com/Kozea/WeasyPrint/issues/1645>`_:
  Support bitmap fonts, with financial support from Expert Germany
* `#1651 <https://github.com/Kozea/WeasyPrint/pull/1651>`_,
  `#630 <https://github.com/Kozea/WeasyPrint/issues/630>`_:
  Support PDF/A, with financial support from Blueshoe

Bug fixes:

* `#1656 <https://github.com/Kozea/WeasyPrint/issues/1656>`_:
  Fix chained variables in the same selector block
* `#1028 <https://github.com/Kozea/WeasyPrint/issues/1028>`_:
  Fix font weight management in @font-face rules
* `#1653 <https://github.com/Kozea/WeasyPrint/issues/1653>`_:
  Don’t crash when @font-face’s src ends with a comma
* `#1650 <https://github.com/Kozea/WeasyPrint/issues/1650>`_:
  Don’t check origin when URL only contains fragment
* `e38bff8 <https://github.com/Kozea/WeasyPrint/commit/e38bff8>`_:
  Don’t crash when inherited SVG attributes are not set on the parent

Performance:

* `e6021da <https://github.com/Kozea/WeasyPrint/commit/e6021da>`_:
  Launch tests in parallel by default

Contributors:

* Guillaume Ayoub
* aschmitz
* Lucie Anglade

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Des images et des mots
* Andreas Zettl
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki


Version 55.0
------------

Released on 2022-05-12.

This version also includes the changes from unstable b1 version listed
below.

Bug fixes:

* `#1626 <https://github.com/Kozea/WeasyPrint/issues/1626>`_,
  `3802f88 <https://github.com/Kozea/WeasyPrint/commit/3802f88>`_:
  Fix the vertical position and available height of absolute boxes
* `9641098 <https://github.com/Kozea/WeasyPrint/commit/9641098>`_,
  `e5e6b88 <https://github.com/Kozea/WeasyPrint/commit/e5e6b88>`_:
  Minor fixes for multi-column layout
* `0fcc7de <https://github.com/Kozea/WeasyPrint/commit/0fcc7de>`_:
  Don’t stop rendering SVG when CSS parsing fails
* `#1636 <https://github.com/Kozea/WeasyPrint/pull/1636>`_:
  Fix sequential footnotes that could disappear when overflowing
* `#1637 <https://github.com/Kozea/WeasyPrint/issues/1637>`_:
  Fix position of absolute boxes with right-to-left direction
* `#1641 <https://github.com/Kozea/WeasyPrint/issues/1641>`_:
  Fix relative paths for SVG files stored as data URLs

Contributors:

* Guillaume Ayoub
* aschmitz

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* Spacinov
* KontextWork
* René Fritz
* NCC Group
* Kobalt
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki


Version 55.0b1
--------------

Released on 2022-04-15.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Dependencies:

* Python 3.7+ is now needed, Python 3.6 is not supported anymore

New features:

* `#1534 <https://github.com/Kozea/WeasyPrint/pull/1534>`_:
  Support ``word-break: break-all``
* `#489 <https://github.com/Kozea/WeasyPrint/issues/489>`_,
  `#1619 <https://github.com/Kozea/WeasyPrint/pull/1619>`_:
  Support column breaks
* `#1553 <https://github.com/Kozea/WeasyPrint/issues/1553>`_:
  Allow reproducible PDF generation

Bug fixes:

* `#1007 <https://github.com/Kozea/WeasyPrint/issues/1007>`_,
  `#1524 <https://github.com/Kozea/WeasyPrint/pull/1524>`_:
  Handle ``inherit`` in shorthand properties
* `#1539 <https://github.com/Kozea/WeasyPrint/issues/1539>`_,
  `#1541 <https://github.com/Kozea/WeasyPrint/pull/1541>`_:
  Space out no-repeat patterns
* `#1554 <https://github.com/Kozea/WeasyPrint/pull/1554>`_:
  Avoid invalid PDF operators when drawing SVG text
* `#1564 <https://github.com/Kozea/WeasyPrint/issues/1564>`_,
  `#1566 <https://github.com/Kozea/WeasyPrint/pull/1566>`_,
  `#1570 <https://github.com/Kozea/WeasyPrint/pull/1570>`_:
  Don’t output footnotes before their call sites
* `#1020 <https://github.com/Kozea/WeasyPrint/issues/1020>`_,
  `#1597 <https://github.com/Kozea/WeasyPrint/pull/1597>`_:
  Prevent infinite loops in multi-column layout
* `#1512 <https://github.com/Kozea/WeasyPrint/issues/1512>`_,
  `#1613 <https://github.com/Kozea/WeasyPrint/pull/1613>`_:
  Fix position of absolute boxes in right-to-left contexts
* `#1093 <https://github.com/Kozea/WeasyPrint/issues/1093>`_:
  Draw borders around absolute replaced boxes
* `#984 <https://github.com/Kozea/WeasyPrint/issues/984>`_,
  `#1604 <https://github.com/Kozea/WeasyPrint/issues/1604>`_:
  Fix skip stacks for columns
* `#1621 <https://github.com/Kozea/WeasyPrint/issues/1621>`_:
  Better support of nested ``text-decoration`` properties
* `fe1f3d9 <https://github.com/Kozea/WeasyPrint/commit/fe1f3d9>`_:
  Fix absolute blocks in lines
* `4650b70 <https://github.com/Kozea/WeasyPrint/commit/4650b70>`_:
  Clear adjoining margins when a container’s child doesn’t fit

Performance:

* `#1548 <https://github.com/Kozea/WeasyPrint/pull/1548>`_:
  Improve tests speed
* `3b0ae92 <https://github.com/Kozea/WeasyPrint/commit/3b0ae92>`_,
  `#1457 <https://github.com/Kozea/WeasyPrint/issues/1457>`_:
  Improve fonts management
* `#1597 <https://github.com/Kozea/WeasyPrint/pull/1597>`_:
  Improve column layout speed
* `#1587 <https://github.com/Kozea/WeasyPrint/pull/1587>`_,
  `#1607 <https://github.com/Kozea/WeasyPrint/pull/1607>`_,
  `#1608 <https://github.com/Kozea/WeasyPrint/pull/1608>`_:
  Cache ``ch`` and ``ex`` units calculations

Contributors:

* Guillaume Ayoub
* aschmitz
* Lucie Anglade
* Christoph Kepper
* Jack Lin
* Rian McGuire

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* KontextWork
* Maykin Media
* René Fritz
* NCC Group
* Spacinov
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Kobalt
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki
* DeivGuerrero


Version 54.3
------------

Released on 2022-04-04.

Bug fixes:

* `#1588 <https://github.com/Kozea/WeasyPrint/pull/1588>`_:
  Support position: absolute in footnotes
* `#1586 <https://github.com/Kozea/WeasyPrint/issues/1586>`_:
  Fix discarded text-align values

Contributors:

* aschmitz
* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* KontextWork
* Maykin Media
* René Fritz
* NCC Group
* Spacinov
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Kobalt
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki
* DeivGuerrero


Version 54.2
------------

Released on 2022-02-27.

Bug fixes:

* `#1575 <https://github.com/Kozea/WeasyPrint/issues/1575>`_:
  Always store parent blocks children as lists
* `#1574 <https://github.com/Kozea/WeasyPrint/issues/1574>`_,
  `#1559 <https://github.com/Kozea/WeasyPrint/pull/1559>`_:
  Fix float rounding errors
* `#1571 <https://github.com/Kozea/WeasyPrint/issues/1571>`_:
  Ignore unknown glyphs
* `#1561 <https://github.com/Kozea/WeasyPrint/issues/1561>`_,
  `#1562 <https://github.com/Kozea/WeasyPrint/issues/1562>`_:
  Fix line break when breaks occur between a nbsp and an inline block
* `#1560 <https://github.com/Kozea/WeasyPrint/issues/1560>`_:
  Always set the child index
* `#1558 <https://github.com/Kozea/WeasyPrint/issues/1558>`_:
  Fix patterns with use tags

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Jack Lin
* aschmitz

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* Crisp BV
* SimonSoft
* Menutech
* KontextWork
* Maykin Media
* René Fritz
* NCC Group
* Spacinov
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Kobalt
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki
* DeivGuerrero


Version 54.1
------------

Released on 2022-01-31.

New features:

* `#1547 <https://github.com/Kozea/WeasyPrint/issues/1547>`_:
  Handle break-inside: avoid on tr tags

Bug fixes:

* `#1540 <https://github.com/Kozea/WeasyPrint/issues/1540>`_,
  `#1239 <https://github.com/Kozea/WeasyPrint/issues/1239>`_:
  Handle absolute children in running elements
* `#1538 <https://github.com/Kozea/WeasyPrint/issues/1538>`_:
  Handle invalid values in text-align
* `#1536 <https://github.com/Kozea/WeasyPrint/issues/1536>`_:
  Handle absolute flex boxes

Contirbutors:

* Guillaume Ayoub
* Lucie Anglade

Backers and sponsors:

* H-Net: Humanities and Social Sciences Online
* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Crisp BV
* Maykin Media
* René Fritz
* Simon Sapin
* NCC Group
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Spacinov
* Des images et des mots
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki


Version 54.0
------------

Released on 2022-01-08.

This version also includes the changes from unstable b1 version listed
below.

Bug fixes:

* `#1531 <https://github.com/Kozea/WeasyPrint/issues/1531>`_:
  Always use absolute paths to get hrefs in SVG
* `#1523 <https://github.com/Kozea/WeasyPrint/issues/1523>`_:
  Fix many rendering problems of broken tables
* `e1aee70 <https://github.com/Kozea/WeasyPrint/commit/e1aee70>`_:
  Fix support of fonts with SVG emojis

Contirbutors:

* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Crisp BV
* Maykin Media
* René Fritz
* Simon Sapin
* NCC Group
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Des images et des mots
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki


Version 54.0b1
--------------

Released on 2021-12-13.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Dependencies:

* html5lib 1.1+ is now needed.

New features:

* `#1509 <https://github.com/Kozea/WeasyPrint/pull/1509>`_:
  Support footnotes, with financial support from Code & Co.
* `#36 <https://github.com/Kozea/WeasyPrint/issues/36>`_:
  Handle parallel flows for floats, absolutes, table-cells
* `#1389 <https://github.com/Kozea/WeasyPrint/pull/1389>`_:
  Support ``text-align-last`` and ``text-align-all`` properties
* `#1434 <https://github.com/Kozea/WeasyPrint/pull/1434>`_:
  Draw SVG and PNG emojis
* `#1520 <https://github.com/Kozea/WeasyPrint/pull/1520>`_:
  Support ``overflow-wrap: anywhere``
* `#1435 <https://github.com/Kozea/WeasyPrint/issues/1435>`_:
  Add environment variable to set DLL folder on Windows

Performance:

* `#1439 <https://github.com/Kozea/WeasyPrint/issues/1439>`_:
  Cache SVG ``use`` tags
* `#1481 <https://github.com/Kozea/WeasyPrint/pull/1481>`_:
  Encode non-JPEG images as PNGs instead of JPEG2000s

Bug fixes:

* `#137 <https://github.com/Kozea/WeasyPrint/issues/137>`_:
  Don’t use ``text-transform`` text for content-based uses
* `#1443 <https://github.com/Kozea/WeasyPrint/issues/1443>`_:
  Don’t serialize and parse again inline SVG files
* `#607 <https://github.com/Kozea/WeasyPrint/issues/607>`_:
  Correctly handle whitespaces in bookmark labels
* `#1094 <https://github.com/Kozea/WeasyPrint/issues/1094>`_:
  Fix column height with ``column-span`` content
* `#1473 <https://github.com/Kozea/WeasyPrint/issues/1473>`_:
  Fix absolutely positioned boxes in duplicated pages
* `#1491 <https://github.com/Kozea/WeasyPrint/issues/1491>`_:
  Fix ``target-counter`` attribute in flex items
* `#1515 <https://github.com/Kozea/WeasyPrint/issues/1515>`_,
  `#1508 <https://github.com/Kozea/WeasyPrint/issues/1508>`_:
  Don’t draw empty glyphs
* `#1499 <https://github.com/Kozea/WeasyPrint/issues/1499>`_:
  Don’t crash when font size is really small

Documentation:

* `#1519 <https://github.com/Kozea/WeasyPrint/issues/1519>`_:
  Fix typo

Packaging:

* The source package does not include a ``setup.py`` file anymore. You can find
  more information about this in
  `issue #1410 <https://github.com/Kozea/WeasyPrint/issues/1410>`_.

Contirbutors:

* Guillaume Ayoub
* Lucie Anglade
* Colin Kinloch
* aschmitz
* Pablo González
* Rian McGuire

Backers and sponsors:

* Grip Angebotssoftware
* Manuel Barkhau
* SimonSoft
* Menutech
* KontextWork
* Crisp BV
* Maykin Media
* René Fritz
* Simon Sapin
* NCC Group
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Des images et des mots
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* Gábor
* Piotr Horzycki


Version 53.4
------------

Released on 2021-11-14.

Bug fixes:

* `#1446 <https://github.com/Kozea/WeasyPrint/issues/1446>`_:
  Fix background on pages with a bleed property
* `#1455 <https://github.com/Kozea/WeasyPrint/issues/1455>`_:
  Use SVG width/height as inner size when no viewBox is given
* `#1469 <https://github.com/Kozea/WeasyPrint/issues/1469>`_:
  Only enable letter- and word-spacing when needed
* `#1471 <https://github.com/Kozea/WeasyPrint/issues/1471>`_:
  Don’t display inputs with "hidden" type
* `#1485 <https://github.com/Kozea/WeasyPrint/issues/1485>`_:
  Allow quotes in url() syntax for SVG,
  Use better approximations for font ascent and descent values in SVG
* `#1486 <https://github.com/Kozea/WeasyPrint/issues/1486>`_:
  Fix images embedded from multiple pages
* `#1489 <https://github.com/Kozea/WeasyPrint/issues/1489>`_:
  Use a better hash for fonts to avoid collisions
* `abd54c4 <https://github.com/Kozea/WeasyPrint/commit/abd54c4>`_:
  Set SVG ratio when width and height are 0

Contributors:

* Guillaume Ayoub
* Lucie Anglade

Backers and sponsors:

* Grip Angebotssoftware
* SimonSoft
* Menutech
* Manuel Barkhau
* Simon Sapin
* KontextWork
* René Fritz
* Maykin Media
* NCC Group
* Crisp BV
* Des images et des mots
* Andreas Zettl
* Nathalie Gutton
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla
* G. Allard
* Gábor


Version 53.3
------------

Released on 2021-09-10.

Bug fixes:

* `#1431 <https://github.com/Kozea/WeasyPrint/issues/1431>`_,
  `#1440 <https://github.com/Kozea/WeasyPrint/issues/1440>`_:
  Fix crashes and malformed PDF files
* `#1430 <https://github.com/Kozea/WeasyPrint/issues/1430>`_:
  Handle cx and cy in SVG rotations
* `#1436 <https://github.com/Kozea/WeasyPrint/pull/1436>`_:
  Fix marker-start being drawn on mid vertices

Contributors:

* Guillaume Ayoub
* Rian McGuire
* Lucie Anglade

Backers and sponsors:

* Grip Angebotssoftware
* SimonSoft
* Menutech
* Manuel Barkhau
* Simon Sapin
* KontextWork
* René Fritz
* Maykin Media
* NCC Group
* Des images et des mots
* Andreas Zettl
* Nathalie Gutton
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla


Version 53.2
------------

Released on 2021-08-27.

New features:

* `#1428 <https://github.com/Kozea/WeasyPrint/issues/1428>`_:
  Re-add the ``make_bookmark_tree()`` method

Bug fixes:

* `#1429 <https://github.com/Kozea/WeasyPrint/issues/1429>`_:
  Fix package deployed on PyPI

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* PDF Blocks
* SimonSoft
* Menutech
* Manuel Barkhau
* Simon Sapin
* KontextWork
* René Fritz
* Maykin Media
* NCC Group
* Des images et des mots
* Andreas Zettl
* Nathalie Gutton
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla


Version 53.1
------------

Released on 2021-08-22.

Bug fixes:

* `#1409 <https://github.com/Kozea/WeasyPrint/issues/1409>`_:
  Don’t crash when leaders are in floats
* `#1414 <https://github.com/Kozea/WeasyPrint/issues/1414>`_:
  Embed images once
* `#1417 <https://github.com/Kozea/WeasyPrint/issues/1417>`_:
  Fix crash with SVG intrinsic ratio

Documentation:

* `#1422 <https://github.com/Kozea/WeasyPrint/issues/1422>`_:
  Include ``weasyprint.tools`` removal in documentation

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Grip Angebotssoftware
* PDF Blocks
* SimonSoft
* Menutech
* Manuel Barkhau
* Simon Sapin
* KontextWork
* René Fritz
* Maykin Media
* NCC Group
* Des images et des mots
* Andreas Zettl
* Nathalie Gutton
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* Yanal-Yves Fargialla


Version 53.0
------------

Released on 2021-07-31.

This version also includes the changes from unstable b1 and b2 versions listed
below.

Dependencies:

* Pango 1.44.0+ is now needed.
* pydyf 0.0.3+ is now needed.
* fontTools 4.0.0+ is now needed.
* html5lib 1.0.1+ is now needed.

API changes:

* ``FontConfiguration`` is now in the ``weasyprint.text.fonts`` module.
* ``--format`` and ``--resolution`` options have been deprecated, PDF is the
  only output format supported.
* ``--optimize-images`` option has been deprecated and replaced by
  ``--optimize-size``, allowing ``images``, ``fonts``, ``all`` and ``none``
  values.
* ``weasyprint.tools`` have been removed.
* ``Document.resolve_links``, ``Document.make_bookmark_tree`` and
  ``Document.add_hyperlinks`` have been removed.

Performance:

* Improve image management

New features:

* `#1374 <https://github.com/Kozea/WeasyPrint/issues/1374>`_:
  Support basic "clipPath" in SVG

Bug fixes:

* `#1369 <https://github.com/Kozea/WeasyPrint/issues/1369>`_:
  Render use path in SVG
* `#1370 <https://github.com/Kozea/WeasyPrint/issues/1370>`_:
  Fix fill color on use path in SVG
* `#1371 <https://github.com/Kozea/WeasyPrint/issues/1371>`_:
  Handle stroke-opacity and fill-opacity
* `#1378 <https://github.com/Kozea/WeasyPrint/issues/1378>`_:
  Fix crash with borders whose widths are in em
* `#1394 <https://github.com/Kozea/WeasyPrint/issues/1394>`_:
  Fix crash on draw_pattern
* `#880 <https://github.com/Kozea/WeasyPrint/issues/880>`_:
  Handle stacking contexts put in contexts by previous generations
* `#1386 <https://github.com/Kozea/WeasyPrint/issues/1386>`_:
  Catch font subsetting errors
* `#1403 <https://github.com/Kozea/WeasyPrint/issues/1403>`_:
  Fix how x and y attributes are handled in SVG
* `#1399 <https://github.com/Kozea/WeasyPrint/issues/1399>`_,
  `#1401 <https://github.com/Kozea/WeasyPrint/pull/1401>`_:
  Don’t crash when use tags reference non-existing element
* `#1393 <https://github.com/Kozea/WeasyPrint/issues/1393>`_:
  Handle font collections
* `#1408 <https://github.com/Kozea/WeasyPrint/issues/1408>`_:
  Handle x and y attributes in use tags

Documentation:

* `#1391 <https://github.com/Kozea/WeasyPrint/issues/1391>`_,
  `#1405 <https://github.com/Kozea/WeasyPrint/pull/1405>`_:
  Add documentation for installation

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Pelle Bo Regener
* aschmitz
* John Jackson
* Felix Schwarz
* Syrus Dark
* Christoph Päper

Backers and sponsors:

* OpenEdition
* Grip Angebotssoftware
* Simonsoft
* PDF Blocks
* Menutech
* Manuel Barkhau
* print-css.rocks
* Simon Sapin
* KontextWork
* René Fritz
* Maykin Media
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* NCC Group
* Moritz Mahringer
* Florian Demmer
* Des images et des mots
* Mohammed Y. Alnajdi
* Yanal-Yves Fargialla
* Yevhenii Hyzyla


Version 53.0b2
--------------

Released on 2021-05-30.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

New features:

* `#359 <https://github.com/Kozea/WeasyPrint/issues/359>`_:
  Embed full sets of fonts in PDF

Bug fixes:

* `#1345 <https://github.com/Kozea/WeasyPrint/issues/1345>`_:
  Fix position of SVG use tags
* `#1346 <https://github.com/Kozea/WeasyPrint/pull/1346>`_:
  Handle "stroke-dasharray: none"
* `#1352 <https://github.com/Kozea/WeasyPrint/issues/1352>`_,
  `#1358 <https://github.com/Kozea/WeasyPrint/pull/1358>`_:
  Sort link target identifiers
* `#1357 <https://github.com/Kozea/WeasyPrint/issues/1357>`_:
  Fix font information
* `#1362 <https://github.com/Kozea/WeasyPrint/issues/1362>`_:
  Handle visibility and display properties in SVG
* `#1365 <https://github.com/Kozea/WeasyPrint/issues/1365>`_:
  Cascade inherited attributes for use tags
* `#1366 <https://github.com/Kozea/WeasyPrint/issues/1366>`_:
  Correctly handle style attributes in SVG
* `#1367 <https://github.com/Kozea/WeasyPrint/issues/1367>`_:
  Include line stroke in box bounding

Documentation:

* `#1341 <https://github.com/Kozea/WeasyPrint/pull/1341>`_:
  Fix typos

Contributors:

* Guillaume Ayoub
* aschmitz
* John Jackson
* Lucie Anglade
* Pelle Bo Regener

Backers and sponsors:

* OpenEdition
* print-css.rocks
* Simonsoft
* PDF Blocks
* Menutech
* Manuel Barkhau
* Simon Sapin
* Grip Angebotssoftware
* KontextWork
* René Fritz
* Nathalie Gutton
* Andreas Zettl
* Tom Pohl
* Maykin Media
* Moritz Mahringer
* Florian Demmer
* Mohammed Y. Alnajdi
* NCC Group
* Des images et des mots
* Yanal-Yves Fargialla
* Yevhenii Hyzyla


Version 53.0b1
--------------

Released on 2021-04-22.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Dependencies:

* This version uses its own PDF generator instead of Cairo. Rendering may be
  different for text, gradients, SVG images…
* Packaging is now done with Flit.

New features:

* `#1328 <https://github.com/Kozea/WeasyPrint/pull/1328>`_:
  Add ISO and JIS paper sizes
* `#1309 <https://github.com/Kozea/WeasyPrint/pull/1309>`_:
  Leader support, with financial support from Simonsoft

Bug fixes:

* `#504 <https://github.com/Kozea/WeasyPrint/issues/504>`_:
  Fix rendering bugs with PDF gradients
* `#606 <https://github.com/Kozea/WeasyPrint/issues/606>`_:
  Fix rounding errors on PDF dimensions
* `#1264 <https://github.com/Kozea/WeasyPrint/issues/1264>`_:
  Include witdh/height when calculating auto margins of absolute boxes
* `#1191 <https://github.com/Kozea/WeasyPrint/issues/1191>`_:
  Don’t try to get an earlier page break between columns
* `#1235 <https://github.com/Kozea/WeasyPrint/issues/1235>`_:
  Include padding, border, padding when calculating inline-block width
* `#1199 <https://github.com/Kozea/WeasyPrint/issues/1199>`_:
  Fix kerning issues with small fonts

Documentation:

* `#1298 <https://github.com/Kozea/WeasyPrint/pull/1298>`_:
  Rewrite documentation

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Felix Schwarz
* Syrus Dark
* Christoph Päper

Backers and sponsors:

* Simonsoft
* PDF Blocks
* Menutech
* Manuel Barkhau
* Simon Sapin
* Nathalie Gutton
* Andreas Zettl
* René Fritz
* Tom Pohl
* KontextWork
* Moritz Mahringer
* Florian Demmer
* Maykin Media
* Yanal-Yves Fargialla
* Des images et des mots
* Yevhenii Hyzyla


Version 52.5
------------

Released on 2021-04-17.

Bug fixes:

* `#1336 <https://github.com/Kozea/WeasyPrint/issues/1336>`_:
  Fix text breaking exception
* `#1318 <https://github.com/Kozea/WeasyPrint/issues/1318>`_:
  Fix @font-face rules with Pango 1.48.3+

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Simonsoft
* PDF Blocks
* Menutech
* Manuel Barkhau
* Simon Sapin
* Nathalie Gutton
* Andreas Zettl
* René Fritz
* Tom Pohl
* KontextWork
* Moritz Mahringer
* Florian Demmer
* Maykin Media
* Yanal-Yves Fargialla
* Des images et des mots
* Yevhenii Hyzyla


Version 52.4
------------

Released on 2021-03-11.

Bug fixes:

* `#1304 <https://github.com/Kozea/WeasyPrint/issues/1304>`_:
  Don’t try to draw SVG files with no size
* `ece5f066 <https://github.com/Kozea/WeasyPrint/commit/ece5f066>`_:
  Avoid crash on last word detection
* `4ee42e48 <https://github.com/Kozea/WeasyPrint/commit/4ee42e48>`_:
  Remove last word before ellipses when hyphenated

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* PDF Blocks
* Simonsoft
* Menutech
* Simon Sapin
* Manuel Barkhau
* Andreas Zettl
* Nathalie Gutton
* Tom Pohl
* René Fritz
* Moritz Mahringer
* Florian Demmer
* KontextWork
* Michele Mostarda


Version 52.3
------------

Released on 2021-03-02.

Bug fixes:

* `#1299 <https://github.com/Kozea/WeasyPrint/issues/1299>`_:
  Fix imports with url() and quotes

New features:

* `#1300 <https://github.com/Kozea/WeasyPrint/pull/1300>`_:
  Add support of line-clamp, with financial support from
  expert Germany

Contributors:

* Guillaume Ayoub
* Lucie Anglade

Backers and sponsors:

* PDF Blocks
* Simonsoft
* Menutech
* Simon Sapin
* Manuel Barkhau
* Andreas Zettl
* Nathalie Gutton
* Tom Pohl
* Moritz Mahringer
* Florian Demmer
* KontextWork
* Michele Mostarda


Version 52.2
------------

Released on 2020-12-06.

Bug fixes:

* `238e214 <https://github.com/Kozea/WeasyPrint/commit/238e214>`_:
  Fix URL handling with tinycss2
* `#1248 <https://github.com/Kozea/WeasyPrint/issues/1248>`_:
  Include missing test data
* `#1254 <https://github.com/Kozea/WeasyPrint/issues/1254>`_:
  Top margins removed from children when tables are displayed on multiple pages
* `#1250 <https://github.com/Kozea/WeasyPrint/issues/1250>`_:
  Correctly draw borders on the last line of split tables
* `a6f9c80 <https://github.com/Kozea/WeasyPrint/commit/a6f9c80>`_:
  Add a nice gif to please gdk-pixbuf 2.42.0

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Felix Schwarz

Backers and sponsors:

* PDF Blocks
* Simonsoft
* Menutech
* Simon Sapin
* Nathalie Gutton
* Andreas Zetti
* Tom Pohl
* Florian Demmer
* Moritz Mahringer


Version 52.1
------------

Released on 2020-11-02.

Bug fixes:

* `238e214 <https://github.com/Kozea/WeasyPrint/commit/238e214>`_:
  Fix URL handling with tinycss2

Contributors:

* Guillaume Ayoub

Backers and sponsors:

* Simonsoft
* Simon Sapin
* Nathalie Gutton
* Andreas Zettl
* Florian Demmer
* Moritz Mahringer


Version 52
----------

Released on 2020-10-29.

Dependencies:

* Python 3.6+ is now needed, Python 3.5 is not supported anymore
* WeasyPrint now depends on Pillow

New features:

* `#1019 <https://github.com/Kozea/WeasyPrint/issues/1019>`_:
  Implement ``counter-set``
* `#1080 <https://github.com/Kozea/WeasyPrint/issues/1080>`_:
  Don’t display ``template`` tags
* `#1210 <https://github.com/Kozea/WeasyPrint/pull/1210>`_:
  Use ``download`` attribute in ``a`` tags for attachment's filename
* `#1206 <https://github.com/Kozea/WeasyPrint/issues/1206>`_:
  Handle strings in ``list-style-type``
* `#1165 <https://github.com/Kozea/WeasyPrint/pull/1165>`_:
  Add support for concatenating ``var()`` functions in ``content`` declarations
* `c56b96b <https://github.com/Kozea/WeasyPrint/commit/c56b96b>`_:
  Add an option to optimize embedded images size, with financial support from
  Hashbang
* `#969 <https://github.com/Kozea/WeasyPrint/issues/969>`_:
  Add an image cache that can be shared between documents, with financial
  support from Hashbang

Bug fixes:

* `#1141 <https://github.com/Kozea/WeasyPrint/pull/1141>`_:
  Don’t clip page margins on account of ``body`` overflow
* `#1000 <https://github.com/Kozea/WeasyPrint/issues/1000>`_:
  Don’t apply ``text-indent`` twice on inline blocks
* `#1051 <https://github.com/Kozea/WeasyPrint/issues/1051>`_:
  Avoid random line breaks
* `#1120 <https://github.com/Kozea/WeasyPrint/pull/1120>`_:
  Gather target counters in page margins
* `#1110 <https://github.com/Kozea/WeasyPrint/issues/1110>`_:
  Handle most cases for boxes avoiding floats in rtl containers, with financial
  support from Innovative Software
* `#1111 <https://github.com/Kozea/WeasyPrint/issues/1111>`_:
  Fix horizontal position of last rtl line, with financial support from
  Innovative Software
* `#1114 <https://github.com/Kozea/WeasyPrint/issues/1114>`_:
  Fix bug with transparent borders in tables
* `#1146 <https://github.com/Kozea/WeasyPrint/pull/1146>`_:
  Don’t gather bookmarks twice for blocks that are displayed on two pages
* `#1237 <https://github.com/Kozea/WeasyPrint/issues/1237>`_:
  Use fallback fonts on unsupported WOFF2 and WOFF fonts
* `#1025 <https://github.com/Kozea/WeasyPrint/issues/1025>`_:
  Don’t insert the same layout attributes multiple times
* `#1027 <https://github.com/Kozea/WeasyPrint/issues/1027>`_:
  Don’t try to break tables after the header or before the footer
* `#1050 <https://github.com/Kozea/WeasyPrint/issues/1050>`_:
  Don’t crash on absolute SVG files with no intrinsic size
* `#1204 <https://github.com/Kozea/WeasyPrint/issues/1204>`_:
  Fix a crash with a flexbox corner case
* `#1030 <https://github.com/Kozea/WeasyPrint/pull/1030>`_:
  Fix frozen builds
* `#1089 <https://github.com/Kozea/WeasyPrint/pull/1089>`_:
  Fix Pyinstaller builds
* `#1216 <https://github.com/Kozea/WeasyPrint/pull/1213>`_:
  Fix embedded files
* `#1225 <https://github.com/Kozea/WeasyPrint/pull/1225>`_:
  Initial support of RTL direction in flexbox layout

Documentation:

* `#1149 <https://github.com/Kozea/WeasyPrint/issues/1149>`_:
  Add the ``--quiet`` CLI option in the documentation
* `#1061 <https://github.com/Kozea/WeasyPrint/pull/1061>`_:
  Update install instructions on Windows

Tests:

* `#1209 <https://github.com/Kozea/WeasyPrint/pull/1209>`_:
  Use GitHub Actions instead of Travis

Contributors:

* Guillaume Ayoub
* Lucie Anglade
* Tontyna
* Mohammed Y. Alnajdi
* Mike Voets
* Bjarni Þórisson
* Balázs Dukai
* Bart Broere
* Endalkachew
* Felix Schwarz
* Julien Sanchez
* Konstantin Alekseev
* Nicolas Hart
* Nikolaus Schlemm
* Thomas J. Lampoltshammer
* mPyth
* nempoBu4
* saddy001

Backers and sponsors:

* Hashbang
* Innovative Software
* Screenbreak
* Simon Sapin
* Lisa Warshaw
* Nathalie Gutton
* Andreas Zettl
* Florian Demmer
* Moritz Mahringer


Version 51
----------

Released on 2019-12-23.

Dependencies:

* Pyphen 0.9.1+ is now needed

New features:

* `#882 <https://github.com/Kozea/WeasyPrint/pull/882>`_:
  Add support of ``element()`` and ``running()``
* `#972 <https://github.com/Kozea/WeasyPrint/pull/972>`_:
  Add HTML element to Box class
* `7a4d6f8 <https://github.com/Kozea/WeasyPrint/commit/7a4d6f8>`_:
  Support ``larger`` and ``smaller`` values for ``font-size``

Bug fixes:

* `#960 <https://github.com/Kozea/WeasyPrint/pull/960>`_:
  Fix how fonts used for macOS tests are installed
* `#956 <https://github.com/Kozea/WeasyPrint/pull/956>`_:
  Fix various crashes due to line breaking bugs
* `#983 <https://github.com/Kozea/WeasyPrint/issues/983>`_:
  Fix typo in variable name
* `#975 <https://github.com/Kozea/WeasyPrint/pull/975>`_:
  Don’t crash when ``string-set`` is set to ``none``
* `#998 <https://github.com/Kozea/WeasyPrint/pull/998>`_:
  Keep font attributes when text lines are modified
* `#1005 <https://github.com/Kozea/WeasyPrint/issues/1005>`_:
  Don’t let presentational hints add decorations on tables with no borders
* `#974 <https://github.com/Kozea/WeasyPrint/pull/974>`_:
  Don’t crash on improper ``var()`` values
* `#1012 <https://github.com/Kozea/WeasyPrint/pull/1012>`_:
  Fix rendering of header and footer for empty tables
* `#1013 <https://github.com/Kozea/WeasyPrint/issues/1013>`_:
  Avoid quadratic time relative to tree depth when setting page names

Contributors:

- Lucie Anglade
- Guillaume Ayoub
- Guillermo Bonvehí
- Holger Brunn
- Felix Schwarz
- Tontyna


Version 50
----------

Released on 2019-09-19.

New features:

* `#209 <https://github.com/Kozea/WeasyPrint/issues/209>`_:
  Make ``break-*`` properties work inside tables
* `#661 <https://github.com/Kozea/WeasyPrint/issues/661>`_:
  Make blocks with ``overflow: auto`` grow to include floating children

Bug fixes:

* `#945 <https://github.com/Kozea/WeasyPrint/issues/945>`_:
  Don't break pages between a list item and its marker
* `#727 <https://github.com/Kozea/WeasyPrint/issues/727>`_:
  Avoid tables lost between pages
* `#831 <https://github.com/Kozea/WeasyPrint/issues/831>`_:
  Ignore auto margins on flex containers
* `#923 <https://github.com/Kozea/WeasyPrint/issues/923>`_:
  Fix a couple of crashes when splitting a line twice
* `#896 <https://github.com/Kozea/WeasyPrint/issues/896>`_:
  Fix skip stack order when using a reverse flex direction

Contributors:

- Lucie Anglade
- Guillaume Ayoub


Version 49
----------

Released on 2019-09-11.

Performance:

* Speed and memory use have been largely improved.

New features:

* `#700 <https://github.com/Kozea/WeasyPrint/issues/700>`_:
  Handle ``::marker`` pseudo-selector
* `135dc06c <https://github.com/Kozea/WeasyPrint/commit/135dc06c>`_:
  Handle ``recto`` and ``verso`` parameters for page breaks
* `#907 <https://github.com/Kozea/WeasyPrint/pull/907>`_:
  Provide a clean way to build layout contexts

Bug fixes:

* `#937 <https://github.com/Kozea/WeasyPrint/issues/937>`_:
  Fix rendering of tables with empty lines and rowspans
* `#897 <https://github.com/Kozea/WeasyPrint/issues/897>`_:
  Don't crash when small columns are wrapped in absolute blocks
* `#913 <https://github.com/Kozea/WeasyPrint/issues/913>`_:
  Fix a test about gradient colors
* `#924 <https://github.com/Kozea/WeasyPrint/pull/924>`_:
  Fix title for document with attachments
* `#917 <https://github.com/Kozea/WeasyPrint/issues/917>`_:
  Fix tests with Pango 1.44
* `#919 <https://github.com/Kozea/WeasyPrint/issues/919>`_:
  Fix padding and margin management for column flex boxes
* `#901 <https://github.com/Kozea/WeasyPrint/issues/901>`_:
  Fix width of replaced boxes with no intrinsic width
* `#906 <https://github.com/Kozea/WeasyPrint/issues/906>`_:
  Don't respect table cell width when content doesn't fit
* `#927 <https://github.com/Kozea/WeasyPrint/pull/927>`_:
  Don't use deprecated ``logger.warn`` anymore
* `a8662794 <https://github.com/Kozea/WeasyPrint/commit/a8662794>`_:
  Fix margin collapsing between caption and table wrapper
* `87d9e84f <https://github.com/Kozea/WeasyPrint/commit/87d9e84f>`_:
  Avoid infinite loops when rendering columns
* `789b80e6 <https://github.com/Kozea/WeasyPrint/commit/789b80e6>`_:
  Only use in flow children to set columns height
* `615e298a <https://github.com/Kozea/WeasyPrint/commit/615e298a>`_:
  Don't include floating elements each time we try to render a column
* `48d8632e <https://github.com/Kozea/WeasyPrint/commit/48d8632e>`_:
  Avoid not in flow children to compute column height
* `e7c452ce <https://github.com/Kozea/WeasyPrint/commit/e7c452ce>`_:
  Fix collapsing margins for columns
* `fb0887cf <https://github.com/Kozea/WeasyPrint/commit/fb0887cf>`_:
  Fix crash when using currentColor in gradients
* `f66df067 <https://github.com/Kozea/WeasyPrint/commit/f66df067>`_:
  Don't crash when using ex units in word-spacing in letter-spacing
* `c790ff20 <https://github.com/Kozea/WeasyPrint/commit/c790ff20>`_:
  Don't crash when properties needing base URL use var functions
* `d63eac31 <https://github.com/Kozea/WeasyPrint/commit/d63eac31>`_:
  Don't crash with object-fit: non images with no intrinsic size

Documentation:

* `#900 <https://github.com/Kozea/WeasyPrint/issues/900>`_:
  Add documentation about semantic versioning
* `#692 <https://github.com/Kozea/WeasyPrint/issues/692>`_:
  Add a snippet about PDF magnification
* `#899 <https://github.com/Kozea/WeasyPrint/pull/899>`_:
  Add .NET wrapper link
* `#893 <https://github.com/Kozea/WeasyPrint/pull/893>`_:
  Fixed wrong nested list comprehension example
* `#902 <https://github.com/Kozea/WeasyPrint/pull/902>`_:
  Add ``state`` to the ``make_bookmark_tree`` documentation
* `#921 <https://github.com/Kozea/WeasyPrint/pull/921>`_:
  Fix typos in the documentation
* `#328 <https://github.com/Kozea/WeasyPrint/issues/328>`_:
  Add CSS sample for forms

Contributors:

- Lucie Anglade
- Guillaume Ayoub
- Raphael Gaschignard
- Stani
- Szmen
- Thomas Dexter
- Tontyna


Version 48
----------

Released on 2019-07-08.

Dependencies:

* CairoSVG 2.4.0+ is now needed

New features:

* `#891 <https://github.com/Kozea/WeasyPrint/pull/891>`_:
  Handle ``text-overflow``
* `#878 <https://github.com/Kozea/WeasyPrint/pull/878>`_:
  Handle ``column-span``
* `#855 <https://github.com/Kozea/WeasyPrint/pull/855>`_:
  Handle all the ``text-decoration`` features
* `#238 <https://github.com/Kozea/WeasyPrint/issues/238>`_:
  Don't repeat background images when it's not needed
* `#875 <https://github.com/Kozea/WeasyPrint/issues/875>`_:
  Handle ``object-fit`` and ``object-position``
* `#870 <https://github.com/Kozea/WeasyPrint/issues/870>`_:
  Handle ``bookmark-state``

Bug fixes:

* `#686 <https://github.com/Kozea/WeasyPrint/issues/686>`_:
  Fix column balance when children are not inline
* `#885 <https://github.com/Kozea/WeasyPrint/issues/885>`_:
  Actually use the content box to resolve flex items percentages
* `#867 <https://github.com/Kozea/WeasyPrint/issues/867>`_:
  Fix rendering of KaTeX output, including (1) set row baseline of tables when
  no cells are baseline-aligned, (2) set baseline for inline tables, (3) don't
  align lines larger than their parents, (4) force CairoSVG to respect image
  size defined by CSS.
* `#873 <https://github.com/Kozea/WeasyPrint/issues/873>`_:
  Set a minimum height for empty list elements with outside marker
* `#811 <https://github.com/Kozea/WeasyPrint/issues/811>`_:
  Don't use translations to align flex items
* `#851 <https://github.com/Kozea/WeasyPrint/issues/851>`_,
  `#860 <https://github.com/Kozea/WeasyPrint/issues/860>`_:
  Don't cut pages when content overflows a very little bit
* `#862 <https://github.com/Kozea/WeasyPrint/issues/862>`_:
  Don't crash when using UTC dates in metadata

Documentation:

* `#854 <https://github.com/Kozea/WeasyPrint/issues/854>`_:
  Add a "Tips & Tricks" section

Contributors:

- Gabriel Corona
- Guillaume Ayoub
- Manuel Barkhau
- Nathan de Maestri
- Lucie Anglade
- theopeek


Version 47
----------

Released on 2019-04-12.

New features:

* `#843 <https://github.com/Kozea/WeasyPrint/pull/843>`_:
  Handle CSS variables
* `#846 <https://github.com/Kozea/WeasyPrint/pull/846>`_:
  Handle ``:nth()`` page selector
* `#847 <https://github.com/Kozea/WeasyPrint/pull/847>`_:
  Allow users to use a custom SSL context for HTTP requests

Bug fixes:

* `#797 <https://github.com/Kozea/WeasyPrint/issues/797>`_:
  Fix underlined justified text
* `#836 <https://github.com/Kozea/WeasyPrint/issues/836>`_:
  Fix crash when flex items are replaced boxes
* `#835 <https://github.com/Kozea/WeasyPrint/issues/835>`_:
  Fix ``margin-break: auto``


Version 46
----------

Released on 2019-03-20.

New features:

* `#771 <https://github.com/Kozea/WeasyPrint/issues/771>`_:
  Handle ``box-decoration-break``
* `#115 <https://github.com/Kozea/WeasyPrint/issues/115>`_:
  Handle ``margin-break``
* `#821 <https://github.com/Kozea/WeasyPrint/issues/821>`_:
  Continuous integration includes tests on Windows

Bug fixes:

* `#765 <https://github.com/Kozea/WeasyPrint/issues/765>`_,
  `#754 <https://github.com/Kozea/WeasyPrint/issues/754>`_,
  `#800 <https://github.com/Kozea/WeasyPrint/issues/800>`_:
  Fix many crashes related to the flex layout
* `#783 <https://github.com/Kozea/WeasyPrint/issues/783>`_:
  Fix a couple of crashes with strange texts
* `#827 <https://github.com/Kozea/WeasyPrint/pull/827>`_:
  Named strings and counters are case-sensitive
* `#823 <https://github.com/Kozea/WeasyPrint/pull/823>`_:
  Shrink min/max-height/width according to box-sizing
* `#728 <https://github.com/Kozea/WeasyPrint/issues/728>`_,
  `#171 <https://github.com/Kozea/WeasyPrint/issues/171>`_:
  Don't crash when fixed boxes are nested
* `#610 <https://github.com/Kozea/WeasyPrint/issues/610>`_,
  `#828 <https://github.com/Kozea/WeasyPrint/issues/828>`_:
  Don't crash when preformatted text lines end with a space
* `#808 <https://github.com/Kozea/WeasyPrint/issues/808>`_,
  `#387 <https://github.com/Kozea/WeasyPrint/issues/387>`_:
  Fix position of some images
* `#813 <https://github.com/Kozea/WeasyPrint/issues/813>`_:
  Don't crash when long preformatted text lines end with ``\n``

Documentation:

* `#815 <https://github.com/Kozea/WeasyPrint/pull/815>`_:
  Add documentation about custom ``url_fetcher``


Version 45
----------

Released on 2019-02-20.

WeasyPrint now has a `code of conduct
<https://github.com/Kozea/WeasyPrint/blob/master/CODE_OF_CONDUCT.rst>`_.

A new website has been launched, with beautiful and useful graphs about speed
and memory use across versions: check `WeasyPerf
<https://kozea.github.io/WeasyPerf/index.html>`_.

Dependencies:

* Python 3.5+ is now needed, Python 3.4 is not supported anymore

Bug fixes:

* `#798 <https://github.com/Kozea/WeasyPrint/pull/798>`_:
  Prevent endless loop and index out of range in pagination
* `#767 <https://github.com/Kozea/WeasyPrint/issues/767>`_:
  Add a ``--quiet`` CLI parameter
* `#784 <https://github.com/Kozea/WeasyPrint/pull/784>`_:
  Fix library loading on Alpine
* `#791 <https://github.com/Kozea/WeasyPrint/pull/791>`_:
  Use path2url in tests for Windows
* `#789 <https://github.com/Kozea/WeasyPrint/pull/789>`_:
  Add LICENSE file to distributed sources
* `#788 <https://github.com/Kozea/WeasyPrint/pull/788>`_:
  Fix pending references
* `#780 <https://github.com/Kozea/WeasyPrint/issues/780>`_:
  Don't draw patterns for empty page backgrounds
* `#774 <https://github.com/Kozea/WeasyPrint/issues/774>`_:
  Don't crash when links include quotes
* `#637 <https://github.com/Kozea/WeasyPrint/issues/637>`_:
  Fix a problem with justified text
* `#763 <https://github.com/Kozea/WeasyPrint/pull/763>`_:
  Launch tests with Python 3.7
* `#704 <https://github.com/Kozea/WeasyPrint/issues/704>`_:
  Fix a corner case with tables
* `#804 <https://github.com/Kozea/WeasyPrint/pull/804>`_:
  Don't logger handlers defined before importing WeasyPrint
* `#109 <https://github.com/Kozea/WeasyPrint/issues/109>`_,
  `#748 <https://github.com/Kozea/WeasyPrint/issues/748>`_:
  Don't include punctuation for hyphenation
* `#770 <https://github.com/Kozea/WeasyPrint/issues/770>`_:
  Don't crash when people use uppercase words from old-fashioned Microsoft
  fonts in tables, especially when there's an 5th column
* Use a `separate logger
  <https://weasyprint.readthedocs.io/en/latest/tutorial.html#logging>`_ to
  report the rendering process
* Add a ``--debug`` CLI parameter and set debug level for unknown prefixed CSS
  properties
* Define minimal versions of Python and setuptools in setup.cfg

Documentation:

* `#796 <https://github.com/Kozea/WeasyPrint/pull/796>`_:
  Fix a small typo in the tutorial
* `#792 <https://github.com/Kozea/WeasyPrint/pull/792>`_:
  Document no alignment character support
* `#773 <https://github.com/Kozea/WeasyPrint/pull/773>`_:
  Fix phrasing in Hacking section
* `#402 <https://github.com/Kozea/WeasyPrint/issues/402>`_:
  Add a paragraph about fontconfig error
* `#764 <https://github.com/Kozea/WeasyPrint/pull/764>`_:
  Fix list of dependencies for Alpine
* Fix API documentation of HTML and CSS classes


Version 44
----------

Released on 2018-12-29.

Bug fixes:

* `#742 <https://github.com/Kozea/WeasyPrint/issues/742>`_:
  Don't crash during PDF generation when locale uses commas as decimal separator
* `#746 <https://github.com/Kozea/WeasyPrint/issues/746>`_:
  Close file when reading VERSION
* Improve speed and memory usage for long texts.

Documentation:

* `#733 <https://github.com/Kozea/WeasyPrint/pull/733>`_:
  Small documentation fixes
* `#735 <https://github.com/Kozea/WeasyPrint/pull/735>`_:
  Fix broken links in NEWS.rst


Version 43
----------

Released on 2018-11-09.

Bug fixes:

* `#726 <https://github.com/Kozea/WeasyPrint/issues/726>`_:
  Make empty strings clear previous values of named strings
* `#729 <https://github.com/Kozea/WeasyPrint/issues/729>`_:
  Include tools in packaging

This version also includes the changes from unstable rc1 and rc2 versions
listed below.


Version 43rc2
-------------

Released on 2018-11-02.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Bug fixes:

* `#706 <https://github.com/Kozea/WeasyPrint/issues/706>`_:
  Fix text-indent at the beginning of a page
* `#687 <https://github.com/Kozea/WeasyPrint/issues/687>`_:
  Allow query strings in file:// URIs
* `#720 <https://github.com/Kozea/WeasyPrint/issues/720>`_:
  Optimize minimum size calculation of long inline elements
* `#717 <https://github.com/Kozea/WeasyPrint/issues/717>`_:
  Display <details> tags as blocks
* `#691 <https://github.com/Kozea/WeasyPrint/issues/691>`_:
  Don't recalculate max content widths when distributing extra space for tables
* `#722 <https://github.com/Kozea/WeasyPrint/issues/722>`_:
  Fix bookmarks and strings set on images
* `#723 <https://github.com/Kozea/WeasyPrint/issues/723>`_:
  Warn users when string() is not used in page margin


Version 43rc1
-------------

Released on 2018-10-15.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Dependencies:

* Python 3.4+ is now needed, Python 2.x is not supported anymore
* Cairo 1.15.4+ is now needed, but 1.10+ should work with missing features
  (such as links, outlines and metadata)
* Pdfrw is not needed anymore

New features:

* `Beautiful website <https://weasyprint.org>`_
* `#579 <https://github.com/Kozea/WeasyPrint/issues/579>`_:
  Initial support of flexbox
* `#592 <https://github.com/Kozea/WeasyPrint/pull/592>`_:
  Support @font-face on Windows
* `#306 <https://github.com/Kozea/WeasyPrint/issues/306>`_:
  Add a timeout parameter to the URL fetcher functions
* `#594 <https://github.com/Kozea/WeasyPrint/pull/594>`_:
  Split tests using modern pytest features
* `#599 <https://github.com/Kozea/WeasyPrint/pull/599>`_:
  Make tests pass on Windows
* `#604 <https://github.com/Kozea/WeasyPrint/pull/604>`_:
  Handle target counters and target texts
* `#631 <https://github.com/Kozea/WeasyPrint/pull/631>`_:
  Enable counter-increment and counter-reset in page context
* `#622 <https://github.com/Kozea/WeasyPrint/issues/622>`_:
  Allow pathlib.Path objects for HTML, CSS and Attachment classes
* `#674 <https://github.com/Kozea/WeasyPrint/issues/674>`_:
  Add extensive installation instructions for Windows

Bug fixes:

* `#558 <https://github.com/Kozea/WeasyPrint/issues/558>`_:
  Fix attachments
* `#565 <https://github.com/Kozea/WeasyPrint/issues/565>`_,
  `#596 <https://github.com/Kozea/WeasyPrint/issues/596>`_,
  `#539 <https://github.com/Kozea/WeasyPrint/issues/539>`_:
  Fix many PDF rendering, printing and compatibility problems
* `#614 <https://github.com/Kozea/WeasyPrint/issues/614>`_:
  Avoid crashes and endless loops caused by a Pango bug
* `#662 <https://github.com/Kozea/WeasyPrint/pull/662>`_:
  Fix warnings and errors when generating documentation
* `#666 <https://github.com/Kozea/WeasyPrint/issues/666>`_,
  `#685 <https://github.com/Kozea/WeasyPrint/issues/685>`_:
  Fix many table layout rendering problems
* `#680 <https://github.com/Kozea/WeasyPrint/pull/680>`_:
  Don't crash when there's no font available
* `#662 <https://github.com/Kozea/WeasyPrint/pull/662>`_:
  Fix support of some align values in tables


Version 0.42.3
--------------

Released on 2018-03-27.

Bug fixes:

* `#583 <https://github.com/Kozea/WeasyPrint/issues/583>`_:
  Fix floating-point number error to fix floating box layout
* `#586 <https://github.com/Kozea/WeasyPrint/issues/586>`_:
  Don't optimize resume_at when splitting lines with trailing spaces
* `#582 <https://github.com/Kozea/WeasyPrint/issues/582>`_:
  Fix table layout with no overflow
* `#580 <https://github.com/Kozea/WeasyPrint/issues/580>`_:
  Fix inline box breaking function
* `#576 <https://github.com/Kozea/WeasyPrint/issues/576>`_:
  Split replaced_min_content_width and replaced_max_content_width
* `#574 <https://github.com/Kozea/WeasyPrint/issues/574>`_:
  Respect text direction and don't translate rtl columns twice
* `#569 <https://github.com/Kozea/WeasyPrint/issues/569>`_:
  Get only first line's width of inline children to get linebox width


Version 0.42.2
--------------

Released on 2018-02-04.

Bug fixes:

* `#560 <https://github.com/Kozea/WeasyPrint/issues/560>`_:
  Fix a couple of crashes and endless loops when breaking lines.


Version 0.42.1
--------------

Released on 2018-02-01.

Bug fixes:

* `#566 <https://github.com/Kozea/WeasyPrint/issues/566>`_:
  Don't crash when using @font-config.
* `#567 <https://github.com/Kozea/WeasyPrint/issues/567>`_:
  Fix text-indent with text-align: justify.
* `#465 <https://github.com/Kozea/WeasyPrint/issues/465>`_:
  Fix string(\*, start).
* `#562 <https://github.com/Kozea/WeasyPrint/issues/562>`_:
  Handle named pages with pseudo-class.
* `#507 <https://github.com/Kozea/WeasyPrint/issues/507>`_:
  Fix running headers.
* `#557 <https://github.com/Kozea/WeasyPrint/issues/557>`_:
  Avoid infinite loops in inline_line_width.
* `#555 <https://github.com/Kozea/WeasyPrint/issues/555>`_:
  Fix margins, borders and padding in column layouts.


Version 0.42
------------

Released on 2017-12-26.

WeasyPrint is not tested with (end-of-life) Python 3.3 anymore.

**This release is probably the last version of the 0.x series.**

Next version may include big changes:

- end of Python 2.7 support,
- initial support of bidirectional text,
- initial support of flexbox,
- improvements for speed and memory usage.

New features:

* `#532 <https://github.com/Kozea/WeasyPrint/issues/532>`_:
  Support relative file URIs when using CLI.

Bug fixes:

* `#553 <https://github.com/Kozea/WeasyPrint/issues/553>`_:
  Fix slow performance for pre-formatted boxes with a lot of children.
* `#409 <https://github.com/Kozea/WeasyPrint/issues/409>`_:
  Don't crash when rendering some tables.
* `#39 <https://github.com/Kozea/WeasyPrint/issues/39>`_:
  Fix rendering of floats in inlines.
* `#301 <https://github.com/Kozea/WeasyPrint/issues/301>`_:
  Split lines carefully.
* `#530 <https://github.com/Kozea/WeasyPrint/issues/530>`_:
  Fix root when frozen with Pyinstaller.
* `#534 <https://github.com/Kozea/WeasyPrint/issues/534>`_:
  Handle SVGs containing images embedded as data URIs.
* `#360 <https://github.com/Kozea/WeasyPrint/issues/360>`_:
  Fix border-radius rendering problem with some PDF readers.
* `#525 <https://github.com/Kozea/WeasyPrint/issues/525>`_:
  Fix pipenv support.
* `#227 <https://github.com/Kozea/WeasyPrint/issues/227>`_:
  Smartly handle replaced boxes with percentage width in auto-width parents.
* `#520 <https://github.com/Kozea/WeasyPrint/issues/520>`_:
  Don't ignore CSS @page rules that are imported by an @import rule.


Version 0.41
------------

Released on 2017-10-05.

WeasyPrint now depends on pdfrw >= 0.4.

New features:

* `#471 <https://github.com/Kozea/WeasyPrint/issues/471>`_:
  Support page marks and bleed.

Bug fixes:

* `#513 <https://github.com/Kozea/WeasyPrint/issues/513>`_:
  Don't crash on unsupported image-resolution values.
* `#506 <https://github.com/Kozea/WeasyPrint/issues/506>`_:
  Fix @font-face use with write_* methods.
* `#500 <https://github.com/Kozea/WeasyPrint/pull/500>`_:
  Improve readability of _select_source function.
* `#498 <https://github.com/Kozea/WeasyPrint/issues/498>`_:
  Use CSS prefixes as recommended by the CSSWG.
* `#441 <https://github.com/Kozea/WeasyPrint/issues/441>`_:
  Fix rendering problems and crashes when using @font-face.
* `bb3a4db <https://github.com/Kozea/WeasyPrint/commit/bb3a4db>`_:
  Try to break pages after a block before trying to break inside it.
* `1d1654c <https://github.com/Kozea/WeasyPrint/commit/1d1654c>`_:
  Fix and test corner cases about named pages.

Documentation:

* `#508 <https://github.com/Kozea/WeasyPrint/pull/508>`_:
  Add missing libpangocairo dependency for Debian and Ubuntu.
* `a7b17fb <https://github.com/Kozea/WeasyPrint/commit/a7b17fb>`_:
  Add documentation on logged rendering steps.


Version 0.40
------------

Released on 2017-08-17.

WeasyPrint now depends on cssselect2 instead of cssselect and lxml.

New features:

* `#57 <https://github.com/Kozea/WeasyPrint/issues/57>`_:
  Named pages.
* Unprefix properties, see
  `#498 <https://github.com/Kozea/WeasyPrint/issues/498>`_.
* Add a "verbose" option logging the document generation steps.

Bug fixes:

* `#483 <https://github.com/Kozea/WeasyPrint/issues/483>`_:
  Fix slow performance with long pre-formatted texts.
* `#70 <https://github.com/Kozea/WeasyPrint/issues/70>`_:
  Improve speed and memory usage for long documents.
* `#487 <https://github.com/Kozea/WeasyPrint/issues/487>`_:
  Don't crash on local() fonts with a space and no quotes.


Version 0.39
------------

Released on 2017-06-24.

Bug fixes:

* Fix the use of WeasyPrint's URL fetcher with CairoSVG.


Version 0.38
------------

Released on 2017-06-16.

Bug fixes:

* `#477 <https://github.com/Kozea/WeasyPrint/issues/477>`_:
  Don't crash on font-face's src attributes with local functions.


Version 0.37
------------

Released on 2017-06-15.

WeasyPrint now depends on tinycss2 instead of tinycss.

New features:

* `#437 <https://github.com/Kozea/WeasyPrint/issues/437>`_:
  Support local links in generated PDFs.

Bug fixes:

* `#412 <https://github.com/Kozea/WeasyPrint/issues/412>`_:
  Use a NullHandler log handler when WeasyPrint is used as a library.
* `#417 <https://github.com/Kozea/WeasyPrint/issues/417>`_,
  `#472 <https://github.com/Kozea/WeasyPrint/issues/472>`_:
  Don't crash on some line breaks.
* `#327 <https://github.com/Kozea/WeasyPrint/issues/327>`_:
  Don't crash with replaced elements with height set in percentages.
* `#467 <https://github.com/Kozea/WeasyPrint/issues/467>`_:
  Remove incorrect line breaks.
* `#446 <https://github.com/Kozea/WeasyPrint/pull/446>`_:
  Let the logging module do the string interpolation.


Version 0.36
------------

Released on 2017-02-25.

New features:

* `#407 <https://github.com/Kozea/WeasyPrint/pull/407>`_:
  Handle ::first-letter.
* `#423 <https://github.com/Kozea/WeasyPrint/pull/423>`_:
  Warn user about broken cairo versions.

Bug fixes:

* `#411 <https://github.com/Kozea/WeasyPrint/pull/411>`_:
  Typos fixed in command-line help.


Version 0.35
------------

Released on 2017-02-25.

Bug fixes:

* `#410 <https://github.com/Kozea/WeasyPrint/pull/410>`_:
  Fix AssertionError in split_text_box.


Version 0.34
------------

Released on 2016-12-21.

Bug fixes:

* `#398 <https://github.com/Kozea/WeasyPrint/issues/398>`_:
  Honor the presentational_hints option for PDFs.
* `#399 <https://github.com/Kozea/WeasyPrint/pull/399>`_:
  Avoid CairoSVG-2.0.0rc* on Python 2.
* `#396 <https://github.com/Kozea/WeasyPrint/issues/396>`_:
  Correctly close files open by mkstemp.
* `#403 <https://github.com/Kozea/WeasyPrint/issues/403>`_:
  Cast the number of columns into int.
* Fix multi-page multi-columns and add related tests.


Version 0.33
------------

Released on 2016-11-28.

New features:

* `#393 <https://github.com/Kozea/WeasyPrint/issues/393>`_:
  Add tests on MacOS.
* `#370 <https://github.com/Kozea/WeasyPrint/issues/370>`_:
  Enable @font-face on MacOS.

Bug fixes:

* `#389 <https://github.com/Kozea/WeasyPrint/issues/389>`_:
  Always update resume_at when splitting lines.
* `#394 <https://github.com/Kozea/WeasyPrint/issues/394>`_:
  Don't build universal wheels.
* `#388 <https://github.com/Kozea/WeasyPrint/issues/388>`_:
  Fix logic when finishing block formatting context.


Version 0.32
------------

Released on 2016-11-17.

New features:

* `#28 <https://github.com/Kozea/WeasyPrint/issues/28>`_:
  Support @font-face on Linux.
* Support CSS fonts level 3 almost entirely, including OpenType features.
* `#253 <https://github.com/Kozea/WeasyPrint/issues/253>`_:
  Support presentational hints (optional).
* Support break-after, break-before and break-inside for pages and columns.
* `#384 <https://github.com/Kozea/WeasyPrint/issues/384>`_:
  Major performance boost.

Bux fixes:

* `#368 <https://github.com/Kozea/WeasyPrint/issues/368>`_:
  Respect white-space for shrink-to-fit.
* `#382 <https://github.com/Kozea/WeasyPrint/issues/382>`_:
  Fix the preferred width for column groups.
* Handle relative boxes in column-layout boxes.

Documentation:

* Add more and more documentation about Windows installation.
* `#355 <https://github.com/Kozea/WeasyPrint/issues/355>`_:
  Add fonts requirements for tests.


Version 0.31
------------

Released on 2016-08-28.

New features:

* `#124 <https://github.com/Kozea/WeasyPrint/issues/124>`_:
  Add MIME sniffing for images.
* `#60 <https://github.com/Kozea/WeasyPrint/issues/60>`_:
  CSS Multi-column Layout.
* `#197 <https://github.com/Kozea/WeasyPrint/pull/197>`_:
  Add hyphens at line breaks activated by a soft hyphen.

Bux fixes:

* `#132 <https://github.com/Kozea/WeasyPrint/pull/132>`_:
  Fix Python 3 compatibility on Windows.

Documentation:

* `#329 <https://github.com/Kozea/WeasyPrint/issues/329>`_:
  Add documentation about installation on Windows.


Version 0.30
------------

Released on 2016-07-18.

WeasyPrint now depends on html5lib-0.999999999.

Bux fixes:

* Fix Acid2
* `#325 <https://github.com/Kozea/WeasyPrint/issues/325>`_:
  Cutting lines is broken in page margin boxes.
* `#334 <https://github.com/Kozea/WeasyPrint/issues/334>`_:
  Newest html5lib 0.999999999 breaks rendering.


Version 0.29
------------

Released on 2016-06-17.

Bug fixes:

* `#263 <https://github.com/Kozea/WeasyPrint/pull/263>`_:
  Don't crash with floats with percents in positions.
* `#323 <https://github.com/Kozea/WeasyPrint/pull/323>`_:
  Fix CairoSVG 2.0 pre-release dependency in Python 2.x.


Version 0.28
------------

Released on 2016-05-16.

Bug fixes:

* `#189 <https://github.com/Kozea/WeasyPrint/issues/189>`_:
  ``white-space: nowrap`` still wraps on hyphens
* `#305 <https://github.com/Kozea/WeasyPrint/issues/305>`_:
  Fix crashes on some tables
* Don't crash when transform matrix isn't invertible
* Don't crash when rendering ratio-only SVG images
* Fix margins and borders on some tables


Version 0.27
------------

Released on 2016-04-08.

New features:

* `#295 <https://github.com/Kozea/WeasyPrint/pull/295>`_:
  Support the 'rem' unit.
* `#299 <https://github.com/Kozea/WeasyPrint/pull/299>`_:
  Enhance the support of SVG images.

Bug fixes:

* `#307 <https://github.com/Kozea/WeasyPrint/issues/307>`_:
  Fix the layout of cells larger than their tables.

Documentation:

* The website is now on GitHub Pages, the documentation is on Read the Docs.
* `#297 <https://github.com/Kozea/WeasyPrint/issues/297>`_:
  Rewrite the CSS chapter of the documentation.


Version 0.26
------------

Released on 2016-01-29.

New features:

* Support the `empty-cells` attribute.
* Respect table, column and cell widths.

Bug fixes:

* `#172 <https://github.com/Kozea/WeasyPrint/issues/172>`_:
  Unable to set table column width on tables td's.
* `#151 <https://github.com/Kozea/WeasyPrint/issues/151>`_:
  Table background colour bleeds beyond table cell boundaries.
* `#260 <https://github.com/Kozea/WeasyPrint/issues/260>`_:
  TypeError: unsupported operand type(s) for +: 'float' and 'str'.
* `#288 <https://github.com/Kozea/WeasyPrint/issues/288>`_:
  Unwanted line-breaks in bold text.
* `#286 <https://github.com/Kozea/WeasyPrint/issues/286>`_:
  AttributeError: 'Namespace' object has no attribute 'attachments'.


Version 0.25
------------

Released on 2015-12-17.

New features:

* Support the 'q' unit.

Bug fixes:

* `#285 <https://github.com/Kozea/WeasyPrint/issues/285>`_:
  Fix a crash happening when splitting lines.
* `#284 <https://github.com/Kozea/WeasyPrint/issues/284>`_:
  Escape parenthesis in PDF links.
* `#280 <https://github.com/Kozea/WeasyPrint/pull/280>`_:
  Replace utf8 with utf-8 for gettext/django compatibility.
* `#269 <https://github.com/Kozea/WeasyPrint/pull/269>`_:
  Add support for use when frozen.
* `#250 <https://github.com/Kozea/WeasyPrint/issues/250>`_:
  Don't crash when attachments are not available.


Version 0.24
------------

Released on 2015-08-04.

New features:

* `#174 <https://github.com/Kozea/WeasyPrint/issues/174>`_:
  Basic support for Named strings.

Bug fixes:

* `#207 <https://github.com/Kozea/WeasyPrint/issues/207>`_:
  Draw rounded corners on replaced boxes.
* `#224 <https://github.com/Kozea/WeasyPrint/pull/224>`_:
  Rely on the font size for rounding bug workaround.
* `#31 <https://github.com/Kozea/WeasyPrint/issues/31>`_:
  Honor the vertical-align property in fixed-height cells.
* `#202 <https://github.com/Kozea/WeasyPrint/issues/202>`_:
  Remove unreachable area/border at bottom of page.
* `#225 <https://github.com/Kozea/WeasyPrint/issues/225>`_:
  Don't allow unknown units during line-height validation.
* Fix some wrong conflict resolutions for table borders with inset
  and outset styles.


Version 0.23
------------

Released on 2014-09-16.

Bug fixes:

* `#196 <https://github.com/Kozea/WeasyPrint/issues/196>`_:
  Use the default image sizing algorithm for images’s preferred size.
* `#194 <https://github.com/Kozea/WeasyPrint/pull/194>`_:
  Try more library aliases with ``dlopen()``.
* `#201 <https://github.com/Kozea/WeasyPrint/pull/201>`_:
  Consider ``page-break-after-avoid`` when pushing floats to the next page.
* `#217 <https://github.com/Kozea/WeasyPrint/issues/217>`_:
  Avoid a crash on zero-sized background images.

Release process:

* Start testing on Python 3.4 on Travis-CI.


Version 0.22
------------

Released on 2014-05-05.

New features:

* `#86 <https://github.com/Kozea/WeasyPrint/pull/86>`_:
  Support gzip and deflate encoding in HTTP responses
* `#177 <https://github.com/Kozea/WeasyPrint/pull/177>`_:
  Support for PDF attachments.

Bug fixes:

* `#169 <https://github.com/Kozea/WeasyPrint/issues/169>`_:
  Fix a crash on percentage-width columns in an auto-width table.
* `#168 <https://github.com/Kozea/WeasyPrint/issues/168>`_:
  Make ``<fieldset>`` a block in the user-agent stylesheet.
* `#175 <https://github.com/Kozea/WeasyPrint/issues/175>`_:
  Fix some ``dlopen()`` library loading issues on OS X.
* `#183 <https://github.com/Kozea/WeasyPrint/issues/183>`_:
  Break to the next page before a float that would overflow the page.
  (It might still overflow if it’s bigger than the page.)
* `#188 <https://github.com/Kozea/WeasyPrint/issues/188>`_:
  Require a recent enough version of Pyphen

Release process:

* Drop Python 3.1 support.
* Set up [Travis CI](https://travis-ci.org/)
  to automatically test all pushes and pull requests.
* Start testing on Python 3.4 locally. (Travis does not support 3.4 yet.)


Version 0.21
------------

Released on 2014-01-11.

New features:

* Add the `overflow-wrap <https://drafts.csswg.org/css-text/#overflow-wrap>`_
  property, allowing line breaks inside otherwise-unbreakable words.
  Thanks Frédérick Deslandes!
* Add the `image-resolution
  <https://drafts.csswg.org/css-images-3/#the-image-resolution>`_ property,
  allowing images to be sized proportionally to their intrinsic size
  at a resolution other than 96 image pixels per CSS ``in``
  (ie. one image pixel per CSS ``px``)

Bug fixes:

* `#145 <https://github.com/Kozea/WeasyPrint/issues/145>`_:
  Fix parsing HTML from an HTTP URL on Python 3.x
* `#40 <https://github.com/Kozea/WeasyPrint/issues/40>`_:
  Use more general hyphenation dictionaries for specific document languages.
  (E.g. use ``hyph_fr.dic`` for ``lang="fr_FR"``.)
* `#26 <https://github.com/Kozea/WeasyPrint/issues/26>`_:
  Fix ``min-width`` and ``max-width`` on floats.
* `#100 <https://github.com/Kozea/WeasyPrint/issues/100>`_:
  Fix a crash on trailing whitespace with ``font-size: 0``
* `#82 <https://github.com/Kozea/WeasyPrint/issues/82>`_:
  Borders on tables with ``border-collapse: collapse`` were sometimes
  drawn at an incorrect position.
* `#30 <https://github.com/Kozea/WeasyPrint/issues/30>`_:
  Fix positioning of images with ``position: absolute``.
* `#118 <https://github.com/Kozea/WeasyPrint/issues/118>`_:
  Fix a crash when using ``position: absolute``
  inside a ``position: relative`` element.
* Fix ``visibility: collapse`` to behave like ``visibility: hidden``
  on elements other than table rows and table columns.
* `#147 <https://github.com/Kozea/WeasyPrint/issues/147>`_ and
  `#153 <https://github.com/Kozea/WeasyPrint/issues/153>`_:
  Fix dependencies to require lxml 3.0 or a more recent version.
  Thanks gizmonerd and Thomas Grainger!
* `#152 <https://github.com/Kozea/WeasyPrint/issues/152>`_:
  Fix a crash on percentage-sized table cells in auto-sized tables.
  Thanks Johannes Duschl!


Version 0.20.2
--------------

Released on 2013-12-18.

* Fix `#146 <https://github.com/Kozea/WeasyPrint/issues/146>`_: don't crash
  when drawing really small boxes with dotted/dashed borders


Version 0.20.1
--------------

Released on 2013-12-16.

* Depend on html5lib >= 0.99 instead of 1.0b3 to fix pip 1.4 support.
* Fix `#74 <https://github.com/Kozea/WeasyPrint/issues/74>`_: don't crash on
  space followed by dot at line break.
* Fix `#78 <https://github.com/Kozea/WeasyPrint/issues/78>`_: nicer colors for
  border-style: ridge/groove/inset/outset.


Version 0.20
------------

Released on 2013-12-14.

* Add support for ``border-radius``.
* Feature `#77 <https://github.com/Kozea/WeasyPrint/issues/77>`_: Add PDF
  metadata from HTML.
* Feature `#12 <https://github.com/Kozea/WeasyPrint/pull/12>`_: Use html5lib.
* Tables: handle percentages for column groups, columns and cells, and values
  for row height.
* Bug fixes:

  * Fix `#84 <https://github.com/Kozea/WeasyPrint/pull/84>`_: don't crash when
    stylesheets are not available.
  * Fix `#101 <https://github.com/Kozea/WeasyPrint/issues/101>`_: use page ids
    instead of page numbers in PDF bookmarks.
  * Use ``logger.warning`` instead of deprecated ``logger.warn``.
  * Add 'font-stretch' in the 'font' shorthand.


Version 0.19.2
--------------

Released on 2013-06-18.

Bug fix release:

* Fix `#88 <https://github.com/Kozea/WeasyPrint/issues/88>`_:
  ``text-decoration: overline`` not being drawn above the text
* Bug fix: Actually draw multiple lines when multiple values are given
  to ``text-decoration``.
* Use the font metrics for text decoration positioning.
* Bug fix: Don't clip the border with ``overflow: hidden``.
* Fix `#99 <https://github.com/Kozea/WeasyPrint/issues/99>`_:
  Regression: JPEG images not loading with cairo 1.8.x.


Version 0.19.1
--------------

Released on 2013-04-30.

Bug fix release:

* Fix incorrect intrinsic width calculation
  leading to unnecessary line breaks in floats, tables, etc.
* Tweak border painting to look better
* Fix unnecessary page break before big tables.
* Fix table row overflowing at the bottom of the page
  when there are margins above the table.
* Fix ``position: fixed`` to actually repeat on every page.
* Fix `#76 <https://github.com/Kozea/WeasyPrint/issues/76>`_:
  repeat ``<thead>`` and ``<tfoot>`` elements on every page,
  even with table border collapsing.


Version 0.19
------------

Released on 2013-04-18.

* Add support for ``linear-gradient()`` and ``radial-gradient``
  in background images.
* Add support for the ``ex`` and ``ch`` length units.
  (``1ex`` is based on the font instead of being always ``0.5em`` as before.)
* Add experimental support for Level 4 hyphenation properties.
* Drop support for CFFI < 0.6 and cairocffi < 0.4.
* Many bug fixes, including:

 * Fix `#54 <https://github.com/Kozea/WeasyPrint/issues/54>`_:
   min/max-width/height on block-level images.
 * Fix `#71 <https://github.com/Kozea/WeasyPrint/issues/71>`_:
   Crash when parsing nested functional notation.


Version 0.18
------------

Released on 2013-03-30.

* Add support for Level 3 backgrounds,
  including multiple background layers per element/box.
* Forward-compatibility with (future releases of) cairocffi 0.4+ and CFFI 0.6+.
* Bug fixes:

  * Avoid some unnecessary line breaks
    for elements sized based on their content (aka. “shrink-to-fit”)
    such as floats and page headers.
  * Allow page breaks between empty blocks.
  * Fix `#66 <https://github.com/Kozea/WeasyPrint/issues/66>`_:
    Resolve images’ auto width from non-auto height and intrinsic ratio.
  * Fix `#21 <https://github.com/Kozea/WeasyPrint/issues/21>`_:
    The ``data:`` URL scheme is case-insensitive.
  * Fix `#53 <https://github.com/Kozea/WeasyPrint/issues/53>`_:
    Crash when backtracking for ``break-before/after: avoid``.


Version 0.17.1
--------------

Released on 2013-03-18.

Bug fixes:

* Fix `#41 <https://github.com/Kozea/WeasyPrint/issues/41>`_:
  GObject initialization when GDK-PixBuf is not installed.
* Fix `#42 <https://github.com/Kozea/WeasyPrint/issues/42>`_:
  absolute URLs without a base URL (ie. document parsed from a string.)
* Fix some whitespace collapsing bugs.
* Fix absolutely-positioned elements inside inline elements.
* Fix URL escaping of image references from CSS.
* Fix `#49 <https://github.com/Kozea/WeasyPrint/issues/49>`_:
  Division by 0 on dashed or dotted border smaller than one dot/dash.
* Fix `#44 <https://github.com/Kozea/WeasyPrint/issues/44>`_:
  bad interaction of ``page-break-before/after: avoid`` and floats.


Version 0.17
------------

Released on 2013-02-27.

* Added `text hyphenation`_ with the ``-weasy-hyphens`` property.
* When a document includes JPEG images, embed them as JPEG in the PDF output.
  This often results in smaller PDF file size
  compared to the default *deflate* compression.
* Switched to using CFFI instead of PyGTK or PyGObject-introspection.
* Layout bug fixes:

  - Correctly trim whitespace at the end of lines.
  - Fix some cases with floats within inline content.

.. _text hyphenation: https://weasyprint.readthedocs.io/en/latest/features.html#css-text-module-level-3-4


Version 0.16
------------

Released on 2012-12-13.

* Add the ``zoom`` parameter to ``HTML.write_pdf`` and
  ``Document.write_pdf() <weasyprint.document.Document.write_pdf>``
* Fix compatibility with old (and buggy) pycairo versions.
  WeasyPrint is now tested on 1.8.8 in addition to the latest.
* Fix layout bugs related to line trailing spaces.


Version 0.15
------------

Released on 2012-10-09.

* Add a low-level API that enables painting pages individually on any
  cairo surface.
* **Backward-incompatible change**: remove the ``HTML.get_png_pages``
  method. The new low-level API covers this functionality and more.
* Add support for the ``font-stretch`` property.
* Add support for ``@page:blank`` to select blank pages.
* New Sphinx-based and improved docs
* Bug fixes:

  - Importing Pango in some PyGTK installations.
  - Layout of inline-blocks with `vertical-align: top` or `bottom`.
  - Do not repeat a block’s margin-top or padding-top after a page break.
  - Performance problem with large tables split across many pages.
  - Anchors and hyperlinks areas now follow CSS transforms.
    Since PDF links have to be axis-aligned rectangles, the bounding box
    is used. This may be larger than expected with rotations that are
    not a multiple of 90 degrees.


Version 0.14
------------

Released on 2012-08-03.

* Add a public API to choose media type used for @media.
  (It still defaults to ``print``). Thanks Chung Lu!
* Add ``--base-url`` and ``--resolution`` to the command-line API, making it
  as complete as the Python one.
* Add support for the ``<base href="...">`` element in HTML.
* Add support for CSS outlines
* Switch to gdk-pixbuf instead of Pystacia for loading raster images.
* Bug fixes:

  - Handling of filenames and URLs on Windows
  - Unicode filenames with older version of py2cairo
  - ``base_url`` now behaves as expected when set to a directory name.
  - Make some tests more robust


Version 0.13
------------

Released on 2012-07-23.

* Add support for PyGTK, as an alternative to PyGObject + introspection.
  This should make WeasyPrint easier to run on platforms that not not have
  packages for PyGObject 3.x yet.
* Bug fix: crash in PDF outlines for some malformed HTML documents


Version 0.12
------------

Released on 2012-07-19.

* Add support for collapsed borders on tables. This is currently incompatible
  with repeating header and footer row groups on each page: headers and footers
  are treated as normal row groups on table with ``border-collapse: collapse``.
* Add ``url_fetcher`` to the public API. This enables users to hook into
  WeasyPrint for fetching linked stylesheets or images, eg. to generate them
  on the fly without going through the network.
  This enables the creation of `Flask-WeasyPrint
  <https://packages.python.org/Flask-WeasyPrint/>`_.


Version 0.11
------------

Released on 2012-07-04.

* Add support for floats and clear.
  Together with various bug fixes, this enables WeasyPrint to pass the Acid2
  test! Acid2 is now part of our automated test suite.
* Add support for the width, min-width, max-width, height, min-height and
  max-height properties in @page. The size property is now the size of the
  page’s containing block.
* Switch the Variable Dimension rules to `the new proposal
  <https://github.com/SimonSapin/css/blob/master/margin-boxes-variable-dimension>`_.
  The previous implementation was broken in many cases.
* The ``image-rendering``, ``transform``, ``transform-origin`` and ``size``
  properties are now unprefixed. The prefixed form (eg. -weasy-size) is ignored
  but gives a specific warning.


Version 0.10
------------

Released on 2012-06-25.

* Add ``get_png_pages()`` to the public API. It returns each page as
  a separate PNG image.
* Add a ``resolution`` parameter for PNG.
* Add *WeasyPrint Navigator*, a web application that shows WeasyPrint’s
  output with clickable links. Yes, that’s a browser in your browser.
  Start it with ``python -m weasyprint.navigator``
* Add support for `vertical-align: top` and `vertical-align: bottom`
* Add support for `page-break-before: avoid` and `page-break-after: avoid`
* Bug fixes


Version 0.9
-----------

Released on 2012-06-04.

* Relative, absolute and fixed positioning
* Proper painting order (z-index)
* In PDF: support for internal and external hyperlinks as well as bookmarks.
* Added the ``tree`` parameter to the ``HTML`` class: accepts a parsed lxml
  object.
* Bug fixes, including many crashes.

Bookmarks can be controlled by the ``-weasy-bookmark-level`` and
``-weasy-bookmark-label`` properties, as described in `CSS Generated Content
for Paged Media Module <https://drafts.csswg.org/css-gcpm-3/#bookmarks>`_.

The default UA stylesheet sets a matching bookmark level on all ``<h1>``
to ``<h6>`` elements.


Version 0.8
-----------

Released on 2012-05-07.

* Switch from cssutils to tinycss_ as the CSS parser.
* Switch to the new cssselect_, almost all level 3 selectors are supported now.
* Support for inline blocks and inline tables
* Automatic table layout (column widths)
* Support for the ``min-width``, ``max-width``, ``min-height`` and
  ``max-height`` properties, except on table-related and page-related boxes.
* Speed improvements on big stylesheets / small documents thanks to tinycss.
* Many bug fixes

.. _tinycss: https://packages.python.org/tinycss/
.. _cssselect: https://packages.python.org/cssselect/


Version 0.7.1
-------------

Released on 2012-03-21.

Change the license from AGPL to BSD.


Version 0.7
-----------

Released on 2012-03-21.

* Support page breaks between table rows
* Support for the ``orphans`` and ``widows`` properties.
* Support for ``page-break-inside: avoid``
* Bug fixes

Only avoiding page breaks before/after an element is still missing.


Version 0.6.1
-------------

Released on 2012-03-01.

Fix a packaging bug. (Remove use_2to3 in setup.py. We use the same
codebase for Python 2 and 3.)


Version 0.6
-----------

Released on 2012-02-29.

* *Backward incompatible*: completely change the Python API. See the
  documentation:
  https://weasyprint.readthedocs.io/en/latest/tutorial.html#as-a-python-library
* *Backward incompatible*: Proper margin collapsing.
  This changes how blocks are rendered: adjoining margins "collapse"
  (their maximum is used) instead of accumulating.
* Support images in ``embed`` or ``object`` elements.
* Switch to pystacia instead of PIL for raster images
* Add compatibility with CPython 2.6 and 3.2. (Previously only 2.7
  was supported)
* Many bug fixes


Version 0.5
-----------

Released on 2012-02-08.

* Support for the ``overflow`` and ``clip`` properties.
* Support for the ``opacity`` property from CSS3 Colors.
* Support for CSS 2D Transforms. These are prefixed, so you need to use
  ``-weasy-transform`` and ``-weasy-transform-origin``.


Version 0.4
-----------

Released on 2012-02-07.

* Support ``text-align: justify``, ``word-spacing`` and ``letter-spacing``.
* Partial support for CSS3 Paged Media: page size and margin boxes with
  page-based counters.
* All CSS 2.1 border styles
* Fix SVG images with non-pixel units. Requires CairoSVG 0.3
* Support for ``page-break-before`` and ``page-break-after``, except for
  the value ``avoid``.
* Support for the ``background-clip``, ``background-origin`` and
  ``background-size`` from CSS3 (but still with a single background
  per element)
* Support for the ``image-rendering`` from SVG. This one is prefixed,
  use ``-weasy-image-rendering``. It only has an effect on PNG output.


Version 0.3.1
-------------

Released on 2011-12-14.

Compatibility with CairoSVG 0.1.2


Version 0.3
-----------

Released on 2011-12-13.

* **Backward-incompatible change:** the 'size' property is now prefixed (since
  it is in an experimental specification). Use '-weasy-size' instead.
* cssutils 0.9.8 or higher is now required.
* Support SVG images with CairoSVG
* Support generated content: the ``:before`` and ``:after`` pseudo-elements,
  the ``content``, ``quotes`` and ``counter-*`` properties.
* Support ordered lists: all CSS 2.1 values of the ``list-style-type`` property.
* New user-agent stylesheet with HTML 5 elements and automatic quotes for many
  languages. Thanks Peter Moulder!
* Disable cssutils validation warnings, they are redundant with WeasyPrint’s.
* Add ``--version`` to the command-line script.
* Various bug fixes


Version 0.2
-----------

Released on 2011-11-25.

* Support for tables.
* Support the `box-sizing` property from CSS 3 Basic User Interface
* Support all values of vertical-align except top and bottom. They are
  interpreted as text-top and text-bottom.
* Minor bug fixes

Tables have some limitations:
Only the fixed layout and separate border model are supported.
There are also no page break inside tables so a table higher
than a page will overflow.


Version 0.1
-----------

Released on 2011-10-28.

First packaged release. Supports "simple" CSS 2.1 pages: there is no
support for floats, tables, or absolute positioning. Other than that
most of CSS 2.1 is supported, as well as CSS 3 Colors and Selectors.


================================================
FILE: docs/common_use_cases.rst
================================================
Common Use Cases
================


Include in Web Applications
---------------------------

Using WeasyPrint in web applications sometimes requires attention on some
details.

Security Problems
.................

First of all, rendering untrusted HTML and CSS files can lead to :ref:`security
problems <Security>`. Please be sure to carefully follow the different proposed
solutions if you allow your users to modify the source of the rendered
documents in any way.

Rights Management
.................

Another problem is rights management: you often need to render templates that
can only be accessed by authenticated users, and WeasyPrint installed on the
server doesn’t send the same cookies as the ones sent by the users. Extensions
such as Flask-WeasyPrint_ (for Flask_) or Django-WeasyPrint_ (for Django_)
solve this issue with a small amount of code. If you use another framework, you
can read these extensions and probably find an equivalent workaround.

.. _Flask-Weasyprint: https://github.com/Kozea/Flask-WeasyPrint
.. _Flask: https://flask.palletsprojects.com/
.. _Django-WeasyPrint: https://github.com/fdemmer/django-weasyprint
.. _Django: https://www.djangoproject.com/

Server Side Requests & Self-Signed SSL Certificates
...................................................

If your server is requesting data from itself, you may encounter a self-signed
certificate error, even if you have a valid certificate.

You need to add yourself as a Certificate Authority, so that your self-signed
SSL certificates can be requested.

.. code-block:: bash

   # If you have not yet created a certificate.
   sudo openssl req -x509 \
       -sha256 \
       -nodes \
       -newkey rsa:4096 \
       -days 365 \
       -keyout localhost.key \
       -out localhost.crt

   # Follow the prompts about your certificate and the domain name.
   openssl x509 -text -noout -in localhost.crt

Add your new self-signed SSL certificate to your nginx.conf, below the line
``server_name 123.123.123.123;``:

.. code-block:: bash

   ssl_certificate /etc/ssl/certs/localhost.crt;
   ssl_certificate_key /etc/ssl/private/localhost.key;

The SSL certificate will be valid when accessing your website from the
internet. However, images will not render when requesting files from the same
server.

You will need to add your new self-signed certificates as trusted:

.. code-block:: bash

   sudo cp /etc/ssl/certs/localhost.crt /usr/local/share/ca-certificates/localhost.crt
   sudo cp /etc/ssl/private/localhost.key /usr/local/share/ca-certificates/localhost.key

   # Update the certificate authority trusted certificates.
   sudo update-ca-certificates

   # Export your newly updated Certificate Authority Bundle file.
   # If using Django, it will use the newly signed certificate authority as
   # valid and images will load properly.
   sudo tee -a /etc/environment <<< 'export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt'


Adjust Document Dimensions
--------------------------

WeasyPrint does not provide support for adjusting page size or document margins
via command-line flags. This is best accomplished with the CSS ``@page``
at-rule. Consider the following example:

.. code-block:: css

  @page {
    size: Letter; /* Change from the default size of A4 */
    margin: 3cm; /* Set margin on each page */
  }

There is much more which can be achieved with the ``@page`` at-rule,
such as page numbers, headers, etc. Read more about the page_ at-rule.

.. _page: https://developer.mozilla.org/en-US/docs/Web/CSS/@page


Generate Specialized PDFs
-------------------------

WeasyPrint can generate different PDF variants, including PDF/UA and PDF/A. The
feature is available by using the ``--pdf-variant`` CLI option, or the
``pdf_variant`` Python parameter of :func:`HTML.write_pdf
<weasyprint.HTML.write_pdf>`.

.. code-block:: python

  from weasyprint import HTML
  HTML(string="<p>document</p>").write_pdf("document.pdf", pdf_variant="pdf/a-3u")

.. code-block:: sh

  $ weasyprint document.html --pdf-variant="pdf/ua-1" document.pdf

The different supported variants can be listed using ``weasyprint --help``.

Even if WeasyPrint tries to generate valid documents, the result is not
guaranteed: the HTML, CSS and PDF features chosen by the user must follow the
limitations defined by the different specifications.

PDF/A (Archiving)
.................

PDF/A documents are specialized for archiving purposes. They are a simple
subset of PDF, with a lot of limitations: no audio, video or JavaScript,
defined color spaces, embedded fonts, etc.

If possible, PDF/A-3u should be preferred: it allows transparency layers that
are forbidden in A-1, and arbitrary formats for attached files that are
forbidden in A-2. The "u" part of the variant indicates that the PDF text is
available as Unicode.

PDF/A documents include a PDF identifier, that is mainly useful to indicate
that a PDF is a new version of another PDF. By default, WeasyPrint generates a
valid PDF identifier, but you can provide your own with the
``--pdf-identifier`` CLI option or ``pdf_identifier`` Python parameter.

If your document includes images, you must set the ``image-rendering:
crisp-edges`` property to avoid anti-aliasing, that is forbidden by PDF/A.

PDF/UA (Universal Accessibility)
................................

PDF/UA documents are specialized for accessibility purposes. They include extra
metadata that define document information and content structure.

The main constraint to get valid PDF/UA documents is to use a correct HTML
structure, to avoid inconsistencies in the PDF structure. The HTML order is
also used to define the order of the PDF content.

Some information is required in your HTML file, including a ``<ti
Download .txt
gitextract_594bexrt/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── doconfly.yml
│       ├── exe.yml
│       ├── release.yml
│       ├── test_pdfa.yml
│       ├── test_pdfua.yml
│       ├── test_samples.yml
│       └── tests.yml
├── .gitignore
├── LICENSE
├── README.rst
├── docs/
│   ├── api_reference.rst
│   ├── changelog.rst
│   ├── common_use_cases.rst
│   ├── conf.py
│   ├── contribute.rst
│   ├── first_steps.rst
│   ├── going_further.rst
│   ├── index.rst
│   ├── manpage.rst
│   └── support.rst
├── pyproject.toml
├── tests/
│   ├── __init__.py
│   ├── conftest.py
│   ├── css/
│   │   ├── __init__.py
│   │   ├── test_common.py
│   │   ├── test_counters.py
│   │   ├── test_descriptors.py
│   │   ├── test_errors.py
│   │   ├── test_expanders.py
│   │   ├── test_fonts.py
│   │   ├── test_layers.py
│   │   ├── test_math.py
│   │   ├── test_nesting.py
│   │   ├── test_pages.py
│   │   ├── test_target.py
│   │   ├── test_ua.py
│   │   ├── test_validation.py
│   │   └── test_variables.py
│   ├── draw/
│   │   ├── __init__.py
│   │   ├── svg/
│   │   │   ├── __init__.py
│   │   │   ├── test_bounding_box.py
│   │   │   ├── test_clip.py
│   │   │   ├── test_defs.py
│   │   │   ├── test_gradients.py
│   │   │   ├── test_images.py
│   │   │   ├── test_markers.py
│   │   │   ├── test_opacity.py
│   │   │   ├── test_paths.py
│   │   │   ├── test_patterns.py
│   │   │   ├── test_shapes.py
│   │   │   ├── test_text.py
│   │   │   ├── test_transform.py
│   │   │   ├── test_units.py
│   │   │   └── test_visibility.py
│   │   ├── test_absolute.py
│   │   ├── test_background.py
│   │   ├── test_before_after.py
│   │   ├── test_box.py
│   │   ├── test_cmyk_color_profiles.py
│   │   ├── test_column.py
│   │   ├── test_current_color.py
│   │   ├── test_float.py
│   │   ├── test_footnote.py
│   │   ├── test_footnote_column.py
│   │   ├── test_gradient.py
│   │   ├── test_image.py
│   │   ├── test_leader.py
│   │   ├── test_list.py
│   │   ├── test_opacity.py
│   │   ├── test_overflow.py
│   │   ├── test_page.py
│   │   ├── test_table.py
│   │   ├── test_text.py
│   │   ├── test_transform.py
│   │   ├── test_visibility.py
│   │   └── test_whitespace.py
│   ├── layout/
│   │   ├── __init__.py
│   │   ├── test_block.py
│   │   ├── test_column.py
│   │   ├── test_flex.py
│   │   ├── test_float.py
│   │   ├── test_footnotes.py
│   │   ├── test_grid.py
│   │   ├── test_image.py
│   │   ├── test_inline.py
│   │   ├── test_inline_block.py
│   │   ├── test_list.py
│   │   ├── test_logical.py
│   │   ├── test_page.py
│   │   ├── test_position.py
│   │   ├── test_preferred.py
│   │   └── test_table.py
│   ├── resources/
│   │   ├── acid2-reference.html
│   │   ├── acid2-test.html
│   │   ├── cmyk.icc
│   │   ├── doc1.html
│   │   ├── doc1_UTF-16BE.html
│   │   ├── latin1-test.css
│   │   ├── mini_ua.css
│   │   ├── sheet2.css
│   │   ├── sub_directory/
│   │   │   └── sheet1.css
│   │   ├── tests_ua.css
│   │   ├── user.css
│   │   ├── utf8-test.css
│   │   ├── weasyprint.otb
│   │   └── weasyprint.otf
│   ├── test_acid2.py
│   ├── test_api.py
│   ├── test_boxes.py
│   ├── test_fonts.py
│   ├── test_pdf.py
│   ├── test_presentational_hints.py
│   ├── test_stacking.py
│   ├── test_text.py
│   ├── test_unicode.py
│   ├── test_url.py
│   └── testing_utils.py
└── weasyprint/
    ├── __init__.py
    ├── __main__.py
    ├── anchors.py
    ├── css/
    │   ├── __init__.py
    │   ├── computed_values.py
    │   ├── counters.py
    │   ├── functions.py
    │   ├── html5_ph.css
    │   ├── html5_ua.css
    │   ├── html5_ua_form.css
    │   ├── media_queries.py
    │   ├── properties.py
    │   ├── targets.py
    │   ├── tokens.py
    │   ├── units.py
    │   └── validation/
    │       ├── __init__.py
    │       ├── descriptors.py
    │       ├── expanders.py
    │       └── properties.py
    ├── document.py
    ├── draw/
    │   ├── __init__.py
    │   ├── border.py
    │   ├── color.py
    │   └── text.py
    ├── formatting_structure/
    │   ├── boxes.py
    │   └── build.py
    ├── html.py
    ├── images.py
    ├── layout/
    │   ├── __init__.py
    │   ├── absolute.py
    │   ├── background.py
    │   ├── block.py
    │   ├── column.py
    │   ├── flex.py
    │   ├── float.py
    │   ├── grid.py
    │   ├── inline.py
    │   ├── leader.py
    │   ├── min_max.py
    │   ├── page.py
    │   ├── percent.py
    │   ├── preferred.py
    │   ├── replaced.py
    │   └── table.py
    ├── logger.py
    ├── matrix.py
    ├── pdf/
    │   ├── __init__.py
    │   ├── anchors.py
    │   ├── debug.py
    │   ├── fonts.py
    │   ├── metadata.py
    │   ├── pdfa.py
    │   ├── pdfua.py
    │   ├── pdfx.py
    │   ├── sRGB2014.icc
    │   ├── stream.py
    │   └── tags.py
    ├── stacking.py
    ├── svg/
    │   ├── __init__.py
    │   ├── bounding_box.py
    │   ├── css.py
    │   ├── defs.py
    │   ├── images.py
    │   ├── path.py
    │   ├── shapes.py
    │   ├── text.py
    │   └── utils.py
    ├── text/
    │   ├── constants.py
    │   ├── ffi.py
    │   ├── fonts.py
    │   └── line_break.py
    └── urls.py
Download .txt
Showing preview only (232K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2695 symbols across 145 files)

FILE: tests/conftest.py
  function document_write_png (line 26) | def document_write_png(document, target=None, resolution=96, antialiasin...
  function html_write_png (line 78) | def html_write_png(document, target=None, font_config=None, counter_styl...
  function test_filename (line 88) | def test_filename(filename):
  function assert_pixels (line 95) | def assert_pixels(request, *args, **kwargs):
  function assert_same_renderings (line 101) | def assert_same_renderings(request, *args, **kwargs):
  function assert_different_renderings (line 107) | def assert_different_renderings(request, *args, **kwargs):
  function assert_pixels_equal (line 113) | def assert_pixels_equal(request, *args, **kwargs):

FILE: tests/css/test_common.py
  function test_find_stylesheets (line 16) | def test_find_stylesheets():
  function test_annotate_document (line 42) | def test_annotate_document():
  function test_important (line 132) | def test_important():
  function test_units (line 222) | def test_units(value, width):
  function test_recursive_lh (line 240) | def test_recursive_lh(property):
  function test_media_queries (line 256) | def test_media_queries(media, width, warning):

FILE: tests/css/test_counters.py
  function test_counters_1 (line 12) | def test_counters_1():
  function test_counters_2 (line 40) | def test_counters_2():
  function test_counters_3 (line 91) | def test_counters_3():
  function test_counters_4 (line 122) | def test_counters_4():
  function test_counters_5 (line 168) | def test_counters_5():
  function test_counters_6 (line 191) | def test_counters_6():
  function test_counters_7 (line 203) | def test_counters_7():
  function test_counters_8 (line 222) | def test_counters_8():
  function test_counters_9 (line 241) | def test_counters_9():
  function test_counter_styles_1 (line 268) | def test_counter_styles_1():
  function test_counter_styles_2 (line 297) | def test_counter_styles_2():
  function test_counter_styles_3 (line 331) | def test_counter_styles_3():
  function test_counter_styles_4 (line 346) | def test_counter_styles_4():
  function test_counter_styles_5 (line 362) | def test_counter_styles_5():
  function test_counter_styles_6 (line 378) | def test_counter_styles_6():
  function test_counter_styles_7 (line 390) | def test_counter_styles_7():
  function test_counter_styles_8 (line 402) | def test_counter_styles_8():
  function test_counter_styles_9 (line 414) | def test_counter_styles_9():
  function test_counter_styles_10 (line 426) | def test_counter_styles_10():
  function test_counter_styles_11 (line 445) | def test_counter_styles_11():
  function test_counter_symbols (line 472) | def test_counter_symbols(arguments, values):
  function test_list_style_types (line 499) | def test_list_style_types(style_type, values):
  function test_list_style_type_empty_string (line 521) | def test_list_style_type_empty_string():
  function test_counter_set (line 526) | def test_counter_set():
  function test_counter_multiple_extends (line 588) | def test_counter_multiple_extends():

FILE: tests/css/test_descriptors.py
  function test_font_face_1 (line 13) | def test_font_face_1():
  function test_font_face_2 (line 30) | def test_font_face_2():
  function test_font_face_3 (line 54) | def test_font_face_3():
  function test_font_face_4 (line 70) | def test_font_face_4():
  function test_font_face_5 (line 87) | def test_font_face_5():
  function test_font_face_bad_1 (line 107) | def test_font_face_bad_1():
  function test_font_face_bad_2 (line 134) | def test_font_face_bad_2():
  function test_font_face_bad_3 (line 144) | def test_font_face_bad_3():
  function test_font_face_bad_4 (line 154) | def test_font_face_bad_4():
  function test_font_face_bad_5 (line 164) | def test_font_face_bad_5():
  function test_font_face_bad_6 (line 176) | def test_font_face_bad_6():
  function test_font_face_bad_7 (line 188) | def test_font_face_bad_7():
  function test_counter_style_invalid (line 207) | def test_counter_style_invalid(rule):

FILE: tests/css/test_errors.py
  function test_warnings (line 24) | def test_warnings(source, messages):
  function test_warnings_stylesheet (line 33) | def test_warnings_stylesheet():
  function test_error_recovery (line 45) | def test_error_recovery(style):

FILE: tests/css/test_expanders.py
  function expand_to_dict (line 14) | def expand_to_dict(css, expected_error=None):
  function assert_invalid (line 34) | def assert_invalid(css, message='invalid'):
  function test_empty_expander_value (line 40) | def test_empty_expander_value(expander):
  function test_text_decoration (line 64) | def test_text_decoration(rule, result):
  function test_text_decoration_invalid (line 76) | def test_text_decoration_invalid(rule):
  function test_four_sides (line 119) | def test_four_sides(rule, result):
  function test_four_sides_warning (line 124) | def test_four_sides_warning():
  function test_four_sides_invalid (line 136) | def test_four_sides_invalid(rule):
  function test_borders (line 174) | def test_borders(rule, result):
  function test_borders_invalid (line 179) | def test_borders_invalid():
  function test_list_style (line 216) | def test_list_style(rule, result):
  function test_list_style_warning (line 221) | def test_list_style_warning():
  function test_list_style_invalid (line 232) | def test_list_style_invalid(rule):
  function test_background (line 325) | def test_background(rule, result):
  function test_background_invalid (line 342) | def test_background_invalid(rule):
  function test_border_radius (line 391) | def test_border_radius(rule, result):
  function test_border_radius_invalid (line 406) | def test_border_radius_invalid(rule, message):
  function test_border_image (line 444) | def test_border_image(rule, result):
  function test_border_image_invalid (line 461) | def test_border_image_invalid(rule, reason):
  function test_mask_border (line 509) | def test_mask_border(rule, result):
  function test_mask_border_invalid (line 528) | def test_mask_border_invalid(rule, reason):
  function test_font (line 558) | def test_font(rule, result):
  function test_font_invalid (line 577) | def test_font_invalid(rule, message):
  function test_font_variant (line 614) | def test_font_variant(rule, result):
  function test_font_variant_invalid (line 631) | def test_font_variant_invalid(rule):
  function test_word_wrap (line 636) | def test_word_wrap():
  function test_flex (line 662) | def test_flex(rule, result):
  function test_flex_invalid (line 673) | def test_flex_invalid(rule):
  function test_flex_flow (line 685) | def test_flex_flow(rule, result):
  function test_flex_flow_invalid (line 697) | def test_flex_flow_invalid(rule):
  function test_grid_column_row (line 712) | def test_grid_column_row(rule, result):
  function test_grid_column_row_invalid (line 729) | def test_grid_column_row_invalid(rule):
  function test_grid_area (line 764) | def test_grid_area(rule, result):
  function test_grid_area_invalid (line 782) | def test_grid_area_invalid(rule):
  function test_grid_template (line 811) | def test_grid_template(rule, result):
  function test_grid_template_invalid (line 825) | def test_grid_template_invalid(rule):
  function test_grid (line 871) | def test_grid(rule, result):
  function test_grid_invalid (line 889) | def test_grid_invalid(rule):
  function test_page_break (line 900) | def test_page_break(rule, result):
  function test_page_break_invalid (line 909) | def test_page_break_invalid(rule):
  function test_page_break_inside (line 918) | def test_page_break_inside(rule, result):
  function test_page_break_inside_invalid (line 926) | def test_page_break_inside_invalid(rule):
  function test_columns (line 936) | def test_columns(rule, result):
  function test_columns_invalid (line 945) | def test_columns_invalid(rule, reason):
  function test_line_clamp (line 962) | def test_line_clamp(rule, result):
  function test_line_clamp_invalid (line 973) | def test_line_clamp_invalid(rule, reason):
  function test_text_align (line 986) | def test_text_align(rule, result):
  function test_text_align_invalid (line 1000) | def test_text_align_invalid(rule, reason):

FILE: tests/css/test_fonts.py
  function test_font_size (line 37) | def test_font_size(parent_css, parent_size, child_css, child_size):
  function test_line_height_inheritance (line 50) | def test_line_height_inheritance():

FILE: tests/css/test_layers.py
  function test_layers (line 75) | def test_layers(style):

FILE: tests/css/test_math.py
  function test_math_functions (line 76) | def test_math_functions(width):
  function test_math_functions_error (line 219) | def test_math_functions_error(width):
  function test_math_functions_percentage_and_font_unit (line 229) | def test_math_functions_percentage_and_font_unit(css_property):
  function test_math_functions_display_size (line 252) | def test_math_functions_display_size(display):
  function test_math_functions_hyphenate (line 268) | def test_math_functions_hyphenate():
  function test_math_functions_gradient (line 278) | def test_math_functions_gradient():
  function test_math_functions_color (line 288) | def test_math_functions_color():
  function test_math_functions_gradient_color (line 297) | def test_math_functions_gradient_color():
  function test_math_image_min_content_calc (line 306) | def test_math_image_min_content_calc():
  function test_math_image_min_content_auto_width_calc (line 322) | def test_math_image_min_content_auto_width_calc():
  function test_math_image_min_content_auto_width_height_calc (line 337) | def test_math_image_min_content_auto_width_height_calc():
  function test_math_table_margin (line 351) | def test_math_table_margin():
  function test_math_grid_padding (line 356) | def test_math_grid_padding():
  function test_math_table_column (line 366) | def test_math_table_column():

FILE: tests/css/test_nesting.py
  function test_nesting_block (line 19) | def test_nesting_block(style):

FILE: tests/css/test_pages.py
  function test_page (line 14) | def test_page():
  function test_page_selectors (line 133) | def test_page_selectors(style, selectors):
  function test_named_pages (line 139) | def test_named_pages():

FILE: tests/css/test_target.py
  function test_target_counter (line 7) | def test_target_counter():
  function test_target_counter_attr (line 37) | def test_target_counter_attr():
  function test_target_counters (line 67) | def test_target_counters():
  function test_target_text (line 101) | def test_target_text():
  function test_target_text_whitespace_around_target (line 136) | def test_target_text_whitespace_around_target():
  function test_target_float (line 156) | def test_target_float():
  function test_target_absolute (line 178) | def test_target_absolute():
  function test_target_absolute_non_root (line 202) | def test_target_absolute_non_root():

FILE: tests/css/test_ua.py
  function test_ua_stylesheets (line 12) | def test_ua_stylesheets(css):

FILE: tests/css/test_validation.py
  function get_value (line 16) | def get_value(css, expected_error=None, level=None):
  function get_default_value (line 34) | def get_default_value(values, index, default):
  function assert_invalid (line 40) | def assert_invalid(css, message='invalid', level=None):
  function test_not_print (line 45) | def test_not_print():
  function test_unstable_prefix (line 50) | def test_unstable_prefix():
  function test_normal_prefix (line 57) | def test_normal_prefix():
  function test_unknown_prefix (line 63) | def test_unknown_prefix():
  function test_empty_property_value (line 72) | def test_empty_property_value(prop):
  function test_clip (line 81) | def test_clip(rule, value):
  function test_clip_invalid (line 92) | def test_clip_invalid(rule):
  function test_counters (line 105) | def test_counters(rule, value):
  function test_counters_warning (line 113) | def test_counters_warning(rule, warning):
  function test_counters_invalid (line 122) | def test_counters_invalid(rule):
  function test_spacing (line 133) | def test_spacing(rule, value):
  function test_spacing_invalid (line 142) | def test_spacing_invalid(rule):
  function test_text_decoration_line (line 152) | def test_text_decoration_line(rule, value):
  function test_text_decoration_style (line 163) | def test_text_decoration_style(rule, value):
  function test_size (line 179) | def test_size(rule, value):
  function test_size_invalid (line 190) | def test_size_invalid(rule):
  function test_transform (line 204) | def test_transform(rule, value):
  function test_transform_invalid (line 216) | def test_transform_invalid(rule):
  function test_background_image_invalid (line 223) | def test_background_image_invalid(rule):
  function test_background_position (line 274) | def test_background_position(rule, value):
  function test_background_position_invalid (line 285) | def test_background_position_invalid(rule):
  function test_font_family_invalid (line 294) | def test_font_family_invalid(rule):
  function test_line_height (line 308) | def test_line_height(rule, value):
  function test_line_height_invalid (line 319) | def test_line_height_invalid(rule):
  function test_list_style_type_invalid (line 334) | def test_list_style_type_invalid(rule):
  function test_image_orientation (line 349) | def test_image_orientation(rule, value):
  function test_image_orientation_invalid (line 366) | def test_image_orientation_invalid(rule):
  function test_border_image_slice (line 379) | def test_border_image_slice(rule, value):
  function test_border_image_slice_invalid (line 394) | def test_border_image_slice_invalid(rule):
  function test_border_image_width (line 409) | def test_border_image_width(rule, value):
  function test_border_image_width_invalid (line 425) | def test_border_image_width_invalid(rule):
  function test_border_image_outset (line 436) | def test_border_image_outset(rule, value):
  function test_border_image_outset_invalid (line 452) | def test_border_image_outset_invalid(rule):
  function test_border_image_repeat (line 462) | def test_border_image_repeat(rule, value):
  function test_border_image_repeat_invalid (line 474) | def test_border_image_repeat_invalid(rule):
  function test_mask_border_slice (line 487) | def test_mask_border_slice(rule, value):
  function test_mask_border_slice_invalid (line 502) | def test_mask_border_slice_invalid(rule):
  function test_mask_border_width (line 517) | def test_mask_border_width(rule, value):
  function test_mask_border_width_invalid (line 533) | def test_mask_border_width_invalid(rule):
  function test_mask_border_outset (line 544) | def test_mask_border_outset(rule, value):
  function test_mask_border_outset_invalid (line 560) | def test_mask_border_outset_invalid(rule):
  function test_mask_border_repeat (line 570) | def test_mask_border_repeat(rule, value):
  function test_mask_border_repeat_invalid (line 582) | def test_mask_border_repeat_invalid(rule):
  function test_mask_border_mode (line 592) | def test_mask_border_mode(rule, value):
  function test_mask_border_mode_invalid (line 603) | def test_mask_border_mode_invalid(rule):
  function test_string_set (line 636) | def test_string_set(rule, value):
  function test_string_set_invalid (line 647) | def test_string_set_invalid(rule):
  function test_overflow_wrap (line 657) | def test_overflow_wrap(rule, value):
  function test_overflow_wrap_invalid (line 666) | def test_overflow_wrap_invalid(rule):
  function test_linear_gradient (line 703) | def test_linear_gradient(rule, value):
  function test_linear_gradient_invalid (line 741) | def test_linear_gradient_invalid(rule):
  function test_radial_gradient (line 780) | def test_radial_gradient(rule, value):
  function test_radial_gradient_invalid (line 821) | def test_radial_gradient_invalid(rule):
  function test_grid_auto_columns_rows (line 840) | def test_grid_auto_columns_rows(rule, value):
  function test_grid_auto_columns_rows_invalid (line 857) | def test_grid_auto_columns_rows_invalid(rule):
  function test_grid_auto_flow (line 872) | def test_grid_auto_flow(rule, value):
  function test_grid_auto_flow_invalid (line 890) | def test_grid_auto_flow_invalid(rule):
  function test_grid_template_columns_rows (line 918) | def test_grid_template_columns_rows(rule, value):
  function test_grid_template_columns_rows_invalid (line 933) | def test_grid_template_columns_rows_invalid(rule):
  function test_grid_template_areas (line 950) | def test_grid_template_areas(rule, value):
  function test_grid_template_areas_invalid (line 962) | def test_grid_template_areas_invalid(rule):
  function test_grid_line (line 978) | def test_grid_line(rule, value):
  function test_grid_line_invalid (line 998) | def test_grid_line_invalid(rule):
  function test_align_content (line 1027) | def test_align_content(rule, value):
  function test_align_content_invalid (line 1044) | def test_align_content_invalid(rule):
  function test_align_items (line 1071) | def test_align_items(rule, value):
  function test_align_items_invalid (line 1089) | def test_align_items_invalid(rule):
  function test_align_self (line 1117) | def test_align_self(rule, value):
  function test_align_self_invalid (line 1134) | def test_align_self_invalid(rule):
  function test_justify_content (line 1160) | def test_justify_content(rule, value):
  function test_justify_content_invalid (line 1176) | def test_justify_content_invalid(rule):
  function test_justify_items (line 1209) | def test_justify_items(rule, value):
  function test_justify_items_invalid (line 1225) | def test_justify_items_invalid(rule):
  function test_justify_self (line 1257) | def test_justify_self(rule, value):
  function test_justify_self_invalid (line 1272) | def test_justify_self_invalid(rule):
  function test_colors_invalid (line 1290) | def test_colors_invalid(rule, value):
  function test_color_scheme (line 1308) | def test_color_scheme(rule, value):
  function test_color_scheme_invalid (line 1320) | def test_color_scheme_invalid(rule):

FILE: tests/css/test_variables.py
  function test_variable_simple (line 13) | def test_variable_simple():
  function test_variable_not_computed (line 27) | def test_variable_not_computed():
  function test_variable_inherit (line 41) | def test_variable_inherit():
  function test_variable_inherit_override (line 56) | def test_variable_inherit_override():
  function test_variable_default_unknown (line 71) | def test_variable_default_unknown():
  function test_variable_default_var (line 85) | def test_variable_default_var():
  function test_variable_case_sensitive (line 99) | def test_variable_case_sensitive():
  function test_variable_chain (line 115) | def test_variable_chain():
  function test_variable_double_chain (line 131) | def test_variable_double_chain():
  function test_variable_chain_root (line 148) | def test_variable_chain_root():
  function test_variable_self (line 159) | def test_variable_self():
  function test_variable_loop (line 167) | def test_variable_loop():
  function test_variable_chain_root_missing (line 175) | def test_variable_chain_root_missing():
  function test_variable_chain_root_missing_inherited (line 184) | def test_variable_chain_root_missing_inherited():
  function test_variable_shorthand_margin (line 194) | def test_variable_shorthand_margin():
  function test_variable_shorthand_margin_multiple (line 212) | def test_variable_shorthand_margin_multiple():
  function test_variable_shorthand_margin_invalid (line 230) | def test_variable_shorthand_margin_invalid():
  function test_variable_shorthand_border (line 251) | def test_variable_shorthand_border():
  function test_variable_shorthand_border_side (line 269) | def test_variable_shorthand_border_side():
  function test_variable_shorthand_border_mixed (line 287) | def test_variable_shorthand_border_mixed():
  function test_variable_shorthand_border_mixed_invalid (line 304) | def test_variable_shorthand_border_mixed_invalid():
  function test_variable_shorthand_background (line 332) | def test_variable_shorthand_background(var, background):
  function test_variable_shorthand_background_invalid (line 347) | def test_variable_shorthand_background_invalid(var, background):
  function test_variable_initial (line 361) | def test_variable_initial():
  function test_variable_initial_default (line 377) | def test_variable_initial_default():
  function test_variable_initial_default_var (line 392) | def test_variable_initial_default_var():
  function test_variable_fallback (line 407) | def test_variable_fallback(prop):
  function test_variable_list_content (line 420) | def test_variable_list_content():
  function test_variable_list_display (line 446) | def test_variable_list_display(var, display):
  function test_variable_list_font (line 469) | def test_variable_list_font(var, font):
  function test_variable_in_function (line 486) | def test_variable_in_function():
  function test_same_variable_in_function (line 509) | def test_same_variable_in_function():
  function test_variable_in_nested_function (line 525) | def test_variable_in_nested_function():
  function test_variable_in_function_multiple_values (line 540) | def test_variable_in_function_multiple_values():
  function test_variable_in_variable_in_function (line 566) | def test_variable_in_variable_in_function():
  function test_variable_in_function_missing (line 591) | def test_variable_in_function_missing():
  function test_variable_in_function_in_variable (line 617) | def test_variable_in_function_in_variable():
  function test_variable_and_function_in_function (line 643) | def test_variable_and_function_in_function():

FILE: tests/draw/__init__.py
  function parse_pixels (line 41) | def parse_pixels(pixels):
  function assert_pixels (line 52) | def assert_pixels(name, expected_pixels, html):
  function assert_same_renderings (line 64) | def assert_same_renderings(name, *documents, tolerance=0):
  function assert_different_renderings (line 78) | def assert_different_renderings(name, *documents):
  function assert_pixels_equal (line 94) | def assert_pixels_equal(name, width, height, raw, expected_raw, toleranc...
  function write_png (line 115) | def write_png(name, pixels, width, height):  # pragma: no cover
  function html_to_pixels (line 124) | def html_to_pixels(html):
  function document_to_pixels (line 134) | def document_to_pixels(document):

FILE: tests/draw/svg/test_bounding_box.py
  function test_bounding_box_rect (line 9) | def test_bounding_box_rect(assert_pixels):
  function test_bounding_box_circle (line 35) | def test_bounding_box_circle(assert_pixels):
  function test_bounding_box_ellipse (line 66) | def test_bounding_box_ellipse(assert_pixels):
  function test_bounding_box_line (line 97) | def test_bounding_box_line(assert_pixels):
  function test_bounding_box_polygon (line 124) | def test_bounding_box_polygon(assert_pixels):
  function test_bounding_box_polyline (line 150) | def test_bounding_box_polyline(assert_pixels):
  function test_bounding_box_text (line 176) | def test_bounding_box_text(assert_pixels):
  function test_bounding_box_path_hv (line 201) | def test_bounding_box_path_hv(assert_pixels):
  function test_bounding_box_path_l (line 227) | def test_bounding_box_path_l(assert_pixels):
  function test_bounding_box_path_c (line 254) | def test_bounding_box_path_c(assert_pixels):
  function test_bounding_box_path_s (line 284) | def test_bounding_box_path_s(assert_pixels):
  function test_svg_empty_size (line 313) | def test_svg_empty_size(assert_pixels):
  function test_bounding_box_use_opacity (line 332) | def test_bounding_box_use_opacity(assert_pixels):

FILE: tests/draw/svg/test_clip.py
  function test_clip_path (line 9) | def test_clip_path(assert_pixels):
  function test_clip_path_on_group (line 38) | def test_clip_path_on_group(assert_pixels):
  function test_clip_path_group_on_group (line 70) | def test_clip_path_group_on_group(assert_pixels):
  function test_clip_path_outside_defs (line 102) | def test_clip_path_outside_defs(assert_pixels):

FILE: tests/draw/svg/test_defs.py
  function test_use (line 43) | def test_use(assert_pixels):
  function test_use_base64 (line 48) | def test_use_base64(assert_pixels):
  function test_use_symbol_color (line 54) | def test_use_symbol_color(assert_pixels):

FILE: tests/draw/svg/test_gradients.py
  function test_linear_gradient (line 9) | def test_linear_gradient(assert_pixels):
  function test_linear_gradient_userspace (line 40) | def test_linear_gradient_userspace(assert_pixels):
  function test_linear_gradient_multicolor (line 71) | def test_linear_gradient_multicolor(assert_pixels):
  function test_linear_gradient_multicolor_userspace (line 106) | def test_linear_gradient_multicolor_userspace(assert_pixels):
  function test_linear_gradient_transform (line 141) | def test_linear_gradient_transform(assert_pixels):
  function test_linear_gradient_transform_nested (line 177) | def test_linear_gradient_transform_nested(assert_pixels):
  function test_linear_gradient_transform_repeat (line 214) | def test_linear_gradient_transform_repeat(assert_pixels):
  function test_linear_gradient_userspace_transform (line 250) | def test_linear_gradient_userspace_transform(assert_pixels):
  function test_linear_gradient_userspace_transform_nested (line 286) | def test_linear_gradient_userspace_transform_nested(assert_pixels):
  function test_linear_gradient_transform_repeat_userspace (line 323) | def test_linear_gradient_transform_repeat_userspace(assert_pixels):
  function test_linear_gradient_repeat (line 359) | def test_linear_gradient_repeat(assert_pixels):
  function test_linear_gradient_repeat_long (line 402) | def test_linear_gradient_repeat_long(assert_pixels):
  function test_linear_gradient_repeat_userspace (line 445) | def test_linear_gradient_repeat_userspace(assert_pixels):
  function test_linear_gradient_reflect (line 488) | def test_linear_gradient_reflect(assert_pixels):
  function test_linear_gradient_reflect_userspace (line 531) | def test_linear_gradient_reflect_userspace(assert_pixels):
  function test_linear_gradient_inherit_attributes (line 574) | def test_linear_gradient_inherit_attributes(assert_pixels):
  function test_linear_gradient_inherit_children (line 607) | def test_linear_gradient_inherit_children(assert_pixels):
  function test_linear_gradient_inherit_no_override (line 640) | def test_linear_gradient_inherit_no_override(assert_pixels):
  function test_radial_gradient (line 676) | def test_radial_gradient(assert_pixels):
  function test_radial_gradient_transform (line 710) | def test_radial_gradient_transform(assert_pixels):
  function test_radial_gradient_transform_nested (line 745) | def test_radial_gradient_transform_nested(assert_pixels):
  function test_radial_gradient_userspace (line 781) | def test_radial_gradient_userspace(assert_pixels):
  function test_radial_gradient_userspace_transform (line 814) | def test_radial_gradient_userspace_transform(assert_pixels):
  function test_radial_gradient_userspace_transform_nested (line 848) | def test_radial_gradient_userspace_transform_nested(assert_pixels):
  function test_radial_gradient_multicolor (line 883) | def test_radial_gradient_multicolor(assert_pixels):
  function test_radial_gradient_multicolor_userspace (line 919) | def test_radial_gradient_multicolor_userspace(assert_pixels):
  function test_radial_gradient_repeat (line 955) | def test_radial_gradient_repeat(assert_pixels):
  function test_radial_gradient_reflect (line 991) | def test_radial_gradient_reflect(assert_pixels):
  function test_radial_gradient_inherit_attributes (line 1027) | def test_radial_gradient_inherit_attributes(assert_pixels):
  function test_radial_gradient_inherit_children (line 1061) | def test_radial_gradient_inherit_children(assert_pixels):
  function test_radial_gradient_inherit_no_override (line 1095) | def test_radial_gradient_inherit_no_override(assert_pixels):
  function test_gradient_opacity (line 1132) | def test_gradient_opacity(assert_pixels):
  function test_gradient_bad_url (line 1164) | def test_gradient_bad_url(assert_pixels, url):

FILE: tests/draw/svg/test_images.py
  function test_image_svg (line 11) | def test_image_svg(assert_pixels):
  function test_image_svg_viewbox (line 31) | def test_image_svg_viewbox(assert_pixels):
  function test_image_svg_align_default (line 51) | def test_image_svg_align_default(assert_pixels):
  function test_image_svg_align_none (line 76) | def test_image_svg_align_none(assert_pixels):
  function test_image_svg_align_no_viewbox (line 102) | def test_image_svg_align_no_viewbox(assert_pixels):
  function test_image_svg_align_meet_x (line 127) | def test_image_svg_align_meet_x(assert_pixels):
  function test_image_svg_align_meet_y (line 153) | def test_image_svg_align_meet_y(assert_pixels):
  function test_image_svg_align_slice_x (line 179) | def test_image_svg_align_slice_x(assert_pixels):
  function test_image_svg_align_slice_y (line 205) | def test_image_svg_align_slice_y(assert_pixels):
  function test_image_svg_percentage (line 232) | def test_image_svg_percentage(assert_pixels):
  function test_image_svg_wrong (line 251) | def test_image_svg_wrong(assert_pixels):
  function test_image_image (line 269) | def test_image_image(assert_pixels):
  function test_image_image_rendering (line 287) | def test_image_image_rendering(assert_pixels):
  function test_image_image_wrong (line 309) | def test_image_image_wrong(assert_pixels):
  function test_image_in_g_height_only (line 327) | def test_image_in_g_height_only(assert_pixels):
  function test_image_in_g_width_only (line 352) | def test_image_in_g_width_only(assert_pixels):

FILE: tests/draw/svg/test_markers.py
  function test_markers (line 7) | def test_markers(assert_pixels):
  function test_markers_viewbox (line 43) | def test_markers_viewbox(assert_pixels):
  function test_markers_size (line 79) | def test_markers_size(assert_pixels):
  function test_markers_viewbox_size (line 117) | def test_markers_viewbox_size(assert_pixels):
  function test_markers_overflow (line 153) | def test_markers_overflow(assert_pixels):
  function test_markers_userspace (line 191) | def test_markers_userspace(assert_pixels):
  function test_markers_stroke_width (line 228) | def test_markers_stroke_width(assert_pixels):
  function test_markers_viewbox_stroke_width (line 265) | def test_markers_viewbox_stroke_width(assert_pixels):

FILE: tests/draw/svg/test_opacity.py
  function test_opacity (line 16) | def test_opacity(assert_same_renderings):
  function test_fill_opacity (line 30) | def test_fill_opacity(assert_same_renderings):
  function test_stroke_opacity (line 47) | def test_stroke_opacity(assert_same_renderings):
  function test_stroke_fill_opacity (line 69) | def test_stroke_fill_opacity(assert_same_renderings):
  function test_pattern_gradient_stroke_fill_opacity (line 86) | def test_pattern_gradient_stroke_fill_opacity(assert_same_renderings):
  function test_translate_opacity (line 134) | def test_translate_opacity(assert_same_renderings):
  function test_translate_use_opacity (line 149) | def test_translate_use_opacity(assert_same_renderings):

FILE: tests/draw/svg/test_paths.py
  function test_path_h (line 7) | def test_path_h(assert_pixels):
  function test_path_v (line 38) | def test_path_v(assert_pixels):
  function test_path_l (line 69) | def test_path_l(assert_pixels):
  function test_path_z (line 96) | def test_path_z(assert_pixels):
  function test_path_z_fill (line 123) | def test_path_z_fill(assert_pixels):
  function test_path_c (line 150) | def test_path_c(assert_pixels):
  function test_path_s (line 177) | def test_path_s(assert_pixels):
  function test_path_cs (line 204) | def test_path_cs(assert_pixels):
  function test_path_q (line 237) | def test_path_q(assert_pixels):
  function test_path_t (line 264) | def test_path_t(assert_pixels):
  function test_path_qt (line 291) | def test_path_qt(assert_pixels):
  function test_path_qt2 (line 320) | def test_path_qt2(assert_pixels):
  function test_path_a (line 349) | def test_path_a(assert_pixels):
  function test_path_a2 (line 378) | def test_path_a2(assert_pixels):
  function test_path_a3 (line 405) | def test_path_a3(assert_pixels):
  function test_path_a4 (line 432) | def test_path_a4(assert_pixels):
  function test_path_a5 (line 461) | def test_path_a5(assert_pixels):
  function test_path_a6 (line 488) | def test_path_a6(assert_pixels):
  function test_path_a7 (line 515) | def test_path_a7(assert_pixels):
  function test_path_wrong_point (line 542) | def test_path_wrong_point(assert_pixels):
  function test_path_markers_l (line 569) | def test_path_markers_l(assert_pixels):
  function test_path_markers_hv (line 603) | def test_path_markers_hv(assert_pixels):

FILE: tests/draw/svg/test_patterns.py
  function test_pattern (line 7) | def test_pattern(assert_pixels):
  function test_pattern_2 (line 39) | def test_pattern_2(assert_pixels):
  function test_pattern_3 (line 71) | def test_pattern_3(assert_pixels):
  function test_pattern_4 (line 103) | def test_pattern_4(assert_pixels):
  function test_pattern_inherit_attributes (line 135) | def test_pattern_inherit_attributes(assert_pixels):
  function test_pattern_inherit_children (line 169) | def test_pattern_inherit_children(assert_pixels):
  function test_pattern_inherit_no_override (line 202) | def test_pattern_inherit_no_override(assert_pixels):

FILE: tests/draw/svg/test_shapes.py
  function test_rect_stroke (line 7) | def test_rect_stroke(assert_pixels):
  function test_rect_fill (line 31) | def test_rect_fill(assert_pixels):
  function test_rect_stroke_fill (line 54) | def test_rect_stroke_fill(assert_pixels):
  function test_rect_round (line 78) | def test_rect_round(assert_pixels):
  function test_rect_round_zero (line 101) | def test_rect_round_zero(assert_pixels):
  function test_line (line 124) | def test_line(assert_pixels):
  function test_polyline (line 148) | def test_polyline(assert_pixels):
  function test_polyline_fill (line 172) | def test_polyline_fill(assert_pixels):
  function test_polygon (line 196) | def test_polygon(assert_pixels):
  function test_polygon_fill (line 220) | def test_polygon_fill(assert_pixels):
  function test_circle_stroke (line 244) | def test_circle_stroke(assert_pixels):
  function test_circle_fill (line 269) | def test_circle_fill(assert_pixels):
  function test_ellipse_stroke (line 294) | def test_ellipse_stroke(assert_pixels):
  function test_ellipse_fill (line 319) | def test_ellipse_fill(assert_pixels):
  function test_rect_in_g (line 344) | def test_rect_in_g(assert_pixels):
  function test_rect_x_y_in_g (line 369) | def test_rect_x_y_in_g(assert_pixels):
  function test_rect_stroke_zero (line 394) | def test_rect_stroke_zero(assert_pixels):
  function test_rect_width_height_zero (line 418) | def test_rect_width_height_zero(assert_pixels):
  function test_rect_fill_inherit (line 441) | def test_rect_fill_inherit(assert_pixels):

FILE: tests/draw/svg/test_text.py
  function test_text_fill (line 7) | def test_text_fill(assert_pixels):
  function test_text_stroke (line 25) | def test_text_stroke(assert_pixels):
  function test_text_x (line 46) | def test_text_x(assert_pixels):
  function test_text_y (line 65) | def test_text_y(assert_pixels):
  function test_text_xy (line 92) | def test_text_xy(assert_pixels):
  function test_text_dx (line 119) | def test_text_dx(assert_pixels):
  function test_text_dy (line 138) | def test_text_dy(assert_pixels):
  function test_text_dx_dy (line 165) | def test_text_dx_dy(assert_pixels):
  function test_text_anchor_start (line 192) | def test_text_anchor_start(assert_pixels):
  function test_text_anchor_middle (line 217) | def test_text_anchor_middle(assert_pixels):
  function test_text_anchor_end (line 236) | def test_text_anchor_end(assert_pixels):
  function test_text_tspan (line 255) | def test_text_tspan(assert_pixels):
  function test_text_tspan_anchor_middle (line 273) | def test_text_tspan_anchor_middle(assert_pixels):
  function test_text_tspan_anchor_end (line 291) | def test_text_tspan_anchor_end(assert_pixels):
  function test_text_anchor_middle_tspan (line 309) | def test_text_anchor_middle_tspan(assert_pixels):
  function test_text_anchor_end_tspan (line 328) | def test_text_anchor_end_tspan(assert_pixels):
  function test_text_anchor_middle_tspan_head_tail (line 347) | def test_text_anchor_middle_tspan_head_tail(assert_pixels):
  function test_text_anchor_end_tspan_head_tail (line 366) | def test_text_anchor_end_tspan_head_tail(assert_pixels):
  function test_text_anchor_middle_end_tspan (line 385) | def test_text_anchor_middle_end_tspan(assert_pixels):
  function test_text_tspan_anchor_non_text (line 406) | def test_text_tspan_anchor_non_text(assert_pixels):
  function test_text_rotate (line 426) | def test_text_rotate(assert_pixels):
  function test_text_text_length (line 447) | def test_text_text_length(assert_pixels):
  function test_text_length_adjust_glyphs_only (line 469) | def test_text_length_adjust_glyphs_only(assert_pixels):
  function test_text_font_face (line 491) | def test_text_font_face(assert_pixels):
  function test_text_font_face_css (line 517) | def test_text_font_face_css(assert_pixels):
  function test_text_length_adjust_spacing_and_glyphs (line 544) | def test_text_length_adjust_spacing_and_glyphs(assert_pixels):
  function test_font_shorthand (line 567) | def test_font_shorthand(assert_pixels):
  function test_font_shorthand_inheritance_from_parent (line 586) | def test_font_shorthand_inheritance_from_parent(assert_pixels):
  function test_explicit_properties_override_parent_shorthand (line 607) | def test_explicit_properties_override_parent_shorthand(assert_pixels):
  function test_font_shorthand_overrides_explicit_parent_properties (line 628) | def test_font_shorthand_overrides_explicit_parent_properties(assert_pixe...
  function test_child_font_shorthand_overrides_parent_shorthand (line 649) | def test_child_font_shorthand_overrides_parent_shorthand(assert_pixels):
  function test_mixed_explicit_and_shorthand_across_levels (line 670) | def test_mixed_explicit_and_shorthand_across_levels(assert_pixels):
  function test_text_fill_opacity (line 693) | def test_text_fill_opacity(assert_pixels):
  function test_emoji_text_svg (line 716) | def test_emoji_text_svg(assert_pixels):

FILE: tests/draw/svg/test_transform.py
  function test_transform_translate (line 7) | def test_transform_translate(assert_pixels):
  function test_transform_translate_one (line 31) | def test_transform_translate_one(assert_pixels):
  function test_transform_translatex (line 55) | def test_transform_translatex(assert_pixels):
  function test_transform_translatey (line 79) | def test_transform_translatey(assert_pixels):
  function test_transform_rotate (line 103) | def test_transform_rotate(assert_pixels):
  function test_transform_rotate_cx_cy (line 127) | def test_transform_rotate_cx_cy(assert_pixels):
  function test_transform_skew (line 151) | def test_transform_skew(assert_pixels):
  function test_transform_skew_one (line 175) | def test_transform_skew_one(assert_pixels):
  function test_transform_skewx (line 199) | def test_transform_skewx(assert_pixels):
  function test_transform_skewy (line 223) | def test_transform_skewy(assert_pixels):
  function test_transform_scale (line 247) | def test_transform_scale(assert_pixels):
  function test_transform_scale_2 (line 271) | def test_transform_scale_2(assert_pixels):
  function test_transform_scalex (line 295) | def test_transform_scalex(assert_pixels):
  function test_transform_scaley (line 319) | def test_transform_scaley(assert_pixels):
  function test_transform_matrix (line 343) | def test_transform_matrix(assert_pixels):
  function test_transform_multiple (line 368) | def test_transform_multiple(assert_pixels):
  function test_transform_unknown (line 393) | def test_transform_unknown(assert_pixels):
  function test_transform_origin (line 417) | def test_transform_origin(assert_pixels):

FILE: tests/draw/svg/test_units.py
  function test_units_px (line 7) | def test_units_px(assert_pixels):
  function test_units_em (line 31) | def test_units_em(assert_pixels):
  function test_units_ex (line 56) | def test_units_ex(assert_pixels):
  function test_units_unknown (line 81) | def test_units_unknown(assert_pixels):

FILE: tests/draw/svg/test_visibility.py
  function test_visibility_visible (line 7) | def test_visibility_visible(assert_pixels):
  function test_visibility_hidden (line 31) | def test_visibility_hidden(assert_pixels):
  function test_visibility_inherit_hidden (line 55) | def test_visibility_inherit_hidden(assert_pixels):
  function test_visibility_inherit_visible (line 80) | def test_visibility_inherit_visible(assert_pixels):
  function test_display_inline (line 106) | def test_display_inline(assert_pixels):
  function test_display_none (line 130) | def test_display_none(assert_pixels):
  function test_display_inherit_none (line 154) | def test_display_inherit_none(assert_pixels):
  function test_display_inherit_inline (line 179) | def test_display_inherit_inline(assert_pixels):

FILE: tests/draw/test_absolute.py
  function test_absolute_split_1 (line 9) | def test_absolute_split_1(assert_pixels):
  function test_absolute_split_2 (line 40) | def test_absolute_split_2(assert_pixels):
  function test_absolute_split_3 (line 71) | def test_absolute_split_3(assert_pixels):
  function test_absolute_split_4 (line 102) | def test_absolute_split_4(assert_pixels):
  function test_absolute_split_5 (line 133) | def test_absolute_split_5(assert_pixels):
  function test_absolute_split_6 (line 171) | def test_absolute_split_6(assert_pixels):
  function test_absolute_split_7 (line 207) | def test_absolute_split_7(assert_pixels):
  function test_absolute_split_8 (line 247) | def test_absolute_split_8(assert_pixels):
  function test_absolute_split_9 (line 281) | def test_absolute_split_9(assert_pixels):
  function test_absolute_split_10 (line 316) | def test_absolute_split_10(assert_pixels):
  function test_absolute_split_11 (line 360) | def test_absolute_split_11(assert_pixels):
  function test_absolute_split_12 (line 392) | def test_absolute_split_12(assert_pixels):
  function test_absolute_next_page (line 444) | def test_absolute_next_page(assert_pixels):
  function test_absolute_rtl_1 (line 482) | def test_absolute_rtl_1(assert_pixels):
  function test_absolute_rtl_2 (line 508) | def test_absolute_rtl_2(assert_pixels):
  function test_absolute_rtl_3 (line 535) | def test_absolute_rtl_3(assert_pixels):
  function test_absolute_rtl_4 (line 563) | def test_absolute_rtl_4(assert_pixels):
  function test_absolute_rtl_5 (line 591) | def test_absolute_rtl_5(assert_pixels):
  function test_absolute_pages_counter (line 615) | def test_absolute_pages_counter(assert_pixels):
  function test_absolute_pages_counter_orphans (line 657) | def test_absolute_pages_counter_orphans(assert_pixels):
  function test_absolute_in_inline (line 710) | def test_absolute_in_inline(assert_pixels):
  function test_fixed_in_inline (line 758) | def test_fixed_in_inline(assert_pixels):
  function test_absolute_image_background (line 806) | def test_absolute_image_background(assert_pixels):
  function test_absolute_in_absolute_break (line 829) | def test_absolute_in_absolute_break(assert_pixels):
  function test_absolute_alternative_layout (line 886) | def test_absolute_alternative_layout(assert_pixels, position, display):

FILE: tests/draw/test_background.py
  function test_canvas_background (line 39) | def test_canvas_background(assert_pixels, expected_pixels, html):
  function test_canvas_background_size (line 43) | def test_canvas_background_size(assert_pixels):
  function test_background_image (line 472) | def test_background_image(assert_pixels, css, pixels):
  function test_background_image_zero_size_background (line 486) | def test_background_image_zero_size_background(assert_pixels):
  function test_background_origin (line 570) | def test_background_origin(assert_pixels, css, pixels):
  function test_background_transform (line 585) | def test_background_transform(assert_pixels):
  function test_background_repeat_space_1 (line 609) | def test_background_repeat_space_1(assert_pixels):
  function test_background_repeat_space_2 (line 638) | def test_background_repeat_space_2(assert_pixels):
  function test_background_repeat_space_3 (line 665) | def test_background_repeat_space_3(assert_pixels):
  function test_background_repeat_space_4 (line 691) | def test_background_repeat_space_4(assert_pixels):
  function test_background_repeat_round_1 (line 712) | def test_background_repeat_round_1(assert_pixels):
  function test_background_repeat_round_2 (line 740) | def test_background_repeat_round_2(assert_pixels):
  function test_background_repeat_round_3 (line 772) | def test_background_repeat_round_3(assert_pixels):
  function test_background_repeat_round_4 (line 800) | def test_background_repeat_round_4(assert_pixels):
  function test_background_clip (line 870) | def test_background_clip(assert_pixels, css, pixels):
  function test_background_size (line 1021) | def test_background_size(assert_pixels, expected_pixels, html):
  function test_bleed_background_size (line 1026) | def test_bleed_background_size(assert_pixels):
  function test_background_size_clip (line 1040) | def test_background_size_clip(assert_pixels):
  function test_page_background_fixed (line 1056) | def test_page_background_fixed(assert_pixels):
  function test_page_background_fixed_bleed (line 1073) | def test_page_background_fixed_bleed(assert_pixels):
  function test_bleed_background_size_clip (line 1092) | def test_bleed_background_size_clip(assert_pixels):
  function test_marks_crop (line 1111) | def test_marks_crop(assert_pixels):
  function test_marks_cross (line 1127) | def test_marks_cross(assert_pixels):
  function test_marks_crop_cross (line 1143) | def test_marks_crop_cross(assert_pixels):

FILE: tests/draw/test_before_after.py
  function test_before_after_1 (line 7) | def test_before_after_1(assert_same_renderings):
  function test_before_after_2 (line 27) | def test_before_after_2(assert_same_renderings):
  function test_before_after_3 (line 51) | def test_before_after_3(assert_same_renderings):

FILE: tests/draw/test_box.py
  function test_outlines_and_borders (line 17) | def test_outlines_and_borders(assert_pixels, assert_different_renderings...
  function test_borders_table_collapse (line 57) | def test_borders_table_collapse(assert_different_renderings):
  function test_borders_table_collapse_equivalent (line 82) | def test_borders_table_collapse_equivalent(assert_same_renderings, styles):
  function test_small_borders_1 (line 98) | def test_small_borders_1(border_style):
  function test_small_borders_2 (line 111) | def test_small_borders_2(border_style):
  function test_em_borders (line 123) | def test_em_borders():
  function test_borders_box_sizing (line 130) | def test_borders_box_sizing(assert_pixels):
  function test_margin_boxes (line 157) | def test_margin_boxes(assert_pixels):
  function test_display_inline_block_twice (line 208) | def test_display_inline_block_twice():
  function test_draw_border_radius (line 216) | def test_draw_border_radius(assert_pixels):
  function test_draw_split_border_radius (line 243) | def test_draw_split_border_radius(assert_pixels):
  function test_border_image_stretch (line 289) | def test_border_image_stretch(assert_pixels):
  function test_border_image_fill (line 318) | def test_border_image_fill(assert_pixels):
  function test_border_image_default_slice (line 347) | def test_border_image_default_slice(assert_pixels):
  function test_border_image_uneven_width (line 379) | def test_border_image_uneven_width(assert_pixels):
  function test_border_image_not_percent (line 409) | def test_border_image_not_percent(assert_pixels):
  function test_border_image_repeat (line 438) | def test_border_image_repeat(assert_pixels):
  function test_border_image_space (line 468) | def test_border_image_space(assert_pixels):
  function test_border_image_outset (line 499) | def test_border_image_outset(assert_pixels):
  function test_border_image_width (line 532) | def test_border_image_width(assert_pixels):
  function test_border_image_gradient (line 562) | def test_border_image_gradient(assert_pixels):
  function test_border_image_gradient_units (line 592) | def test_border_image_gradient_units(assert_pixels):
  function test_mask_border (line 625) | def test_mask_border(assert_pixels):
  function test_mask_border_fill (line 656) | def test_mask_border_fill(assert_pixels):
  function test_outline_and_border (line 687) | def test_outline_and_border(assert_pixels):
  function test_outline_offset (line 716) | def test_outline_offset(assert_pixels):
  function test_infinite_border_radius (line 748) | def test_infinite_border_radius(assert_pixels):

FILE: tests/draw/test_cmyk_color_profiles.py
  function test_device_cmyk_with_icc (line 7) | def test_device_cmyk_with_icc(assert_pixels):
  function test_device_cmyk_without_icc (line 22) | def test_device_cmyk_without_icc(assert_pixels):
  function test_custom_cmyk_with_icc (line 33) | def test_custom_cmyk_with_icc(assert_pixels):
  function test_image_cmyk_without_icc (line 48) | def test_image_cmyk_without_icc(assert_pixels):
  function test_image_cmyk_with_external_icc (line 58) | def test_image_cmyk_with_external_icc(assert_pixels):
  function test_image_cmyk_with_icc (line 72) | def test_image_cmyk_with_icc(assert_pixels):

FILE: tests/draw/test_column.py
  function test_column_rule_1 (line 7) | def test_column_rule_1(assert_pixels):
  function test_column_rule_2 (line 30) | def test_column_rule_2(assert_pixels):
  function test_column_rule_span (line 55) | def test_column_rule_span(assert_pixels):
  function test_column_rule_normal (line 86) | def test_column_rule_normal(assert_pixels):

FILE: tests/draw/test_current_color.py
  function test_current_color_1 (line 9) | def test_current_color_1(assert_pixels):
  function test_current_color_2 (line 21) | def test_current_color_2(assert_pixels):
  function test_current_color_3 (line 33) | def test_current_color_3(assert_pixels):
  function test_current_color_4 (line 45) | def test_current_color_4(assert_pixels):
  function test_current_color_svg_1 (line 58) | def test_current_color_svg_1(assert_pixels):
  function test_current_color_svg_2 (line 72) | def test_current_color_svg_2(assert_pixels):
  function test_current_color_variable (line 86) | def test_current_color_variable(assert_pixels):
  function test_current_color_variable_border (line 98) | def test_current_color_variable_border(assert_pixels):

FILE: tests/draw/test_float.py
  function test_float (line 9) | def test_float(assert_pixels):
  function test_float_rtl (line 28) | def test_float_rtl(assert_pixels):
  function test_float_inline (line 47) | def test_float_inline(assert_pixels):
  function test_float_inline_rtl (line 69) | def test_float_inline_rtl(assert_pixels):
  function test_float_inline_block (line 91) | def test_float_inline_block(assert_pixels):
  function test_float_inline_block_rtl (line 113) | def test_float_inline_block_rtl(assert_pixels):
  function test_float_table (line 135) | def test_float_table(assert_pixels):
  function test_float_table_rtl (line 157) | def test_float_table_rtl(assert_pixels):
  function test_float_inline_table (line 179) | def test_float_inline_table(assert_pixels):
  function test_float_inline_table_rtl (line 202) | def test_float_inline_table_rtl(assert_pixels):
  function test_float_replaced_block (line 225) | def test_float_replaced_block(assert_pixels):
  function test_float_replaced_block_rtl (line 245) | def test_float_replaced_block_rtl(assert_pixels):
  function test_float_replaced_inline (line 266) | def test_float_replaced_inline(assert_pixels):
  function test_float_replaced_inline_rtl (line 288) | def test_float_replaced_inline_rtl(assert_pixels):
  function test_float_margin (line 309) | def test_float_margin(assert_pixels):
  function test_float_split_1 (line 340) | def test_float_split_1(assert_pixels):
  function test_float_split_2 (line 368) | def test_float_split_2(assert_pixels):
  function test_float_split_3 (line 396) | def test_float_split_3(assert_pixels):
  function test_float_split_4 (line 424) | def test_float_split_4(assert_pixels):
  function test_float_split_5 (line 452) | def test_float_split_5(assert_pixels):
  function test_float_split_6 (line 485) | def test_float_split_6(assert_pixels):
  function test_float_split_7 (line 518) | def test_float_split_7(assert_pixels):
  function test_float_split_8 (line 551) | def test_float_split_8(assert_pixels):
  function test_float_split_9 (line 580) | def test_float_split_9(assert_pixels):
  function test_float_split_10 (line 609) | def test_float_split_10(assert_pixels):
  function test_float_split_11 (line 645) | def test_float_split_11(assert_pixels):
  function test_float_split_12 (line 683) | def test_float_split_12(assert_pixels):
  function test_float_split_13 (line 724) | def test_float_split_13(assert_pixels):
  function test_float_split_14 (line 764) | def test_float_split_14(assert_pixels):
  function test_float_split_15 (line 804) | def test_float_split_15(assert_pixels):
  function test_float_split_clear (line 839) | def test_float_split_clear(assert_pixels):
  function test_float_split_clear_empty (line 875) | def test_float_split_clear_empty(assert_pixels):
  function test_float_split_large_parent (line 911) | def test_float_split_large_parent(assert_pixels):
  function test_float_split_in_stacking_context (line 963) | def test_float_split_in_stacking_context(assert_pixels):

FILE: tests/draw/test_footnote.py
  function test_inline_footnote (line 7) | def test_inline_footnote(assert_pixels):
  function test_block_footnote (line 35) | def test_block_footnote(assert_pixels):
  function test_long_footnote (line 63) | def test_long_footnote(assert_pixels):
  function test_footnote_margin (line 91) | def test_footnote_margin(assert_pixels):
  function test_footnote_multiple_margin (line 123) | def test_footnote_multiple_margin(assert_pixels):
  function test_footnote_with_absolute (line 173) | def test_footnote_with_absolute(assert_pixels):
  function test_footnote_max_height_1 (line 208) | def test_footnote_max_height_1(assert_pixels):
  function test_footnote_max_height_2 (line 250) | def test_footnote_max_height_2(assert_pixels):
  function test_footnote_max_height_3 (line 290) | def test_footnote_max_height_3(assert_pixels):
  function test_footnote_max_height_4 (line 338) | def test_footnote_max_height_4(assert_pixels):
  function test_footnote_max_height_5 (line 380) | def test_footnote_max_height_5(assert_pixels):

FILE: tests/draw/test_footnote_column.py
  function test_footnote_column_margin_top (line 9) | def test_footnote_column_margin_top(assert_pixels):
  function test_footnote_column_fill_auto (line 49) | def test_footnote_column_fill_auto(assert_pixels):
  function test_footnote_column_fill_auto_break_inside_avoid (line 86) | def test_footnote_column_fill_auto_break_inside_avoid(assert_pixels):
  function test_footnote_column_p_after (line 131) | def test_footnote_column_p_after(assert_pixels):
  function test_footnote_column_p_before (line 179) | def test_footnote_column_p_before(assert_pixels):
  function test_footnote_column_3 (line 233) | def test_footnote_column_3(assert_pixels):
  function test_footnote_column_3_p_before (line 268) | def test_footnote_column_3_p_before(assert_pixels):
  function test_footnote_column_clone_decoration (line 312) | def test_footnote_column_clone_decoration(assert_pixels):
  function test_footnote_column_max_height (line 351) | def test_footnote_column_max_height(assert_pixels):
  function test_footnote_column_reported_split (line 400) | def test_footnote_column_reported_split(assert_pixels):

FILE: tests/draw/test_gradient.py
  function test_linear_gradients_1 (line 7) | def test_linear_gradients_1(assert_pixels):
  function test_linear_gradients_2 (line 24) | def test_linear_gradients_2(assert_pixels):
  function test_linear_gradients_3 (line 41) | def test_linear_gradients_3(assert_pixels):
  function test_linear_gradients_4 (line 54) | def test_linear_gradients_4(assert_pixels):
  function test_linear_gradients_5 (line 67) | def test_linear_gradients_5(assert_pixels):
  function test_linear_gradients_6 (line 81) | def test_linear_gradients_6(assert_pixels):
  function test_linear_gradients_7 (line 94) | def test_linear_gradients_7(assert_pixels):
  function test_linear_gradients_8 (line 108) | def test_linear_gradients_8(assert_pixels):
  function test_linear_gradients_9 (line 120) | def test_linear_gradients_9(assert_pixels):
  function test_linear_gradients_10 (line 132) | def test_linear_gradients_10(assert_pixels):
  function test_linear_gradients_11 (line 145) | def test_linear_gradients_11(assert_pixels):
  function test_linear_gradients_12 (line 158) | def test_linear_gradients_12(assert_pixels):
  function test_linear_gradients_13 (line 171) | def test_linear_gradients_13(assert_pixels):
  function test_linear_gradients_currentcolor (line 189) | def test_linear_gradients_currentcolor(assert_pixels):
  function test_linear_gradients_hints (line 201) | def test_linear_gradients_hints(assert_pixels):
  function test_linear_gradients_hints_percentage (line 218) | def test_linear_gradients_hints_percentage(assert_pixels):
  function test_radial_gradients_1 (line 235) | def test_radial_gradients_1(assert_pixels):
  function test_radial_gradients_2 (line 248) | def test_radial_gradients_2(assert_pixels):
  function test_radial_gradients_3 (line 261) | def test_radial_gradients_3(assert_pixels):
  function test_radial_gradients_4 (line 284) | def test_radial_gradients_4(assert_pixels):
  function test_radial_gradients_5 (line 307) | def test_radial_gradients_5(assert_pixels):
  function test_radial_gradients_negative (line 330) | def test_radial_gradients_negative(assert_pixels):
  function test_radial_gradients_repeating (line 353) | def test_radial_gradients_repeating(assert_pixels):
  function test_radial_gradients_repeating_outer (line 376) | def test_radial_gradients_repeating_outer(assert_pixels):
  function test_radial_gradients_repeating_outer_partial (line 399) | def test_radial_gradients_repeating_outer_partial(assert_pixels):
  function test_radial_gradients_repeating_negative (line 422) | def test_radial_gradients_repeating_negative(assert_pixels):
  function test_radial_gradients_hints (line 445) | def test_radial_gradients_hints(assert_pixels):
  function test_radial_gradients_hints_percentage (line 458) | def test_radial_gradients_hints_percentage(assert_pixels):

FILE: tests/draw/test_image.py
  function test_images (line 161) | def test_images(assert_pixels, filename, image):
  function test_resized_images (line 178) | def test_resized_images(assert_pixels, filename):
  function test_image_overflow (line 189) | def test_image_overflow(assert_pixels):
  function test_svg_sizing (line 208) | def test_svg_sizing(assert_pixels, viewbox, width, height):
  function test_svg_resizing (line 236) | def test_svg_resizing(assert_pixels, viewbox, width, height, image):
  function test_images_block (line 253) | def test_images_block(assert_pixels):
  function test_images_not_found (line 264) | def test_images_not_found(assert_pixels):
  function test_images_no_src (line 279) | def test_images_no_src(assert_pixels):
  function test_images_alt (line 290) | def test_images_alt(assert_same_renderings):
  function test_images_repeat_transparent (line 312) | def test_images_repeat_transparent(assert_pixels):
  function test_images_no_width (line 323) | def test_images_no_width(assert_pixels):
  function test_images_no_height (line 334) | def test_images_no_height(assert_pixels):
  function test_images_no_width_height (line 345) | def test_images_no_width_height(assert_pixels):
  function test_images_page_break (line 356) | def test_images_page_break(assert_pixels):
  function test_image_repeat_inline (line 367) | def test_image_repeat_inline(assert_pixels):
  function test_image_repeat_block (line 390) | def test_image_repeat_block(assert_pixels):
  function test_images_padding (line 413) | def test_images_padding(assert_pixels):
  function test_images_in_inline_block (line 426) | def test_images_in_inline_block(assert_pixels):
  function test_images_transparent_text (line 439) | def test_images_transparent_text(assert_pixels):
  function test_images_shared_pattern (line 451) | def test_images_shared_pattern(assert_pixels):
  function test_image_resolution (line 480) | def test_image_resolution(assert_same_renderings):
  function test_image_cover (line 508) | def test_image_cover(assert_pixels):
  function test_image_contain (line 519) | def test_image_contain(assert_pixels):
  function test_image_none (line 530) | def test_image_none(assert_pixels):
  function test_image_scale_down (line 541) | def test_image_scale_down(assert_pixels):
  function test_image_position (line 552) | def test_image_position(assert_pixels):
  function test_images_border (line 564) | def test_images_border(assert_pixels):
  function test_images_border_absolute (line 575) | def test_images_border_absolute(assert_pixels):
  function test_image_exif (line 586) | def test_image_exif(assert_same_renderings):
  function test_image_exif_image_orientation (line 601) | def test_image_exif_image_orientation(assert_same_renderings):
  function test_image_exif_image_orientation_keep_format (line 617) | def test_image_exif_image_orientation_keep_format():

FILE: tests/draw/test_leader.py
  function test_leader_simple (line 9) | def test_leader_simple(assert_pixels):
  function test_leader_too_long (line 42) | def test_leader_too_long(assert_pixels):
  function test_leader_alone (line 83) | def test_leader_alone(assert_pixels):
  function test_leader_content (line 108) | def test_leader_content(assert_pixels):
  function test_leader_float (line 134) | def test_leader_float(assert_pixels):
  function test_leader_float_small (line 170) | def test_leader_float_small(assert_pixels):
  function test_leader_in_inline (line 203) | def test_leader_in_inline(assert_pixels):
  function test_leader_bad_alignment (line 232) | def test_leader_bad_alignment(assert_pixels):
  function test_leader_simple_rtl (line 259) | def test_leader_simple_rtl(assert_pixels):
  function test_leader_too_long_rtl (line 294) | def test_leader_too_long_rtl(assert_pixels):
  function test_leader_float_leader (line 337) | def test_leader_float_leader(assert_pixels):
  function test_leader_empty_string (line 372) | def test_leader_empty_string(assert_pixels):
  function test_leader_zero_width_string (line 397) | def test_leader_zero_width_string(assert_pixels):
  function test_leader_absolute (line 422) | def test_leader_absolute(assert_pixels):
  function test_leader_padding (line 453) | def test_leader_padding(assert_pixels):
  function test_leader_inline_padding (line 486) | def test_leader_inline_padding(assert_pixels):
  function test_leader_margin (line 519) | def test_leader_margin(assert_pixels):
  function test_leader_inline_margin (line 552) | def test_leader_inline_margin(assert_pixels):

FILE: tests/draw/test_list.py
  function test_list_style_image (line 44) | def test_list_style_image(assert_pixels, position, pixels):
  function test_list_style_image_none (line 56) | def test_list_style_image_none(assert_pixels):

FILE: tests/draw/test_opacity.py
  function test_opacity_zero (line 14) | def test_opacity_zero(assert_same_renderings):
  function test_opacity_normal_range (line 23) | def test_opacity_normal_range(assert_same_renderings):
  function test_opacity_nested (line 33) | def test_opacity_nested(assert_same_renderings):
  function test_opacity_percent_clamp_down (line 46) | def test_opacity_percent_clamp_down(assert_same_renderings):
  function test_opacity_percent_clamp_up (line 55) | def test_opacity_percent_clamp_up(assert_same_renderings):
  function test_opacity_black (line 64) | def test_opacity_black(assert_same_renderings):

FILE: tests/draw/test_overflow.py
  function test_overflow_1 (line 9) | def test_overflow_1(assert_pixels):
  function test_overflow_2 (line 30) | def test_overflow_2(assert_pixels):
  function test_overflow_3 (line 51) | def test_overflow_3(assert_pixels):
  function test_overflow_4 (line 72) | def test_overflow_4(assert_pixels):
  function test_overflow_5 (line 96) | def test_overflow_5(assert_pixels):
  function test_clip (line 193) | def test_clip(assert_pixels, number, css, pixels):

FILE: tests/draw/test_page.py
  function test_nth_page (line 23) | def test_nth_page(assert_pixels, rule, pixels):

FILE: tests/draw/test_table.py
  function test_tables_1 (line 41) | def test_tables_1(assert_pixels):
  function test_tables_1_rtl (line 78) | def test_tables_1_rtl(assert_pixels):
  function test_tables_2 (line 116) | def test_tables_2(assert_pixels):
  function test_tables_2_rtl (line 154) | def test_tables_2_rtl(assert_pixels):
  function test_tables_3 (line 192) | def test_tables_3(assert_pixels):
  function test_tables_3_rtl (line 256) | def test_tables_3_rtl(assert_pixels):
  function test_tables_4 (line 321) | def test_tables_4(assert_pixels):
  function test_tables_4_rtl (line 358) | def test_tables_4_rtl(assert_pixels):
  function test_tables_5 (line 395) | def test_tables_5(assert_pixels):
  function test_tables_5_rtl (line 433) | def test_tables_5_rtl(assert_pixels):
  function test_tables_6 (line 471) | def test_tables_6(assert_pixels):
  function test_tables_6_rtl (line 509) | def test_tables_6_rtl(assert_pixels):
  function test_tables_7 (line 547) | def test_tables_7(assert_pixels):
  function test_tables_7_rtl (line 585) | def test_tables_7_rtl(assert_pixels):
  function test_tables_8 (line 623) | def test_tables_8(assert_pixels):
  function test_tables_8_rtl (line 661) | def test_tables_8_rtl(assert_pixels):
  function test_tables_9 (line 699) | def test_tables_9(assert_pixels):
  function test_tables_10 (line 751) | def test_tables_10(assert_pixels):
  function test_tables_11 (line 801) | def test_tables_11(assert_pixels):
  function test_tables_12 (line 826) | def test_tables_12(assert_pixels):
  function test_tables_13 (line 864) | def test_tables_13(assert_pixels):
  function test_tables_14 (line 930) | def test_tables_14(assert_pixels):
  function test_tables_15 (line 993) | def test_tables_15(assert_pixels):
  function test_tables_16 (line 1046) | def test_tables_16(assert_pixels):
  function test_tables_17 (line 1073) | def test_tables_17(assert_pixels):
  function test_tables_18 (line 1106) | def test_tables_18(assert_pixels):
  function test_tables_19 (line 1141) | def test_tables_19(assert_pixels):
  function test_tables_20 (line 1162) | def test_tables_20(assert_pixels):
  function test_tables_21 (line 1183) | def test_tables_21(assert_pixels):
  function test_tables_22 (line 1219) | def test_tables_22(assert_pixels):
  function test_tables_23 (line 1252) | def test_tables_23(assert_pixels):
  function test_tables_24 (line 1285) | def test_tables_24(assert_pixels):
  function test_tables_24_rtl (line 1333) | def test_tables_24_rtl(assert_pixels):
  function test_running_elements_table_border_collapse (line 1382) | def test_running_elements_table_border_collapse(assert_pixels):
  function test_running_elements_table_border_collapse_empty (line 1426) | def test_running_elements_table_border_collapse_empty(assert_pixels):
  function test_running_elements_table_border_collapse_border_style (line 1463) | def test_running_elements_table_border_collapse_border_style(assert_pixe...
  function test_running_elements_table_border_collapse_span (line 1507) | def test_running_elements_table_border_collapse_span(assert_pixels):
  function test_running_elements_table_border_collapse_margin (line 1551) | def test_running_elements_table_border_collapse_margin(assert_pixels):
  function test_tables_split_row (line 1596) | def test_tables_split_row(assert_pixels):
  function test_tables_column_background (line 1622) | def test_tables_column_background(assert_pixels):

FILE: tests/draw/test_text.py
  function test_text_overflow_clip (line 10) | def test_text_overflow_clip(assert_pixels):
  function test_text_overflow_ellipsis (line 40) | def test_text_overflow_ellipsis(assert_pixels):
  function test_text_align_rtl_trailing_whitespace (line 87) | def test_text_align_rtl_trailing_whitespace(assert_pixels):
  function test_rtl_default_direction (line 114) | def test_rtl_default_direction(assert_pixels):
  function test_rtl_forced_direction (line 130) | def test_rtl_forced_direction(assert_pixels):
  function test_rtl_nested_inline (line 146) | def test_rtl_nested_inline(assert_pixels):
  function test_max_lines_ellipsis (line 170) | def test_max_lines_ellipsis(assert_pixels):
  function test_max_lines_nested (line 200) | def test_max_lines_nested(assert_pixels):
  function test_line_clamp (line 246) | def test_line_clamp(assert_pixels):
  function test_line_clamp_none (line 282) | def test_line_clamp_none(assert_pixels):
  function test_line_clamp_number (line 316) | def test_line_clamp_number(assert_pixels):
  function test_line_clamp_nested (line 349) | def test_line_clamp_nested(assert_pixels):
  function test_line_clamp_nested_after (line 387) | def test_line_clamp_nested_after(assert_pixels):
  function test_ellipsis_nested (line 426) | def test_ellipsis_nested(assert_pixels):
  function test_text_align_right (line 460) | def test_text_align_right(assert_pixels):
  function test_text_align_justify (line 487) | def test_text_align_justify(assert_pixels):
  function test_text_align_justify_nbsp (line 514) | def test_text_align_justify_nbsp(assert_pixels):
  function test_text_word_spacing (line 539) | def test_text_word_spacing(assert_pixels):
  function test_text_letter_spacing (line 564) | def test_text_letter_spacing(assert_pixels):
  function test_text_underline (line 589) | def test_text_underline(assert_pixels):
  function test_text_underline_offset (line 614) | def test_text_underline_offset(assert_pixels):
  function test_text_underline_offset_percentage (line 642) | def test_text_underline_offset_percentage(assert_pixels):
  function test_text_underline_offset_calc (line 670) | def test_text_underline_offset_calc(assert_pixels):
  function test_text_underline_thickness (line 698) | def test_text_underline_thickness(assert_pixels):
  function test_text_underline_thickness_percentage (line 726) | def test_text_underline_thickness_percentage(assert_pixels):
  function test_text_underline_thickness_calc (line 754) | def test_text_underline_thickness_calc(assert_pixels):
  function test_text_overline (line 782) | def test_text_overline(assert_pixels):
  function test_text_line_through (line 809) | def test_text_line_through(assert_pixels):
  function test_text_multiple_text_decoration (line 834) | def test_text_multiple_text_decoration(assert_pixels):
  function test_text_nested_text_decoration (line 860) | def test_text_nested_text_decoration(assert_pixels):
  function test_text_nested_text_decoration_color (line 890) | def test_text_nested_text_decoration_color(assert_pixels):
  function test_text_nested_block_text_decoration (line 920) | def test_text_nested_block_text_decoration(assert_pixels):
  function test_text_float_text_decoration (line 956) | def test_text_float_text_decoration(assert_pixels):
  function test_text_decoration_var (line 985) | def test_text_decoration_var(assert_pixels):
  function test_zero_width_character (line 1013) | def test_zero_width_character(assert_pixels):
  function test_font_size_very_small (line 1036) | def test_font_size_very_small(assert_pixels):
  function test_missing_glyph_fallback (line 1057) | def test_missing_glyph_fallback(assert_pixels):
  function test_tabulation_character (line 1079) | def test_tabulation_character(assert_pixels):
  function test_otb_font (line 1103) | def test_otb_font(assert_pixels):
  function test_huge_justification (line 1131) | def test_huge_justification(assert_pixels):
  function test_font_variant_caps_small (line 1156) | def test_font_variant_caps_small(assert_pixels):
  function test_font_variant_caps_all_small (line 1179) | def test_font_variant_caps_all_small(assert_pixels):
  function test_font_variant_caps_petite (line 1202) | def test_font_variant_caps_petite(assert_pixels):
  function test_font_variant_caps_all_petite (line 1227) | def test_font_variant_caps_all_petite(assert_pixels):
  function test_font_variant_caps_unicase (line 1250) | def test_font_variant_caps_unicase(assert_pixels):
  function test_font_variant_caps_titling (line 1273) | def test_font_variant_caps_titling(assert_pixels):
  function test_unicode_range (line 1295) | def test_unicode_range(assert_pixels):

FILE: tests/draw/test_transform.py
  function test_2d_transform_1 (line 7) | def test_2d_transform_1(assert_pixels):
  function test_2d_transform_2 (line 29) | def test_2d_transform_2(assert_pixels):
  function test_2d_transform_3 (line 51) | def test_2d_transform_3(assert_pixels):
  function test_2d_transform_4 (line 74) | def test_2d_transform_4(assert_pixels):
  function test_2d_transform_5 (line 96) | def test_2d_transform_5(assert_pixels):
  function test_2d_transform_6 (line 115) | def test_2d_transform_6(assert_pixels):
  function test_2d_transform_7 (line 134) | def test_2d_transform_7(assert_pixels):
  function test_2d_transform_8 (line 153) | def test_2d_transform_8(assert_pixels):
  function test_2d_transform_9 (line 173) | def test_2d_transform_9(assert_pixels):
  function test_2d_transform_10 (line 192) | def test_2d_transform_10(assert_pixels):
  function test_2d_transform_11 (line 216) | def test_2d_transform_11(assert_pixels):
  function test_2d_transform_12 (line 240) | def test_2d_transform_12(assert_pixels):
  function test_2d_transform_13 (line 264) | def test_2d_transform_13(assert_pixels):
  function test_2d_transform_opacity (line 288) | def test_2d_transform_opacity(assert_pixels):

FILE: tests/draw/test_visibility.py
  function test_visibility_1 (line 19) | def test_visibility_1(assert_pixels):
  function test_visibility_2 (line 32) | def test_visibility_2(assert_pixels):
  function test_visibility_3 (line 45) | def test_visibility_3(assert_pixels):
  function test_visibility_4 (line 59) | def test_visibility_4(assert_pixels):

FILE: tests/draw/test_whitespace.py
  function test_whitespace_inline (line 7) | def test_whitespace_inline(assert_pixels):
  function test_whitespace_nested_inline (line 28) | def test_whitespace_nested_inline(assert_pixels):
  function test_whitespace_inline_space_between (line 49) | def test_whitespace_inline_space_between(assert_pixels):
  function test_whitespace_float_between (line 70) | def test_whitespace_float_between(assert_pixels):
  function test_whitespace_in_float (line 92) | def test_whitespace_in_float(assert_pixels):
  function test_whitespace_absolute_between (line 117) | def test_whitespace_absolute_between(assert_pixels):
  function test_whitespace_in_absolute (line 144) | def test_whitespace_in_absolute(assert_pixels):
  function test_whitespace_running_between (line 171) | def test_whitespace_running_between(assert_pixels):
  function test_whitespace_in_running (line 203) | def test_whitespace_in_running(assert_pixels):

FILE: tests/layout/test_block.py
  function test_block_widths (line 11) | def test_block_widths():
  function test_block_heights_p (line 134) | def test_block_heights_p():
  function test_block_heights_img (line 164) | def test_block_heights_img():
  function test_block_heights_img_no_body_height (line 191) | def test_block_heights_img_no_body_height():
  function test_block_percentage_heights_no_html_height (line 219) | def test_block_percentage_heights_no_html_height():
  function test_block_percentage_heights (line 236) | def test_block_percentage_heights():
  function test_box_sizing (line 260) | def test_box_sizing(size):
  function test_box_sizing_zero (line 315) | def test_box_sizing_zero(size):
  function test_vertical_space_1 (line 361) | def test_vertical_space_1(margin_1, margin_2, result):
  function test_vertical_space_2 (line 381) | def test_vertical_space_2(margin_1, margin_2, result):
  function test_vertical_space_3 (line 404) | def test_vertical_space_3(margin_1, margin_2, result):
  function test_vertical_space_4 (line 427) | def test_vertical_space_4(margin_1, margin_2, result):
  function test_vertical_space_5 (line 453) | def test_vertical_space_5(margin_1, margin_2, result):
  function test_vertical_space_6 (line 482) | def test_vertical_space_6(margin_1, margin_2, result):
  function test_vertical_space_7 (line 508) | def test_vertical_space_7(margin_1, margin_2, result):
  function test_vertical_space_8 (line 530) | def test_vertical_space_8(margin_1, margin_2, result):
  function test_vertical_space_9 (line 548) | def test_vertical_space_9(margin_1, margin_2, result):
  function test_box_decoration_break_block_slice (line 568) | def test_box_decoration_break_block_slice():
  function test_box_decoration_break_block_clone (line 617) | def test_box_decoration_break_block_clone():
  function test_box_decoration_break_clone_bottom_padding (line 671) | def test_box_decoration_break_clone_bottom_padding():
  function test_box_decoration_break_slice_bottom_padding (line 701) | def test_box_decoration_break_slice_bottom_padding():  # pragma: no cover
  function test_nested_blocks_padding_border (line 737) | def test_nested_blocks_padding_border():  # pragma: no cover
  function test_overflow_non_collapsing_parent (line 770) | def test_overflow_non_collapsing_parent():
  function test_overflow_auto (line 797) | def test_overflow_auto():
  function test_overflow_hidden_in_flow_layout (line 809) | def test_overflow_hidden_in_flow_layout():
  function test_overflow_hidden_out_of_flow_layout (line 823) | def test_overflow_hidden_out_of_flow_layout():
  function test_box_margin_top_repagination (line 837) | def test_box_margin_top_repagination():
  function test_continue_discard (line 864) | def test_continue_discard():
  function test_continue_discard_children (line 891) | def test_continue_discard_children():
  function test_block_in_block_with_bottom_padding (line 923) | def test_block_in_block_with_bottom_padding():
  function test_page_breaks_1 (line 965) | def test_page_breaks_1():
  function test_page_breaks_2 (line 1000) | def test_page_breaks_2():
  function test_page_breaks_3 (line 1037) | def test_page_breaks_3():
  function test_page_break_child_margin_no_collapse (line 1074) | def test_page_break_child_margin_no_collapse():
  function test_min_max_rtl (line 1102) | def test_min_max_rtl():

FILE: tests/layout/test_column.py
  function test_columns (line 17) | def test_columns(css):
  function test_column_gap (line 48) | def test_column_gap(value, width):
  function test_column_span_1 (line 75) | def test_column_span_1():
  function test_column_span_2 (line 105) | def test_column_span_2():
  function test_column_span_3 (line 133) | def test_column_span_3():
  function test_column_span_4 (line 176) | def test_column_span_4():
  function test_column_span_5 (line 219) | def test_column_span_5():
  function test_column_span_6 (line 260) | def test_column_span_6():
  function test_column_span_7 (line 298) | def test_column_span_7():
  function test_column_span_8 (line 339) | def test_column_span_8():
  function test_column_span_9 (line 380) | def test_column_span_9():
  function test_column_span_balance (line 410) | def test_column_span_balance():
  function test_columns_multipage (line 441) | def test_columns_multipage():
  function test_columns_breaks (line 476) | def test_columns_breaks():
  function test_columns_break_after_column_1 (line 507) | def test_columns_break_after_column_1():
  function test_columns_break_after_column_2 (line 530) | def test_columns_break_after_column_2():
  function test_columns_break_after_avoid_column (line 553) | def test_columns_break_after_avoid_column():
  function test_columns_break_before_column_1 (line 576) | def test_columns_break_before_column_1():
  function test_columns_break_before_column_2 (line 599) | def test_columns_break_before_column_2():
  function test_columns_break_before_avoid_column (line 622) | def test_columns_break_before_avoid_column():
  function test_columns_break_inside_column_1 (line 645) | def test_columns_break_inside_column_1():
  function test_columns_break_inside_column_2 (line 668) | def test_columns_break_inside_column_2():
  function test_columns_break_inside_column_not_empty_page (line 691) | def test_columns_break_inside_column_not_empty_page():
  function test_columns_not_enough_content (line 716) | def test_columns_not_enough_content():
  function test_columns_higher_than_page (line 737) | def test_columns_higher_than_page():
  function test_columns_empty (line 770) | def test_columns_empty():
  function test_columns_fixed_height (line 790) | def test_columns_fixed_height(prop):
  function test_columns_padding (line 813) | def test_columns_padding():
  function test_columns_bottom_margin (line 838) | def test_columns_bottom_margin():
  function test_columns_relative (line 862) | def test_columns_relative():
  function test_columns_regression_1 (line 891) | def test_columns_regression_1():
  function test_columns_regression_2 (line 935) | def test_columns_regression_2():
  function test_columns_regression_3 (line 976) | def test_columns_regression_3():
  function test_columns_regression_4 (line 1006) | def test_columns_regression_4():
  function test_columns_regression_5 (line 1026) | def test_columns_regression_5():
  function test_columns_regression_6 (line 1047) | def test_columns_regression_6():
  function test_columns_regression_7 (line 1058) | def test_columns_regression_7():
  function test_columns_margin_top (line 1084) | def test_columns_margin_top():
  function test_columns_grid (line 1104) | def test_columns_grid():

FILE: tests/layout/test_flex.py
  function test_flex_direction_row (line 9) | def test_flex_direction_row():
  function test_flex_direction_row_max_width (line 30) | def test_flex_direction_row_max_width():
  function test_flex_direction_row_min_height (line 43) | def test_flex_direction_row_min_height():
  function test_flex_direction_row_rtl (line 56) | def test_flex_direction_row_rtl():
  function test_flex_direction_row_rtl_gap (line 77) | def test_flex_direction_row_rtl_gap():
  function test_flex_direction_row_reverse (line 99) | def test_flex_direction_row_reverse():
  function test_flex_direction_row_reverse_rtl (line 120) | def test_flex_direction_row_reverse_rtl():
  function test_flex_direction_column (line 142) | def test_flex_direction_column():
  function test_flex_direction_column_min_width (line 163) | def test_flex_direction_column_min_width():
  function test_flex_direction_column_max_height (line 176) | def test_flex_direction_column_max_height():
  function test_flex_direction_column_rtl (line 201) | def test_flex_direction_column_rtl():
  function test_flex_direction_column_reverse (line 223) | def test_flex_direction_column_reverse():
  function test_flex_direction_column_reverse_rtl (line 244) | def test_flex_direction_column_reverse_rtl():
  function test_flex_direction_column_box_sizing (line 266) | def test_flex_direction_column_box_sizing():
  function test_flex_row_wrap (line 289) | def test_flex_row_wrap():
  function test_flex_column_wrap (line 311) | def test_flex_column_wrap():
  function test_flex_row_wrap_reverse (line 333) | def test_flex_row_wrap_reverse():
  function test_flex_column_wrap_reverse (line 355) | def test_flex_column_wrap_reverse():
  function test_flex_direction_column_fixed_height_container (line 378) | def test_flex_direction_column_fixed_height_container():
  function test_flex_direction_column_fixed_height (line 404) | def test_flex_direction_column_fixed_height():
  function test_flex_direction_column_fixed_height_wrap (line 427) | def test_flex_direction_column_fixed_height_wrap():
  function test_flex_direction_column_break (line 450) | def test_flex_direction_column_break():
  function test_flex_direction_column_break_margin (line 476) | def test_flex_direction_column_break_margin():
  function test_flex_direction_column_break_border (line 507) | def test_flex_direction_column_break_border():
  function test_flex_direction_column_break_multiple_children (line 543) | def test_flex_direction_column_break_multiple_children():
  function test_flex_item_min_width (line 570) | def test_flex_item_min_width():
  function test_flex_item_min_height (line 595) | def test_flex_item_min_height():
  function test_flex_auto_margin (line 614) | def test_flex_auto_margin():
  function test_flex_item_auto_margin_sized (line 622) | def test_flex_item_auto_margin_sized():
  function test_flex_no_baseline (line 645) | def test_flex_no_baseline():
  function test_flex_align_content (line 661) | def test_flex_align_content(align, height, y1, y2):
  function test_flex_item_percentage (line 698) | def test_flex_item_percentage():
  function test_flex_undefined_percentage_height_multiple_lines (line 712) | def test_flex_undefined_percentage_height_multiple_lines():
  function test_flex_absolute (line 722) | def test_flex_absolute():
  function test_flex_percent_height (line 731) | def test_flex_percent_height():
  function test_flex_percent_height_auto (line 749) | def test_flex_percent_height_auto():
  function test_flex_break_inside_avoid (line 762) | def test_flex_break_inside_avoid():
  function test_flex_absolute_content (line 784) | def test_flex_absolute_content():
  function test_flex_column_height (line 802) | def test_flex_column_height():
  function test_flex_column_height_margin (line 827) | def test_flex_column_height_margin():
  function test_flex_column_width (line 847) | def test_flex_column_width():
  function test_flex_column_in_flex_row (line 872) | def test_flex_column_in_flex_row():
  function test_flex_overflow (line 890) | def test_flex_overflow():
  function test_flex_column_overflow (line 917) | def test_flex_column_overflow():
  function test_inline_flex (line 932) | def test_inline_flex():
  function test_inline_flex_empty_child (line 944) | def test_inline_flex_empty_child():
  function test_inline_flex_absolute_baseline (line 956) | def test_inline_flex_absolute_baseline():
  function test_flex_item_overflow (line 968) | def test_flex_item_overflow():
  function test_flex_item_child_bottom_margin (line 992) | def test_flex_item_child_bottom_margin(direction):
  function test_flex_direction_row_inline_block (line 1014) | def test_flex_direction_row_inline_block():
  function test_flex_float (line 1031) | def test_flex_float():
  function test_flex_float_in_flex_item (line 1045) | def test_flex_float_in_flex_item():
  function test_flex_direction_row_defined_main (line 1066) | def test_flex_direction_row_defined_main():
  function test_flex_direction_row_defined_main_border_box (line 1081) | def test_flex_direction_row_defined_main_border_box():
  function test_flex_direction_column_defined_main (line 1096) | def test_flex_direction_column_defined_main():
  function test_flex_direction_column_defined_main_border_box (line 1111) | def test_flex_direction_column_defined_main_border_box():
  function test_flex_item_negative_margin (line 1126) | def test_flex_item_negative_margin():
  function test_flex_item_auto_margin_main (line 1141) | def test_flex_item_auto_margin_main():
  function test_flex_item_auto_margin_cross (line 1157) | def test_flex_item_auto_margin_cross():
  function test_flex_direction_column_item_auto_margin (line 1173) | def test_flex_direction_column_item_auto_margin():
  function test_flex_item_auto_margin_flex_basis (line 1189) | def test_flex_item_auto_margin_flex_basis():
  function test_flex_direction_row_justify (line 1216) | def test_flex_direction_row_justify(align, x1, x2, x3):
  function test_flex_direction_column_justify (line 1252) | def test_flex_direction_column_justify(align, y1, y2, y3):
  function test_flex_direction_row_justify_gap (line 1288) | def test_flex_direction_row_justify_gap(align, x1, x2, x3):
  function test_flex_direction_column_justify_gap (line 1324) | def test_flex_direction_column_justify_gap(align, y1, y2, y3):
  function test_flex_direction_row_justify_gap_wrap (line 1360) | def test_flex_direction_row_justify_gap_wrap(align, x1, x2, x3):
  function test_flex_direction_column_justify_gap_wrap (line 1397) | def test_flex_direction_column_justify_gap_wrap(align, y1, y2, y3):
  function test_flex_direction_row_stretch_no_grow (line 1423) | def test_flex_direction_row_stretch_no_grow():
  function test_flex_direction_row_stretch_grow (line 1447) | def test_flex_direction_row_stretch_grow():
  function test_flex_direction_row_justify_margin_padding (line 1485) | def test_flex_direction_row_justify_margin_padding(align, x1, x2, x3):
  function test_flex_direction_column_justify_margin_padding (line 1525) | def test_flex_direction_column_justify_margin_padding(align, y1, y2, y3):
  function test_flex_item_table (line 1553) | def test_flex_item_table():
  function test_flex_item_table_width (line 1571) | def test_flex_item_table_width():
  function test_flex_width_on_parent (line 1589) | def test_flex_width_on_parent():
  function test_flex_column_item_flex_1 (line 1604) | def test_flex_column_item_flex_1():
  function test_flex_row_item_flex_0 (line 1618) | def test_flex_row_item_flex_0():
  function test_flex_item_intrinsic_width (line 1636) | def test_flex_item_intrinsic_width():
  function test_flex_align_content_negative (line 1653) | def test_flex_align_content_negative():
  function test_flex_shrink (line 1676) | def test_flex_shrink():
  function test_flex_item_intrinsic_width_shrink (line 1691) | def test_flex_item_intrinsic_width_shrink():
  function test_flex_item_intrinsic_height_shrink (line 1707) | def test_flex_item_intrinsic_height_shrink():
  function test_flex_wrap_in_flex (line 1723) | def test_flex_wrap_in_flex():
  function test_flex_auto_break_before (line 1743) | def test_flex_auto_break_before():
  function test_flex_grow_in_flex_column (line 1765) | def test_flex_grow_in_flex_column():
  function test_flex_collapsing_margin (line 1784) | def test_flex_collapsing_margin():
  function test_flex_direction_column_next_page (line 1802) | def test_flex_direction_column_next_page():
  function test_flex_1_item_padding (line 1833) | def test_flex_1_item_padding():
  function test_flex_1_item_padding_direction_column (line 1848) | def test_flex_1_item_padding_direction_column():
  function test_flex_item_replaced (line 1864) | def test_flex_item_replaced():
  function test_flex_nested_column (line 1880) | def test_flex_nested_column():
  function test_flex_blockify_image (line 1900) | def test_flex_blockify_image():
  function test_flex_image_max_width (line 1914) | def test_flex_image_max_width():
  function test_flex_image_max_height (line 1928) | def test_flex_image_max_height():
  function test_flex_image_min_width (line 1942) | def test_flex_image_min_width():
  function test_flex_image_justify_content (line 1957) | def test_flex_image_justify_content():
  function test_flex_root_formatting_context (line 1973) | def test_flex_root_formatting_context():
  function test_flex_height_page_overflow (line 1988) | def test_flex_height_page_overflow():
  function test_flex_break_after_page (line 2006) | def test_flex_break_after_page():

FILE: tests/layout/test_float.py
  function outer_area (line 10) | def outer_area(box):
  function test_floats_1 (line 17) | def test_floats_1():
  function test_floats_2 (line 34) | def test_floats_2():
  function test_floats_3 (line 62) | def test_floats_3():
  function test_floats_4 (line 92) | def test_floats_4():
  function test_floats_5 (line 114) | def test_floats_5():
  function test_floats_6 (line 136) | def test_floats_6():
  function test_floats_7 (line 163) | def test_floats_7():
  function test_floats_8 (line 186) | def test_floats_8():
  function test_floats_9 (line 215) | def test_floats_9():
  function test_floats_page_breaks_1 (line 221) | def test_floats_page_breaks_1():
  function test_floats_page_breaks_2 (line 248) | def test_floats_page_breaks_2():
  function test_floats_page_breaks_3 (line 275) | def test_floats_page_breaks_3():
  function test_preferred_widths_1 (line 306) | def test_preferred_widths_1():
  function test_preferred_widths_2 (line 327) | def test_preferred_widths_2():
  function test_preferred_widths_3 (line 342) | def test_preferred_widths_3():
  function test_preferred_widths_4 (line 356) | def test_preferred_widths_4():
  function test_preferred_widths_5 (line 369) | def test_preferred_widths_5():
  function test_float_in_inline_1 (line 383) | def test_float_in_inline_1():
  function test_float_in_inline_2 (line 427) | def test_float_in_inline_2():
  function test_float_in_inline_3 (line 462) | def test_float_in_inline_3():
  function test_float_in_inline_4 (line 496) | def test_float_in_inline_4():
  function test_float_next_line (line 532) | def test_float_next_line():
  function test_float_text_indent_1 (line 564) | def test_float_text_indent_1():
  function test_float_text_indent_2 (line 598) | def test_float_text_indent_2():
  function test_float_text_indent_3 (line 639) | def test_float_text_indent_3():
  function test_float_previous_break (line 685) | def test_float_previous_break():
  function test_float_fail (line 731) | def test_float_fail():
  function test_float_table_aborted_row (line 757) | def test_float_table_aborted_row():
  function test_formatting_context_avoid_rtl (line 802) | def test_formatting_context_avoid_rtl():
  function test_nested_right_float (line 811) | def test_nested_right_float():
  function test_first_letter_float (line 827) | def test_first_letter_float():

FILE: tests/layout/test_footnotes.py
  function test_inline_footnote (line 9) | def test_inline_footnote():
  function test_block_footnote (line 41) | def test_block_footnote():
  function test_long_footnote (line 72) | def test_long_footnote():
  function test_after_marker_footnote (line 107) | def test_after_marker_footnote():
  function test_several_footnote (line 139) | def test_several_footnote():
  function test_reported_footnote_1 (line 183) | def test_reported_footnote_1():
  function test_reported_footnote_2 (line 224) | def test_reported_footnote_2():
  function test_reported_footnote_3 (line 267) | def test_reported_footnote_3():
  function test_reported_sequential_footnote (line 312) | def test_reported_sequential_footnote():
  function test_reported_sequential_footnote_second_line (line 338) | def test_reported_sequential_footnote_second_line():
  function test_footnote_report_orphans (line 364) | def test_footnote_report_orphans():
  function test_footnote_area_after_call (line 415) | def test_footnote_area_after_call(css, tail):
  function test_footnote_display_inline (line 446) | def test_footnote_display_inline():
  function test_footnote_longer_than_space_left (line 483) | def test_footnote_longer_than_space_left():
  function test_footnote_longer_than_page (line 520) | def test_footnote_longer_than_page():
  function test_footnote_policy_line (line 561) | def test_footnote_policy_line():
  function test_footnote_policy_block (line 602) | def test_footnote_policy_block():
  function test_footnote_repagination (line 641) | def test_footnote_repagination():
  function test_reported_footnote_repagination (line 677) | def test_reported_footnote_repagination():
  function test_footnote_max_height (line 723) | def test_footnote_max_height():
  function test_footnote_table_aborted_row (line 777) | def test_footnote_table_aborted_row():
  function test_footnote_table_aborted_group (line 820) | def test_footnote_table_aborted_group():
  function test_footnote_bottom_margin (line 873) | def test_footnote_bottom_margin():
  function test_footnotes_column_converge_end (line 906) | def test_footnotes_column_converge_end():
  function test_footnotes_column_converge (line 948) | def test_footnotes_column_converge():

FILE: tests/layout/test_grid.py
  function test_grid_empty (line 11) | def test_grid_empty():
  function test_grid_single_item (line 26) | def test_grid_single_item():
  function test_grid_single_auto_width (line 42) | def test_grid_single_auto_width():
  function test_grid_single_percentage_width (line 60) | def test_grid_single_percentage_width():
  function test_grid_rows (line 76) | def test_grid_rows():
  function test_grid_template_fr (line 95) | def test_grid_template_fr():
  function test_grid_template_areas (line 126) | def test_grid_template_areas():
  function test_grid_template_areas_grid_area (line 157) | def test_grid_template_areas_grid_area():
  function test_grid_template_areas_empty_row (line 188) | def test_grid_template_areas_empty_row():
  function test_grid_template_areas_multiple_rows (line 219) | def test_grid_template_areas_multiple_rows():
  function test_grid_template_areas_multiple_columns (line 252) | def test_grid_template_areas_multiple_columns():
  function test_grid_template_areas_overlap (line 285) | def test_grid_template_areas_overlap():
  function test_grid_template_big_span (line 315) | def test_grid_template_big_span():
  function test_grid_template_multiple_big_span (line 348) | def test_grid_template_multiple_big_span():
  function test_grid_template_areas_span_overflow (line 389) | def test_grid_template_areas_span_overflow():
  function test_grid_template_areas_extra_span (line 422) | def test_grid_template_areas_extra_span():
  function test_grid_template_areas_extra_span_dense (line 460) | def test_grid_template_areas_extra_span_dense():
  function test_grid_area_multiple_values (line 500) | def test_grid_area_multiple_values():
  function test_grid_template_repeat_fr (line 534) | def test_grid_template_repeat_fr():
  function test_grid_template_shorthand_fr (line 576) | def test_grid_template_shorthand_fr():
  function test_grid_shorthand_auto_flow_rows_fr_size (line 613) | def test_grid_shorthand_auto_flow_rows_fr_size():
  function test_grid_template_fr_too_large (line 645) | def test_grid_template_fr_too_large():
  function test_grid_shorthand_auto_flow_columns_none_dense (line 674) | def test_grid_shorthand_auto_flow_columns_none_dense():
  function test_grid_template_fr_undefined_free_space (line 706) | def test_grid_template_fr_undefined_free_space():
  function test_grid_column_start (line 738) | def test_grid_column_start():
  function test_grid_column_start_blockified (line 781) | def test_grid_column_start_blockified():
  function test_grid_undefined_free_space (line 824) | def test_grid_undefined_free_space():
  function test_grid_padding (line 869) | def test_grid_padding():
  function test_grid_border (line 911) | def test_grid_border():
  function test_grid_border_box (line 953) | def test_grid_border_box():
  function test_grid_item_border_box (line 997) | def test_grid_item_border_box():
  function test_grid_border_split (line 1019) | def test_grid_border_split():
  function test_grid_margin (line 1056) | def test_grid_margin():
  function test_grid_item_margin (line 1098) | def test_grid_item_margin():
  function test_grid_auto_flow_column (line 1118) | def test_grid_auto_flow_column():
  function test_grid_template_areas_extra_span_column_dense (line 1137) | def test_grid_template_areas_extra_span_column_dense():
  function test_grid_gap_explicit_grid_column (line 1184) | def test_grid_gap_explicit_grid_column():
  function test_grid_break (line 1215) | def test_grid_break():
  function test_grid_break_order_negative (line 1276) | def test_grid_break_order_negative():
  function test_grid_break_order_positive (line 1337) | def test_grid_break_order_positive():
  function test_grid_break_border (line 1404) | def test_grid_break_border():
  function test_grid_break_multiple (line 1484) | def test_grid_break_multiple():
  function test_grid_break_span (line 1566) | def test_grid_break_span():
  function test_grid_break_item_avoid (line 1649) | def test_grid_break_item_avoid():
  function test_grid_break_item_avoid_auto (line 1699) | def test_grid_break_item_avoid_auto():
  function test_grid_break_container (line 1749) | def test_grid_break_container():
  function test_grid_bottom_page (line 1777) | def test_grid_bottom_page():
  function test_grid_in_grid (line 1800) | def test_grid_in_grid():
  function test_grid_in_flex_after_full_height (line 1844) | def test_grid_in_flex_after_full_height():
  function test_grid_in_columns (line 1871) | def test_grid_in_columns():
  function test_grid_in_columns_with_break (line 1909) | def test_grid_in_columns_with_break():

FILE: tests/layout/test_image.py
  function get_img (line 10) | def get_img(html):
  function test_images_1 (line 40) | def test_images_1(html):
  function test_images_2 (line 47) | def test_images_2():
  function test_images_3 (line 71) | def test_images_3(url):
  function test_images_4 (line 102) | def test_images_4(url):
  function test_images_5 (line 108) | def test_images_5():
  function test_images_6 (line 117) | def test_images_6():
  function test_images_7 (line 128) | def test_images_7():
  function test_images_8 (line 138) | def test_images_8():
  function test_images_9 (line 149) | def test_images_9():
  function test_images_10 (line 159) | def test_images_10():
  function test_images_11 (line 166) | def test_images_11():
  function test_images_12 (line 186) | def test_images_12():
  function test_images_13 (line 209) | def test_images_13():
  function test_images_14 (line 231) | def test_images_14():
  function test_images_15 (line 253) | def test_images_15():
  function test_images_16 (line 276) | def test_images_16():
  function test_images_17 (line 295) | def test_images_17():
  function test_images_18 (line 315) | def test_images_18():
  function test_images_19 (line 332) | def test_images_19(html, children):
  function test_linear_gradient (line 340) | def test_linear_gradient():
  function test_radial_gradient (line 401) | def test_radial_gradient():
  function test_image_min_max_width (line 534) | def test_image_min_max_width(props, div_width):
  function test_svg_no_size_width (line 557) | def test_svg_no_size_width(css, width):
  function test_svg_no_size_min_width (line 578) | def test_svg_no_size_min_width(css, width):

FILE: tests/layout/test_inline.py
  function test_empty_linebox (line 11) | def test_empty_linebox():
  function test_empty_linebox_removed_space (line 22) | def test_empty_linebox_removed_space():
  function test_breaking_linebox (line 39) | def test_breaking_linebox():
  function test_position_x_ltr (line 72) | def test_position_x_ltr():
  function test_position_x_rtl (line 100) | def test_position_x_rtl():
  function test_breaking_linebox_regression_1 (line 132) | def test_breaking_linebox_regression_1():
  function test_breaking_linebox_regression_2 (line 147) | def test_breaking_linebox_regression_2():
  function test_breaking_linebox_regression_3 (line 225) | def test_breaking_linebox_regression_3():
  function test_breaking_linebox_regression_4 (line 243) | def test_breaking_linebox_regression_4():
  function test_breaking_linebox_regression_5 (line 260) | def test_breaking_linebox_regression_5():
  function test_breaking_linebox_regression_6 (line 277) | def test_breaking_linebox_regression_6():
  function test_breaking_linebox_regression_7 (line 291) | def test_breaking_linebox_regression_7():
  function test_breaking_linebox_regression_8 (line 307) | def test_breaking_linebox_regression_8():
  function test_breaking_linebox_regression_9 (line 326) | def test_breaking_linebox_regression_9():
  function test_breaking_linebox_regression_10 (line 345) | def test_breaking_linebox_regression_10():
  function test_breaking_linebox_regression_11 (line 365) | def test_breaking_linebox_regression_11():
  function test_breaking_linebox_regression_12 (line 382) | def test_breaking_linebox_regression_12():
  function test_breaking_linebox_regression_13 (line 398) | def test_breaking_linebox_regression_13():
  function test_breaking_linebox_regression_14 (line 415) | def test_breaking_linebox_regression_14():
  function test_breaking_linebox_regression_15 (line 431) | def test_breaking_linebox_regression_15():
  function test_breaking_linebox_regression_16 (line 458) | def test_breaking_linebox_regression_16():
  function test_linebox_text (line 488) | def test_linebox_text():
  function test_linebox_positions (line 509) | def test_linebox_positions():
  function test_forced_line_breaks_pre (line 539) | def test_forced_line_breaks_pre():
  function test_forced_line_breaks_paragraph (line 563) | def test_forced_line_breaks_paragraph():
  function test_inlinebox_splitting (line 584) | def test_inlinebox_splitting():
  function test_whitespace_processing (line 612) | def test_whitespace_processing():
  function test_inline_replaced_auto_margins (line 636) | def test_inline_replaced_auto_margins():
  function test_empty_inline_auto_margins (line 654) | def test_empty_inline_auto_margins():
  function test_font_stretch (line 672) | def test_font_stretch():
  function test_line_count (line 697) | def test_line_count(source, lines_count):
  function test_vertical_align_1 (line 706) | def test_vertical_align_1():
  function test_vertical_align_2 (line 732) | def test_vertical_align_2():
  function test_vertical_align_3 (line 757) | def test_vertical_align_3():
  function test_vertical_align_4 (line 777) | def test_vertical_align_4():
  function test_vertical_align_5 (line 799) | def test_vertical_align_5():
  function test_vertical_align_6 (line 822) | def test_vertical_align_6():
  function test_vertical_align_7 (line 847) | def test_vertical_align_7():
  function test_vertical_align_8 (line 868) | def test_vertical_align_8():
  function test_vertical_align_9 (line 889) | def test_vertical_align_9():
  function test_vertical_align_10 (line 933) | def test_vertical_align_10():
  function test_vertical_align_11 (line 969) | def test_vertical_align_11():
  function test_vertical_align_12 (line 986) | def test_vertical_align_12():
  function test_vertical_align_13 (line 1002) | def test_vertical_align_13():
  function test_box_decoration_break_inline_slice (line 1019) | def test_box_decoration_break_inline_slice():
  function test_box_decoration_break_inline_clone (line 1049) | def test_box_decoration_break_inline_clone():
  function test_bidi_position_x_invariant (line 1080) | def test_bidi_position_x_invariant():
  function test_nested_waiting_children_width (line 1108) | def test_nested_waiting_children_width():

FILE: tests/layout/test_inline_block.py
  function test_inline_block_sizes (line 7) | def test_inline_block_sizes():
  function test_inline_block_with_margin (line 106) | def test_inline_block_with_margin():

FILE: tests/layout/test_list.py
  function test_lists_style (line 15) | def test_lists_style(inside, style, character):
  function test_lists_empty_item (line 45) | def test_lists_empty_item():
  function test_lists_whitespace_item (line 62) | def test_lists_whitespace_item():
  function test_lists_page_break (line 78) | def test_lists_page_break():
  function test_lists_page_break_margin (line 107) | def test_lists_page_break_margin():

FILE: tests/layout/test_logical.py
  function test_logical (line 93) | def test_logical(assert_same_renderings, documents):

FILE: tests/layout/test_page.py
  function test_page_size_basic (line 21) | def test_page_size_basic(size, width, height):
  function test_page_size_with_margin (line 29) | def test_page_size_with_margin():
  function test_page_size_with_margin_border_padding (line 67) | def test_page_size_with_margin_border_padding():
  function test_page_size_margins (line 85) | def test_page_size_margins(margin, top, right, bottom, left):
  function test_page_size_over_constrained (line 105) | def test_page_size_over_constrained(style, width, height):
  function test_page_breaks (line 117) | def test_page_breaks(html):
  function test_page_breaks_box_split (line 140) | def test_page_breaks_box_split():
  function test_page_breaks_complex_1 (line 174) | def test_page_breaks_complex_1():
  function test_page_breaks_complex_2 (line 230) | def test_page_breaks_complex_2():
  function test_page_breaks_complex_3 (line 261) | def test_page_breaks_complex_3():
  function test_page_breaks_complex_4 (line 294) | def test_page_breaks_complex_4():
  function test_page_breaks_complex_5 (line 328) | def test_page_breaks_complex_5():
  function test_page_breaks_complex_6 (line 361) | def test_page_breaks_complex_6():
  function test_page_breaks_complex_7 (line 401) | def test_page_breaks_complex_7():
  function test_page_breaks_complex_8 (line 416) | def test_page_breaks_complex_8():
  function test_page_breaks_complex_9 (line 452) | def test_page_breaks_complex_9():
  function test_margin_break (line 497) | def test_margin_break(break_after, margin_break, margin_top):
  function test_margin_break_clearance (line 526) | def test_margin_break_clearance():
  function test_recto_verso_break (line 568) | def test_recto_verso_break(direction, page_break, pages_number):
  function test_recto_verso_break_root (line 591) | def test_recto_verso_break_root(direction, page_break, first_page):
  function test_page_names_1 (line 604) | def test_page_names_1():
  function test_page_names_2 (line 619) | def test_page_names_2():
  function test_page_names_3 (line 635) | def test_page_names_3():
  function test_page_names_4 (line 668) | def test_page_names_4():
  function test_page_names_5 (line 697) | def test_page_names_5():
  function test_page_names_6 (line 725) | def test_page_names_6():
  function test_page_names_7 (line 761) | def test_page_names_7():
  function test_page_names_8 (line 794) | def test_page_names_8():
  function test_page_names_9 (line 826) | def test_page_names_9():
  function test_page_names_10 (line 859) | def test_page_names_10():
  function test_page_groups (line 895) | def test_page_groups():
  function test_page_groups_blank_inside (line 973) | def test_page_groups_blank_inside():
  function test_page_groups_blank_outside (line 993) | def test_page_groups_blank_outside():
  function test_page_groups_first_nth (line 1012) | def test_page_groups_first_nth():
  function test_page_groups_counters (line 1040) | def test_page_groups_counters():
  function test_orphans_widows_avoid (line 1114) | def test_orphans_widows_avoid(style, line_counts):
  function test_page_and_linebox_breaking (line 1137) | def test_page_and_linebox_breaking():
  function test_margin_boxes_fixed_dimension_1 (line 1164) | def test_margin_boxes_fixed_dimension_1():
  function test_margin_boxes_fixed_dimension_2 (line 1225) | def test_margin_boxes_fixed_dimension_2():
  function test_margin_boxes_fixed_dimension_3 (line 1249) | def test_margin_boxes_fixed_dimension_3():
  function test_margin_boxes_fixed_dimension_4 (line 1267) | def test_margin_boxes_fixed_dimension_4():
  function test_margin_boxes_fixed_dimension_5 (line 1290) | def test_margin_boxes_fixed_dimension_5():
  function test_margin_boxes_fixed_dimension_6 (line 1313) | def test_margin_boxes_fixed_dimension_6():
  function test_margin_boxes_fixed_dimension_7 (line 1331) | def test_margin_boxes_fixed_dimension_7():
  function test_margin_boxes_fixed_dimension_8 (line 1349) | def test_margin_boxes_fixed_dimension_8():
  function test_margin_boxes_fixed_dimension_9 (line 1367) | def test_margin_boxes_fixed_dimension_9():
  function images (line 1384) | def images(*widths):
  function test_page_style (line 1472) | def test_page_style(css, widths):
  function test_margin_boxes_vertical_align (line 1499) | def test_margin_boxes_vertical_align():
  function test_margin_boxes_element (line 1542) | def test_margin_boxes_element():
  function test_margin_boxes_running_element (line 1583) | def test_margin_boxes_running_element():
  function test_running_elements (line 1647) | def test_running_elements(argument, texts):
  function test_running_elements_display (line 1689) | def test_running_elements_display():
  function test_running_img (line 1718) | def test_running_img():
  function test_running_absolute (line 1736) | def test_running_absolute():
  function test_running_flex (line 1757) | def test_running_flex():
  function test_running_float (line 1778) | def test_running_float():

FILE: tests/layout/test_position.py
  function test_relative_positioning_1 (line 9) | def test_relative_positioning_1():
  function test_relative_positioning_2 (line 42) | def test_relative_positioning_2():
  function test_relative_positioning_3 (line 83) | def test_relative_positioning_3():
  function test_relative_positioning_4 (line 103) | def test_relative_positioning_4():
  function test_absolute_positioning_1 (line 124) | def test_absolute_positioning_1():
  function test_absolute_positioning_2 (line 149) | def test_absolute_positioning_2():
  function test_absolute_positioning_3 (line 166) | def test_absolute_positioning_3():
  function test_absolute_positioning_4 (line 188) | def test_absolute_positioning_4():
  function test_absolute_positioning_5 (line 206) | def test_absolute_positioning_5():
  function test_absolute_positioning_6 (line 224) | def test_absolute_positioning_6():
  function test_absolute_positioning_7 (line 248) | def test_absolute_positioning_7():
  function test_absolute_positioning_8 (line 311) | def test_absolute_positioning_8():
  function test_absolute_images (line 329) | def test_absolute_images():
  function test_fixed_positioning (line 361) | def test_fixed_positioning():
  function test_fixed_positioning_regression_1 (line 381) | def test_fixed_positioning_regression_1():
  function test_fixed_positioning_regression_2 (line 418) | def test_fixed_positioning_regression_2():
  function test_flex_relative_positioning (line 453) | def test_flex_relative_positioning():
  function test_grid_relative_positioning (line 475) | def test_grid_relative_positioning():
  function test_flex_absolute_positioning (line 498) | def test_flex_absolute_positioning():
  function test_grid_absolute_positioning (line 523) | def test_grid_absolute_positioning():

FILE: tests/layout/test_preferred.py
  function test_shrink_to_fit_floating_point_error_1 (line 11) | def test_shrink_to_fit_floating_point_error_1(margin_left, font_size):
  function test_shrink_to_fit_floating_point_error_2 (line 29) | def test_shrink_to_fit_floating_point_error_2(font_size):
  function test_preferred_inline_zero_width_inline_block (line 54) | def test_preferred_inline_zero_width_inline_block():
  function test_preferred_inline_nested_trailing_spaces (line 69) | def test_preferred_inline_nested_trailing_spaces():
  function test_preferred_inline_trailing_space_in_nested (line 84) | def test_preferred_inline_trailing_space_in_nested():

FILE: tests/layout/test_table.py
  function _get_grid (line 11) | def _get_grid(html, grid_width, grid_height):
  function test_inline_table (line 25) | def test_inline_table():
  function test_inline_table_width (line 55) | def test_inline_table_width():
  function test_implicit_width_table_col_percent (line 72) | def test_implicit_width_table_col_percent():
  function test_implicit_width_table_td_percent (line 94) | def test_implicit_width_table_td_percent():
  function test_layout_table_fixed_1 (line 113) | def test_layout_table_fixed_1():
  function test_layout_table_fixed_2 (line 142) | def test_layout_table_fixed_2():
  function test_layout_table_fixed_3 (line 169) | def test_layout_table_fixed_3():
  function test_layout_table_fixed_4 (line 205) | def test_layout_table_fixed_4():
  function test_layout_table_fixed_5 (line 236) | def test_layout_table_fixed_5():
  function test_layout_table_auto_1 (line 279) | def test_layout_table_auto_1():
  function test_layout_table_auto_2 (line 309) | def test_layout_table_auto_2():
  function test_layout_table_auto_3 (line 338) | def test_layout_table_auto_3():
  function test_layout_table_auto_4 (line 373) | def test_layout_table_auto_4():
  function test_layout_table_auto_5 (line 408) | def test_layout_table_auto_5():
  function test_layout_table_auto_6 (line 433) | def test_layout_table_auto_6():
  function test_layout_table_auto_7 (line 473) | def test_layout_table_auto_7():
  function test_layout_table_auto_8 (line 502) | def test_layout_table_auto_8():
  function test_layout_table_auto_9 (line 529) | def test_layout_table_auto_9():
  function test_layout_table_auto_10 (line 564) | def test_layout_table_auto_10():
  function test_layout_table_auto_11 (line 594) | def test_layout_table_auto_11():
  function test_layout_table_auto_12 (line 636) | def test_layout_table_auto_12():
  function test_layout_table_auto_13 (line 678) | def test_layout_table_auto_13():
  function test_layout_table_auto_14 (line 701) | def test_layout_table_auto_14():
  function test_layout_table_auto_15 (line 723) | def test_layout_table_auto_15():
  function test_layout_table_auto_16 (line 741) | def test_layout_table_auto_16():
  function test_layout_table_auto_17 (line 764) | def test_layout_table_auto_17():
  function test_layout_table_auto_18 (line 806) | def test_layout_table_auto_18():
  function test_layout_table_auto_19 (line 835) | def test_layout_table_auto_19():
  function test_layout_table_auto_20 (line 867) | def test_layout_table_auto_20():
  function test_layout_table_auto_21 (line 899) | def test_layout_table_auto_21():
  function test_layout_table_auto_22 (line 936) | def test_layout_table_auto_22():
  function test_layout_table_auto_23 (line 973) | def test_layout_table_auto_23():
  function test_layout_table_auto_24 (line 1002) | def test_layout_table_auto_24():
  function test_layout_table_auto_25 (line 1031) | def test_layout_table_auto_25():
  function test_layout_table_auto_26 (line 1063) | def test_layout_table_auto_26():
  function test_layout_table_auto_27 (line 1074) | def test_layout_table_auto_27():
  function test_layout_table_auto_28 (line 1084) | def test_layout_table_auto_28():
  function test_layout_table_auto_29 (line 1094) | def test_layout_table_auto_29():
  function test_layout_table_auto_30 (line 1106) | def test_layout_table_auto_30():
  function test_layout_table_auto_31 (line 1116) | def test_layout_table_auto_31():
  function test_layout_table_auto_32 (line 1126) | def test_layout_table_auto_32():
  function test_layout_table_auto_33 (line 1140) | def test_layout_table_auto_33():
  function test_layout_table_auto_34 (line 1158) | def test_layout_table_auto_34():
  function test_layout_table_auto_35 (line 1174) | def test_layout_table_auto_35():
  function test_layout_table_auto_36 (line 1193) | def test_layout_table_auto_36():
  function test_layout_table_auto_37 (line 1203) | def test_layout_table_auto_37():
  function test_layout_table_auto_38 (line 1225) | def test_layout_table_auto_38():
  function test_layout_table_auto_39 (line 1245) | def test_layout_table_auto_39():
  function test_layout_table_auto_40 (line 1263) | def test_layout_table_auto_40():
  function test_layout_table_auto_41 (line 1280) | def test_layout_table_auto_41():
  function test_layout_table_auto_42 (line 1308) | def test_layout_table_auto_42():
  function test_layout_table_auto_43 (line 1333) | def test_layout_table_auto_43():
  function test_layout_table_auto_44 (line 1363) | def test_layout_table_auto_44():
  function test_layout_table_auto_45 (line 1397) | def test_layout_table_auto_45():
  function test_layout_table_auto_46 (line 1440) | def test_layout_table_auto_46():
  function test_layout_table_auto_47 (line 1464) | def test_layout_table_auto_47():
  function test_layout_table_auto_48 (line 1484) | def test_layout_table_auto_48():
  function test_layout_table_auto_49 (line 1506) | def test_layout_table_auto_49():
  function test_layout_table_auto_50 (line 1527) | def test_layout_table_auto_50():
  function test_layout_table_auto_51 (line 1550) | def test_layout_table_auto_51():
  function test_layout_table_auto_52 (line 1572) | def test_layout_table_auto_52():
  function test_explicit_width_table_percent_rtl (line 1614) | def test_explicit_width_table_percent_rtl(body_width, table_width, check...
  function test_table_column_width_1 (line 1652) | def test_table_column_width_1():
  function test_table_column_width_2 (line 1751) | def test_table_column_width_2():
  function test_table_column_width_3 (line 1777) | def test_table_column_width_3():
  function test_table_row_height_1 (line 1805) | def test_table_row_height_1():
  function test_table_row_height_2 (line 1888) | def test_table_row_height_2():
  function test_table_row_height_3 (line 1909) | def test_table_row_height_3():
  function test_table_row_height_4 (line 1931) | def test_table_row_height_4():
  function test_table_vertical_align (line 1949) | def test_table_vertical_align(assert_pixels):
  function test_table_vertical_align_float (line 2013) | def test_table_vertical_align_float():
  function test_table_wrapper (line 2114) | def test_table_wrapper():
  function test_table_html_tag (line 2141) | def test_table_html_tag():
  function test_table_page_breaks (line 2286) | def test_table_page_breaks(html, rows, positions):
  function test_table_page_breaks_in_cell (line 2316) | def test_table_page_breaks_in_cell():
  function test_table_page_breaks_complex_1 (line 2349) | def test_table_page_breaks_complex_1():
  function test_table_page_breaks_complex_2 (line 2403) | def test_table_page_breaks_complex_2():
  function test_table_page_break_after (line 2464) | def test_table_page_break_after():
  function test_table_page_break_before (line 2544) | def test_table_page_break_before():
  function test_table_page_break_avoid (line 2825) | def test_table_page_break_avoid(html, rows):
  function test_table_page_break_avoid_before_table (line 2848) | def test_table_page_break_avoid_before_table():
  function test_table_page_break_avoid_before_tbody (line 2882) | def test_table_page_break_avoid_before_tbody():
  function test_inline_table_baseline (line 2921) | def test_inline_table_baseline(vertical_align, table_position_y):
  function test_table_caption_margin_top (line 2957) | def test_table_caption_margin_top():
  function test_table_caption_margin_bottom (line 2986) | def test_table_caption_margin_bottom():
  function test_table_empty_body (line 3034) | def test_table_empty_body(rows_expected, thead, tfoot, content):
  function test_table_group_break_inside_avoid_absolute (line 3068) | def test_table_group_break_inside_avoid_absolute():
  function test_table_row_break_inside_avoid_absolute (line 3099) | def test_table_row_break_inside_avoid_absolute():
  function test_table_break_inside_avoid_absolute (line 3132) | def test_table_break_inside_avoid_absolute():
  function test_table_break_children_margin (line 3162) | def test_table_break_children_margin():
  function test_table_td_break_inside_avoid (line 3178) | def test_table_td_break_inside_avoid():
  function test_table_bad_int_td_th_span (line 3197) | def test_table_bad_int_td_th_span():
  function test_table_bad_int_col_span (line 3223) | def test_table_bad_int_col_span():
  function test_table_bad_int_colgroup_span (line 3246) | def test_table_bad_int_colgroup_span():
  function test_table_different_display (line 3269) | def test_table_different_display():
  function test_min_width_with_overflow (line 3311) | def test_min_width_with_overflow():
  function test_table_cell_max_width (line 3369) | def test_table_cell_max_width():
  function test_border_collapse_1 (line 3409) | def test_border_collapse_1():
  function test_border_collapse_2 (line 3422) | def test_border_collapse_2():
  function test_border_collapse_3 (line 3442) | def test_border_collapse_3():
  function test_border_collapse_4 (line 3463) | def test_border_collapse_4():
  function test_border_collapse_5 (line 3491) | def test_border_collapse_5():
  function test_table_zero_width (line 3513) | def test_table_zero_width():
  function test_table_inline_atomic_nowrap (line 3531) | def test_table_inline_atomic_nowrap():

FILE: tests/test_acid2.py
  function test_acid2 (line 13) | def test_acid2(assert_pixels_equal):

FILE: tests/test_api.py
  class chdir (line 37) | class chdir(AbstractContextManager):  # noqa: N801
    method __init__ (line 38) | def __init__(self, path):
    method __enter__ (line 42) | def __enter__(self):
    method __exit__ (line 46) | def __exit__(self, *excinfo):
  function _test_resource (line 50) | def _test_resource(class_, name, check, **kwargs):
  function _check_doc1 (line 89) | def _check_doc1(html, has_base_url=True):
  function _run (line 106) | def _run(args, stdin=b''):
  function _gzip_compress (line 114) | def _gzip_compress(data):
  function http_server (line 123) | def http_server():
  class FakeFile (line 172) | class FakeFile:
    method __init__ (line 173) | def __init__(self):
    method write (line 176) | def write(self, data):
    method getvalue (line 179) | def getvalue(self):
  function _png_size (line 183) | def _png_size(png_bytes):
  function _round_meta (line 188) | def _round_meta(pages):
  function test_html_parsing (line 213) | def test_html_parsing():
  function test_css_parsing (line 233) | def test_css_parsing():
  function check_png_pattern (line 251) | def check_png_pattern(assert_pixels_equal, png_bytes, x2=False, blank=Fa...
  function test_python_render (line 311) | def test_python_render(assert_pixels_equal, tmp_path):
  function test_unknown_options (line 373) | def test_unknown_options():
  function test_command_line_render (line 382) | def test_command_line_render(tmp_path):
  function test_pdfa (line 524) | def test_pdfa(version, pdf_version):
  function test_pdfa_compressed (line 538) | def test_pdfa_compressed(version, pdf_version):
  function test_pdfa1b_cidset (line 543) | def test_pdfa1b_cidset():
  function test_pdfua (line 554) | def test_pdfua(version, pdf_version):
  function test_pdfua_compressed (line 566) | def test_pdfua_compressed(version, pdf_version):
  function test_pdf_tags (line 572) | def test_pdf_tags():
  function test_pdf_identifier (line 579) | def test_pdf_identifier():
  function test_pdf_version (line 585) | def test_pdf_version():
  function test_pdf_custom_metadata (line 591) | def test_pdf_custom_metadata():
  function test_bad_pdf_custom_metadata (line 600) | def test_bad_pdf_custom_metadata():
  function test_partial_pdf_custom_metadata (line 608) | def test_partial_pdf_custom_metadata():
  function test_pdf_srgb (line 617) | def test_pdf_srgb():
  function test_pdf_no_srgb (line 623) | def test_pdf_no_srgb():
  function test_pdf_font_name (line 629) | def test_pdf_font_name():
  function test_to_unicode (line 636) | def test_to_unicode():
  function test_to_unicode_rtl (line 646) | def test_to_unicode_rtl():
  function test_no_redirect (line 656) | def test_no_redirect():
  function test_fail_on_error (line 672) | def test_fail_on_error():
  function test_no_redirect_fail_on_error (line 685) | def test_no_redirect_fail_on_error():
  function test_allowed_protocols (line 706) | def test_allowed_protocols(command):
  function test_allowed_protocols_data (line 716) | def test_allowed_protocols_data(command):
  function test_disallowed_protocols (line 727) | def test_disallowed_protocols(command):
  function test_redirect_loop (line 735) | def test_redirect_loop():
  function test_pdf_inputs (line 764) | def test_pdf_inputs(html, fields):
  function test_appearance (line 778) | def test_appearance(css, with_forms, without_forms):
  function test_appearance_non_input (line 786) | def test_appearance_non_input():
  function test_reproducible (line 791) | def test_reproducible():
  function test_unicode_filenames (line 800) | def test_unicode_filenames(assert_pixels_equal, tmp_path):
  function test_low_level_api (line 833) | def test_low_level_api(assert_pixels_equal):
  function test_assert_bookmarks (line 1034) | def test_assert_bookmarks(html, expected_by_page, expected_tree, round):
  function simplify_links (line 1042) | def simplify_links(links):
  function assert_links (line 1048) | def assert_links(html, links, anchors, resolved_links,
  function test_links_1 (line 1069) | def test_links_1():
  function test_links_2 (line 1113) | def test_links_2():
  function test_links_3 (line 1126) | def test_links_3():
  function test_links_4 (line 1140) | def test_links_4():
  function test_links_5 (line 1152) | def test_links_5():
  function test_links_6 (line 1165) | def test_links_6():
  function test_links_7 (line 1184) | def test_links_7():
  function test_links_8 (line 1198) | def test_links_8():
  function test_links_9 (line 1216) | def test_links_9():
  function test_links_10 (line 1230) | def test_links_10():
  function test_links_11 (line 1243) | def test_links_11():
  function test_links_12 (line 1254) | def test_links_12():
  function test_deprecated_url_fetcher (line 1274) | def test_deprecated_url_fetcher(assert_pixels_equal):
  class Fetcher (line 1337) | class Fetcher(URLFetcher):
    method fetch (line 1338) | def fetch(self, url, headers=None):
  function test_url_fetcher (line 1375) | def test_url_fetcher(html, assert_pixels_equal):
  function test_url_fetcher_default (line 1383) | def test_url_fetcher_default(assert_pixels_equal):
  function test_url_fetcher_bad_image (line 1392) | def test_url_fetcher_bad_image(assert_pixels_equal):
  function test_url_fetcher_bad_stylesheet (line 1404) | def test_url_fetcher_bad_stylesheet(assert_pixels_equal):
  function test_url_fetcher_non_fatal_error (line 1415) | def test_url_fetcher_non_fatal_error(assert_pixels_equal):
  function test_url_fetcher_fatal_error (line 1424) | def test_url_fetcher_fatal_error(assert_pixels_equal):
  function test_url_fetcher_default_fail_on_errors (line 1431) | def test_url_fetcher_default_fail_on_errors(assert_pixels_equal):
  function assert_meta (line 1439) | def assert_meta(html, **meta):
  function test_html_meta_1 (line 1455) | def test_html_meta_1():
  function test_html_meta_2 (line 1460) | def test_html_meta_2():
  function test_html_meta_3 (line 1497) | def test_html_meta_3():
  function test_html_meta_4 (line 1511) | def test_html_meta_4():
  function test_http (line 1526) | def test_http():
  function test_page_copy_relative (line 1569) | def test_page_copy_relative():

FILE: tests/test_boxes.py
  function test_box_tree (line 15) | def test_box_tree():
  function test_html_entities (line 33) | def test_html_entities():
  function test_inline_in_block_1 (line 41) | def test_inline_in_block_1():
  function test_inline_in_block_2 (line 60) | def test_inline_in_block_2():
  function test_inline_in_block_3 (line 79) | def test_inline_in_block_3():
  function test_inline_in_block_4 (line 99) | def test_inline_in_block_4():
  function test_block_in_inline (line 116) | def test_block_in_inline():
  function test_styles (line 189) | def test_styles():
  function test_whitespace (line 213) | def test_whitespace():
  function test_page_style (line 260) | def test_page_style(page_type, top, right, bottom, left):
  function test_images_1 (line 287) | def test_images_1():
  function test_images_2 (line 308) | def test_images_2():
  function test_tables_1 (line 322) | def test_tables_1():
  function test_tables_2 (line 382) | def test_tables_2():
  function test_tables_3 (line 401) | def test_tables_3():
  function test_tables_4 (line 425) | def test_tables_4():
  function test_tables_5 (line 440) | def test_tables_5():
  function test_tables_6 (line 454) | def test_tables_6():
  function test_tables_7 (line 466) | def test_tables_7():
  function test_tables_8 (line 490) | def test_tables_8():
  function test_tables_9 (line 504) | def test_tables_9():
  function test_table_style (line 518) | def test_table_style():
  function test_column_style (line 532) | def test_column_style():
  function test_nested_grid_x (line 551) | def test_nested_grid_x():
  function test_colspan_rowspan_1 (line 572) | def test_colspan_rowspan_1():
  function test_colspan_rowspan_2 (line 633) | def test_colspan_rowspan_2():
  function test_before_after_1 (line 665) | def test_before_after_1():
  function test_before_after_2 (line 683) | def test_before_after_2():
  function test_before_after_3 (line 701) | def test_before_after_3():
  function test_before_after_4 (line 717) | def test_before_after_4():
  function test_before_after_5 (line 744) | def test_before_after_5():
  function test_quotes_auto (line 770) | def test_quotes_auto():
  function test_quotes_none (line 797) | def test_quotes_none():
  function test_quotes_lang (line 824) | def test_quotes_lang():
  function test_quotes_lang_alternate (line 850) | def test_quotes_lang_alternate():
  function test_quotes_lang_parent (line 876) | def test_quotes_lang_parent():
  function test_margin_boxes (line 902) | def test_margin_boxes():
  function test_margin_box_string_set_1 (line 935) | def test_margin_box_string_set_1():
  function test_margin_box_string_set_2 (line 965) | def test_margin_box_string_set_2():
  function test_margin_box_string_set_3 (line 998) | def test_margin_box_string_set_3():
  function test_margin_box_string_set_4 (line 1020) | def test_margin_box_string_set_4():
  function test_margin_box_string_set_5 (line 1047) | def test_margin_box_string_set_5():
  function test_margin_box_string_set_6 (line 1070) | def test_margin_box_string_set_6():
  function test_margin_box_string_set_7 (line 1110) | def test_margin_box_string_set_7():
  function test_margin_box_string_set_8 (line 1133) | def test_margin_box_string_set_8():
  function test_margin_box_string_set_9 (line 1165) | def test_margin_box_string_set_9():
  function test_margin_box_string_set_10 (line 1190) | def test_margin_box_string_set_10():
  function test_page_counters (line 1225) | def test_page_counters():
  function test_display_none_root (line 1255) | def test_display_none_root(html):

FILE: tests/test_fonts.py
  function test_font_face (line 7) | def test_font_face():
  function test_kerning_default (line 20) | def test_kerning_default():
  function test_ligatures_word_space (line 36) | def test_ligatures_word_space():
  function test_kerning_deactivate (line 50) | def test_kerning_deactivate():
  function test_kerning_ligature_deactivate (line 76) | def test_kerning_ligature_deactivate():
  function test_font_face_descriptors (line 103) | def test_font_face_descriptors():
  function test_woff_simple (line 134) | def test_woff_simple():

FILE: tests/test_pdf.py
  function test_page_size_zoom (line 25) | def test_page_size_zoom(zoom):
  function test_bookmarks_1 (line 32) | def test_bookmarks_1():
  function test_bookmarks_2 (line 51) | def test_bookmarks_2():
  function test_bookmarks_3 (line 57) | def test_bookmarks_3():
  function test_bookmarks_4 (line 64) | def test_bookmarks_4():
  function test_bookmarks_5 (line 104) | def test_bookmarks_5():
  function test_bookmarks_6 (line 127) | def test_bookmarks_6():
  function test_bookmarks_7 (line 158) | def test_bookmarks_7():
  function test_bookmarks_8 (line 173) | def test_bookmarks_8():
  function test_bookmarks_9 (line 200) | def test_bookmarks_9():
  function test_bookmarks_10 (line 211) | def test_bookmarks_10():
  function test_bookmarks_11 (line 231) | def test_bookmarks_11():
  function test_bookmarks_12 (line 253) | def test_bookmarks_12():
  function test_bookmarks_13 (line 265) | def test_bookmarks_13():
  function test_bookmarks_14 (line 278) | def test_bookmarks_14():
  function test_bookmarks_15 (line 292) | def test_bookmarks_15():
  function test_links_none (line 304) | def test_links_none():
  function test_links (line 310) | def test_links():
  function test_sorted_links (line 371) | def test_sorted_links():
  function test_relative_links_no_height (line 383) | def test_relative_links_no_height():
  function test_relative_links_missing_base (line 393) | def test_relative_links_missing_base():
  function test_relative_links_missing_base_link (line 403) | def test_relative_links_missing_base_link():
  function test_relative_links_internal (line 416) | def test_relative_links_internal():
  function test_relative_links_anchors (line 433) | def test_relative_links_anchors():
  function test_relative_links_different_base (line 449) | def test_relative_links_different_base():
  function test_relative_links_same_base (line 457) | def test_relative_links_same_base():
  function test_missing_links (line 465) | def test_missing_links():
  function test_anchor_multiple_pages (line 488) | def test_anchor_multiple_pages():
  function test_embed_gif (line 502) | def test_embed_gif():
  function test_embed_jpeg (line 509) | def test_embed_jpeg():
  function test_embed_image_once (line 517) | def test_embed_image_once():
  function test_embed_images_from_pages (line 530) | def test_embed_images_from_pages():
  function test_document_info (line 545) | def test_document_info():
  function test_embedded_files_attachments (line 569) | def test_embedded_files_attachments(tmp_path):
  function test_attachments_data (line 624) | def test_attachments_data():
  function test_attachments_data_with_anchor (line 636) | def test_attachments_data_with_anchor():
  function test_attachments_no_href (line 650) | def test_attachments_no_href():
  function test_attachments_none (line 664) | def test_attachments_none():
  function test_attachments_none_empty (line 675) | def test_attachments_none_empty():
  function test_annotations (line 685) | def test_annotations():
  function test_bleed (line 711) | def test_bleed(style, media, bleed, trim):
  function test_default_rdf_metadata (line 723) | def test_default_rdf_metadata():
  function test_custom_rdf_metadata (line 734) | def test_custom_rdf_metadata():
  function test_font_descent_ascent (line 749) | def test_font_descent_ascent():
  function test_pdf_tags_inline_table (line 758) | def test_pdf_tags_inline_table():

FILE: tests/test_presentational_hints.py
  function test_no_ph (line 14) | def test_no_ph():
  function test_ph_page (line 29) | def test_ph_page():
  function test_ph_flow (line 46) | def test_ph_flow():
  function test_ph_phrasing (line 70) | def test_ph_phrasing():
  function test_ph_lists (line 104) | def test_ph_lists():
  function test_ph_lists_types (line 136) | def test_ph_lists_types():
  function test_ph_tables (line 162) | def test_ph_tables():
  function test_ph_hr (line 225) | def test_ph_hr():
  function test_ph_embedded (line 255) | def test_ph_embedded():

FILE: tests/test_stacking.py
  function flatten_blocks_and_cells (line 24) | def flatten_blocks_and_cells(blocks_and_cells):
  function serialize_stacking (line 30) | def serialize_stacking(context):
  function test_nested (line 51) | def test_nested(source, contexts):
  function test_image_contexts (line 58) | def test_image_contexts():
  function test_z_index (line 82) | def test_z_index(assert_pixels, z_indexes, color):

FILE: tests/test_text.py
  function make_text (line 13) | def make_text(text, width=None, **style):
  function test_line_content (line 24) | def test_line_content():
  function test_line_with_any_width (line 35) | def test_line_with_any_width():
  function test_line_breaking (line 42) | def test_line_breaking():
  function test_line_breaking_rtl (line 58) | def test_line_breaking_rtl():
  function test_line_breaking_nbsp (line 70) | def test_line_breaking_nbsp():
  function test_text_dimension (line 89) | def test_text_dimension():
  function test_text_font_size_zero (line 98) | def test_text_font_size_zero():
  function test_text_font_size_very_small (line 116) | def test_text_font_size_very_small():
  function test_text_spaced_inlines (line 133) | def test_text_spaced_inlines():
  function test_text_align_left (line 160) | def test_text_align_left():
  function test_text_align_right (line 186) | def test_text_align_right():
  function test_text_align_center (line 213) | def test_text_align_center():
  function test_text_align_justify (line 240) | def test_text_align_justify():
  function test_text_align_justify_all (line 278) | def test_text_align_justify_all():
  function test_text_align_all_last (line 319) | def test_text_align_all_last():
  function test_text_align_not_enough_space (line 358) | def test_text_align_not_enough_space():
  function test_text_align_justify_no_space (line 373) | def test_text_align_justify_no_space():
  function test_text_align_justify_text_indent (line 390) | def test_text_align_justify_text_indent():
  function test_text_align_justify_no_break_between_children (line 430) | def test_text_align_justify_no_break_between_children():
  function test_word_spacing (line 470) | def test_word_spacing(text):
  function test_letter_spacing_1 (line 492) | def test_letter_spacing_1():
  function test_spacing_ex (line 544) | def test_spacing_ex(spacing):
  function test_text_indent (line 551) | def test_text_indent(indent):
  function test_text_indent_inline (line 573) | def test_text_indent_inline():
  function test_text_indent_multipage (line 590) | def test_text_indent_multipage(indent):
  function test_hyphenate_character_1 (line 618) | def test_hyphenate_character_1():
  function test_hyphenate_character_2 (line 634) | def test_hyphenate_character_2():
  function test_hyphenate_character_3 (line 650) | def test_hyphenate_character_3():
  function test_hyphenate_character_4 (line 666) | def test_hyphenate_character_4():
  function test_hyphenate_character_5 (line 681) | def test_hyphenate_character_5():
  function test_hyphenate_manual_1 (line 698) | def test_hyphenate_manual_1(i):
  function test_hyphenate_manual_2 (line 718) | def test_hyphenate_manual_2(i):
  function test_hyphenate_manual_3 (line 743) | def test_hyphenate_manual_3():
  function test_hyphenate_manual_4 (line 760) | def test_hyphenate_manual_4():
  function test_hyphenate_limit_zone_1 (line 773) | def test_hyphenate_limit_zone_1():
  function test_hyphenate_limit_zone_2 (line 789) | def test_hyphenate_limit_zone_2():
  function test_hyphenate_limit_zone_3 (line 805) | def test_hyphenate_limit_zone_3():
  function test_hyphenate_limit_zone_4 (line 821) | def test_hyphenate_limit_zone_4():
  function test_hyphen_nbsp (line 836) | def test_hyphen_nbsp():
  function test_hyphenate_limit_chars (line 868) | def test_hyphenate_limit_chars(css, result):
  function test_hyphenate_limit_chars_punctuation (line 887) | def test_hyphenate_limit_chars_punctuation(css):
  function test_overflow_wrap (line 910) | def test_overflow_wrap(wrap, text, test, full_text):
  function test_wrap_overflow_word_break (line 944) | def test_wrap_overflow_word_break(span_css, expected_lines):
  function test_overflow_wrap_2 (line 972) | def test_overflow_wrap_2(wrap, text, body_width, expected_width):
  function test_overflow_wrap_trailing_space (line 996) | def test_overflow_wrap_trailing_space(wrap, text, body_width, expected_w...
  function test_overflow_wrap_no_break_on_space (line 1013) | def test_overflow_wrap_no_break_on_space():
  function test_line_break_before_trailing_space (line 1029) | def test_line_break_before_trailing_space():
  function test_line_break_before_nested_trailing_space (line 1042) | def test_line_break_before_nested_trailing_space():
  function white_space_lines (line 1054) | def white_space_lines(width, space):
  function test_white_space_1 (line 1067) | def test_white_space_1():
  function test_white_space_2 (line 1084) | def test_white_space_2():
  function test_white_space_3 (line 1095) | def test_white_space_3():
  function test_white_space_4 (line 1103) | def test_white_space_4():
  function test_white_space_5 (line 1123) | def test_white_space_5():
  function test_white_space_6 (line 1140) | def test_white_space_6():
  function test_white_space_7 (line 1148) | def test_white_space_7():
  function test_white_space_8 (line 1159) | def test_white_space_8():
  function test_white_space_9 (line 1167) | def test_white_space_9():
  function test_white_space_10 (line 1178) | def test_white_space_10():
  function test_white_space_11 (line 1189) | def test_white_space_11():
  function test_white_space_12 (line 1208) | def test_white_space_12():
  function test_tab_size (line 1233) | def test_tab_size(value, width):
  function test_text_transform (line 1248) | def test_text_transform():
  function test_text_transform_lang_uppercase (line 1287) | def test_text_transform_lang_uppercase(lang, lowercase, uppercase):
  function test_text_transform_lang_lowercase (line 1307) | def test_text_transform_lang_lowercase(lang, uppercase, lowercase):
  function test_text_transform_capitalize (line 1339) | def test_text_transform_capitalize(original, transformed, lang_code):
  function test_text_floating_pre_line (line 1346) | def test_text_floating_pre_line():
  function test_leader_content (line 1363) | def test_leader_content(leader, content):
  function test_max_lines (line 1379) | def test_max_lines():
  function test_continue (line 1407) | def test_continue():
  function test_first_letter_line_height (line 1432) | def test_first_letter_line_height():
  function test_first_letter_text_transform (line 1451) | def test_first_letter_text_transform():
  function test_first_letter_nested (line 1470) | def test_first_letter_nested():
  function test_first_line_line_height (line 1499) | def test_first_line_line_height():
  function test_first_line_text_transform (line 1518) | def test_first_line_text_transform():
  function test_first_line_nested (line 1537) | def test_first_line_nested():
  function test_first_line_first_letter (line 1568) | def test_first_line_first_letter():

FILE: tests/test_unicode.py
  function test_unicode (line 10) | def test_unicode(assert_pixels_equal, tmp_path):

FILE: tests/test_url.py
  function test_malformed_url_link (line 15) | def test_malformed_url_link(url, base_url):

FILE: tests/testing_utils.py
  class FakeHTML (line 42) | class FakeHTML(HTML):
    method __init__ (line 44) | def __init__(self, *args, force_uncompressed_pdf=True, **kwargs):
    method _ua_stylesheets (line 48) | def _ua_stylesheets(self, forms=False):
    method render (line 53) | def render(self, font_config=None, *args, **kwargs):
    method write_pdf (line 56) | def write_pdf(self, target=None, zoom=1, finisher=None, **options):
  function resource_path (line 63) | def resource_path(name):
  function assert_no_logs (line 75) | def assert_no_logs(function):
  function serialize (line 96) | def serialize(box_list):
  function tree_position (line 109) | def tree_position(box_list, matcher):
  function _parse_base (line 130) | def _parse_base(html_content, base_url=BASE_URL):
  function parse (line 144) | def parse(html_content):
  function parse_all (line 150) | def parse_all(html_content, base_url=BASE_URL):
  function render_pages (line 158) | def render_pages(html_content):
  function assert_tree (line 165) | def assert_tree(box, expected):
  function _sanity_checks (line 185) | def _sanity_checks(box):

FILE: weasyprint/__init__.py
  function _find_base_url (line 101) | def _find_base_url(html_document, fallback_base_url):
  class HTML (line 115) | class HTML:
    method __init__ (line 159) | def __init__(self, guess=None, filename=None, url=None, file_obj=None,
    method _ua_stylesheets (line 186) | def _ua_stylesheets(self, forms=False):
    method _ua_counter_style (line 191) | def _ua_counter_style(self):
    method _ph_stylesheets (line 194) | def _ph_stylesheets(self):
    method render (line 197) | def render(self, font_config=None, counter_style=None, color_profiles=...
    method write_pdf (line 225) | def write_pdf(self, target=None, zoom=1, finisher=None,
  class CSS (line 270) | class CSS:
    method __init__ (line 285) | def __init__(self, guess=None, filename=None, url=None, file_obj=None,...
  class Attachment (line 318) | class Attachment:
    method __init__ (line 343) | def __init__(self, guess=None, filename=None, url=None, file_obj=None,

FILE: weasyprint/__main__.py
  class PrintInfo (line 16) | class PrintInfo(argparse.Action):
    method __call__ (line 17) | def __call__(*_, **__):
  class Parser (line 33) | class Parser(argparse.ArgumentParser):
    method __init__ (line 34) | def __init__(self, *args, **kwargs):
    method add_argument (line 38) | def add_argument(self, *args, _group_name=None, **kwargs):
    method add_argument_group (line 46) | def add_argument_group(self, name, *args, **kwargs):
    method docstring (line 57) | def docstring(self):
  function main (line 173) | def main(argv=None, stdout=None, stdin=None, HTML=HTML):  # noqa: N803

FILE: weasyprint/anchors.py
  function rectangle_aabb (line 10) | def rectangle_aabb(matrix, pos_x, pos_y, width, height):
  function gather_anchors (line 30) | def gather_anchors(box, anchors, links, bookmarks, forms, parent_matrix=...
  function make_page_bookmark_tree (line 132) | def make_page_bookmark_tree(page, skipped_levels, last_by_depth,

FILE: weasyprint/css/__init__.py
  class StyleFor (line 54) | class StyleFor:
    method __init__ (line 56) | def __init__(self, html, sheets, presentational_hints, font_config,
    method __call__ (line 141) | def __call__(self, element, pseudo_type=None):
    method set_computed_styles (line 155) | def set_computed_styles(self, element, parent, root=None, pseudo_type=...
    method add_page_declarations (line 182) | def add_page_declarations(self, page_type):
    method get_cascaded_styles (line 200) | def get_cascaded_styles(self):
    method get_computed_styles (line 203) | def get_computed_styles(self):
    method _page_type_match (line 207) | def _page_type_match(page_selector_type, page_type):
  function get_child_text (line 234) | def get_child_text(element):
  function text_decoration (line 243) | def text_decoration(key, value, parent_value, cascaded):
  function find_stylesheets (line 262) | def find_stylesheets(wrapper_element, device_media_type, url_fetcher, ba...
  function find_style_attributes (line 310) | def find_style_attributes(tree, presentational_hints=False, base_url=None):
  function declaration_precedence (line 569) | def declaration_precedence(origin, importance):
  function resolve_var (line 592) | def resolve_var(computed, token, parent_style, known_variables=None):
  function _resolve_calc_sum (line 635) | def _resolve_calc_sum(computed, tokens, property_name, refer_to):
  function _resolve_calc_product (line 704) | def _resolve_calc_product(computed, tokens, property_name, refer_to):
  function _resolve_calc_value (line 754) | def _resolve_calc_value(computed, tokens):
  function resolve_math (line 772) | def resolve_math(token, computed=None, property_name=None, refer_to=None):
  class InitialStyle (line 1034) | class InitialStyle(dict):
    method __init__ (line 1036) | def __init__(self, font_config):
    method __missing__ (line 1042) | def __missing__(self, key):
  class AnonymousStyle (line 1047) | class AnonymousStyle(dict):
    method __init__ (line 1049) | def __init__(self, parent_style):
    method copy (line 1066) | def copy(self):
    method __missing__ (line 1071) | def __missing__(self, key):
  class ComputedStyle (line 1091) | class ComputedStyle(dict):
    method __init__ (line 1093) | def __init__(self, parent_style, cascaded, element, pseudo_type,
    method copy (line 1107) | def copy(self):
    method __missing__ (line 1115) | def __missing__(self, key):
  class ColorProfile (line 1244) | class ColorProfile:
    method __init__ (line 1245) | def __init__(self, file_object, descriptors):
    method name (line 1252) | def name(self):
    method content (line 1258) | def content(self):
  function _add_layer (line 1262) | def _add_layer(layer, layers):
  function computed_from_cascaded (line 1282) | def computed_from_cascaded(element, cascaded, parent_style, pseudo_type=...
  function _parse_layer (line 1290) | def _parse_layer(tokens):
  function parse_color_profile_name (line 1309) | def parse_color_profile_name(prelude):
  function parse_page_selectors (line 1323) | def parse_page_selectors(rule):
  function preprocess_stylesheet (line 1440) | def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules,...
  function get_all_computed_styles (line 1786) | def get_all_computed_styles(html, user_stylesheets=None, presentational_...

FILE: weasyprint/css/computed_values.py
  function register_logical (line 133) | def register_logical(names, prefixes=('',), suffixes=('',)):
  function physical_size (line 154) | def physical_size(name, prefix, suffix, block, inline):
  function physical_inset (line 167) | def physical_inset(name, prefix, suffix, block, inline):
  function physical_radius (line 189) | def physical_radius(name, prefix, suffix, block, inline):
  function register_computer (line 214) | def register_computer(name):
  function compute_attr (line 225) | def compute_attr(style, values):
  function background_image (line 260) | def background_image(style, name, values):
  function image (line 266) | def image(style, name, image):
  function color (line 292) | def color(style, name, values):
  function compute_position (line 298) | def compute_position(style, name, values):
  function length_or_percentage_tuple (line 307) | def length_or_percentage_tuple(style, name, values):
  function length_tuple (line 315) | def length_tuple(style, name, values):
  function break_before_after (line 322) | def break_before_after(style, name, value):
  function length (line 356) | def length(style, name, value, font_size=None, pixels_only=False):
  function bleed (line 374) | def bleed(style, name, value):
  function pixel_length (line 381) | def pixel_length(style, name, value):
  function background_size (line 388) | def background_size(style, name, values):
  function image_orientation (line 397) | def image_orientation(style, name, values):
  function border_width (line 411) | def border_width(style, name, value):
  function border_image_slice (line 430) | def border_image_slice(style, name, values):
  function border_image_width (line 454) | def border_image_width(style, name, values):
  function border_image_outset (line 474) | def border_image_outset(style, name, values):
  function border_image_repeat (line 490) | def border_image_repeat(style, name, values):
  function length_pixels_only (line 497) | def length_pixels_only(style, name, value):
  function border_radius (line 506) | def border_radius(style, name, values):
  function gap (line 513) | def gap(style, name, value):
  function _content_list (line 518) | def _content_list(style, values):
  function bookmark_label (line 554) | def bookmark_label(style, name, values):
  function string_set (line 560) | def string_set(style, name, values):
  function content (line 569) | def content(style, name, values):
  function display (line 581) | def display(style, name, value):
  function compute_float (line 600) | def compute_float(style, name, value):
  function font_size (line 611) | def font_size(style, name, value):
  function font_weight (line 643) | def font_weight(style, name, value):
  function _compute_track_breadth (line 659) | def _compute_track_breadth(style, name, value):
  function _track_size (line 670) | def _track_size(style, name, values):
  function grid_template (line 698) | def grid_template(style, name, values):
  function grid_auto (line 708) | def grid_auto(style, name, values):
  function line_height (line 726) | def line_height(style, name, value):
  function anchor (line 742) | def anchor(style, name, values):
  function link (line 751) | def link(style, name, values):
  function lang (line 762) | def lang(style, name, values):
  function tab_size (line 774) | def tab_size(style, name, value):
  function transform (line 780) | def transform(style, name, value):
  function vertical_align (line 791) | def vertical_align(style, name, value):
  function word_spacing (line 817) | def word_spacing(style, name, value):

FILE: weasyprint/css/counters.py
  function symbol (line 13) | def symbol(string_or_url):
  function parse_counter_style_name (line 23) | def parse_counter_style_name(tokens, counter_style):
  class CounterStyle (line 35) | class CounterStyle(dict):
    method resolve_counter (line 44) | def resolve_counter(self, counter_name, previous_types=None):
    method render_value (line 103) | def render_value(self, counter_value, counter_name=None, counter=None,
    method render_marker (line 277) | def render_marker(self, counter_name, counter_value):
    method copy (line 294) | def copy(self):

FILE: weasyprint/css/functions.py
  class Function (line 4) | class Function:
    method __init__ (line 8) | def __init__(self, token):
    method split_space (line 16) | def split_space(self):
    method split_comma (line 23) | def split_comma(self, single_tokens=True, trailing=False):
  function check_attr (line 61) | def check_attr(token, allowed_type=None):
  function check_counter (line 89) | def check_counter(token, allowed_type=None):
  function check_content (line 126) | def check_content(token):
  function check_string_or_element (line 139) | def check_string_or_element(string_or_element, token):
  function check_var (line 161) | def check_var(token):
  function check_math (line 176) | def check_math(token):

FILE: weasyprint/css/media_queries.py
  function evaluate_media_query (line 13) | def evaluate_media_query(query_list, device_media_type):
  function parse_media_query (line 25) | def parse_media_query(tokens):

FILE: weasyprint/css/targets.py
  class TargetLookupItem (line 14) | class TargetLookupItem:
    method __init__ (line 20) | def __init__(self, state='pending'):
  class CounterLookupItem (line 39) | class CounterLookupItem:
    method __init__ (line 45) | def __init__(self, parse_again, missing_counters, missing_target_count...
  function anchor_name_from_token (line 63) | def anchor_name_from_token(anchor_token):
  class TargetCollector (line 71) | class TargetCollector:
    method __init__ (line 74) | def __init__(self):
    method collect_anchor (line 90) | def collect_anchor(self, anchor_name):
    method lookup_target (line 99) | def lookup_target(self, anchor_token, source_box, css_token, parse_aga...
    method store_target (line 123) | def store_target(self, anchor_name, target_counter_values, target_box):
    method collect_missing_counters (line 141) | def collect_missing_counters(self, parent_box, css_token,
    method check_pending_targets (line 166) | def check_pending_targets(self):
    method cache_target_page_counters (line 176) | def cache_target_page_counters(self, anchor_name, page_counter_values,

FILE: weasyprint/css/tokens.py
  class InvalidValues (line 52) | class InvalidValues(ValueError):  # noqa: N818
  class PercentageInMath (line 56) | class PercentageInMath(ValueError):  # noqa: N818
  class RelativeLengthInMath (line 60) | class RelativeLengthInMath(ValueError):  # noqa: N818
  class Pending (line 64) | class Pending(ABC):
    method __init__ (line 67) | def __init__(self, tokens, name):
    method validate (line 73) | def validate(self, tokens, wanted_key):
    method solve (line 77) | def solve(self, tokens, wanted_key):
  function parse_color_hint (line 99) | def parse_color_hint(tokens):
  function parse_color_stop (line 104) | def parse_color_stop(tokens):
  function parse_color_stops_and_hints (line 120) | def parse_color_stops_and_hints(color_stops_hints):
  function parse_linear_gradient_parameters (line 146) | def parse_linear_gradient_parameters(arguments):
  function parse_2d_position (line 159) | def parse_2d_position(tokens):
  function parse_position (line 187) | def parse_position(tokens):
  function parse_radial_gradient_parameters (line 236) | def parse_radial_gradient_parameters(arguments):
  function split_on_comma (line 279) | def split_on_comma(tokens):
  function remove_whitespace (line 298) | def remove_whitespace(tokens):
  function get_keyword (line 305) | def get_keyword(token):
  function get_custom_ident (line 315) | def get_custom_ident(token):
  function get_single_keyword (line 325) | def get_single_keyword(tokens):
  function get_number (line 337) | def get_number(token, negative=True, integer=False):
  function get_string (line 368) | def get_string(token):
  function get_percentage (line 383) | def get_percentage(token, negative=True):
  function get_length (line 400) | def get_length(token, negative=True, percentage=False):
  function get_angle (line 427) | def get_angle(token):
  function get_resolution (line 444) | def get_resolution(token):
  function get_image (line 458) | def get_image(token, base_url):
  function get_url (line 490) | def get_url(token, base_url):
  function get_quote (line 512) | def get_quote(token):
  function get_target (line 521) | def get_target(token, base_url):
  function get_content_list (line 578) | def get_content_list(tokens, base_url):
  function get_content_list_token (line 586) | def get_content_list_token(token, base_url):
  function single_keyword (line 636) | def single_keyword(function):
  function single_token (line 647) | def single_token(function):
  function comma_separated_list (line 658) | def comma_separated_list(function):
  function tokenize (line 673) | def tokenize(item, function=None, unit=None):

FILE: weasyprint/css/units.py
  function to_pixels (line 58) | def to_pixels(value, style, property_name, font_size=None):
  function to_radians (line 115) | def to_radians(value):

FILE: weasyprint/css/validation/__init__.py
  function preprocess_declarations (line 114) | def preprocess_declarations(base_url, declarations, prelude=None):

FILE: weasyprint/css/validation/descriptors.py
  class NoneFakeToken (line 25) | class NoneFakeToken:
  class NormalFakeToken (line 30) | class NormalFakeToken:
  function preprocess_descriptors (line 35) | def preprocess_descriptors(rule, base_url, descriptors):
  function descriptor (line 73) | def descriptor(rule, descriptor_name=None, wants_base_url=False):
  function expand_font_variant (line 99) | def expand_font_variant(tokens):
  function font_family (line 134) | def font_family(tokens, allow_spaces=False):
  function src (line 148) | def src(tokens, base_url):
  function font_style (line 163) | def font_style(keyword):
  function font_weight (line 170) | def font_weight(token):
  function font_stretch (line 182) | def font_stretch(keyword):
  function font_feature_settings (line 191) | def font_feature_settings(tokens):
  function font_variant (line 197) | def font_variant(tokens):
  function unicode_range (line 216) | def unicode_range(token):
  function system (line 223) | def system(tokens):
  function negative (line 244) | def negative(tokens, base_url):
  function prefix_suffix (line 269) | def prefix_suffix(tokens, base_url):
  function range (line 284) | def range(tokens):
  function pad (line 302) | def pad(tokens, base_url):
  function fallback (line 322) | def fallback(token):
  function symbols (line 330) | def symbols(tokens, base_url):
  function additive_symbols (line 346) | def additive_symbols(tokens, base_url):
  function color_profile_src (line 360) | def color_profile_src(token, base_url):
  function rendering_intent (line 368) | def rendering_intent(keyword):
  function components (line 377) | def components(tokens):

FILE: weasyprint/css/validation/expanders.py
  class PendingExpander (line 27) | class PendingExpander(Pending):
    method __init__ (line 29) | def __init__(self, tokens, validator):
    method validate (line 33) | def validate(self, tokens, wanted_key):
  function _find_var (line 42) | def _find_var(tokens, expander, expanded_names):
  function expander (line 51) | def expander(property_name):
  function generic_expander (line 61) | def generic_expander(*expanded_names, **kwargs):
  function expand_two_logical_sides (line 137) | def expand_two_logical_sides(tokens, name, base_url):
  function expand_four_sides (line 149) | def expand_four_sides(tokens, name, base_url):
  function _expand_sides (line 158) | def _expand_sides(tokens, name, base_url, sides):
  function border_radius (line 198) | def border_radius(tokens, name, base_url):
  function expand_list_style (line 237) | def expand_list_style(tokens, name, base_url):
  function expand_border (line 279) | def expand_border(tokens, name, base_url):
  function expand_logical_border (line 291) | def expand_logical_border(tokens, name, base_url):
  function expand_border_side (line 308) | def expand_border_side(tokens, name):
  function expand_border_image (line 329) | def expand_border_image(tokens, name, base_url):
  function expand_mask_border (line 393) | def expand_mask_border(tokens, name, base_url):
  function expand_background (line 457) | def expand_background(tokens, name, base_url):
  function expand_text_decoration (line 561) | def expand_text_decoration(tokens, name):
  function expand_page_break_before_after (line 602) | def expand_page_break_before_after(tokens, name):
  function expand_page_break_after (line 622) | def expand_page_break_after(tokens, name):
  function expand_page_break_before (line 633) | def expand_page_break_before(tokens, name):
  function expand_page_break_inside (line 644) | def expand_page_break_inside(tokens, name):
  function expand_columns (line 659) | def expand_columns(tokens, name):
  function font_variant (line 682) | def font_variant(tokens, name):
  function expand_font (line 694) | def expand_font(tokens, name):
  function expand_word_wrap (line 766) | def expand_word_wrap(tokens, name):
  function expand_flex (line 780) | def expand_flex(tokens, name):
  function expand_flex_flow (line 838) | def expand_flex_flow(tokens, name):
  function _expand_grid_template (line 864) | def _expand_grid_template(tokens, name):
  function expand_grid_template (line 900) | def expand_grid_template(tokens, name):
  function expand_grid (line 908) | def expand_grid(tokens, name):
  function _expand_grid_column_row_area (line 968) | def _expand_grid_column_row_area(tokens, max_number):
  function expand_grid_column_row (line 1001) | def expand_grid_column_row(tokens, name):
  function expand_grid_area (line 1011) | def expand_grid_area(tokens, name):
  function expand_gap (line 1022) | def expand_gap(tokens, name):
  function expand_legacy_column_gap (line 1041) | def expand_legacy_column_gap(tokens, name):
  function expand_legacy_row_gap (line 1051) | def expand_legacy_row_gap(tokens, name):
  function expand_place_content (line 1061) | def expand_place_content(tokens, name):
  function expand_place_items (line 1069) | def expand_place_items(tokens, name):
  function expand_place_self (line 1077) | def expand_place_self(tokens, name):
  function expand_line_clamp (line 1085) | def expand_line_clamp(tokens, name):
  function expand_text_align (line 1125) | def expand_text_align(tokens, name):

FILE: weasyprint/css/validation/properties.py
  class PendingProperty (line 34) | class PendingProperty(Pending):
    method validate (line 36) | def validate(self, tokens, wanted_key):
  function property (line 42) | def property(property_name=None, proprietary=False, unstable=False,
  function validate_non_shorthand (line 83) | def validate_non_shorthand(tokens, name, base_url=None, required=False):
  function background_attachment (line 117) | def background_attachment(keyword):
  function other_colors (line 134) | def other_colors(token):
  function outline_color (line 141) | def outline_color(token):
  function border_collapse (line 150) | def border_collapse(keyword):
  function empty_cells (line 156) | def empty_cells(keyword):
  function color (line 163) | def color(token):
  function background_image (line 175) | def background_image(token, base_url):
  function list_style_image (line 183) | def list_style_image(token, base_url):
  function transform_origin (line 194) | def transform_origin(tokens):
  function background_position (line 204) | def background_position(tokens):
  function object_position (line 211) | def object_position(tokens):
  function background_repeat (line 218) | def background_repeat(tokens):
  function background_size (line 235) | def background_size(tokens):
  function box (line 263) | def box(keyword):
  function border_spacing (line 270) | def border_spacing(tokens):
  function border_corner_radius (line 288) | def border_corner_radius(tokens):
  function border_style (line 308) | def border_style(keyword):
  function break_before_after (line 317) | def break_before_after(keyword):
  function break_inside (line 325) | def break_inside(keyword):
  function box_decoration_break (line 332) | def box_decoration_break(keyword):
  function block_ellipsis (line 339) | def block_ellipsis(token):
  function continue_ (line 351) | def continue_(keyword):
  function max_lines (line 358) | def max_lines(token):
  function margin_break (line 367) | def margin_break(keyword):
  function page (line 374) | def page(token):
  function bleed (line 385) | def bleed(token):
  function marks (line 394) | def marks(tokens):
  function outline_style (line 409) | def outline_style(keyword):
  function border_width (line 426) | def border_width(token):
  function border_image_source (line 437) | def border_image_source(token, base_url):
  function border_image_slice (line 445) | def border_image_slice(tokens):
  function border_image_width (line 466) | def border_image_width(tokens):
  function border_image_outset (line 484) | def border_image_outset(tokens):
  function border_image_repeat (line 500) | def border_image_repeat(tokens):
  function mask_border_mode (line 509) | def mask_border_mode(keyword):
  function column_width (line 515) | def column_width(token):
  function column_span (line 526) | def column_span(keyword):
  function box_sizing (line 533) | def box_sizing(keyword):
  function caption_side (line 540) | def caption_side(keyword):
  function clear (line 547) | def clear(keyword):
  function clip (line 554) | def clip(token):
  function content (line 573) | def content(tokens, base_url):
  function counter_increment (line 600) | def counter_increment(tokens):
  function counter_reset (line 606) | def counter_reset(tokens):
  function counter_set (line 612) | def counter_set(tokens):
  function counter (line 617) | def counter(tokens, default_integer):
  function lenght_precentage_or_auto (line 662) | def lenght_precentage_or_auto(token):
  function width_height (line 675) | def width_height(token):
  function gap (line 686) | def gap(token):
  function column_fill (line 697) | def column_fill(keyword):
  function direction (line 704) | def direction(keyword):
  function display (line 710) | def display(tokens):
  function float_ (line 757) | def float_(keyword):  # XXX do not hide the "float" builtin
  function font_family (line 765) | def font_family(tokens):
  function font_kerning (line 775) | def font_kerning(keyword):
  function font_language_override (line 781) | def font_language_override(token):
  function font_variant_ligatures (line 790) | def font_variant_ligatures(tokens):
  function font_variant_position (line 822) | def font_variant_position(keyword):
  function font_variant_caps (line 828) | def font_variant_caps(keyword):
  function font_variant_numeric (line 835) | def font_variant_numeric(tokens):
  function font_feature_settings (line 866) | def font_feature_settings(tokens):
  function font_variant_alternates (line 898) | def font_variant_alternates(keyword):
  function font_variant_east_asian (line 905) | def font_variant_east_asian(tokens):
  function font_variation_settings (line 935) | def font_variation_settings(tokens):
  function font_size (line 952) | def font_size(token):
  function font_style (line 965) | def font_style(keyword):
  function font_stretch (line 972) | def font_stretch(keyword):
  function font_weight (line 982) | def font_weight(token):
  function object_fit (line 994) | def object_fit(keyword):
  function image_resolution (line 1003) | def image_resolution(token):
  function spacing (line 1011) | def spacing(token):
  function outline_offset (line 1021) | def outline_offset(token):
  function line_height (line 1029) | def line_height(token):
  function list_style_position (line 1041) | def list_style_position(keyword):
  function list_style_type (line 1048) | def list_style_type(token):
  function min_width_height (line 1085) | def min_width_height(token):
  function length_or_precentage (line 1103) | def length_or_precentage(token):
  function max_width_height (line 1114) | def max_width_height(token):
  function opacity (line 1124) | def opacity(token):
  function z_index (line 1134) | def z_index(token):
  function orphans_widows (line 1145) | def orphans_widows(token):
  function column_count (line 1154) | def column_count(token):
  function overflow (line 1165) | def overflow(keyword):
  function text_overflow (line 1172) | def text_overflow(keyword):
  function position (line 1179) | def position(token):
  function quotes (line 1190) | def quotes(tokens):
  function table_layout (line 1205) | def table_layout(keyword):
  function text_align_all (line 1213) | def text_align_all(keyword):
  function text_align_last (line 1220) | def text_align_last(keyword):
  function text_decoration_line (line 1226) | def text_decoration_line(tokens):
  function text_decoration_style (line 1237) | def text_decoration_style(keyword):
  function text_decoration_thickness (line 1245) | def text_decoration_thickness(token):
  function text_indent (line 1255) | def text_indent(token):
  function text_transform (line 1263) | def text_transform(keyword):
  function vertical_align (line 1270) | def vertical_align(token):
  function visibility (line 1282) | def visibility(keyword):
  function white_space (line 1289) | def white_space(keyword):
  function overflow_wrap (line 1296) | def overflow_wrap(keyword):
  function word_break (line 1303) | def word_break(keyword):
  function flex_basis (line 1310) | def flex_basis(token):
  function flex_direction (line 1320) | def flex_direction(keyword):
  function flex_grow_shrink (line 1328) | def flex_grow_shrink(token):
  function _inflexible_breadth (line 1333) | def _inflexible_breadth(token):
  function _track_breadth (line 1343) | def _track_breadth(token):
  function _track_size (line 1350) | def _track_size(token):
  function _fixed_size (line 1368) | def _fixed_size(token):
  function _line_names (line 1386) | def _line_names(token):
  function grid_auto (line 1400) | def grid_auto(tokens):
  function grid_auto_flow (line 1412) | def grid_auto_flow(tokens):
  function grid_template (line 1428) | def grid_template(tokens):
  function grid_template_areas (line 1557) | def grid_template_areas(tokens):
  function grid_line (line 1617) | def grid_line(tokens):
  function flex_wrap (line 1658) | def flex_wrap(keyword):
  function justify_content (line 1664) | def justify_content(tokens):
  function justify_items (line 1683) | def justify_items(tokens):
  function justify_self (line 1710) | def justify_self(tokens):
  function align_items (line 1734) | def align_items(tokens):
  function align_self (line 1757) | def align_self(tokens):
  function align_content (line 1780) | def align_content(tokens):
  function order (line 1804) | def order(token):
  function image_rendering (line 1811) | def image_rendering(keyword):
  function image_orientation (line 1817) | def image_orientation(tokens):
  function size (line 1841) | def size(tokens):
  function anchor (line 1882) | def anchor(token):
  function link (line 1895) | def link(token, base_url):
  function tab_size (line 1911) | def tab_size(token):
  function hyphens (line 1925) | def hyphens(token):
  function hyphenate_character (line 1933) | def hyphenate_character(token):
  function hyphenate_limit_zone (line 1943) | def hyphenate_limit_zone(token):
  function hyphenate_limit_chars (line 1949) | def hyphenate_limit_chars(tokens):
  function lang (line 1987) | def lang(token):
  function bookmark_label (line 2001) | def bookmark_label(tokens, base_url):
  function bookmark_level (line 2010) | def bookmark_level(token):
  function bookmark_state (line 2021) | def bookmark_state(keyword):
  function footnote_display (line 2028) | def footnote_display(keyword):
  function footnote_policy (line 2035) | def footnote_policy(keyword):
  function string_set (line 2042) | def string_set(tokens, base_url):
  function transform (line 2058) | def transform(tokens):
  function appearance (line 2121) | def appearance(token):
  function color_scheme (line 2128) | def color_scheme(tokens):

FILE: weasyprint/document.py
  class Page (line 25) | class Page:
    method __init__ (line 33) | def __init__(self, page_box):
    method paint (line 83) | def paint(self, stream, scale=1):
  class DiskCache (line 90) | class DiskCache:
    method __init__ (line 98) | def __init__(self, folder):
    method _path_from_key (line 104) | def _path_from_key(self, key):
    method __getitem__ (line 108) | def __getitem__(self, key):
    method __setitem__ (line 114) | def __setitem__(self, key, value):
    method __contains__ (line 122) | def __contains__(self, key):
    method __del__ (line 127) | def __del__(self):
  class Document (line 137) | class Document:
    method _build_layout_context (line 149) | def _build_layout_context(cls, html, font_config, counter_style, color...
    method _render (line 181) | def _render(cls, html, font_config, counter_style, color_profiles, opt...
    method __init__ (line 207) | def __init__(self, pages, metadata, url_fetcher, font_config, color_pr...
    method copy (line 227) | def copy(self, pages='all'):
    method make_bookmark_tree (line 260) | def make_bookmark_tree(self, scale=1, transform_pages=False):
    method write_pdf (line 293) | def write_pdf(self, target=None, zoom=1, finisher=None, **options):

FILE: weasyprint/draw/__init__.py
  function draw_page (line 18) | def draw_page(page, stream):
  function draw_stacking_context (line 31) | def draw_stacking_context(stream, stacking_context):
  function draw_background (line 139) | def draw_background(stream, bg, clip_box=True, bleed=None, marks=()):
  function draw_background_image (line 238) | def draw_background_image(stream, layer, style):
  function draw_table (line 324) | def draw_table(stream, table):
  function draw_collapsed_borders (line 354) | def draw_collapsed_borders(stream, table):
  function draw_replacedbox (line 471) | def draw_replacedbox(stream, box):
  function draw_inline_level (line 489) | def draw_inline_level(stream, page, box, offset_x=0, text_overflow='clip',
  function draw_block_level (line 529) | def draw_block_level(page, stream, blocks_and_cells):

FILE: weasyprint/draw/border.py
  function set_mask_border (line 14) | def set_mask_border(stream, box):
  function draw_column_rules (line 28) | def draw_column_rules(stream, box):
  function draw_border (line 56) | def draw_border(stream, box):
  function draw_border_image (line 116) | def draw_border_image(box, stream, image, border_slice, border_repeat, b...
  function clip_border_segment (line 321) | def clip_border_segment(stream, style, width, side, border_box,
  function draw_rounded_border (line 552) | def draw_rounded_border(stream, box, style, color):
  function draw_rect_border (line 572) | def draw_rect_border(stream, box, widths, style, color):
  function draw_line (line 602) | def draw_line(stream, x1, y1, x2, y2, thickness, style, color, offset=0):
  function draw_outline (line 670) | def draw_outline(stream, box):
  function rounded_box (line 693) | def rounded_box(stream, radii):

FILE: weasyprint/draw/color.py
  function get_color (line 8) | def get_color(style, key):
  function darken (line 14) | def darken(color):
  function lighten (line 24) | def lighten(color):
  function styled_color (line 35) | def styled_color(style, color, side):

FILE: weasyprint/draw/text.py
  function draw_text (line 18) | def draw_text(stream, textbox, offset_x, text_overflow, block_ellipsis):
  function draw_emojis (line 78) | def draw_emojis(stream, style, x, y, emojis):
  function draw_first_line (line 87) | def draw_first_line(stream, textbox, text_overflow, block_ellipsis, matr...
  function draw_text_decoration (line 291) | def draw_text_decoration(stream, textbox, offset_x, offset_y, thickness,...

FILE: weasyprint/formatting_structure/boxes.py
  class Box (line 57) | class Box:
    method all_children (line 89) | def all_children(self):
    method descendants (line 92) | def descendants(self, placeholders=False):
    method __init__ (line 101) | def __init__(self, element_tag, style, element):
    method __repr__ (line 110) | def __repr__(self):
    method anonymous_from (line 114) | def anonymous_from(cls, parent, *args, **kwargs):
    method copy (line 119) | def copy(self):
    method deepcopy (line 129) | def deepcopy(self):
    method translate (line 133) | def translate(self, dx=0, dy=0, ignore_floats=False):
    method padding_width (line 150) | def padding_width(self):
    method padding_height (line 154) | def padding_height(self):
    method border_width (line 158) | def border_width(self):
    method border_height (line 163) | def border_height(self):
    method margin_width (line 168) | def margin_width(self):
    method margin_height (line 172) | def margin_height(self):
    method content_box_x (line 178) | def content_box_x(self):
    method content_box_y (line 183) | def content_box_y(self):
    method padding_box_x (line 188) | def padding_box_x(self):
    method padding_box_y (line 192) | def padding_box_y(self):
    method border_box_x (line 196) | def border_box_x(self):
    method border_box_y (line 200) | def border_box_y(self):
    method hit_area (line 204) | def hit_area(self):
    method rounded_box (line 212) | def rounded_box(self, bt, br, bb, bl):
    method rounded_box_ratio (line 258) | def rounded_box_ratio(self, ratio):
    method rounded_padding_box (line 265) | def rounded_padding_box(self):
    method rounded_border_box (line 273) | def rounded_border_box(self):
    method rounded_content_box (line 277) | def rounded_content_box(self):
    method is_floated (line 287) | def is_floated(self):
    method is_footnote (line 291) | def is_footnote(self):
    method is_absolutely_positioned (line 295) | def is_absolutely_positioned(self):
    method is_running (line 299) | def is_running(self):
    method is_in_normal_flow (line 303) | def is_in_normal_flow(self):
    method is_monolithic (line 309) | def is_monolithic(self):
    method establishes_formatting_context (line 319) | def establishes_formatting_context(self):
    method page_values (line 332) | def page_values(self):
    method is_attachment (line 338) | def is_attachment(self):
    method is_input (line 348) | def is_input(self):
    method is_form (line 356) | def is_form(self):
  class ParentBox (line 363) | class ParentBox(Box):
    method __init__ (line 365) | def __init__(self, element_tag, style, element, children):
    method _reset_spacing (line 369) | def _reset_spacing(self, side):
    method remove_decoration (line 376) | def remove_decoration(self, start, end):
    method copy_with_children (line 384) | def copy_with_children(self, new_children):
    method deepcopy (line 395) | def deepcopy(self):
    method get_wrapped_table (line 400) | def get_wrapped_table(self):
    method page_values (line 409) | def page_values(self):
    method top_margin_collapses (line 427) | def top_margin_collapses(self):
    method bottom_margin_collapses (line 435) | def bottom_margin_collapses(self):
  class BlockLevelBox (line 444) | class BlockLevelBox(Box):
  class BlockContainerBox (line 454) | class BlockContainerBox(ParentBox):
  class BlockBox (line 467) | class BlockBox(BlockContainerBox, BlockLevelBox):
  class LineBox (line 476) | class LineBox(ParentBox):
    method anonymous_from (line 490) | def anonymous_from(cls, parent, *args, **kwargs):
  class InlineLevelBox (line 497) | class InlineLevelBox(Box):
    method remove_decoration (line 507) | def remove_decoration(self, start, end):
  class InlineBox (line 517) | class InlineBox(InlineLevelBox, ParentBox):
    method hit_area (line 527) | def hit_area(self):
  class TextBox (line 534) | class TextBox(InlineLevelBox):
    method __init__ (line 543) | def __init__(self, element_tag, style, element, text):
    method copy_with_text (line 548) | def copy_with_text(self, text):
  class AtomicInlineLevelBox (line 556) | class AtomicInlineLevelBox(InlineLevelBox):
  class InlineBlockBox (line 564) | class InlineBlockBox(AtomicInlineLevelBox, BlockContainerBox):
  class ReplacedBox (line 575) | class ReplacedBox(Box):
    method __init__ (line 582) | def __init__(self, element_tag, style, element, replacement):
  class BlockReplacedBox (line 587) | class BlockReplacedBox(ReplacedBox, BlockLevelBox):
  class InlineReplacedBox (line 596) | class InlineReplacedBox(ReplacedBox, AtomicInlineLevelBox):
  class TableBox (line 606) | class TableBox(BlockLevelBox, ParentBox):
    method all_children (line 612) | def all_children(self):
    method translate (line 615) | def translate(self, dx=0, dy=0, ignore_floats=False):
    method page_values (line 620) | def page_values(self):
  class InlineTableBox (line 624) | class InlineTableBox(TableBox):
  class TableRowGroupBox (line 628) | class TableRowGroupBox(ParentBox):
  class TableRowBox (line 640) | class TableRowBox(ParentBox):
  class TableColumnGroupBox (line 648) | class TableColumnGroupBox(ParentBox):
    method get_cells (line 665) | def get_cells(self):
    method span (line 671) | def span(self):
  class TableColumnBox (line 682) | class TableColumnBox(ParentBox):
    method get_cells (line 699) | def get_cells(self):
    method span (line 708) | def span(self):
  class TableCellBox (line 715) | class TableCellBox(BlockContainerBox):
    method __init__ (line 719) | def __init__(self, *args, **kwargs):
  class TableCaptionBox (line 737) | class TableCaptionBox(BlockBox):
  class PageBox (line 744) | class PageBox(ParentBox):
    method __init__ (line 751) | def __init__(self, page_type, style):
    method __repr__ (line 757) | def __repr__(self):
    method bleed (line 761) | def bleed(self):
    method bleed_area (line 767) | def bleed_area(self):
  class MarginBox (line 774) | class MarginBox(BlockContainerBox):
    method __init__ (line 776) | def __init__(self, at_keyword, style):
    method __repr__ (line 782) | def __repr__(self):
  class FootnoteAreaBox (line 786) | class FootnoteAreaBox(BlockBox):
    method __init__ (line 788) | def __init__(self, page, style):
    method __repr__ (line 794) | def __repr__(self):
  class FlexContainerBox (line 798) | class FlexContainerBox(ParentBox):
  class FlexBox (line 802) | class FlexBox(FlexContainerBox, BlockLevelBox):
  class InlineFlexBox (line 810) | class InlineFlexBox(FlexContainerBox, InlineLevelBox):
  class GridContainerBox (line 818) | class GridContainerBox(ParentBox):
    method __init__ (line 820) | def __init__(self, element_tag, style, element, children):
  class GridBox (line 826) | class GridBox(GridContainerBox, BlockLevelBox):
  class InlineGridBox (line 834) | class InlineGridBox(GridContainerBox, InlineLevelBox):

FILE: weasyprint/formatting_structure/build.py
  function create_anonymous_boxes (line 53) | def create_anonymous_boxes(box):
  function build_formatting_structure (line 63) | def build_formatting_structure(element_tree, style_for, get_image_from_uri,
  function make_box (line 97) | def make_box(element_tag, style, content, element):
  function element_to_box (line 102) | def element_to_box(element, style_for, get_image_from_uri, base_url,
  function before_after_to_box (line 262) | def before_after_to_box(element, pseudo_type, state, style_for,
  function marker_to_box (line 308) | def marker_to_box(element, state, parent_style, style_for, get_image_fro...
  function compute_content_list (line 367) | def compute_content_list(content_list, parent_box, counter_values, css_t...
  function content_to_boxes (line 551) | def content_to_boxes(style, parent_box, quote_depth, counter_values,
  function compute_string_set (line 593) | def compute_string_set(element, box, string_name, content_list,
  function compute_bookmark_label (line 625) | def compute_bookmark_label(element, box, content_list, counter_values,
  function set_content_lists (line 649) | def set_content_lists(element, box, style, counter_values, target_collec...
  function update_counters (line 669) | def update_counters(state, style):
  function is_whitespace (line 708) | def is_whitespace(box, _has_non_whitespace=re.compile('\\S').search):
  function wrap_improper (line 713) | def wrap_improper(box, children, wrapper_type, test=None):
  function anonymous_table_boxes (line 739) | def anonymous_table_boxes(box):
  function table_boxes_children (line 755) | def table_boxes_children(box, children):
  function wrap_table (line 849) | def wrap_table(box, children):
  function blockify (line 980) | def blockify(box, layout):
  function flex_boxes (line 998) | def flex_boxes(box):
  function flex_children (line 1015) | def flex_children(box, children):
  function grid_boxes (line 1033) | def grid_boxes(box):
  function grid_children (line 1050) | def grid_children(box, children):
  function process_whitespace (line 1067) | def process_whitespace(box, following_collapsible_space=False):
  function process_text_transform (line 1120) | def process_text_transform(box):
  function uppercase (line 1145) | def uppercase(text, lang_code):
  function lowercase (line 1182) | def lowercase(text, lang_code):
  function capitalize (line 1205) | def capitalize(text, lang_code):
  function inline_in_block (line 1230) | def inline_in_block(box):
  function block_in_inline (line 1342) | def block_in_inline(box):
  function _inner_block_in_inline (line 1444) | def _inner_block_in_inline(box, skip_stack=None):
  function set_viewport_overflow (line 1497) | def set_viewport_overflow(root_box):
  function box_text (line 1519) | def box_text(box):
  function extract_text (line 1537) | def extract_text(text_part, box):

FILE: weasyprint/html.py
  function ascii_lower (line 36) | def ascii_lower(string):
  function element_has_link_type (line 56) | def element_has_link_type(element, link_type):
  function handle_element (line 66) | def handle_element(element, box, get_image_from_uri, base_url):
  function handler (line 78) | def handler(tag):
  function make_replaced_box (line 87) | def make_replaced_box(element, box, image):
  function handle_img (line 106) | def handle_img(element, box, get_image_from_uri, base_url):
  function handle_embed (line 143) | def handle_embed(element, box, get_image_from_uri, base_url):
  function handle_object (line 162) | def handle_object(element, box, get_image_from_uri, base_url):
  function handle_colgroup (line 181) | def handle_colgroup(element, box, _get_image_from_uri, _base_url):
  function handle_col (line 192) | def handle_col(element, box, _get_image_from_uri, _base_url):
  function handle_svg (line 202) | def handle_svg(element, box, get_image_from_uri, base_url):
  function get_html_metadata (line 221) | def get_html_metadata(html):
  function strip_whitespace (line 294) | def strip_whitespace(string):
  function parse_w3c_date (line 340) | def parse_w3c_date(meta_name, string):

FILE: weasyprint/images.py
  class ImageLoadingError (line 26) | class ImageLoadingError(ValueError):
  class RasterImage (line 34) | class RasterImage:
    method __init__ (line 35) | def __init__(self, pillow_image, image_id, image_data, filename=None,
    method get_intrinsic_size (line 87) | def get_intrinsic_size(self, resolution, font_size):
    method draw (line 90) | def draw(self, stream, concrete_width, concrete_height, style):
    method cache_image_data (line 110) | def cache_image_data(self, data, filename=None, slot='source'):
    method get_x_object (line 117) | def get_x_object(self, interpolate, dpi_ratio):
    method _get_png_data (line 201) | def _get_png_data(pillow_image):
  class LazyImage (line 229) | class LazyImage(pydyf.Object):
    method __init__ (line 230) | def __init__(self, cache, key, data):
    method data (line 237) | def data(self):
  class LazyLocalImage (line 241) | class LazyLocalImage(pydyf.Object):
    method __init__ (line 242) | def __init__(self, filename):
    method data (line 247) | def data(self):
  class SVGImage (line 251) | class SVGImage:
    method __init__ (line 252) | def __init__(self, tree, base_url, url_fetcher, context):
    method get_intrinsic_size (line 259) | def get_intrinsic_size(self, image_resolution, font_size):
    method draw (line 277) | def draw(self, stream, concrete_width, concrete_height, _style):
  function get_image_from_uri (line 287) | def get_image_from_uri(cache, url_fetcher, options, url, forced_mime_typ...
  function rotate_pillow_image (line 338) | def rotate_pillow_image(pillow_image, orientation):
  function process_color_stops (line 362) | def process_color_stops(vector_length, positions, hints, style):
  function normalize_stop_positions (line 414) | def normalize_stop_positions(positions):
  function gradient_average_color (line 433) | def gradient_average_color(colors, positions):
  class Gradient (line 467) | class Gradient:
    method __init__ (line 468) | def __init__(self, color_stops, repeating, color_hints):
    method get_intrinsic_size (line 479) | def get_intrinsic_size(self, image_resolution, font_size):
    method draw (line 482) | def draw(self, stream, concrete_width, concrete_height, style):
    method layout (line 544) | def layout(self, width, height, style):
  class LinearGradient (line 569) | class LinearGradient(Gradient):
    method __init__ (line 570) | def __init__(self, color_stops, direction, repeating, color_hints):
    method layout (line 575) | def layout(self, width, height, style):
  class RadialGradient (line 667) | class RadialGradient(Gradient):
    method __init__ (line 668) | def __init__(self, color_stops, shape, size, center, repeating, color_...
    method layout (line 681) | def layout(self, width, height, style):
    method _repeat (line 763) | def _repeat(self, width, height, scale_y, points, positions, colors, h...
    method _resolve_size (line 849) | def _resolve_size(self, width, height, center_x, center_y, style):
    method _handle_degenerate (line 878) | def _handle_degenerate(self, size_x, size_y):

FILE: weasyprint/layout/__init__.py
  function initialize_page_maker (line 25) | def initialize_page_maker(context, root_box):
  function layout_fixed_boxes (line 78) | def layout_fixed_boxes(context, pages, containing_page):
  function layout_document (line 103) | def layout_document(html, root_box, context, max_loops=8):
  class FakeList (line 219) | class FakeList(list):
    method append (line 221) | def append(self, item):
  class LayoutContext (line 225) | class LayoutContext:
    method __init__ (line 226) | def __init__(self, style_for, get_image_from_uri, font_config,
    method overflows_page (line 252) | def overflows_page(self, bottom_space, position_y):
    method overflows (line 256) | def overflows(bottom, position_y):
    method excluded_shapes (line 262) | def excluded_shapes(self):
    method excluded_shapes (line 266) | def excluded_shapes(self, excluded_shapes):
    method create_block_formatting_context (line 269) | def create_block_formatting_context(self, root_box=None, new_list=None):
    method finish_block_formatting_context (line 275) | def finish_block_formatting_context(self, root_box=None):
    method create_flex_formatting_context (line 285) | def create_flex_formatting_context(self, root_box):
    method finish_flex_formatting_context (line 288) | def finish_flex_formatting_context(self, root_box):
    method add_broken_out_of_flow (line 291) | def add_broken_out_of_flow(self, new_box, box, containing_block, resum...
    method get_string_set_for (line 295) | def get_string_set_for(self, page, name, keyword='first'):
    method get_running_element_for (line 300) | def get_running_element_for(self, page, name, keyword='first'):
    method get_string_or_element_for (line 305) | def get_string_or_element_for(self, store, page, name, keyword):
    method layout_footnote (line 357) | def layout_footnote(self, footnote):
    method unlayout_footnote (line 363) | def unlayout_footnote(self, footnote):
    method report_footnote (line 375) | def report_footnote(self, footnote):
    method _update_footnote_area (line 381) | def _update_footnote_area(self):

FILE: weasyprint/layout/absolute.py
  class AbsolutePlaceholder (line 11) | class AbsolutePlaceholder:
    method __init__ (line 13) | def __init__(self, box):
    method set_laid_out_box (line 19) | def set_laid_out_box(self, new_box):
    method translate (line 23) | def translate(self, dx=0, dy=0, ignore_floats=False):
    method copy (line 33) | def copy(self):
    method __getattr__ (line 39) | def __getattr__(self, name):
    method __setattr__ (line 42) | def __setattr__(self, name, value):
    method __repr__ (line 45) | def __repr__(self):
  function absolute_width (line 50) | def absolute_width(box, context, cb_x, cb_y, cb_width, cb_height):
  function absolute_height (line 126) | def absolute_height(box, context, cb_x, cb_y, cb_width, cb_height):
  function absolute_block (line 179) | def absolute_block(context, box, containing_block, fixed_boxes, bottom_s...
  function absolute_layout (line 232) | def absolute_layout(context, placeholder, containing_block, fixed_boxes,
  function absolute_box_layout (line 244) | def absolute_box_layout(context, box, containing_block, fixed_boxes,
  function absolute_replaced (line 275) | def absolute_replaced(context, box, cb_x, cb_y, cb_width, cb_height):

FILE: weasyprint/layout/background.py
  function box_rectangle (line 19) | def box_rectangle(box, which_rectangle):
  function layout_box_backgrounds (line 35) | def layout_box_backgrounds(page, box, get_image_from_uri, layout_childre...
  function layout_background_layer (line 94) | def layout_background_layer(box, page, resolution, image, size, clip, re...
  function layout_backgrounds (line 222) | def layout_backgrounds(page, get_image_from_uri):

FILE: weasyprint/layout/block.py
  function block_level_layout (line 18) | def block_level_layout(context, box, bottom_space, skip_stack, containin...
  function block_level_layout_switch (line 65) | def block_level_layout_switch(context, box, bottom_space, skip_stack, co...
  function block_box_layout (line 94) | def block_box_layout(context, box, bottom_space, skip_stack,
  function block_level_width (line 144) | def block_level_width(box, containing_block, with_min_max=True):
  function relative_positioning (line 207) | def relative_positioning(box, containing_block):
  function _out_of_flow_layout (line 238) | def _out_of_flow_layout(context, box, index, child, new_children,
  function _break_line (line 304) | def _break_line(context, box, line, new_children, needed, page_is_empty,...
  function _linebox_layout (line 334) | def _linebox_layout(context, box, index, child, new_children, page_is_em...
  function _in_flow_layout (line 476) | def _in_flow_layout(context, box, index, child, new_children, page_is_em...
  function block_container_layout (line 662) | def block_container_layout(context, box, bottom_space, skip_stack, page_...
  function collapse_margin (line 926) | def collapse_margin(adjoining_margins):
  function block_level_page_break (line 935) | def block_level_page_break(sibling_before, sibling_after):
  function block_level_page_name (line 991) | def block_level_page_name(sibling_before, sibling_after):
  function find_earlier_page_break (line 999) | def find_earlier_page_break(context, children, absolute_boxes, fixed_box...
  function find_last_in_flow_child (line 1077)
Condensed preview — 190 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,940K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 78,
    "preview": "# These are supported funding model platforms\n\nopen_collective: courtbouillon\n"
  },
  {
    "path": ".github/workflows/doconfly.yml",
    "chars": 921,
    "preview": "name: doconfly\non:\n  push:\n    branches:\n      - main\n    tags:\n      - \"*\"\n\njobs:\n  doconfly:\n    name: doconfly job\n  "
  },
  {
    "path": ".github/workflows/exe.yml",
    "chars": 1247,
    "preview": "name: WeasyPrint’s exe generation\non: [push]\n\njobs:\n  generate:\n    name: ${{ matrix.os }}\n    runs-on: 'windows-latest'"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1208,
    "preview": "name: Release new version\non:\n  push:\n    tags:\n      - v*\n\njobs:\n  pypi-publish:\n    name: Upload release to PyPI\n    r"
  },
  {
    "path": ".github/workflows/test_pdfa.yml",
    "chars": 2471,
    "preview": "name: WeasyPrint's PDF/A tests\non: [push, pull_request]\n\nenv:\n  PDF_FOLDER: 'pdfs'\n  VERA_FOLDER: 'vera'\n\njobs:\n  pdf-ua"
  },
  {
    "path": ".github/workflows/test_pdfua.yml",
    "chars": 2340,
    "preview": "name: WeasyPrint's PDF/UA tests\non: [push, pull_request]\n\nenv:\n  PDF_FOLDER: 'pdfs'\n  VERA_FOLDER: 'vera'\n\njobs:\n  pdf-u"
  },
  {
    "path": ".github/workflows/test_samples.yml",
    "chars": 2083,
    "preview": "name: WeasyPrint's samples tests\non: [push, pull_request]\n\nenv:\n  REPORTS_FOLDER: 'report'\n\njobs:\n  samples:\n    name: G"
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 1827,
    "preview": "name: WeasyPrint's tests\non: [push, pull_request]\n\njobs:\n  tests:\n    name: ${{ matrix.os }} - ${{ matrix.python-version"
  },
  {
    "path": ".gitignore",
    "chars": 90,
    "preview": "*.pyc\n.cache\n/.coverage\n/build\n/dist\n/docs/_build\n/pytest_cache\n/tests/draw/results\n/venv\n"
  },
  {
    "path": "LICENSE",
    "chars": 1534,
    "preview": "BSD 3-Clause License\n\nCopyright (c) 2011-2021, Simon Sapin and contributors.\nAll rights reserved.\n\nRedistribution and us"
  },
  {
    "path": "README.rst",
    "chars": 1635,
    "preview": "**The Awesome Document Factory**\n\nWeasyPrint is a smart solution helping web developers to create PDF\ndocuments. It turn"
  },
  {
    "path": "docs/api_reference.rst",
    "chars": 33963,
    "preview": "API Reference\n=============\n\n.. currentmodule:: weasyprint\n\n\nThis page is for WeasyPrint |version|. See :doc:`changelog "
  },
  {
    "path": "docs/changelog.rst",
    "chars": 143063,
    "preview": "Changelog\n=========\n\n\nVersion 68.1\n------------\n\nReleased on 2026-02-06.\n\nBug fixes:\n\n* `#2662 <https://github.com/Kozea"
  },
  {
    "path": "docs/common_use_cases.rst",
    "chars": 22419,
    "preview": "Common Use Cases\n================\n\n\nInclude in Web Applications\n---------------------------\n\nUsing WeasyPrint in web app"
  },
  {
    "path": "docs/conf.py",
    "chars": 2945,
    "preview": "# WeasyPrint documentation build configuration file.\n\nimport weasyprint\n\n# Add any Sphinx extension module names here, a"
  },
  {
    "path": "docs/contribute.rst",
    "chars": 2216,
    "preview": "Contribute\n==========\n\nYou want to add some code to WeasyPrint, launch its tests or improve its\ndocumentation? Thank you"
  },
  {
    "path": "docs/first_steps.rst",
    "chars": 23066,
    "preview": "First Steps\n===========\n\n.. currentmodule:: weasyprint\n\n\nInstallation\n------------\n\nWeasyPrint |version| depends on:\n\n* "
  },
  {
    "path": "docs/going_further.rst",
    "chars": 11732,
    "preview": "Going Further\n=============\n\n.. currentmodule:: weasyprint\n\n\nWhy WeasyPrint?\n---------------\n\nAutomatic document generat"
  },
  {
    "path": "docs/index.rst",
    "chars": 308,
    "preview": "WeasyPrint\n==========\n\n.. currentmodule:: weasyprint\n\n.. include:: ../README.rst\n\n.. toctree::\n   :caption: Documentatio"
  },
  {
    "path": "docs/manpage.rst",
    "chars": 180,
    "preview": ":orphan:\n\n.. currentmodule:: weasyprint\n\n\nDescription\n-----------\n\n.. autofunction:: weasyprint.__main__.main(argv=sys.a"
  },
  {
    "path": "docs/support.rst",
    "chars": 880,
    "preview": "Support\n=======\n\n\nSponsorship\n-----------\n\nWith `donations and sponsorship`, you help make the projects\nbetter. Donation"
  },
  {
    "path": "pyproject.toml",
    "chars": 2476,
    "preview": "[build-system]\nrequires = ['flit_core >=3.2,<4']\nbuild-backend = 'flit_core.buildapi'\n\n[project]\nname = 'weasyprint'\ndes"
  },
  {
    "path": "tests/__init__.py",
    "chars": 33,
    "preview": "\"\"\"The Weasyprint test suite.\"\"\"\n"
  },
  {
    "path": "tests/conftest.py",
    "chars": 3589,
    "preview": "\"\"\"Configuration for WeasyPrint tests.\n\nThis module adds a PNG export based on Ghostscript.\n\nNote that Ghostscript is re"
  },
  {
    "path": "tests/css/__init__.py",
    "chars": 25,
    "preview": "\"\"\"Test CSS features.\"\"\"\n"
  },
  {
    "path": "tests/css/test_common.py",
    "chars": 8163,
    "preview": "\"\"\"Test the CSS parsing, cascade, inherited and computed values.\"\"\"\n\nfrom math import isclose\n\nimport pytest\n\nfrom weasy"
  },
  {
    "path": "tests/css/test_counters.py",
    "chars": 19475,
    "preview": "\"\"\"Test CSS counters.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import (  # isort:skip\n    FakeHTML, assert_no_logs, asser"
  },
  {
    "path": "tests/css/test_descriptors.py",
    "chars": 7855,
    "preview": "\"\"\"Test CSS descriptors.\"\"\"\n\nimport pytest\nimport tinycss2\n\nfrom weasyprint.css import preprocess_stylesheet\nfrom weasyp"
  },
  {
    "path": "tests/css/test_errors.py",
    "chars": 1667,
    "preview": "\"\"\"Test CSS errors and warnings.\"\"\"\n\nimport pytest\n\nfrom weasyprint import CSS\n\nfrom ..testing_utils import assert_no_lo"
  },
  {
    "path": "tests/css/test_expanders.py",
    "chars": 33230,
    "preview": "\"\"\"Test expanders for shorthand properties.\"\"\"\n\nimport pytest\nimport tinycss2\nfrom tinycss2.color5 import parse_color\n\nf"
  },
  {
    "path": "tests/css/test_fonts.py",
    "chars": 2510,
    "preview": "\"\"\"Test CSS font-related properties.\"\"\"\n\nfrom math import isclose\n\nimport pytest\n\nfrom weasyprint import CSS\nfrom weasyp"
  },
  {
    "path": "tests/css/test_layers.py",
    "chars": 1996,
    "preview": "\"\"\"Test CSS layers.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_no_logs\n@pytes"
  },
  {
    "path": "tests/css/test_math.py",
    "chars": 9736,
    "preview": "\"\"\"Test CSS math functions.\"\"\"\n\nfrom math import isclose\n\nimport pytest\n\nfrom weasyprint.css.validation.properties impor"
  },
  {
    "path": "tests/css/test_nesting.py",
    "chars": 785,
    "preview": "\"\"\"Test CSS nesting.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_no_logs\n@pyte"
  },
  {
    "path": "tests/css/test_pages.py",
    "chars": 6364,
    "preview": "\"\"\"Test CSS pages.\"\"\"\n\nimport pytest\nimport tinycss2\n\nfrom weasyprint import CSS\nfrom weasyprint.css import get_all_comp"
  },
  {
    "path": "tests/css/test_target.py",
    "chars": 7111,
    "preview": "\"\"\"Test the CSS cross references using target-*() functions.\"\"\"\n\nfrom ..testing_utils import assert_no_logs, render_page"
  },
  {
    "path": "tests/css/test_ua.py",
    "chars": 302,
    "preview": "\"\"\"Test the user-agent stylesheet.\"\"\"\n\nimport pytest\n\nfrom weasyprint.html import CSS, HTML5_PH, HTML5_UA, HTML5_UA_FORM"
  },
  {
    "path": "tests/css/test_validation.py",
    "chars": 38988,
    "preview": "\"\"\"Test validation of properties.\"\"\"\n\nimport logging\nfrom math import pi\n\nimport pytest\nimport tinycss2\n\nfrom weasyprint"
  },
  {
    "path": "tests/css/test_variables.py",
    "chars": 16853,
    "preview": "\"\"\"Test CSS custom properties, also known as CSS variables.\"\"\"\n\nimport pytest\n\nfrom weasyprint.css.properties import KNO"
  },
  {
    "path": "tests/draw/__init__.py",
    "chars": 5186,
    "preview": "\"\"\"Test the final, drawn results and compare PNG images pixel per pixel.\"\"\"\n\nimport io\nfrom itertools import zip_longest"
  },
  {
    "path": "tests/draw/svg/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/draw/svg/test_bounding_box.py",
    "chars": 9184,
    "preview": "\"\"\"Test how bounding boxes are defined for SVG tags.\"\"\"\n\nimport pytest\n\nfrom ...testing_utils import assert_no_logs\n\n\n@a"
  },
  {
    "path": "tests/draw/svg/test_clip.py",
    "chars": 3092,
    "preview": "\"\"\"Test clip-path attribute.\"\"\"\n\nimport pytest\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_c"
  },
  {
    "path": "tests/draw/svg/test_defs.py",
    "chars": 1235,
    "preview": "\"\"\"Test how SVG definitions are drawn.\"\"\"\n\nfrom base64 import b64encode\n\nfrom ...testing_utils import assert_no_logs\n\nSV"
  },
  {
    "path": "tests/draw/svg/test_gradients.py",
    "chars": 34976,
    "preview": "\"\"\"Test how SVG simple gradients are drawn.\"\"\"\n\nimport pytest\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_"
  },
  {
    "path": "tests/draw/svg/test_images.py",
    "chars": 9138,
    "preview": "\"\"\"Test how images are drawn in SVG.\"\"\"\n\nimport pytest\n\nfrom weasyprint.urls import path2url\n\nfrom ...testing_utils impo"
  },
  {
    "path": "tests/draw/svg/test_markers.py",
    "chars": 7534,
    "preview": "\"\"\"Test how SVG markers are drawn.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_markers(as"
  },
  {
    "path": "tests/draw/svg/test_opacity.py",
    "chars": 5969,
    "preview": "\"\"\"Test how opacity is handled for SVG.\"\"\"\n\nimport pytest\n\nfrom ...testing_utils import assert_no_logs\n\nopacity_source ="
  },
  {
    "path": "tests/draw/svg/test_paths.py",
    "chars": 15468,
    "preview": "\"\"\"Test how SVG simple paths are drawn.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_path_"
  },
  {
    "path": "tests/draw/svg/test_patterns.py",
    "chars": 7333,
    "preview": "\"\"\"Test how SVG simple patterns are drawn.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_pa"
  },
  {
    "path": "tests/draw/svg/test_shapes.py",
    "chars": 10177,
    "preview": "\"\"\"Test how SVG simple shapes are drawn.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_rect"
  },
  {
    "path": "tests/draw/svg/test_text.py",
    "chars": 19780,
    "preview": "\"\"\"Test how SVG text is drawn.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_text_fill(asse"
  },
  {
    "path": "tests/draw/svg/test_transform.py",
    "chars": 10466,
    "preview": "\"\"\"Test how SVG shapes are transformed.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_trans"
  },
  {
    "path": "tests/draw/svg/test_units.py",
    "chars": 2317,
    "preview": "\"\"\"Test SVG units.\"\"\"\n\nfrom ...testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_units_px(assert_pixels):\n "
  },
  {
    "path": "tests/draw/svg/test_visibility.py",
    "chars": 4525,
    "preview": "\"\"\"Test how the visibility is controlled with \"visibility\" and \"display\".\"\"\"\n\nfrom ...testing_utils import assert_no_log"
  },
  {
    "path": "tests/draw/test_absolute.py",
    "chars": 19728,
    "preview": "\"\"\"Test how absolutes are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef tes"
  },
  {
    "path": "tests/draw/test_background.py",
    "chars": 27427,
    "preview": "\"\"\"Test how backgrounds are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\n@pyte"
  },
  {
    "path": "tests/draw/test_before_after.py",
    "chars": 2060,
    "preview": "\"\"\"Test how before and after pseudo elements are drawn.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs"
  },
  {
    "path": "tests/draw/test_box.py",
    "chars": 16939,
    "preview": "\"\"\"Test how boxes, borders, outlines are drawn.\"\"\"\n\nimport itertools\n\nimport pytest\n\nfrom weasyprint import HTML\n\nfrom ."
  },
  {
    "path": "tests/draw/test_cmyk_color_profiles.py",
    "chars": 1941,
    "preview": "\"\"\"Test CMYK and Color Profiles.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_device_cmyk_w"
  },
  {
    "path": "tests/draw/test_column.py",
    "chars": 2627,
    "preview": "\"\"\"Test how columns are drawn.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_column_rule_1(a"
  },
  {
    "path": "tests/draw/test_current_color.py",
    "chars": 2834,
    "preview": "\"\"\"Test the currentColor value.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test"
  },
  {
    "path": "tests/draw/test_float.py",
    "chars": 23275,
    "preview": "\"\"\"Test how floats are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_f"
  },
  {
    "path": "tests/draw/test_footnote.py",
    "chars": 8592,
    "preview": "\"\"\"Test how footnotes are drawn.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_inline_footno"
  },
  {
    "path": "tests/draw/test_footnote_column.py",
    "chars": 8543,
    "preview": "\"\"\"Test how footnotes in columns are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_l"
  },
  {
    "path": "tests/draw/test_gradient.py",
    "chars": 10428,
    "preview": "\"\"\"Test how gradients are drawn.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_linear_gradie"
  },
  {
    "path": "tests/draw/test_image.py",
    "chars": 15568,
    "preview": "\"\"\"Test how images are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import FakeHTML, assert_no_logs, capture_logs, res"
  },
  {
    "path": "tests/draw/test_leader.py",
    "chars": 12317,
    "preview": "\"\"\"Test how leaders are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_"
  },
  {
    "path": "tests/draw/test_list.py",
    "chars": 1974,
    "preview": "\"\"\"Test how lists are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import SANS_FONTS, assert_no_logs\n\n\n@assert_no_logs"
  },
  {
    "path": "tests/draw/test_opacity.py",
    "chars": 2144,
    "preview": "\"\"\"Test opacity.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\nopacity_source = '''\n    <style>\n        @page { size: "
  },
  {
    "path": "tests/draw/test_overflow.py",
    "chars": 4749,
    "preview": "\"\"\"Test overflow and clipping.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_"
  },
  {
    "path": "tests/draw/test_page.py",
    "chars": 743,
    "preview": "\"\"\"Test how pages are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\n@pytest.mar"
  },
  {
    "path": "tests/draw/test_table.py",
    "chars": 50690,
    "preview": "\"\"\"Test how tables are drawn.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\ntables_source = '''\n  <styl"
  },
  {
    "path": "tests/draw/test_text.py",
    "chars": 27693,
    "preview": "\"\"\"Test how text is drawn.\"\"\"\n\nimport pytest\n\nfrom weasyprint.text.ffi import pango\n\nfrom ..testing_utils import SANS_FO"
  },
  {
    "path": "tests/draw/test_transform.py",
    "chars": 6855,
    "preview": "\"\"\"Test transformations.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_2d_transform_1(assert"
  },
  {
    "path": "tests/draw/test_visibility.py",
    "chars": 1502,
    "preview": "\"\"\"Test visibility.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\nvisibility_source = '''\n  <style>\n    @page { size: "
  },
  {
    "path": "tests/draw/test_whitespace.py",
    "chars": 5380,
    "preview": "\"\"\"Test how white spaces collapse.\"\"\"\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\ndef test_whitespace_"
  },
  {
    "path": "tests/layout/__init__.py",
    "chars": 101,
    "preview": "\"\"\"Tests for layout.\n\nIncludes positioning and dimensioning of boxes, line breaks, page breaks.\n\n\"\"\"\n"
  },
  {
    "path": "tests/layout/test_block.py",
    "chars": 33253,
    "preview": "\"\"\"Tests for blocks layout.\"\"\"\n\nimport pytest\n\nfrom weasyprint.formatting_structure import boxes\n\nfrom ..testing_utils i"
  },
  {
    "path": "tests/layout/test_column.py",
    "chars": 36642,
    "preview": "\"\"\"Tests for multicolumn layout.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_n"
  },
  {
    "path": "tests/layout/test_flex.py",
    "chars": 62484,
    "preview": "\"\"\"Tests for flex layout.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_no_logs\n"
  },
  {
    "path": "tests/layout/test_float.py",
    "chars": 22892,
    "preview": "\"\"\"Tests for floating boxes layout.\"\"\"\n\nimport pytest\n\nfrom weasyprint.formatting_structure import boxes\n\nfrom ..testing"
  },
  {
    "path": "tests/layout/test_footnotes.py",
    "chars": 29788,
    "preview": "\"\"\"Tests for footnotes layout.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages, tree_positio"
  },
  {
    "path": "tests/layout/test_grid.py",
    "chars": 59418,
    "preview": "\"\"\"Tests for grid layout.\"\"\"\n\nfrom math import isclose\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, rende"
  },
  {
    "path": "tests/layout/test_image.py",
    "chars": 20894,
    "preview": "\"\"\"Tests for images layout.\"\"\"\n\nimport pytest\n\nfrom weasyprint.formatting_structure import boxes\n\nfrom ..testing_utils i"
  },
  {
    "path": "tests/layout/test_inline.py",
    "chars": 35611,
    "preview": "\"\"\"Tests for inlines layout.\"\"\"\n\nimport pytest\n\nfrom weasyprint.formatting_structure import boxes\n\nfrom ..testing_utils "
  },
  {
    "path": "tests/layout/test_inline_block.py",
    "chars": 3633,
    "preview": "\"\"\"Tests for inline blocks layout.\"\"\"\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_no_logs\ndef te"
  },
  {
    "path": "tests/layout/test_list.py",
    "chars": 3442,
    "preview": "\"\"\"Tests for lists layout.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_no_logs"
  },
  {
    "path": "tests/layout/test_logical.py",
    "chars": 4416,
    "preview": "\"\"\"Tests for logical properties.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs\n\n\n@assert_no_logs\n@pytest"
  },
  {
    "path": "tests/layout/test_page.py",
    "chars": 51825,
    "preview": "\"\"\"Tests for pages layout.\"\"\"\n\nimport pytest\n\nfrom weasyprint.formatting_structure import boxes\n\nfrom ..testing_utils im"
  },
  {
    "path": "tests/layout/test_position.py",
    "chars": 18133,
    "preview": "\"\"\"Tests for position property.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@assert_no"
  },
  {
    "path": "tests/layout/test_preferred.py",
    "chars": 2687,
    "preview": "\"\"\"Tests for shrink-to-fit algorithm.\"\"\"\n\nimport pytest\n\nfrom ..testing_utils import assert_no_logs, render_pages\n\n\n@ass"
  },
  {
    "path": "tests/layout/test_table.py",
    "chars": 103405,
    "preview": "\"\"\"Tests for layout of tables.\"\"\"\n\nimport pytest\n\nfrom weasyprint.formatting_structure import boxes\nfrom weasyprint.layo"
  },
  {
    "path": "tests/resources/acid2-reference.html",
    "chars": 2556,
    "preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\r\n<html>\r\n <head>\r\n  <title>The Second Acid Test (Reference Rendering)"
  },
  {
    "path": "tests/resources/acid2-test.html",
    "chars": 14267,
    "preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n<html>\n <head>\n  <title>The Second Acid Test</title>\n  <style type=\"t"
  },
  {
    "path": "tests/resources/doc1.html",
    "chars": 2105,
    "preview": "<html>\n<head>\n    <meta http-equiv=Content-Type content=text/html;charset=utf-8>\n    <!-- currentColor means 'inherit' o"
  },
  {
    "path": "tests/resources/latin1-test.css",
    "chars": 82,
    "preview": "h1::before {\n    content: \"Ilv Unicode\";\n    background-image: url(pattern.png)\n}\n"
  },
  {
    "path": "tests/resources/mini_ua.css",
    "chars": 153,
    "preview": "/* Minimal user-agent stylesheet */\np { margin: 1em 0px } /* 0px should be translated to 0*/\na { text-decoration: underl"
  },
  {
    "path": "tests/resources/sheet2.css",
    "chars": 120,
    "preview": "li {\n    margin-bottom: 3em; /* Should be masked*/\n    margin: 2em 0;\n    margin-left: 4em; /* Should not be masked*/\n}\n"
  },
  {
    "path": "tests/resources/sub_directory/sheet1.css",
    "chars": 249,
    "preview": "@import url(../sheet2.css) all;\np {\n    background: currentColor;\n}\n\n@media print {\n    ul {\n        /* 1ex == 0.8em for"
  },
  {
    "path": "tests/resources/tests_ua.css",
    "chars": 1581,
    "preview": "/* Simplified user-agent stylesheet for HTML5 in tests. */\n\n@font-face { src: url(weasyprint.otf); font-family: weasypri"
  },
  {
    "path": "tests/resources/user.css",
    "chars": 84,
    "preview": "html {\n    /* Reversed contrast */\n    color: white;\n    background-color: black;\n}\n"
  },
  {
    "path": "tests/resources/utf8-test.css",
    "chars": 85,
    "preview": "h1::before {\n    content: \"I løvë Unicode\";\n    background-image: url(pattern.png)\n}\n"
  },
  {
    "path": "tests/test_acid2.py",
    "chars": 1199,
    "preview": "\"\"\"Check the famous Acid2 test.\"\"\"\n\nimport io\n\nfrom PIL import Image\n\nfrom weasyprint import CSS, HTML\n\nfrom .testing_ut"
  },
  {
    "path": "tests/test_api.py",
    "chars": 56455,
    "preview": "\"\"\"Test the public API.\"\"\"\n\nimport contextlib\nimport gzip\nimport io\nimport os\nimport re\nimport sys\nimport threading\nimpo"
  },
  {
    "path": "tests/test_boxes.py",
    "chars": 41196,
    "preview": "\"\"\"Test that the \"before layout\" box tree is correctly constructed.\"\"\"\n\nimport pytest\n\nfrom weasyprint.css import get_al"
  },
  {
    "path": "tests/test_fonts.py",
    "chars": 4739,
    "preview": "\"\"\"Test the fonts features.\"\"\"\n\nfrom .testing_utils import assert_no_logs, render_pages\n\n\n@assert_no_logs\ndef test_font_"
  },
  {
    "path": "tests/test_pdf.py",
    "chars": 23124,
    "preview": "\"\"\"Test PDF-related code, including metadata, bookmarks and hyperlinks.\"\"\"\n\nimport hashlib\nimport io\nimport re\nfrom code"
  },
  {
    "path": "tests/test_presentational_hints.py",
    "chars": 9387,
    "preview": "\"\"\"Test the HTML presentational hints.\"\"\"\n\nfrom weasyprint import CSS, HTML\n\nfrom .testing_utils import BASE_URL, assert"
  },
  {
    "path": "tests/test_stacking.py",
    "chars": 2460,
    "preview": "\"\"\"Test CSS stacking contexts.\"\"\"\n\nimport pytest\n\nfrom weasyprint.stacking import StackingContext\n\nfrom .testing_utils i"
  },
  {
    "path": "tests/test_text.py",
    "chars": 48315,
    "preview": "\"\"\"Test the text layout.\"\"\"\n\nimport pytest\n\nfrom weasyprint.css import InitialStyle\nfrom weasyprint.formatting_structure"
  },
  {
    "path": "tests/test_unicode.py",
    "chars": 1187,
    "preview": "\"\"\"Test various unicode texts and filenames.\"\"\"\n\nfrom weasyprint.urls import ensure_url\n\nfrom .draw import document_to_p"
  },
  {
    "path": "tests/test_url.py",
    "chars": 924,
    "preview": "\"\"\"Test URLs.\"\"\"\n\nimport re\n\nimport pytest\n\nfrom .testing_utils import FakeHTML, capture_logs, resource_path\n\n\n@pytest.m"
  },
  {
    "path": "tests/testing_utils.py",
    "chars": 7685,
    "preview": "\"\"\"Helpers for tests.\"\"\"\n\nimport functools\nimport sys\nfrom pathlib import Path\n\nfrom weasyprint import CSS, DEFAULT_OPTI"
  },
  {
    "path": "weasyprint/__init__.py",
    "chars": 14949,
    "preview": "\"\"\"The Awesome Document Factory.\n\nThe public API is what is accessible from this \"root\" packages without\nimporting sub-m"
  },
  {
    "path": "weasyprint/__main__.py",
    "chars": 9370,
    "preview": "\"\"\"Command-line interface to WeasyPrint.\"\"\"\n\nimport argparse\nimport logging\nimport platform\nimport sys\n\nimport pydyf\n\nfr"
  },
  {
    "path": "weasyprint/anchors.py",
    "chars": 6470,
    "preview": "\"\"\"Find anchors, links, bookmarks and inputs in documents.\"\"\"\n\nimport math\n\nfrom .formatting_structure import boxes\nfrom"
  },
  {
    "path": "weasyprint/css/__init__.py",
    "chars": 78425,
    "preview": "\"\"\"Find and apply CSS.\n\nThis module takes care of steps 3 and 4 of “CSS 2.1 processing model”: Retrieve\nstylesheets asso"
  },
  {
    "path": "weasyprint/css/computed_values.py",
    "chars": 27820,
    "preview": "\"\"\"Convert specified property values into computed values.\"\"\"\n\nfrom functools import partial\nfrom math import pi\n\nfrom t"
  },
  {
    "path": "weasyprint/css/counters.py",
    "chars": 11374,
    "preview": "\"\"\"Implement counter styles.\n\nThese are defined in CSS Counter Styles Level 3:\nhttps://www.w3.org/TR/css-counter-styles-"
  },
  {
    "path": "weasyprint/css/functions.py",
    "chars": 6779,
    "preview": "\"\"\"CSS functions parsers.\"\"\"\n\n\nclass Function:\n    \"\"\"CSS function.\"\"\"\n    # See https://drafts.csswg.org/css-values-4/#"
  },
  {
    "path": "weasyprint/css/html5_ph.css",
    "chars": 4629,
    "preview": "/*\n\nPresentational hints stylsheet for HTML.\n\nThis stylesheet contains all the presentational hints rules that can be\nex"
  },
  {
    "path": "weasyprint/css/html5_ua.css",
    "chars": 16716,
    "preview": "/*\n\nUser agent stylsheet for HTML.\n\nContributed by Peter Moulder.\nBased on suggested styles in the HTML5 specification, "
  },
  {
    "path": "weasyprint/css/html5_ua_form.css",
    "chars": 308,
    "preview": "/* Default stylesheet for PDF forms */\n\nbutton, input, select, textarea { appearance: auto }\nselect option, select:not(["
  },
  {
    "path": "weasyprint/css/media_queries.py",
    "chars": 1179,
    "preview": "\"\"\"Handle media queries.\n\nhttps://www.w3.org/TR/mediaqueries-4/\n\n\"\"\"\n\nimport tinycss2\n\nfrom ..logger import LOGGER\nfrom "
  },
  {
    "path": "weasyprint/css/properties.py",
    "chars": 13376,
    "preview": "\"\"\"Various data about known CSS properties.\"\"\"\n\nimport collections\nfrom math import inf\n\nfrom tinycss2.color5 import par"
  },
  {
    "path": "weasyprint/css/targets.py",
    "chars": 8853,
    "preview": "\"\"\"Handle target-counter, target-counters and target-text.\n\nThe TargetCollector is a structure providing required target"
  },
  {
    "path": "weasyprint/css/tokens.py",
    "chars": 23577,
    "preview": "\"\"\"CSS tokens parsers.\"\"\"\n\nimport functools\nfrom abc import ABC, abstractmethod\nfrom math import e, inf, nan, pi\n\nfrom t"
  },
  {
    "path": "weasyprint/css/units.py",
    "chars": 4177,
    "preview": "\"\"\"Constants and helpers for units.\"\"\"\n\nimport math\n\nfrom ..logger import LOGGER\nfrom ..text.line_break import character"
  },
  {
    "path": "weasyprint/css/validation/__init__.py",
    "chars": 8467,
    "preview": "\"\"\"Validate properties, expanders and descriptors.\"\"\"\n\nfrom cssselect2 import SelectorError, compile_selector_list\nfrom "
  },
  {
    "path": "weasyprint/css/validation/descriptors.py",
    "chars": 11837,
    "preview": "\"\"\"Validate descriptors used for some at-rules.\"\"\"\n\nfrom math import inf\n\nimport tinycss2\n\nfrom ...logger import LOGGER\n"
  },
  {
    "path": "weasyprint/css/validation/expanders.py",
    "chars": 40811,
    "preview": "\"\"\"Validate properties expanders.\"\"\"\n\nimport functools\n\nfrom tinycss2.ast import DimensionToken, IdentToken, NumberToken"
  },
  {
    "path": "weasyprint/css/validation/properties.py",
    "chars": 68056,
    "preview": "\"\"\"Validate properties.\n\nSee https://www.w3.org/TR/CSS21/propidx.html and various CSS3 modules.\n\n\"\"\"\n\nfrom math import i"
  },
  {
    "path": "weasyprint/document.py",
    "chars": 13681,
    "preview": "\"\"\"Document generation management.\"\"\"\n\nimport functools\nimport io\nfrom hashlib import md5\nfrom pathlib import Path\n\nfrom"
  },
  {
    "path": "weasyprint/draw/__init__.py",
    "chars": 22713,
    "preview": "\"\"\"Take an \"after layout\" box tree and draw it onto a pydyf stream.\"\"\"\n\nimport operator\nfrom math import floor\nfrom xml."
  },
  {
    "path": "weasyprint/draw/border.py",
    "chars": 30373,
    "preview": "\"\"\"Draw borders.\"\"\"\n\nfrom math import ceil, cos, floor, pi, sin, sqrt, tan\n\nfrom ..formatting_structure import boxes\nfro"
  },
  {
    "path": "weasyprint/draw/color.py",
    "chars": 1449,
    "preview": "\"\"\"Draw colors.\"\"\"\n\nfrom colorsys import hsv_to_rgb, rgb_to_hsv\n\nfrom tinycss2.color5 import parse_color\n\n\ndef get_color"
  },
  {
    "path": "weasyprint/draw/text.py",
    "chars": 12430,
    "preview": "\"\"\"Draw text.\"\"\"\n\nfrom io import BytesIO\nfrom xml.etree import ElementTree\n\nfrom PIL import Image\n\nfrom ..images import "
  },
  {
    "path": "weasyprint/formatting_structure/boxes.py",
    "chars": 27428,
    "preview": "\"\"\"Classes for all types of boxes in the CSS formatting structure / box model.\n\nSee https://www.w3.org/TR/CSS21/visuren."
  },
  {
    "path": "weasyprint/formatting_structure/build.py",
    "chars": 58449,
    "preview": "\"\"\"Turn an element tree with style into a \"before layout\" box tree.\n\nThis includes creating anonymous boxes and processi"
  },
  {
    "path": "weasyprint/html.py",
    "chars": 11588,
    "preview": "\"\"\"Specific handling for some HTML elements, especially replaced elements.\n\nReplaced elements (eg. <img> elements) are r"
  },
  {
    "path": "weasyprint/images.py",
    "chars": 36362,
    "preview": "\"\"\"Fetch and decode images in various formats.\"\"\"\n\nimport io\nimport math\nimport struct\nfrom hashlib import md5\nfrom io i"
  },
  {
    "path": "weasyprint/layout/__init__.py",
    "chars": 16765,
    "preview": "\"\"\"Transform a \"before layout\" box tree into an \"after layout\" tree.\n\nBreak boxes across lines and pages; determine the "
  },
  {
    "path": "weasyprint/layout/absolute.py",
    "chars": 14005,
    "preview": "\"\"\"Absolutely positioned boxes management.\"\"\"\n\nfrom ..formatting_structure import boxes\nfrom .min_max import handle_min_"
  },
  {
    "path": "weasyprint/layout/background.py",
    "chars": 10015,
    "preview": "\"\"\"Manage background position and size.\"\"\"\n\nfrom collections import namedtuple\nfrom itertools import cycle\n\nfrom tinycss"
  },
  {
    "path": "weasyprint/layout/block.py",
    "chars": 49250,
    "preview": "\"\"\"Page breaking and layout for block-level and block-container boxes.\"\"\"\n\nfrom functools import partial\nfrom math impor"
  },
  {
    "path": "weasyprint/layout/column.py",
    "chars": 17197,
    "preview": "\"\"\"Layout for columns.\"\"\"\n\nfrom math import floor, inf\n\nfrom .absolute import absolute_layout\nfrom .percent import perce"
  },
  {
    "path": "weasyprint/layout/flex.py",
    "chars": 44334,
    "preview": "\"\"\"Layout for flex containers and flex-items.\"\"\"\n\nimport sys\nfrom math import inf, log10\n\nfrom ..css.properties import D"
  },
  {
    "path": "weasyprint/layout/float.py",
    "chars": 10557,
    "preview": "\"\"\"Layout for floating boxes.\"\"\"\n\nfrom math import inf\n\nfrom ..formatting_structure import boxes\nfrom .min_max import ha"
  },
  {
    "path": "weasyprint/layout/grid.py",
    "chars": 64606,
    "preview": "\"\"\"Layout for grid containers and grid-items.\"\"\"\n\nfrom collections import defaultdict\nfrom itertools import count, cycle"
  },
  {
    "path": "weasyprint/layout/inline.py",
    "chars": 51025,
    "preview": "\"\"\"Layout for inline-level boxes.\"\"\"\n\nimport unicodedata\nfrom math import inf\n\nfrom ..css import AnonymousStyle, Pending"
  },
  {
    "path": "weasyprint/layout/leader.py",
    "chars": 2821,
    "preview": "\"\"\"Leaders management.\"\"\"\n\nfrom ..formatting_structure import boxes\n\n\ndef leader_index(box):\n    \"\"\"Get the index of the"
  },
  {
    "path": "weasyprint/layout/min_max.py",
    "chars": 1145,
    "preview": "\"\"\"Decorators handling min- and max- widths and heights.\"\"\"\n\nimport functools\n\n\ndef handle_min_max_width(function):\n    "
  },
  {
    "path": "weasyprint/layout/page.py",
    "chars": 41716,
    "preview": "\"\"\"Layout for pages and CSS3 margin boxes.\"\"\"\n\nimport copy\nfrom collections import defaultdict, namedtuple\nfrom math imp"
  },
  {
    "path": "weasyprint/layout/percent.py",
    "chars": 5829,
    "preview": "\"\"\"Resolve percentages into fixed values.\"\"\"\n\nfrom math import inf\n\nfrom ..css import resolve_math\nfrom ..css.functions "
  },
  {
    "path": "weasyprint/layout/preferred.py",
    "chars": 35278,
    "preview": "\"\"\"Preferred and minimum preferred width.\n\nAlso known as max-content and min-content width, also known as the\nshrink-to-"
  },
  {
    "path": "weasyprint/layout/replaced.py",
    "chars": 11357,
    "preview": "\"\"\"Layout for images and other replaced elements.\n\nSee https://drafts.csswg.org/css-images-3/#sizing\n\n\"\"\"\n\nfrom .min_max"
  },
  {
    "path": "weasyprint/layout/table.py",
    "chars": 47766,
    "preview": "\"\"\"Layout for tables and internal table boxes.\"\"\"\n\nfrom math import inf\n\nimport tinycss2.color5\n\nfrom ..formatting_struc"
  },
  {
    "path": "weasyprint/logger.py",
    "chars": 1824,
    "preview": "\"\"\"Logging setup.\n\nThe rest of the code gets the logger through this module rather than\n``logging.getLogger`` to make su"
  },
  {
    "path": "weasyprint/matrix.py",
    "chars": 1909,
    "preview": "\"\"\"Transformation matrix.\"\"\"\n\n\nclass Matrix(list):\n    def __init__(self, a=1, b=0, c=0, d=1, e=0, f=0, matrix=None):\n  "
  },
  {
    "path": "weasyprint/pdf/__init__.py",
    "chars": 14303,
    "preview": "\"\"\"PDF generation management.\"\"\"\n\nfrom importlib.resources import files\n\nimport pydyf\nfrom tinycss2.color5 import D50, D"
  },
  {
    "path": "weasyprint/pdf/anchors.py",
    "chars": 17266,
    "preview": "\"\"\"Insert anchors, links, bookmarks and inputs in PDFs.\"\"\"\n\nimport collections\nimport mimetypes\nfrom hashlib import md5\n"
  },
  {
    "path": "weasyprint/pdf/debug.py",
    "chars": 1407,
    "preview": "\"\"\"PDF generation with debug information.\"\"\"\n\nimport pydyf\n\nfrom ..matrix import Matrix\n\n\ndef debug(pdf, metadata, docum"
  },
  {
    "path": "weasyprint/pdf/fonts.py",
    "chars": 28151,
    "preview": "\"\"\"Fonts integration in PDF.\"\"\"\n\nimport io\nimport re\nfrom hashlib import md5\nfrom logging import WARNING\nfrom math impor"
  },
  {
    "path": "weasyprint/pdf/metadata.py",
    "chars": 9203,
    "preview": "\"\"\"PDF metadata stream generation.\"\"\"\n\nfrom uuid import uuid4\nfrom xml.etree.ElementTree import Element, SubElement, reg"
  },
  {
    "path": "weasyprint/pdf/pdfa.py",
    "chars": 4239,
    "preview": "\"\"\"PDF/A generation.\"\"\"\n\nfrom functools import partial\n\nimport pydyf\n\n\ndef pdfa(pdf, metadata, document, page_streams, a"
  },
  {
    "path": "weasyprint/pdf/pdfua.py",
    "chars": 486,
    "preview": "\"\"\"PDF/UA generation.\"\"\"\n\nfrom functools import partial\n\n\ndef pdfua(pdf, metadata, document, page_streams, attachments, "
  },
  {
    "path": "weasyprint/pdf/pdfx.py",
    "chars": 2629,
    "preview": "\"\"\"PDF/X generation.\"\"\"\n\nfrom functools import partial\nfrom time import localtime\n\nimport pydyf\n\n\ndef pdfx(pdf, metadata"
  },
  {
    "path": "weasyprint/pdf/stream.py",
    "chars": 11615,
    "preview": "\"\"\"PDF stream.\"\"\"\n\nfrom contextlib import contextmanager\n\nimport pydyf\n\nfrom ..logger import LOGGER\nfrom ..matrix import"
  },
  {
    "path": "weasyprint/pdf/tags.py",
    "chars": 11779,
    "preview": "\"\"\"PDF tagging.\"\"\"\n\nfrom collections import defaultdict\n\nimport pydyf\n\nfrom ..formatting_structure import boxes\nfrom ..l"
  },
  {
    "path": "weasyprint/stacking.py",
    "chars": 5697,
    "preview": "\"\"\"Stacking contexts management.\"\"\"\n\nfrom .formatting_structure import boxes\nfrom .layout.absolute import AbsolutePlaceh"
  },
  {
    "path": "weasyprint/svg/__init__.py",
    "chars": 32177,
    "preview": "\"\"\"Render SVG images.\"\"\"\n\nimport re\nfrom contextlib import suppress\nfrom math import cos, hypot, pi, radians, sin, sqrt\n"
  },
  {
    "path": "weasyprint/svg/bounding_box.py",
    "chars": 13127,
    "preview": "\"\"\"Calculate bounding boxes of SVG tags.\"\"\"\n\nfrom math import atan, atan2, cos, inf, isinf, pi, radians, sin, sqrt, tan\n"
  },
  {
    "path": "weasyprint/svg/css.py",
    "chars": 4871,
    "preview": "\"\"\"Apply CSS to SVG documents.\"\"\"\n\nfrom urllib.parse import urljoin\n\nimport cssselect2\nimport tinycss2\n\nfrom ..css.valid"
  },
  {
    "path": "weasyprint/svg/defs.py",
    "chars": 20840,
    "preview": "\"\"\"Parse and draw definitions: gradients, patterns, masks, uses…\"\"\"\n\nfrom itertools import cycle\nfrom math import ceil, "
  },
  {
    "path": "weasyprint/svg/images.py",
    "chars": 3333,
    "preview": "\"\"\"Draw image and svg tags.\"\"\"\n\nfrom .bounding_box import bounding_box, is_valid_bounding_box\nfrom .utils import preserv"
  },
  {
    "path": "weasyprint/svg/path.py",
    "chars": 10059,
    "preview": "\"\"\"Draw paths.\"\"\"\n\nfrom math import atan2, cos, isclose, pi, radians, sin, tan\n\nfrom ..matrix import Matrix\nfrom .utils "
  },
  {
    "path": "weasyprint/svg/shapes.py",
    "chars": 3845,
    "preview": "\"\"\"Draw simple shapes.\"\"\"\n\nfrom math import atan2, pi, sqrt\n\nfrom .utils import normalize, point\n\n\ndef circle(svg, node,"
  },
  {
    "path": "weasyprint/svg/text.py",
    "chars": 6658,
    "preview": "\"\"\"Draw text.\"\"\"\n\nfrom math import cos, inf, radians, sin\n\nfrom ..matrix import Matrix\nfrom .bounding_box import extend_"
  },
  {
    "path": "weasyprint/svg/utils.py",
    "chars": 7287,
    "preview": "\"\"\"Util functions for SVG rendering.\"\"\"\n\nimport re\nfrom contextlib import suppress\nfrom math import cos, radians, sin, t"
  },
  {
    "path": "weasyprint/text/constants.py",
    "chars": 13393,
    "preview": "\"\"\"Constants used for text layout.\"\"\"\n\nfrom functools import lru_cache\n\nfrom .ffi import pango\n\n# Pango features\nPANGO_S"
  },
  {
    "path": "weasyprint/text/ffi.py",
    "chars": 18437,
    "preview": "\"\"\"Imports of dynamic libraries used for text layout.\"\"\"\n\nimport os\nimport sys\nfrom contextlib import suppress\n\nimport c"
  },
  {
    "path": "weasyprint/text/fonts.py",
    "chars": 17583,
    "preview": "\"\"\"Interface with external libraries managing fonts installed on the system.\"\"\"\n\nfrom hashlib import md5\nfrom io import "
  },
  {
    "path": "weasyprint/text/line_break.py",
    "chars": 28079,
    "preview": "\"\"\"Decide where to break text lines.\"\"\"\n\nimport re\nfrom math import inf\n\nimport pyphen\n\nfrom .constants import LST_TO_IS"
  },
  {
    "path": "weasyprint/urls.py",
    "chars": 18120,
    "preview": "\"\"\"Various utility functions and classes for URL management.\"\"\"\n\nimport contextlib\nimport os.path\nimport re\nimport sys\ni"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the Kozea/WeasyPrint GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 190 files (2.7 MB), approximately 715.3k tokens, and a symbol index with 2695 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!