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

Last change on this file since f38d027 was 5f9e874, checked in by wojciech, 6 years ago

Fix for making sasmodels doc working on linux

  • 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")
[5f9e874]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")
[5f9e874]53SASMODELS_GUIDE_TARGET = joinpath(SPHINX_PERSPECTIVES, "Fitting")
[3bd677b]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")
[5f9e874]61BUMPS_TARGET = joinpath(SPHINX_PERSPECTIVES, "Fitting")
[3bd677b]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 ===")
[db7d2c7]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"))
[c22c5e3]155        for f in filenames:
[f4d571b]156            print("Copying file", f)
[c22c5e3]157            shutil.copy(f, BUMPS_TARGET)
158    else:
[f4d571b]159        print("""
[01f1e17]160======= Error =======
161missing directory %s
[c22c5e3]162The documentation will not include the optimizer selection section.
163Checkout the bumps source tree and rebuild the docs.
[f4d571b]164""" % BUMPS_DOCS)
[c22c5e3]165
[35bf493]166def apidoc():
167    """
168    Runs sphinx-apidoc to generate .rst files from the docstrings in .py files
169    in the SasView build directory.
170    """
[f4d571b]171    print("=== Generate API Rest Files ===")
[35bf493]172
173    # Clean directory before generating a new version.
[3bd677b]174    #_remove_dir(SASVIEW_API_TARGET)
[35bf493]175
176    subprocess.call(["sphinx-apidoc",
[3bd677b]177                     "-o", SASVIEW_API_TARGET, # Output dir.
[35bf493]178                     "-d", "8", # Max depth of TOC.
[3bd677b]179                     "-H", "SasView", # Package header
[35bf493]180                     SASVIEW_BUILD])
181
[3bd677b]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
[3194371]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.
[3bd677b]197                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
[3194371]198                     SPHINX_SOURCE,
[3bd677b]199                     joinpath(SPHINX_BUILD, "latex")])
[3194371]200
[3bd677b]201    LATEXDIR = joinpath(SPHINX_BUILD, "latex")
[1573220]202    #TODO: Does it need to be done so many time?
[3194371]203    def pdflatex():
[6e546f8]204        subprocess.call(["pdflatex", "SasView.tex"], cwd=LATEXDIR)
[3194371]205    pdflatex()
206    pdflatex()
207    pdflatex()
[6e546f8]208    subprocess.call(["makeindex", "-s", "python.ist", "SasView.idx"], cwd=LATEXDIR)
[3194371]209    pdflatex()
210    pdflatex()
211
212    print("=== Copy PDF to HTML Directory ===")
[3bd677b]213    source = joinpath(LATEXDIR, "SasView.pdf")
214    target = joinpath(SASVIEW_DOC_TARGET, "SasView.pdf")
[3194371]215    shutil.copyfile(source, target)
216
[35bf493]217def build():
218    """
219    Runs sphinx-build.  Reads in all .rst files and spits out the final html.
220    """
[3194371]221    print("=== Build HTML Docs from ReST Files ===")
[35bf493]222    subprocess.call(["sphinx-build",
[f1b696d]223                     "-b", "html", # Builder name. TODO: accept as arg to setup.py.
[3bd677b]224                     "-d", joinpath(SPHINX_BUILD, "doctrees"),
[35bf493]225                     SPHINX_SOURCE,
[3bd677b]226                     joinpath(SPHINX_BUILD, "html")])
[35bf493]227
[f4d571b]228    print("=== Copy HTML Docs to Build Directory ===")
[3bd677b]229    html = joinpath(SPHINX_BUILD, "html")
230    copy_tree(html, SASVIEW_DOC_TARGET)
[35bf493]231
[f4771596]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
[3bd677b]237    if not exists(cache_path):
[f4771596]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
[3194371]247def convert_katex():
248    print("=== Preprocess HTML, converting latex to html ===")
[3bd677b]249    subprocess.call(["node", "convertKaTex.js", SASVIEW_DOC_TARGET])
[3194371]250
[f4771596]251def convert_mathjax():
252    print("=== Preprocess HTML, converting latex to html ===")
[3bd677b]253    subprocess.call(["node", "convertMathJax.js", SASVIEW_DOC_TARGET])
[f4771596]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
[c2ee2b1]259def rebuild():
[35bf493]260    clean()
[5dd7499]261    setup_source_temp()
[35bf493]262    retrieve_user_docs()
[c22c5e3]263    retrieve_bumps_docs()
[f4771596]264    #fetch_katex(version=KATEX_VERSION, destination=KATEX_PARENT)
265    #fetch_mathjax()
[35bf493]266    apidoc()
267    build()
[3d37fe9]268    if find_executable('latex'):
[df72475]269        build_pdf()
[3194371]270    #convert_katex()
[f4771596]271    #convert_mathjax()
[c2ee2b1]272
[f4d571b]273    print("=== Done ===")
[c2ee2b1]274
275if __name__ == "__main__":
[9bf64f6]276    rebuild()
Note: See TracBrowser for help on using the repository browser.