From e400744907f76f1913aabaaa5260acb9ff264b92 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 20 Jul 2015 11:10:58 +0200 Subject: [PATCH] [ADD] github links to edit documentation pages --- _extensions/github_link.py | 105 +++++++++++++++++++++++++++++++++++++ conf.py | 6 ++- 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 _extensions/github_link.py diff --git a/_extensions/github_link.py b/_extensions/github_link.py new file mode 100644 index 000000000..baf301810 --- /dev/null +++ b/_extensions/github_link.py @@ -0,0 +1,105 @@ +import inspect +import importlib +import os.path +from urlparse import urlunsplit + +""" +* adds github_link(mode) context variable: provides URL (in relevant mode) of + current document on github +* if sphinx.ext.linkcode is enabled, automatically generates github linkcode + links (by setting config.linkcode_resolve) + +Settings +======== + +* ``github_user``, username/organisation under which the project lives +* ``github_project``, name of the project on github +* (optional) ``version``, github branch to link to (default: master) + +Notes +===== + +* provided ``linkcode_resolve`` only supports Python domain +* generates https github links +* explicitly imports ``openerp``, so useless for anyone else +""" + +def setup(app): + app.add_config_value('github_user', None, 'env') + app.add_config_value('github_project', None, 'env') + app.connect('html-page-context', add_doc_link) + + def linkcode_resolve(domain, info): + """ Resolves provided object to corresponding github URL + """ + # TODO: js? + if domain != 'py': + return None + if not (app.config.github_user and app.config.github_project): + return None + + module, fullname = info['module'], info['fullname'] + # TODO: attributes/properties don't have modules, maybe try to look + # them up based on their cached host object? + if not module: + return None + + obj = importlib.import_module(module) + for item in fullname.split('.'): + obj = getattr(obj, item, None) + + if obj is None: + return None + + # get original from decorated methods + try: obj = getattr(obj, '_orig') + except AttributeError: pass + + try: + obj_source_path = inspect.getsourcefile(obj) + _, line = inspect.getsourcelines(obj) + except (TypeError, IOError): + # obj doesn't have a module, or something + return None + + import openerp + # FIXME: make finding project root project-independent + project_root = os.path.join(os.path.dirname(openerp.__file__), '..') + return make_github_link( + app, + os.path.relpath(obj_source_path, project_root), + line) + app.config.linkcode_resolve = linkcode_resolve + +def make_github_link(app, path, line=None, mode="blob"): + config = app.config + + urlpath = "/{user}/{project}/{mode}/{branch}/{path}".format( + user=config.github_user, + project=config.github_project, + branch=config.version or 'master', + path=path, + mode=mode, + ) + return urlunsplit(( + 'https', + 'github.com', + urlpath, + '', + '' if line is None else 'L%d' % line + )) + +def add_doc_link(app, pagename, templatename, context, doctree): + """ Add github_link function linking to the current page on github """ + if not app.config.github_user and app.config.github_project: + return + + # FIXME: find other way to recover current document's source suffix + # in Sphinx 1.3 it's possible to have mutliple source suffixes and that + # may be useful in the future + source_suffix = app.config.source_suffix + source_suffix = source_suffix if isinstance(source_suffix, basestring) else source_suffix[0] + # FIXME: odoo/odoo has a doc/ prefix which is incorrect for this + # project, how to unify? Add new setting? + context['github_link'] = lambda mode='edit': make_github_link( + app, '%s%s' % (pagename, source_suffix), mode=mode) diff --git a/conf.py b/conf.py index 387322d1f..817985e18 100644 --- a/conf.py +++ b/conf.py @@ -33,6 +33,7 @@ extensions = [ 'odoo', 'html_domain', 'demo_link', + 'github_link', ] # Add any paths that contain templates here, relative to this directory. @@ -55,8 +56,6 @@ copyright = u'2015, Odoo S.A.' # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. -version = '0.1' # The full version, including alpha/beta/rc tags. release = '0.1' @@ -265,6 +264,9 @@ texinfo_documents = [ # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False +github_user = 'odoo' +github_project = 'documentation-user' + def setup(app): app.add_stylesheet('accounting.css') app.add_javascript('prefixfree.min.js')