def _warn_out(self, text): self.info(text, nonl=True) if self.app.quiet: self.warn(text) if isinstance(text, binary_type): text = force_decode(text, None) self.outfile.write(text)
def make_rst(self): app = import_object(self.arguments[0]) for method, path, endpoint in get_routes(app): try: blueprint, endpoint_internal = endpoint.split('.') if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and path == static_url_path + '/(path:filename)'): continue view = app.view_functions[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, unicode): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line
def get_doc(self, encoding=None): content = self.env.config.autoclass_content docstrings = [] attrdocstring = sage_getdoc_original(self.object) if attrdocstring: docstrings.append(attrdocstring) # for classes, what the "docstring" is can be controlled via a # config value; the default is only the class docstring if content in ('both', 'init'): initdocstring = sage_getdoc_original( self.get_attr(self.object, '__init__', None)) # for new-style classes, no __init__ means default __init__ if initdocstring == object.__init__.__doc__: initdocstring = None if initdocstring: if content == 'init': docstrings = [initdocstring] else: docstrings.append(initdocstring) doc = [] for docstring in docstrings: if not isinstance(docstring, unicode): docstring = force_decode(docstring, encoding) doc.append(prepare_docstring(docstring)) return doc
def object_description(object): # type: (Any) -> unicode """A repr() implementation that returns text safe to use in reST context.""" if isinstance(object, dict): try: sorted_keys = sorted(object) except TypeError: pass # Cannot sort dict keys, fall back to generic repr else: items = ("%s: %s" % (object_description(key), object_description(object[key])) for key in sorted_keys) return "{%s}" % ", ".join(items) if isinstance(object, set): try: sorted_values = sorted(object) except TypeError: pass # Cannot sort set values, fall back to generic repr else: template = "{%s}" if PY3 else "set([%s])" return template % ", ".join(object_description(x) for x in sorted_values) try: s = repr(object) except Exception: raise ValueError if isinstance(s, binary_type): s = force_decode(s, None) # type: ignore # Strip non-deterministic memory addresses such as # ``<__main__.A at 0x7f68cb685710>`` s = memory_address_re.sub('', s) return s.replace('\n', ' ')
def recurse(cls): if not show_builtins and cls in py_builtins: return if not private_bases and cls.__name__.startswith('_'): return nodename = self.class_name(cls, parts) fullname = self.class_name(cls, 0) # Use first line of docstring as tooltip, if available tooltip = None try: if cls.__doc__: enc = ModuleAnalyzer.for_module(cls.__module__).encoding doc = cls.__doc__.strip().split("\n")[0] if not isinstance(doc, text_type): doc = force_decode(doc, enc) if doc: tooltip = '"%s"' % doc.replace('"', '\\"') except Exception: # might raise AttributeError for strange classes pass baselist = [] all_classes[cls] = (nodename, fullname, baselist, tooltip) for base in cls.__bases__: if not show_builtins and base in py_builtins: continue if not private_bases and base.__name__.startswith('_'): continue baselist.append(self.class_name(base, parts)) if base not in all_classes: recurse(base)
def get_doc(self, encoding=None, ignore=1): """Overrides ClassDocumenter.get_doc to create the doc scraped from the Process object, then adds additional content from the class docstring. """ from six import text_type # Get the class docstring. This is a copy of the ClassDocumenter.get_doc method. Using "super" does weird stuff. docstring = self.get_attr(self.object, '__doc__', None) # make sure we have Unicode docstrings, then sanitize and split # into lines if isinstance(docstring, text_type): docstring = prepare_docstring(docstring, ignore) elif isinstance(docstring, str): # this will not trigger on Py3 docstring = prepare_docstring(force_decode(docstring, encoding), ignore) # Create the docstring by scraping info from the Process instance. pdocstrings = self.make_numpy_doc() if self.options.docstring and docstring is not None: # Add the sections from the class docstring itself. pdocstrings.extend(docstring[self.options.skiplines:]) # Parse using the Numpy docstring format. docstrings = NumpyDocstring(pdocstrings, self.env.config, self.env.app, what='class', obj=self.object, options=self.options) return [docstrings.lines()]
def add_content(self, more_content, no_docstring=False): if not is_mpd_running(): return try: cls = self.object instance = cls(must_start_worker = False, must_handle_state = False) try: #instance.initialize_code() parameter_documentation = self.get_sphinx_doc_for_parameters(instance.parameters) finally: instance.stop() except Exception as ex: print ex return if self.analyzer: # prevent encoding errors when the file name is non-ASCII filename = unicode(self.analyzer.srcname, sys.getfilesystemencoding(), 'replace') sourcename = u'%s:docstring of %s' % (filename, self.fullname) else: sourcename = u'docstring of %s' % self.fullname encoding = self.analyzer and self.analyzer.encoding lines = prepare_docstring(force_decode(parameter_documentation, encoding)) for i, line in enumerate(self.process_doc([lines,])): self.add_line(line, sourcename, i)
def get_doc(self, encoding=None): """Decode and return lines of the docstring(s) for the object.""" docstring = self.get_attr(self.object, '__doc__', None) if docstring: # make sure we have Unicode docstrings, then sanitize and split # into lines return [prepare_docstring(force_decode(docstring, encoding))] return []
def inspect_routes(self, app): """Inspects the views of Flask. :param app: The Flask application. :returns: 4-tuple like ``(method, paths, view_func, view_doc)`` """ if self.endpoints: routes = itertools.chain(*[get_routes(app, endpoint, self.order) for endpoint in self.endpoints]) else: routes = get_routes(app, order=self.order) for method, paths, endpoint in routes: try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and static_url_path + '/(path:filename)' in paths): continue view = app.view_functions[endpoint] if self.modules and view.__module__ not in self.modules: continue if self.undoc_modules and view.__module__ in self.modules: continue view_class = getattr(view, 'view_class', None) if view_class is None: view_func = view else: view_func = getattr(view_class, method.lower(), None) view_doc = view.__doc__ or '' if view_func and view_func.__doc__: view_doc = view_func.__doc__ if not isinstance(view_doc, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) view_doc = force_decode(view_doc, analyzer.encoding) if not view_doc and 'include-empty-docstring' not in self.options: continue yield (method, paths, view_func, view_doc)
def safe_repr(object): """A repr() implementation that returns text safe to use in reST context.""" try: s = repr(object) except Exception: raise ValueError if isinstance(s, bytes): return force_decode(s, None).replace('\n', ' ') return s.replace('\n', ' ')
def add_docstring(docstring): if docstring: with IndentBlock(self): self.add_line(u'', directive_name) source_name = u'docstring of %s.%s' % (self.fullname, name) docstring = [prepare_docstring(force_decode(docstring, None))] for i, line in enumerate(self.process_doc(docstring)): self.add_line(line, source_name, i) self.add_line(u'', directive_name)
def _warn_out(self, text): # type: (unicode) -> None if self.app.quiet or self.app.warningiserror: logger.warning(text) else: logger.info(text, nonl=True) if isinstance(text, binary_type): text = force_decode(text, None) self.outfile.write(text)
def document_members(self, all_members=True): oldindent = self.indent members = list(self.object.attributes.items()) if self.options.members is not autodoc.ALL: specified = [] for line in (self.options.members or []): specified.extend(line.split()) members = { name: value for name, value in members if name in specified } member_order = ( self.options.member_order or self.env.config.autodoc_member_order ) if member_order == 'alphabetical': members.sort() if member_order == 'groupwise': members.sort(key=lambda e: isinstance(e[1], Method)) elif member_order == 'bysource' and self.analyzer: name = self.object.__name__ def keyfunc(entry): return self.analyzer.tagorder.get( '.'.join((name, entry[0])), len(self.analyzer.tagorder) ) members.sort(key=keyfunc) for name, specification in members: self.add_line(u'', '<autointerface>') if isinstance(specification, Method): self.add_line( u'.. method:: {name}{arguments}'.format( name=name, arguments=inspect.formatargspec( *specification.argument_specification ) ), '<autointerface>' ) else: self.add_line( u'.. attribute:: {name}'.format(name=name), '<autointerface>' ) doc = specification.docstring if doc: self.add_line(u'', '<autointerface>') self.indent += self.content_indent sourcename = u'docstring of %s.%s' % (self.fullname, name) docstrings = [prepare_docstring(force_decode(doc, None))] for i, line in enumerate(self.process_doc(docstrings)): self.add_line(line, sourcename, i) self.add_line(u'', '<autointerface>') self.indent = oldindent
def get_doc(self, encoding=None): docstr = self.get_attr(self.object, '__doc__', None) if docstr: docstr = force_decode(docstr, encoding) myname = self.fullname[len(self.modname)+1:] if myname.endswith('()'): myname = myname[:-2] if (docstr and (myname + '(') in docstr and '\n' in docstr and docstr[docstr.index('\n')-1] == ')'): docstr = docstr[docstr.index('\n')+1:] if docstr: # make sure we have Unicode docstrings, then sanitize and split # into lines return [prepare_docstring(force_decode(docstr, encoding))] return []
def _warn_out(self, text): self.info(text, nonl=True) if self.app.quiet: self.warn(text) if sys.version_info >= (3,0,0): isbytes = isinstance(text, bytes) else: isbytes = isinstance(text, str) if isbytes: text = force_decode(text, None) self.outfile.write(text)
def make_rst(self, qref=False): app = import_object(self.arguments[0]) if self.endpoints: routes = itertools.chain(*[get_routes(app, endpoint, self.order) for endpoint in self.endpoints]) else: routes = get_routes(app, order=self.order) for method, paths, endpoint in routes: try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and static_url_path + '/(path:filename)' in paths): continue view = app.view_functions[endpoint] if self.modules and view.__module__ not in self.modules: continue if self.undoc_modules and view.__module__ in self.modules: continue docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) if qref == True: for path in paths: row = quickref_directive(method, path, docstring) yield row else: for line in http_directive(method, paths, docstring): yield line
def object_description(object): """A repr() implementation that returns text safe to use in reST context.""" try: s = repr(object) except Exception: raise ValueError if isinstance(s, binary_type): s = force_decode(s, None) # Strip non-deterministic memory addresses such as # ``<__main__.A at 0x7f68cb685710>`` s = memory_address_re.sub('', s) return s.replace('\n', ' ')
def method_interface_documenter(app, what, name, obj, options, lines): if what != 'method': return if lines: return if not getattr(obj, 'im_class'): return interfaces = get_implemented_interfaces(obj.im_class) for interface in interfaces: if obj.__name__ in interface.attributes: docstring = interface.attributes[obj.__name__].docstring lines.extend( prepare_docstring(force_decode(docstring, None)) )
def document_members(self, all_members=True): oldindent = self.indent members = list(self.object.namesAndDescriptions()) if self.options.members is not autodoc.ALL: specified = [] for line in (self.options.members or []): specified.extend(line.split()) mapping = dict(members) members = [(x, mapping[x]) for x in specified] member_order = (self.options.member_order or self.env.config.autodoc_member_order) if member_order == 'alphabetical': members.sort() if member_order == 'groupwise': # sort by group; relies on stable sort to keep items in the # same group sorted alphabetically members.sort(key=lambda e: getattr(e[1], 'getSignatureString', None) is not None) elif member_order == 'bysource' and self.analyzer: # sort by source order, by virtue of the module analyzer tagorder = self.analyzer.tagorder name = self.object.__name__ def keyfunc(entry): return tagorder.get('%s.%s' % (name, entry[0]), len(tagorder)) members.sort(key=keyfunc) for name, desc in members: self.add_line(u'', '<autointerface>') sig = getattr(desc, 'getSignatureString', None) if sig is None: self.add_line(u'.. attribute:: %s' % name, '<autointerface>') else: self.add_line(u'.. method:: %s%s' % (name, sig()), '<autointerface>') doc = desc.getDoc() if doc: self.add_line(u'', '<autointerface>') self.indent += self.content_indent sourcename = u'docstring of %s.%s' % (self.fullname, name) docstrings = [prepare_docstring(force_decode(doc, None))] for i, line in enumerate(self.process_doc(docstrings)): self.add_line(line, sourcename, i) self.add_line(u'', '<autointerface>') self.indent = oldindent
def make_rst(self): app = import_object(self.arguments[0]) for method, path, target in get_routes(app): endpoint = target.name or target.callback.__name__ if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue view = target.callback docstring = view.__doc__ or '' if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line
def get_doc(self, encoding=None, ignore=1): content = self.env.config.autoclass_content docstrings = [] attrdocstring = self.get_attr(self.object, '__doc__', None) if attrdocstring: docstrings.append(attrdocstring) # for classes, what the "docstring" is can be controlled via a # config value; the default is only the class docstring if content in ('both', 'init'): # get __init__ method document from __init__.__doc__ if self.env.config.autodoc_docstring_signature: # only act if the feature is enabled init_doc = MatMethodDocumenter(self.directive, self.object.name) init_doc.object = self.get_attr(self.object, self.object.name, None) init_doc.objpath = [self.object.name] init_doc._find_signature() # this effects to get_doc() result initdocstring = '\n'.join( ['\n'.join(l) for l in init_doc.get_doc(encoding)]) else: initdocstring = self.get_attr( self.get_attr(self.object, self.object.name, None), '__doc__') # for new-style classes, no __init__ means default __init__ if initdocstring == object.__init__.__doc__: initdocstring = None if initdocstring: if content == 'init': docstrings = [initdocstring] else: docstrings.append(initdocstring) doc = [] for docstring in docstrings: if not isinstance(docstring, unicode): docstring = force_decode(docstring, encoding) doc.append(prepare_docstring(docstring)) return doc
def format_args(self): myname = self.fullname[len(self.modname)+1:] if myname.endswith('()'): myname = myname[:-2] # Try to parse docstring docstr = self.get_attr(self.object, '__doc__', None) if docstr: docstr = force_decode(docstr, 'utf-8') if (docstr and (myname + '(') in docstr and '\n' in docstr and docstr[docstr.index('\n')-1] == ')'): args = docstr[len(myname)+1:docstr.index('\n')-1] # Get rid of Cython style types declarations argl = [] for arg in [ x.strip() for x in args.split(',') ]: if (arg in ('cls', 'self') and isinstance(self, SphinxAutodoc.MethodDocumenter)): continue hit = TYPE_RE.match(arg) if hit: argl.append(hit.group(1)) else: argl.append(arg) args = '(%s)' % ', '.join(argl) else: # super seems to get this wrong: for cls in (MethodDocumenter, FunctionDocumenter, ClassDocumenter): if isinstance(self, cls): return cls.format_args(self) # return super(self.__class__, self).format_args() # escape backslashes for reST args = args.replace('\\', '\\\\') return args
def get_doc(self, encoding=None): content = self.env.config.autoclass_content docstrings = [] docstring = self.get_attr(self.object, '__doc__', None) if docstring: docstrings.append(docstring) # for classes, what the "docstring" is can be controlled via a # config value; the default is only the class docstring if content in ('both', 'init'): initdocstring = self.get_attr( self.get_attr(self.object, '__init__', None), '__doc__') # for new-style classes, no __init__ means default __init__ if initdocstring == object.__init__.__doc__: initdocstring = None if initdocstring: if content == 'init': docstrings = [initdocstring] else: docstrings.append(initdocstring) return [prepare_docstring(force_decode(docstring, encoding)) for docstring in docstrings]
def document_members(self, all_members=True): # a member in our example is baz, x, and bart oldindent = self.indent for name, desc in self.object.namesAndDescriptions(): # name is going to be successively baz, x, then bart self.add_line(u'', '<autointerface>') sig = getattr(desc, 'getSignatureString', None) if sig is None: self.add_line(u'.. attribute:: %s' % name, '<autointerface>') else: self.add_line(u'.. method:: %s%s' % (name, sig()), '<autointerface>') doc = desc.getDoc() if doc: self.add_line(u'', '<autointerface>') self.indent += self.content_indent sourcename = u'docstring of %s.%s' % (self.fullname, name) docstrings=[prepare_docstring(force_decode(doc, None))] for i, line in enumerate(self.process_doc(docstrings)): self.add_line(line, sourcename, i) self.add_line(u'', '<autointerface>') self.indent = oldindent
def inspect_routes(self, app): """Inspects the views of Flask. :param app: The Flask application. :returns: 4-tuple like ``(method, paths, view_func, view_doc)`` """ if self.endpoints: routes = itertools.chain(*[ get_routes(app, endpoint, self.order) for endpoint in self.endpoints ]) else: routes = get_routes(app, order=self.order) for method, paths, endpoint in routes: try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and static_url_path + '/(path:filename)' in paths): continue view = app.view_functions[endpoint] if self.modules and view.__module__ not in self.modules: continue if self.undoc_modules and view.__module__ in self.modules: continue view_class = getattr(view, 'view_class', None) if view_class is None: view_func = view else: view_func = getattr(view_class, method.lower(), None) view_doc = view.__doc__ or '' if view_func and view_func.__doc__: view_doc = view_func.__doc__ if not isinstance(view_doc, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) view_doc = force_decode(view_doc, analyzer.encoding) if not view_doc and 'include-empty-docstring' not in self.options: continue # select section (delimited by http:<method>) corresponding to method view_doc = filter_by_method(view_doc, method) # convert numpy-style docstrings into RST via napoleon from sphinx.ext.napoleon import Config, NumpyDocstring view_doc = str( NumpyDocstring( '\n'.join( NumpyDocstring('')._dedent(view_doc.split('\n'))), Config())) yield (method, paths, view_func, view_doc)
def get_doc(self, encoding=None): """Get the documentation from the object.""" doc = self.func_doc or self.kwargs.get('doc') or '' return force_decode(doc, encoding)
def build_qhp(self, outdir, outname): self.info('writing project file...') # sections tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False) istoctree = lambda node: ( isinstance(node, addnodes.compact_paragraph) and 'toctree' in node) sections = [] for node in tocdoc.traverse(istoctree): sections.extend(self.write_toc(node)) for indexname, indexcls, content, collapse in self.domain_indices: item = section_template % {'title': indexcls.localname, 'ref': '%s.html' % indexname} sections.append(' ' * 4 * 4 + item) # sections may be unicode strings or byte strings, we have to make sure # they are all unicode strings before joining them new_sections = [] for section in sections: if not isinstance(section, text_type): new_sections.append(force_decode(section, None)) else: new_sections.append(section) sections = u'\n'.join(new_sections) # keywords keywords = [] index = self.env.create_index(self, group_entries=False) for (key, group) in index: for title, (refs, subitems) in group: keywords.extend(self.build_keywords(title, refs, subitems)) keywords = u'\n'.join(keywords) # files if not outdir.endswith(os.sep): outdir += os.sep olen = len(outdir) projectfiles = [] staticdir = path.join(outdir, '_static') imagesdir = path.join(outdir, self.imagedir) for root, dirs, files in os.walk(outdir): resourcedir = root.startswith(staticdir) or \ root.startswith(imagesdir) for fn in files: if (resourcedir and not fn.endswith('.js')) or \ fn.endswith('.html'): filename = path.join(root, fn)[olen:] projectfiles.append(file_template % {'filename': htmlescape(filename)}) projectfiles = '\n'.join(projectfiles) # it seems that the "namespace" may not contain non-alphanumeric # characters, and more than one successive dot, or leading/trailing # dots, are also forbidden nspace = 'org.sphinx.%s.%s' % (outname, self.config.version) nspace = re.sub('[^a-zA-Z0-9.]', '', nspace) nspace = re.sub(r'\.+', '.', nspace).strip('.') nspace = nspace.lower() # write the project file f = codecs.open(path.join(outdir, outname+'.qhp'), 'w', 'utf-8') try: f.write(project_template % { 'outname': htmlescape(outname), 'title': htmlescape(self.config.html_title), 'version': htmlescape(self.config.version), 'project': htmlescape(self.config.project), 'namespace': htmlescape(nspace), 'masterdoc': htmlescape(self.config.master_doc), 'sections': sections, 'keywords': keywords, 'files': projectfiles}) finally: f.close() homepage = 'qthelp://' + posixpath.join( nspace, 'doc', self.get_target_uri(self.config.master_doc)) startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html') self.info('writing collection project file...') f = codecs.open(path.join(outdir, outname+'.qhcp'), 'w', 'utf-8') try: f.write(collection_template % { 'outname': htmlescape(outname), 'title': htmlescape(self.config.html_short_title), 'homepage': htmlescape(homepage), 'startpage': htmlescape(startpage)}) finally: f.close()
def build_qhp(self, outdir, outname): # type: (unicode, unicode) -> None logger.info(__('writing project file...')) # sections tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False) def istoctree(node): # type: (nodes.Node) -> bool return isinstance(node, addnodes.compact_paragraph) and \ 'toctree' in node sections = [] for node in tocdoc.traverse(istoctree): sections.extend(self.write_toc(node)) for indexname, indexcls, content, collapse in self.domain_indices: item = section_template % {'title': indexcls.localname, 'ref': '%s.html' % indexname} sections.append(' ' * 4 * 4 + item) # sections may be unicode strings or byte strings, we have to make sure # they are all unicode strings before joining them new_sections = [] for section in sections: if not isinstance(section, text_type): new_sections.append(force_decode(section, None)) else: new_sections.append(section) sections = u'\n'.join(new_sections) # type: ignore # keywords keywords = [] index = IndexEntries(self.env).create_index(self, group_entries=False) for (key, group) in index: for title, (refs, subitems, key_) in group: keywords.extend(self.build_keywords(title, refs, subitems)) keywords = u'\n'.join(keywords) # type: ignore # it seems that the "namespace" may not contain non-alphanumeric # characters, and more than one successive dot, or leading/trailing # dots, are also forbidden if self.config.qthelp_namespace: nspace = self.config.qthelp_namespace else: nspace = 'org.sphinx.%s.%s' % (outname, self.config.version) nspace = re.sub('[^a-zA-Z0-9.]', '', nspace) nspace = re.sub(r'\.+', '.', nspace).strip('.') nspace = nspace.lower() # write the project file with codecs.open(path.join(outdir, outname + '.qhp'), 'w', 'utf-8') as f: # type: ignore # NOQA body = render_file('project.qhp', outname=outname, title=self.config.html_title, version=self.config.version, project=self.config.project, namespace=nspace, master_doc=self.config.master_doc, sections=sections, keywords=keywords, files=self.get_project_files(outdir)) f.write(body) homepage = 'qthelp://' + posixpath.join( nspace, 'doc', self.get_target_uri(self.config.master_doc)) startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html') logger.info(__('writing collection project file...')) with codecs.open(path.join(outdir, outname + '.qhcp'), 'w', 'utf-8') as f: # type: ignore # NOQA body = render_file('project.qhcp', outname=outname, title=self.config.html_short_title, homepage=homepage, startpage=startpage) f.write(body)
def make_rst(self): app = import_object(self.arguments[0]) yield "Services:\n" yield "" for x in self._make_toc(get_routes(app)): yield '- {}'.format(x) yield "" for method, path, endpoint in get_routes(app): try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and path == static_url_path + '/(path:filename)'): continue view = app.view_functions[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue #Thanks flask-classy for this :D if len(endpoint.split(":")) == 2: view_cls, view_func = endpoint.split(":") if hasattr(app, 'view_classes') and view_cls in app.view_classes: cls = app.view_classes[view_cls] members = inspect.getmembers(cls,predicate=inspect.ismethod) if hasattr(cls,'args_rules'): rules = cls.args_rules if view_func in rules: for m in members: if m[0] == view_func: docstring += m[1].__doc__.strip() docstring += '\n\n' for a in rules[view_func]: t = str(a.type).replace('type','').replace("'","").replace('<','').replace('>','') params = dict( type=t, name=str(a.name), description=str(a.description), default=str(a.default) ) if a.required: docstring += ' :<json {type} {name}: {description}.\n'.format(**params) else: docstring += ' :<json {type} {name}: *(optional)* {description}. *Default*={default}\n'.format(**params) docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line
def build_qhp(self, outdir, outname): # type: (unicode, unicode) -> None logger.info(__('writing project file...')) # sections tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False) def istoctree(node): # type: (nodes.Node) -> bool return isinstance(node, addnodes.compact_paragraph) and \ 'toctree' in node sections = [] for node in tocdoc.traverse(istoctree): sections.extend(self.write_toc(node)) for indexname, indexcls, content, collapse in self.domain_indices: item = section_template % { 'title': indexcls.localname, 'ref': '%s.html' % indexname } sections.append(' ' * 4 * 4 + item) # sections may be unicode strings or byte strings, we have to make sure # they are all unicode strings before joining them new_sections = [] for section in sections: if not isinstance(section, text_type): new_sections.append(force_decode(section, None)) else: new_sections.append(section) sections = u'\n'.join(new_sections) # type: ignore # keywords keywords = [] index = IndexEntries(self.env).create_index(self, group_entries=False) for (key, group) in index: for title, (refs, subitems, key_) in group: keywords.extend(self.build_keywords(title, refs, subitems)) keywords = u'\n'.join(keywords) # type: ignore # it seems that the "namespace" may not contain non-alphanumeric # characters, and more than one successive dot, or leading/trailing # dots, are also forbidden if self.config.qthelp_namespace: nspace = self.config.qthelp_namespace else: nspace = 'org.sphinx.%s.%s' % (outname, self.config.version) nspace = re.sub(r'[^a-zA-Z0-9.\-]', '', nspace) nspace = re.sub(r'\.+', '.', nspace).strip('.') nspace = nspace.lower() # write the project file with codecs.open(path.join(outdir, outname + '.qhp'), 'w', 'utf-8') as f: # type: ignore # NOQA body = render_file('project.qhp', outname=outname, title=self.config.html_title, version=self.config.version, project=self.config.project, namespace=nspace, master_doc=self.config.master_doc, sections=sections, keywords=keywords, files=self.get_project_files(outdir)) f.write(body) homepage = 'qthelp://' + posixpath.join( nspace, 'doc', self.get_target_uri(self.config.master_doc)) startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html') logger.info(__('writing collection project file...')) with codecs.open(path.join(outdir, outname + '.qhcp'), 'w', 'utf-8') as f: # type: ignore # NOQA body = render_file('project.qhcp', outname=outname, title=self.config.html_short_title, homepage=homepage, startpage=startpage) f.write(body)
def build_qhp(self, outdir, outname): self.info("writing project file...") # sections tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False) def istoctree(node): return isinstance(node, addnodes.compact_paragraph) and "toctree" in node sections = [] for node in tocdoc.traverse(istoctree): sections.extend(self.write_toc(node)) for indexname, indexcls, content, collapse in self.domain_indices: item = section_template % {"title": indexcls.localname, "ref": "%s.html" % indexname} sections.append(" " * 4 * 4 + item) # sections may be unicode strings or byte strings, we have to make sure # they are all unicode strings before joining them new_sections = [] for section in sections: if not isinstance(section, text_type): new_sections.append(force_decode(section, None)) else: new_sections.append(section) sections = u"\n".join(new_sections) # keywords keywords = [] index = self.env.create_index(self, group_entries=False) for (key, group) in index: for title, (refs, subitems, key_) in group: keywords.extend(self.build_keywords(title, refs, subitems)) keywords = u"\n".join(keywords) # files if not outdir.endswith(os.sep): outdir += os.sep olen = len(outdir) projectfiles = [] staticdir = path.join(outdir, "_static") imagesdir = path.join(outdir, self.imagedir) for root, dirs, files in os.walk(outdir): resourcedir = root.startswith(staticdir) or root.startswith(imagesdir) for fn in files: if (resourcedir and not fn.endswith(".js")) or fn.endswith(".html"): filename = path.join(root, fn)[olen:] projectfiles.append(file_template % {"filename": htmlescape(filename)}) projectfiles = "\n".join(projectfiles) # it seems that the "namespace" may not contain non-alphanumeric # characters, and more than one successive dot, or leading/trailing # dots, are also forbidden nspace = "org.sphinx.%s.%s" % (outname, self.config.version) nspace = re.sub("[^a-zA-Z0-9.]", "", nspace) nspace = re.sub(r"\.+", ".", nspace).strip(".") nspace = nspace.lower() # write the project file with codecs.open(path.join(outdir, outname + ".qhp"), "w", "utf-8") as f: f.write( project_template % { "outname": htmlescape(outname), "title": htmlescape(self.config.html_title), "version": htmlescape(self.config.version), "project": htmlescape(self.config.project), "namespace": htmlescape(nspace), "masterdoc": htmlescape(self.config.master_doc), "sections": sections, "keywords": keywords, "files": projectfiles, } ) homepage = "qthelp://" + posixpath.join(nspace, "doc", self.get_target_uri(self.config.master_doc)) startpage = "qthelp://" + posixpath.join(nspace, "doc", "index.html") self.info("writing collection project file...") with codecs.open(path.join(outdir, outname + ".qhcp"), "w", "utf-8") as f: f.write( collection_template % { "outname": htmlescape(outname), "title": htmlescape(self.config.html_short_title), "homepage": htmlescape(homepage), "startpage": htmlescape(startpage), } )
def build_qhp(self, outdir, outname): self.info('writing project file...') # sections tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False) def istoctree(node): return isinstance(node, addnodes.compact_paragraph) and \ 'toctree' in node sections = [] for node in tocdoc.traverse(istoctree): sections.extend(self.write_toc(node)) for indexname, indexcls, content, collapse in self.domain_indices: item = section_template % { 'title': indexcls.localname, 'ref': '%s.html' % indexname } sections.append(' ' * 4 * 4 + item) # sections may be unicode strings or byte strings, we have to make sure # they are all unicode strings before joining them new_sections = [] for section in sections: if not isinstance(section, text_type): new_sections.append(force_decode(section, None)) else: new_sections.append(section) sections = u'\n'.join(new_sections) # keywords keywords = [] index = self.env.create_index(self, group_entries=False) for (key, group) in index: for title, (refs, subitems, key_) in group: keywords.extend(self.build_keywords(title, refs, subitems)) keywords = u'\n'.join(keywords) # files if not outdir.endswith(os.sep): outdir += os.sep olen = len(outdir) projectfiles = [] staticdir = path.join(outdir, '_static') imagesdir = path.join(outdir, self.imagedir) for root, dirs, files in os.walk(outdir): resourcedir = root.startswith(staticdir) or \ root.startswith(imagesdir) for fn in files: if (resourcedir and not fn.endswith('.js')) or \ fn.endswith('.html'): filename = path.join(root, fn)[olen:] projectfiles.append(file_template % {'filename': htmlescape(filename)}) projectfiles = '\n'.join(projectfiles) # it seems that the "namespace" may not contain non-alphanumeric # characters, and more than one successive dot, or leading/trailing # dots, are also forbidden nspace = 'org.sphinx.%s.%s' % (outname, self.config.version) nspace = re.sub('[^a-zA-Z0-9.]', '', nspace) nspace = re.sub(r'\.+', '.', nspace).strip('.') nspace = nspace.lower() # write the project file with codecs.open(path.join(outdir, outname + '.qhp'), 'w', 'utf-8') as f: f.write( project_template % { 'outname': htmlescape(outname), 'title': htmlescape(self.config.html_title), 'version': htmlescape(self.config.version), 'project': htmlescape(self.config.project), 'namespace': htmlescape(nspace), 'masterdoc': htmlescape(self.config.master_doc), 'sections': sections, 'keywords': keywords, 'files': projectfiles }) homepage = 'qthelp://' + posixpath.join( nspace, 'doc', self.get_target_uri(self.config.master_doc)) startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html') self.info('writing collection project file...') with codecs.open(path.join(outdir, outname + '.qhcp'), 'w', 'utf-8') as f: f.write( collection_template % { 'outname': htmlescape(outname), 'title': htmlescape(self.config.html_short_title), 'homepage': htmlescape(homepage), 'startpage': htmlescape(startpage) })