weasyprint 66.0__tar.gz → 67.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. {weasyprint-66.0 → weasyprint-67.0}/PKG-INFO +5 -6
  2. {weasyprint-66.0 → weasyprint-67.0}/README.rst +1 -1
  3. {weasyprint-66.0 → weasyprint-67.0}/docs/api_reference.rst +45 -21
  4. {weasyprint-66.0 → weasyprint-67.0}/docs/changelog.rst +159 -0
  5. {weasyprint-66.0 → weasyprint-67.0}/docs/common_use_cases.rst +26 -0
  6. {weasyprint-66.0 → weasyprint-67.0}/docs/first_steps.rst +4 -4
  7. {weasyprint-66.0 → weasyprint-67.0}/pyproject.toml +5 -6
  8. {weasyprint-66.0 → weasyprint-67.0}/tests/conftest.py +2 -2
  9. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_common.py +37 -13
  10. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_counters.py +4 -4
  11. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_descriptors.py +9 -9
  12. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_errors.py +4 -4
  13. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_expanders.py +88 -87
  14. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_fonts.py +5 -5
  15. weasyprint-67.0/tests/css/test_layers.py +85 -0
  16. weasyprint-67.0/tests/css/test_math.py +264 -0
  17. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_nesting.py +2 -2
  18. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_pages.py +2 -2
  19. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_target.py +1 -1
  20. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_ua.py +1 -1
  21. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_validation.py +177 -150
  22. {weasyprint-66.0 → weasyprint-67.0}/tests/css/test_variables.py +59 -8
  23. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/__init__.py +5 -2
  24. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_gradients.py +1 -1
  25. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_images.py +77 -0
  26. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_absolute.py +6 -6
  27. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_background.py +15 -15
  28. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_before_after.py +3 -3
  29. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_box.py +17 -21
  30. weasyprint-67.0/tests/draw/test_cmyk_color_profiles.py +78 -0
  31. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_column.py +2 -2
  32. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_current_color.py +2 -2
  33. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_float.py +101 -3
  34. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_footnote.py +3 -3
  35. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_footnote_column.py +3 -3
  36. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_gradient.py +68 -8
  37. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_image.py +9 -10
  38. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_list.py +2 -2
  39. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_overflow.py +2 -2
  40. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_page.py +2 -2
  41. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_table.py +0 -1
  42. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_block.py +76 -13
  43. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_column.py +25 -5
  44. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_flex.py +73 -20
  45. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_float.py +16 -0
  46. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_footnotes.py +89 -2
  47. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_grid.py +732 -0
  48. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_image.py +58 -10
  49. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_inline.py +2 -2
  50. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_list.py +3 -3
  51. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_page.py +21 -26
  52. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_position.py +95 -0
  53. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_preferred.py +1 -1
  54. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_table.py +10 -10
  55. weasyprint-67.0/tests/resources/cmyk.icc +0 -0
  56. weasyprint-67.0/tests/resources/cmyk_with_icc.jpg +0 -0
  57. weasyprint-67.0/tests/resources/cmyk_without_icc.jpg +0 -0
  58. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/weasyprint.otf +0 -0
  59. {weasyprint-66.0 → weasyprint-67.0}/tests/test_api.py +62 -37
  60. {weasyprint-66.0 → weasyprint-67.0}/tests/test_boxes.py +4 -4
  61. {weasyprint-66.0 → weasyprint-67.0}/tests/test_fonts.py +2 -2
  62. {weasyprint-66.0 → weasyprint-67.0}/tests/test_pdf.py +13 -4
  63. {weasyprint-66.0 → weasyprint-67.0}/tests/test_presentational_hints.py +2 -1
  64. {weasyprint-66.0 → weasyprint-67.0}/tests/test_stacking.py +4 -4
  65. {weasyprint-66.0 → weasyprint-67.0}/tests/test_text.py +172 -27
  66. {weasyprint-66.0 → weasyprint-67.0}/tests/test_url.py +2 -2
  67. {weasyprint-66.0 → weasyprint-67.0}/tests/testing_utils.py +3 -3
  68. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/__init__.py +14 -7
  69. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/__main__.py +19 -10
  70. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/anchors.py +4 -4
  71. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/__init__.py +723 -66
  72. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/computed_values.py +64 -175
  73. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/counters.py +1 -1
  74. weasyprint-67.0/weasyprint/css/functions.py +206 -0
  75. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/html5_ua.css +1 -0
  76. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/html5_ua_form.css +1 -1
  77. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/media_queries.py +3 -1
  78. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/properties.py +6 -2
  79. weasyprint-66.0/weasyprint/css/utils.py → weasyprint-67.0/weasyprint/css/tokens.py +306 -397
  80. weasyprint-67.0/weasyprint/css/units.py +91 -0
  81. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/validation/__init__.py +1 -1
  82. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/validation/descriptors.py +47 -19
  83. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/validation/expanders.py +7 -8
  84. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/validation/properties.py +341 -357
  85. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/document.py +19 -10
  86. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/draw/__init__.py +6 -7
  87. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/draw/border.py +3 -5
  88. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/draw/color.py +1 -1
  89. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/draw/text.py +59 -39
  90. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/formatting_structure/boxes.py +21 -3
  91. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/formatting_structure/build.py +2 -4
  92. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/images.py +68 -47
  93. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/__init__.py +27 -24
  94. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/absolute.py +3 -5
  95. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/background.py +7 -7
  96. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/block.py +140 -128
  97. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/column.py +18 -24
  98. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/flex.py +13 -5
  99. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/float.py +4 -6
  100. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/grid.py +284 -90
  101. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/inline.py +114 -60
  102. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/page.py +23 -12
  103. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/percent.py +14 -10
  104. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/preferred.py +45 -30
  105. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/replaced.py +9 -6
  106. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/table.py +8 -5
  107. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/__init__.py +46 -13
  108. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/anchors.py +1 -2
  109. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/fonts.py +126 -69
  110. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/metadata.py +36 -4
  111. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/pdfa.py +19 -3
  112. weasyprint-67.0/weasyprint/pdf/pdfx.py +83 -0
  113. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/stream.py +18 -1
  114. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/tags.py +6 -4
  115. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/__init__.py +37 -21
  116. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/images.py +11 -3
  117. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/text.py +11 -2
  118. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/utils.py +6 -3
  119. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/text/constants.py +1 -1
  120. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/text/ffi.py +4 -3
  121. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/text/fonts.py +12 -4
  122. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/text/line_break.py +101 -17
  123. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/urls.py +21 -4
  124. {weasyprint-66.0 → weasyprint-67.0}/LICENSE +0 -0
  125. {weasyprint-66.0 → weasyprint-67.0}/docs/conf.py +0 -0
  126. {weasyprint-66.0 → weasyprint-67.0}/docs/contribute.rst +0 -0
  127. {weasyprint-66.0 → weasyprint-67.0}/docs/going_further.rst +0 -0
  128. {weasyprint-66.0 → weasyprint-67.0}/docs/index.rst +0 -0
  129. {weasyprint-66.0 → weasyprint-67.0}/docs/manpage.rst +0 -0
  130. {weasyprint-66.0 → weasyprint-67.0}/docs/support.rst +0 -0
  131. {weasyprint-66.0 → weasyprint-67.0}/tests/__init__.py +0 -0
  132. {weasyprint-66.0 → weasyprint-67.0}/tests/css/__init__.py +0 -0
  133. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/__init__.py +0 -0
  134. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_bounding_box.py +0 -0
  135. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_clip.py +0 -0
  136. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_defs.py +0 -0
  137. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_markers.py +0 -0
  138. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_opacity.py +0 -0
  139. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_paths.py +0 -0
  140. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_patterns.py +0 -0
  141. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_shapes.py +0 -0
  142. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_text.py +0 -0
  143. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_transform.py +0 -0
  144. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_units.py +0 -0
  145. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/svg/test_visibility.py +0 -0
  146. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_leader.py +0 -0
  147. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_opacity.py +0 -0
  148. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_text.py +0 -0
  149. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_transform.py +0 -0
  150. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_visibility.py +0 -0
  151. {weasyprint-66.0 → weasyprint-67.0}/tests/draw/test_whitespace.py +0 -0
  152. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/__init__.py +0 -0
  153. {weasyprint-66.0 → weasyprint-67.0}/tests/layout/test_inline_block.py +0 -0
  154. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/acid2-reference.html +0 -0
  155. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/acid2-test.html +0 -0
  156. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/blue.jpg +0 -0
  157. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/border.svg +0 -0
  158. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/border2.svg +0 -0
  159. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/doc1.html +0 -0
  160. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/doc1_UTF-16BE.html +0 -0
  161. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/icon.png +0 -0
  162. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/latin1-test.css +0 -0
  163. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/logo_small.png +0 -0
  164. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/mask.svg +0 -0
  165. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/mini_ua.css +0 -0
  166. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/not-optimized-exif.jpg +0 -0
  167. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/not-optimized.jpg +0 -0
  168. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/pattern-transparent.svg +0 -0
  169. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/pattern.gif +0 -0
  170. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/pattern.palette.png +0 -0
  171. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/pattern.png +0 -0
  172. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/pattern.svg +0 -0
  173. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/really-a-png.svg +0 -0
  174. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/really-a-svg.png +0 -0
  175. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/sheet2.css +0 -0
  176. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/sub_directory/sheet1.css +0 -0
  177. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/tests_ua.css +0 -0
  178. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/user.css +0 -0
  179. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/utf8-test.css +0 -0
  180. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/weasyprint.otb +0 -0
  181. {weasyprint-66.0 → weasyprint-67.0}/tests/resources/weasyprint.woff +0 -0
  182. {weasyprint-66.0 → weasyprint-67.0}/tests/test_acid2.py +0 -0
  183. {weasyprint-66.0 → weasyprint-67.0}/tests/test_unicode.py +0 -0
  184. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/html5_ph.css +0 -0
  185. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/css/targets.py +0 -0
  186. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/html.py +0 -0
  187. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/leader.py +0 -0
  188. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/layout/min_max.py +0 -0
  189. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/logger.py +0 -0
  190. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/matrix.py +0 -0
  191. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/debug.py +0 -0
  192. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/pdfua.py +0 -0
  193. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/pdf/sRGB2014.icc +0 -0
  194. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/stacking.py +0 -0
  195. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/bounding_box.py +0 -0
  196. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/css.py +0 -0
  197. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/defs.py +0 -0
  198. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/path.py +0 -0
  199. {weasyprint-66.0 → weasyprint-67.0}/weasyprint/svg/shapes.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weasyprint
3
- Version: 66.0
3
+ Version: 67.0
4
4
  Summary: The Awesome Document Factory
5
5
  Keywords: html,css,pdf,converter
6
6
  Author-email: Simon Sapin <simon.sapin@exyr.org>
7
7
  Maintainer-email: CourtBouillon <contact@courtbouillon.org>
8
- Requires-Python: >=3.9
8
+ Requires-Python: >=3.10
9
9
  Description-Content-Type: text/x-rst
10
10
  Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Intended Audience :: Developers
@@ -14,7 +14,6 @@ Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
- Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
@@ -29,11 +28,11 @@ License-File: LICENSE
29
28
  Requires-Dist: pydyf >=0.11.0
30
29
  Requires-Dist: cffi >=0.6
31
30
  Requires-Dist: tinyhtml5 >=2.0.0b1
32
- Requires-Dist: tinycss2 >=1.4.0
31
+ Requires-Dist: tinycss2 >=1.5.0
33
32
  Requires-Dist: cssselect2 >=0.8.0
34
33
  Requires-Dist: Pyphen >=0.9.1
35
34
  Requires-Dist: Pillow >=9.1.0
36
- Requires-Dist: fonttools[woff] >=4.0.0
35
+ Requires-Dist: fonttools[woff] >=4.59.2
37
36
  Requires-Dist: sphinx ; extra == "doc"
