Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headings and Title styles #1080

Closed
dmail00 opened this issue Jan 1, 2024 · 5 comments
Closed

Headings and Title styles #1080

dmail00 opened this issue Jan 1, 2024 · 5 comments

Comments

@dmail00
Copy link

dmail00 commented Jan 1, 2024

Describe the bug

When generating documents I use normal mode pdf.write ... and HTML (well it is actually markdown which gets converted by python-markdown yet that is off topic). A problem is that PDF has headings and so does HTML, but in the codebase they are offset of one and you have to specify the sizes in two locations.

The problem happens when you do define TitleStyles and use HTML headings,
Either:

  1. HTML will write its own heading and then another heading will be wrote using the TitleStyle which will then effect all the size of all text that follows. Run the code as is to see this.
  2. If you have defined at least one TitleSytle (say level0) and use a H2 in HTML then you will get a crash, see the comment in the code about the second parameter and see the error trace below.

Error details
X:\foo\bar\baz is a replacement for the real path

Exception has occurred: AttributeError       (note: full exception trace is shown but execution is paused at: _run_module_as_main)
'NoneType' object has no attribute 't_margin'
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\fpdf.py", line 4847, in _use_title_style
    if title_style.t_margin:
       ^^^^^^^^^^^^^^^^^^^^
  File "C:\nProgram Files\Python\Python311\Lib\contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\fpdf.py", line 4820, in start_section
    with pdf._use_title_style(pdf.section_title_styles[level]):
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\fpdf.py", line 217, in wrapper
    return fn(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\html.py", line 421, in _write_data
    self.pdf.start_section(data, self.heading_level - 1, strict=False)
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\html.py", line 413, in handle_data
    self._write_data(data)
  File "C:\nProgram Files\Python\Python311\Lib\html\parser.py", line 162, in goahead
    self.handle_data(unescape(rawdata[i:j]))
  File "C:\nProgram Files\Python\Python311\Lib\html\parser.py", line 110, in feed
    self.goahead(0)
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\html.py", line 737, in feed
    super().feed(data)
  File "X:\foo\bar\baz\.venv311\Lib\site-packages\fpdf\fpdf.py", line 408, in write_html
    html2pdf.feed(text)
  File "X:\foo\bar\baz\fpdf2_test.py", line 342, in defining_headers_normally_and_using_headers_html
    pdf.write_html(
  File "X:\foo\bar\baz\fpdf2_test.py", line 355, in <module>
    defining_headers_normally_and_using_headers_html()
  File "C:\nProgram Files\Python\Python311\Lib\runpy.py", line 88, in _run_code
    exec(code, run_globals)
  File "C:\nProgram Files\Python\Python311\Lib\runpy.py", line 198, in _run_module_as_main (Current frame)
    return _run_code(code, main_globals, None,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 't_margin'

Minimal code

from fpdf import FPDF


pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", "", 10)
level0 = TitleStyle("Helvetica", "B", 20, (0, 0, 0))
# comment out the next code line to see how it should look
# comment out the second parameter to see the crash
pdf.set_section_title_styles(level0, level0)
pdf.write(text="This is size 10")
pdf.ln()
pdf.write_html(
    """
<h1>Heading One</h1>
<p>Just enough text to show how bad the situation really is</p>
<h2>Heading Two</h2>
<p>This will not overflow</p>
<p>Just enough text to show how bad the situation really is</p>
"""
)
pdf.output("headings_hmmm.pdf")

Environment
Please provide the following information:

  • Operating System: Windows
  • Python version: 3.11.3
  • fpdf2 version used: 2.7.7
@Lucas-C
Copy link
Member

Lucas-C commented Jan 2, 2024

Hi @dmail00

Thank you for reporting this 🙂

.set_section_title_styles() was never planned to be used with .write_html().
HTML headings are supposed to be rendered by fpdf.html.HTML2FPDF, not by fpdf.FPDF.start_section().
For now, I will add code to raise an error if both mechanisms are used (cf. PR #1083).

Why did you wish to use both features at the same time?
Was it that you wanted more control hover HTML headings styling?
If so, some thinking on the subject was started in #1066 (review):

Maybe it would make sense to have a single, shared, configuration entry to be able to set a default style for all HTML elements the same way, including their color?

@dmail00
Copy link
Author

dmail00 commented Jan 2, 2024

Was it that you wanted more control hover HTML headings styling?

I already have that,

Some of the text I am rendering is known and has headings, whilst other text comes from files on disk which are not know by the code and can include headings.

You current solution is fine, I have hacks for all the issues I have reported.

@Lucas-C
Copy link
Member

Lucas-C commented Jan 2, 2024

You current solution is fine, I have hacks for all the issues I have reported.

Alright.

If you wish to contribute to fpdf2 and share the solutions you found, you are very welcome 🙂

Otherwise, I will close this issue.

@dmail00
Copy link
Author

dmail00 commented Jan 2, 2024

Well this one seems simple enough.

In write_html cache the section_title_styles and replace with an empty dict, restore the cached vesion on exiting the method.

@Lucas-C
Copy link
Member

Lucas-C commented Jan 15, 2024

If I understand you correctly, I think we can close this issue given that PR #1083 was merged to alert users in the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants