Skip to content

Commit

Permalink
HTML headings relative sizes can now be configured through an optiona…
Browse files Browse the repository at this point in the history
…l `heading_sizes` parameter (#237)
  • Loading branch information
Lucas-C authored Sep 28, 2021
1 parent 3c1a68a commit fb9af3d
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 23 deletions.
28 changes: 13 additions & 15 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,44 @@ and [PEP 440](https://www.python.org/dev/peps/pep-0440/).
### Added
- markdown support in `multi_cell()`, thanks to Yeshi Namkhai
- base 64 images can now be provided to `FPDF.image`, thanks to @MWhatsUp
- documentation on how to generate datamatrix barcodes using the `pystrich` lib: [documentation section](https://pyfpdf.github.io/fpdf2/Barcodes.html#datamatrix), thanks to @MWhatsUp
- documentation on how to generate datamatrix barcodes using the `pystrich` lib: [documentation section](https://pyfpdf.github.io/fpdf2/Barcodes.html#datamatrix),
thanks to @MWhatsUp
- `write_html`: headings (`<h1>`, `<h2>`...) relative sizes can now be configured through an optional `heading_sizes` parameter
### Fixed
- line height of HTML headings (`<h1>`, `<h2>`...) that were not scaled properly with the font size
- HTML headings (`<h1>`, `<h2>`...) can now contain non-ASCII characters without triggering a `UnicodeEncodeError`
- when using `Template`, CSV column types are now safely parsed, thanks to @gmischler
- `write_html`: headings (`<h1>`, `<h2>`...) can now contain non-ASCII characters without triggering a `UnicodeEncodeError`
- `Template`: CSV column types are now safely parsed, thanks to @gmischler
### Changed
- some `FPDF` should not be used inside a `rotation` context, or things can get broken.
This is now forbidden: an exception is raised in case there is such risk.
- `write_html`: the line height of headings (`<h1>`, `<h2>`...) 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:/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:/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)

## [2.4.2] - 2021-06-29
### 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)

Expand All @@ -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)
Expand All @@ -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 `<img>` inside `<td>` & allowing to center them horizontally
- `write_html`: properly handling `<img>` inside `<td>` & allowing to center them horizontally

## [2.3.2] - 2021-03-27
### Added
Expand Down Expand Up @@ -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
Expand Down
16 changes: 10 additions & 6 deletions fpdf/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -198,6 +199,7 @@ def __init__(
li_tag_indent=5,
table_line_separators=False,
ul_bullet_char=BULLET_WIN1252,
heading_sizes=None,
**_,
):
"""
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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":
Expand Down Expand Up @@ -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()
Expand Down
Binary file added test/html/html_custom_heading_sizes.pdf
Binary file not shown.
Binary file modified test/html/html_headings_line_height.pdf
Binary file not shown.
18 changes: 16 additions & 2 deletions test/html/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,21 @@ def test_html_headings_line_height(tmp_path): # issue-223
<h4>H4 {long_title*3}</h4>
<h5>H5 {long_title*3}</h5>
<h6>H6 {long_title*4}</h6>
<p>P {long_title*5}<p>
"""
<p>P {long_title*5}<p>"""
)
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(
"""<h1>This is a H1</h1>
<h2>This is a H2</h2>
<h3>This is a H3</h3>
<h4>This is a H4</h4>
<h5>This is a H5</h5>
<h6>This is a H6</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)

0 comments on commit fb9af3d

Please sign in to comment.