forked from vemel/handsdown
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsection_map.py
More file actions
107 lines (77 loc) · 3.1 KB
/
Copy pathsection_map.py
File metadata and controls
107 lines (77 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""Module for splitting docstring into `Section` groups."""
from collections.abc import Iterator
from handsdown.processors.section import Section
from handsdown.processors.section_block import SectionBlock
from handsdown.utils.indent_trimmer import IndentTrimmer
class SectionMap:
"""
Dict-based storage for parsed `Section` list.
Used for `handsdown.processors.base.BaseDocstringProcessor`.
Key is a `Section` title.
Value is a related `Section` instance.
"""
def __init__(self) -> None:
super().__init__()
self._order: list[str] = []
self.sections: dict[str, Section] = {}
def add_line_indent(self, section_name: str, line: str) -> None:
"""
Add line respecting indent of the current section block.
Arguments:
section_name -- Target section title
line -- Line to add
"""
if section_name in self.sections:
section = self.sections[section_name]
if section.blocks and section.blocks[-1].lines:
indent = IndentTrimmer.get_line_indent(section.blocks[-1].lines[-1])
line = IndentTrimmer.indent_line(line, indent)
self.add_line(section_name, line)
def add_line(self, section_name: str, line: str) -> None:
"""
Add new `line` to the last `SectionBlock` of section `section_name`.
If line and section are empty - section is not created.
Arguments:
section_name -- Target section title
line -- Line to add
"""
if section_name not in self.sections:
if not line:
return
self._order.append(section_name)
self.sections[section_name] = Section(title=section_name, blocks=[])
section = self.sections[section_name]
if not section.blocks:
section.blocks.append(SectionBlock(lines=[]))
self.sections[section_name].blocks[-1].lines.append(line)
def add_block(self, section_name: str) -> None:
"""
Add new `SectionBlock` to section `section_name`.
If `Section` does not exist - it is not created.
Arguments:
section_name -- Target section title
"""
if section_name not in self.sections:
return
self.sections[section_name].blocks.append(SectionBlock(lines=[]))
def trim_block(self, section_name: str) -> None:
"""
Delete last empty lines from the last `SectionBlock`.
If `Section` does not exist - it is not created.
Arguments:
section_name -- Target section title.
"""
if section_name not in self.sections:
return
lines = self.sections[section_name].blocks[-1].lines
while lines and not lines[-1].strip():
lines.pop()
def __iter__(self) -> Iterator[Section]:
"""
Iterate over existing `Section` objects.
Yields:
`Section` objects in order of appearance.
"""
for section_name in self._order:
section = self.sections[section_name]
yield section