38
37
  Requires-Dist: furo ; extra == "doc"
39
38
  Requires-Dist: pytest ; extra == "test"
@@ -62,7 +61,7 @@ WebKit or Gecko. The CSS layout engine is written in Python, designed for
62
61
  pagination, and meant to be easy to hack on.
63
62
 
64
63
  * Free software: BSD license
65
- * For Python 3.9+, tested on CPython and PyPy
64
+ * For Python 3.10+, tested on CPython and PyPy
66
65
  * Documentation: https://doc.courtbouillon.org/weasyprint
67
66
  * Examples: https://weasyprint.org/#samples
68
67
  * Changelog: https://github.com/Kozea/WeasyPrint/releases
@@ -13,7 +13,7 @@ WebKit or Gecko. The CSS layout engine is written in Python, designed for
13
13
  pagination, and meant to be easy to hack on.
14
14
 
15
15
  * Free software: BSD license
16
- * For Python 3.9+, tested on CPython and PyPy
16
+ * For Python 3.10+, tested on CPython and PyPy
17
17
  * Documentation: https://doc.courtbouillon.org/weasyprint
18
18
  * Examples: https://weasyprint.org/#samples
19
19
  * Changelog: https://github.com/Kozea/WeasyPrint/releases
@@ -182,14 +182,35 @@ specifications.
182
182
  Fonts
183
183
  ~~~~~
184
184
 
185
- WeasyPrint can use any font that Pango can find installed on the system. Fonts
186
- are automatically embedded in PDF files.
185
+ WeasyPrint can use any font that Pango_ can find installed on the system. Fonts are
186
+ automatically embedded in PDF files and are subset by default to only include the glyphs
187
+ used in the PDF. Subsetting is done with hb-subset_ when available on the system,
188
+ or by the slower fontTools_ library as a fallback.
187
189
 
188
- Pango always uses fontconfig to access fonts, even on Windows and macOS. You
190
+ Pango_ always uses Fontconfig_ to access fonts, even on Windows and macOS. You
189
191
  can list the available fonts thanks to the ``fc-list`` command, and know which
190
192
  font is matched by a given pattern thanks to ``fc-match``. Copying a font file
191
193
  into the ``~/.local/share/fonts`` directory is generally enough to install a
192
- new font. WeasyPrint should support the major font formats handled by Harfbuzz.
194
+ new font. WeasyPrint should support the major font formats handled by HarfBuzz_.
195
+
196
+ WeasyPrint follows the Fontconfig_ configuration of the system. This default
197
+ configuration is often useful for many cases: font fallbacks for missing glyphs, aliases
198
+ for standard font families like "serif" or "monospace", colored variants for emojis,
199
+ etc. But some of these default rules can sometimes interfere with CSS rules, and it may
200
+ be interesting to disable them if you need to tweak details about font management.
201
+
202
+ When a Unicode code point is not supported by a font and its fallbacks, the font’s `.notdef glyph`_ is
203
+ displayed instead, and a warning is displayed in logs. Because of the way Pango handles
204
+ this case, the .notdef glyph may be rendered with an incorrect width (advance), but the layout of
205
+ the other glyphs is correct. Text search and selection work as if the glyph was
206
+ available.
207
+
208
+ .. _hb-subset: https://harfbuzz.github.io/harfbuzz-hb-subset.html
209
+ .. _fontTools: https://fonttools.readthedocs.io/en/latest/
210
+ .. _Pango: https://www.pango.org/
211
+ .. _Fontconfig: https://www.freedesktop.org/wiki/Software/fontconfig/
212
+ .. _HarfBuzz: https://harfbuzz.github.io/
213
+ .. _.notdef glyph: https://en.wikipedia.org/wiki/Notdef_glyph
193
214
 
194
215
 
195
216
  CSS
@@ -199,13 +220,7 @@ WeasyPrint supports many of the `CSS specifications`_ written by the W3C. You
199
220
  will find in this chapter a comprehensive list of the specifications or drafts
200
221
  with at least one feature implemented in WeasyPrint.
201
222
 
202
- The results of some of the test suites provided by the W3C are also available
203
- at `test.weasyprint.org`_. This website uses a tool called `WeasySuite`_ that
204
- can be useful if you want to implement new features in WeasyPrint.
205
-
206
223
  .. _CSS specifications: https://www.w3.org/Style/CSS/current-work
207
- .. _test.weasyprint.org: http://test.weasyprint.org/
208
- .. _WeasySuite: https://github.com/Kozea/WeasySuite
209
224
 
210
225
  CSS Level 2 Revision 1
211
226
  ++++++++++++++++++++++
