Provided by: weasyprint_54.1-3_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