Skip to content

Commit 9251695

Browse files
authored
👌 Centralise indented code block test (#260)
For CommonMark, the presence of indented code blocks prevent any other block element from having an indent of greater than 4 spaces. Certain Markdown flavors and derivatives, such as mdx and djot, disable these code blocks though, since it is more common to use code fences and/or arbitrary indenting is desirable. Currently, disabling code blocks does not remove the indent limitation, since most block elements have the 3 space limitation hard-coded. This commit therefore centralises the logic of applying this limitation, and only applies it when indented code blocks are enabled. Note, this is a potential breaking change and divergence from upstream markdown-it, for this niche case, but I feel makes sense and could even be upstreamed.
1 parent 83d66d4 commit 9251695

File tree

13 files changed

+104
-26
lines changed

13 files changed

+104
-26
lines changed

markdown_it/rules_block/blockquote.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ def blockquote(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
1818
pos = state.bMarks[startLine] + state.tShift[startLine]
1919
max = state.eMarks[startLine]
2020

21-
# if it's indented more than 3 spaces, it should be a code block
22-
if (state.sCount[startLine] - state.blkIndent) >= 4:
21+
if state.is_code_block(startLine):
2322
return False
2423

2524
# check the block quote marker

markdown_it/rules_block/code.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
def code(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool:
1010
LOGGER.debug("entering code: %s, %s, %s, %s", state, startLine, endLine, silent)
1111

12-
if state.sCount[startLine] - state.blkIndent < 4:
12+
if not state.is_code_block(startLine):
1313
return False
1414

1515
last = nextLine = startLine + 1
@@ -19,7 +19,7 @@ def code(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool:
1919
nextLine += 1
2020
continue
2121

22-
if state.sCount[nextLine] - state.blkIndent >= 4:
22+
if state.is_code_block(nextLine):
2323
nextLine += 1
2424
last = nextLine
2525
continue

markdown_it/rules_block/fence.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ def fence(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool
1313
pos = state.bMarks[startLine] + state.tShift[startLine]
1414
maximum = state.eMarks[startLine]
1515

16-
# if it's indented more than 3 spaces, it should be a code block
17-
if state.sCount[startLine] - state.blkIndent >= 4:
16+
if state.is_code_block(startLine):
1817
return False
1918

2019
if pos + 3 > maximum:
@@ -72,8 +71,7 @@ def fence(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool
7271
except IndexError:
7372
break
7473

75-
if state.sCount[nextLine] - state.blkIndent >= 4:
76-
# closing fence should be indented less than 4 spaces
74+
if state.is_code_block(nextLine):
7775
continue
7876

7977
pos = state.skipChars(pos, marker)

markdown_it/rules_block/heading.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ def heading(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bo
1515
pos = state.bMarks[startLine] + state.tShift[startLine]
1616
maximum = state.eMarks[startLine]
1717

18-
# if it's indented more than 3 spaces, it should be a code block
19-
if state.sCount[startLine] - state.blkIndent >= 4:
18+
if state.is_code_block(startLine):
2019
return False
2120

2221
ch: int | None = state.srcCharCode[pos]

markdown_it/rules_block/hr.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ def hr(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool:
1616
pos = state.bMarks[startLine] + state.tShift[startLine]
1717
maximum = state.eMarks[startLine]
1818

19-
# if it's indented more than 3 spaces, it should be a code block
20-
if state.sCount[startLine] - state.blkIndent >= 4:
19+
if state.is_code_block(startLine):
2120
return False
2221

2322
try:

markdown_it/rules_block/html_block.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ def html_block(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
3838
pos = state.bMarks[startLine] + state.tShift[startLine]
3939
maximum = state.eMarks[startLine]
4040

41-
# if it's indented more than 3 spaces, it should be a code block
42-
if state.sCount[startLine] - state.blkIndent >= 4:
41+
if state.is_code_block(startLine):
4342
return False
4443

4544
if not state.md.options.get("html", None):

markdown_it/rules_block/lheading.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ def lheading(state: StateBlock, startLine: int, endLine: int, silent: bool) -> b
1515
ruler: Ruler = state.md.block.ruler
1616
terminatorRules = ruler.getRules("paragraph")
1717

18-
# if it's indented more than 3 spaces, it should be a code block
19-
if state.sCount[startLine] - state.blkIndent >= 4:
18+
if state.is_code_block(startLine):
2019
return False
2120

2221
oldParentType = state.parentType

markdown_it/rules_block/list.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ def list_block(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
102102
isTerminatingParagraph = False
103103
tight = True
104104

105-
# if it's indented more than 3 spaces, it should be a code block
106-
if state.sCount[startLine] - state.blkIndent >= 4:
105+
if state.is_code_block(startLine):
107106
return False
108107

109108
# Special case:
@@ -295,8 +294,7 @@ def list_block(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
295294
if state.sCount[nextLine] < state.blkIndent:
296295
break
297296

298-
# if it's indented more than 3 spaces, it should be a code block
299-
if state.sCount[startLine] - state.blkIndent >= 4:
297+
if state.is_code_block(startLine):
300298
break
301299

302300
# fail if terminating block found

markdown_it/rules_block/reference.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ def reference(state: StateBlock, startLine: int, _endLine: int, silent: bool) ->
1616
maximum = state.eMarks[startLine]
1717
nextLine = startLine + 1
1818

19-
# if it's indented more than 3 spaces, it should be a code block
20-
if state.sCount[startLine] - state.blkIndent >= 4:
19+
if state.is_code_block(startLine):
2120
return False
2221

2322
if state.srcCharCode[pos] != 0x5B: # /* [ */

markdown_it/rules_block/state_block.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ def __init__(
116116

117117
self.lineMax = len(self.bMarks) - 1 # don't count last fake line
118118

119+
# pre-check if code blocks are enabled, to speed up is_code_block method
120+
self._code_enabled = "code" in self.md["block"].ruler.get_active_rules()
121+
119122
def __repr__(self) -> str:
120123
return (
121124
f"{self.__class__.__name__}"
@@ -228,3 +231,9 @@ def getLines(self, begin: int, end: int, indent: int, keepLastLF: bool) -> str:
228231
i += 1
229232

230233
return "".join(queue)
234+
235+
def is_code_block(self, line: int) -> bool:
236+
"""Check if line is a code block,
237+
i.e. the code block rule is enabled and text is indented by more than 3 spaces.
238+
"""
239+
return self._code_enabled and (self.sCount[line] - self.blkIndent) >= 4

0 commit comments

Comments
 (0)