| 1 | import sys, os, re |
|---|
| 2 | SAGE_ROOT = os.environ['SAGE_ROOT'] |
|---|
| 3 | SAGE_DOC = os.path.join(SAGE_ROOT, 'devel/sage/doc') |
|---|
| 4 | |
|---|
| 5 | # If your extensions are in another directory, add it here. If the directory |
|---|
| 6 | # is relative to the documentation root, use os.path.abspath to make it |
|---|
| 7 | # absolute, like shown here. |
|---|
| 8 | #sys.path.append(os.path.abspath('.')) |
|---|
| 9 | |
|---|
| 10 | # General configuration |
|---|
| 11 | # --------------------- |
|---|
| 12 | |
|---|
| 13 | # Add any Sphinx extension module names here, as strings. They can be extensions |
|---|
| 14 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
|---|
| 15 | extensions = ['sphinx.ext.autodoc'] |
|---|
| 16 | |
|---|
| 17 | if 'SAGE_DOC_JSMATH' in os.environ: |
|---|
| 18 | extensions.append('sphinx.ext.jsmath') |
|---|
| 19 | else: |
|---|
| 20 | extensions.append('sphinx.ext.pngmath') |
|---|
| 21 | jsmath_path = 'jsmath_sage.js' |
|---|
| 22 | |
|---|
| 23 | # Add any paths that contain templates here, relative to this directory. |
|---|
| 24 | templates_path = [os.path.join(SAGE_DOC, 'common/templates'), 'templates'] |
|---|
| 25 | |
|---|
| 26 | # The suffix of source filenames. |
|---|
| 27 | source_suffix = '.rst' |
|---|
| 28 | |
|---|
| 29 | # The master toctree document. |
|---|
| 30 | master_doc = 'index' |
|---|
| 31 | |
|---|
| 32 | # General information about the project. |
|---|
| 33 | project = u"" |
|---|
| 34 | copyright = u'2005--2009, The Sage Development Team' |
|---|
| 35 | |
|---|
| 36 | # The version info for the project you're documenting, acts as replacement for |
|---|
| 37 | # |version| and |release|, also used in various other places throughout the |
|---|
| 38 | # built documents. |
|---|
| 39 | # |
|---|
| 40 | # The short X.Y version. |
|---|
| 41 | from sage.version import version |
|---|
| 42 | release = version |
|---|
| 43 | |
|---|
| 44 | #version = '3.1.2' |
|---|
| 45 | # The full version, including alpha/beta/rc tags. |
|---|
| 46 | #release = '3.1.2' |
|---|
| 47 | |
|---|
| 48 | # The language for content autogenerated by Sphinx. Refer to documentation |
|---|
| 49 | # for a list of supported languages. |
|---|
| 50 | #language = None |
|---|
| 51 | |
|---|
| 52 | # There are two options for replacing |today|: either, you set today to some |
|---|
| 53 | # non-false value, then it is used: |
|---|
| 54 | #today = '' |
|---|
| 55 | # Else, today_fmt is used as the format for a strftime call. |
|---|
| 56 | #today_fmt = '%B %d, %Y' |
|---|
| 57 | |
|---|
| 58 | # List of documents that shouldn't be included in the build. |
|---|
| 59 | #unused_docs = [] |
|---|
| 60 | |
|---|
| 61 | # List of directories, relative to source directory, that shouldn't be searched |
|---|
| 62 | # for source files. |
|---|
| 63 | exclude_trees = ['.build'] |
|---|
| 64 | |
|---|
| 65 | # The reST default role (used for this markup: `text`) to use for all documents. |
|---|
| 66 | default_role = 'math' |
|---|
| 67 | |
|---|
| 68 | # If true, '()' will be appended to :func: etc. cross-reference text. |
|---|
| 69 | #add_function_parentheses = True |
|---|
| 70 | |
|---|
| 71 | # If true, the current module name will be prepended to all description |
|---|
| 72 | # unit titles (such as .. function::). |
|---|
| 73 | #add_module_names = True |
|---|
| 74 | |
|---|
| 75 | # If true, sectionauthor and moduleauthor directives will be shown in the |
|---|
| 76 | # output. They are ignored by default. |
|---|
| 77 | #show_authors = False |
|---|
| 78 | |
|---|
| 79 | # The name of the Pygments (syntax highlighting) style to use. NOTE: |
|---|
| 80 | # This overrides a HTML theme's corresponding setting (see below). |
|---|
| 81 | pygments_style = 'sphinx' |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | # Options for HTML output |
|---|
| 85 | # ----------------------- |
|---|
| 86 | |
|---|
| 87 | # HTML theme (e.g., 'default', 'sphinxdoc'). We use a custom Sage |
|---|
| 88 | # theme to set a Pygments style, stylesheet, and insert jsMath macros. |
|---|
| 89 | html_theme = 'sage' |
|---|
| 90 | |
|---|
| 91 | # Theme options are theme-specific and customize the look and feel of |
|---|
| 92 | # a theme further. For a list of options available for each theme, |
|---|
| 93 | # see the documentation. |
|---|
| 94 | html_theme_options = {} |
|---|
| 95 | |
|---|
| 96 | if 'SAGE_DOC_JSMATH' in os.environ: |
|---|
| 97 | from sage.misc.latex_macros import sage_jsmath_macros_easy |
|---|
| 98 | html_theme_options['jsmath_macros'] = sage_jsmath_macros_easy |
|---|
| 99 | |
|---|
| 100 | from sage.misc.package import is_package_installed |
|---|
| 101 | html_theme_options['jsmath_image_fonts'] = is_package_installed('jsmath-image-fonts') |
|---|
| 102 | |
|---|
| 103 | # Add any paths that contain custom themes here, relative to this directory. |
|---|
| 104 | html_theme_path = [os.path.join(SAGE_DOC, 'common/themes')] |
|---|
| 105 | |
|---|
| 106 | # HTML style sheet NOTE: This overrides a HTML theme's corresponding |
|---|
| 107 | # setting. |
|---|
| 108 | #html_style = 'default.css' |
|---|
| 109 | |
|---|
| 110 | # The name for this set of Sphinx documents. If None, it defaults to |
|---|
| 111 | # "<project> v<release> documentation". |
|---|
| 112 | #html_title = None |
|---|
| 113 | |
|---|
| 114 | # A shorter title for the navigation bar. Default is the same as html_title. |
|---|
| 115 | #html_short_title = None |
|---|
| 116 | |
|---|
| 117 | # The name of an image file (within the static path) to place at the top of |
|---|
| 118 | # the sidebar. |
|---|
| 119 | #html_logo = 'sagelogo-word.ico' |
|---|
| 120 | |
|---|
| 121 | # The name of an image file (within the static path) to use as favicon of the |
|---|
| 122 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
|---|
| 123 | # pixels large. |
|---|
| 124 | html_favicon = 'favicon.ico' |
|---|
| 125 | |
|---|
| 126 | # Add any paths that contain custom static files (such as style sheets) here, |
|---|
| 127 | # relative to this directory. They are copied after the builtin static files, |
|---|
| 128 | # so a file named "default.css" will overwrite the builtin "default.css". |
|---|
| 129 | html_static_path = [os.path.join(SAGE_DOC, 'common/static'), 'static'] |
|---|
| 130 | |
|---|
| 131 | # If we're using jsMath, we prepend its location to the static path |
|---|
| 132 | # array. We can override / overwrite selected files by putting them |
|---|
| 133 | # in the remaining paths. |
|---|
| 134 | if 'SAGE_DOC_JSMATH' in os.environ: |
|---|
| 135 | from pkg_resources import Requirement, working_set |
|---|
| 136 | sagenb_path = working_set.find(Requirement.parse('sagenb')).location |
|---|
| 137 | jsmath_static = os.path.join(sagenb_path, 'sagenb', 'data', 'jsmath') |
|---|
| 138 | html_static_path.insert(0, jsmath_static) |
|---|
| 139 | |
|---|
| 140 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
|---|
| 141 | # using the given strftime format. |
|---|
| 142 | #html_last_updated_fmt = '%b %d, %Y' |
|---|
| 143 | |
|---|
| 144 | # If true, SmartyPants will be used to convert quotes and dashes to |
|---|
| 145 | # typographically correct entities. |
|---|
| 146 | #html_use_smartypants = True |
|---|
| 147 | |
|---|
| 148 | # Custom sidebar templates, maps document names to template names. |
|---|
| 149 | #html_sidebars = {} |
|---|
| 150 | |
|---|
| 151 | # Additional templates that should be rendered to pages, maps page names to |
|---|
| 152 | # template names. |
|---|
| 153 | #html_additional_pages = {} |
|---|
| 154 | |
|---|
| 155 | # If false, no module index is generated. |
|---|
| 156 | html_use_modindex = false |
|---|
| 157 | |
|---|
| 158 | # If false, no index is generated. |
|---|
| 159 | html_use_index = false |
|---|
| 160 | |
|---|
| 161 | # If true, the index is split into individual pages for each letter. |
|---|
| 162 | html_split_index = True |
|---|
| 163 | |
|---|
| 164 | # If true, the reST sources are included in the HTML build as _sources/<name>. |
|---|
| 165 | #html_copy_source = True |
|---|
| 166 | |
|---|
| 167 | # If true, an OpenSearch description file will be output, and all pages will |
|---|
| 168 | # contain a <link> tag referring to it. The value of this option must be the |
|---|
| 169 | # base URL from which the finished HTML is served. |
|---|
| 170 | #html_use_opensearch = '' |
|---|
| 171 | |
|---|
| 172 | # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). |
|---|
| 173 | #html_file_suffix = '' |
|---|
| 174 | |
|---|
| 175 | # Output file base name for HTML help builder. |
|---|
| 176 | #htmlhelp_basename = '' |
|---|
| 177 | |
|---|
| 178 | |
|---|
| 179 | # Options for LaTeX output |
|---|
| 180 | # ------------------------ |
|---|
| 181 | |
|---|
| 182 | # The paper size ('letter' or 'a4'). |
|---|
| 183 | #latex_paper_size = 'letter' |
|---|
| 184 | |
|---|
| 185 | # The font size ('10pt', '11pt' or '12pt'). |
|---|
| 186 | #latex_font_size = '10pt' |
|---|
| 187 | |
|---|
| 188 | # Grouping the document tree into LaTeX files. List of tuples |
|---|
| 189 | # (source start file, target name, title, author, document class [howto/manual]). |
|---|
| 190 | latex_documents = [] |
|---|
| 191 | |
|---|
| 192 | # The name of an image file (relative to this directory) to place at the top of |
|---|
| 193 | # the title page. |
|---|
| 194 | #latex_logo = 'sagelogo-word.png' |
|---|
| 195 | |
|---|
| 196 | # For "manual" documents, if this is true, then toplevel headings are parts, |
|---|
| 197 | # not chapters. |
|---|
| 198 | #latex_use_parts = False |
|---|
| 199 | |
|---|
| 200 | # Additional stuff for the LaTeX preamble. |
|---|
| 201 | #latex_preamble = '' |
|---|
| 202 | latex_preamble = '\usepackage{amsmath}\n\usepackage{amsfonts}\n' |
|---|
| 203 | |
|---|
| 204 | # Documents to append as an appendix to all manuals. |
|---|
| 205 | #latex_appendices = [] |
|---|
| 206 | |
|---|
| 207 | # If false, no module index is generated. |
|---|
| 208 | #latex_use_modindex = True |
|---|
| 209 | |
|---|
| 210 | ##################################################### |
|---|
| 211 | # add LaTeX macros for Sage |
|---|
| 212 | |
|---|
| 213 | from sage.misc.latex_macros import sage_latex_macros |
|---|
| 214 | |
|---|
| 215 | try: |
|---|
| 216 | pngmath_latex_preamble # check whether this is already defined |
|---|
| 217 | except NameError: |
|---|
| 218 | pngmath_latex_preamble = "" |
|---|
| 219 | |
|---|
| 220 | for macro in sage_latex_macros: |
|---|
| 221 | # used when building latex and pdf versions |
|---|
| 222 | latex_preamble += macro + '\n' |
|---|
| 223 | # used when building html version |
|---|
| 224 | pngmath_latex_preamble += macro + '\n' |
|---|
| 225 | |
|---|
| 226 | ##################################################### |
|---|
| 227 | |
|---|
| 228 | def process_docstring_aliases(app, what, name, obj, options, docstringlines): |
|---|
| 229 | """ |
|---|
| 230 | Change the docstrings for aliases to point to the original object. |
|---|
| 231 | """ |
|---|
| 232 | basename = name.rpartition('.')[2] |
|---|
| 233 | if hasattr(obj, '__name__') and obj.__name__ != basename: |
|---|
| 234 | docstringlines[:] = ['See :obj:`%s`.' % name] |
|---|
| 235 | |
|---|
| 236 | def process_directives(app, what, name, obj, options, docstringlines): |
|---|
| 237 | """ |
|---|
| 238 | Remove 'nodetex' and other directives from the first line of any |
|---|
| 239 | docstring where they appear. |
|---|
| 240 | """ |
|---|
| 241 | if len(docstringlines) == 0: |
|---|
| 242 | return |
|---|
| 243 | first_line = docstringlines[0] |
|---|
| 244 | directives = [ d.lower() for d in first_line.split(',') ] |
|---|
| 245 | if 'nodetex' in directives: |
|---|
| 246 | docstringlines.pop(0) |
|---|
| 247 | |
|---|
| 248 | def process_docstring_cython(app, what, name, obj, options, docstringlines): |
|---|
| 249 | """ |
|---|
| 250 | Remove Cython's filename and location embedding. |
|---|
| 251 | """ |
|---|
| 252 | if len(docstringlines) <= 1: |
|---|
| 253 | return |
|---|
| 254 | |
|---|
| 255 | first_line = docstringlines[0] |
|---|
| 256 | if first_line.startswith('File:') and '(starting at' in first_line: |
|---|
| 257 | #Remove the first two lines |
|---|
| 258 | docstringlines.pop(0) |
|---|
| 259 | docstringlines.pop(0) |
|---|
| 260 | |
|---|
| 261 | def process_docstring_module_title(app, what, name, obj, options, docstringlines): |
|---|
| 262 | """ |
|---|
| 263 | Removes the first line from the beginning of the module's docstring. This |
|---|
| 264 | corresponds to the title of the module's documentation page. |
|---|
| 265 | """ |
|---|
| 266 | if what != "module": |
|---|
| 267 | return |
|---|
| 268 | |
|---|
| 269 | #Remove any additional blank lines at the beginning |
|---|
| 270 | title_removed = False |
|---|
| 271 | while len(docstringlines) > 1 and not title_removed: |
|---|
| 272 | if docstringlines[0].strip() != "": |
|---|
| 273 | title_removed = True |
|---|
| 274 | docstringlines.pop(0) |
|---|
| 275 | |
|---|
| 276 | #Remove any additional blank lines at the beginning |
|---|
| 277 | while len(docstringlines) > 1: |
|---|
| 278 | if docstringlines[0].strip() == "": |
|---|
| 279 | docstringlines.pop(0) |
|---|
| 280 | else: |
|---|
| 281 | break |
|---|
| 282 | |
|---|
| 283 | def skip_NestedClass(app, what, name, obj, skip, options): |
|---|
| 284 | """ |
|---|
| 285 | Don't include the docstring for any class/function/object in |
|---|
| 286 | sage.misc.misc whose ``name`` contains "MainClass.NestedClass". |
|---|
| 287 | (This is to avoid some Sphinx warnings when processing |
|---|
| 288 | sage.misc.misc.) Otherwise, abide by Sphinx's decision. |
|---|
| 289 | """ |
|---|
| 290 | skip_nested = str(obj).find("sage.misc.misc") != -1 and name.find("MainClass.NestedClass") != -1 |
|---|
| 291 | return skip or skip_nested |
|---|
| 292 | |
|---|
| 293 | def process_dollars(app, what, name, obj, options, docstringlines): |
|---|
| 294 | r""" |
|---|
| 295 | Replace dollar signs with backticks. |
|---|
| 296 | |
|---|
| 297 | More precisely, do a regular expression search. Replace a plain |
|---|
| 298 | dollar sign ($) by a backtick (`). Replace an escaped dollar sign |
|---|
| 299 | (\$) by a dollar sign ($). Don't change a dollar sign preceded or |
|---|
| 300 | followed by a backtick (`$ or $`), because of strings like |
|---|
| 301 | "``$HOME``". Don't make any changes on lines starting with |
|---|
| 302 | spaces, because those are indented and hence part of a block of |
|---|
| 303 | code or examples. |
|---|
| 304 | |
|---|
| 305 | This also doesn't replaces dollar signs enclosed in curly braces, |
|---|
| 306 | to avoid nested math environments, such as :: |
|---|
| 307 | |
|---|
| 308 | $f(n) = 0 \text{ if $n$ is prime}$ |
|---|
| 309 | |
|---|
| 310 | Thus the above line would get changed to |
|---|
| 311 | |
|---|
| 312 | `f(n) = 0 \text{ if $n$ is prime}` |
|---|
| 313 | """ |
|---|
| 314 | s = "\n".join(docstringlines) |
|---|
| 315 | if s.find("$") == -1: |
|---|
| 316 | return |
|---|
| 317 | # Indices will be a list of pairs of positions in s, to search between. |
|---|
| 318 | # If the following search has no matches, then indices will be (0, len(s)). |
|---|
| 319 | indices = [0] |
|---|
| 320 | # This searches for "$blah$" inside a pair of curly braces -- |
|---|
| 321 | # don't change these, since they're probably coming from a nested |
|---|
| 322 | # math environment. So for each match, search to the left of its |
|---|
| 323 | # start and to the right of its end, but not in between. |
|---|
| 324 | for m in re.finditer(r"{[^{}$]*\$([^{}$]*)\$[^{}$]*}", s): |
|---|
| 325 | indices[-1] = (indices[-1], m.start()) |
|---|
| 326 | indices.append(m.end()) |
|---|
| 327 | indices[-1] = (indices[-1], len(s)) |
|---|
| 328 | |
|---|
| 329 | # regular expression for $ (not \$, `$, $`, and only on a line |
|---|
| 330 | # with no leading whitespace). |
|---|
| 331 | dollar = re.compile(r"""^ # beginning of line |
|---|
| 332 | ([^\s] # non whitespace |
|---|
| 333 | .*?)? # non-greedy match any non-newline characters |
|---|
| 334 | (?<!`|\\)\$(?!`) # $ with negative lookbehind and lookahead |
|---|
| 335 | """, re.M | re.X) |
|---|
| 336 | # regular expression for \$ |
|---|
| 337 | slashdollar = re.compile(r"\\\$") |
|---|
| 338 | for start, end in indices: |
|---|
| 339 | while dollar.search(s, start, end): |
|---|
| 340 | m = dollar.search(s, start, end) |
|---|
| 341 | s = s[:m.end()-1] + "`" + s[m.end():] |
|---|
| 342 | while slashdollar.search(s, start, end): |
|---|
| 343 | m = slashdollar.search(s, start, end) |
|---|
| 344 | s = s[:m.start()] + "$" + s[m.end():] |
|---|
| 345 | # now save results in docstringlines |
|---|
| 346 | lines = s.split("\n") |
|---|
| 347 | for i in range(len(lines)): |
|---|
| 348 | docstringlines[i] = lines[i] |
|---|
| 349 | |
|---|
| 350 | from sage.misc.sageinspect import sage_getargspec |
|---|
| 351 | autodoc_builtin_argspec = sage_getargspec |
|---|
| 352 | |
|---|
| 353 | def setup(app): |
|---|
| 354 | app.connect('autodoc-process-docstring', process_docstring_cython) |
|---|
| 355 | app.connect('autodoc-process-docstring', process_directives) |
|---|
| 356 | app.connect('autodoc-process-docstring', process_docstring_module_title) |
|---|
| 357 | app.connect('autodoc-process-docstring', process_dollars) |
|---|
| 358 | app.connect('autodoc-skip-member', skip_NestedClass) |
|---|