Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/markdown_it/rules_block/fence.py: 97%
58 statements
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-14 06:12 +0000
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-14 06:12 +0000
1# fences (``` lang, ~~~ lang)
2import logging
4from .state_block import StateBlock
6LOGGER = logging.getLogger(__name__)
9def fence(state: StateBlock, startLine: int, endLine: int, silent: bool):
10 LOGGER.debug("entering fence: %s, %s, %s, %s", state, startLine, endLine, silent)
12 haveEndMarker = False
13 pos = state.bMarks[startLine] + state.tShift[startLine]
14 maximum = state.eMarks[startLine]
16 # if it's indented more than 3 spaces, it should be a code block
17 if state.sCount[startLine] - state.blkIndent >= 4:
18 return False
20 if pos + 3 > maximum:
21 return False
23 marker = state.srcCharCode[pos]
25 # /* ~ */ /* ` */
26 if marker != 0x7E and marker != 0x60:
27 return False
29 # scan marker length
30 mem = pos
31 pos = state.skipChars(pos, marker)
33 length = pos - mem
35 if length < 3:
36 return False
38 markup = state.src[mem:pos]
39 params = state.src[pos:maximum]
41 # /* ` */
42 if marker == 0x60:
43 if chr(marker) in params:
44 return False
46 # Since start is found, we can report success here in validation mode
47 if silent:
48 return True
50 # search end of block
51 nextLine = startLine
53 while True:
54 nextLine += 1
55 if nextLine >= endLine:
56 # unclosed block should be autoclosed by end of document.
57 # also block seems to be autoclosed by end of parent
58 break
60 pos = mem = state.bMarks[nextLine] + state.tShift[nextLine]
61 maximum = state.eMarks[nextLine]
63 if pos < maximum and state.sCount[nextLine] < state.blkIndent:
64 # non-empty line with negative indent should stop the list:
65 # - ```
66 # test
67 break
69 try:
70 if state.srcCharCode[pos] != marker:
71 continue
72 except IndexError:
73 break
75 if state.sCount[nextLine] - state.blkIndent >= 4:
76 # closing fence should be indented less than 4 spaces
77 continue
79 pos = state.skipChars(pos, marker)
81 # closing code fence must be at least as long as the opening one
82 if pos - mem < length:
83 continue
85 # make sure tail has spaces only
86 pos = state.skipSpaces(pos)
88 if pos < maximum:
89 continue
91 haveEndMarker = True
92 # found!
93 break
95 # If a fence has heading spaces, they should be removed from its inner block
96 length = state.sCount[startLine]
98 state.line = nextLine + (1 if haveEndMarker else 0)
100 token = state.push("fence", "code", 0)
101 token.info = params
102 token.content = state.getLines(startLine + 1, nextLine, length, True)
103 token.markup = markup
104 token.map = [startLine, state.line]
106 return True