5
5
import attr
6
6
from attr .validators import deep_iterable , instance_of , matches_re , optional
7
7
8
+ #: Pattern used to match URL items.
9
+ URL_PATTERN : str = r".+://.*"
10
+
8
11
9
12
class FileItem (str ):
10
13
"""A document path in a toctree list.
11
14
12
- This should be in Posix format (folders split by ``/``),
13
- relative to the source directory,
14
- and can be with or without extension.
15
+ This should be in POSIX format (folders split by ``/``), relative to the
16
+ source directory, and can be with or without an extension.
15
17
"""
16
18
17
19
@@ -24,7 +26,7 @@ class UrlItem:
24
26
"""A URL in a toctree."""
25
27
26
28
# regex should match sphinx.util.url_re
27
- url : str = attr .ib (validator = [instance_of (str ), matches_re (r".+://.*" )])
29
+ url : str = attr .ib (validator = [instance_of (str ), matches_re (URL_PATTERN )])
28
30
title : Optional [str ] = attr .ib (None , validator = optional (instance_of (str )))
29
31
30
32
@@ -39,40 +41,55 @@ class TocTree:
39
41
)
40
42
)
41
43
caption : Optional [str ] = attr .ib (
42
- None , kw_only = True , validator = optional (instance_of (str ))
44
+ default = None , kw_only = True , validator = optional (instance_of (str ))
43
45
)
44
- hidden : bool = attr .ib (True , kw_only = True , validator = instance_of (bool ))
45
- maxdepth : int = attr .ib (- 1 , kw_only = True , validator = instance_of (int ))
46
+ hidden : bool = attr .ib (default = True , kw_only = True , validator = instance_of (bool ))
47
+ maxdepth : int = attr .ib (default = - 1 , kw_only = True , validator = instance_of (int ))
46
48
numbered : Union [bool , int ] = attr .ib (
47
- False , kw_only = True , validator = instance_of ((bool , int ))
49
+ default = False , kw_only = True , validator = instance_of ((bool , int ))
48
50
)
49
- reversed : bool = attr .ib (False , kw_only = True , validator = instance_of (bool ))
50
- titlesonly : bool = attr .ib (False , kw_only = True , validator = instance_of (bool ))
51
+ reversed : bool = attr .ib (default = False , kw_only = True , validator = instance_of (bool ))
52
+ titlesonly : bool = attr .ib (default = False , kw_only = True , validator = instance_of (bool ))
51
53
52
54
def files (self ) -> List [str ]:
55
+ """Returns a list of file items included in this ToC tree.
56
+
57
+ :return: file items
58
+ """
53
59
return [str (item ) for item in self .items if isinstance (item , FileItem )]
54
60
55
61
def globs (self ) -> List [str ]:
62
+ """Returns a list of glob items included in this ToC tree.
63
+
64
+ :return: glob items
65
+ """
56
66
return [str (item ) for item in self .items if isinstance (item , GlobItem )]
57
67
58
68
59
69
@attr .s (slots = True )
60
70
class Document :
61
71
"""A document in the site map."""
62
72
63
- docname : str = attr .ib (validator = instance_of (str ))
64
- title : Optional [str ] = attr .ib (None , validator = optional (instance_of (str )))
65
73
# TODO validate uniqueness of docnames across all parts (and none should be the docname)
74
+ docname : str = attr .ib (validator = instance_of (str ))
66
75
subtrees : List [TocTree ] = attr .ib (
67
- factory = list , validator = deep_iterable (instance_of (TocTree ), instance_of (list ))
76
+ factory = list ,
77
+ validator = deep_iterable (instance_of (TocTree ), instance_of (list )),
68
78
)
79
+ title : Optional [str ] = attr .ib (default = None , validator = optional (instance_of (str )))
69
80
70
81
def child_files (self ) -> List [str ]:
71
- """Return all children files."""
82
+ """Return all children files.
83
+
84
+ :return: child files
85
+ """
72
86
return [name for tree in self .subtrees for name in tree .files ()]
73
87
74
88
def child_globs (self ) -> List [str ]:
75
- """Return all children globs."""
89
+ """Return all children globs.
90
+
91
+ :return: child globs
92
+ """
76
93
return [name for tree in self .subtrees for name in tree .globs ()]
77
94
78
95
@@ -93,17 +110,26 @@ def __init__(
93
110
94
111
@property
95
112
def root (self ) -> Document :
96
- """Return the root document."""
113
+ """Return the root document of the ToC tree.
114
+
115
+ :return: root document
116
+ """
97
117
return self ._root
98
118
99
119
@property
100
120
def meta (self ) -> Dict [str , Any ]:
101
- """Return the site-map metadata."""
121
+ """Return the site-map metadata.
122
+
123
+ :return: metadata dictionary
124
+ """
102
125
return self ._meta
103
126
104
127
@property
105
128
def file_format (self ) -> Optional [str ]:
106
- """Return the format of the file to write to."""
129
+ """Return the format of the file to write to.
130
+
131
+ :return: output file format
132
+ """
107
133
return self ._file_format
108
134
109
135
@file_format .setter
@@ -116,21 +142,45 @@ def globs(self) -> Set[str]:
116
142
return {glob for item in self ._docs .values () for glob in item .child_globs ()}
117
143
118
144
def __getitem__ (self , docname : str ) -> Document :
145
+ """Enable retrieving a document by name using the indexing operator.
146
+
147
+ :param docname: document name
148
+ :return: document instance
149
+ """
119
150
return self ._docs [docname ]
120
151
121
152
def __setitem__ (self , docname : str , item : Document ) -> None :
153
+ """Enable setting a document by name using the indexing operator.
154
+
155
+ :param docname: document name
156
+ :param item: document instance
157
+ """
122
158
assert item .docname == docname
123
159
self ._docs [docname ] = item
124
160
125
- def __delitem__ (self , docname : str ):
161
+ def __delitem__ (self , docname : str ) -> None :
162
+ """Enable removing a document by name.
163
+
164
+ :param docname: document name
165
+ """
126
166
assert docname != self ._root .docname , "cannot delete root doc item"
127
167
del self ._docs [docname ]
128
168
129
169
def __iter__ (self ) -> Iterator [str ]:
170
+ """Enable iterating the names of the documents the site map is composed
171
+ of.
172
+
173
+ :yield: document name
174
+ """
130
175
for docname in self ._docs :
131
176
yield docname
132
177
133
178
def __len__ (self ) -> int :
179
+ """Enable using Python's built-in `len()` function to return the number
180
+ of documents contained in a site map.
181
+
182
+ :return: number of documents in this site map
183
+ """
134
184
return len (self ._docs )
135
185
136
186
@staticmethod
@@ -151,15 +201,19 @@ def as_json(self) -> Dict[str, Any]:
151
201
else self ._docs [k ]
152
202
for k in sorted (self ._docs )
153
203
}
154
- data = {"root" : self .root .docname , "documents" : doc_dict , "meta" : self .meta }
204
+ data = {
205
+ "root" : self .root .docname ,
206
+ "documents" : doc_dict ,
207
+ "meta" : self .meta ,
208
+ }
155
209
if self .file_format :
156
210
data ["file_format" ] = self .file_format
157
211
return data
158
212
159
213
def get_changed (self , previous : "SiteMap" ) -> Set [str ]:
160
214
"""Compare this sitemap to another and return a list of changed documents.
161
215
162
- Note: for sphinx , file extensions should be removed to get docnames
216
+ .. note:: for Sphinx , file extensions should be removed to get docnames.
163
217
"""
164
218
changed_docs = set ()
165
219
# check if the root document has changed
0 commit comments