1
+ import re
1
2
from docutils import nodes
3
+ from docutils .parsers .rst import roles
2
4
from sphinx import addnodes
3
5
from sphinx .environment .adapters import toctree
4
6
@@ -15,6 +17,7 @@ def setup(app):
15
17
app .add_js_file ('js/menu.js' )
16
18
app .add_js_file ('js/page_toc.js' )
17
19
app .add_js_file ('js/switchers.js' )
20
+ roles .register_local_role ('icon' , icon_role )
18
21
19
22
return {
20
23
'parallel_read_safe' : True ,
@@ -107,3 +110,56 @@ def _set_docname_as_class(_reference_node, _node_docname):
107
110
if resolved_toc : # `resolve` returns None if the depth of the TOC to resolve is too high
108
111
_update_toctree_nodes (resolved_toc )
109
112
return resolved_toc
113
+
114
+
115
+ def extract_icon_classes (filename ):
116
+ """
117
+ Return a list of icon classes from a CSS file.
118
+ """
119
+ icon_classes = []
120
+ try :
121
+ with open (filename , 'r' ) as f :
122
+ for line in f :
123
+ match = re .search (r'\.([a-zA-Z0-9_-]+):before' , line )
124
+ if match :
125
+ icon_class = match .group (1 )
126
+ icon_classes .append (icon_class )
127
+ except FileNotFoundError :
128
+ print (f"Error: File '{ filename } ' not found." )
129
+ except Exception as e :
130
+ print (f"Error: { e } " )
131
+ return icon_classes
132
+
133
+ def handle_error (inliner , rawtext , error_message , lineno ):
134
+ """
135
+ Handle an error by creating a system message node.
136
+ """
137
+ error_node = nodes .system_message (
138
+ lineno , backrefs = [], source = rawtext , type = 'error' , level = 1 )
139
+ error_node ['message' ] = inliner .reporter .error (error_message , line = lineno )
140
+ return [error_node ], []
141
+
142
+ def icon_role (role , rawtext , text , lineno , inliner , options = {}, content = []):
143
+ """
144
+ Custom role for adding icons to the documentation.
145
+ """
146
+ # Paths to icon sets used by the :icon: role
147
+ odoo_ui_icon_path = 'extensions/odoo_theme/static/scss/_odoo_ui_icon.scss'
148
+ font_awesome_icon_path = 'extensions/odoo_theme/static/scss/_font_awesome.scss'
149
+ # Check which icon set the icon belongs to
150
+ if 'oi-' in text :
151
+ icon_file = odoo_ui_icon_path
152
+ elif 'fa-' in text :
153
+ icon_file = font_awesome_icon_path
154
+ else :
155
+ return handle_error (
156
+ inliner , rawtext , f"'{ text } ' is not an 'oi-' or 'fa-' icon set" , lineno )
157
+ # Extract icon classes from the icon set
158
+ icon_classes = extract_icon_classes (icon_file )
159
+ # Check if the icon class is in the icon set and create the element
160
+ if text in icon_classes :
161
+ inline_node = nodes .inline (classes = [text ])
162
+ return [inline_node ], []
163
+ else :
164
+ return handle_error (
165
+ inliner , rawtext , f"Icon class '{ text } ' not found in { icon_file } " , lineno )
0 commit comments