Provided by: weasyprint_54.1-1_all bug

NAME

       weasyprint - WeasyPrint Documentation

       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.6+, 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.

FIRST STEPS

   Installation
       WeasyPrint 54.1 depends on:

       • Python ≥ 3.6.0

       • Pango ≥ 1.44.0

       • pydyf ≥ 0.0.3

       • CFFI ≥ 0.6

       • html5lib ≥ 1.1

       • tinycss2 ≥ 1.0.0

       • cssselect2 ≥ 0.1

       • Pyphen ≥ 0.9.1

       • Pillow ≥ 4.0.0

       • fontTools ≥ 4.0.0

       There are many ways to install WeasyPrint, depending on the system you use.

   Linux
       The easiest way to install WeasyPrint on Linux is to  use  the  package  manager  of  your  distribution.
       WeasyPrint is packaged for recent versions of Debian, Ubuntu, Fedora, Archlinux, Gentoo…

       If  WeasyPrint  is  not  available  on  your distribution, or if you want to use a more recent version of
       WeasyPrint, you have to be sure that Python (at least version 3.6.0) and Pango (at least version  1.44.0)
       are installed on your system. You can verify this by launching:

          python3 --version
          pango-view --version

       If  the version of Pango provided by your distribution is too old, you can use version 52.5 of WeasyPrint
       which does not need recent Pango features.

       When everything is OK, you can install WeasyPrint directly on your system or  in  a  virtual  environment
       using pip:

          python3 -m venv venv
          source venv/bin/activate
          pip install weasyprint
          weasyprint --info

   Alpine  3.12
       To install WeasyPrint without a virtualenv, you need the following packages:

          apk add py3-pip py3-pillow py3-cffi py3-brotli gcc musl-dev python3-dev pango

       To install WeasyPrint inside a virtualenv using wheels (if possible), you need the following packages:

          apk add py3-pip gcc musl-dev python3-dev pango zlib-dev jpeg-dev openjpeg-dev g++ libffi-dev

       To install WeasyPrint inside a virtualenv without using wheels, you need the following packages:

          apk add py3-pip gcc musl-dev python3-dev pango zlib-dev jpeg-dev openjpeg-dev g++ libffi-dev

   Archlinux
       To install WeasyPrint without a virtualenv, you need the following packages:

          pacman -S python-pip pango python-cffi python-pillow python-brotli python-zopfli

       To install WeasyPrint inside a virtualenv using wheels (if possible), you need the following packages:

          pacman -S python-pip pango

       To install WeasyPrint inside a virtualenv without using wheels, you need the following packages:

          pacman -S python-pip pango gcc libjpeg-turbo openjpeg2

   Debian  11
       To install WeasyPrint without a virtualenv, you need the following packages:

          apt install python3-pip python3-cffi python3-brotli libpango-1.0-0 libpangoft2-1.0-0

       To install WeasyPrint inside a virtualenv using wheels (if possible), you need the following packages:

          apt install python3-pip libpango-1.0-0 libpangoft2-1.0-0

       To install WeasyPrint inside a virtualenv without using wheels, you need the following packages:

          apt install python3-pip libpango-1.0-0 libpangoft2-1.0-0 libjpeg-dev libopenjp2-7-dev libffi-dev

   Fedora  34
       To install WeasyPrint without a virtualenv, you need the following packages:

          yum install python-pip python-pillow python-cffi python3-brotli pango

       To install WeasyPrint inside a virtualenv using wheels (if possible), you need the following packages:

          yum install python-pip pango

       To install WeasyPrint inside a virtualenv without using wheels, you need the following packages:

          yum install python-pip pango gcc python3-devel gcc-c++ zlib-devel libjpeg-devel openjpeg2-devel libffi-devel

   Ubuntu  20.04
       To install WeasyPrint without a virtualenv, you need the following packages:

          apt install python3-pip python3-cffi python3-brotli libpango-1.0-0 libharfbuzz0b libpangoft2-1.0-0

       To install WeasyPrint inside a virtualenv using wheels (if possible), you need the following packages:

          apt install python3-pip libpango-1.0-0 libharfbuzz0b libpangoft2-1.0-0

       To install WeasyPrint inside a virtualenv without using wheels, you need the following packages:

          apt install python3-pip libpango-1.0-0 libharfbuzz0b libpangoft2-1.0-0 libffi-dev libjpeg-dev libopenjp2-7-dev

   macOS
       The easiest way to install WeasyPrint on macOS is to use Homebrew.

       When Homebrew is installed, install Python, Pango and libffi:

          brew install python pango libffi

       You can then install WeasyPrint in a virtual environment using pip:

          python3 -m venv venv
          source venv/bin/activate
          pip install weasyprint
          weasyprint --info

   Windows
       Installing  WeasyPrint  on  Windows requires to follow a few steps that may not be easy. Please read this
       chapter carefully.

       Only Windows 10 64-bit is supported. You can find this information in  the  Control  Panel →  System  and
       Security → System.

       The first step is to install the latest version of Python from the Microsoft Store.

       When  Python  is installed, you have to install GTK. Download the latest GTK3 installer and launch it. If
       you don’t know what some options mean, you can safely keep the default options selected.

       When everything is OK, you can launch a command prompt by clicking on the Start menu,  typing  "cmd"  and
       clicking the "Command Prompt" icon. You can then install WeasyPrint in a virtual environment using pip:

          python3 -m venv venv
          venv\Scripts\activate.bat
          python3 -m pip install weasyprint
          python3 -m weasyprint --info

   Other Solutions
       Other solutions are available to install WeasyPrint. These solutions are not tested but they are known to
       work for some use cases on specific platforms.

   Macports
       On macOS, you can install WeasyPrint’s dependencies with Macports:

          sudo port install py-pip pango libffi

       You can then install WeasyPrint in a virtual environment using pip:

          python3 -m venv venv
          source venv/bin/activate
          pip install weasyprint
          weasyprint --info

   Conda
       On Linux and macOS, WeasyPrint is available on Conda, with a WeasyPrint package on Conda Forge.

   WSL
       On Windows, you can also use WSL and install WeasyPrint the same way it has to be installed on Linux.

   .NET Wrapper
       On Windows, Bader Albarrak maintains a .NET wrapper.

   AWS
       Kotify maintains an AWS Lambda layer, see issue #1003 for more information.

   Troubleshooting
       Most  of  the  installation  problems  have already been met, and some issues on GitHub could help you to
       solve them.

   Missing Library
       On Windows, most of the problems come from unreachable libraries. If you get an error  like  cannot  load
       library 'xxx': error xxx, it means that WeasyPrint can’t find this library.

       You  can  set the WEASYPRINT_DLL_DIRECTORIES environment variable to list the folders where the libraries
       can be found. For example, in cmd.exe:

          > set WEASYPRINT_DLL_DIRECTORIES=C:\GTK3\bin;D:\GTK3\bin

       You can find more about this issue in #589, #721 or #1240.

   Missing Fonts
       If no character is drawn in the generated PDF, or if you get squares instead  of  letters,  you  have  to
       install fonts and make them available to WeasyPrint.  Following the standard way to install fonts on your
       system should be enough.  You can also use @font-face rules to explicitly reference fonts using URLs.

   Command-Line
       Using the WeasyPrint command line interface can be as simple as this:

          weasyprint http://weasyprint.org /tmp/weasyprint-website.pdf

       You  may see warnings on the standard error output about unsupported CSS properties. See Command-Line API
       for the details of all available options.

       In particular, the -s option can add a filename for a user stylesheet. For quick experimentation however,
       you may not want to create a file. In bash or zsh, you can use the shell’s redirection instead:

          weasyprint http://weasyprint.org /tmp/weasyprint-website.pdf \
              -s <(echo 'body { font-family: serif !important }')

       If you have many documents to convert you may prefer using the Python  API  in  long-lived  processes  to
       avoid paying the start-up costs every time.

   Python Library
       ATTENTION:
          Using WeasyPrint with untrusted HTML or untrusted CSS may lead to various security problems.

   Quickstart
       The Python version of the above example goes like this:

          from weasyprint import HTML
          HTML('http://weasyprint.org/').write_pdf('/tmp/weasyprint-website.pdf')

       … or with the inline stylesheet:

          from weasyprint import HTML, CSS
          HTML('http://weasyprint.org/').write_pdf('/tmp/weasyprint-website.pdf',
              stylesheets=[CSS(string='body { font-family: serif !important }')])

   Instantiating HTML and CSS Objects
       If  you  have a file name, an absolute URL or a readable file object, you can just pass it to HTML or CSS
       to create an instance.  Alternatively, use a named argument so that no guessing is involved:

          from weasyprint import HTML

          HTML('../foo.html')  # Same as …
          HTML(filename='../foo.html')

          HTML('http://weasyprint.org')  # Same as …
          HTML(url='http://weasyprint.org')

          HTML(sys.stdin)  # Same as …
          HTML(file_obj=sys.stdin)

       If you have a byte string or Unicode string already in memory  you  can  also  pass  that,  although  the
       argument must be named:

          from weasyprint import HTML, CSS

          # HTML('<h1>foo') would be filename
          HTML(string='''
              <h1>The title</h1>
              <p>Content goes here
          ''')
          CSS(string='@page { size: A3; margin: 1cm }')

       If you have @font-face rules in your CSS, you have to create a FontConfiguration object:

          from weasyprint import HTML, CSS
          from weasyprint.text.fonts import FontConfiguration

          font_config = FontConfiguration()
          html = HTML(string='<h1>The title</h1>')
          css = CSS(string='''
              @font-face {
                  font-family: Gentium;
                  src: url(http://example.com/fonts/Gentium.otf);
              }
              h1 { font-family: Gentium }''', font_config=font_config)
          html.write_pdf(
              '/tmp/example.pdf', stylesheets=[css],
              font_config=font_config)

   Rendering to a Single File
       Once  you  have  a HTML object, call its HTML.write_pdf() method to get the rendered document in a single
       PDF file.

       Without arguments, this method returns a byte string in memory. If you pass a file  name  or  a  writable
       file  object,  they  will  write  there  directly  instead. (Warning: with a filename, these methods will
       overwrite existing files silently.)

   Individual Pages & Meta-Data
       If you want more than a single PDF, the HTML.render() method gives you a  document.Document  object  with
       access  to  individual  document.Page  objects.  Thus you can get the number of pages, their size[1], the
       details of hyperlinks and bookmarks, etc. Documents also have a document.Document.write_pdf() method, and
       you can get a subset  of  the  pages  with  document.Document.copy().   Finally,  for  ultimate  control,
       document.Page.paint() individual pages anywhere on any pydyf.Stream.

       [1]  Pages in the same document do not always have the same size.

            See the Python API for details. A few random examples:

          # Write odd and even pages separately:
          #   Lists count from 0 but page numbers usually from 1
          #   [::2] is a slice of even list indexes but odd-numbered pages.
          document.copy(document.pages[::2]).write_pdf('odd_pages.pdf')
          document.copy(document.pages[1::2]).write_pdf('even_pages.pdf')

          # Print the outline of the document.
          # Output on http://www.w3.org/TR/CSS21/intro.html
          #     1. Introduction to CSS 2.1 (page 2)
          #       1. A brief CSS 2.1 tutorial for HTML (page 2)
          #       2. A brief CSS 2.1 tutorial for XML (page 5)
          #       3. The CSS 2.1 processing model (page 6)
          #         1. The canvas (page 7)
          #         2. CSS 2.1 addressing model (page 7)
          #       4. CSS design principles (page 8)
          def print_outline(bookmarks, indent=0):
              for i, bookmark in enumerate(bookmarks, 1):
                  page = bookmark.destination[0]
                  print('%s%d. %s (page %d)' % (
                      ' ' * indent, i, bookmark.label.lstrip('0123456789. '), page))
                  print_outline(bookmark.children, indent + 2)
          print_outline(document.make_bookmark_tree())

   URL Fetchers
       WeasyPrint  goes through a URL fetcher to fetch external resources such as images or CSS stylesheets. The
       default fetcher can natively open file and HTTP URLs, but the  HTTP  client  does  not  support  advanced
       features  like  cookies  or  authentication.  This  can  be worked-around by passing a custom url_fetcher
       callable to the HTML or CSS classes.  It must have the same signature as default_url_fetcher().

       Custom fetchers can choose to handle some URLs and defer others to the default fetcher:

          from weasyprint import default_url_fetcher, HTML

          def my_fetcher(url):
              if url.startswith('graph:'):
                  graph_data = map(float, url[6:].split(','))
                  return dict(string=generate_graph(graph_data),
                              mime_type='image/png')
              return default_url_fetcher(url)

          source = '<img src="graph:42,10.3,87">'
          HTML(string=source, url_fetcher=my_fetcher).write_pdf('out.pdf')

       Flask-WeasyPrint for Flask and Django-Weasyprint for Django both make use of  a  custom  URL  fetcher  to
       integrate WeasyPrint and use the filesystem instead of a network call for static and media files.

       A custom fetcher should be returning a dict with

       • One of string (a bytestring) or file_obj (a file object).

       • Optionally: mime_type, a MIME type extracted e.g. from a Content-Type header. If not provided, the type
         is guessed from the file extension in the URL.

       • Optionally:  encoding,  a  character encoding extracted e.g. from a charset parameter in a Content-Type
         header

       • Optionally: redirected_url, the actual URL of the resource if there were e.g. HTTP redirects.

       • Optionally: filename, the filename of the resource. Usually derived from the filename  parameter  in  a
         Content-Disposition header

       If  a  file_obj  is  given,  the resource will be closed automatically by the function internally used by
       WeasyPrint to retreive data.

   Image Cache and Optimization
       WeasyPrint provides two options to deal with images: optimize_size and image_cache.

       optimize_size can enable size optimization for images, but also for fonts.  When enabled,  the  generated
       PDF will include smaller images and fonts, but the rendering time may be slightly increased.

          # No size optimization, faster, but generated PDF is larger
          HTML('http://example.org/').write_pdf(
              'example.pdf', optimize_size=())

          # Full size optimization, slower, but generated PDF is smaller
          HTML('http://example.org/').write_pdf(
              'example.pdf', optimize_size=('fonts', 'images'))

       image_cache  gives  the  possibility  to use a cache for images, avoiding to download, parse and optimize
       them each time they are used.

       By default, the cache is used document by document, but you can share it  between  documents  if  needed.
       This  feature can save a lot of network and CPU time when you render a lot of documents that use the same
       images.

          cache = {}
          for i in range(10):
              HTML(f'http://example.org/?id={i}').write_pdf(
                  f'example-{i}.pdf', image_cache=cache)

   Logging
       Most errors (unsupported CSS property, missing image, ...)  are not fatal and will not prevent a document
       from being rendered.

       WeasyPrint uses the logging module from the Python standard library to log these errors and let you  know
       about  them. When WeasyPrint is launched in a terminal, logged messaged will go to stderr by default. You
       can change that by configuring the weasyprint logger object:

          import logging
          logger = logging.getLogger('weasyprint')
          logger.addHandler(logging.FileHandler('/path/to/weasyprint.log'))

       The weasyprint.progress logger is used to report the rendering progress. It is  useful  to  get  feedback
       when  WeasyPrint  is  launched  in  a  terminal  (using the --verbose or --debug option), or to give this
       feedback to end users when used as a library.

       See the documentation of the logging module for details.

   Security
       When used with untrusted HTML or untrusted CSS, WeasyPrint can meet  security  problems.  You  will  need
       extra  configuration  in  your  Python  application to avoid high memory use, endless renderings or local
       files leaks.

       This section has been added thanks to the very useful reports and advice from Raz Becker.

   Long Renderings
       WeasyPrint is pretty slow and can take a long time to render long documents  or  specially  crafted  HTML
       pages.

       When  WeasyPrint used on a server with HTML or CSS files from untrusted sources, this problem can lead to
       very long time renderings, with processes with high CPU and memory use. Even small documents may lead  to
       really long rendering times, restricting HTML document size is not enough.

       If you use WeasyPrint on a server with HTML or CSS samples coming from untrusted users, you should:

       • limit  rendering  time and memory use of your process, for example using evil-reload-on-as and harakiri
         options if you use uWSGI,

       • limit memory use at the OS level, for example with ulimit on Linux,

       • automatically kill the process when it uses too much memory or when the rendering time is too high,  by
         regularly launching a script to do so if no better option is available,

       • truncate and sanitize HTML and CSS input to avoid very long documents and access to external URLs.

   Infinite Requests
       WeasyPrint  can  reach  files  on  the network, for example using http:// URIs. For various reasons, HTTP
       requests may take a long time and lead to problems similar to Long Renderings.

       WeasyPrint has a default timeout of 10 seconds for HTTP, HTTPS and FTP resources.  This  timeout  has  no
       effect with other protocols, including access to file:// URIs.

       If  you use WeasyPrint on a server with HTML or CSS samples coming from untrusted users, or need to reach
       network resources, you should:

       • use a custom URL fetcher,

       • follow solutions listed in Long Renderings.

   Infinite Loops
       WeasyPrint has been hit by a large number of bugs, including infinite loops. Specially crafted  HTML  and
       CSS files can quite easily lead to infinite loops and infinite rendering times.

       If you use WeasyPrint on a server with HTML or CSS samples coming from untrusted users, you should:

       • follow solutions listed in Long Renderings.

   Huge Values
       WeasyPrint  doesn't  restrict integer and float values used in CSS. Using huge values for some properties
       (page sizes, font sizes, block sizes) can lead to various problems, including infinite  rendering  times,
       huge PDF files, high memory use and crashes.

       This  problem  is really hard to avoid. Even parsing CSS stylesheets and searching for huge values is not
       enough, as it is quite easy to trick CSS pre-processors using relative units (em and % for example).

       If you use WeasyPrint on a server with HTML or CSS samples coming from untrusted users, you should:

       • follow solutions listed in Long Renderings.

   Access to Local Files
       As any web renderer, WeasyPrint can reach files on the local filesystem using file:// URIs.  These  files
       can be shown in img or embed tags for example.

       When  WeasyPrint used on a server with HTML or CSS files from untrusted sources, this feature may be used
       to know if files are present on the server filesystem, and to embed them in generated documents.

       Unix-like systems also have special local files with infinite size, like /dev/urandom. Referencing  these
       files in HTML or CSS files obviously lead to infinite time renderings.

       If you use WeasyPrint on a server with HTML or CSS samples coming from untrusted users, you should:

       • restrict your process access to trusted files using sandboxing solutions,

       • use a custom URL fetcher that doesn't allow file:// URLs or filters access depending on given paths.

       • follow solutions listed in Long Renderings.

   System Information Leaks
       WeasyPrint  relies  on  many  libraries  that  can leak hardware and software information. Even when this
       information looks useless, it can be used by attackers to exploit other security breaches.

       Leaks can include (but are not restricted to):

       • locally installed fonts (using font-family and @font-face),

       • network configuration (IPv4 and IPv6 support, IP addressing, firewall configuration, using http:// URIs
         and tracking time used to render documents),

       • Python, Pango and other libraries versions (implementation details lead to different renderings).

   SVG Images
       Rendering SVG images more or less suffers from the same problems as the ones listed here for WeasyPrint.

       Security advices apply for untrusted SVG files as they apply for untrusted HTML and CSS documents.

       Note that WeasyPrint’s URL fetcher is used to render SVG files.

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 security problems.  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.

   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.

          # 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;:

          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:

          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:

          @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.

   Improve Rendering Speed and Memory Use
       WeasyPrint  is  often  slower  than other web engines. Python is the usual suspect, but it’s not the main
       culprit here. Optimization is not the main goal  of  WeasyPrint  and  it  may  lead  to  unbearable  long
       rendering times.

       First  of  all:  WeasyPrint’s  performance  gets  generally  better with time. You can check WeasyPerf to
       compare time and memory needed across versions.

       Some tips may help you to get better results.

       • A high number of CSS properties with a high number of HTML tags can lead to a huge amount of time spent
         for the cascade. Avoiding large CSS frameworks can drastically reduce the rendering time.

       • Tables are known to be slow, especially when they are rendered on multiple pages. When possible,  using
         a common block layout instead gives much faster layouts.

       • Optimizing images and fonts can reduce the PDF size, but increase the rendering time. Moreover, caching
         images gives the possibility to read and optimize images only once, and thus to save time when the same
         image is used multiple times. See Image Cache and Optimization.

