Authentic people growing open source code with taste

WeasyPrint v61 Has Been Released

Version 61 of WeasyPrint has been released. It comes with nice new features 🚀, a Windows executable 🪟, a lot of bug fixes 🐛, and code from 12 different contributors!

Better CSS Support

WeasyPrint v61 brings better CSS support for various properties.

Allowing var() Everywhere

var() is widely used. WeasyPrint supports it since 2019, but only in the simplest use case: as a single value. There was no way to use it in shorthand properties (like background or border), or even in properties that allow multiple values (like background-position or transform-origin).

Good news, var() should now be allowed everywhere: shorthand properties, multi-value properties, and even in functions! Also, it now works at the CSS token level as expected, meaning you can for, example include, put values in a single variable and pass them as multiple function parameters or multiple property values. Ever wanted to use --rgb: 0, 255, 128; color: rgb(var(--rgb))? Now you can 🌈!

Drawing Full Page Backgrounds with background-attachment: fixed

Positioning a background image on a page can sometimes be confusing, because the default page surface doesn’t include page margins.

Hopefully, CSS provides a feature that allows you to include these margins: background-attachment: fixed. Set it to your page background, and the default page surface will automatically include its margins. No need to calculate negative background positions and complicated image sizes anymore!

Using Percentages for opacity

In the CSS Color Level 3 specification, the well-known opacity property was designed to allow a number between 0 and 1. But… what about percentages? Since many users wanted to use percentages too, the feature was added in Level 4.

Since the new feature was quickly adopted by browsers, many stylesheets already use it. It was time to support it in WeasyPrint as well ✨!

Let’s Introduce… weasyprint.exe

Installing WeasyPrint on Windows is known to be a bit complicated. Since it requires non-Python dependencies, pip install weasyprint is not enough, and escaping the DLL hell can sometimes discourage newcomers 😔.

As a lot of related issues have been opened in the last few years, we’ve tried to improve our communication about this problem: a dedicated chapter was added in the documentation, consistent answers were given to issues, and an explicit warning message was printed on the terminal when such a problem occurs. But let’s face it: nobody wants to carefully follow the documentation steps to install software!

We had to do more. There are several solutions to this problem, and here’s the one we chose: weasyprint.exe. Building an executable from a Python project is not an easy task, but thanks to PyInstaller we now generate a standalone executable. Download the file, run it, and… you’re done 🧙!

Of course, using an executable doesn’t magically solve all cases: for example, you can’t use WeasyPrint as a Python library. The startup time is also known to be affected by this packaging. But avoiding complex installation steps can be a big advantage for many users, and you might be interested if you just want to test WeasyPrint or use it in a non-Python application.

Dear Windows users, it’s time to download and test weasyprint.exe!

Less Bugs, More Tests

Nobody likes bugs, and fixing them is a big part of our work. But the best way to reduce this part is… to avoid introducing new bugs 🐛!

In this release, we added about 260 lines of code (1117 insertions, 855 deletions) to WeasyPrint. It doesn’t seem like much, but we have to be careful: more code means more maintenance and more bugs. Keeping WeasyPrint "small" and "simple" is important if we want the project to be sustainable. But writing small code takes a lot of time, and writing simple code is sometimes really complex!

Another cornerstone of our quality management is testing, and we always try to add a lot of tests! We add tests when we add new features, and when we fix bugs to avoid regressions. That’s why we added almost 1000 new lines of tests in this release (1463 insertions, 483 deletions). This ratio of about 4:1 lines between tests and code is not a perfect metric, as tests tend to be more verbose than code, but it’s an important thing to keep in mind: in WeasyPrint, code almost always comes with hidden related test code.

Tests are very powerful for us. As you can imagine, they check that features behave correctly, they prevent old bugs from reappearing, they detect problems on specific versions of Python, on specific OSes, with new dependency versions. But tests have an even greater power: they allow us to add new features quickly, with (almost) no fear of breaking everything. We can also easily refactor code, clean dirty parts, reduce our technical debt. This way we can always keep our motivation high when we code on WeasyPrint 😁!

What’s Next?

What’s next? That depends on you! If you are interested in better CSS layout support such as solid Flexbox and Grid support, don’t be afraid to contact us! Your help might be very useful.

Opening issues and pull requests is also a great way to improve WeasyPrint. This release includes code from 12 different contributors, and we’re very proud to welcome a growing number of contributors 💜. If you want to get involved, a list of good first issues is waiting for you! Choose your favorite issue and write a short comment, we’ll be happy to help you dive into WeasyPrint’s code!

And of course you can also become a sponsor on OpenCollective, it really helps us to have more time to work on WeasyPrint and its dependencies.

Have fun with this new version of WeasyPrint, we hope that these improvements will be useful for you!