15
15
import sys
16
16
import os
17
17
import shutil
18
+ import csv
18
19
import subprocess
19
20
import argparse
20
21
import webbrowser
22
+ import docutils
23
+ import docutils .parsers .rst
21
24
22
25
23
26
DOC_PATH = os .path .dirname (os .path .abspath (__file__ ))
24
27
SOURCE_PATH = os .path .join (DOC_PATH , 'source' )
25
28
BUILD_PATH = os .path .join (DOC_PATH , 'build' )
26
- BUILD_DIRS = [ 'doctrees' , 'html' , 'latex' , 'plots' , '_static' , '_templates' ]
29
+ REDIRECTS_FILE = os . path . join ( DOC_PATH , 'redirects.csv' )
27
30
28
31
29
32
class DocBuilder :
@@ -139,6 +142,77 @@ def _open_browser(self, single_doc_html):
139
142
single_doc_html )
140
143
webbrowser .open (url , new = 2 )
141
144
145
+ def _get_page_title (self , page ):
146
+ """
147
+ Open the rst file `page` and extract its title.
148
+ """
149
+ fname = os .path .join (SOURCE_PATH , '{}.rst' .format (page ))
150
+ option_parser = docutils .frontend .OptionParser (
151
+ components = (docutils .parsers .rst .Parser ,))
152
+ doc = docutils .utils .new_document (
153
+ '<doc>' ,
154
+ option_parser .get_default_values ())
155
+ with open (fname ) as f :
156
+ data = f .read ()
157
+
158
+ parser = docutils .parsers .rst .Parser ()
159
+ # do not generate any warning when parsing the rst
160
+ with open (os .devnull , 'a' ) as f :
161
+ doc .reporter .stream = f
162
+ parser .parse (data , doc )
163
+
164
+ section = next (node for node in doc .children
165
+ if isinstance (node , docutils .nodes .section ))
166
+ title = next (node for node in section .children
167
+ if isinstance (node , docutils .nodes .title ))
168
+
169
+ return title .astext ()
170
+
171
+ def _add_redirects (self ):
172
+ """
173
+ Create in the build directory an html file with a redirect,
174
+ for every row in REDIRECTS_FILE.
175
+ """
176
+ html = '''
177
+ <html>
178
+ <head>
179
+ <meta http-equiv="refresh" content="0;URL={url}"/>
180
+ </head>
181
+ <body>
182
+ <p>
183
+ The page has been moved to <a href="{url}">{title}</a>
184
+ </p>
185
+ </body>
186
+ <html>
187
+ '''
188
+ with open (REDIRECTS_FILE ) as mapping_fd :
189
+ reader = csv .reader (mapping_fd )
190
+ for row in reader :
191
+ if not row or row [0 ].strip ().startswith ('#' ):
192
+ continue
193
+
194
+ path = os .path .join (BUILD_PATH ,
195
+ 'html' ,
196
+ * row [0 ].split ('/' )) + '.html'
197
+
198
+ try :
199
+ title = self ._get_page_title (row [1 ])
200
+ except Exception :
201
+ # the file can be an ipynb and not an rst, or docutils
202
+ # may not be able to read the rst because it has some
203
+ # sphinx specific stuff
204
+ title = 'this page'
205
+
206
+ if os .path .exists (path ):
207
+ raise RuntimeError ((
208
+ 'Redirection would overwrite an existing file: '
209
+ '{}' ).format (path ))
210
+
211
+ with open (path , 'w' ) as moved_page_fd :
212
+ moved_page_fd .write (
213
+ html .format (url = '{}.html' .format (row [1 ]),
214
+ title = title ))
215
+
142
216
def html (self ):
143
217
"""
144
218
Build HTML documentation.
@@ -150,6 +224,8 @@ def html(self):
150
224
151
225
if self .single_doc_html is not None :
152
226
self ._open_browser (self .single_doc_html )
227
+ else :
228
+ self ._add_redirects ()
153
229
return ret_code
154
230
155
231
def latex (self , force = False ):
0 commit comments