1515import sys
1616import os
1717import shutil
18+ import csv
1819import subprocess
1920import argparse
2021import webbrowser
22+ import docutils
23+ import docutils .parsers .rst
2124
2225
2326DOC_PATH = os .path .dirname (os .path .abspath (__file__ ))
2427SOURCE_PATH = os .path .join (DOC_PATH , 'source' )
2528BUILD_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' )
2730
2831
2932class DocBuilder :
@@ -139,6 +142,77 @@ def _open_browser(self, single_doc_html):
139142 single_doc_html )
140143 webbrowser .open (url , new = 2 )
141144
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+
142216 def html (self ):
143217 """
144218 Build HTML documentation.
@@ -150,6 +224,8 @@ def html(self):
150224
151225 if self .single_doc_html is not None :
152226 self ._open_browser (self .single_doc_html )
227+ else :
228+ self ._add_redirects ()
153229 return ret_code
154230
155231 def latex (self , force = False ):
0 commit comments