API REFERENCE

       This page is for WeasyPrint 54.1. See 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.

   Command-line API
       weasyprint.__main__.main(argv=sys.argv)
              The weasyprint program takes at least two arguments:

                 weasyprint [options] <input> <output>

              The  input is a filename or URL to an HTML document, or - to read HTML from stdin. The output is a
              filename, or - to write to stdout.

              Options can be mixed anywhere before, between, or after the input and output.

              -e <input_encoding>, --encoding <input_encoding>
                     Force the input character encoding (e.g. -e utf8).

              -s <filename_or_URL>, --stylesheet <filename_or_URL>
                     Filename or URL of a user cascading stylesheet (see  Stylesheet  Origins)  to  add  to  the
                     document (e.g. -s print.css). Multiple stylesheets are allowed.

              -m <type>, --media-type <type>
                     Set the media type to use for @media. Defaults to print.

              -u <URL>, --base-url <URL>
                     Set  the base for relative URLs in the HTML input.  Defaults to the input’s own URL, or the
                     current directory for stdin.

              -a <file>, --attachment <file>
                     Adds an attachment to the document.  The attachment is included in  the  PDF  output.  This
                     option can be used multiple times.

              -p, --presentational-hints
                     Follow HTML presentational hints.

              -O <type>, --optimize-size <type>
                     Optimize  the size of generated documents. Supported types are images, fonts, all and none.
                     This option can be used multiple times, all adds  all  allowed  values,  none  removes  all
                     previously set values.

              -v, --verbose
                     Show warnings and information messages.

              -d, --debug
                     Show debugging messages.

              -q, --quiet
                     Hide logging messages.

              --version
                     Show the version number. Other options and arguments are ignored.

              -h, --help
                     Show the command-line usage. Other options and arguments are ignored.

   Python API
       class weasyprint.HTML(input, **kwargs)
              HTML document parsed by html5lib.

              You  can  just create an instance with a positional argument: doc = HTML(something) The class will
              try to guess if the input is a filename, an absolute URL, or a file object.

              Alternatively, use one named argument so that no guessing is involved:

              Parametersfilename (str or pathlib.Path) -- A filename,  relative  to  the  current  directory,  or
                       absolute.

                     • url (str) -- An absolute, fully qualified URL.

                     • file_obj (file object) -- Any object with a read method.

                     • string (str) -- A string of HTML source.

              Specifying multiple inputs is an error: HTML(filename="foo.html", url="localhost://bar.html") will
              raise a TypeError.

              You can also pass optional named arguments:

              Parametersencoding (str) -- Force the source character encoding.

                     • base_url   (str)   --   The   base   used   to   resolve  relative  URLs  (e.g.  in  <img
                       src="../foo.png">). If not provided,  try  to  use  the  input  filename,  URL,  or  name
                       attribute of file objects.

                     • url_fetcher  (function)  --  A  function  or  other  callable  with the same signature as
                       default_url_fetcher() called to fetch external resources such as stylesheets and  images.
                       (See URL Fetchers.)

                     • media_type (str) -- The media type to use for @media.  Defaults to 'print'. Note: In some
                       cases like HTML(string=foo) relative URLs will be invalid if base_url is not provided.

              render(stylesheets=None, presentational_hints=False, optimize_size=('fonts',), font_config=None,
              counter_style=None, image_cache=None)
                     Lay out and paginate the document, but do not (yet) export it.

                     This  returns  a  document.Document  object  which  provides access to individual pages and
                     various meta-data.  See write_pdf() to get a PDF directly.

                     New in version 0.15.

                     Parametersstylesheets (list) -- An optional list of user stylesheets. List elements are  CSS
                              objects, filenames, URLs, or file objects. (See Stylesheet Origins.)

                            • presentational_hints (bool) -- Whether HTML presentational hints are followed.

                            • optimize_size  (tuple) -- Optimize size of generated PDF. Can contain "images" and
                              "fonts".

                            • font_config  (text.fonts.FontConfiguration)  --  A  font  configuration   handling
                              @font-face rules.

                            • counter_style  (css.counters.CounterStyle)  -- A dictionary storing @counter-style
                              rules.

                            • image_cache (dict) -- A dictionary used to cache images.

                     Returns
                            A document.Document object.

              write_pdf(target=None, stylesheets=None, zoom=1, attachments=None, finisher=None,
              presentational_hints=False, optimize_size=('fonts',), font_config=None, counter_style=None,
              image_cache=None)
                     Render the document to a PDF file.

                     This is a shortcut for calling render(), then Document.write_pdf().

                     Parameterstarget (str, pathlib.Path or file object) -- A filename  where  the  PDF  file  is
                              generated, a file object, or None.

                            • stylesheets  (list)  --  An optional list of user stylesheets. The list's elements
                              are CSS objects, filenames, URLs, or file-like objects. (See Stylesheet Origins.)

                            • zoom (float) -- The zoom factor in PDF units per  CSS  units.   Warning:  All  CSS
                              units are affected, including physical units like cm and named sizes like A4.  For
                              values other than 1, the physical CSS units will thus be "wrong".

                            • attachments  (list) -- A list of additional file attachments for the generated PDF
                              document or None. The list's elements are Attachment objects, filenames,  URLs  or
                              file-like objects.

                            • finisher  -- A finisher function, that accepts the document and a pydyf.PDF object
                              as parameters, can be passed to perform post-processing on the  PDF  right  before
                              the trailer is written.

                            • presentational_hints (bool) -- Whether HTML presentational hints are followed.

                            • optimize_size  (tuple) -- Optimize size of generated PDF. Can contain "images" and
                              "fonts".

                            • font_config  (text.fonts.FontConfiguration)  --  A  font  configuration   handling
                              @font-face rules.

                            • counter_style  (css.counters.CounterStyle)  -- A dictionary storing @counter-style
                              rules.

                            • image_cache (dict) -- A dictionary used to cache images.

                     Returns
                            The PDF as bytes if target is not provided or  None,  otherwise  None  (the  PDF  is
                            written to target).

       class weasyprint.CSS(input, **kwargs)
              CSS stylesheet parsed by tinycss2.

              An instance is created in the same way as HTML, with the same arguments.

              An  additional  argument  called font_config must be provided to handle @font-face rules. The same
              text.fonts.FontConfiguration object must be used for different CSS objects  applied  to  the  same
              document.

              CSS  objects  have  no  public  attributes  or  methods.  They  are  only  meant to be used in the
              HTML.write_pdf() and HTML.render() methods of HTML objects.

       class weasyprint.Attachment(input, **kwargs)
              File attachment for a PDF document.

              New in version 0.22.

              An instance is created in the same way as HTML, except that the HTML specific arguments  (encoding
              and  media_type)  are  not supported. An optional description can be provided with the description
              argument.

              Parameters
                     description -- A description of the attachment to be included in the PDF document.  May  be
                     None.

       weasyprint.default_url_fetcher(url, timeout=10, ssl_context=None)
              Fetch an external resource such as an image or stylesheet.

              Another  callable with the same signature can be given as the url_fetcher argument to HTML or CSS.
              (See URL Fetchers.)

              Parametersurl (str) -- The URL of the resource to fetch.

                     • timeout (int) -- The number of seconds before HTTP requests are dropped.

                     • ssl_context (ssl.SSLContext) -- An SSL context used for HTTP requests.

              Raises An exception indicating failure, e.g. ValueError on syntactically invalid URL.

              Returns
                     A dict with the following keys:

                     • One of string (a bytestring) or file_obj (a file object).

                     • Optionally: mime_type, a MIME type extracted e.g. from  a  Content-Type  header.  If  not
                       provided, the type is guessed from the file extension in the URL.

                     • Optionally:  encoding,  a character encoding extracted e.g. from a charset parameter in a
                       Content-Type header

                     • Optionally: redirected_url, the actual URL of  the  resource  if  there  were  e.g.  HTTP
                       redirects.

                     • Optionally:  filename,  the  filename  of the resource. Usually derived from the filename
                       parameter in a Content-Disposition header

                     If a file_obj key is given, it is the caller’s responsibility to call file_obj.close(). The
                     default function used internally to fetch data in WeasyPrint tries to close the file object
                     after retreiving; but if this URL fetcher is used elsewhere, the  file  object  has  to  be
                     closed manually.

       class weasyprint.document.Document(pages, metadata, url_fetcher, font_config, optimize_size)
              A rendered document ready to be painted in a pydyf stream.

              Typically obtained from HTML.render(), but can also be instantiated directly with a list of pages,
              a set of metadata, a url_fetcher function, and a font_config.

              copy(pages='all')
                     Take a subset of the pages.

                     New in version 0.15.

                     Parameters
                            pages (iterable) -- An iterable of Page objects from pages.

                     Returns
                            A new Document object.

                     Examples:

                     Write two PDF files for odd-numbered and even-numbered pages:

                        # Python lists count from 0 but pages are numbered from 1.
                        # [::2] is a slice of even list indexes but odd-numbered pages.
                        document.copy(document.pages[::2]).write_pdf('odd_pages.pdf')
                        document.copy(document.pages[1::2]).write_pdf('even_pages.pdf')

                     Combine multiple documents into one PDF file, using metadata from the first:

                        all_pages = [p for doc in documents for p in doc.pages]
                        documents[0].copy(all_pages).write_pdf('combined.pdf')

              fonts  A  dict  of  fonts used by the document. Keys are hashes used to identify fonts, values are
                     Font objects.

              make_bookmark_tree()
                     Make a tree of all bookmarks in the document.

                     New in version 0.15.

                     Returns
                            A list of bookmark subtrees.  A subtree is (label, target, children,  state).  label
                            is  a string, target is (page_number, x, y) like in resolve_links(), and children is
                            a list of child subtrees.

              metadata
                     A DocumentMetadata object.  Contains information that does not belong to  a  specific  page
                     but to the whole document.

              pages  A list of Page objects.

              url_fetcher
                     A  function  or  other callable with the same signature as weasyprint.default_url_fetcher()
                     called to fetch external resources such as stylesheets and images. (See URL Fetchers.)

              write_pdf(target=None, zoom=1, attachments=None, finisher=None)
                     Paint the pages in a PDF file, with metadata.

                     Parameterstarget (str, pathlib.Path or file object) -- A filename  where  the  PDF  file  is
                              generated, a file object, or None.

                            • zoom  (float)  --  The  zoom  factor in PDF units per CSS units.  Warning: All CSS
                              units are affected, including physical units like cm and named sizes like A4.  For
                              values other than 1, the physical CSS units will thus be "wrong".

                            • attachments (list) -- A list of additional file attachments for the generated  PDF
                              document   or   None.  The  list's  elements  are  weasyprint.Attachment  objects,
                              filenames, URLs or file-like objects.

                            • finisher -- A finisher function, that accepts the document and a pydyf.PDF  object
                              as  parameters,  can  be passed to perform post-processing on the PDF right before
                              the trailer is written.

                     Returns
                            The PDF as bytes if target is not provided or  None,  otherwise  None  (the  PDF  is
                            written to target).

       class weasyprint.document.DocumentMetadata
              Meta-information belonging to a whole Document.

              New in version 0.20.

              New attributes may be added in future versions of WeasyPrint.

              attachments
                     File  attachments,  as  a list of tuples of URL and a description or None. (Defaults to the
                     empty list.)  Extracted from the <link rel=attachment> elements in HTML and written to  the
                     /EmbeddedFiles dictionary in PDF.

                     New in version 0.22.

              authors
                     The  authors  of  the  document,  as  a  list  of  strings.   (Defaults to the empty list.)
                     Extracted from the <meta name=author> elements in HTML and  written  to  the  /Author  info
                     field in PDF.

              created
                     The  creation  date  of  the  document,  as  a string or None.  Dates are in one of the six
                     formats  specified  in  W3C’s  profile   of   ISO   8601.    Extracted   from   the   <meta
                     name=dcterms.created> element in HTML and written to the /CreationDate info field in PDF.

              description
                     The  description  of  the  document,  as  a  string  or  None.   Extracted  from  the <meta
                     name=description> element in HTML and written to the /Subject info field in PDF.

              generator
                     The name of one of the software packages used to generate the  document,  as  a  string  or
                     None.  Extracted from the <meta name=generator> element in HTML and written to the /Creator
                     info field in PDF.

              keywords
                     Keywords associated with the document, as a list of strings.  (Defaults to the empty list.)
                     Extracted  from  <meta  name=keywords>  elements  in HTML and written to the /Keywords info
                     field in PDF.

              modified
                     The modification date of the document, as a string or None.  Dates are in one  of  the  six
                     formats   specified   in   W3C’s   profile   of   ISO   8601.   Extracted  from  the  <meta
                     name=dcterms.modified> element in HTML and written to the /ModDate info field in PDF.

              title  The title of the document, as a string or None.  Extracted from the <title> element in HTML
                     and written to the /Title info field in PDF.

       class weasyprint.document.Page
              Represents a single rendered page.

              New in version 0.15.

              Should be obtained from Document.pages but not instantiated directly.

              anchors
                     The dict mapping each anchor name to its target, an (x, y) point in  CSS  pixels  from  the
                     top-left of the page.

              bleed  The  page  bleed  widths  as  a  dict with 'top', 'right', 'bottom' and 'left' as keys, and
                     values in CSS pixels.

              bookmarks
                     The  list  of  (bookmark_level,  bookmark_label,   target)   tuples.   bookmark_level   and
                     bookmark_label  are  respectively  an  int and a string, based on the CSS properties of the
                     same names. target is an (x, y) point in CSS pixels from the top-left of the page.

              height The page height, including margins, in CSS pixels.

              links  The list of (link_type, target, rectangle) tuples. A rectangle is (x, y, width, height), in
                     CSS pixels from the top-left of the page. link_type is one of three strings:

                     • 'external': target is an absolute URL

                     • 'internal': target is an anchor name (see Page.anchors).  The anchor might be defined  in
                       another  page,  in  multiple pages (in which case the first occurence is used), or not at
                       all.

                     • 'attachment': target is an absolute URL and  points  to  a  resource  to  attach  to  the
                       document.

              paint(stream, left_x=0, top_y=0, scale=1, clip=False)
                     Paint the page into the PDF file.

                     Parametersstream (document.Stream) -- A document stream.

                            • left_x (float) -- X coordinate of the left of the page, in PDF points.

                            • top_y (float) -- Y coordinate of the top of the page, in PDF points.

                            • scale (float) -- Zoom scale.

                            • clip  (bool)  --  Whether  to  clip/cut  content outside the page. If false or not
                              provided, content can overflow.

              width  The page width, including margins, in CSS pixels.

       class weasyprint.text.fonts.FontConfiguration
              A FreeType font configuration.

              New in version 0.32.

              Keep a list of fonts, including fonts installed on the system, fonts  installed  for  the  current
              user, and fonts referenced by cascading stylesheets.

              When  created,  an  instance  of  this  class  gathers  available  fonts.  It can then be given to
              weasyprint.HTML methods or to weasyprint.CSS to find fonts in @font-face rules.

       class weasyprint.css.counters.CounterStyle
              Counter styles dictionary.

              New in version 0.52.

              Keep a list of counter styles defined by @counter-style rules, indexed by their names.

              See https://www.w3.org/TR/css-counter-styles-3/.

   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 URL
       fetcher can help.

   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.

   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.

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

       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="/news/">   on   the   WeasyPrint   website   would    always    point    to
       http://weasyprint.org/news/ 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.

   Fonts
       WeasyPrint can use any font that Pango can find installed on the system. Fonts are automatically embedded
       in PDF files.

       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 or ~/.fonts directory is generally enough to install  a
       new font. WeasyPrint should support any font format handled by FreeType.

   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.

       The results of some of the test suites provided by the W3C are  also  available  at  test.weasyprint.org.
       This  website  uses  a tool called WeasySuite that can be useful if you want to implement new features in
       WeasyPrint.

   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:

       • The ::first-line pseudo-element.

       • 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.

       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
       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.

   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 full-width value of the text-transform property; and

       • the tab-size property.

       Experimental properties controling 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.

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

       Automatic hyphenation can be disabled again with the manual value:

          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 and word-break properties;

       • the start, end, match-parent and start end values of the text-align property;

       • the text-align-last and text-justify properties; and

       • 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.

   CSS Fonts Module Level 3
       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, provided that Pango >= 1.38 is installed.

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

       The font-variant-caps property is supported but needs the small-caps variant of the font to be installed.
       WeasyPrint does not simulate missing small-caps fonts.

   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 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:

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

       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.

       Page groups (:nth(X of pagename) pseudo-class) are not supported.

   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.

          @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:

          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 experimental 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:

          h1 { bookmark-level: none }

       The other features of this module are not implemented:

       • quotes (content: *-quote);

       • leaders (content: leader()).

   CSS Color Module Level 3
       The CSS Color Module Level 3 is a recommendation defining "CSS properties which allow authors to  specify
       the  foreground  color  and  opacity  of an element". Its main goal is to specify how colors are defined,
       including color keywords and the #rgb, #rrggbb, rgb(), rgba(), hsl(), hsla() syntaxes. Opacity and  alpha
       compositing are also defined in this document.

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

   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(X|Y)?, scale(X|Y)?, skew(X|Y)?).

       WeasyPrint does not support the transform-style, perspective, perspective-origin and  backface-visibility
       properties, and all the 3D transformations (matrix3d, rotate(3d|X|Y|Z), translate(3d|Z), scale(3d|Z)).

   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  does  not  support  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 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 property is supported.

       The image-orientation property is not supported.

   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 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 Values and Units Module Level 3
       The  CSS  Values  and  Units  Module Level 3 defines various units and keywords used in "value definition
       field of each CSS property".

       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-related lengths (em, ex, ch, rem), absolute lengths (cm, mm, q, in, pt, pc, px), angles (rad,  grad,
       turn, deg), resolutions (dpi, dpcm, dppx) are supported.

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

       Viewport-percentage lengths (vw, vh, vmin, vmax) are not supported.

   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 not 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 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 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 Text Decoration Module Level 3
       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  text-decoration-line,  text-decoration-style  and  text-decoration-color  properties  are supported,
       except from the wavy value of text-decoration-style. The text-decoration shorthand is also supported.

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

   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.

