diff --git a/.readthedocs.yml b/.readthedocs.yml index 0d8d849e..4df19be7 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,7 +1,7 @@ version: 2 python: - version: 3 + version: "3.8" install: - method: pip path: . diff --git a/docs/conf.py b/docs/conf.py index 2228cd8a..07ececd3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,10 +55,16 @@ intersphinx_mapping = { 'readthedocs': ('https://docs.readthedocs.io/en/stable/', None), 'sphinx': ('https://www.sphinx-doc.org/en/master/', None), + 'sympy': ('https://docs.sympy.org/latest/', None), + 'numpy': ('https://numpy.org/doc/stable/', None), + 'python': ('https://docs.python.org/3/', None), } hoverxref_intersphinx = [ 'readthedocs', 'sphinx', + 'sympy', + 'numpy', + 'python', ] hoverxref_intersphinx_types = { 'readthedocs': 'modal', @@ -81,6 +87,10 @@ # Building on a local Read the Docs instance hoverxref_api_host = 'http://community.dev.readthedocs.io' +if os.environ.get('NGROK_READTHEDOCS') == 'True': + # Building on a local Read the Docs instance using NGROK for HTTPS + hoverxref_api_host = 'https://readthedocs.ngrok.io' + hoverxref_tooltip_maxwidth = 650 hoverxref_auto_ref = True hoverxref_roles = [ @@ -93,6 +103,7 @@ 'confval': 'tooltip', 'mod': 'modal', 'class': 'modal', + 'obj': 'tooltip', } hoverxref_domains = [ 'py', diff --git a/docs/configuration.rst b/docs/configuration.rst index 7aefa9a1..c3092e03 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -101,8 +101,9 @@ These settings are global and have effect on both, tooltips and modal dialogues. .. warning:: - The Sphinx's target project **must be hosted on Read the Docs** to work. - This is a current limitation that we hope to remove in the future. + The Sphinx's target project **must be hosted on Read the Docs** to work or, + be one of the allowed external projects: + currently CPython, SymPy, NumPy are supported. .. confval:: hoverxref_intersphinx_types @@ -152,33 +153,16 @@ These settings are global and have effect on both, tooltips and modal dialogues. .. _Mathjax: http://www.sphinx-doc.org/es/master/usage/extensions/math.html#module-sphinx.ext.mathjax -.. warning:: - - You shouldn't modify the following three settings (api_host, project, version) unless you know what you are doing. - Their defaults should be fine to build the documentation and make it work in Read the Docs. - - .. confval:: hoverxref_api_host Description: Host URL for the API to retrieve the content of the floating window - Default: ``https://readthedocs.org`` - - Type: string - -.. confval:: hoverxref_project - - Description: Read the Docs project slug - - Default: It defaults to ``READTHEDOCS_PROJECT`` environment variable - - Type: string - -.. confval:: hoverxref_version + .. warning:: - Description: Read the Docs version slug + You shouldn't modify this setting unless you know what you are doing. + Its default should be fine to build the documentation and make it work in Read the Docs. - Default: It defaults to ``READTHEDOCS_VERSION`` environment variable + Default: ``https://readthedocs.org`` Type: string diff --git a/docs/development.rst b/docs/development.rst index a81d82fa..d7710209 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -21,13 +21,11 @@ To setup this approach, you need to put these settings in the ``conf.py`` of you .. code-block:: python - hoverxref_project = 'sphinx-hoverxref' - hoverxref_version = 'latest' hoverxref_api_host = 'https://readthedocs.org' After building the documentation all the requests will be done to URLs like:: - https://readthedocs.org/api/v2/embed/?project=sphinx-hoverxref&version=latest&doc=...§ion=... + https://readthedocs.org/api/v3/embed/?doctool=sphinx&doctoolversion=...&url=... .. note:: @@ -84,7 +82,7 @@ To make the extension to work, you will need to define this setting in your ``co .. code-block:: python - hoverxref_api_host = 'http://dev.readthedocs.io:8000' + hoverxref_api_host = 'http://community.dev.readthedocs.io' .. tip:: diff --git a/docs/index.rst b/docs/index.rst index 0688a87b..a1e39eb2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -99,8 +99,8 @@ Badges: .. _Read the Docs: https://readthedocs.org -.. |Build| image:: https://travis-ci.org/readthedocs/sphinx-hoverxref.svg?branch=master - :target: https://travis-ci.org/readthedocs/sphinx-hoverxref +.. |Build| image:: https://circleci.com/gh/readthedocs/sphinx-hoverxref.svg?style=svg + :target: https://circleci.com/gh/readthedocs/sphinx-hoverxref :alt: Build status .. |PyPI version| image:: https://img.shields.io/pypi/v/sphinx-hoverxref.svg :target: https://pypi.org/project/sphinx-hoverxref diff --git a/docs/installation.rst b/docs/installation.rst index 1dca5ebd..9a1f29df 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -37,8 +37,8 @@ you can use ``:hoverxref:`` role to show a tooltip [#]_ when hovering with the m .. warning:: This extension **requires a backend server** to retrieve the tooltip content. - Currently only `Read the Docs`_ is supported, - so it will only work if your documentation is hosted on Read the Docs. + Currently, only `Read the Docs`_ is supported as backend server. + Take into account that your documentation has to be hosted on Read the Docs for this extension to work. If you prefer to apply this behavior to *all* your ``:ref:`` in your documentation, you can use the config :confval:`hoverxref_auto_ref`. diff --git a/docs/requirements.txt b/docs/requirements.txt index 191c315d..e5845dfa 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,12 +1,6 @@ -# Sphinx 3.5.x includes a feature to only include the JS and CSS on the pages -# that they are used. This conflicts when we render content that uses MathJax, -# since the page that shows the tooltip does not has MathJax loaded, but the -# content rendered inside the tooltip requires it to work. -# https://github.com/sphinx-doc/sphinx/pull/8631 -sphinx==3.4.3 # pyup: <3.5 - +sphinx==4.2.0 sphinx-autoapi==1.8.4 -sphinx-rtd-theme==0.5.2 +sphinx-rtd-theme==1.0.0 sphinx-tabs==3.2.0 sphinx-prompt==1.4.0 sphinx-version-warning==1.1.2 diff --git a/docs/usage.rst b/docs/usage.rst index a2df45a1..1e33d782 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -7,9 +7,7 @@ and will embed the content of the document/section the link is pointing to, into ``:hoverxref:`` role uses Sphinx's internals reference resolution to find out where the link points to. So, the way of referencing the section works in the same way as the ``:ref:`` standard role. -See `Sphinx's ref role documentation`_ for more information. - -.. _Sphinx's ref role documentation: https://www.sphinx-doc.org/en/stable/usage/restructuredtext/roles.html#cross-referencing-arbitrary-locations +See Sphinx's :rst:role:`ref` for more information. Simplest usage example, @@ -42,14 +40,23 @@ Show a tooltip for :doc:`Read the Docs automation rules `. +* Show a tooltip for SymPy documentation: :py:class:`sympy.functions.combinatorial.numbers.tribonacci `. +* Show a tooltip for NumPy documentation: :py:class:`numpy.single `. Tooltip on custom object ------------------------ -Sphinx has the ability to define custom objects (via `Sphinx.add_object_type`_). +Sphinx has the ability to define custom objects (via :py:meth:`Sphinx.add_object_type `). ``hoverxref`` can also show a tooltip on these objects if desired. You need to tell ``hoverxref`` which are the roles where the tooltip has to appear on. To do this, use :confval:`hoverxref_roles ` config. @@ -119,9 +126,9 @@ These actions are usually calling a Javascript function. .. warning:: - Note that Sphinx>3.5 adds `a feature to only include JS/CSS in pages where they are used`_ instead of in all the pages. + Note that Sphinx>=3.5 adds `a feature to only include JS/CSS in pages where they are used`_ instead of in all the pages. This `may affect the rendering of tooltips`_ that includes content requiring extra rendering steps. - **Make sure you are using Sphinx 3.4.x or >=4.1.x** if you require rendering this type of content in your tooltips. + **Make sure you are using Sphinx <=3.4.x or >=4.1.x** if you require rendering this type of content in your tooltips. .. _a feature to only include JS/CSS in pages where they are used: https://github.com/sphinx-doc/sphinx/pull/8631 .. _may affect the rendering of tooltips: https://github.com/sphinx-doc/sphinx/issues/9115 @@ -151,8 +158,6 @@ To render a tooltip where its contents has a ``mathjax`` you need to enable :con Show a :hoverxref:`tooltip with Mathjax ` formulas. -.. _Sphinx.add_object_type: https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_object_type - .. _sphinx-tabs: https://github.com/djungelorm/sphinx-tabs .. _mathjax: http://www.sphinx-doc.org/es/master/usage/extensions/math.html#module-sphinx.ext.mathjax diff --git a/hoverxref/_static/js/hoverxref.js_t b/hoverxref/_static/js/hoverxref.js_t index 3af25a6a..f9d6d323 100644 --- a/hoverxref/_static/js/hoverxref.js_t +++ b/hoverxref/_static/js/hoverxref.js_t @@ -79,22 +79,14 @@ function reLoadSphinxTabs() { }; }; -function getEmbedURL(project, version, doc, docpath, section, url) { - if (url) { - var params = { - 'url': url, - } - } else { - var params = { - 'project': project, - 'version': version, - 'doc': doc, - 'path': docpath, - 'section': section, - } +function getEmbedURL(url) { + var params = { + 'doctool': 'sphinx', + 'doctoolversion': '{{ hoverxref_sphinx_version }}', + 'url': url, } console.debug('Data: ' + JSON.stringify(params)); - var url = '{{ hoverxref_api_host }}' + '/api/v2/embed/?' + $.param(params); + var url = '{{ hoverxref_api_host }}' + '/api/v3/embed/?' + $.param(params); console.debug('URL: ' + url); return url } @@ -109,20 +101,15 @@ $(document).ready(function() { animationDuration: {{ hoverxref_tooltip_animation_duration }}, side: '{{ hoverxref_tooltip_side }}', content: '{{ hoverxref_tooltip_content }}', + contentAsHTML: true, functionBefore: function(instance, helper) { var $origin = $(helper.origin); - var project = $origin.data('project'); - var version = $origin.data('version'); - var doc = $origin.data('doc'); - var docpath = $origin.data('docpath'); - var section = $origin.data('section'); - var url = $origin.data('url'); - + var href = $origin.prop('href'); // we set a variable so the data is only loaded once via Ajax, not every time the tooltip opens if ($origin.data('loaded') !== true) { - var url = getEmbedURL(project, version, doc, docpath, section, url); + var url = getEmbedURL(href); $.get(url, function(data) { // call the 'content' method to update the content of our tooltip with the returned data. // note: this content update will trigger an update animation (see the updateAnimation option) @@ -186,23 +173,21 @@ $(document).ready(function() { {% endif %} function showModal(element) { - var project = element.data('project'); - var version = element.data('version'); - var doc = element.data('doc'); - var docpath = element.data('docpath'); - var section = element.data('section'); - var url = element.data('url'); - - var url = getEmbedURL(project, version, doc, docpath, section, url); + var href = element.prop('href'); + var url = getEmbedURL(href); $.get(url, function(data) { var content = $('
'); - content.html(data['content'][0]); + content.html(data['content']); var h1 = $('h1:first', content); var title = h1.text() if (title) { var link = $('a', h1).attr('href') || '#'; - var a = $('').attr('href', link).text('{{ hoverxref_modal_prefix_title }}' + title.replace('¶', '')); + + // Remove permalink icon from the title + var title = title.replace('¶', '').replace('', ''); + + var a = $('').attr('href', link).text('{{ hoverxref_modal_prefix_title }}' + title); } else { var a = '{{ hoverxref_modal_prefix_title }}{{ hoverxref_modal_default_title }}'; diff --git a/hoverxref/domains.py b/hoverxref/domains.py index 6baf721a..44a85dd5 100644 --- a/hoverxref/domains.py +++ b/hoverxref/domains.py @@ -1,5 +1,4 @@ from sphinx.util import logging -from .utils import get_ref_xref_data, get_ref_obj_data, get_ref_numref_data logger = logging.getLogger(__name__) @@ -12,7 +11,7 @@ class HoverXRefBaseDomain: 'hoverxrefmodal', ) - def _inject_hoverxref_data(self, env, refnode, typ, docname, docpath, labelid): + def _inject_hoverxref_data(self, env, refnode, typ): classes = ['hoverxref'] type_class = None if typ == 'hoverxreftooltip': @@ -35,21 +34,12 @@ def _inject_hoverxref_data(self, env, refnode, typ, docname, docpath, labelid): classes.append(type_class) refnode.replace_attr('classes', classes) - - project = env.config.hoverxref_project - version = env.config.hoverxref_version - refnode._hoverxref = { - 'data-project': project, - 'data-version': version, - 'data-doc': docname, - 'data-docpath': docpath, - 'data-section': labelid, - } - - def _get_docpath(self, builder, docname): - docpath = builder.get_outfilename(docname) - docpath = docpath.replace(builder.outdir, '') - return docpath + # TODO: log something else here, so we can unique identify this node + logger.debug( + ':%s: _hoverxref injected. classes=%s', + typ, + classes, + ) def _is_ignored_ref(self, env, target): # HACK: skip all references if the builder is non-html. We shouldn't @@ -78,27 +68,10 @@ def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): if refnode is None: return refnode - if any([ - not env.config.hoverxref_is_configured, - self._is_ignored_ref(env, target), - ]): + if self._is_ignored_ref(env, target): return refnode - modname = node.get('py:module') - clsname = node.get('py:class') - searchmode = node.hasattr('refspecific') and 1 or 0 - matches = self.find_obj(env, modname, clsname, target, - typ, searchmode) - name, obj = matches[0] - - docname, labelid = obj[0], name - docpath = self._get_docpath(builder, docname) - self._inject_hoverxref_data(env, refnode, typ, docname, docpath, labelid) - logger.debug( - ':ref: _hoverxref injected: fromdocname=%s %s', - fromdocname, - refnode._hoverxref, - ) + self._inject_hoverxref_data(env, refnode, typ) return refnode @@ -110,8 +83,8 @@ class HoverXRefStandardDomainMixin(HoverXRefBaseDomain): (``sphinx.addnodes.pending_xref``). These nodes are translated to regular ``docsutils.nodes.reference`` for this domain class. - Before loosing the data used to resolve the reference, our customized domain - saves it inside the node itself to be used later by the ``HTMLTranslator``. + This class add the required ``hoverxref`` and ``modal``/``tooltip`` to tell + the frontend to show a modal/tooltip on this element. """ def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): @@ -128,21 +101,13 @@ def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contno return refnode if any([ - not env.config.hoverxref_is_configured, self._is_ignored_ref(env, target), not (env.config.hoverxref_auto_ref or typ in self.hoverxref_types) ]): return refnode - docname, labelid, _ = get_ref_xref_data(self, node, target) - docpath = self._get_docpath(builder, docname) - self._inject_hoverxref_data(env, refnode, typ, docname, docpath, labelid) - logger.debug( - ':ref: _hoverxref injected: fromdocname=%s %s', - fromdocname, - refnode._hoverxref, - ) + self._inject_hoverxref_data(env, refnode, typ) return refnode def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode): @@ -151,21 +116,12 @@ def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contno return refnode if any([ - not env.config.hoverxref_is_configured, self._is_ignored_ref(env, target), typ not in env.config.hoverxref_roles, ]): return refnode - docname, labelid = get_ref_obj_data(self, node, typ, target) - docpath = self._get_docpath(builder, docname) - self._inject_hoverxref_data(env, refnode, typ, docname, docpath, labelid) - logger.debug( - ':%s: _hoverxref injected: fromdocname=%s %s', - typ, - fromdocname, - refnode._hoverxref, - ) + self._inject_hoverxref_data(env, refnode, typ) return refnode # TODO: combine this method with ``_resolve_obj_xref`` @@ -175,19 +131,10 @@ def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, con return refnode if any([ - not env.config.hoverxref_is_configured, self._is_ignored_ref(env, target), typ not in env.config.hoverxref_roles, ]): return refnode - docname, labelid = get_ref_numref_data(self, node, typ, target) - docpath = self._get_docpath(builder, docname) - self._inject_hoverxref_data(env, refnode, typ, docname, docpath, labelid) - logger.debug( - ':%s: _hoverxref injected: fromdocname=%s %s', - typ, - fromdocname, - refnode._hoverxref, - ) + self._inject_hoverxref_data(env, refnode, typ) return refnode diff --git a/hoverxref/extension.py b/hoverxref/extension.py index c9f2d931..20a09bdd 100644 --- a/hoverxref/extension.py +++ b/hoverxref/extension.py @@ -15,7 +15,6 @@ HoverXRefPythonDomainMixin, HoverXRefStandardDomainMixin, ) -from .translators import HoverXRefHTMLTranslatorMixin logger = logging.getLogger(__name__) @@ -222,9 +221,20 @@ def missing_reference(app, env, node, contnode): # refexplicit: False inventories = InventoryAdapter(env) + # TODO: credits to https://github.com/readthedocs/sphinx-hoverxref/pull/144 + # This chunk of code needs tests :) + reftype_fallbacks = { + 'meth': 'method', + 'mod': 'module', + } + for inventory_name in app.config.hoverxref_intersphinx: inventory = inventories.named_inventory.get(inventory_name, {}) - if inventory.get(f'{domain}:{reftype}', {}).get(target) is not None: + inventory_member = ( + inventory.get(f'{domain}:{reftype}') or + inventory.get(f'{domain}:{reftype_fallbacks.get(reftype)}') + ) + if inventory_member and inventory_member.get(target) is not None: # The object **does** exist on the inventories defined by the # user: enable hoverxref on this node skip_node = False @@ -242,70 +252,10 @@ def missing_reference(app, env, node, contnode): classes = newnode.get('classes') classes.extend(['hoverxref', hoverxref_type]) newnode.replace_attr('classes', classes) - newnode._hoverxref = { - 'data-url': newnode.get('refuri'), - } return newnode -def setup_translators(app): - """ - Override translators respecting the one defined (if any). - - We create a new class by inheriting the Sphinx Translator already defined - and our own ``HoverXRefHTMLTranslatorMixin`` that includes the logic to - ``_hoverxref`` attributes. - """ - - if app.builder.format != 'html': - # do not modify non-html builders - return - - for name, klass in app.registry.translators.items(): - translator = types.new_class( - 'HoverXRefHTMLTranslator', - ( - HoverXRefHTMLTranslatorMixin, - klass, - ), - {}, - ) - app.set_translator(name, translator, override=True) - - translator = types.new_class( - 'HoverXRefHTMLTranslator', - ( - HoverXRefHTMLTranslatorMixin, - app.builder.default_translator_class, - ), - {}, - ) - app.set_translator(app.builder.name, translator, override=True) - - - -def is_hoverxref_configured(app, config): - """ - Save a config if hoverxref is properly configured. - - It checks for ``hoverxref_project`` and ``hoverxref_version`` being defined - and set ``hoverxref_is_configured=True`` if configured. - """ - config.hoverxref_is_configured = True - - project = config.hoverxref_project - version = config.hoverxref_version - if not project or not version: - config.hoverxref_is_configured = False - # ``hoverxref`` extension is not fully configured - logger.info( - 'hoverxref extension is not fully configured. ' - 'Tooltips may not work as expected. ' - 'Check out the documentation for hoverxref_project and hoverxref_version configuration options.', - ) - - def setup_theme(app, exception): """ Auto-configure default settings for known themes. @@ -361,10 +311,6 @@ def setup(app): # ``override`` was introduced in 1.8 app.require_sphinx('1.8') - default_project = os.environ.get('READTHEDOCS_PROJECT') - default_version = os.environ.get('READTHEDOCS_VERSION') - app.add_config_value('hoverxref_project', default_project, 'html') - app.add_config_value('hoverxref_version', default_version, 'html') app.add_config_value('hoverxref_auto_ref', False, 'env') app.add_config_value('hoverxref_mathjax', False, 'env') app.add_config_value('hoverxref_sphinxtabs', False, 'env') @@ -376,6 +322,7 @@ def setup(app): app.add_config_value('hoverxref_intersphinx', [], 'env') app.add_config_value('hoverxref_intersphinx_types', {}, 'env') app.add_config_value('hoverxref_api_host', 'https://readthedocs.org', 'env') + app.add_config_value('hoverxref_sphinx_version', sphinx.__version__, 'env') # Tooltipster settings # Deprecated in favor of ``hoverxref_api_host`` @@ -402,14 +349,11 @@ def setup(app): app.add_config_value('hoverxref_modal_default_title', 'Note', 'env') app.add_config_value('hoverxref_modal_prefix_title', '📝 ', 'env') - app.connect('builder-inited', setup_translators) - app.connect('config-inited', deprecated_configs_warning) app.connect('config-inited', setup_domains) app.connect('config-inited', setup_sphinx_tabs) app.connect('config-inited', setup_intersphinx) - app.connect('config-inited', is_hoverxref_configured) app.connect('config-inited', setup_theme) app.connect('config-inited', setup_assets_policy) app.connect('build-finished', copy_asset_files) diff --git a/hoverxref/translators.py b/hoverxref/translators.py deleted file mode 100644 index f617339b..00000000 --- a/hoverxref/translators.py +++ /dev/null @@ -1,20 +0,0 @@ -from sphinx.util import logging - -logger = logging.getLogger(__name__) - - -class HoverXRefHTMLTranslatorMixin: - - """ - Mixin ``HTMLTranslator`` to render extra data saved in reference nodes. - - It adds all the values saved under ``_hoverxref`` as attributes of the HTML - reference tag. - """ - - def starttag(self, node, tagname, suffix='\n', empty=False, **attributes): - if tagname == 'a' and hasattr(node, '_hoverxref'): - attributes.update(node._hoverxref) - logger.info('_hoverxref attributes: %s', attributes) - - return super().starttag(node, tagname, suffix, empty, **attributes) diff --git a/hoverxref/utils.py b/hoverxref/utils.py deleted file mode 100644 index 06d83f40..00000000 --- a/hoverxref/utils.py +++ /dev/null @@ -1,76 +0,0 @@ -import sphinx - - -def get_ref_xref_data(domain, node, target): - """ - Use Sphinx's internals to resolve the reference and returns this data. - - :returns: tuple (``docname``, ``labelid``, ``sectname``) - """ - if sphinx.version_info < (2, 1): - # Borrowed from https://github.com/sphinx-doc/sphinx/blob/6ef08a42df4534dbb2664d49dc10a16f6df2acb2/sphinx/domains/std.py#L702-L711 - if node['refexplicit']: - # reference to anonymous label; the reference uses - # the supplied link caption - docname, labelid = domain.data['anonlabels'].get(target, ('', '')) - sectname = node.astext() - else: - # reference to named label; the final node will - # contain the section name after the label - docname, labelid, sectname = domain.data['labels'].get(target, ('', '', '')) - else: - # Borrowed from https://github.com/sphinx-doc/sphinx/blob/47cd262b3e50ed650a82f272ba128a1f872cda4d/sphinx/domains/std.py#L681-L689 - if node['refexplicit']: - # reference to anonymous label; the reference uses - # the supplied link caption - docname, labelid = domain.anonlabels.get(target, ('', '')) - sectname = node.astext() - else: - # reference to named label; the final node will - # contain the section name after the label - docname, labelid, sectname = domain.labels.get(target, ('', '', '')) - return docname, labelid, sectname - - -def get_ref_obj_data(domain, node, typ, target): - """ - Use Sphinx's internals to resolve an object reference and returns this data. - - :returns: tuple (``docname``, ``labelid``) - """ - objtypes = domain.objtypes_for_role(typ) or [] - if sphinx.version_info < (2, 1): - # Borrowed from https://github.com/sphinx-doc/sphinx/blob/6ef08a42df4534dbb2664d49dc10a16f6df2acb2/sphinx/domains/std.py#L851-L855 - for objtype in objtypes: - if (objtype, target) in domain.data['objects']: - docname, labelid = domain.data['objects'][objtype, target] - break - else: - # Borrowed from https://github.com/sphinx-doc/sphinx/blob/47cd262b3e50ed650a82f272ba128a1f872cda4d/sphinx/domains/std.py#L812-L816 - for objtype in objtypes: - if (objtype, target) in domain.objects: - docname, labelid = domain.objects[objtype, target] - break - return docname, labelid - - -def get_ref_numref_data(domain, node, typ, target): - """ - Use Sphinx's internals to resolve :numref: and returns this data. - - :returns: tuple (``docname``, ``labelid``) - """ - # Borrowed from https://github.com/sphinx-doc/sphinx/blob/47cd262b3e50ed650a82f272ba128a1f872cda4d/sphinx/domains/std.py#L699-L702 - if sphinx.version_info < (2, 1): - if node['refexplicit']: - docname, labelid = domain.data['anonlabels'].get(target, ('', '')) - else: - # reference to named label; the final node will - # contain the section name after the label - docname, labelid, sectname = domain.data['labels'].get(target, ('', '', '')) - else: - if target in domain.labels: - docname, labelid, figname = domain.labels.get(target, ('', '', '')) - else: - docname, labelid = domain.anonlabels.get(target, ('', '')) - return docname, labelid diff --git a/tests/examples/custom-object/conf.py b/tests/examples/custom-object/conf.py index 11241721..a0ffb291 100644 --- a/tests/examples/custom-object/conf.py +++ b/tests/examples/custom-object/conf.py @@ -6,8 +6,6 @@ 'hoverxref.extension', ] -hoverxref_project = 'myproject' -hoverxref_version = 'myversion' hoverxref_roles = [ 'confval', 'numref', diff --git a/tests/examples/intersphinx/conf.py b/tests/examples/intersphinx/conf.py index 0b4658ab..69225ebd 100644 --- a/tests/examples/intersphinx/conf.py +++ b/tests/examples/intersphinx/conf.py @@ -7,9 +7,6 @@ 'sphinx.ext.autodoc', ] -hoverxref_project = 'myproject' -hoverxref_version = 'myversion' - # https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), diff --git a/tests/examples/python-domain/api.rst b/tests/examples/python-domain/api.rst index bea8e0c3..3d6fbfde 100644 --- a/tests/examples/python-domain/api.rst +++ b/tests/examples/python-domain/api.rst @@ -9,4 +9,4 @@ API .. automodule:: hoverxref.extension -.. autofunction:: hoverxref.utils.get_ref_xref_data +.. autofunction:: hoverxref.extension.setup diff --git a/tests/examples/python-domain/conf.py b/tests/examples/python-domain/conf.py index 4dd50597..bafab780 100644 --- a/tests/examples/python-domain/conf.py +++ b/tests/examples/python-domain/conf.py @@ -6,6 +6,3 @@ 'sphinx.ext.autosectionlabel', 'hoverxref.extension', ] - -hoverxref_project = 'myproject' -hoverxref_version = 'myversion' diff --git a/tests/examples/python-domain/index.rst b/tests/examples/python-domain/index.rst index fd15f791..89dc610d 100644 --- a/tests/examples/python-domain/index.rst +++ b/tests/examples/python-domain/index.rst @@ -7,4 +7,4 @@ This is an example page with a Python Domain role usage. :py:mod:`hoverxref.extension` -:py:func:`hoverxref.utils.get_ref_xref_data` +:py:func:`hoverxref.extension.setup` diff --git a/tests/test_htmltag.py b/tests/test_htmltag.py index 32f13612..b127b557 100644 --- a/tests/test_htmltag.py +++ b/tests/test_htmltag.py @@ -18,7 +18,7 @@ def test_default_settings(app, status, warning): chunks = [ 'This a :ref: to Chapter I', - 'This a :hoverxref: to Chapter I, Section I', + 'This a :hoverxref: to Chapter I, Section I', ] for chunk in chunks: @@ -27,32 +27,6 @@ def test_default_settings(app, status, warning): @pytest.mark.sphinx( srcdir=srcdir, - confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', - }, -) -def test_project_version_settings(app, status, warning): - app.build() - path = app.outdir / 'index.html' - assert path.exists() is True - content = open(path).read() - - chunks = [ - 'This a :ref: to Chapter I', - 'This a :hoverxref: to Chapter I, Section I', - ] - - for chunk in chunks: - assert chunk in content - - -@pytest.mark.sphinx( - srcdir=srcdir, - confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', - }, ) def test_js_render(app, status, warning): app.build() @@ -66,24 +40,21 @@ def test_js_render(app, status, warning): "maxWidth: 450", "animation: 'fade'", "animationDuration: 0", + "contentAsHTML: true", "content: 'Loading...'", - "var url = 'https://readthedocs.org' + '/api/v2/embed/?' + $.param(params);", - textwrap.indent(textwrap.dedent(""" - var params = { - 'project': project, - 'version': version, - 'doc': doc, - 'path': docpath, - 'section': section, - }"""), ' ').strip(), - textwrap.indent(textwrap.dedent(""" - var params = { + "var url = 'https://readthedocs.org' + '/api/v3/embed/?' + $.param(params);", + textwrap.indent( + textwrap.dedent(""" + var params = {{ + 'doctool': 'sphinx', + 'doctoolversion': '{}', 'url': url, - }"""), ' ').strip(), + }}""".format(sphinx.__version__)), + ' ', + ).strip(), "var sphinxtabs = false", "var mathjax = false", - "var url = $origin.data('url');", - "var url = getEmbedURL(project, version, doc, docpath, section, url);", + "var url = getEmbedURL(href);", ] for chunk in chunks: @@ -92,10 +63,6 @@ def test_js_render(app, status, warning): @pytest.mark.sphinx( srcdir=prefixdocumentsrcdir, - confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', - }, ) def test_autosectionlabel_project_version_settings(app, status, warning): app.build() @@ -105,7 +72,7 @@ def test_autosectionlabel_project_version_settings(app, status, warning): chunks = [ 'This a :ref: to Chapter I.', - 'This a :hoverxref: to Chapter I', + 'This a :hoverxref: to Chapter I', ] for chunk in chunks: @@ -123,9 +90,9 @@ def test_custom_object(app, status, warning): content = open(path).read() chunks = [ - 'This is a :confval: to conf-title', - 'This is a :hoverxref: to Configuration document', - 'This is a :numref: to a Python code block (PyExample)' + 'This is a :confval: to conf-title', + 'This is a :hoverxref: to Configuration document', + 'This is a :numref: to a Python code block (PyExample)' ] for chunk in chunks: @@ -145,9 +112,9 @@ def test_python_domain(app, status, warning): content = open(path).read() chunks = [ - 'This is a :py:class: role to a Python object', - 'hoverxref.extension', - 'hoverxref.utils.get_ref_xref_data()', + 'This is a :py:class: role to a Python object', + 'hoverxref.extension', + 'hoverxref.extension.setup()', ] for chunk in chunks: @@ -157,8 +124,6 @@ def test_python_domain(app, status, warning): @pytest.mark.sphinx( srcdir=srcdir, confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', 'hoverxref_default_type': 'modal', }, ) @@ -170,7 +135,7 @@ def test_default_type(app, status, warning): chunks = [ 'This a :ref: to Chapter I', - 'This a :hoverxref: to Chapter I, Section I', + 'This a :hoverxref: to Chapter I, Section I', ] for chunk in chunks: @@ -200,7 +165,7 @@ def test_ignore_refs(app, status, warning): assert chunk in content ignored_chunks = [ - 'This a :hoverxref: to Chapter I, Section I', + 'This a :hoverxref: to Chapter I, Section I', ] for chunk in ignored_chunks: assert chunk not in content @@ -259,9 +224,9 @@ def test_intersphinx_python_mapping(app, status, warning): chunks_regex = [ # Python's links do have hoverxref enabled - r'This a :ref: to The Python Tutorial using intersphinx', - r'This a :ref: to datetime.datetime Python’s function using intersphinx', - r'float', + r'This a :ref: to The Python Tutorial using intersphinx', + r'This a :ref: to datetime.datetime Python’s function using intersphinx', + r'float', # Read the Docs' link does not have hoverxref enabled r'This a :ref: to Config File v2 Read the Docs’ page using intersphinx', @@ -304,18 +269,18 @@ def test_intersphinx_all_mappings(app, status, warning): chunks_regex = [ # Python's links do have hoverxref enabled - r'This a :ref: to The Python Tutorial using intersphinx', - r'This a :ref: to datetime.datetime Python’s function using intersphinx', - r'float', + r'This a :ref: to The Python Tutorial using intersphinx', + r'This a :ref: to datetime.datetime Python’s function using intersphinx', + r'float', # Read the Docs' link does have hoverxref enabled - r'This a :ref: to Config File v2 Read the Docs’ page using intersphinx', + r'This a :ref: to Config File v2 Read the Docs’ page using intersphinx', ] chunks = [ # Python domain's link does have hoverxref enabled - 'hoverxref.extension.setup()', + 'hoverxref.extension.setup()', ] for chunk in chunks: diff --git a/tests/test_internals.py b/tests/test_internals.py index d031a88e..509766d7 100644 --- a/tests/test_internals.py +++ b/tests/test_internals.py @@ -4,8 +4,6 @@ import shutil from unittest import mock -from hoverxref.translators import HoverXRefHTMLTranslatorMixin - from .utils import srcdir @@ -13,46 +11,6 @@ srcdir=srcdir, buildername='latex', confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', - }, -) -def test_dont_override_translator_non_html_builder(app, status, warning): - app.build() - path = app.outdir / 'test.tex' - assert path.exists() is True - content = open(path).read() - - assert app.builder.format == 'latex' - for name, klass in app.registry.translators.items(): - assert not issubclass(klass, HoverXRefHTMLTranslatorMixin) - - -@pytest.mark.sphinx( - srcdir=srcdir, - buildername='html', - confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', - }, -) -def test_override_translator_non_html_builder(app, status, warning): - app.build() - path = app.outdir / 'index.html' - assert path.exists() is True - content = open(path).read() - - assert app.builder.format == 'html' - for name, klass in app.registry.translators.items(): - assert issubclass(klass, HoverXRefHTMLTranslatorMixin) - - -@pytest.mark.sphinx( - srcdir=srcdir, - buildername='latex', - confoverrides={ - 'hoverxref_project': 'myproject', - 'hoverxref_version': 'myversion', 'hoverxref_auto_ref': True, }, ) @@ -70,9 +28,7 @@ def _get_docpath(self, builder, docname): LaTeXBuilder should never use our resolver. """ - with mock.patch('hoverxref.domains.HoverXRefBaseDomain._get_docpath') as _get_docpath: - app.build() - assert not _get_docpath.called + app.build() path = app.outdir / 'test.tex' assert path.exists() is True content = open(path).read()