== Python API docs ==
authorLuca Bonavita <mindrones@gmail.com>
Fri, 16 Mar 2012 10:49:39 +0000 (10:49 +0000)
committerLuca Bonavita <mindrones@gmail.com>
Fri, 16 Mar 2012 10:49:39 +0000 (10:49 +0000)
Committing a patch similar to revision 44887 with fixes to my own bugs
(sorry Campbell, and thanks for reviewing :)

Fixes
------
- examples/ svn directory not removed anymore (in-source builds possible again)
- fixed "include references somehow stopped working"
+ using shutils.makearchive() to zip the file

New command line options
------------------------

-l: Log the output of the api dump and sphinx|latex warnings and errors
    If given, save logs in:
    * OUTPUT_DIR/.bpy.log
    * OUTPUT_DIR/.sphinx-build.log
    * OUTPUT_DIR/.sphinx-build_pdf.log
    * OUTPUT_DIR/.latex_make.log

    (using only one log directive instead of -l for bpy and -L for sphinx)

-P: builds the pdf

-R: pack the files in a dir ready for online deployment
    (including the zip and the pdf eventually)

Example usage:
./blender.bin -b -P doc/python_api/sphinx_doc_gen.py -- -p bmesh* -o ./<OUTPUTDIR> -B -P -R -l

doc/python_api/sphinx_doc_gen.py

index b15fcd9303b1f42a89a4d2635d9a4c7710b096c6..327707facc7ebfd59961c6d5413e345a6b173d86 100644 (file)
@@ -26,16 +26,16 @@ API dump in RST files
 ---------------------
   Run this script from blenders root path once you have compiled blender
 
-    ./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py
+    ./blender.bin --background -noaudio --python doc/python_api/sphinx_doc_gen.py
 
   This will generate python files in doc/python_api/sphinx-in/
   providing ./blender.bin is or links to the blender executable
 
   To choose sphinx-in directory:
-    ./blender.bin -b -P doc/python_api/sphinx_doc_gen.py -- -o ../python_api
+    ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- -o ../python_api
 
   For quick builds:
-    ./blender.bin -b -P doc/python_api/sphinx_doc_gen.py -- -q
+    ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- -p
 
 
 Sphinx: HTML generation
@@ -75,6 +75,7 @@ import os
 import sys
 import inspect
 import shutil
+import logging
 
 from platform import platform
 PLATFORM = platform().split('-')[0].lower()    # 'linux', 'darwin', 'windows'
@@ -94,27 +95,36 @@ def handle_args():
         usage=SCRIPT_HELP_MSG
     )
 
-    # optional arguments    
-    parser.add_argument("-o", "--output",
-                        dest="output_dir",
+    # optional arguments
+    parser.add_argument("-p", "--partial",
+                        dest="partial",
                         type=str,
-                        default=SCRIPT_DIR,
-                        # XXX, THIS ISNT WORKING, EXAMPLE SCRIPTS WILL NOT BE FOUND
-                        help="Path of the API docs (default=<script dir>).",
+                        default="",
+                        help="Use a wildcard to only build specific module(s)\n"
+                             "Example: --partial bmesh*\n",
                         required=False)
 
-    parser.add_argument("-B", "--sphinx-build",
-                        dest="sphinx_build",
+    parser.add_argument("-f", "--fullrebuild",
+                        dest="full_rebuild",
                         default=False,
                         action='store_true',
-                        help="Run sphinx-build SPHINX_IN SPHINX_OUT (default=False)",
+                        help="Rewrite all rst files in sphinx-in/ "
+                             "(default=False)",
                         required=False)
 
-    parser.add_argument("-N", "--sphinx-named-output",
-                        dest="sphinx_named_output",
+    parser.add_argument("-b", "--bpy",
+                        dest="bpy",
                         default=False,
                         action='store_true',
-                        help="Add the theme name to the html dir name (default=False)",
+                        help="Write the rst file of the bpy module "
+                             "(default=False)",
+                        required=False)
+
+    parser.add_argument("-o", "--output",
+                        dest="output_dir",
+                        type=str,
+                        default=SCRIPT_DIR,
+                        help="Path of the API docs (default=<script dir>)",
                         required=False)
 
     parser.add_argument("-T", "--sphinx-theme",
@@ -135,25 +145,53 @@ def handle_args():
 #                                 'sphinxdoc', 'traditional'],   # sphinx
                         required=False)
 
-    parser.add_argument("-f", "--fullrebuild",
-                        dest="full_rebuild",
+    parser.add_argument("-N", "--sphinx-named-output",
+                        dest="sphinx_named_output",
                         default=False,
                         action='store_true',
-                        help="Rewrite all rst files in sphinx-in/ (default=False)",
+                        help="Add the theme name to the html dir name.\n"
+                             "Example: \"sphinx-out_haiku\" (default=False)",
                         required=False)
 
-    parser.add_argument("-p", "--partial",
-                        dest="partial",
-                        type=str,
-                        default="",
-                        help="Use a wildcard to only build spesific module(s)",
+    parser.add_argument("-B", "--sphinx-build",
+                        dest="sphinx_build",
+                        default=False,
+                        action='store_true',
+                        help="Build the html docs by running:\n"
+                             "sphinx-build SPHINX_IN SPHINX_OUT\n"
+                             "(default=False; does not depend on -P)",
                         required=False)
 
-    parser.add_argument("-b", "--bpy",
-                        dest="bpy",
+    parser.add_argument("-P", "--sphinx-build-pdf",
+                        dest="sphinx_build_pdf",
+                        default=False,
+                        action='store_true',
+                        help="Build the pdf by running:\n"
+                             "sphinx-build -b latex SPHINX_IN SPHINX_OUT_PDF\n"
+                             "(default=False; does not depend on -B)",
+                        required=False)
+
+    parser.add_argument("-R", "--pack-reference",
+                        dest="pack_reference",
+                        default=False,
+                        action='store_true',
+                        help="Pack all necessary files in the deployed dir.\n"
+                             "(default=False; use with -B and -P)",
+                        required=False)
+
+    parser.add_argument("-l", "--log",
+                        dest="log",
                         default=False,
                         action='store_true',
-                        help="Write the rst file of the bpy module (default=False)",
+                        help=(
+                        "Log the output of the api dump and sphinx|latex "
+                        "warnings and errors (default=False).\n"
+                        "If given, save logs in:\n"
+                        "* OUTPUT_DIR/.bpy.log\n"
+                        "* OUTPUT_DIR/.sphinx-build.log\n"
+                        "* OUTPUT_DIR/.sphinx-build_pdf.log\n"
+                        "* OUTPUT_DIR/.latex_make.log",
+                        ),
                         required=False)
 
     # parse only the args passed after '--'
@@ -168,11 +206,29 @@ ARGS = handle_args()
 
 # ----------------------------------BPY-----------------------------------------
 
+BPY_LOGGER = logging.getLogger('bpy')
+BPY_LOGGER.setLevel(logging.DEBUG)
+
+if ARGS.log:
+    BPY_LOGFILE = os.path.join(ARGS.output_dir, ".bpy.log")
+    bpy_logfilehandler = logging.FileHandler(BPY_LOGFILE, mode="w")
+    bpy_logfilehandler.setLevel(logging.DEBUG)
+    BPY_LOGGER.addHandler(bpy_logfilehandler)
+
+    # using a FileHandler seems to disable the stdout, so we add a StreamHandler
+    bpy_log_stdout_handler = logging.StreamHandler(stream=sys.stdout)
+    bpy_log_stdout_handler.setLevel(logging.DEBUG)
+    BPY_LOGGER.addHandler(bpy_log_stdout_handler)
+
 """
 # for quick rebuilds
 rm -rf /b/doc/python_api/sphinx-* && \
-./blender.bin --background -noaudio --factory-startup --python  doc/python_api/sphinx_doc_gen.py && \
+./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \
 sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
+
+or
+
+./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
 """
 
 # Switch for quick testing so doc-builds don't take so long
@@ -228,7 +284,7 @@ else:
     del m
     del fnmatch
 
-    print("Partial Doc Build, Skipping: %s\n" % "\n                             ".join(sorted(EXCLUDE_MODULES)))
+    BPY_LOGGER.debug("Partial Doc Build, Skipping: %s\n" % "\n                             ".join(sorted(EXCLUDE_MODULES)))
 
     #
     # done filtering
@@ -237,7 +293,7 @@ else:
 try:
     __import__("aud")
 except ImportError:
-    print("Warning: Built without 'aud' module, docs incomplete...")
+    BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...")
     EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", )
 
 # examples
@@ -248,7 +304,7 @@ for f in os.listdir(EXAMPLES_DIR):
         EXAMPLE_SET.add(os.path.splitext(f)[0])
 EXAMPLE_SET_USED = set()
 
-#rst files dir
+# rst files dir
 RST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "rst"))
 
 # extra info, not api reference docs
@@ -268,9 +324,35 @@ RNA_BLACKLIST = {
     }
 
 
+# --------------------configure compile time options----------------------------
+
+# -------------------------------BLENDER----------------------------------------
+
+blender_version_strings = [str(v) for v in bpy.app.version]
+
+# converting bytes to strings, due to #30154
+BLENDER_REVISION = str(bpy.app.build_revision, 'utf_8')
+BLENDER_DATE = str(bpy.app.build_date, 'utf_8')
+
+BLENDER_VERSION_DOTS = ".".join(blender_version_strings)    # '2.62.1'
+if BLENDER_REVISION != "Unknown":
+    BLENDER_VERSION_DOTS += " r" + BLENDER_REVISION         # '2.62.1 r44584'
+
+BLENDER_VERSION_PATH = "_".join(blender_version_strings)    # '2_62_1'
+if bpy.app.version_cycle == "release":
+    BLENDER_VERSION_PATH = "%s%s_release" % ("_".join(blender_version_strings[:2]),
+                                             bpy.app.version_char)   # '2_62_release'
+
+# --------------------------DOWNLOADABLE FILES----------------------------------
+
+REFERENCE_NAME = "blender_python_reference_%s" % BLENDER_VERSION_PATH
+REFERENCE_PATH = os.path.join(ARGS.output_dir, REFERENCE_NAME)
+BLENDER_PDF_FILENAME = "%s.pdf" % REFERENCE_NAME
+BLENDER_ZIP_FILENAME = "%s.zip" % REFERENCE_NAME
+
 # -------------------------------SPHINX-----------------------------------------
 
-SPHINX_THEMES = {'bf': ['blender-org'], # , 'naiad',
+SPHINX_THEMES = {'bf': ['blender-org'],  # , 'naiad',
                  'sphinx': ['agogo',
                             'basic',
                             'default',
@@ -286,37 +368,43 @@ if ARGS.sphinx_theme not in available_themes:
     print ("Please choose a theme among: %s" % ', '.join(available_themes))
     sys.exit()
 
+if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
+    SPHINX_THEME_DIR = os.path.join(ARGS.output_dir, ARGS.sphinx_theme)
+    SPHINX_THEME_SVN_DIR = os.path.join(SCRIPT_DIR, ARGS.sphinx_theme)
+
 SPHINX_IN = os.path.join(ARGS.output_dir, "sphinx-in")
 SPHINX_IN_TMP = SPHINX_IN + "-tmp"
 SPHINX_OUT = os.path.join(ARGS.output_dir, "sphinx-out")
 if ARGS.sphinx_named_output:
     SPHINX_OUT += "_%s" % ARGS.sphinx_theme
 
-if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
-    SPHINX_THEME_DIR = os.path.join(ARGS.output_dir, ARGS.sphinx_theme)
-    SPHINX_THEME_SVN_DIR = os.path.join(SCRIPT_DIR, ARGS.sphinx_theme)
-
-# ------------------------------------------------------------------------------
-
-# configure compile time options
-
-# -------------------------------BLENDER----------------------------------------
-
-'''
-blender version
-'''
-version_strings = [str(v) for v in bpy.app.version]
-
-BLENDER_VERSION_DOTS = ".".join(version_strings)    # '2.62.1'
-if bpy.app.build_revision != b"Unknown":
-    # converting bytes to strings, due to #30154
-    BLENDER_VERSION_DOTS += " r" + str(bpy.app.build_revision, 'utf_8')    # '2.62.1 r44584'
-
-BLENDER_VERSION_PDF = "_".join(version_strings)    # '2_62_1'
-if bpy.app.version_cycle == "release":
-    BLENDER_VERSION_PDF = "%s%s_release" % ("_".join(version_strings[:2]),
-                                            bpy.app.version_char)   # '2_62_release'
-
+# html build
+if ARGS.sphinx_build:
+    SPHINX_BUILD = ["sphinx-build", SPHINX_IN, SPHINX_OUT]
+
+    if ARGS.log:
+        SPHINX_BUILD_LOG = os.path.join(ARGS.output_dir, ".sphinx-build.log")
+        SPHINX_BUILD = ["sphinx-build",
+                        "-w", SPHINX_BUILD_LOG,
+                        SPHINX_IN, SPHINX_OUT]
+
+# pdf build
+if ARGS.sphinx_build_pdf:
+    SPHINX_OUT_PDF = os.path.join(ARGS.output_dir, "sphinx-out_pdf")
+    SPHINX_BUILD_PDF = ["sphinx-build",
+                        "-b", "latex",
+                        SPHINX_IN, SPHINX_OUT_PDF]
+    SPHINX_MAKE_PDF = ["make", "-C", SPHINX_OUT_PDF]
+    SPHINX_MAKE_PDF_STDOUT = None
+
+    if ARGS.log:
+        SPHINX_BUILD_PDF_LOG = os.path.join(ARGS.output_dir, ".sphinx-build_pdf.log")
+        SPHINX_BUILD_PDF = ["sphinx-build", "-b", "latex",
+                            "-w", SPHINX_BUILD_PDF_LOG,
+                            SPHINX_IN, SPHINX_OUT_PDF]
+
+        sphinx_make_pdf_log = os.path.join(ARGS.output_dir, ".latex_make.log")
+        SPHINX_MAKE_PDF_STDOUT = open(sphinx_make_pdf_log, "w", encoding="utf-8")
 
 # --------------------------------API DUMP--------------------------------------
 
@@ -344,13 +432,13 @@ def undocumented_message(module_name, type_name, identifier):
         preloadtitle = '%s.%s' % (module_name, identifier)
     else:
         preloadtitle = '%s.%s.%s' % (module_name, type_name, identifier)
-    message =   "Undocumented (`contribute "\
-                "<http://wiki.blender.org/index.php/"\
-                "Dev:2.5/Py/API/Generating_API_Reference/Contribute/Howto-message"\
-                "?action=edit"\
-                "&section=new"\
-                "&preload=Dev:2.5/Py/API/Documentation/Contribute/Howto-message"\
-                "&preloadtitle=%s>`_)\n\n" % preloadtitle
+    message = ("Undocumented (`contribute "
+               "<http://wiki.blender.org/index.php/"
+               "Dev:2.5/Py/API/Generating_API_Reference/Contribute"
+               "?action=edit"
+               "&section=new"
+               "&preload=Dev:2.5/Py/API/Generating_API_Reference/Contribute/Howto-message"
+               "&preloadtitle=%s>`_)\n\n" % preloadtitle)
     return message
 
 
@@ -400,7 +488,7 @@ def write_example_ref(ident, fw, example_id, ext="py"):
     if example_id in EXAMPLE_SET:
 
         # extract the comment
-        filepath = os.path.join(EXAMPLES_DIR, "%s.%s" % (example_id, ext))
+        filepath = os.path.join("..", "examples", "%s.%s" % (example_id, ext))
         filepath_full = os.path.join(os.path.dirname(fw.__self__.name), filepath)
 
         text, line_no = example_extract_docstring(filepath_full)
@@ -416,7 +504,7 @@ def write_example_ref(ident, fw, example_id, ext="py"):
         EXAMPLE_SET_USED.add(example_id)
     else:
         if bpy.app.debug:
-            print("\tskipping example:", example_id)
+            BPY_LOGGER.debug("\tskipping example: " + example_id)
 
     # Support for numbered files bpy.types.Operator -> bpy.types.Operator.1.py
     i = 1
@@ -703,7 +791,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
             write_indented_lines("   ", fw, "constant value %s" % repr(value), False)
             fw("\n")
         else:
-            print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
+            BPY_LOGGER.debug("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
             continue
 
         attribute_set.add(attribute)
@@ -711,7 +799,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
     del module_dir_value_type
 
     # TODO, bpy_extras does this already, mathutils not.
-    """
+    '''
     if submodules:
         fw("\n"
            "**********\n"
@@ -722,7 +810,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
         for attribute, submod in submodules:
             fw("* :mod:`%s.%s`\n" % (module_name, attribute))
         fw("\n")
-    """
+    '''
 
     # write collected classes now
     for (type_name, value) in classes:
@@ -1313,11 +1401,11 @@ def write_rst_contents(basepath):
     fw(" Blender Documentation contents\n")
     fw("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
     fw("\n")
-    fw("Welcome, this document is an API reference for Blender %s. built %s.\n" % (BLENDER_VERSION_DOTS, str(bpy.app.build_date, 'utf_8')))
+    fw("Welcome, this document is an API reference for Blender %s, built %s.\n" % (BLENDER_VERSION_DOTS, BLENDER_DATE))
     fw("\n")
 
-    # fw("`A PDF version of this document is also available <blender_python_reference_%s.pdf>`_\n" % BLENDER_VERSION_PDF)
-    fw("`A compressed ZIP file of this site is available <blender_python_reference_%s.zip>`_\n" % BLENDER_VERSION_PDF)
+    # fw("`A PDF version of this document is also available <%s>`_\n" % BLENDER_PDF_FILENAME)
+    fw("`A compressed ZIP file of this site is available <%s>`_\n" % BLENDER_ZIP_FILENAME)
 
     fw("\n")
 
@@ -1604,7 +1692,7 @@ def align_sphinx_in_to_sphinx_in_tmp():
     # remove deprecated files that have been removed
     for f in sorted(sphinx_in_files):
         if f not in sphinx_in_tmp_files:
-            print("\tdeprecated: %s" % f)
+            BPY_LOGGER.debug("\tdeprecated: %s" % f)
             os.remove(os.path.join(SPHINX_IN, f))
 
     # freshen with new files.
@@ -1618,53 +1706,128 @@ def align_sphinx_in_to_sphinx_in_tmp():
                 do_copy = False
 
         if do_copy:
-            print("\tupdating: %s" % f)
+            BPY_LOGGER.debug("\tupdating: %s" % f)
             shutil.copy(f_from, f_to)
 
 
+def refactor_sphinx_log(sphinx_logfile):
+    refactored_log = []
+    with open(sphinx_logfile, "r", encoding="utf-8") as original_logfile:
+        lines = set(original_logfile.readlines())
+        for line in lines:
+            if 'warning' in line.lower() or 'error' in line.lower():
+                line = line.strip().split(None, 2)
+                if len(line) == 3:
+                    location, kind, msg = line
+                    location = os.path.relpath(location, start=SPHINX_IN)
+                    refactored_log.append((kind, location, msg))
+    with open(sphinx_logfile, "w", encoding="utf-8") as refactored_logfile:
+        for log in sorted(refactored_log):
+            refactored_logfile.write("%-12s %s\n             %s\n" % log)
+
+
 def main():
 
-    # dirs preparation
+    # eventually, create the dirs
     for dir_path in [ARGS.output_dir, SPHINX_IN]:
         if not os.path.exists(dir_path):
             os.mkdir(dir_path)
 
+    # in case of out-of-source build, copy the needed dirs
+    if ARGS.output_dir != SCRIPT_DIR:
+        # examples dir
+        examples_dir_copy = os.path.join(ARGS.output_dir, "examples")
+        if os.path.exists(examples_dir_copy):
+            shutil.rmtree(examples_dir_copy, True)
+        shutil.copytree(EXAMPLES_DIR,
+                        examples_dir_copy,
+                        ignore=shutil.ignore_patterns(*(".svn",)),
+                        copy_function=shutil.copy)
+
+        # eventually, copy the theme dir
+        if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
+            if os.path.exists(SPHINX_THEME_DIR):
+                shutil.rmtree(SPHINX_THEME_DIR, True)
+            shutil.copytree(SPHINX_THEME_SVN_DIR,
+                            SPHINX_THEME_DIR,
+                            ignore=shutil.ignore_patterns(*(".svn",)),
+                            copy_function=shutil.copy)
+
     # dump the api in rst files
+    if os.path.exists(SPHINX_IN_TMP):
+        shutil.rmtree(SPHINX_IN_TMP, True)
+
+    rna2sphinx(SPHINX_IN_TMP)
+
     if ARGS.full_rebuild:
         # only for full updates
         shutil.rmtree(SPHINX_IN, True)
-        shutil.rmtree(SPHINX_OUT, True)
-        rna2sphinx(SPHINX_IN_TMP)
         shutil.copytree(SPHINX_IN_TMP,
                         SPHINX_IN,
                         copy_function=shutil.copy)
+        if ARGS.sphinx_build and os.path.exists(SPHINX_OUT):
+            shutil.rmtree(SPHINX_OUT, True)
+        if ARGS.sphinx_build_pdf and os.path.exists(SPHINX_OUT_PDF):
+            shutil.rmtree(SPHINX_OUT_PDF, True)
     else:
-        # write here, then move
-        shutil.rmtree(SPHINX_IN_TMP, True)
-        rna2sphinx(SPHINX_IN_TMP)
+        # move changed files in SPHINX_IN
         align_sphinx_in_to_sphinx_in_tmp()
 
     # report which example files weren't used
     EXAMPLE_SET_UNUSED = EXAMPLE_SET - EXAMPLE_SET_USED
     if EXAMPLE_SET_UNUSED:
-        print("\nUnused examples found in '%s'..." % EXAMPLES_DIR)
-        for f in EXAMPLE_SET_UNUSED:
-            print("    %s.py" % f)
-        print("  %d total\n" % len(EXAMPLE_SET_UNUSED))
-
-    # eventually, copy the theme in the output directory
-    if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
-        if not os.path.exists(SPHINX_THEME_DIR):
-            shutil.copytree(SPHINX_THEME_SVN_DIR,
-                            SPHINX_THEME_DIR,
-                            copy_function=shutil.copy)
+        BPY_LOGGER.debug("\nUnused examples found in '%s'..." % EXAMPLES_DIR)
+        for f in sorted(EXAMPLE_SET_UNUSED):
+            BPY_LOGGER.debug("    %s.py" % f)
+        BPY_LOGGER.debug("  %d total\n" % len(EXAMPLE_SET_UNUSED))
 
-    # eventually, build the docs
+    # eventually, build the html docs
     if ARGS.sphinx_build:
         import subprocess
-        sphinx_build_command = "sphinx-build %s %s" % (SPHINX_IN, SPHINX_OUT)
-        print ('\n%s\n' % sphinx_build_command)
-        subprocess.call(sphinx_build_command, shell=True)
+        subprocess.call(SPHINX_BUILD)
+
+        # sphinx-build log cleanup+sort
+        if ARGS.log:
+            if os.stat(SPHINX_BUILD_LOG).st_size:
+                refactor_sphinx_log(SPHINX_BUILD_LOG)
+
+    # eventually, build the pdf docs
+    if ARGS.sphinx_build_pdf:
+        import subprocess
+        subprocess.call(SPHINX_BUILD_PDF)
+        subprocess.call(SPHINX_MAKE_PDF, stdout=SPHINX_MAKE_PDF_STDOUT)
+
+        # sphinx-build log cleanup+sort
+        if ARGS.log:
+            if os.stat(SPHINX_BUILD_PDF_LOG).st_size:
+                refactor_sphinx_log(SPHINX_BUILD_PDF_LOG)
+
+    # eventually, prepare the dir to be deployed online (REFERENCE_PATH)
+    if ARGS.pack_reference:
+
+        if ARGS.sphinx_build:
+            # delete REFERENCE_PATH
+            if os.path.exists(REFERENCE_PATH):
+                shutil.rmtree(REFERENCE_PATH, True)
+
+            # copy SPHINX_OUT to the REFERENCE_PATH
+            ignores = ('.doctrees', 'objects.inv', '.buildinfo')
+            shutil.copytree(SPHINX_OUT,
+                            REFERENCE_PATH,
+                            ignore=shutil.ignore_patterns(*ignores))
+            shutil.copy(os.path.join(REFERENCE_PATH, "contents.html"),
+                        os.path.join(REFERENCE_PATH, "index.html"))
+
+            # zip REFERENCE_PATH
+            basename = os.path.join(ARGS.output_dir, REFERENCE_NAME)
+            tmp_path = shutil.make_archive(basename, 'zip', REFERENCE_PATH)
+            final_path = os.path.join(REFERENCE_PATH, BLENDER_ZIP_FILENAME)
+            os.rename(tmp_path, final_path)
+
+        if ARGS.sphinx_build_pdf:
+            # copy the pdf to REFERENCE_PATH
+            shutil.copy(os.path.join(SPHINX_OUT_PDF, "contents.pdf"),
+                        os.path.join(REFERENCE_PATH, BLENDER_PDF_FILENAME))
 
     sys.exit()