GOING FURTHER

   Why WeasyPrint?
       Automatic document generation is a common need of many applications, even if a lot of operations  do  not
       require printed paper anymore.

       Invoices,  tickets,  leaflets,  diplomas,  documentation, books… All these documents are read and used on
       paper, but also on electronical readers, on smartphones, on computers. PDF is a great format to store and
       display them in a reliable way, with pagination.

       Using HTML and CSS to generate static and paged content can be strange at first glance: browsers  display
       only  one page, with variable dimensions, often in a very dynamic way. But paged media layout is actually
       included in CSS2, which was already a W3C recommendation in 1998.

       Other well-known tools can be used to automatically generate PDF documents, like LaTeX  and  LibreOffice,
       but  they miss many advantages that HTML and CSS offer. HTML and CSS are very widely known, by developers
       but also by webdesigners. They are specified in a backwards-compatible  way,  and  regularly  adapted  to
       please  the  use  of  billions  of  people. They are really easy to write and generate, with a ridiculous
       amount of tools that are finely adapted to the needs and taste of their users.

       However, the web engines that are used for browsers were very limited for pagination when WeasyPrint  was
       created in 2011. Even now, they lack a lot of basic features. That’s why projects such as wkhtmltopdf and
       PagedJS have been created: they add some of these features to existing browsers.

       Other  solutions have beed developed, including web engine dedicated to paged media. Prince, Antennahouse
       or Typeset.sh created original renderers supporting many features related to pagination. These tools  are
       very powerful, but they are not open source.

       Building  a  free  and  open  source  web  renderer generating high-quality documents is the main goal of
       WeasyPrint. Do you think that it was a little bit crazy to create such a big project from  scratch?  Here
       is what Simon Sapin wrote in WeasyPrint’s documentation one month after the beginning:
          Are  we crazy? Yes. But not that much. Each modern web browser did take many developers’ many years of
          work to get where they are now, but WeasyPrint’s scope is much smaller: there is no  user-interaction,
          no  JavaScript,  no  live  rendering  (the  document doesn’t changed after it was first parsed) and no
          quirks mode (we don’t need to support every broken page of the web.)

          We still need however to implement the whole CSS box model and visual rendering.  This  is  a  lot  of
          work,  but we feel we can get something useful much quicker than “Let’s build a rendering engine!” may
          seem.

       Simon is often right.

   Why Python?
       Python is a really good language to design a small, OS-agnostic parser.  As  it  is  object-oriented,  it
       gives  the  possibility  to  follow  the specification with high-level classes and a small amount of very
       simple code.

       Speed is not WeasyPrint’s main goal. Web rendering is a very complex  task,  and  following  the  Zen  of
       Python  helped  a  lot  to  keep  our  sanity  (both  in  our  code  and  in our heads): code simplicity,
       maintainability and flexibility are the most important goals for this library, as they give  the  ability
       to stay really close to the specification and to fix bugs easily.

   Dive into the Source
       This  chapter  is  a  high-level  overview of WeasyPrint’s source code. For more details, see the various
       docstrings or even the code itself. When in doubt, feel free to ask!

       Much like in web browsers, the rendering of a document in WeasyPrint goes like this:

       1. The HTML document is fetched and parsed into a tree of elements (like DOM).

       2. CSS stylesheets (either found in the HTML or supplied by the user) are fetched and parsed.

       3. The stylesheets are applied to the DOM-like tree.

       4. The DOM-like tree with styles is transformed into a formatting structure made of rectangular boxes.

       5. These boxes are laid-out with fixed dimensions and position onto pages.

       6. For each page, the boxes are re-ordered to observe stacking rules, and are drawn on a PDF page.

       7. Metadata −such as document information, attachments, embedded files,  hyperlinks,  and  PDF  trim  and
          bleed boxes− are added to the PDF.

   Parsing HTML
       Not  much  to  see  here.  The  HTML class handles step 1 and gives a tree of HTML elements. Although the
       actual API is different, this tree is conceptually the same as what web browsers call the DOM.

   Parsing CSS
       As with HTML, CSS stylesheets are parsed in the CSS class with an external library, tinycss2.

       In addition to the actual parsing, the css and css.validation modules do some pre-processing:

       • Unknown and unsupported declarations are ignored with warnings.  Remaining property values  are  parsed
         in a property-specific way from raw tinycss2 tokens into a higher-level form.

       • Shorthand  properties are expanded. For example, margin becomes margin-top, margin-right, margin-bottom
         and margin-left.

       • Hyphens  in  property  names  are  replaced  by  underscores  (margin-top  becomes  margin_top).   This
         transformation is safe since none of the known (not ignored) properties have an underscore character.

       • Selectors are pre-compiled with cssselect2.

   The Cascade
       After  that  and  still in the css package, the cascade (that’s the C in CSS!) applies the stylesheets to
       the element tree.  Selectors  associate  property  declarations  to  elements.  In  case  of  conflicting
       declarations  (different  values  for  the  same  property on the same element), the one with the highest
       weight wins. Weights are based on the stylesheet’s origin, !important markers, selector  specificity  and
       source  order.  Missing  values  are  filled  in  through  inheritance  (from  the parent element) or the
       property’s initial value, so that every element has a specified value for every property.

       These specified values are turned into computed values in the css.computed_values  module.  Keywords  and
       lengths in various units are converted to pixels, etc. At this point the value for some properties can be
       represented by a single number or string, but some require more complex objects. For example, a Dimension
       object can be either an absolute length or a percentage.

       The  final  result  of  the  css.get_all_computed_styles  function is a big dict where keys are (element,
       pseudo_element_type) tuples, and keys are style dict objects. Elements are  ElementTree  elements,  while
       the  type  of  pseudo-element  is a string for eg. ::first-line selectors, or None for “normal” elements.
       Style dict objects are dicts mapping property names to the computed values. (The return value is not  the
       dict itself, but a convenience style_for function for accessing it.)

   Formatting Structure
       The  visual  formatting  model  explains  how elements (from the ElementTree tree) generate boxes (in the
       formatting structure). This is step 4 above.  Boxes may have children and thus form  a  tree,  much  like
       elements.  This tree is generally close but not identical to the ElementTree tree: some elements generate
       more than one box or none.

       Boxes are of a lot of different kinds. For example you should not confuse  block-level  boxes  and  block
       containers,  though block boxes are both.  The formatting_structure.boxes module has a whole hierarchy of
       classes to represent all these boxes. We won’t go into  the  details  here,  see  the  module  and  class
       docstrings.

       The  formatting_structure.build  module  takes  an  ElementTree tree with associated computed styles, and
       builds a formatting structure. It generates the right boxes for each element and ensures they conform  to
       the  models  rules (eg. an inline box can not contain a block). Each box has a style attribute containing
       the style dict of computed values.

       The main logic is based on the display property, but it can be overridden for some elements by  adding  a
       handler in the html module.  This is how <img> and <td colspan=3> are currently implemented, for example.

       This  module  is  rather short as most of HTML is defined in CSS rather than in Python, in the user agent
       stylesheet.

       The formatting_structure.build.build_formatting_structure function returns the box for the  root  element
       (and, through its children attribute, the whole tree).

   Layout
       Step 5 is the layout. You could say the everything else is glue code and this is where the magic happens.

       During the layout the document’s content is, well, laid out on pages.  This is when we decide where to do
       line  breaks  and  page  breaks. If a break happens inside of a box, that box is split into two (or more)
       boxes in the layout result.

       According to the box model, each box has rectangular margin, border, padding and content  areas:  [image:
       CSS Box Model] [image]

       While  box.style contains computed values, the used values are set as attributes of the Box object itself
       during the layout. This include resolving percentages and especially auto  values  into  absolute,  pixel
       lengths.  Once  the layout done, each box has used values for margins, border width, padding of each four
       sides, as well as the width and height of the content area. They also have position_x and position_y, the
       absolute coordinates of the top-left corner of the margin box (not the content  box)  from  the  top-left
       corner of the page.[1]

       Boxes  also  have helpers methods such as content_box_y and margin_width that give other metrics that can
       be useful in various parts of the code.

       The final result of the layout is a list of PageBox objects.

       [1]  These are the coordinates if no CSS transform applies.  Transforms change  the  actual  location  of
            boxes, but they are applied later during drawing and do not affect layout.

   Stacking & Drawing
       In  step  6, the boxes are reordered by the stacking module to observe stacking rules such as the z-index
       property.  The result is a tree of stacking contexts.

       Next, each laid-out page is drawn onto a PDF page. Since each box has absolute coordinates  on  the  page
       from  the layout step, the logic here should be minimal. If you find yourself adding a lot of logic here,
       maybe it should go in the layout or stacking instead.

       The code lives in the draw module.

   Metadata
       Finally (step 7), the pdf adds metadata to the PDF file: document information,  attachments,  hyperlinks,
       embedded files, trim box and bleed box.