@@ -216,7 +231,6 @@ Test`_.
216
231
 
217
232
  The CSS 2.1 features listed here are **not** supported:
218
233
 
219
- * The `::first-line`_ pseudo-element.
220
234
  * On tables: `visibility: collapse`_.
221
235
  * Minimum and maximum height_ on table-related boxes.
222
236
  * Minimum and maximum width_ and height_ on page-margin boxes.
@@ -228,7 +242,6 @@ The CSS 2.1 features listed here are **not** supported:
228
242
 
229
243
  .. _CSS Level 2 Revision 1: https://www.w3.org/TR/CSS21/
230
244
  .. _Acid2 Test: https://www.webstandards.org/files/acid2/test.html
231
- .. _::first-line: https://www.w3.org/TR/CSS21/selector.html#first-line-pseudo
232
245
  .. _empty-cells: https://www.w3.org/TR/CSS21/tables.html#empty-cells
233
246
  .. _visibility\: collapse: https://www.w3.org/TR/CSS21/tables.html#dynamic-effects
234
247
  .. _width: https://www.w3.org/TR/CSS21/visudet.html#min-max-widths
@@ -237,6 +250,7 @@ The CSS 2.1 features listed here are **not** supported:
237
250
  .. _Bi-directional text: https://www.w3.org/TR/CSS21/visuren.html#direction
238
251
  .. _System colors: https://www.w3.org/TR/CSS21/ui.html#system-colors
239
252
  .. _system fonts: https://www.w3.org/TR/CSS21/fonts.html#propdef-font
253
+ .. _CSS Color Module Level 3: https://www.w3.org/TR/css-color-3/
240
254
 
241
255
  To the best of our knowledge, everything else that applies to the
242
256
  print media **is** supported. Please report a bug if you find this list
@@ -492,20 +506,30 @@ The other features of this module are **not** implemented:
492
506
  .. _user agent stylesheet: https://github.com/Kozea/WeasyPrint/blob/main/weasyprint/css/html5_ua.css
493
507
  .. _Leaders: https://www.w3.org/TR/css-content-3/#leaders
494
508
 
495
- CSS Color Module Level 3
496
- ++++++++++++++++++++++++
509
+ CSS Color Module Level 4 / 5
510
+ ++++++++++++++++++++++++++++
497
511
 
498
- The `CSS Color Module Level 3`_ is a recommendation defining "CSS properties
499
- which allow authors to specify the foreground color and opacity of an
500
- element". Its main goal is to specify how colors are defined, including color
501
- keywords and the ``#rgb``, ``#rrggbb``, ``rgb()``, ``rgba()``, ``hsl()``,
502
- ``hsla()`` syntaxes. Opacity and alpha compositing are also defined in this
503
- document.
512
+ The `CSS Color Module Level 4`_ is a recommendation defining "CSS properties which allow
513
+ authors to specify the foreground color and opacity of the text content of an element".
514
+ Its main goal is to specify how colors are defined, including color keywords and many
515
+ color notations including ``#rgba``, ``rgb()``, ``hsl()``, ``hwb()``, ``lab()``, etc.
516
+ The standard ``color()`` function gives a common way to define colors giving their color
517
+ space. Opacity and alpha compositing are also defined in this document.
504
518
 
505
519
  This recommendation is fully implemented in WeasyPrint, except the deprecated
506
520
  System Colors.
507
521
 
508
- .. _CSS Color Module Level 3: https://www.w3.org/TR/css-color-3/
522
+ The `CSS Color Module Level 5`_ is a working draft adding "color modification functions,
523
+ custom color spaces (ICC profiles), ``contrast-color()``, ``light-dark()`` and
524
+ ``device-cmyk()``" to level 4.
525
+
526
+ WeasyPrint supports the ``light-dark()`` and ``device-cmyk()`` properties, and the
527
+ ``@color-profile`` at-rule.
528
+
529
+ WeasyPrint does **not** support the ``color-mix()`` and ``contrast-color()`` properties.
530
+
531
+ .. _CSS Color Module Level 4: https://www.w3.org/TR/css-color-4/
532
+ .. _CSS Color Module Level 5: https://www.w3.org/TR/css-color-5/
509
533
 
510
534
  CSS Transforms Module Level 1
511
535
  +++++++++++++++++++++++++++++
@@ -2,6 +2,165 @@ Changelog
2
2
  =========
3
3
 
4
4
 
5
+ Version 67.0
6
+ ------------
7
+
8
+ Released on 2025-12-02.
9
+
10
+ Dependencies:
11
+
12
+ * Python 3.10+ is now needed, Python 3.9 is not supported anymore
13
+ * tinycss2 1.5.0+ is now needed
14
+ * fontTools 4.59.2+ is now needed
15
+
16
+ Features:
17
+
18
+ * `#2560 <https://github.com/Kozea/WeasyPrint/pull/2560>`_,
19
+ `#640 <https://github.com/Kozea/WeasyPrint/issues/640>`_,
20
+ `#844 <https://github.com/Kozea/WeasyPrint/issues/844>`_,
21
+ `#1091 <https://github.com/Kozea/WeasyPrint/issues/1091>`_,
22
+ `#2517 <https://github.com/Kozea/WeasyPrint/issues/2517>`_:
23
+ Support CMYK colors, PDF/X, color profiles and light-dark() function
24
+ * `#2558 <https://github.com/Kozea/WeasyPrint/pull/2558>`_,
25
+ `#1175 <https://github.com/Kozea/WeasyPrint/issues/1175>`_:
26
+ Support ::first-line, with financial support from Karte Technology
27
+ * `#2552 <https://github.com/Kozea/WeasyPrint/pull/2552>`_:
28
+ Support CSS layers, with financial support from Code & Co.
29
+ * `#2564 <https://github.com/Kozea/WeasyPrint/pull/2564>`_,
30
+ `#2599 <https://github.com/Kozea/WeasyPrint/pull/2599>`_,
31
+ `#2397 <https://github.com/Kozea/WeasyPrint/issues/2397>`_:
32
+ Allow page breaks in grid rows, with financial support from Ocean Recap
33
+ * `#2568 <https://github.com/Kozea/WeasyPrint/pull/2568>`_,
34
+ `#357 <https://github.com/Kozea/WeasyPrint/issues/357>`_:
35
+ Support calc() and other mathematical functions
36
+ * `#2575 <https://github.com/Kozea/WeasyPrint/pull/2575>`_,
37
+ `#2574 <https://github.com/Kozea/WeasyPrint/issues/2574>`_:
38
+ Support PDF/A-1a, PDF/A-2a and PDF/A-3a
39
+ * `#2611 <https://github.com/Kozea/WeasyPrint/pull/2611>`_,
40
+ `#2573 <https://github.com/Kozea/WeasyPrint/issues/2573>`_:
41
+ Support PDF/A-4e and PDF/A-4f
42
+ * `#2523 <https://github.com/Kozea/WeasyPrint/pull/2523>`_:
43
+ Display tofu for missing glyphs
44
+ * `#2581 <https://github.com/Kozea/WeasyPrint/pull/2581>`_:
45
+ Add option to disable protocols in URL resolution
46
+ * `#2570 <https://github.com/Kozea/WeasyPrint/pull/2570>`_:
47
+ Support rch, cap, rcap, rex, ic and ric font-relative units
48
+ * `#2547 <https://github.com/Kozea/WeasyPrint/pull/2547>`_,
49
+ `#2140 <https://github.com/Kozea/WeasyPrint/issues/2140>`_:
50
+ Support "only" keyword in media queries
51
+
52
+ Bug fixes:
53
+
54
+ * `#2516 <https://github.com/Kozea/WeasyPrint/pull/2516>`_,
55
+ `#1510 <https://github.com/Kozea/WeasyPrint/issues/1510>`_:
56
+ Fix rendering of first line of text with nested right float
57
+ * `#2510 <https://github.com/Kozea/WeasyPrint/pull/2510>`_,
58
+ `#1073 <https://github.com/Kozea/WeasyPrint/issues/1073>`_,
59
+ `#2507 <https://github.com/Kozea/WeasyPrint/issues/2507>`_:
60
+ Avoid Pango crashes and font mismatches with @font-face rules referencing local fonts
61
+ * `#2532 <https://github.com/Kozea/WeasyPrint/pull/2532>`_,
62
+ `#2531 <https://github.com/Kozea/WeasyPrint/issues/2531>`_:
63
+ Use fonttools instancer instead of deprecated mutator API
64
+ * `#2541 <https://github.com/Kozea/WeasyPrint/pull/2541>`_:
65
+ Fix syntax of functions
66
+ * `#2543 <https://github.com/Kozea/WeasyPrint/pull/2543>`_:
67
+ Allow font-related units to access @font-face fonts
68
+ * `#2525 <https://github.com/Kozea/WeasyPrint/pull/2525>`_:
69
+ Respect top margins and avoid overlapping footnotes for columns, with financial support from Code & Co.
70
+ * `#2536 <https://github.com/Kozea/WeasyPrint/pull/2536>`_:
71
+ Remove Subtype key from font descriptor
72
+ * `#2539 <https://github.com/Kozea/WeasyPrint/pull/2539>`_:
73
+ Fix min width for SVGs with intrinsic ratio but no intrinsic size
74
+ * `#2537 <https://github.com/Kozea/WeasyPrint/pull/2537>`_,
75
+ `#2533 <https://github.com/Kozea/WeasyPrint/issues/2533>`_:
76
+ Fix order of operators when drawing SVGs
77
+ * `#2538 <https://github.com/Kozea/WeasyPrint/pull/2538>`_:
78
+ Don’t crash with nested unknown functions
79
+ * `#2542 <https://github.com/Kozea/WeasyPrint/pull/2542>`_:
80
+ Don’t crash when lh and rlh are used for line height or font size
81
+ * `#2540 <https://github.com/Kozea/WeasyPrint/pull/2540>`_,
82
+ `#2528 <https://github.com/Kozea/WeasyPrint/issues/2528>`_:
83
+ Use locale encoding instead of filesystem encoding for font paths
84
+ * `#2563 <https://github.com/Kozea/WeasyPrint/pull/2563>`_,
85
+ `#2479 <https://github.com/Kozea/WeasyPrint/issues/2479>`_:
86
+ Don’t avoid float collisions for atomic flex items
87
+ * `#2569 <https://github.com/Kozea/WeasyPrint/pull/2569>`_:
88
+ Don’t be case-sensitive for units
89
+ * `#2567 <https://github.com/Kozea/WeasyPrint/pull/2567>`_,
90
+ `#2566 <https://github.com/Kozea/WeasyPrint/issues/2566>`_:
91
+ Add x-default attribute for metadata description to be compliant with PDF/A
92
+ * `#2586 <https://github.com/Kozea/WeasyPrint/pull/2586>`_,
93
+ `#2571 <https://github.com/Kozea/WeasyPrint/issues/2571>`_:
94
+ Improve formatting contexts management
95
+ * `#2600 <https://github.com/Kozea/WeasyPrint/pull/2600>`_:
96
+ Fix SVG image aspect ratio when only width or height is specified
97
+ * `#2612 <https://github.com/Kozea/WeasyPrint/pull/2612>`_,
98
+ `#2595 <https://github.com/Kozea/WeasyPrint/pull/2595>`_:
99
+ Clean block layout and fix corner cases
100
+ * `#2522 <https://github.com/Kozea/WeasyPrint/issues/2522>`_:
101
+ Ignore preserveAspectRatio when SVG has no viewBox
102
+ * `#2544 <https://github.com/Kozea/WeasyPrint/issues/2544>`_:
103
+ Allow to use a variable twice in a function
104
+ * `#2555 <https://github.com/Kozea/WeasyPrint/issues/2555>`_:
105
+ Fix flex gap in right-to-left context
106
+ * `#2591 <https://github.com/Kozea/WeasyPrint/issues/2591>`_:
107
+ Respect non-auto widths and fix padding of grid items
108
+ * `#2601 <https://github.com/Kozea/WeasyPrint/issues/2601>`_:
109
+ Don’t crash when tagged tables are not displayed as tables
110
+ * `#2607 <https://github.com/Kozea/WeasyPrint/issues/2607>`_:
111
+ Fix rendering of multiline textareas with PDF forms
112
+ * `#2106 <https://github.com/Kozea/WeasyPrint/issues/2106>`_:
113
+ Force variable initialization to avoid crashes during column layout
114
+ * `#2618 <https://github.com/Kozea/WeasyPrint/pull/2618>`_,
115
+ `#2617 <https://github.com/Kozea/WeasyPrint/issues/2617>`_:
116
+ Fix rendering of relative grid and flex items
117
+
118
+ Documentation:
119
+
120
+ * `#2535 <https://github.com/Kozea/WeasyPrint/pull/2535>`_:
121
+ `#2534 <https://github.com/Kozea/WeasyPrint/issues/2534>`_:
122
+ Removed reference to defunct site
123
+
124
+ Contributors:
125
+
126
+ * Guillaume Ayoub
127
+ * Fazle Rabbi Ferdaus
128
+ * Lucie Anglade
129
+ * Luca Vercelli
130
+ * ChickenF622
131
+ * Ernie Chu
132
+ * Mark Pullin
133
+ * Malte Laukötter
134
+ * Markus Mohanty
135
+ * Yvonne Kothmeier
136
+ * Jarom Ort
137
+ * kuypan
138
+
139
+ Backers and sponsors:
140
+
141
+ * Spacinov
142
+ * Syslifters
143
+ * Kobalt
144
+ * Simon Sapin
145
+ * Grip Angebotssoftware
146
+ * Manuel Barkhau
147
+ * Simonsoft
148
+ * KontextWork
149
+ * Menutech
150
+ * TrainingSparkle
151
+ * Healthchecks.io
152
+ * Method B
153
+ * FieldHub
154
+ * Hammerbacher
155
+ * Yanal-Yves Fargialla
156
+ * Morntag
157
+ * Piloterr
158
+ * Xavid
159
+ * Charlie S.
160
+ * Prothesis Dental Solutions
161
+ * Kai DeLorenzo
162
+
163
+
5
164
  Version 66.0
