|
1 | 1 | import os
|
2 | 2 | import inspect
|
3 | 3 | from docutils import nodes
|
4 |
| -from sphinx.domains.python import PythonDomain |
5 |
| -from sphinx.domains.std import StandardDomain |
6 | 4 | from sphinx.roles import XRefRole
|
7 |
| -from sphinx.util import logging |
8 | 5 | from sphinx.util.fileutil import copy_asset
|
9 |
| -from sphinx.writers.html import HTMLTranslator |
10 | 6 |
|
11 | 7 | from . import version
|
12 |
| -from .utils import get_ref_xref_data, get_ref_obj_data |
| 8 | +from .domains import HoverXRefPythonDomain, HoverXRefStandardDomain |
| 9 | +from .translators import HoverXRefHTMLTranslator |
13 | 10 |
|
14 | 11 | ASSETS_FILES = [
|
15 | 12 | 'js/hoverxref.js_t', # ``_t`` tells Sphinx this is a template
|
|
19 | 16 | 'css/tooltipster-sideTip-shadow.min.css',
|
20 | 17 | ]
|
21 | 18 |
|
22 |
| -logger = logging.getLogger(__name__) |
23 |
| - |
24 |
| - |
25 |
| -class HoverXRefBaseDomain: |
26 |
| - |
27 |
| - def _is_hoverxref_configured(self, env): |
28 |
| - project = env.config.hoverxref_project |
29 |
| - version = env.config.hoverxref_version |
30 |
| - return project and version |
31 |
| - |
32 |
| - def _inject_hoverxref_data(self, env, refnode, docname, labelid): |
33 |
| - refnode.replace_attr('classes', ['hoverxref']) |
34 |
| - |
35 |
| - project = env.config.hoverxref_project |
36 |
| - version = env.config.hoverxref_version |
37 |
| - refnode._hoverxref = { |
38 |
| - 'data-project': project, |
39 |
| - 'data-version': version, |
40 |
| - 'data-doc': docname, |
41 |
| - 'data-section': labelid, |
42 |
| - } |
43 |
| - |
44 |
| - |
45 |
| -class HoverXRefPythonDomain(HoverXRefBaseDomain, PythonDomain): |
46 |
| - |
47 |
| - def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode): |
48 |
| - refnode = super().resolve_xref(env, fromdocname, builder, type, target, node, contnode) |
49 |
| - if refnode is None: |
50 |
| - return |
51 |
| - |
52 |
| - modname = node.get('py:module') |
53 |
| - clsname = node.get('py:class') |
54 |
| - searchmode = node.hasattr('refspecific') and 1 or 0 |
55 |
| - matches = self.find_obj(env, modname, clsname, target, |
56 |
| - type, searchmode) |
57 |
| - name, obj = matches[0] |
58 |
| - |
59 |
| - if self._is_hoverxref_configured(env): |
60 |
| - docname, labelid = obj[0], name |
61 |
| - self._inject_hoverxref_data(env, refnode, docname, labelid) |
62 |
| - logger.info( |
63 |
| - ':ref: _hoverxref injected: fromdocname=%s %s', |
64 |
| - fromdocname, |
65 |
| - refnode._hoverxref, |
66 |
| - ) |
67 |
| - return refnode |
68 |
| - |
69 |
| - |
70 |
| -class HoverXRefStandardDomain(HoverXRefBaseDomain, StandardDomain): |
71 |
| - """ |
72 |
| - Override ``StandardDomain`` to save the values after the xref resolution. |
73 |
| -
|
74 |
| - ``:ref:`` are treating as a different node in Sphinx |
75 |
| - (``sphinx.addnodes.pending_xref``). These nodes are translated to regular |
76 |
| - ``docsutils.nodes.reference`` for this domain class. |
77 |
| -
|
78 |
| - Before loosing the data used to resolve the reference, our customized domain |
79 |
| - saves it inside the node itself to be used later by the ``HTMLTranslator``. |
80 |
| - """ |
81 |
| - |
82 |
| - def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): |
83 |
| - if typ == 'hoverxref': |
84 |
| - resolver = self._resolve_ref_xref |
85 |
| - return resolver(env, fromdocname, builder, typ, target, node, contnode) |
86 |
| - |
87 |
| - return super().resolve_xref(env, fromdocname, builder, typ, target, node, contnode) |
88 |
| - |
89 |
| - # NOTE: We could override more ``_resolve_xref`` method apply hover in more places |
90 |
| - def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode): |
91 |
| - refnode = super()._resolve_ref_xref(env, fromdocname, builder, typ, target, node, contnode) |
92 |
| - if refnode is None: |
93 |
| - return |
94 |
| - |
95 |
| - if not self._is_hoverxref_configured(env) and typ == 'hoverxref': |
96 |
| - # Using ``:hoverxref:`` role without having hoverxref configured |
97 |
| - # properly. Log a warning. |
98 |
| - logger.warning('hoverxref role is not fully configured.') |
99 |
| - |
100 |
| - if self._is_hoverxref_configured(env) and (env.config.hoverxref_auto_ref or typ == 'hoverxref'): |
101 |
| - docname, labelid, _ = get_ref_xref_data(self, node, target) |
102 |
| - self._inject_hoverxref_data(env, refnode, docname, labelid) |
103 |
| - logger.info( |
104 |
| - ':ref: _hoverxref injected: fromdocname=%s %s', |
105 |
| - fromdocname, |
106 |
| - refnode._hoverxref, |
107 |
| - ) |
108 |
| - return refnode |
109 |
| - |
110 |
| - def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode): |
111 |
| - refnode = super()._resolve_obj_xref(env, fromdocname, builder, typ, target, node, contnode) |
112 |
| - if refnode is None: |
113 |
| - return |
114 |
| - |
115 |
| - if typ in env.config.hoverxref_roles: |
116 |
| - docname, labelid = get_ref_obj_data(self, node, typ, target) |
117 |
| - if self._is_hoverxref_configured(env): |
118 |
| - self._inject_hoverxref_data(env, refnode, docname, labelid) |
119 |
| - logger.info( |
120 |
| - ':%s: _hoverxref injected: fromdocname=%s %s', |
121 |
| - typ, |
122 |
| - fromdocname, |
123 |
| - refnode._hoverxref, |
124 |
| - ) |
125 |
| - return refnode |
126 |
| - |
127 |
| - |
128 |
| -class HoverXRefHTMLTranslator(HTMLTranslator): |
129 |
| - |
130 |
| - """ |
131 |
| - Override ``HTMLTranslator`` to render extra data saved in reference nodes. |
132 |
| -
|
133 |
| - It adds all the values saved under ``_hoverxref`` as attributes of the HTML |
134 |
| - reference tag. |
135 |
| - """ |
136 |
| - |
137 |
| - def starttag(self, node, tagname, suffix='\n', empty=False, **attributes): |
138 |
| - if tagname == 'a' and hasattr(node, '_hoverxref'): |
139 |
| - attributes.update(node._hoverxref) |
140 |
| - logger.info('_hoverxref attributes: %s', attributes) |
141 |
| - |
142 |
| - return super().starttag(node, tagname, suffix, empty, **attributes) |
143 |
| - |
144 | 19 |
|
145 | 20 | def copy_asset_files(app, exception):
|
146 | 21 | """
|
|
0 commit comments