CHANGELOG

   Version 54.1
       Released on 2022-01-31.

       Features:

       • #1547: Handle break-inside: avoid on tr tags

       Bug fixes:

       • #1540, #1239: Handle absolute children in running elements

       • #1538: Handle invalid values in text-align

       • #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-Yvez 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: Always use absolute paths to get hrefs in SVG

       • #1523: Fix many rendering problems of broken tables

       • 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-Yvez 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: Support footnotes, with financial support from Code & Co.

       • #36: Handle parallel flows for floats, absolutes, table-cells

       • #1389: Support text-align-last and text-align-all properties

       • #1434: Draw SVG and PNG emojis

       • #1520: Support overflow-wrap: anywhere#1435: Add environment variable to set DLL folder on Windows

       Performance:

       • #1439: Cache SVG use tags

       • #1481: Encode non-JPEG images as PNGs instead of JPEG2000s

       Bug fixes:

       • #137: Don’t use text-transform text for content-based uses

       • #1443: Don’t serialize and parse again inline SVG files

       • #607: Correctly handle whitespaces in bookmark labels

       • #1094: Fix column height with column-span content

       • #1473: Fix absolutely positioned boxes in duplicated pages

       • #1491: Fix target-counter attribute in flex items

       • #1515, #1508: Don’t draw empty glyphs

       • #1499: Don’t crash when font size is really small

       Documentation:

       • #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.

       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-Yvez Fargialla

       • Gábor

       • Piotr Horzycki

   Version 53.4
       Released on 2021-11-14.

       Bug fixes:

       • #1446: Fix background on pages with a bleed property

       • #1455: Use SVG width/height as inner size when no viewBox is given

       • #1469: Only enable letter- and word-spacing when needed

       • #1471: Don’t display inputs with "hidden" type

       • #1485: Allow quotes in url() syntax for SVG, Use better approximations  for  font  ascent  and  descent
         values in SVG

       • #1486: Fix images embedded from multiple pages

       • #1489: Use a better hash for fonts to avoid collisions

       • 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-Yvez Fargialla

       •

         G. Allard

       • Gábor

   Version 53.3
       Released on 2021-09-10.

       Bug fixes:

       • #1431, #1440: Fix crashes and malformed PDF files

       • #1430: Handle cx and cy in SVG rotations

       • #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-Yvez Fargialla

   Version 53.2
       Released on 2021-08-27.

       New features:

       • #1428: Re-add the make_bookmark_tree() method

       Bug fixes:

       • #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-Yvez Fargialla

   Version 53.1
       Released on 2021-08-22.

       Bug fixes:

       • #1409: Don’t crash when leaders are in floats

       • #1414: Embed images once

       • #1417: Fix crash with SVG intrinsic ratio

       Documentation:

       • #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-Yvez 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: Support basic "clipPath" in SVG

       Bug fixes:

       • #1369: Render use path in SVG

       • #1370: Fix fill color on use path in SVG

       • #1371: Handle stroke-opacity and fill-opacity

       • #1378: Fix crash with borders whose widths are in em

       • #1394: Fix crash on draw_pattern

       • #880: Handle stacking contexts put in contexts by previous generations

       • #1386: Catch font subsetting errors

       • #1403: Fix how x and y attributes are handled in SVG

       • #1399, #1401: Don’t crash when use tags reference non-existing element

       • #1393: Handle font collections

       • #1408: Handle x and y attributes in use tags

       Documentation:

       • #1391, #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-Yvez 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: Embed full sets of fonts in PDF

       Bug fixes:

       • #1345: Fix position of SVG use tags

       • #1346: Handle "stroke-dasharray: none"

       • #1352, #1358: Sort link target identifiers

       • #1357: Fix font information

       • #1362: Handle visibility and display properties in SVG

       • #1365: Cascade inherited attributes for use tags

       • #1366: Correctly handle style attributes in SVG

       • #1367: Include line stroke in box bounding

       Documentation:

       • #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-Yvez 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: Add ISO and JIS paper sizes

       • #1309: Leader support, with financial support from Simonsoft

       Bug fixes:

       • #504: Fix rendering bugs with PDF gradients

       • #606: Fix rounding errors on PDF dimensions

       • #1264: Include witdh/height when calculating auto margins of absolute boxes

       • #1191: Don’t try to get an earlier page break between columns

       • #1235: Include padding, border, padding when calculating inline-block width

       • #1199: Fix kerning issues with small fonts

       Documentation:

       • #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-Yvez Fargialla

       • Des images et des mots

       • Yevhenii Hyzyla

   Version 52.5
       Released on 2021-04-17.

       Bug fixes:

       • #1336: Fix text breaking exception

       • #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-Yvez Fargialla

       • Des images et des mots

       • Yevhenii Hyzyla

   Version 52.4
       Released on 2021-03-11.

       Bug fixes:

       • #1304: Don’t try to draw SVG files with no size

       • ece5f066: Avoid crash on last word detection

       • 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: Fix imports with url() and quotes

       New features:

       • #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: Fix URL handling with tinycss2

       • #1248: Include missing test data

       • #1254: Top margins removed from children when tables are displayed on multiple pages

       • #1250: Correctly draw borders on the last line of split tables

       • 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: 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: Implement counter-set#1080: Don’t display template tags

       • #1210: Use download attribute in a tags for attachment's filename

       • #1206: Handle strings in list-style-type#1165: Add support for concatenating var() functions in content declarations

       • c56b96b: Add an option to optimize embedded images size, with financial support from Hashbang

       • #969: Add an image cache that can be shared between documents, with financial support from Hashbang

       Bug fixes:

       • #1141: Don’t clip page margins on account of body overflow

       • #1000: Don’t apply text-indent twice on inline blocks

       • #1051: Avoid random line breaks

       • #1120: Gather target counters in page margins

       • #1110:  Handle  most  cases  for  boxes  avoiding floats in rtl containers, with financial support from
         Innovative Software

       • #1111: Fix horizontal position of last rtl line, with financial support from Innovative Software

       • #1114: Fix bug with transparent borders in tables

       • #1146: Don’t gather bookmarks twice for blocks that are displayed on two pages

       • #1237: Use fallback fonts on unsupported WOFF2 and WOFF fonts

       • #1025: Don’t insert the same layout attributes multiple times

       • #1027: Don’t try to break tables after the header or before the footer

       • #1050: Don’t crash on absolute SVG files with no intrinsic size

       • #1204: Fix a crash with a flexbox corner case

       • #1030: Fix frozen builds

       • #1089: Fix Pyinstaller builds

       • #1216: Fix embedded files

       • #1225: Initial support of RTL direction in flexbox layout

       Documentation:

       • #1149: Add the --quiet CLI option in the documentation

       • #1061: Update install instructions on Windows

       Tests:

       • #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: Add support of element() and running()#972: Add HTML element to Box class

       • 7a4d6f8: Support larger and smaller values for font-size

       Bug fixes:

       • #960: Fix how fonts used for macOS tests are installed

       • #956: Fix various crashes due to line breaking bugs

       • #983: Fix typo in variable name

       • #975: Don’t crash when string-set is set to none#998: Keep font attributes when text lines are modified

       • #1005: Don’t let presentational hints add decorations on tables with no borders

       • #974: Don’t crash on improper var() values

       • #1012: Fix rendering of header and footer for empty tables

       • #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: Make break-* properties work inside tables

       • #661: Make blocks with overflow: auto grow to include floating children

       Bug fixes:

       • #945: Don't break pages between a list item and its marker

       • #727: Avoid tables lost between pages

       • #831: Ignore auto margins on flex containers

       • #923: Fix a couple of crashes when splitting a line twice

       • #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: Handle ::marker pseudo-selector

       • 135dc06c: Handle recto and verso parameters for page breaks

       • #907: Provide a clean way to build layout contexts

       Bug fixes:

       • #937: Fix rendering of tables with empty lines and rowspans

       • #897: Don't crash when small columns are wrapped in absolute blocks

       • #913: Fix a test about gradient colors

       • #924: Fix title for document with attachments

       • #917: Fix tests with Pango 1.44

       • #919: Fix padding and margin management for column flex boxes

       • #901: Fix width of replaced boxes with no intrinsic width

       • #906: Don't respect table cell width when content doesn't fit

       • #927: Don't use deprecated logger.warn anymore

       • a8662794: Fix margin collapsing between caption and table wrapper

       • 87d9e84f: Avoid infinite loops when rendering columns

       • 789b80e6: Only use in flow children to set columns height

       • 615e298a: Don't include floating elements each time we try to render a column

       • 48d8632e: Avoid not in flow children to compute column height

       • e7c452ce: Fix collapsing margins for columns

       • fb0887cf: Fix crash when using currentColor in gradients

       • f66df067: Don't crash when using ex units in word-spacing in letter-spacing

       • c790ff20: Don't crash when properties needing base URL use var functions

       • d63eac31: Don't crash with object-fit: non images with no intrinsic size

       Documentation:

       • #900: Add documentation about semantic versioning

       • #692: Add a snippet about PDF magnification

       • #899: Add .NET wrapper link

       • #893: Fixed wrong nested list comprehension example

       • #902: Add state to the make_bookmark_tree documentation

       • #921: Fix typos in the documentation

       • #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: Handle text-overflow#878: Handle column-span#855: Handle all the text-decoration features

       • #238: Don't repeat background images when it's not needed

       • #875: Handle object-fit and object-position#870: Handle bookmark-state

       Bug fixes:

       • #686: Fix column balance when children are not inline

       • #885: Actually use the content box to resolve flex items percentages

       • #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: Set a minimum height for empty list elements with outside marker

       • #811: Don't use translations to align flex items

       • #851, #860: Don't cut pages when content overflows a very little bit

       • #862: Don't crash when using UTC dates in metadata

       Documentation:

       • #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: Handle CSS variables

       • #846: Handle :nth() page selector

       • #847: Allow users to use a custom SSL context for HTTP requests

       Bug fixes:

       • #797: Fix underlined justified text

       • #836: Fix crash when flex items are replaced boxes

       • #835: Fix margin-break: auto

   Version 46
       Released on 2019-03-20.

       New features:

       • #771: Handle box-decoration-break#115: Handle margin-break#821: Continuous integration includes tests on Windows

       Bug fixes:

       • #765, #754, #800: Fix many crashes related to the flex layout

       • #783: Fix a couple of crashes with strange texts

       • #827: Named strings and counters are case-sensitive

       • #823: Shrink min/max-height/width according to box-sizing

       • #728, #171: Don't crash when fixed boxes are nested

       • #610, #828: Don't crash when preformatted text lines end with a space

       • #808, #387: Fix position of some images

       • #813: Don't crash when long preformatted text lines end with \n

       Documentation:

       • #815: Add documentation about custom url_fetcher

   Version 45
       Released on 2019-02-20.

       WeasyPrint now has a code of conduct.

       A new website has been launched, with beautiful and useful graphs  about  speed  and  memory  use  across
       versions: check WeasyPerf.

       Dependencies:

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

       Bug fixes:

       • #798: Prevent endless loop and index out of range in pagination

       • #767: Add a --quiet CLI parameter

       • #784: Fix library loading on Alpine

       • #791: Use path2url in tests for Windows

       • #789: Add LICENSE file to distributed sources

       • #788: Fix pending references

       • #780: Don't draw patterns for empty page backgrounds

       • #774: Don't crash when links include quotes

       • #637: Fix a problem with justified text

       • #763: Launch tests with Python 3.7

       • #704: Fix a corner case with tables

       • #804: Don't logger handlers defined before importing WeasyPrint

       • #109, #748: Don't include punctuation for hyphenation

       • #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 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: Fix a small typo in the tutorial

       • #792: Document no alignement character support

       • #773: Fix phrasing in Hacking section

       • #402: Add a paragraph about fontconfig error

       • #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: Don't crash during PDF generation when locale uses commas as decimal separator

       • #746: Close file when reading VERSION

       • Improve speed and memory usage for long texts.

       Documentation:

       • #733: Small documentation fixes

       • #735: Fix broken links in NEWS.rst

   Version 43
       Released on 2018-11-09.

       Bug fixes:

       • #726: Make empty strings clear previous values of named strings

       • #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: Fix text-indent at the beginning of a page

       • #687: Allow query strings in file:// URIs

       • #720: Optimize minimum size calculation of long inline elements

       • #717: Display <details> tags as blocks

       • #691: Don't recalculate max content widths when distributing extra space for tables

       • #722: Fix bookmarks and strings set on images

       • #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#579: Initial support of flexbox

       • #592: Support @font-face on Windows

       • #306: Add a timeout parameter to the URL fetcher functions

       • #594: Split tests using modern pytest features

       • #599: Make tests pass on Windows

       • #604: Handle target counters and target texts

       • #631: Enable counter-increment and counter-reset in page context

       • #622: Allow pathlib.Path objects for HTML, CSS and Attachment classes

       • #674: Add extensive installation instructions for Windows

       Bug fixes:

       • #558: Fix attachments

       • #565, #596, #539: Fix many PDF rendering, printing and compatibility problems

       • #614: Avoid crashes and endless loops caused by a Pango bug

       • #662: Fix warnings and errors when generating documentation

       • #666, #685: Fix many table layout rendering problems

       • #680: Don't crash when there's no font available

       • #662: Fix support of some align values in tables

   Version 0.42.3
       Released on 2018-03-27.

       Bug fixes:

       • #583: Fix floating-point number error to fix floating box layout

       • #586: Don't optimize resume_at when splitting lines with trailing spaces

       • #582: Fix table layout with no overflow

       • #580: Fix inline box breaking function

       • #576: Split replaced_min_content_width and replaced_max_content_width

       • #574: Respect text direction and don't translate rtl columns twice

       • #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: Fix a couple of crashes and endless loops when breaking lines.

   Version 0.42.1
       Released on 2018-02-01.

       Bug fixes:

       • #566: Don't crash when using @font-config.

       • #567: Fix text-indent with text-align: justify.

       • #465: Fix string(*, start).

       • #562: Handle named pages with pseudo-class.

       • #507: Fix running headers.

       • #557: Avoid infinite loops in inline_line_width.

       • #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: Support relative file URIs when using CLI.

       Bug fixes:

       • #553: Fix slow performance for pre-formatted boxes with a lot of children.

       • #409: Don't crash when rendering some tables.

       • #39: Fix rendering of floats in inlines.

       • #301: Split lines carefully.

       • #530: Fix root when frozen with Pyinstaller.

       • #534: Handle SVGs containing images embedded as data URIs.

       • #360: Fix border-radius rendering problem with some PDF readers.

       • #525: Fix pipenv support.

       • #227: Smartly handle replaced boxes with percentage width in auto-width parents.

       • #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: Support page marks and bleed.

       Bug fixes:

       • #513: Don't crash on unsupported image-resolution values.

       • #506: Fix @font-face use with write_* methods.

       • #500: Improve readability of _select_source function.

       • #498: Use CSS prefixes as recommanded by the CSSWG.

       • #441: Fix rendering problems and crashes when using @font-face.

       • bb3a4db: Try to break pages after a block before trying to break inside it.

       • 1d1654c: Fix and test corner cases about named pages.

       Documentation:

       • #508: Add missing libpangocairo dependency for Debian and Ubuntu.

       • 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: Named pages.

       • Unprefix properties, see #498.

       • Add a "verbose" option logging the document generation steps.

       Bug fixes:

       • #483: Fix slow performance with long pre-formatted texts.

       • #70: Improve speed and memory usage for long documents.

       • #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: 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: Support local links in generated PDFs.

       Bug fixes:

       • #412: Use a NullHandler log handler when WeasyPrint is used as a library.

       • #417, #472: Don't crash on some line breaks.

       • #327: Don't crash with replaced elements with height set in percentages.

       • #467: Remove incorrect line breaks.

       • #446: Let the logging module do the string interpolation.

   Version 0.36
       Released on 2017-02-25.

       New features:

       • #407: Handle ::first-letter.

       • #423: Warn user about broken cairo versions.

       Bug fixes:

       • #411: Typos fixed in command-line help.

   Version 0.35
       Released on 2017-02-25.

       Bug fixes:

       • #410: Fix AssertionError in split_text_box.

   Version 0.34
       Released on 2016-12-21.

       Bug fixes:

       • #398: Honor the presentational_hints option for PDFs.

       • #399: Avoid CairoSVG-2.0.0rc* on Python 2.

       • #396: Correctly close files open by mkstemp.

       • #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: Add tests on MacOS.

       • #370: Enable @font-face on MacOS.

       Bug fixes:

       • #389: Always update resume_at when splitting lines.

       • #394: Don't build universal wheels.

       • #388: Fix logic when finishing block formatting context.

   Version 0.32
       Released on 2016-11-17.

       New features:

       • #28: Support @font-face on Linux.

       • Support CSS fonts level 3 almost entirely, including OpenType features.

       • #253: Support presentational hints (optional).

       • Support break-after, break-before and break-inside for pages and columns.

       • #384: Major performance boost.

       Bux fixes:

       • #368: Respect white-space for shrink-to-fit.

       • #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: Add fonts requirements for tests.

   Version 0.31
       Released on 2016-08-28.

       New features:

       • #124: Add MIME sniffing for images.

       • #60: CSS Multi-column Layout.

       • #197: Add hyphens at line breaks activated by a soft hyphen.

       Bux fixes:

       • #132: Fix Python 3 compatibility on Windows.

       Documentation:

       • #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: Cutting lines is broken in page margin boxes.

       • #334: Newest html5lib 0.999999999 breaks rendering.

   Version 0.29
       Released on 2016-06-17.

       Bug fixes:

       • #263: Don't crash with floats with percents in positions.

       • #323: Fix CairoSVG 2.0 pre-release dependency in Python 2.x.

   Version 0.28
       Released on 2016-05-16.

       Bug fixes:

       • #189: white-space: nowrap still wraps on hyphens

       • #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: Support the 'rem' unit.

       • #299: Enhance the support of SVG images.

       Bug fixes:

       • #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: 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: Unable to set table column width on tables td's.

       • #151: Table background colour bleeds beyond table cell boundaries.

       • #260: TypeError: unsupported operand type(s) for +: 'float' and 'str'.

       • #288: Unwanted line-breaks in bold text.

       • #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: Fix a crash happening when splitting lines.

       • #284: Escape parenthesis in PDF links.

       • #280: Replace utf8 with utf-8 for gettext/django compatibility.

       • #269: Add support for use when frozen.

       • #250: Don't crash when attachments are not available.

   Version 0.24
       Released on 2015-08-04.

       New features:

       • #174: Basic support for Named strings.

       Bug fixes:

       • #207: Draw rounded corners on replaced boxes.

       • #224: Rely on the font size for rounding bug workaround.

       • #31: Honor the vertical-align property in fixed-height cells.

       • #202: Remove unreachable area/border at bottom of page.

       • #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: Use the default image sizing algorithm for images’s preferred size.

       • #194: Try more library aliases with dlopen().

       • #201: Consider page-break-after-avoid when pushing floats to the next page.

       • #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: Support gzip and deflate encoding in HTTP responses

       • #177: Support for PDF attachments.

       Bug fixes:

       • #169: Fix a crash on percentage-width columns in an auto-width table.

       • #168: Make <fieldset> a block in the user-agent stylesheet.

       • #175: Fix some dlopen() library loading issues on OS X.

       • #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: Require a recent enough version of Pyphen

       Release process:

       • Drop Python 3.1 support.

       • Set up [Travis CI](http://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 property,  allowing  line  breaks  inside  otherwise-unbreakable  words.   Thanks
         Frédérick Deslandes!

       • Add  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: Fix parsing HTML from an HTTP URL on Python 3.x

       • #40: Use more general hyphenation dictionnaries for specific document languages.  (E.g. use hyph_fr.dic
         for lang="fr_FR".)

       • #26: Fix min-width and max-width on floats.

       • #100: Fix a crash on trailing whitespace with font-size: 0#82: Borders on tables with border-collapse: collapse were sometimes drawn at an incorrect position.

       • #30: Fix positioning of images with position: absolute.

       • #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  and  #153:  Fix  dependencies to require lxml 3.0 or a more recent version.  Thanks gizmonerd and
         Thomas Grainger!

       • #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: 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: don't crash on space followed by dot at line break.

       • Fix #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: Add PDF metadata from HTML.

       • Feature #12: Use html5lib.

       • Tables: handle percentages for column groups, columns and cells, and values for row height.

       • Bug fixes:

         • Fix #84: don't crash when stylesheets are not available.

         • Fix #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: 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: 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: 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: min/max-width/height on block-level images.

          • Fix #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: Resolve images’ auto width from non-auto height and intrinsic ratio.

         • Fix #21: The data: URL scheme is case-insensitive.

         • Fix #53: Crash when backtracking for break-before/after: avoid.

   Version 0.17.1
       Released on 2013-03-18.

       Bug fixes:

       • Fix #41: GObject initialization when GDK-PixBuf is not installed.

       • Fix #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: Division by 0 on dashed or dotted border smaller than one dot/dash.

       • Fix #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.

   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.

   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.  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.

       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

   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-libraryBackward  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.