6
165
  ------------
7
166
 
@@ -158,6 +158,32 @@ also used to define the order of the PDF content.
158
158
  Some information is required in your HTML file, including a ``<title>`` tag,
159
159
  and a ``lang`` attribute set on the ``<html>`` tag.
160
160
 
161
+ PDF/X (Graphics Exchange)
162
+ .........................
163
+
164
+ PDF/X documents facilitate graphics exchange and adds printing-related requirements such
165
+ as color profiles.
166
+
167
+ The easiest way to fulfill these requirements is to use device-dependent CMYK colors and
168
+ images everywhere in your document. For colors, you can use the ``device-cmyk()``
169
+ function:
170
+
171
+ .. code-block:: css
172
+
173
+ body { color: device-cmyk(0% 10% 0% 80%) }
174
+
175
+ You also have to define the output profile color to use.
176
+
177
+ .. code-block:: css
178
+
179
+ @color-profile device-cmyk {
180
+ components: cyan, magenta, yellow, black;
181
+ src: url(path/to/cmyk-profile.icc);
182
+ }
183
+
184
+ If possible, PDF/X-4 should be preferred: it allows transparency layers that are
185
+ forbidden by previous variants.
186
+
161
187
  Factur-X / ZUGFeRD (Electronic Invoices)
162
188
  ........................................
