1
1
"""
2
- sphinxnotes.snippet
3
- ~~~~~~~~~~~~~~~~~~~
2
+ sphinxnotes.snippet
3
+ ~~~~~~~~~~~~~~~~~~~
4
4
5
- :copyright: Copyright 2020 Shengyu Zhang
6
- :license: BSD, see LICENSE for details.
5
+ :copyright: Copyright 2020 Shengyu Zhang
6
+ :license: BSD, see LICENSE for details.
7
7
"""
8
8
9
9
from __future__ import annotations
14
14
15
15
__version__ = '1.1.1'
16
16
17
+
17
18
class Snippet (object ):
18
19
"""
19
20
Snippet is base class of reStructuredText snippet.
20
21
21
- :param nodes: Document nodes that make up this snippet
22
+ :param nodes: Document nodes that make up this snippet
22
23
"""
23
24
24
25
#: Source file path of snippet
25
- file :str
26
+ file : str
26
27
27
28
#: Line number range of snippet, in the source file which is left closed
28
29
#: and right opened.
29
- lineno :Tuple [int ,int ]
30
+ lineno : Tuple [int , int ]
30
31
31
32
#: The original reStructuredText of snippet
32
- rst :List [str ]
33
+ rst : List [str ]
33
34
34
35
#: The possible identifier key of snippet, which is picked from nodes'
35
36
#: (or nodes' parent's) `ids attr`_.
36
37
#:
37
38
#: .. _ids attr: https://docutils.sourceforge.io/docs/ref/doctree.html#ids
38
- refid :Optional [str ]
39
+ refid : Optional [str ]
39
40
40
- def __init__ (self , * nodes :nodes .Node ) -> None :
41
+ def __init__ (self , * nodes : nodes .Node ) -> None :
41
42
assert len (nodes ) != 0
42
43
43
44
self .file = nodes [0 ].source
44
45
45
46
lineno = [float ('inf' ), - float ('inf' )]
46
47
for node in nodes :
47
48
if not node .line :
48
- continue # Skip node that have None line, I dont know why
49
+ continue # Skip node that have None line, I dont know why
49
50
lineno [0 ] = min (lineno [0 ], _line_of_start (node ))
50
51
lineno [1 ] = max (lineno [1 ], _line_of_end (node ))
51
52
self .lineno = lineno
52
53
53
54
lines = []
54
- with open (self .file , "r" ) as f :
55
+ with open (self .file , 'r' ) as f :
55
56
start = self .lineno [0 ] - 1
56
57
stop = self .lineno [1 ] - 1
57
58
for line in itertools .islice (f , start , stop ):
@@ -73,61 +74,60 @@ def __init__(self, *nodes:nodes.Node) -> None:
73
74
break
74
75
75
76
76
-
77
77
class Text (Snippet ):
78
78
#: Text of snippet
79
- text :str
79
+ text : str
80
80
81
- def __init__ (self , node :nodes .Node ) -> None :
81
+ def __init__ (self , node : nodes .Node ) -> None :
82
82
super ().__init__ (node )
83
83
self .text = node .astext ()
84
84
85
85
86
86
class CodeBlock (Text ):
87
87
#: Language of code block
88
- language :str
88
+ language : str
89
89
#: Caption of code block
90
- caption :Optional [str ]
90
+ caption : Optional [str ]
91
91
92
- def __init__ (self , node :nodes .literal_block ) -> None :
92
+ def __init__ (self , node : nodes .literal_block ) -> None :
93
93
assert isinstance (node , nodes .literal_block )
94
94
super ().__init__ (node )
95
95
self .language = node ['language' ]
96
96
self .caption = node .get ('caption' )
97
97
98
98
99
99
class WithCodeBlock (object ):
100
- code_blocks :List [CodeBlock ]
100
+ code_blocks : List [CodeBlock ]
101
101
102
- def __init__ (self , nodes :nodes .Nodes ) -> None :
102
+ def __init__ (self , nodes : nodes .Nodes ) -> None :
103
103
self .code_blocks = []
104
104
for n in nodes .traverse (nodes .literal_block ):
105
105
self .code_blocks .append (self .CodeBlock (n ))
106
106
107
107
108
108
class Title (Text ):
109
- def __init__ (self , node :nodes .title ) -> None :
109
+ def __init__ (self , node : nodes .title ) -> None :
110
110
assert isinstance (node , nodes .title )
111
111
super ().__init__ (node )
112
112
113
113
114
114
class WithTitle (object ):
115
- title :Optional [Title ]
115
+ title : Optional [Title ]
116
116
117
- def __init__ (self , node :nodes .Node ) -> None :
117
+ def __init__ (self , node : nodes .Node ) -> None :
118
118
title_node = node .next_node (nodes .title )
119
119
self .title = Title (title_node ) if title_node else None
120
120
121
121
122
122
class Section (Snippet , WithTitle ):
123
- def __init__ (self , node :nodes .section ) -> None :
123
+ def __init__ (self , node : nodes .section ) -> None :
124
124
assert isinstance (node , nodes .section )
125
125
Snippet .__init__ (self , node )
126
126
WithTitle .__init__ (self , node )
127
127
128
128
129
129
class Document (Section ):
130
- def __init__ (self , node :nodes .document ) -> None :
130
+ def __init__ (self , node : nodes .document ) -> None :
131
131
assert isinstance (node , nodes .document )
132
132
super ().__init__ (node .next_node (nodes .section ))
133
133
@@ -136,7 +136,8 @@ def __init__(self, node:nodes.document) -> None:
136
136
# Nodes helper #
137
137
################
138
138
139
- def _line_of_start (node :nodes .Node ) -> int :
139
+
140
+ def _line_of_start (node : nodes .Node ) -> int :
140
141
assert node .line
141
142
if isinstance (node , nodes .title ):
142
143
if isinstance (node .parent .parent , nodes .document ):
@@ -155,7 +156,7 @@ def _line_of_start(node:nodes.Node) -> int:
155
156
return node .line
156
157
157
158
158
- def _line_of_end (node :nodes .Node ) -> Optional [int ]:
159
+ def _line_of_end (node : nodes .Node ) -> Optional [int ]:
159
160
next_node = node .next_node (descend = False , siblings = True , ascend = True )
160
161
while next_node :
161
162
if next_node .line :
@@ -166,7 +167,9 @@ def _line_of_end(node:nodes.Node) -> Optional[int]:
166
167
descend = True ,
167
168
# If node and its children have not valid line attr, try use line
168
169
# of next node
169
- ascend = True , siblings = True )
170
+ ascend = True ,
171
+ siblings = True ,
172
+ )
170
173
# No line found, return the max line of source file
171
174
if node .source :
172
175
with open (node .source ) as f :
0 commit comments