source: sasview/docs/sphinx-docs/build_sphinx.py @ d3ee425

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since d3ee425 was 417c03f, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Moved RST files around and modified sphinx config to use them. SASVIEW-927

  • Property mode set to 100755
File size: 9.5 KB
Line 
1#!/usr/bin/env python
2"""
3Functions for building sphinx docs.
4
5For more information on the invocation of sphinx see:
6http://sphinx-doc.org/invocation.html
7"""
8from __future__ import print_function
9
10import subprocess
11import os
12from os.path import join as joinpath, abspath, dirname, isdir, exists, relpath
13import sys
14import fnmatch
15import shutil
16import imp
17
18from glob import glob
19from distutils.dir_util import copy_tree
20from distutils.util import get_platform
21from distutils.spawn import find_executable
22
23from shutil import copy
24from os import listdir
25
26platform = '.%s-%s'%(get_platform(),sys.version[:3])
27
28# sphinx paths
29SPHINX_ROOT = dirname(abspath(__file__))
30SPHINX_BUILD = joinpath(SPHINX_ROOT, "build")
31SPHINX_SOURCE = joinpath(SPHINX_ROOT, "source-temp")
32SPHINX_PERSPECTIVES = joinpath(SPHINX_SOURCE, "user", "qtgui", "perspectives")
33
34# sasview paths
35SASVIEW_ROOT = joinpath(SPHINX_ROOT, '..', '..')
36SASVIEW_DOCS = joinpath(SPHINX_ROOT, "source")
37SASVIEW_BUILD = abspath(joinpath(SASVIEW_ROOT, "build", "lib"+platform))
38SASVIEW_MEDIA_SOURCE = joinpath(SASVIEW_ROOT, "src", "sas")
39SASVIEW_DOC_TARGET = joinpath(SASVIEW_BUILD, "doc")
40SASVIEW_API_TARGET = joinpath(SPHINX_SOURCE, "dev", "sasview-api")
41
42# sasmodels paths
43SASMODELS_ROOT = joinpath(SASVIEW_ROOT, "..", "sasmodels")
44SASMODELS_DOCS = joinpath(SASMODELS_ROOT, "doc")
45SASMODELS_BUILD = joinpath(SASMODELS_ROOT, "build", "lib")
46SASMODELS_MODEL_SOURCE = joinpath(SASMODELS_DOCS, "model")
47SASMODELS_MODEL_TARGET = joinpath(SPHINX_SOURCE, "user", "models")
48#SASMODELS_API_SOURCE = joinpath(SASMODELS_DOCS, "api")
49SASMODELS_API_TARGET = joinpath(SPHINX_SOURCE, "dev", "sasmodels-api")
50SASMODELS_DEV_SOURCE = joinpath(SASMODELS_DOCS, "developer")
51SASMODELS_DEV_TARGET = joinpath(SPHINX_SOURCE, "dev", "sasmodels-dev")
52SASMODELS_GUIDE_SOURCE = joinpath(SASMODELS_DOCS, "guide")
53SASMODELS_GUIDE_TARGET = joinpath(SPHINX_PERSPECTIVES, "fitting")
54SASMODELS_GUIDE_EXCLUDE = [
55    "index.rst", "install.rst", "intro.rst",
56]
57
58# bumps paths
59BUMPS_DOCS = joinpath(SASVIEW_ROOT, "..", "bumps", "doc")
60BUMPS_SOURCE = joinpath(BUMPS_DOCS, "guide")
61BUMPS_TARGET = joinpath(SPHINX_PERSPECTIVES, "fitting")
62
63run = imp.load_source('run', joinpath(SASVIEW_ROOT, 'run.py'))
64run.prepare()
65
66def inplace_change(filename, old_string, new_string):
67# Thanks to http://stackoverflow.com/questions/4128144/replace-string-within-file-contents
68        s=open(filename).read()
69        if old_string in s:
70                print('Changing "{old_string}" to "{new_string}"'.format(**locals()))
71                s=s.replace(old_string, new_string)
72                f=open(filename, 'w')
73                f.write(s)
74                f.flush()
75                f.close()
76        else:
77                print('No occurences of "{old_string}" found.'.format(**locals()))
78
79def _remove_dir(dir_path):
80    """Removes the given directory."""
81    if isdir(dir_path):
82        print("Removing \"%s\"... " % dir_path)
83        shutil.rmtree(dir_path)
84
85def clean():
86    """
87    Clean the sphinx build directory.
88    """
89    print("=== Cleaning Sphinx Build ===")
90    _remove_dir(SASVIEW_DOC_TARGET)
91    _remove_dir(SPHINX_BUILD)
92    _remove_dir(SPHINX_SOURCE)
93
94def setup_source_temp():
95    """
96    Copy the source toctrees to new folder for assembling the sphinx-docs
97    """
98    print("=== Copying Source toctrees ===")
99    shutil.copytree(SASVIEW_DOCS, SPHINX_SOURCE)
100
101def retrieve_user_docs():
102    """
103    Copies across the contents of any media/ directories in src/, and puts them
104    in an appropriately named directory of docs/sphinx-docs/source/. For
105    example:
106
107        sas/../[MODULE]/media/dir/A.rst
108        sas/../[MODULE]/media/B.rst
109
110    gets copied to a new location:
111
112        docs/sphinx-docs/source/user/[MODULE]/dir/A.rst
113        docs/sphinx-docs/source/user/[MODULE]/B.rst
114
115    so that Sphinx may pick it up when generating the documentation.
116    """
117    print("=== Retrieve User Docs ===")
118
119    # Copy documentation files from sas/.../media to the sphinx directory
120    for root, dirs, _ in os.walk(SASVIEW_MEDIA_SOURCE):
121        if 'media' in dirs:
122            source_dir = abspath(joinpath(root, "media"))
123            relative = dirname(relpath(source_dir, SASVIEW_MEDIA_SOURCE))
124            dest_dir = joinpath(SPHINX_SOURCE, "user", relative)
125
126            print("Found sasview docs folder at \"%s\"." % relative)
127            copy_tree(source_dir, dest_dir)
128
129    print("=== Sasmodels Docs ===")
130    shutil.copy(joinpath(SASMODELS_DOCS, "rst_prolog"), SPHINX_SOURCE)
131    copy_tree(SASMODELS_MODEL_SOURCE, SASMODELS_MODEL_TARGET)
132    #copy_tree(SASMODELS_API_SOURCE, SASMODELS_API_TARGET)
133    copy_tree(SASMODELS_DEV_SOURCE, SASMODELS_DEV_TARGET)
134    copy_tree(SASMODELS_GUIDE_SOURCE, SASMODELS_GUIDE_TARGET)
135    for filename in SASMODELS_GUIDE_EXCLUDE:
136        os.unlink(joinpath(SASMODELS_GUIDE_TARGET, filename))
137
138    # Model category files reference the model as ../../model/name.rst.  Since
139    # we are rearranging the tree, we need to update each of these links.
140    catdir = joinpath(SASMODELS_GUIDE_TARGET, "models")
141    for filename in os.listdir(catdir):
142        inplace_change(joinpath(catdir, filename), "../../model/", "/user/models/")
143
144
145def retrieve_bumps_docs():
146    """
147    Copies select files from the bumps documentation into fitting perspective
148    """
149    if exists(BUMPS_SOURCE):
150        print("=== Retrieve BUMPS Docs ===")
151        filenames = [joinpath(BUMPS_SOURCE, "optimizer.rst")]
152        filenames += glob(joinpath(BUMPS_SOURCE, "dream-*.png"))
153        filenames += glob(joinpath(BUMPS_SOURCE, "fit-*.png"))
154        for f in filenames:
155            print("Copying file", f)
156            shutil.copy(f, BUMPS_TARGET)
157    else:
158        print("""
159======= Error =======
160missing directory %s
161The documentation will not include the optimizer selection section.
162Checkout the bumps source tree and rebuild the docs.
163""" % BUMPS_DOCS)
164
165def apidoc():
166    """
167    Runs sphinx-apidoc to generate .rst files from the docstrings in .py files
168    in the SasView build directory.
169    """
170    print("=== Generate API Rest Files ===")
171
172    # Clean directory before generating a new version.
173    #_remove_dir(SASVIEW_API_TARGET)
174
175    subprocess.call(["sphinx-apidoc",
176                     "-o", SASVIEW_API_TARGET, # Output dir.
177                     "-d", "8", # Max depth of TOC.
178                     "-H", "SasView", # Package header
179                     SASVIEW_BUILD])
180
181    subprocess.call(["sphinx-apidoc",
182                     "-o", SASMODELS_API_TARGET, # Output dir.
183                     "-d", "8", # Max depth of TOC.
184                     "-H", "sasmodels", # Package header
185                     SASMODELS_BUILD,
186                     joinpath(SASMODELS_BUILD, "sasmodels", "models"), # exclude
187                     ])
188
189def build_pdf():
190    """
191    Runs sphinx-build for pdf.  Reads in all .rst files and spits out the final html.
192    """
193    print("=== Build PDF Docs from ReST Files ===")
194    subprocess.call(["sphinx-build",
195                     "-b", "latex", # Builder name. TODO: accept as arg to setup.py.
196                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
197                     SPHINX_SOURCE,
198                     joinpath(SPHINX_BUILD, "latex")])
199
200    LATEXDIR = joinpath(SPHINX_BUILD, "latex")
201    #TODO: Does it need to be done so many time?
202    def pdflatex():
203        subprocess.call(["pdflatex", "SasView.tex"], cwd=LATEXDIR)
204    pdflatex()
205    pdflatex()
206    pdflatex()
207    subprocess.call(["makeindex", "-s", "python.ist", "SasView.idx"], cwd=LATEXDIR)
208    pdflatex()
209    pdflatex()
210
211    print("=== Copy PDF to HTML Directory ===")
212    source = joinpath(LATEXDIR, "SasView.pdf")
213    target = joinpath(SASVIEW_DOC_TARGET, "SasView.pdf")
214    shutil.copyfile(source, target)
215
216def build():
217    """
218    Runs sphinx-build.  Reads in all .rst files and spits out the final html.
219    """
220    print("=== Build HTML Docs from ReST Files ===")
221    subprocess.call(["sphinx-build",
222                     "-b", "qthelp", # Builder name. TODO: accept as arg to setup.py.
223                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
224                     SPHINX_SOURCE,
225                     joinpath(SPHINX_BUILD, "html")])
226
227    print("=== Copy HTML Docs to Build Directory ===")
228    html = joinpath(SPHINX_BUILD, "html")
229    copy_tree(html, SASVIEW_DOC_TARGET)
230
231def fetch_katex(version, destination="_static"):
232    from zipfile import ZipFile
233    import urllib2
234    url = "https://github.com/Khan/KaTeX/releases/download/%s/katex.zip" % version
235    cache_path = "katex_%s.zip" % version
236    if not exists(cache_path):
237        try:
238            fd_in = urllib2.urlopen(url)
239            with open(cache_path, "wb") as fd_out:
240                fd_out.write(fd_in.read())
241        finally:
242            fd_in.close()
243    with ZipFile(cache_path) as zip:
244        zip.extractall(destination)
245
246def convert_katex():
247    print("=== Preprocess HTML, converting latex to html ===")
248    subprocess.call(["node", "convertKaTex.js", SASVIEW_DOC_TARGET])
249
250def convert_mathjax():
251    print("=== Preprocess HTML, converting latex to html ===")
252    subprocess.call(["node", "convertMathJax.js", SASVIEW_DOC_TARGET])
253
254def fetch_mathjax():
255    subprocess.call(["npm", "install", "mathjax-node-page"])
256    # TODO: copy fonts from node_modules/mathjax/fonts/HTML-CSS/Tex into static
257
258def rebuild():
259    clean()
260    setup_source_temp()
261    retrieve_user_docs()
262    retrieve_bumps_docs()
263    #fetch_katex(version=KATEX_VERSION, destination=KATEX_PARENT)
264    #fetch_mathjax()
265    apidoc()
266    build()
267    if find_executable('latex'):
268        build_pdf()
269    #convert_katex()
270    #convert_mathjax()
271
272    print("=== Done ===")
273
274if __name__ == "__main__":
275    rebuild()
Note: See TracBrowser for help on using the repository browser.