Ticket #5653: 5653-cleanup.patch

File 5653-cleanup.patch, 25.1 KB (added by boothby, 12 years ago)
  • sage/server/notebook/cell.py

    # HG changeset patch
    # User Tom Boothby <boothby@u.washington.edu>
    # Date 1242707716 25200
    # Node ID a282869211145f751f1a1bfe4894a678a25f0932
    # Parent  d5c1c302275dd4d2da2f514e561e4be808a75d3a
    Suppress noisy sphinx messages.
    
    diff -r d5c1c302275d -r a28286921114 sage/server/notebook/cell.py
    a b  
    15491549                confoverrides = {'html_context' : {}, 'master_doc' : hash}
    15501550
    15511551                # To suppress output, use this:
    1552 #                sphinx_app = Sphinx(srcdir, confdir, srcdir, doctreedir, 'html', confoverrides, None, None, True)
     1552                sphinx_app = Sphinx(srcdir, confdir, srcdir, doctreedir, 'html', confoverrides, None, None, True)
    15531553
    15541554                # For verbose output, use these instead:
    15551555                import sys
    1556                 sphinx_app = Sphinx(srcdir, confdir, srcdir, doctreedir, 'html', confoverrides, sys.stdout, sys.stderr, True)
     1556#                sphinx_app = Sphinx(srcdir, confdir, srcdir, doctreedir, 'html', confoverrides, sys.stdout, sys.stderr, True)
    15571557
    15581558                # Run Sphinx. The first argument corresponds to
    15591559                # sphinx-build's "write all files" -a flag, which we
  • sage/server/notebook/css.py

    diff -r d5c1c302275d -r a28286921114 sage/server/notebook/css.py
    a b  
    16521652
    16531653
    16541654
     1655/* These have been scraped directly from pygment. */
     1656
    16551657.hll { background-color: #ffffcc }
    16561658.c { color: #408090; font-style: italic } /* Comment */
    16571659.err { border: 1px solid #FF0000 } /* Error */
     
    17141716.vi { color: #bb60d5 } /* Name.Variable.Instance */
    17151717.il { color: #208050 } /* Literal.Number.Integer.Long */
    17161718
    1717 
     1719/* end stuff scraped from pygment */
    17181720
    17191721"""
    17201722    if color == 'gmail':
  • deleted file doc/introspect/builder.py

    # HG changeset patch
    # User Tom Boothby <boothby@u.washington.edu>
    # Date 1242706642 25200
    # Node ID d5c1c302275dd4d2da2f514e561e4be808a75d3a
    # Parent  a36953af67c9d00c9e6a67ecc8e1f9fc181829ba
    Removed builder.py, it isn't used and shouldn't be here.
    
    diff -r a36953af67c9 -r d5c1c302275d doc/introspect/builder.py
    + -  
    1 #!/usr/bin/env python
    2 import os, sys, subprocess, shutil, glob, optparse
    3 
    4 #We remove the current directory from sys.path right away
    5 #so that we import sage from the proper spot
    6 try:
    7     sys.path.remove(os.path.realpath(os.getcwd()))
    8 except:
    9     pass
    10 
    11 from sage.misc.cachefunc import cached_method
    12 
    13 ##########################################
    14 #                Options                 #
    15 ##########################################
    16 SAGE_DOC = os.environ['SAGE_DOC']
    17 LANGUAGES = ['en', 'fr']
    18 SPHINXOPTS  = ""
    19 PAPER       = ""
    20 
    21 if PAPER == "a4":
    22     PAPEROPTS = "-D latex_paper_size=a4"
    23 elif PAPER == "letter":
    24     PAPEROPTS = "-D latex_paper_size=letter"
    25 else:
    26     PAPEROPTS = ""
    27 
    28 #Note that this needs to have the doctrees dir   
    29 ALLSPHINXOPTS   = SPHINXOPTS + " " + PAPEROPTS + " . "
    30 
    31 
    32 ##########################################
    33 #          Utility Functions             #
    34 ##########################################
    35 def mkdir(path):
    36     """
    37     Makes the directory at path if it doesn't exist and returns the
    38     string path.
    39 
    40     EXAMPLES::
    41 
    42         sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    43         sage: d = tmp_filename(); d
    44         '/.../tmp_...'
    45         sage: os.path.exists(d)
    46         False
    47         sage: dd = builder.mkdir(d)
    48         sage: d == dd
    49         True
    50         sage: os.path.exists(d)
    51         True
    52     """
    53     if not os.path.exists(path):
    54         os.makedirs(path)
    55     return path
    56 
    57 def copytree(src, dst, symlinks=False, ignore_errors=False):
    58     """
    59     Recursively copy a directory tree using copy2().
    60 
    61     The destination directory must not already exist.
    62     If exception(s) occur, an Error is raised with a list of reasons.
    63 
    64     If the optional symlinks flag is true, symbolic links in the
    65     source tree result in symbolic links in the destination tree; if
    66     it is false, the contents of the files pointed to by symbolic
    67     links are copied.
    68 
    69     XXX Consider this example code rather than the ultimate tool.
    70 
    71     """
    72     names = os.listdir(src)
    73     mkdir(dst)
    74     errors = []
    75     for name in names:
    76         srcname = os.path.join(src, name)
    77         dstname = os.path.join(dst, name)
    78         try:
    79             if symlinks and os.path.islink(srcname):
    80                 linkto = os.readlink(srcname)
    81                 os.symlink(linkto, dstname)
    82             elif os.path.isdir(srcname):
    83                 copytree(srcname, dstname, symlinks)
    84             else:
    85                 shutil.copy2(srcname, dstname)
    86             # XXX What about devices, sockets etc.?
    87         except (IOError, os.error), why:
    88             errors.append((srcname, dstname, str(why)))
    89         # catch the Error from the recursive copytree so that we can
    90         # continue with other files
    91         except shutil.Error, err:
    92             errors.extend(err.args[0])
    93     try:
    94         shutil.copystat(src, dst)
    95     except OSError, why:
    96         errors.extend((src, dst, str(why)))
    97     if errors and not ignore_errors:
    98         raise shutil.Error, errors
    99 
    100 
    101 
    102 ##########################################
    103 #             Builders                   #
    104 ##########################################
    105 def builder_helper(type):
    106     """
    107     Returns a function which builds the documentation for
    108     output type type.
    109     """
    110     def f(self):
    111         output_dir = self._output_dir(type)
    112         os.chdir(self.dir)
    113 
    114         build_command = 'sphinx-build'
    115         build_command += ' -b %s -d %s %s %s'%(type, self._doctrees_dir(),
    116                                                ALLSPHINXOPTS, output_dir)
    117         print build_command
    118         subprocess.call(build_command, shell=True)
    119 
    120         print "Build finished.  The built documents can be found in %s"%output_dir
    121        
    122     f.is_output_format = True
    123     return f
    124        
    125 
    126 class DocBuilder(object):
    127     def __init__(self, name, lang='en'):
    128         """
    129         INPUT:
    130            
    131         - ``name`` - the name of a subdirectory in SAGE_DOC, such as
    132           'tutorial' or 'bordeaux_2008'
    133 
    134         - ``lang`` - (default "en") the language of the document.
    135         """
    136         if '/' in name:
    137             lang, name = name.split(os.path.sep)
    138         self.name = name
    139         self.lang = lang
    140         self.dir = os.path.join(SAGE_DOC, lang, name)
    141 
    142         #Make sure the .static and .templates directories are there
    143         mkdir(os.path.join(self.dir, "static"))
    144         mkdir(os.path.join(self.dir, "templates"))
    145 
    146     def _output_dir(self, type):
    147         """
    148         Returns the directory where the output of type type is stored.
    149         If the directory does not exist, then it will automatically be
    150         created.
    151 
    152         EXAMPLES::
    153 
    154             sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    155             sage: b = builder.DocBuilder('tutorial')
    156             sage: b._output_dir('html')
    157             '.../devel/sage/doc/output/html/en/tutorial'
    158         """
    159         return mkdir(os.path.join(SAGE_DOC, "output", type, self.lang, self.name))
    160 
    161     def _doctrees_dir(self):
    162         """
    163         Returns the directory where the doctrees are stored.  If the
    164         directory does not exist, then it will automatically be
    165         created.
    166 
    167         EXAMPLES::
    168 
    169             sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    170             sage: b = builder.DocBuilder('tutorial')
    171             sage: b._doctrees_dir()
    172             '.../devel/sage/doc/output/doctrees/en/tutorial'
    173         """
    174         return mkdir(os.path.join(SAGE_DOC, "output", 'doctrees', self.lang, self.name))
    175 
    176     def _output_formats(self):
    177         """
    178         Returns a list of the possible output formats.
    179 
    180         EXAMPLES::
    181 
    182             sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    183             sage: b = builder.DocBuilder('tutorial')
    184             sage: b._output_formats()
    185             ['changes', 'html', 'htmlhelp', 'json', 'latex', 'linkcheck', 'pickle', 'web']
    186 
    187         """
    188         #Go through all the attributes of self and check to
    189         #see which ones have an 'is_output_format' attribute.  These
    190         #are the ones created with builder_helper.
    191         output_formats = []
    192         for attr in dir(self):
    193             if hasattr(getattr(self, attr), 'is_output_format'):
    194                 output_formats.append(attr)
    195         output_formats.sort()
    196         return output_formats
    197 
    198     def pdf(self):
    199         """
    200         Builds the PDF files for this document.  This is done by first
    201         (re)-building the LaTeX output, going into that LaTeX
    202         directory, and running 'make all-pdf' there.
    203 
    204         EXAMPLES::
    205 
    206             sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    207             sage: b = builder.DocBuilder('tutorial')
    208             sage: b.pdf() #not tested
    209         """
    210         self.latex()
    211         os.chdir(self._output_dir('latex'))
    212         subprocess.call('make all-pdf', shell=True)
    213 
    214         pdf_dir = self._output_dir('pdf')
    215         for pdf_file in glob.glob('*.pdf'):
    216             shutil.move(pdf_file, os.path.join(pdf_dir, pdf_file))
    217 
    218         print "Build finished.  The built documents can be found in %s"%pdf_dir             
    219 
    220     def clean(self, *args):
    221         """
    222         """
    223         import shutil
    224         shutil.rmtree(self._doctrees_dir())
    225         output_formats = list(args) if args else self._output_formats()
    226         for format in output_formats:
    227             shutil.rmtree(self._output_dir(format), ignore_errors=True)
    228        
    229     html = builder_helper('html')
    230     pickle = builder_helper('pickle')
    231     web = pickle
    232     json = builder_helper('json')                       
    233     htmlhelp = builder_helper('htmlhelp')
    234     latex = builder_helper('latex')
    235     changes = builder_helper('changes')
    236     linkcheck = builder_helper('linkcheck')
    237 
    238 class AllBuilder(object):
    239     """
    240     A class used to build all of the documentation.
    241     """
    242     def __getattr__(self, attr):
    243         """
    244         For any attributes not explicitly defined, we just go through
    245         all of the documents and call their attr.  For example,
    246         'AllBuilder().json()' will go through all of the documents
    247         and call the json() method on their builders.
    248         """
    249         from functools import partial
    250         return partial(self._wrapper, attr)
    251 
    252     def _wrapper(self, name, *args, **kwds):
    253         """
    254         This is the function which goes through all of the documents
    255         and does the actual building.
    256         """
    257         for document in self.get_all_documents():
    258             getattr(get_builder(document), name)(*args, **kwds)
    259 
    260     def get_all_documents(self):
    261         """
    262         Returns a list of all of the documents. A document is a directory within one of
    263         the language subdirectories of SAGE_DOC specified by the global LANGUAGES
    264         variable.
    265 
    266         EXAMPLES::
    267 
    268             sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    269             sage: documents = builder.AllBuilder().get_all_documents()
    270             sage: 'en/tutorial' in documents
    271             True
    272         """
    273         documents = []
    274         for lang in LANGUAGES:
    275             for document in os.listdir(os.path.join(SAGE_DOC, lang)):
    276                 documents.append(os.path.join(lang, document))
    277         return documents
    278 
    279 class WebsiteBuilder(DocBuilder):
    280     def html(self):
    281         """
    282         After we've finished building the website index page, we copy
    283         everything one directory up.
    284         """
    285         DocBuilder.html(self)
    286         html_output_dir = self._output_dir('html')
    287         copytree(html_output_dir,
    288                  os.path.realpath(os.path.join(html_output_dir, '..')),
    289                  ignore_errors=False)
    290 
    291     def clean(self):
    292         """
    293         When we clean the output for the website index, we need to
    294         remove all of the HTML that were placed in the parent
    295         directory.
    296         """
    297         html_output_dir = self._output_dir('html')
    298         parent_dir = os.path.realpath(os.path.join(html_output_dir, '..'))
    299         for filename in os.listdir(html_output_dir):
    300             parent_filename = os.path.join(parent_dir, filename)
    301             if not os.path.exists(parent_filename):
    302                 continue
    303             if os.path.isdir(parent_filename):
    304                 shutil.rmtree(parent_filename, ignore_errors=True)
    305             else:
    306                 os.unlink(parent_filename)
    307 
    308         DocBuilder.clean(self)
    309 
    310 class ReferenceBuilder(DocBuilder):
    311     """
    312     This the class used to build the reference manual.  It is
    313     resposible for making sure the auto generated ReST files for the
    314     Sage library are up to date.
    315 
    316     When building any output, we must first go through and check
    317     to see if we need to update any of the autogenerated ReST
    318     files.  There are two cases where this would happen:
    319 
    320     1. A new module gets added to one of the toctrees.
    321    
    322     2. The actual module gets updated and possibly contains a new
    323        title.
    324     """
    325     def __init__(self, *args, **kwds):
    326         DocBuilder.__init__(self, *args, **kwds)
    327         self._wrap_builder_helpers()
    328 
    329     def _wrap_builder_helpers(self):
    330         from functools import partial, update_wrapper
    331         for attr in dir(self):
    332             if hasattr(getattr(self, attr), 'is_output_format'):
    333                 f = partial(self._wrapper, attr)
    334                 f.is_output_format = True
    335                 update_wrapper(f, getattr(self, attr))
    336                 setattr(self, attr, f)
    337    
    338     def _wrapper(self, build_type, *args, **kwds):
    339         """
    340         This is the wrapper around the builder_helper methods that
    341         goes through and makes sure things are up to date.
    342         """
    343         #Write the .rst files for newly included modules
    344         for module_name in self.get_newly_included_modules(save=True):
    345             self.write_auto_rest_file(module_name)
    346 
    347         #Update the .rst files for modified Python modules
    348         for module_name in self.get_modified_modules():
    349             self.write_auto_rest_file(module_name.replace(os.path.sep, '.'))
    350 
    351         #Copy over the custom .rst files from _sage
    352         _sage = os.path.join(self.dir, '_sage')
    353         if os.path.exists(_sage):
    354             copytree(_sage, os.path.join(self.dir, 'sage'))
    355                
    356         getattr(DocBuilder, build_type)(self, *args, **kwds)
    357    
    358     def cache_filename(self):
    359         """
    360         Returns the filename where the pickle of the dictionary of
    361         already generated .rst files is stored.
    362         """
    363         return os.path.join(self._doctrees_dir(), 'reference.pickle')
    364 
    365     @cached_method
    366     def get_cache(self):
    367         """
    368         Retreive the cache of already generated .rst files.  If it
    369         doesn't exist, then we just return an empty dictionary.
    370         """
    371         filename = self.cache_filename()
    372         if not os.path.exists(filename):
    373             return {}
    374 
    375         import cPickle
    376         file = open(self.cache_filename(), 'rb')
    377         cache = cPickle.load(file)
    378         file.close()
    379         return cache
    380        
    381 
    382     def save_cache(self):
    383         """
    384         Save the cache of already generated .rst files.
    385         """
    386         import cPickle
    387         file = open(self.cache_filename(), 'wb')
    388         cPickle.dump(self.get_cache(), file)
    389         file.close()
    390 
    391     def get_sphinx_environment(self):
    392         """
    393         Returns the Sphinx environment for this project.
    394         """
    395         from sphinx.environment import BuildEnvironment
    396         class Foo(object):
    397             pass
    398         config = Foo()
    399         config.values = []
    400 
    401         env_pickle = os.path.join(self._doctrees_dir(), 'environment.pickle')
    402         try:
    403             return BuildEnvironment.frompickle(config, env_pickle)
    404         except IOError:
    405             pass
    406                                            
    407     def get_modified_modules(self):
    408         """
    409         Returns an iterator for all the modules that have been modified
    410         since the docuementation was last built.
    411         """
    412         env = self.get_sphinx_environment()
    413         if env is None:
    414             return
    415         added, changed, removed = env.get_outdated_files(False)
    416         for name in changed:
    417             if name.startswith('sage'):
    418                 yield name
    419 
    420     def print_modified_modules(self):
    421         """
    422         Prints a list of all the modules that have been modified since
    423         the documentation was last built.
    424         """
    425         for module_name in self.get_modified_modules():
    426             print module_name
    427 
    428     def get_all_rst_files(self, exclude_sage=True):
    429         """
    430         Returns an iterator for all rst files which are not
    431         autogenerated.
    432         """
    433         for directory, subdirs, files in os.walk(self.dir):
    434             if exclude_sage and directory.startswith(os.path.join(self.dir, 'sage')):
    435                 continue
    436             for filename in files:
    437                 if not filename.endswith('.rst'):
    438                     continue
    439                 yield os.path.join(directory, filename)
    440 
    441     def get_all_included_modules(self):
    442         """
    443         Returns an iterator for all modules which are included in the
    444         reference manual.
    445         """
    446         for filename in self.get_all_rst_files():
    447             for module in self.get_modules(filename):
    448                 yield module
    449 
    450     def get_newly_included_modules(self, save=False):
    451         """
    452         Returns an iterator for all modules that appear in the
    453         toctrees that don't appear in the cache.
    454         """
    455         cache = self.get_cache()
    456         new_modules = []
    457         for module in self.get_all_included_modules():
    458             if module not in cache:
    459                 cache[module] = True
    460                 yield module
    461         if save:
    462             self.save_cache()
    463 
    464     def print_newly_included_modules(self):
    465         """
    466         Prints all of the modules that appear in the toctrees that
    467         don't appear in the cache.
    468         """
    469         for module_name in self.get_newly_included_modules():
    470             print module_name
    471 
    472     def get_modules(self, filename):
    473         """
    474         Given a filename for a .rst file, return an iterator for
    475         all of the autogenerated rst files that it includes.
    476         """
    477         #Create the regular expression used to detect an autogenerated file
    478         import re
    479         auto_re = re.compile('^\s*(..\/)*(sage\/[\w\/]*)\s*$')
    480 
    481         #Read the lines
    482         f = open(filename)
    483         lines = f.readlines()
    484         f.close()
    485 
    486         for line in lines:
    487             match = auto_re.match(line)
    488             if match:
    489                 yield match.group(2).replace(os.path.sep, '.')
    490                
    491     def get_module_docstring_title(self, module_name):
    492         """
    493         Returns the title of the module from its docstring.
    494         """
    495         #Try to import the module
    496         try:
    497             import sage.all
    498             __import__(module_name)
    499         except ImportError, err:
    500             raise
    501             print "Warning: could not import %s"%module_name
    502             print err
    503             return "UNABLE TO IMPORT MODULE"
    504         module = sys.modules[module_name]
    505 
    506         #Get the docstring
    507         doc = module.__doc__
    508         if doc is None:
    509             doc = module.doc if hasattr(module, 'doc') else ""
    510 
    511         #Extract the title
    512         i = doc.find('\n')
    513         if i != -1:
    514             return doc[i+1:].lstrip().splitlines()[0]
    515         else:
    516             return doc
    517 
    518     def write_auto_rest_file(self, module_name):
    519         """
    520         Writes the autogenerated .rst file for module_name.
    521         """
    522         if not module_name.startswith('sage'):
    523             return
    524         filename = self.dir + os.path.sep + module_name.replace('.',os.path.sep) + '.rst'
    525         mkdir(os.path.dirname(filename))
    526        
    527         outfile = open(filename, 'w')
    528 
    529         title = self.get_module_docstring_title(module_name)
    530 
    531         if title == '':
    532             print "WARNING: Missing title for", module_name
    533             title = "MISSING TITLE"
    534 
    535         outfile.write(title + '\n')
    536         outfile.write('='*len(title) + "\n\n")
    537         outfile.write('.. This file has been autogenerated.\n\n')
    538         automodule = '.. automodule:: %s\n   :members:\n   :undoc-members:\n\n'
    539         outfile.write(automodule%module_name)
    540 
    541         outfile.close()
    542 
    543     def clean_auto(self):
    544         """
    545         Remove the cache file for the autogenerated files as well as
    546         the files themselves.
    547         """
    548         if os.path.exists(self.cache_filename()):
    549             os.unlink(self.cache_filename())
    550 
    551         import shutil
    552         shutil.rmtree(self.dir + '/sage')
    553 
    554     def get_unincluded_modules(self):
    555         """
    556         Returns an iterator for all the modules in the Sage library
    557         which are not included in the reference manual.
    558         """
    559         #Make a dictionary of the included modules
    560         included_modules = {}
    561         for module_name in self.get_all_included_modules():
    562             included_modules[module_name] = True
    563        
    564         base_path = os.path.join(os.environ['SAGE_ROOT'], 'devel', 'sage', 'sage')
    565         for directory, subdirs, files in os.walk(base_path):
    566             for filename in files:
    567                 if not (filename.endswith('.py') or
    568                         filename.endswith('.pyx')):
    569                     continue
    570                
    571                 path = os.path.join(directory, filename)
    572 
    573                 #Create the module name
    574                 module_name = path[len(base_path):].replace(os.path.sep, '.')
    575                 module_name = 'sage' + module_name
    576                 module_name = module_name[:-4] if module_name.endswith('pyx') else module_name[:-3]
    577 
    578                 #Exclude some ones  -- we don't want init the manual
    579                 if module_name.endswith('__init__') or module_name.endswith('all'):
    580                     continue
    581 
    582                 if module_name not in included_modules:
    583                     yield module_name
    584                
    585     def print_unincluded_modules(self):
    586         """
    587         Prints all of the modules which are not included in the Sage
    588         reference manual.
    589         """
    590         for module_name in self.get_unincluded_modules():
    591             print module_name
    592 
    593     def print_included_modules(self):
    594         """
    595         Prints all of the modules that are included in the Sage reference
    596         manual.
    597         """
    598         for module_name in self.get_all_included_modules():
    599             print module_name
    600 
    601        
    602 
    603 def get_builder(name):
    604     """
    605     Returns a either a AllBuilder or DocBuilder object depending
    606     on whether ``name`` is 'all' or not.  These are the objects
    607     which do all the real work in building the documentation.
    608     """
    609     if name == 'all':
    610         return AllBuilder()
    611     elif name.endswith('reference'):
    612         return ReferenceBuilder(name)
    613     elif name.endswith('website'):
    614         return WebsiteBuilder(name)
    615     else:
    616         return DocBuilder(name)
    617              
    618 
    619 def help_message():
    620     """
    621     Returns the help message.
    622     """
    623     all_b = AllBuilder()
    624     docs = all_b.get_all_documents()
    625     docs = [(d[3:] if d[0:3] == 'en/' else d) for d in docs]
    626     tut_b = DocBuilder('en/tutorial')
    627     formats = tut_b._output_formats()
    628     formats.remove('html')
    629     help = "Usage: sage -docbuild {document} {format}\n"
    630     help += "Where {document} is one of:\n    "
    631     help += "\n    ".join(docs)
    632     help += "\nor 'all' for all documents, and {format} is one of:\n    "
    633     help += 'html, pdf, ' + ', '.join(formats)
    634     help += "\n"
    635     help += "When building the reference manual, there are several additional\n"
    636     help += "values for {format}:\n"
    637     help += "    print_modified_modules: list modules modified since the documentation\n"
    638     help += "         was last built\n"
    639     help += "    print_newly_included_modules: list modules added to the\n"
    640     help += "         documentation since it was last built\n"
    641     help += "    print_unincluded_modules: list modules not included in the documentation\n"
    642     help += "    print_included_modules: list modules included in the documentation\n"
    643     print help
    644 
    645 
    646 parser = optparse.OptionParser(usage="usage: sage -docbuild [options] name type")
    647 parser.add_option("--jsmath", action="store_true",
    648                   help="render math using jsMath")
    649 parser.print_help = help_message
    650 
    651 if __name__ == '__main__':
    652     options, args = parser.parse_args()
    653 
    654     if options.jsmath:
    655         os.environ['SAGE_DOC_JSMATH'] = "True"
    656 
    657     #Get the name of the document we are trying to build
    658     try:
    659         name, type = args
    660     except ValueError:
    661         print "You must specify the document name and the output format"
    662         sys.exit(0)
    663    
    664     #Make sure common/static exists
    665     mkdir(os.path.join(SAGE_DOC, 'common', 'static'))
    666 
    667     #Get the builder and build
    668     getattr(get_builder(name), type)()