`...) is now properly scaled with its font size
+- some `FPDF` methods should not be used inside a `rotation` context, or things can get broken.
+ This is now forbidden: an exception is now raised in those cases.
## [2.4.3] - 2021-09-01
### Added
-- support for **emojis**! Me precisely unicode characters above `0xFFFF` in general, thanks to @moe-25
+- support for **emojis**! More precisely unicode characters above `0xFFFF` in general, thanks to @moe-25
- `Template` can now insert justified text
- [`get_scale_factor`](https://pyfpdf.github.io/fpdf2/fpdf/util.html#fpdf.util.get_scale_factor) utility function to obtain `FPDF.k` without having to create a document
- [`convert_unit`](https://pyfpdf.github.io/fpdf2/fpdf/util.html#fpdf.util.convert_unit) utility function to convert a number, `x,y` point, or list of `x,y` points from one unit to another unit
-
### Changed
- `fpdf.FPDF()` constructor now accepts ints or floats as a unit, and raises a `ValueError` if an invalid unit is provided.
-
### Fixed
- `Template` `background` property is now properly supported - [#203](https://github.com/PyFPDF/fpdf2/pull/203)
⚠️ Beware that its default value changed from `0` to `0xffffff`, as a value of **zero would render the background as black**.
- `Template.parse_csv`: preserving numeric values when using CSV based templates - [#205](https://github.com/PyFPDF/fpdf2/pull/205)
- the code snippet to generate Code 39 barcodes in the documentation was missing the start & end `*` characters.
This has been fixed, and a warning is now triggered by the [`FPDF.code39`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.code39) method when those characters are missing.
-
### Fixed
- Detect missing `uni=True` when loading cached fonts (page numbering was missing digits)
@@ -44,13 +43,12 @@ This has been fixed, and a warning is now triggered by the [`FPDF.code39`](https
### Added
- disable font caching when `fpdf.FPDF` constructor invoked with `font_cache_dir=None`, thanks to @moe-25 !
- [`FPDF.circle`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.circle): new method added, thanks to @viraj-shah18 !
-- `HTMLMixin` / `HTML2FPDF`: support setting HTML font colors by name and short hex codes
+- `write_html`: support setting HTML font colors by name and short hex codes
- [`FPDF.will_page_break`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.will_page_break)
utility method to let users know in advance when adding an elemnt will trigger a page break.
This can be useful to repeat table headers on each page for exemple,
_cf._ [documentation on Tables](https://pyfpdf.github.io/fpdf2/Tables.html#repeat-table-header-on-each-page).
- [`FPDF.set_link`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_link) now support a new optional `x` parameter to set the horizontal position after following the link
-
### Fixed
- fixed a bug when `fpdf.Template` was used to render QRCodes, due to a forced conversion to string (#175)
@@ -73,7 +71,7 @@ _cf._ [documentation on Tables](https://pyfpdf.github.io/fpdf2/Tables.html#repea
- `FPDF.cell`: new optional boolean `center` parameter that positions the cell horizontally
- `FPDF.set_link`: new optional `zoom` parameter that sets the zoom level after following the link.
Currently ignored by Sumatra PDF Reader, but observed by Adobe Acrobat reader.
-- `HTMLMixin` / `HTML2FPDF`: now support `align="justify"`
+- `write_html`: now support `align="justify"`
- new method `FPDF.image_filter` to control the image filters used for images
- `FPDF.add_page`: new optional `duration` & `transition` parameters
used for [presentations (documentation page)](https://pyfpdf.github.io/fpdf2/Presentations.html)
@@ -100,7 +98,7 @@ _cf._ [documentation on Tables](https://pyfpdf.github.io/fpdf2/Tables.html#repea
- new method `FPDF.text_annotation` to insert... Text Annotations
- `FPDF.image` now also accepts an `io.BytesIO` as input
### Fixed
-- `HTMLMixin` / `HTML2FPDF`: properly handling `` inside `` & allowing to center them horizontally
+- `write_html`: properly handling `` inside ` | ` & allowing to center them horizontally
## [2.3.2] - 2021-03-27
### Added
@@ -146,7 +144,7 @@ prevented strings passed first to the text-rendering methods to be displayed.
## [2.2.0] - 2021-01-11
### Added
- new unit tests, a code formatter (`black`) and a linter (`pylint`) to improve code quality
-- new boolean parameter `table_line_separators` for `HTMLMixin.write_html` & underlying `HTML2FPDF` constructor
+- new boolean parameter `table_line_separators` for `write_html` & underlying `HTML2FPDF` constructor
### Changed
- the documentation URL is now simply https://pyfpdf.github.io/fpdf2/
### Removed
diff --git a/fpdf/html.py b/fpdf/html.py
index 20bf3542f..2af98e903 100644
--- a/fpdf/html.py
+++ b/fpdf/html.py
@@ -12,6 +12,7 @@
LOGGER = logging.getLogger(__name__)
BULLET_WIN1252 = "\x95" # BULLET character in Windows-1252 encoding
+DEFAULT_HEADING_SIZES = dict(h1=2, h2=1.5, h3=1.17, h4=1, h5=0.83, h6=0.67)
COLOR_DICT = {
"black": "#000000",
@@ -198,6 +199,7 @@ def __init__(
li_tag_indent=5,
table_line_separators=False,
ul_bullet_char=BULLET_WIN1252,
+ heading_sizes=None,
**_,
):
"""
@@ -239,7 +241,9 @@ def __init__(
self.theader_out = self.tfooter_out = False
self.table_row_height = 0
self.heading_level = None
- self.hsize = dict(h1=2, h2=1.5, h3=1.17, h4=1, h5=0.83, h6=0.67)
+ self.heading_sizes = dict(**DEFAULT_HEADING_SIZES)
+ if heading_sizes:
+ self.heading_sizes.update(heading_sizes)
self._only_imgs_in_td = False
def width2unit(self, length):
@@ -405,12 +409,12 @@ def handle_starttag(self, tag, attrs):
self.pdf.ln(self.h)
if attrs:
self.align = attrs.get("align")
- if tag in self.hsize:
+ if tag in self.heading_sizes:
self.heading_level = int(tag[1:])
- k = self.hsize[tag]
- self.pdf.ln(5 * k)
+ hsize = self.heading_sizes[tag]
+ self.pdf.ln(5 * hsize)
self.pdf.set_text_color(150, 0, 0)
- self.set_font(size=12 * k)
+ self.set_font(size=12 * hsize)
if attrs:
self.align = attrs.get("align")
if tag == "hr":
@@ -552,7 +556,7 @@ def handle_starttag(self, tag, attrs):
def handle_endtag(self, tag):
# Closing tag
LOGGER.debug("ENDTAG %s", tag)
- if tag in self.hsize:
+ if tag in self.heading_sizes:
self.heading_level = None
self.pdf.ln(self.h)
self.set_font()
diff --git a/test/html/html_custom_heading_sizes.pdf b/test/html/html_custom_heading_sizes.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..e4d2b3332dd435a5fa0bbbf76f1c05cac5955c17
GIT binary patch
literal 2006
zcma)7UuYaf7)J#E3>d9G2@OusU@P=yXaC)v#7J`2Yf}?1T(6`y4YIkLT(<1(hTU0{
zQy;`q8o}g2@Ih?_LDAMHp%1MO7ObMa^r6+qh(aEPT0^UE^_$(fyS>{yWI1kUzS;SH
zzxjQCW@M&RK1g#K(y)U4h0|zsl+@bG43inV$q@Vp%;T8CY88$M@v-5xjQajQ+m6e$>7AWb44w8*g7fclrI_ex6yovcCA}
zt+QvD`jB(3{lc@(^UbZzOKqcl?<9F^YyHLt$G`gKxpy!BXbo@7Zmpd8;sU-9Y~0;`
z=kTx2!c#}j+_+`F-nh1xqWA6%pITWX)0>|?xcAk`E4P=Uhd;Sl8~*G5%3ArKXa4>3
z>!CffA78ru(E~$o{P5lFM~)v}`h9wn{_*l-V>8=#=0AUFduZR|7e5t;muHbO2-z~C
zhKRi4G(tQlB(KgRQuHGsF(T8f;n)-YDxOnd$tV~()xwreb5>y<^~5y>y_O*gh)mca
z6C+G&PK$*HtA5M&5IGht@Hn6%tN?PzgAh1g6O&oT8}~w|V@M&0=q9`&0|LK(jBz|i
zAXUIOTLpy47G%eSd>7?=63!A67#)QH#e!#5cqJz)3#VC~V_1M`?<8glr>jEQ2||wZ
z@n$k*_r^(HRwC{?9t%@$#J3%~T{k5LI}?pDIq}*_tmG7IDP~SLu@||nAR8lDDI__T
zSuf~8*4G^FGQ7XG2gW(PeEiy21Z`b<-0NHz{q1~Vaz_5UW
z$R)m=vfF+HYd~YbW@?bh1GfAQ{w!cN_+7ySar*aC#maD@D$QU}P0!kN
zBkRvlQk;2UJ1z_08ivm8yvc-qr0V-{Kg3roB9q>tk7;~&h$a+rJK(X_)KpD0GIFR=
GM*jneM>OF8
literal 0
HcmV?d00001
diff --git a/test/html/html_headings_line_height.pdf b/test/html/html_headings_line_height.pdf
index 24ca3aab55df5485d0d00448d7274c12f526ca5c..66d990926a84bc852f5446f3a68868a8df0d3526 100644
GIT binary patch
delta 339
zcmbO$HbZPe1Eb-@Ml+_qsEIo_%1XSsAnSKQ)6MLu2q)i^Y4>;DZan^;-K5U`O1h`q
zod4_7@s+`Zuh_A4bj2g
zug`aR7)w{Y+Rs>E;li}}J>v~_F#`()0}xQiQ{VzK3=GUHjV9maw5~V7kTJJ3!w|DD
zGe;LQG%z>C5HqsCFwfA$5>uVIsUbwK8Nx|M1_qYs1{xVzU}!cnHZhodmdk^~fJ;@?
I)!&T^02mcrqW}N^
delta 344
zcmbOsHdkyy1Ebl*Ml+^$K@)dwl(o3A(0a~-;GUdQnnE%fy8DZ_Gxy);&-hcf;`}6;
z$?c394vlGt#1F_B3)kP9pgeJ#QE+|kHEBPFRI3V}Et)HN>od4_7@s+`Zuh_A4bj2g
zug`aR7)!sq;@#YGTkk=>4Y#k}=2wh2*u@Nu6%0T?Ay0t|%rG!8voxQ4gVVa+5<|wq
zzz|c++z4IF(7?g~L(Iqm!#qP%puK3e8=9M%LBz}uPBJnuG(lHrWMqk<*~r+$bn*!<
O4-QiH4 {long_title*3}
H5 {long_title*3}
H6 {long_title*4}
- P {long_title*5}
- """
+ P {long_title*5} """
)
assert_pdf_equal(pdf, HERE / "html_headings_line_height.pdf", tmp_path)
+
+
+def test_html_custom_heading_sizes(tmp_path): # issue-223
+ pdf = MyFPDF()
+ pdf.add_page()
+ pdf.write_html(
+ """ This is a H1
+ This is a H2
+ This is a H3
+ This is a H4
+ This is a H5
+ This is a H6""",
+ heading_sizes=dict(h1=0.5, h2=1, h3=1.5, h4=2, h5=2.5, h6=3),
+ )
+ assert_pdf_equal(pdf, HERE / "html_custom_heading_sizes.pdf", tmp_path)
|