CONTRIBUTE

       You  want  to  add some code to WeasyPrint, launch its tests or improve its documentation? Thank you very
       much! Here are some tips to help you play with WeasyPrint in good conditions.

       The first step is  to  clone  the  repository,  create  a  virtual  environment  and  install  WeasyPrint
       dependencies.

          git clone https://github.com/Kozea/WeasyPrint.git
          cd WeasyPrint
          python -m venv venv
          venv/bin/pip install -e .[doc,test]

       You can then launch Python to test your changes.

          venv/bin/python

   Code & Issues
       If you’ve found a bug in WeasyPrint, it’s time to report it, and to fix it if you can!

       You  can report bugs and feature requests on GitHub. If you want to add or fix some code, please fork the
       repository and create a pull request, we’ll be happy to review your work.

       You can find more information about the code architecture in the Dive into the Source section.

   Tests
       Tests are stored in the tests folder at the top of the repository. They use the pytest library.

       You can launch tests (with code coverage and lint) using the following command:

          venv/bin/python -m pytest

   Documentation
       Documentation is stored in the docs folder at the top of the repository. It relies on the Sphinx library.

       You can build the documentation using the following command:

          venv/bin/sphinx-build docs docs/_build

       The documentation home page can now be found in the /path/to/weasyprint/docs/_build/index.html file.  You
       can open this file in a browser to see the final rendering.

SUPPORT

   Sponsorship
       With donations and sponsorship, you help make the projects better. Donations allow the CourtBouillon team
       to have more time dedicated to add new features, fix bugs, and improve documentation.

   Professional Support
       You  can  improve your experience with CourtBouillon’s tools thanks to our professional support. You want
       bugs fixed as soon as possible? Your projects would highly benefit from some new features?  You  or  your
       team would like to get new skills with one of the technologies we master?

       Please contact us by mail, by chat, or by tweet to get in touch and find the best way we can help you.

AUTHOR

       Simon Sapin and contributors

COPYRIGHT

       Simon Sapin and contributors

54.1                                              Feb 01, 2022                                     WEASYPRINT(1)