Skip to content

Commit a574c66

Browse files
committed
Extend CMakeModule to parse markdown
Signed-off-by: Cristian Le <git@lecris.dev>
1 parent 0d6b277 commit a574c66

File tree

1 file changed

+61
-40
lines changed

1 file changed

+61
-40
lines changed

sphinxcontrib/moderncmakedomain/cmake.py

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
if sphinx.version_info >= (2,):
1515
from docutils import io, nodes
1616
from docutils.nodes import Element, Node, TextElement, system_message
17-
from docutils.parsers.rst import Directive, directives
17+
from docutils.parsers.rst import directives
1818
from docutils.transforms import Transform
1919
from docutils.utils.code_analyzer import Lexer, LexerError
2020

2121
from sphinx import addnodes
22-
from sphinx.directives import ObjectDescription, nl_escape_re
22+
from sphinx.directives import SphinxDirective, ObjectDescription, nl_escape_re
2323
from sphinx.domains import Domain, ObjType
2424
from sphinx.roles import XRefRole
2525
from sphinx.util import logging, ws_re
2626
from sphinx.util.docutils import ReferenceRole
27-
from sphinx.util.nodes import make_refnode
27+
from sphinx.util.nodes import make_refnode, nested_parse_with_titles
2828
else:
2929
# Sphinx 2.x is required.
3030
assert sphinx.version_info >= (2,)
@@ -128,15 +128,16 @@ class ObjectEntry:
128128
name: str
129129

130130

131-
class CMakeModule(Directive):
131+
class CMakeModule(SphinxDirective):
132132
required_arguments = 1
133133
optional_arguments = 0
134134
final_argument_whitespace = True
135135
option_spec = {'encoding': directives.encoding}
136136

137137
def __init__(self, *args, **keys):
138-
self.re_start = re.compile(r'^#\[(?P<eq>=*)\[\.rst:$')
139-
Directive.__init__(self, *args, **keys)
138+
self.re_block_start = re.compile(r'^(?P<prefix>\s*)#\[(?P<eq>=*)\[\.(?:rst|md):$')
139+
self.re_single = re.compile(r'^(?P<prefix>\s*)#\.(?:rst|md):$')
140+
super().__init__(*args, **keys)
140141

141142
def run(self):
142143
settings = self.state.document.settings
@@ -161,41 +162,61 @@ def run(self):
161162
raise self.severe(msg)
162163
raw_lines = f.read().splitlines()
163164
f.close()
164-
rst = None
165165
lines = []
166-
for line in raw_lines:
167-
if rst is not None and rst != '#':
168-
# Bracket mode: check for end bracket
169-
pos = line.find(rst)
170-
if pos >= 0:
171-
if line[0] == '#':
172-
line = ''
173-
else:
174-
line = line[0:pos]
175-
rst = None
176-
else:
177-
# Line mode: check for .rst start (bracket or line)
178-
m = self.re_start.match(line)
179-
if m:
180-
rst = f']{m.group("eq")}]'
181-
line = ''
182-
elif line == '#.rst:':
183-
rst = '#'
184-
line = ''
185-
elif rst == '#':
186-
if line == '#' or line[:2] == '# ':
187-
line = line[2:]
188-
else:
189-
rst = None
190-
line = ''
191-
elif rst is None:
192-
line = ''
193-
lines.append(line)
194-
if rst is not None and rst != '#':
195-
raise self.warning(f'{self.name!r} found unclosed bracket '
196-
f'"#[{rst[1:-1]}[.rst:" in {path!r}')
197-
self.state_machine.insert_input(lines, path)
198-
return []
166+
block_end = ""
167+
prefix = ""
168+
block_start = -1
169+
# TODO: Parse nested comments as belonging to specific directive
170+
# Similar to python's documentaiton
171+
for indx, line in enumerate(raw_lines):
172+
# Check if in block comment mode
173+
if block_end:
174+
# Check for block_end
175+
if line.startswith(block_end):
176+
# Exit block mode
177+
block_end = ""
178+
prefix = ""
179+
continue
180+
# Check if line is only whitespace, then add an empty line
181+
if not line or line.isspace():
182+
lines.append("")
183+
continue
184+
# Otherwise remove prefix and add the lines
185+
if not line.startswith(prefix):
186+
raise self.warning(f"{self.name} found ill-formatted block line in {path}:\nline#{indx}: {line}")
187+
lines.append(line.lstrip(prefix))
188+
continue
189+
# Check if in line comment mode
190+
if prefix:
191+
if line.startswith(prefix):
192+
# Current line is still part of the comment
193+
lines.append(line.lstrip(prefix))
194+
continue
195+
# Otherwise we are exiting line-mode
196+
prefix = ""
197+
continue
198+
# Otherwise we are not in comment mode
199+
# Check if we can enter a comment mode
200+
# First check for block-mode
201+
block_mode = self.re_block_start.match(line)
202+
if block_mode:
203+
block_start = indx
204+
prefix = block_mode.group('prefix')
205+
block_end = f"{prefix}]{block_mode.group('eq')}]"
206+
continue
207+
# Next check for line-mode
208+
line_mode = self.re_single.match(line)
209+
if line_mode:
210+
prefix = line_mode.group('prefix')
211+
continue
212+
# Sanitize exit
213+
if block_end:
214+
raise self.warning(f"{self.name} found unclosed bracket in {path}:\n"
215+
f"bracket start at:{block_start};bracket end:\"{block_end}\"")
216+
node = nodes.Element()
217+
node.document = self.state.document
218+
self.state.nested_parse(lines, self.content_offset, node, match_titles=True)
219+
return node.children
199220

200221

201222
class _cmake_index_entry:

0 commit comments

Comments
 (0)