提交 bfd8a94a authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Remove obsolete :api: role, and replace refs.

Also removes now unused scripts.
上级 1bde7f38
......@@ -23,7 +23,7 @@ import sys, os
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'ext']
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo']
todo_include_todos = True
......@@ -175,7 +175,7 @@ latex_documents = [
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = 'images/snake_theta2-trans.png'
latex_logo = None
latex_logo = 'images/theano_logo_allblue_200x46.png'
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
......
import sys
import re
import os
from docutils import nodes, utils
from docutils.parsers.rst import roles
import epydoc.docwriter.xlink as xlink
def role_fn(name, rawtext, text, lineno, inliner,
options={}, content=[]):
node = nodes.reference(rawtext, text, refuri = "http://pylearn.org/theano/wiki/%s" % text)
return [node], []
_TARGET_RE = re.compile(r'^(.*?)\s*<(?:URI:|URL:)?([^<>]+)>$')
def create_api_role(name, problematic):
"""
Create and register a new role to create links for an API documentation.
Create a role called `name`, which will use the URL resolver registered as
``name`` in `api_register` to create a link for an object.
:Parameters:
`name` : `str`
name of the role to create.
`problematic` : `bool`
if True, the registered role will create problematic nodes in
case of failed references. If False, a warning will be raised
anyway, but the output will appear as an ordinary literal.
"""
def resolve_api_name(n, rawtext, text, lineno, inliner,
options={}, content=[]):
# Check if there's separate text & targets
m = _TARGET_RE.match(text)
if m: text, target = m.groups()
else: target = text
# node in monotype font
text = utils.unescape(text)
node = nodes.literal(rawtext, text, **options)
# Get the resolver from the register and create an url from it.
try:
url = xlink.api_register[name].get_url(target)
except IndexError, exc:
msg = inliner.reporter.warning(str(exc), line=lineno)
if problematic:
prb = inliner.problematic(rawtext, text, msg)
return [prb], [msg]
else:
return [node], []
if url is not None:
node = nodes.reference(rawtext, '', node, refuri=url, **options)
return [node], []
roles.register_local_role(name, resolve_api_name)
def setup(app):
try:
xlink.set_api_file('api', os.path.join(app.outdir, 'api', 'api-objects.txt'))
apiroot = os.getenv('THEANO_API_ROOT')
if not apiroot:
apiroot = os.path.join(os.path.realpath('api'), '')
xlink.set_api_root('api', apiroot)
#xlink.create_api_role('api', True)
create_api_role('api', True)
except IOError:
print >>sys.stderr, 'WARNING: Could not find api file! API links will not work.'
app.add_role("wiki", role_fn)
......@@ -44,7 +44,7 @@ What needs to be defined
In order to be C-compatible, a Type must define several additional
methods, which all start with the ``c_`` prefix. The complete list can
be found in the documentation for :api:`gof.type.Type`. Here, we'll focus on
be found in the documentation for :class:`.gof.type.Type`. Here, we'll focus on
the most important ones:
......
......@@ -10,7 +10,7 @@ Making the double type
Type's contract
===============
In Theano's framework, a ``Type`` (:api:`gof.type.Type`)
In Theano's framework, a ``Type`` (:class:`.gof.type.Type`)
is any object which defines the following
methods. To obtain the default methods described below, the Type should
be an instance of ``Type`` or should be an instance of a
......
......@@ -252,3 +252,10 @@ to both.
As you read through examples of Theano code, you will probably see many
instances of Modules being nested in this way.
===================================================================
:mod:`module` -- API documentation
===================================================================
.. automodule:: theano.compile.module
:members:
......@@ -15,6 +15,7 @@
env
toolbox
type
.. _libdoc_gof_type:
================================================
:mod:`type` -- Interface for types of variables
================================================
.. module:: env
:platform: Unix, Windows
:synopsis: Interface for types of symbolic variables
.. moduleauthor:: LISA
---------
Reference
---------
.. automodule:: theano.gof.type
:members:
......@@ -133,7 +133,7 @@ analogous to a function.
A Module is meant to contain Components.
Attributes which are not Components themselves must at least be transform-able
into Components by :api:`compile.module.wrap`. If a Module contains something
into Components by :func:`.compile.module.wrap`. If a Module contains something
that is not convertible into a Component, then it is not possible to compile
that Module with ``make``.
......
.. _module:
.. _module2:
######
Module
......
......@@ -62,7 +62,7 @@ What is staticmethod, st_impl?
implicitly take the class instance as a first argument. Hence, st_impl
can be used for Op implementations when no information from the Op
instance is needed. This can be useful for testing an implementation.
See :api:`XlogX` for an example.
See the ``XlogX`` class below for an example.
**This documentation is useful when we show users how to write Ops.
Olivier says this behavior should be discouraged but I feel that st_impl
......@@ -72,7 +72,7 @@ should be encouraged where possible.**
how do we write scalar ops and upgrade them to tensor ops?
============================================================
**Olivier says that :api:`XlogX` gives a good example. In fact, I would
**Olivier says that** :class:`~theano.tensor.xlogx.XlogX` **gives a good example. In fact, I would
like to beef xlogx up into our running example for demonstrating how to
write an Op:**
......
......@@ -112,8 +112,8 @@ Misc
----
The sparse equivalent of dmatrix is csc_matrix and csr_matrix.
:api:`Dot` vs. :api:`StructuredDot`
----------------------------------------
:class:`~theano.sparse.basic.Dot` vs. :class:`~theano.sparse.basic.StructuredDot`
---------------------------------------------------------------------------------
Often when you use a sparse matrix it is because there is a meaning to the
structure of non-zeros. The gradient on terms outside that structure
......
......@@ -73,19 +73,9 @@ if __name__ == '__main__':
print ' --help: this help'
sys.exit(0)
options['--all'] = not (bool(options['--epydoc']) ^ bool(options['--rst']))
if 0:
import gen_oplist
print 'Generating oplist...'
gen_oplist.print_file(open('%s/doc/indexes/oplist.txt' % throot, 'w'))
print 'oplist done!'
if 0:
import gen_typelist
print 'Generating typelist...'
gen_typelist.print_file(open('%s/doc/indexes/typelist.txt' % throot, 'w'))
print 'typelist done!'
if not (options['--epydoc'] or options['--rst']):
# Default is now rst
options['--rst'] = True
def mkdir(path):
try:
......@@ -96,8 +86,6 @@ if __name__ == '__main__':
outdir = options['-o'] or (throot + '/html')
mkdir(outdir)
os.chdir(outdir)
mkdir("doc")
mkdir("api")
# Make sure the appropriate 'theano' directory is in the PYTHONPATH
pythonpath = os.environ.get('PYTHONPATH', '')
......@@ -105,6 +93,7 @@ if __name__ == '__main__':
os.environ['PYTHONPATH'] = pythonpath
if options['--all'] or options['--epydoc']:
mkdir("api")
from epydoc.cli import cli
sys.path[0:0] = [throot]
......@@ -120,6 +109,7 @@ if __name__ == '__main__':
# TODO
if options['--all'] or options['--rst']:
mkdir("doc")
import sphinx
sys.path[0:0] = [os.path.join(throot, 'doc')]
sphinx.main(['', '-E', os.path.join(throot, 'doc'), '.'])
......
"""script to generate doc/oplist.txt, which compiles to :doc:`oplist`. """
__docformat__ = "restructuredtext en"
import sys, os
throot = "/".join(sys.path[0].split("/")[:-2])
sys.path[0:0] = [throot]
from theano import gof
def print_title(file, title_string, under_char, over_char=''):
l = len(title_string)
if over_char:
print >>file, over_char * l
print >>file, title_string
if under_char:
print >>file, under_char * l
print >>file, ""
def print_hline(file):
print >>file, '-' * 80
class Entry:
"""Structure for generating the oplist file"""
symbol = None
name = None
module = None
docstring = None
tags = []
def __init__(self, symbol, name, current_module):
self.symbol = symbol
self.name = name
self.module = symbol.__module__ # current_module.__name__ # symbol.__module__
self.docstring = symbol.__doc__
self.tags = ['%s' % current_module.__name__] + getattr(symbol, '__oplist_tags', [])
def mini_desc(self, maxlen=50):
"""Return a short description of the op"""
def chomp(s):
"""interpret and left-align a docstring"""
if 'subtensor' in s:
debug = 0
else:
debug = 0
r = []
leadspace = True
for c in s:
if leadspace and c in ' \n\t':
continue
else:
leadspace = False
if c == '\n':
if debug:
print >> sys.stderr, 'breaking'
break
if c in '\t*`':
c = ' ';
r.append(c)
if debug:
print >> sys.stderr, r
return "".join(r)
minmax = 5
assert maxlen >= minmax
if not self.docstring:
return "" #+ '(no doc)'
elif len(self.docstring) < maxlen:
return chomp(self.docstring)
else:
return "%s ..."% chomp(self.docstring[:maxlen-minmax])
apilink = property(lambda self: ":api:`%s <%s.%s>`"% (self.name, self.module, self.name))
"""Return the ReST link into the epydoc of this symbol"""
class EntryOp(Entry):
def __init__(self, symbol, *args):
has_perform = hasattr(symbol, 'perform')
if symbol is gof.Op:
raise TypeError('not an Op subclass')
if not issubclass(symbol, gof.Op):
raise TypeError('not an Op subclass')
Entry.__init__(self, symbol, *args)
class EntryConstructor(Entry):
def __init__(self, symbol, name, module):
is_op = isinstance(symbol, gof.Op)
is_ctor = symbol in getattr(module, '__oplist_constructor_list', [])
if not (is_op or is_ctor):
raise TypeError('not a constructor', symbol)
Entry.__init__(self, symbol, name, module)
def search_entries(module_list, ops = None, constructors = None, seen = None):
if ops is None: ops = []
if constructors is None: constructors = []
if seen is None: seen = set()
modules = []
for module in module_list:
symbol_name_list = [s for s in dir(module) if not s[0] == '_']
for symbol_name in symbol_name_list:
symbol = getattr(module, symbol_name)
try:
if symbol in seen:
continue
seen.add(symbol)
except TypeError:
pass
if type(symbol) == type(module): # module
modules.append(symbol)
try:
ops.append(EntryOp(symbol, symbol_name, module))
except TypeError:
try:
constructors.append(EntryConstructor(symbol, symbol_name, module))
except TypeError:
pass
for symbol in modules:
search_entries([symbol], ops, constructors, seen)
return ops, constructors
def print_entries(file, ops, constructors):
tags = {}
for o in ops + constructors:
for t in o.tags:
tags.setdefault(t, []).append(o)
for t in tags:
print_title(file, t, '=')
tagged_ops = [op for op in tags[t] if isinstance(op, EntryOp)]
if len(tagged_ops):
print_title(file, 'Op Classes', '-')
for op in tagged_ops:
print >>file, "- %s" % op.apilink
print >>file, " %s" % op.mini_desc()
print >>file, ""
tagged_ops = [op for op in tags[t] if isinstance(op, EntryConstructor)]
if len(tagged_ops):
print_title(file, 'Op Constructors', '-')
for op in tagged_ops:
print >>file, "- %s" % op.apilink
print >>file, " %s" % op.mini_desc()
print >>file, ""
def print_file(file):
print >>file, '.. _oplist:\n\n'
print_title(file, "Op List", "~", "~")
print >>file, """
This page lists the `Op Classes` and `constructors` that are provided by the Theano library.
`Op Classes` drive from :api:`Op`, whereas `constructors` are typically `Op Class` instances, but may be true Python functions.
In the future, this list may distinguish `constructors` that are Op instances from true Python functions.
"""
print_hline(file)
print >>file, ""
print >>file, ".. contents:: "
print >>file, ""
ops, constructors = search_entries([theano])
print_entries(file, ops, constructors)
print >>file, ""
import theano
if __name__ == "__main__":
"""Generate the op list"""
if len(sys.argv) >= 2:
file = open(sys.argv[1], 'w')
else:
file = sys.stdout
print_file(file)
from gen_oplist import print_title, print_hline
def print_file(file):
print >>file, '.. _typelist:\n\n'
print_title(file, "Type List", "~", "~")
print >>file, "*THIS PAGE IS A PLACEHOLDER: WRITEME*"
print >>file, ""
print_hline(file)
print >>file, ""
print >>file, ".. contents::"
print >>file, ""
print_title(file, "Type Classes", '=')
print >>file, "- scalar.Scalar\n"
print >>file, "- tensor.Tensor\n"
print >>file, "- sparse.Sparse\n"
print_title(file, "Type Instances", '=')
print >>file, "- scalar.int8\n"
print >>file, "- tensor.lvector\n"
print >>file, "- sparse.??\n"
print >>file, ""
if __name__ == '__main__':
if len(sys.argv) >= 2:
file = open(sys.argv[1], 'w')
else:
file = sys.stdout
print_file(file)
......@@ -223,10 +223,9 @@ class Variable(utils.object2):
A Variable which is the output of a symbolic computation will have an owner != None.
Code Example
============
**Code Example**
.. python::
.. code-block:: python
import theano
from theano import tensor
......
......@@ -340,7 +340,8 @@ class Type(object2, PureType, CLinkerType):
The following following code illustrates the use of a Type instance, here tensor.fvector:
.. python::
.. code-block:: python
# Declare a symbolic floating-point vector using __call__
b = tensor.fvector()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论