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