source: sasview/docs/sphinx-docs/build_sphinx.py @ 417c03f

ESS_GUIESS_GUI_DocsESS_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 417c03f was 417c03f, checked in by Piotr Rozyczko <rozyczko@…>, 6 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
RevLine 
[9bf64f6]1#!/usr/bin/env python
[35bf493]2"""
3Functions for building sphinx docs.
4
5For more information on the invocation of sphinx see:
6http://sphinx-doc.org/invocation.html
7"""
[01f1e17]8from __future__ import print_function
9
[35bf493]10import subprocess
11import os
[3bd677b]12from os.path import join as joinpath, abspath, dirname, isdir, exists, relpath
[35bf493]13import sys
14import fnmatch
15import shutil
[296f290]16import imp
[35bf493]17
[21bba86]18from glob import glob
[35bf493]19from distutils.dir_util import copy_tree
20from distutils.util import get_platform
[1573220]21from distutils.spawn import find_executable
22
[d2143ab]23from shutil import copy
[b7a2ebfd]24from os import listdir
[35bf493]25
[90d9cd3]26platform = '.%s-%s'%(get_platform(),sys.version[:3])
[35bf493]27
[3bd677b]28# sphinx paths
29SPHINX_ROOT = dirname(abspath(__file__))
30SPHINX_BUILD = joinpath(SPHINX_ROOT, "build")
31SPHINX_SOURCE = joinpath(SPHINX_ROOT, "source-temp")
[417c03f]32SPHINX_PERSPECTIVES = joinpath(SPHINX_SOURCE, "user", "qtgui", "perspectives")
[3bd677b]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'))
[296f290]64run.prepare()
65
[bb0c836]66def inplace_change(filename, old_string, new_string):
67# Thanks to http://stackoverflow.com/questions/4128144/replace-string-within-file-contents
[90d9cd3]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()))
[bb0c836]78
[35bf493]79def _remove_dir(dir_path):
80    """Removes the given directory."""
[3bd677b]81    if isdir(dir_path):
[21bba86]82        print("Removing \"%s\"... " % dir_path)
[35bf493]83        shutil.rmtree(dir_path)
84
85def clean():
86    """
87    Clean the sphinx build directory.
88    """
[f4d571b]89    print("=== Cleaning Sphinx Build ===")
[3bd677b]90    _remove_dir(SASVIEW_DOC_TARGET)
[35bf493]91    _remove_dir(SPHINX_BUILD)
[5dd7499]92    _remove_dir(SPHINX_SOURCE)
[35bf493]93
[5dd7499]94def setup_source_temp():
95    """
96    Copy the source toctrees to new folder for assembling the sphinx-docs
97    """
[f4d571b]98    print("=== Copying Source toctrees ===")
[3bd677b]99    shutil.copytree(SASVIEW_DOCS, SPHINX_SOURCE)
[354524d]100
[35bf493]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    """
[f4d571b]117    print("=== Retrieve User Docs ===")
[35bf493]118
[3bd677b]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
[6a9c0e5a]144
[c22c5e3]145def retrieve_bumps_docs():
146    """
147    Copies select files from the bumps documentation into fitting perspective
148    """
[3bd677b]149    if exists(BUMPS_SOURCE):
[f4d571b]150        print("=== Retrieve BUMPS Docs ===")
[3bd677b]151        filenames = [joinpath(BUMPS_SOURCE, "optimizer.rst")]
152        filenames += glob(joinpath(BUMPS_SOURCE, "dream-*.png"))
153        filenames += glob(joinpath(BUMPS_SOURCE, "fit-*.png"))
[c22c5e3]154        for f in filenames:
[f4d571b]155            print("Copying file", f)
[c22c5e3]156            shutil.copy(f, BUMPS_TARGET)
157    else:
[f4d571b]158        print("""
[01f1e17]159======= Error =======
160missing directory %s
[c22c5e3]161The documentation will not include the optimizer selection section.
162Checkout the bumps source tree and rebuild the docs.
[f4d571b]163""" % BUMPS_DOCS)
[c22c5e3]164
[35bf493]165def apidoc():
166    """
167    Runs sphinx-apidoc to generate .rst files from the docstrings in .py files
168    in the SasView build directory.
169    """
[f4d571b]170    print("=== Generate API Rest Files ===")
[35bf493]171
172    # Clean directory before generating a new version.
[3bd677b]173    #_remove_dir(SASVIEW_API_TARGET)
[35bf493]174
175    subprocess.call(["sphinx-apidoc",
[3bd677b]176                     "-o", SASVIEW_API_TARGET, # Output dir.
[35bf493]177                     "-d", "8", # Max depth of TOC.
[3bd677b]178                     "-H", "SasView", # Package header
[35bf493]179                     SASVIEW_BUILD])
180
[3bd677b]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
[3194371]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.
[3bd677b]196                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
[3194371]197                     SPHINX_SOURCE,
[3bd677b]198                     joinpath(SPHINX_BUILD, "latex")])
[3194371]199
[3bd677b]200    LATEXDIR = joinpath(SPHINX_BUILD, "latex")
[1573220]201    #TODO: Does it need to be done so many time?
[3194371]202    def pdflatex():
[6e546f8]203        subprocess.call(["pdflatex", "SasView.tex"], cwd=LATEXDIR)
[3194371]204    pdflatex()
205    pdflatex()
206    pdflatex()
[6e546f8]207    subprocess.call(["makeindex", "-s", "python.ist", "SasView.idx"], cwd=LATEXDIR)
[3194371]208    pdflatex()
209    pdflatex()
210
211    print("=== Copy PDF to HTML Directory ===")
[3bd677b]212    source = joinpath(LATEXDIR, "SasView.pdf")
213    target = joinpath(SASVIEW_DOC_TARGET, "SasView.pdf")
[3194371]214    shutil.copyfile(source, target)
215
[35bf493]216def build():
217    """
218    Runs sphinx-build.  Reads in all .rst files and spits out the final html.
219    """
[3194371]220    print("=== Build HTML Docs from ReST Files ===")
[35bf493]221    subprocess.call(["sphinx-build",
[e90988c]222                     "-b", "qthelp", # Builder name. TODO: accept as arg to setup.py.
[3bd677b]223                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
[35bf493]224                     SPHINX_SOURCE,
[3bd677b]225                     joinpath(SPHINX_BUILD, "html")])
[35bf493]226
[f4d571b]227    print("=== Copy HTML Docs to Build Directory ===")
[3bd677b]228    html = joinpath(SPHINX_BUILD, "html")
229    copy_tree(html, SASVIEW_DOC_TARGET)
[35bf493]230
[f4771596]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
[3bd677b]236    if not exists(cache_path):
[f4771596]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
[3194371]246def convert_katex():
247    print("=== Preprocess HTML, converting latex to html ===")
[3bd677b]248    subprocess.call(["node", "convertKaTex.js", SASVIEW_DOC_TARGET])
[3194371]249
[f4771596]250def convert_mathjax():
251    print("=== Preprocess HTML, converting latex to html ===")
[3bd677b]252    subprocess.call(["node", "convertMathJax.js", SASVIEW_DOC_TARGET])
[f4771596]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
[c2ee2b1]258def rebuild():
[35bf493]259    clean()
[5dd7499]260    setup_source_temp()
[35bf493]261    retrieve_user_docs()
[c22c5e3]262    retrieve_bumps_docs()
[f4771596]263    #fetch_katex(version=KATEX_VERSION, destination=KATEX_PARENT)
264    #fetch_mathjax()
[35bf493]265    apidoc()
266    build()
[3d37fe9]267    if find_executable('latex'):
[df72475]268        build_pdf()
[3194371]269    #convert_katex()
[f4771596]270    #convert_mathjax()
[c2ee2b1]271
[f4d571b]272    print("=== Done ===")
[c2ee2b1]273
274if __name__ == "__main__":
[9bf64f6]275    rebuild()
Note: See TracBrowser for help on using the repository browser.