11#!/usr/bin/env python
2+ """Wrapper script for calling Sphinx. """
23
34from __future__ import print_function
45import glob
78import sys
89import re
910import argparse
11+ import subprocess
1012import matplotlib
1113
14+
1215def copy_if_out_of_date (original , derived ):
16+ """Copy file only if newer as target or if target does not exist. """
1317 if (not os .path .exists (derived ) or
1418 os .stat (derived ).st_mtime < os .stat (original ).st_mtime ):
1519 try :
@@ -22,7 +26,9 @@ def copy_if_out_of_date(original, derived):
2226 else :
2327 raise
2428
29+
2530def check_build ():
31+ """Create target build directories if necessary. """
2632 build_dirs = ['build' , 'build/doctrees' , 'build/html' , 'build/latex' ,
2733 'build/texinfo' , '_static' , '_templates' ]
2834 for d in build_dirs :
@@ -31,14 +37,58 @@ def check_build():
3137 except OSError :
3238 pass
3339
40+
3441def doctest ():
42+ """Execute Sphinx 'doctest' target. """
3543 os .system ('sphinx-build -b doctest -d build/doctrees . build/doctest' )
3644
45+
3746def linkcheck ():
47+ """Execute Sphinx 'linkcheck' target. """
3848 os .system ('sphinx-build -b linkcheck -d build/doctrees . build/linkcheck' )
3949
50+
51+ # For generating PNGs of the top row of index.html:
52+ FRONTPAGE_PY_PATH = "../examples/frontpage/" # python scripts location
53+ FRONTPAGE_PNG_PATH = "_static/" # png files location
54+ # png files and corresponding generation scripts:
55+ FRONTPAGE_PNGS = {"surface3d_frontpage.png" : "plot_3D.py" ,
56+ "contour_frontpage.png" : "plot_contour.py" ,
57+ "histogram_frontpage.png" : "plot_histogram.py" ,
58+ "membrane_frontpage.png" : "plot_membrane.py" }
59+
60+
61+ def generate_frontpage_pngs (only_if_needed = True ):
62+ """Executes the scripts for PNG generation of the top row of index.html.
63+
64+ If `only_if_needed` is `True`, then the PNG file is only generated, if it
65+ doesn't exist or if the python file is newer.
66+
67+ Note that the element `div.responsive_screenshots` in the file
68+ `_static/mpl.css` has the height and cumulative width of the used PNG files
69+ as attributes. This ensures that the magnification of those PNGs is <= 1.
70+ """
71+ for fn_png , fn_py in FRONTPAGE_PNGS .items ():
72+ pn_png = os .path .join (FRONTPAGE_PNG_PATH , fn_png ) # get full paths
73+ pn_py = os .path .join (FRONTPAGE_PY_PATH , fn_py )
74+
75+ # Read file modification times:
76+ mtime_py = os .path .getmtime (pn_py )
77+ mtime_png = (os .path .getmtime (pn_png ) if os .path .exists (pn_png ) else
78+ mtime_py - 1 ) # set older time, if file doesn't exist
79+
80+ if only_if_needed and mtime_py <= mtime_png :
81+ continue # do nothing if png is newer
82+
83+ # Execute python as subprocess (preferred over os.system()):
84+ subprocess .check_call (["python" , pn_py ]) # raises CalledProcessError()
85+ os .rename (fn_png , pn_png ) # move file to _static/ directory
86+
87+
4088def html (buildername = 'html' ):
89+ """Build Sphinx 'html' target. """
4190 check_build ()
91+ generate_frontpage_pngs ()
4292
4393 rc = '../lib/matplotlib/mpl-data/matplotlibrc'
4494 default_rc = os .path .join (matplotlib ._get_data_path (), 'matplotlibrc' )
@@ -62,20 +112,24 @@ def html(buildername='html'):
62112
63113 shutil .copy ('../CHANGELOG' , 'build/%s/_static/CHANGELOG' % buildername )
64114
115+
65116def htmlhelp ():
117+ """Build Sphinx 'htmlhelp' target. """
66118 html (buildername = 'htmlhelp' )
67119 # remove scripts from index.html
68120 with open ('build/htmlhelp/index.html' , 'r+' ) as fh :
69121 content = fh .read ()
70122 fh .seek (0 )
71123 content = re .sub (r'<script>.*?</script>' , '' , content ,
72- flags = re .MULTILINE | re .DOTALL )
124+ flags = re .MULTILINE | re .DOTALL )
73125 fh .write (content )
74126 fh .truncate ()
75127
128+
76129def latex ():
130+ """Build Sphinx 'latex' target. """
77131 check_build ()
78- #figs()
132+ # figs()
79133 if sys .platform != 'win32' :
80134 # LaTeX format.
81135 if os .system ('sphinx-build -b latex -d build/doctrees . build/latex' ):
@@ -92,9 +146,11 @@ def latex():
92146 else :
93147 print ('latex build has not been tested on windows' )
94148
149+
95150def texinfo ():
151+ """Build Sphinx 'texinfo' target. """
96152 check_build ()
97- #figs()
153+ # figs()
98154 if sys .platform != 'win32' :
99155 # Texinfo format.
100156 if os .system (
@@ -112,7 +168,9 @@ def texinfo():
112168 else :
113169 print ('texinfo build has not been tested on windows' )
114170
171+
115172def clean ():
173+ """Remove generated files. """
116174 shutil .rmtree ("build" , ignore_errors = True )
117175 shutil .rmtree ("examples" , ignore_errors = True )
118176 for pattern in ['mpl_examples/api/*.png' ,
@@ -126,21 +184,27 @@ def clean():
126184 for filename in glob .glob (pattern ):
127185 if os .path .exists (filename ):
128186 os .remove (filename )
187+ for fn in FRONTPAGE_PNGS .keys (): # remove generated PNGs
188+ pn = os .path .join (FRONTPAGE_PNG_PATH , fn )
189+ if os .path .exists (pn ):
190+ os .remove (os .path .join (pn ))
191+
129192
130- def all ():
131- #figs()
193+ def build_all ():
194+ """Build Sphinx 'html' and 'latex' target. """
195+ # figs()
132196 html ()
133197 latex ()
134198
135199
136200funcd = {
137- 'html' : html ,
138- 'htmlhelp' : htmlhelp ,
139- 'latex' : latex ,
140- 'texinfo' : texinfo ,
141- 'clean' : clean ,
142- 'all' : all ,
143- 'doctest' : doctest ,
201+ 'html' : html ,
202+ 'htmlhelp' : htmlhelp ,
203+ 'latex' : latex ,
204+ 'texinfo' : texinfo ,
205+ 'clean' : clean ,
206+ 'all' : build_all ,
207+ 'doctest' : doctest ,
144208 'linkcheck' : linkcheck ,
145209 }
146210
@@ -167,8 +231,8 @@ def all():
167231 # This is special processing that applies on platforms that don't deal
168232 # with git symlinks -- probably only MS windows.
169233 delete = False
170- with open (link , 'r' ) as content :
171- delete = target == content .read ()
234+ with open (link , 'r' ) as link_content :
235+ delete = target == link_content .read ()
172236 if delete :
173237 symlink_warnings .append ('deleted: doc/{0}' .format (link ))
174238 os .unlink (link )
@@ -185,7 +249,7 @@ def all():
185249if sys .platform == 'win32' and len (symlink_warnings ) > 0 :
186250 print ('The following items related to symlinks will show up '
187251 'as spurious changes in your \' git status\' :\n \t {0}'
188- .format ('\n \t ' .join (symlink_warnings )))
252+ .format ('\n \t ' .join (symlink_warnings )))
189253
190254parser = argparse .ArgumentParser (description = 'Build matplotlib docs' )
191255parser .add_argument ("cmd" , help = ("Command to execute. Can be multiple. "
0 commit comments