Skip to content

body_offset is inflated by one when a directive has an option block **and** its body ends in blank line(s) #1177

Description

@chrisjsewell

Thanks for this: the document-relative content_offset is exactly the contract I was missing.

One adjacent bug this PR doesn't cover, in case you'd like to fold it in while you're in here: body_offset is inflated by one when a directive has an option block and its body ends in blank line(s). It's independent of the relative-to-absolute reframe: it lives in the len(content.splitlines()) - len(body_lines) line, which this PR leaves unchanged, so it persists on this branch.

See:

from docutils.parsers.rst.directives.admonitions import Note
from myst_parser.parsers.directives import parse_directive_text

parse_directive_text(Note, "", ":class: tip\nbody").body_offset        # 1  (correct)
parse_directive_text(Note, "", ":class: tip\nbody\n\n\n").body_offset  # 2  (should be 1)
# YAML-style option block inflates the same way: 3 -> 4

Root cause: body_lines comes back from _parse_directive_options through a "\n".join(...) round-trip that drops exactly one trailing blank line, so when the body ends in blank line(s) the subtraction over-counts the option block by one. Every body element is then reported one source line too low.

Originally posted by @kdeldycke in #1175 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions