source: sasview/docs/sphinx-docs/build_sphinx.py @ 5dba493

Last change on this file since 5dba493 was db7d2c7, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Moved fitting algorithm help images to sasview. Temporarily for SASVIEW-947

  • 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 = glob(joinpath(BUMPS_SOURCE, "dream-*.png"))
152        #filenames = [joinpath(BUMPS_SOURCE, "optimizer.rst")]
153        #filenames += glob(joinpath(BUMPS_SOURCE, "dream-*.png"))
154        #filenames += glob(joinpath(BUMPS_SOURCE, "fit-*.png"))
155        for f in filenames:
156            print("Copying file", f)
157            shutil.copy(f, BUMPS_TARGET)
158    else:
159        print("""
160======= Error =======
161missing directory %s
162The documentation will not include the optimizer selection section.
163Checkout the bumps source tree and rebuild the docs.
164""" % BUMPS_DOCS)
165
166def apidoc():
167    """
168    Runs sphinx-apidoc to generate .rst files from the docstrings in .py files
169    in the SasView build directory.
170    """
171    print("=== Generate API Rest Files ===")
172
173    # Clean directory before generating a new version.
174    #_remove_dir(SASVIEW_API_TARGET)
175
176    subprocess.call(["sphinx-apidoc",
177                     "-o", SASVIEW_API_TARGET, # Output dir.
178                     "-d", "8", # Max depth of TOC.
179                     "-H", "SasView", # Package header
180                     SASVIEW_BUILD])
181
182    subprocess.call(["sphinx-apidoc",
183                     "-o", SASMODELS_API_TARGET, # Output dir.
184                     "-d", "8", # Max depth of TOC.
185                     "-H", "sasmodels", # Package header
186                     SASMODELS_BUILD,
187                     joinpath(SASMODELS_BUILD, "sasmodels", "models"), # exclude
188                     ])
189
190def build_pdf():
191    """
192    Runs sphinx-build for pdf.  Reads in all .rst files and spits out the final html.
193    """
194    print("=== Build PDF Docs from ReST Files ===")
195    subprocess.call(["sphinx-build",
196                     "-b", "latex", # Builder name. TODO: accept as arg to setup.py.
197                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
198                     SPHINX_SOURCE,
199                     joinpath(SPHINX_BUILD, "latex")])
200
201    LATEXDIR = joinpath(SPHINX_BUILD, "latex")
202    #TODO: Does it need to be done so many time?
203    def pdflatex():
204        subprocess.call(["pdflatex", "SasView.tex"], cwd=LATEXDIR)
205    pdflatex()
206    pdflatex()
207    pdflatex()
208    subprocess.call(["makeindex", "-s", "python.ist", "SasView.idx"], cwd=LATEXDIR)
209    pdflatex()
210    pdflatex()
211
212    print("=== Copy PDF to HTML Directory ===")
213    source = joinpath(LATEXDIR, "SasView.pdf")
214    target = joinpath(SASVIEW_DOC_TARGET, "SasView.pdf")
215    shutil.copyfile(source, target)
216
217def build():
218    """
219    Runs sphinx-build.  Reads in all .rst files and spits out the final html.
220    """
221    print("=== Build HTML Docs from ReST Files ===")
222    subprocess.call(["sphinx-build",
223                     "-b", "qthelp", # Builder name. TODO: accept as arg to setup.py.
224                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
225                     SPHINX_SOURCE,
226                     joinpath(SPHINX_BUILD, "html")])
227
228    print("=== Copy HTML Docs to Build Directory ===")
229    html = joinpath(SPHINX_BUILD, "html")
230    copy_tree(html, SASVIEW_DOC_TARGET)
231
232def fetch_katex(version, destination="_static"):
233    from zipfile import ZipFile
234    import urllib2
235    url = "https://github.com/Khan/KaTeX/releases/download/%s/katex.zip" % version
236    cache_path = "katex_%s.zip" % version
237    if not exists(cache_path):
238        try:
239            fd_in = urllib2.urlopen(url)
240            with open(cache_path, "wb") as fd_out:
241                fd_out.write(fd_in.read())
242        finally:
243            fd_in.close()
244    with ZipFile(cache_path) as zip:
245        zip.extractall(destination)
246
247def convert_katex():
248    print("=== Preprocess HTML, converting latex to html ===")
249    subprocess.call(["node", "convertKaTex.js", SASVIEW_DOC_TARGET])
250
251def convert_mathjax():
252    print("=== Preprocess HTML, converting latex to html ===")
253    subprocess.call(["node", "convertMathJax.js", SASVIEW_DOC_TARGET])
254
255def fetch_mathjax():
256    subprocess.call(["npm", "install", "mathjax-node-page"])
257    # TODO: copy fonts from node_modules/mathjax/fonts/HTML-CSS/Tex into static
258
259def rebuild():
260    clean()
261    setup_source_temp()
262    retrieve_user_docs()
263    retrieve_bumps_docs()
264    #fetch_katex(version=KATEX_VERSION, destination=KATEX_PARENT)
265    #fetch_mathjax()
266    apidoc()
267    build()
268    if find_executable('latex'):
269        build_pdf()
270    #convert_katex()
271    #convert_mathjax()
272
273    print("=== Done ===")
274
275if __name__ == "__main__":
276    rebuild()
Note: See TracBrowser for help on using the repository browser.