[GH-ISSUE #292] trailing spaces not allowed in code block #247

Closed
opened 2026-03-03 01:25:06 +03:00 by kerem · 9 comments
Owner

Originally created by @PeterConstable on GitHub (May 23, 2020).
Original GitHub issue: https://github.com/DavidAnson/markdownlint/issues/292

I'm encountering this error. I saw issue #190 and that a change was made for that, so I wasn't expecting to get this error—not sure if my case is the same or different.

Inside my .md file, I have a Python code fragment within a code block:

    if kind == "rect":
        l, w = spec  # assign tuple elements
        draw_rect(l, w)
    
    elif kind == "circle":
        draw_circle(spec)

The "blank" line is included for clarity and has four spaces, which are needed to preserve the integrity of the if...else construct as a unit. I don't need the spaces for the page to look right, but if someone copy/pasted the fragment, they'd end up with a syntax error. So, I've kept four spaces in the line. But that's giving me an error.

Is this a different issue than #190? Am I missing something?

Thanks!

Originally created by @PeterConstable on GitHub (May 23, 2020). Original GitHub issue: https://github.com/DavidAnson/markdownlint/issues/292 I'm encountering this error. I saw issue #190 and that a change was made for that, so I wasn't expecting to get this error—not sure if my case is the same or different. Inside my .md file, I have a Python code fragment within a code block: ```python if kind == "rect": l, w = spec # assign tuple elements draw_rect(l, w) elif kind == "circle": draw_circle(spec) ``` The "blank" line is included for clarity and has four spaces, which are needed to preserve the integrity of the ```if```...```else``` construct as a unit. I don't need the spaces for the page to look right, but if someone copy/pasted the fragment, they'd end up with a syntax error. So, I've kept four spaces in the line. But that's giving me an error. Is this a different issue than #190? Am I missing something? Thanks!
kerem 2026-03-03 01:25:06 +03:00
Author
Owner

@DavidAnson commented on GitHub (May 23, 2020):

Yes, it looks like the same scenario. When I try your example, it does not report an issue: https://dlaa.me/markdownlint/#%25m%23%20Issue%20292%0A%0A%20%20%20%20if%20kind%20%3D%3D%20%22rect%22%3A%0A%20%20%20%20%20%20%20%20l%2C%20w%20%3D%20spec%20%20%23%20assign%20tuple%20elements%0A%20%20%20%20%20%20%20%20draw_rect(l%2C%20w)%0A%20%20%20%20%0A%20%20%20%20elif%20kind%20%3D%3D%20%22circle%22%3A%0A%20%20%20%20%20%20%20%20draw_circle(spec)%0A

Could you please double check what version of markdownlint you're using or show how to reproduce the issue (either linking to a file or in the playground above)?

Thanks!

<!-- gh-comment-id:633136865 --> @DavidAnson commented on GitHub (May 23, 2020): Yes, it looks like the same scenario. When I try your example, it does not report an issue: https://dlaa.me/markdownlint/#%25m%23%20Issue%20292%0A%0A%20%20%20%20if%20kind%20%3D%3D%20%22rect%22%3A%0A%20%20%20%20%20%20%20%20l%2C%20w%20%3D%20spec%20%20%23%20assign%20tuple%20elements%0A%20%20%20%20%20%20%20%20draw_rect(l%2C%20w)%0A%20%20%20%20%0A%20%20%20%20elif%20kind%20%3D%3D%20%22circle%22%3A%0A%20%20%20%20%20%20%20%20draw_circle(spec)%0A Could you please double check what version of `markdownlint` you're using or show how to reproduce the issue (either linking to a file or in the playground above)? Thanks!
Author
Owner

@PeterConstable commented on GitHub (May 23, 2020):

I have v 0.35.2. When I use @outdated, in the marketplace search, it tells me I don't have any out-of-date extensions

When I copy/paste from my md file into the playground (replacing what was there), I get three occurrences of the error. Same if I load the entire .md file. I'm not sure how to give you a link to the playground with my file, but you can get it here:
https://github.com/PeterConstable/PythonTutorial/blob/master/9_Sample_Program.md

<!-- gh-comment-id:633143135 --> @PeterConstable commented on GitHub (May 23, 2020): I have v 0.35.2. When I use @outdated, in the marketplace search, it tells me I don't have any out-of-date extensions When I copy/paste from my md file into the playground (replacing what was there), I get three occurrences of the error. Same if I load the entire .md file. I'm not sure how to give you a link to the playground with my file, but you can get it here: https://github.com/PeterConstable/PythonTutorial/blob/master/9_Sample_Program.md
Author
Owner

@DavidAnson commented on GitHub (May 23, 2020):

Your example used indented code blocks, but the file you link to uses code fences. The original change allowed blank lines in indented code so that it wouldn’t be broken up undesirably. That’s not an issue with code fences, so blank lines continue to be reported as a violation there.

Are you sure that Python requires a blank line with exactly four spaces in order to maintain proper syntax? If so, then it would seem that the earlier allowance may need to be made for code fences as well.

<!-- gh-comment-id:633143758 --> @DavidAnson commented on GitHub (May 23, 2020): Your example used indented code blocks, but the file you link to uses code fences. The original change allowed blank lines in indented code so that it wouldn’t be broken up undesirably. That’s not an issue with code fences, so blank lines continue to be reported as a violation there. Are you sure that Python requires a blank line with exactly four spaces in order to maintain proper syntax? If so, then it would seem that the earlier allowance may need to be made for code fences as well.
Author
Owner

@PeterConstable commented on GitHub (May 23, 2020):

Indentation in Python is syntactic. If you leave out indentation spaces, you've changed the construct and can end up with syntax errors.

You can use any amount of indentation. However:

"Use 4 spaces per indentation level."

https://www.python.org/dev/peps/pep-0008/#indentation

<!-- gh-comment-id:633145057 --> @PeterConstable commented on GitHub (May 23, 2020): Indentation in Python is syntactic. If you leave out indentation spaces, you've changed the construct and can end up with syntax errors. You can use any amount of indentation. However: "Use 4 spaces per indentation level." https://www.python.org/dev/peps/pep-0008/#indentation
Author
Owner

@DavidAnson commented on GitHub (May 23, 2020):

I was vaguely aware that Python treats indentation as a structural requirement, but I am surprised that it would require indentation for blank lines.

This section in the document you linked to seems not to mention that for blank lines: https://www.python.org/dev/peps/pep-0008/#blank-lines

And this section explicitly calls out that trailing whitespace is to be avoided everywhere: https://www.python.org/dev/peps/pep-0008/#other-recommendations

Is your example exceptional for some reason? Is that discussed anywhere?

<!-- gh-comment-id:633150463 --> @DavidAnson commented on GitHub (May 23, 2020): I was vaguely aware that Python treats indentation as a structural requirement, but I am surprised that it would require indentation for blank lines. This section in the document you linked to seems not to mention that for blank lines: https://www.python.org/dev/peps/pep-0008/#blank-lines And this section explicitly calls out that trailing whitespace is to be avoided everywhere: https://www.python.org/dev/peps/pep-0008/#other-recommendations Is your example exceptional for some reason? Is that discussed anywhere?
Author
Owner

@PeterConstable commented on GitHub (May 24, 2020):

You don't think that syntactic requirement would supersede an "avoid" recommendation?

Looking at the spec, it's not 100% clear to me what exact syntactic requirements would be. On the one hand, this is relevant:

"In the standard interactive interpreter, an entirely blank logical line (i.e. one containing not even whitespace or a comment) terminates a multi-line statement."

https://docs.python.org/3.8/reference/lexical_analysis.html#blank-lines

The part that's not clear to me is what is considered a multi-line statement. In my case there are 3 errors that involve two specs: functdef and if_stmt. Let's consider the latter:

if_stmt ::=  "if" assignment_expression ":" suite
             ("elif" assignment_expression ":" suite)*
             ["else" ":" suite]

https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-if-stmt

The blank line is occurring within suite.

suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

My understanding is that if_stmt — its full parse — would be considered a multi-line statement. So, without the spaces in the blank line, then the standard interactive interpreter would terminate the statement at that line. And that's exactly what I'm encountering, and the problem I'm trying to avoid.

(In a .py file executed as a script, an entirely blank line doesn't cause this problem.)

<!-- gh-comment-id:633156931 --> @PeterConstable commented on GitHub (May 24, 2020): You don't think that syntactic requirement would supersede an "avoid" recommendation? Looking at the spec, it's not 100% clear to me what exact syntactic requirements would be. On the one hand, this is relevant: "In the standard interactive interpreter, an entirely blank logical line (i.e. one containing not even whitespace or a comment) terminates a multi-line statement." https://docs.python.org/3.8/reference/lexical_analysis.html#blank-lines The part that's not clear to me is what is considered a _multi-line statement_. In my case there are 3 errors that involve two specs: functdef and if_stmt. Let's consider the latter: ``` if_stmt ::= "if" assignment_expression ":" suite ("elif" assignment_expression ":" suite)* ["else" ":" suite] ``` https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-if-stmt The blank line is occurring within ```suite```. ``` suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT statement ::= stmt_list NEWLINE | compound_stmt stmt_list ::= simple_stmt (";" simple_stmt)* [";"] ``` My understanding is that ```if_stmt``` — its full parse — would be considered a multi-line statement. So, without the spaces in the blank line, then the standard interactive interpreter would terminate the statement at that line. And that's exactly what I'm encountering, and the problem I'm trying to avoid. (In a .py file executed as a script, an entirely blank line doesn't cause this problem.)
Author
Owner

@DavidAnson commented on GitHub (May 24, 2020):

Thanks, I’ll look at opting fenced code blocks into the exception.

<!-- gh-comment-id:633162429 --> @DavidAnson commented on GitHub (May 24, 2020): Thanks, I’ll look at opting fenced code blocks into the exception.
Author
Owner

@PeterConstable commented on GitHub (May 24, 2020):

Thanks. Blank line in interactive mode being handled differently than in a script is somewhat motivated: when editing multi-line statements, the console needs some way to detect when end of statement is intended. They could have required entry of a truly empty line (no spaces), but that would have impacted usability in interactive mode. At any rate, for better or worse, it's long-standing practice now.

<!-- gh-comment-id:633167922 --> @PeterConstable commented on GitHub (May 24, 2020): Thanks. Blank line in interactive mode being handled differently than in a script is somewhat motivated: when editing multi-line statements, the console needs some way to detect when end of statement is intended. They could have required entry of a truly empty line (no spaces), but that would have impacted usability in interactive mode. At any rate, for better or worse, it's long-standing practice now.
Author
Owner

@lowlydba commented on GitHub (Jun 26, 2020):

Also would like to see this implemented. In my use case, I am generating markdown documentation for databases and so can't guarantee (as is the case with my demo code) that the code within a database follows markdown best practices.

Giving a pass to the code blocks allows me to more tightly control my markdown, while not erroring out for the fenced code blocks that originate elsewhere.

<!-- gh-comment-id:650422333 --> @lowlydba commented on GitHub (Jun 26, 2020): Also would like to see this implemented. In my use case, I am generating markdown documentation for databases and so can't guarantee (as is the case with my demo code) that the code within a database follows markdown best practices. Giving a pass to the code blocks allows me to more tightly control my markdown, while not erroring out for the fenced code blocks that originate elsewhere.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/markdownlint#247
No description provided.