163
189
 
@@ -9,16 +9,16 @@ Installation
9
9
 
10
10
  WeasyPrint |version| depends on:
11
11
 
12
- * Python_ ≥ 3.9.0
12
+ * Python_ ≥ 3.10.0
13
13
  * Pango_ ≥ 1.44.0
14
- * pydyf_ ≥ 0.10.0
14
+ * pydyf_ ≥ 0.11.0
15
15
  * CFFI_ ≥ 0.6
16
16
  * tinyhtml5_ ≥ 2.0.0b1
17
- * tinycss2_ ≥ 1.3.0
17
+ * tinycss2_ ≥ 1.5.0
18
18
  * cssselect2_ ≥ 0.8.0
19
19
  * Pyphen_ ≥ 0.9.1
20
20
  * Pillow_ ≥ 9.1.0
21
- * fontTools_ ≥ 4.0.0
21
+ * fontTools_ ≥ 4.59.2
22
22
 
23
23
  .. _Python: https://www.python.org/
24
24
  .. _Pango: https://pango.gnome.org/
@@ -8,18 +8,18 @@ description = 'The Awesome Document Factory'
8
8
  keywords = ['html', 'css', 'pdf', 'converter']
9
9
  authors = [{name = 'Simon Sapin', email = 'simon.sapin@exyr.org'}]
10
10
  maintainers = [{name = 'CourtBouillon', email = 'contact@courtbouillon.org'}]
11
- requires-python = '>=3.9'
11
+ requires-python = '>=3.10'
12
12
  readme = {file = 'README.rst', content-type = 'text/x-rst'}
13
13
  license = {file = 'LICENSE'}
14
14
  dependencies = [
15
15
  'pydyf >=0.11.0',
16
16
  'cffi >=0.6',
17
17
  'tinyhtml5 >=2.0.0b1',
18
- 'tinycss2 >=1.4.0',
18
+ 'tinycss2 >=1.5.0',
19
19
  'cssselect2 >=0.8.0',
20
20
  'Pyphen >=0.9.1',
21
21
  'Pillow >=9.1.0',
22
- 'fonttools[woff] >=4.0.0',
22
+ 'fonttools[woff] >=4.59.2',
23
23
  ]
24
24
  classifiers = [
25
25
  'Development Status :: 5 - Production/Stable',
@@ -29,7 +29,6 @@ classifiers = [
29
29
  'Programming Language :: Python',
30
30
  'Programming Language :: Python :: 3',
31
31
  'Programming Language :: Python :: 3 :: Only',
32
- 'Programming Language :: Python :: 3.9',
33
32
  'Programming Language :: Python :: 3.10',
34
33
  'Programming Language :: Python :: 3.11',
35
34
  'Programming Language :: Python :: 3.12',
@@ -69,5 +68,5 @@ include = ['tests/*', 'weasyprint/*']
69
68
  exclude_lines = ['pragma: no cover', 'def __repr__', 'raise NotImplementedError']
70
69
 
71
70
  [tool.ruff.lint]
72
- select = ['E', 'W', 'F', 'I', 'N', 'RUF']
73
- ignore = ['RUF001', 'RUF002', 'RUF003']
71
+ select = ['E', 'W', 'F', 'I', 'N', 'RUF', 'T20', 'PIE', 'PT', 'RSE', 'UP']
72
+ ignore = ['E226', 'RUF001', 'RUF002', 'RUF003', 'RUF039', 'RUF059', 'UP031']
@@ -31,8 +31,8 @@ def document_write_png(document, target=None, resolution=96, antialiasing=1,
31
31
  command = (
32
32
  'gs', '-q', '-sDEVICE=png16m', f'-dTextAlphaBits={antialiasing}',
33
33
  f'-dGraphicsAlphaBits={antialiasing}', '-dBATCH', '-dNOPAUSE',
34
- '-dPDFSTOPONERROR', f'-r{resolution / zoom}', '-sOutputFile=-',
35
- pdf.name)
34
+ '-dPDFSTOPONERROR', f'-r{resolution / zoom}', '-dUsePDFX3Profile',
35
+ '-sOutputFile=-', pdf.name)
36
36
  pngs = run(command, stdout=PIPE).stdout
37
37
  os.remove(pdf.name)
38
38
 
@@ -1,5 +1,7 @@
1
1
  """Test the CSS parsing, cascade, inherited and computed values."""
2
2
 
3
+ from math import isclose
4
+
3
5
  import pytest
4
6
 
5
7
  from weasyprint import CSS, default_url_fetcher
@@ -16,7 +18,8 @@ def test_find_stylesheets():
16
18
 
17
19
  sheets = list(find_stylesheets(
18
20
  html.wrapper_element, 'print', default_url_fetcher, html.base_url,
19
- font_config=None, counter_style=None, page_rules=None))
21
+ font_config=None, counter_style=None, color_profiles=None, page_rules=None,
22
+ layers=None))
20
23
  assert len(sheets) == 2
21
24
  # Also test that stylesheets are in tree order.
22
25
  sheet_names = [
@@ -163,7 +166,7 @@ def test_important():
163
166
 
164
167
 
165
168
  @assert_no_logs
166
- @pytest.mark.parametrize('value, width', (
169
+ @pytest.mark.parametrize(('value', 'width'), [
167
170
  ('96px', 96),
168
171
  ('1in', 96),
169
172
  ('72pt', 96),
@@ -173,29 +176,50 @@ def test_important():
173
176
  ('101.6q', 96),
174
177
  ('1.1em', 11),
175
178
  ('1.1rem', 17.6),
176
- # TODO: ch and ex units don't work with font-face, see computed_values.py.
177
- # ('1.1ch', 11),
178
- # ('1.5ex', 12),
179
- # ('1.1lh', 13.2),
180
- # ('1.1rlh', 17.6),
181
- ))
179
+ ('1.1ch', 11),
180
+ ('1.1rch', 17.6),
181
+ ('1.1cap', 11),
182
+ ('1.1rcap', 17.6),
183
+ ('1.5ex', 12),
184
+ ('2rex', 25.6),
185
+ ('1ic', 20),
186
+ ('1ric', 32),
187
+ ('1.1lh', 13.2),
188
+ ('1.1rlh', 26.4),
189
+ ])
182
190
  def test_units(value, width):
183
191
  document = FakeHTML(base_url=BASE_URL, string='''
184
192
  <html style="font: 16px / 1.5 weasyprint">
185
193
  <body style="font: 10px / 1.2 weasyprint">
186
- <p style="margin-left: %s"></p>''' % value)
194
+ <p style="margin-left: %s"></p>
195
+ <p style="margin-left: %s"></p>
196
+ ''' % (value, value.upper()))
187
197
  page, = document.render().pages
188
198
  html, = page._page_box.children
189
199
  body, = html.children
190
- p, = body.children
191
- assert p.margin_left == width
200
+ p1, p2 = body.children
201
+ assert p1.margin_left == p2.margin_left
202
+ assert isclose(p1.margin_left, width, rel_tol=0.01)
203
+
204
+
205
+ @assert_no_logs
206
+ @pytest.mark.parametrize('property', ['line-height', 'font-size'])
207
+ def test_recursive_lh(property):
208
+ document = FakeHTML(base_url=BASE_URL, string='''
209
+ <html style="%s: 1lh">
210
+ <body style="%s: 1rlh">a''' % (property, property))
211
+ document.render().pages
212
+ document = FakeHTML(base_url=BASE_URL, string='''
213
+ <html style="%s: 1rlh">
214
+ <body style="%s: 1lh">a''' % (property, property))
215
+ document.render().pages
192
216
 
193
217
 
194
- @pytest.mark.parametrize('media, width, warning', (
218
+ @pytest.mark.parametrize(('media', 'width', 'warning'), [
195
219
  ('@media screen { @page { size: 10px } }', 20, False),
196
220
  ('@media print { @page { size: 10px } }', 10, False),
197
221
  ('@media ("unknown content") { @page { size: 10px } }', 20, True),
198
- ))
222
+ ])
199
223
  def test_media_queries(media, width, warning):
200
224
  document = FakeHTML(string='<p>a<span>b')
201
225
  with capture_logs() as logs:
@@ -461,14 +461,14 @@ def test_counter_styles_11():
461
461
 
462
462
 
463
463
  @assert_no_logs
464
- @pytest.mark.parametrize('arguments, values', (
464
+ @pytest.mark.parametrize(('arguments', 'values'), [
465
465
  ('cyclic "a" "b" "c"', ('a ', 'b ', 'c ', 'a ')),
466
466
  ('symbolic "a" "b"', ('a ', 'b ', 'aa ', 'bb ')),
467
467
  ('"a" "b"', ('a ', 'b ', 'aa ', 'bb ')),
468
468
  ('alphabetic "a" "b"', ('a ', 'b ', 'aa ', 'ab ')),
469
469
  ('fixed "a" "b"', ('a ', 'b ', '3 ', '4 ')),
470
470
  ('numeric "0" "1" "2"', ('1 ', '2 ', '10 ', '11 ')),
471
- ))
471
+ ])
472
472
  def test_counter_symbols(arguments, values):
473
473
  page, = render_pages('''
474
474
  <style>
@@ -492,10 +492,10 @@ def test_counter_symbols(arguments, values):
492
492
 
493
493
 
494
494
  @assert_no_logs
495
- @pytest.mark.parametrize('style_type, values', (
495
+ @pytest.mark.parametrize(('style_type', 'values'), [
496
496
  ('decimal', ('1. ', '2. ', '3. ', '4. ')),
497
497
  ('"/"', ('/', '/', '/', '/')),
498
- ))
498
+ ])
499
499
  def test_list_style_types(style_type, values):
500
500
  page, = render_pages('''
501
501
  <style>
@@ -136,7 +136,7 @@ def test_font_face_bad_2():
136
136
  with capture_logs() as logs:
137
137
  preprocess_stylesheet(
138
138
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
139
- None, None)
139
+ None, None, None, None)
140
140
  assert logs == [
141
141
  "WARNING: Missing src descriptor in '@font-face' rule at 1:1"]
142
142
 
@@ -146,7 +146,7 @@ def test_font_face_bad_3():
146
146
  with capture_logs() as logs:
147
147
  preprocess_stylesheet(
148
148
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
149
- None, None)
149
+ None, None, None, None)
150
150
  assert logs == [
151
151
  "WARNING: Missing font-family descriptor in '@font-face' rule at 1:1"]
152
152
 
@@ -156,7 +156,7 @@ def test_font_face_bad_4():
156
156
  with capture_logs() as logs:
157
157
  preprocess_stylesheet(
158
158
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
159
- None, None)
159
+ None, None, None, None)
160
160
  assert logs == [
161
161
  "WARNING: Missing src descriptor in '@font-face' rule at 1:1"]
162
162
 
@@ -167,7 +167,7 @@ def test_font_face_bad_5():
167
167
  with capture_logs() as logs:
168
168
  preprocess_stylesheet(
169
169
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
170
- None, None)
170
+ None, None, None, None)
171
171
  assert logs == [
172
172
  'WARNING: Ignored `src: wrong ` at 1:33, invalid value.',
173
173
  "WARNING: Missing src descriptor in '@font-face' rule at 1:1"]
@@ -179,7 +179,7 @@ def test_font_face_bad_6():
179
179
  with capture_logs() as logs:
180
180
  preprocess_stylesheet(
181
181
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
182
- None, None)
182
+ None, None, None, None)
183
183
  assert logs == [
184
184
  'WARNING: Ignored `font-family: good, bad` at 1:14, invalid value.',
185
185
  "WARNING: Missing font-family descriptor in '@font-face' rule at 1:1"]
@@ -191,23 +191,23 @@ def test_font_face_bad_7():
191
191
  with capture_logs() as logs:
192
192
  preprocess_stylesheet(
193
193
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
194
- None, None)
194
+ None, None, None, None)
195
195
  assert logs == [
196
196
  'WARNING: Ignored `font-family: good, bad` at 1:14, invalid value.',
197
197
  'WARNING: Ignored `src: really bad ` at 1:38, invalid value.',
198
198
  "WARNING: Missing src descriptor in '@font-face' rule at 1:1"]
199
199
 
200
200
 
201
- @pytest.mark.parametrize('rule', (
201
+ @pytest.mark.parametrize('rule', [
202
202
  '@counter-style test {system: alphabetic; symbols: a}',
203
203
  '@counter-style test {system: cyclic}',
204
204
  '@counter-style test {system: additive; additive-symbols: a 1}',
205
205
  '@counter-style test {system: additive; additive-symbols: 10 x, 1 i, 5 v}',
206
- ))
206
+ ])
207
207
  def test_counter_style_invalid(rule):
208
208
  stylesheet = tinycss2.parse_stylesheet(rule)
209
209
  with capture_logs() as logs:
210
210
  preprocess_stylesheet(
211
211
  'print', 'https://wp.org/foo/', stylesheet, None, None, None,
212
- None, {})
212
+ None, None, None, {})
213
213
  assert len(logs) >= 1