Skip to content

Preserve leading spaces on new lines in <pre> blocks#1866

Merged
andersonhc merged 2 commits into
py-pdf:masterfrom
eugen-goebel:fix/issue-1063-pre-leading-spaces
Jun 17, 2026
Merged

Preserve leading spaces on new lines in <pre> blocks#1866
andersonhc merged 2 commits into
py-pdf:masterfrom
eugen-goebel:fix/issue-1063-pre-leading-spaces

Conversation

@eugen-goebel

Copy link
Copy Markdown

Fixes #1063.

Leading spaces on new lines inside <pre> and <pre><code> blocks were dropped. The root cause is that Paragraph and ParagraphCollectorMixin.paragraph() had skip_leading_spaces defaulting to False, and the effective value was computed as skip_leading_spaces or self._region.skip_leading_spaces. Since the HTML parser creates its text region with skip_leading_spaces=True, an explicitly passed False was always swallowed by the or.

Following @gmischler's plan from the issue thread:

  • In fpdf/text_region.py the default is now None in both Paragraph.__init__ and paragraph(), and an explicit True or False always wins over the region default. The value is resolved once when the paragraph is constructed, and build_lines() and the bullet renderer use the paragraph's own value instead of falling back to the region again. This is the part @dmail00 pointed out was still missing.
  • In fpdf/html.py _new_paragraph() now passes skip_leading_spaces=not self._pre_formatted, so preformatted blocks keep their leading whitespace while every other block behaves exactly as before.

I added a regression test in test/html/ based on the minimal example from the issue. The existing test_html_whitespace_handling reference is unchanged, since its <pre> lines have no leading spaces.

Checklist:

  • A unit test is covering the code added / modified by this PR
  • In case of a new feature, docstrings have been added, with also some documentation in the docs/ folder — N/A (bugfix)
  • A mention of the change is present in CHANGELOG.md
  • This PR is ready to be merged

By submitting this pull request, I confirm that my contribution is made under the terms of the GNU LGPL 3.0 license.

Fixes py-pdf#1063.

The skip_leading_spaces default of Paragraph and
ParagraphCollectorMixin.paragraph() was False, so an explicitly passed
False got swallowed by the `or self._region.skip_leading_spaces`
fallback whenever the region had skip_leading_spaces=True, which is how
the HTML parser configures it. As a result, leading whitespace inside
<pre> and <pre><code> blocks was dropped.

The default is now None, and an explicit True or False always wins over
the region default, resolved once when the paragraph is constructed.
build_lines() and the bullet renderer use the paragraph's own resolved
value instead of falling back to the region again.

In html.py, _new_paragraph() now passes
skip_leading_spaces=not self._pre_formatted, so preformatted blocks keep
their leading whitespace while normal blocks behave as before.

A regression test based on the issue's minimal example is added in
test/html/.

@andersonhc andersonhc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution.
I don't have any comment - the PR should be ready to be merged as soon as I fix the problems with the github actions workflow.

@andersonhc andersonhc merged commit d7006ed into py-pdf:master Jun 17, 2026
23 checks passed
@andersonhc

Copy link
Copy Markdown
Collaborator

@allcontributors please add @eugen-goebel for code

@allcontributors

Copy link
Copy Markdown

@andersonhc

I've put up a pull request to add @eugen-goebel! 🎉

@andersonhc

Copy link
Copy Markdown
Collaborator

Merged. Thank you @eugen-goebel

@eugen-goebel

Copy link
Copy Markdown
Author

Thanks a lot for the review and the quick merge, and for adding me to the contributors list. This was my first contribution here and it was a really good experience. I will keep an eye out for more issues I can help with.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Leading spaces on new lines ignored in <pre><code> tags

2 participants