Skip to content

Commit eb351c1

Browse files
committed
Refactor documenter
1 parent 2412905 commit eb351c1

File tree

1 file changed

+128
-60
lines changed

1 file changed

+128
-60
lines changed

ams/core/documenter.py

Lines changed: 128 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,12 @@
66

77
import logging
88
from collections import OrderedDict
9-
from andes.core.documenter import Documenter as adDocumenter
109
from andes.utils.tab import make_doc_table, math_wrap
1110

1211
logger = logging.getLogger(__name__)
1312

1413

15-
def disable_method(func):
16-
def wrapper(*args, **kwargs):
17-
msg = f"Method `{func.__name__}` is included in ANDES Documenter but not supported in AMS Documenter."
18-
logger.warning(msg)
19-
return None
20-
return wrapper
21-
22-
23-
def disable_methods(methods):
24-
for method in methods:
25-
setattr(Documenter, method, disable_method(getattr(Documenter, method)))
26-
27-
28-
class Documenter(adDocumenter):
14+
class Documenter:
2915
"""
3016
Helper class for documenting models.
3117
@@ -37,16 +23,6 @@ class Documenter(adDocumenter):
3723

3824
def __init__(self, parent):
3925
self.parent = parent
40-
self.system = parent.system
41-
self.class_name = parent.class_name
42-
self.config = parent.config
43-
self.params = parent.params
44-
self.algebs = parent.algebs
45-
self.services = parent.services
46-
47-
func_to_disable = ['_init_doc', '_eq_doc',
48-
'_discrete_doc', '_block_doc']
49-
disable_methods(func_to_disable)
5026

5127
def get(self, max_width=78, export='plain'):
5228
"""
@@ -68,14 +44,15 @@ def get(self, max_width=78, export='plain'):
6844
if export == 'rest':
6945
max_width = 0
7046
model_header = '-' * 80 + '\n'
71-
out += f'.. _{self.class_name}:\n\n'
47+
out += f'.. _{self.parent.class_name}:\n\n'
7248
else:
7349
model_header = ''
7450

7551
if export == 'rest':
76-
out += model_header + f'{self.class_name}\n' + model_header
52+
out += model_header + f'{self.parent.class_name}\n' + model_header
7753
else:
78-
out += model_header + f'Model <{self.class_name}> in Group <{self.parent.group}>\n' + model_header
54+
out += model_header + \
55+
f'Model <{self.parent.class_name}> in Group <{self.parent.group}>\n' + model_header
7956

8057
if self.parent.__doc__ is not None:
8158
out += inspect.cleandoc(self.parent.__doc__)
@@ -86,20 +63,35 @@ def get(self, max_width=78, export='plain'):
8663
out += self._var_doc(max_width=max_width, export=export)
8764
out += self._service_doc(max_width=max_width, export=export)
8865
# TODO: fix and add the config doc later on
89-
# out += self.config.doc(max_width=max_width, export=export)
66+
# out += self.parent.config.doc(max_width=max_width, export=export)
9067

9168
return out
9269

9370
def _var_doc(self, max_width=78, export='plain'):
71+
"""
72+
Export formatted model variable documentation as a string.
73+
74+
Parameters
75+
----------
76+
max_width : int, optional = 80
77+
Maximum table width. If export format is ``rest`` it will be unlimited.
78+
export : str, optional = 'plain'
79+
Export format, 'plain' for plain text, 'rest' for restructuredText.
80+
81+
Returns
82+
-------
83+
str
84+
Tabulated output in a string
85+
"""
9486
# variable documentation
95-
if len(self.algebs) == 0:
87+
if len(self.parent.algebs) == 0:
9688
return ''
9789

9890
names, symbols, units = list(), list(), list()
9991
info = list()
10092
units_rest, ty = list(), list()
10193

102-
for p in self.algebs.values():
94+
for p in self.parent.algebs.values():
10395
names.append(p.name)
10496
ty.append(p.class_name)
10597
info.append(p.info if p.info else '')
@@ -110,7 +102,7 @@ def _var_doc(self, max_width=78, export='plain'):
110102

111103
# replace with latex math expressions if export is ``rest``
112104
if export == 'rest':
113-
symbols = [item.tex_name for item in self.algebs.values()]
105+
symbols = [item.tex_name for item in self.parent.algebs.values()]
114106
symbols = math_wrap(symbols, export=export)
115107
title = 'Variables\n---------'
116108

@@ -132,14 +124,29 @@ def _var_doc(self, max_width=78, export='plain'):
132124
rest_dict=rest_dict)
133125

134126
def _service_doc(self, max_width=78, export='plain'):
135-
if len(self.services) == 0:
127+
"""
128+
Export formatted model service documentation as a string.
129+
130+
Parameters
131+
----------
132+
max_width : int, optional = 80
133+
Maximum table width. If export format is ``rest`` it will be unlimited.
134+
export : str, optional = 'plain'
135+
Export format, 'plain' for plain text, 'rest' for restructuredText.
136+
137+
Returns
138+
-------
139+
str
140+
Tabulated output in a string
141+
"""
142+
if len(self.parent.services) == 0:
136143
return ''
137144

138145
names, symbols = list(), list()
139146
info = list()
140147
class_names = list()
141148

142-
for p in self.services.values():
149+
for p in self.parent.services.values():
143150
names.append(p.name)
144151
class_names.append(p.class_name)
145152
info.append(p.info if p.info else '')
@@ -165,6 +172,74 @@ def _service_doc(self, max_width=78, export='plain'):
165172
plain_dict=plain_dict,
166173
rest_dict=rest_dict)
167174

175+
def _param_doc(self, max_width=78, export='plain'):
176+
"""
177+
Export formatted model parameter documentation as a string.
178+
179+
Parameters
180+
----------
181+
max_width : int, optional = 80
182+
Maximum table width. If export format is ``rest`` it will be unlimited.
183+
184+
export : str, optional = 'plain'
185+
Export format, 'plain' for plain text, 'rest' for restructuredText.
186+
187+
Returns
188+
-------
189+
str
190+
Tabulated output in a string
191+
"""
192+
if len(self.parent.params) == 0:
193+
return ''
194+
195+
# prepare temporary lists
196+
names, units, class_names = list(), list(), list()
197+
info, defaults, properties = list(), list(), list()
198+
units_rest = list()
199+
200+
for p in self.parent.params.values():
201+
names.append(p.name)
202+
class_names.append(p.class_name)
203+
info.append(p.info if p.info else '')
204+
defaults.append(p.default if p.default is not None else '')
205+
units.append(f'{p.unit}' if p.unit else '')
206+
units_rest.append(f'*{p.unit}*' if p.unit else '')
207+
208+
plist = []
209+
for key, val in p.property.items():
210+
if val is True:
211+
plist.append(key)
212+
properties.append(','.join(plist))
213+
214+
# symbols based on output format
215+
if export == 'rest':
216+
symbols = [item.tex_name for item in self.parent.params.values()]
217+
symbols = math_wrap(symbols, export=export)
218+
title = 'Parameters\n----------'
219+
else:
220+
symbols = [item.name for item in self.parent.params.values()]
221+
title = 'Parameters'
222+
223+
plain_dict = OrderedDict([('Name', names),
224+
('Description', info),
225+
('Default', defaults),
226+
('Unit', units),
227+
('Properties', properties)])
228+
229+
rest_dict = OrderedDict([('Name', names),
230+
('Symbol', symbols),
231+
('Description', info),
232+
('Default', defaults),
233+
('Unit', units_rest),
234+
('Properties', properties)])
235+
236+
# convert to rows and export as table
237+
return make_doc_table(title=title,
238+
max_width=max_width,
239+
export=export,
240+
plain_dict=plain_dict,
241+
rest_dict=rest_dict)
242+
168243

169244
class RDocumenter:
170245
"""
@@ -178,14 +253,6 @@ class RDocumenter:
178253

179254
def __init__(self, parent):
180255
self.parent = parent
181-
self.system = parent.system
182-
self.class_name = parent.class_name
183-
self.config = parent.config
184-
self.services = parent.services
185-
self.rparams = parent.rparams
186-
self.vars = parent.vars
187-
self.constrs = parent.constrs
188-
self.obj = parent.obj
189256

190257
def get(self, max_width=78, export='plain'):
191258
"""
@@ -207,14 +274,15 @@ def get(self, max_width=78, export='plain'):
207274
if export == 'rest':
208275
max_width = 0
209276
model_header = '-' * 80 + '\n'
210-
out += f'.. _{self.class_name}:\n\n'
277+
out += f'.. _{self.parent.class_name}:\n\n'
211278
else:
212279
model_header = ''
213280

214281
if export == 'rest':
215-
out += model_header + f'{self.class_name}\n' + model_header
282+
out += model_header + f'{self.parent.class_name}\n' + model_header
216283
else:
217-
out += model_header + f'Routine <{self.class_name}> in Type <{self.parent.type}>\n' + model_header
284+
out += model_header + \
285+
f'Routine <{self.parent.class_name}> in Type <{self.parent.type}>\n' + model_header
218286

219287
if self.parent.__doc__ is not None:
220288
out += inspect.cleandoc(self.parent.__doc__)
@@ -229,20 +297,20 @@ def get(self, max_width=78, export='plain'):
229297
out += self._exprc_doc(max_width=max_width, export=export)
230298
out += self._service_doc(max_width=max_width, export=export)
231299
out += self._param_doc(max_width=max_width, export=export)
232-
out += self.config.doc(max_width=max_width, export=export)
300+
out += self.parent.config.doc(max_width=max_width, export=export)
233301

234302
return out
235303

236304
def _service_doc(self, max_width=78, export='plain'):
237305
# routine service documentation
238-
if len(self.services) == 0:
306+
if len(self.parent.services) == 0:
239307
return ''
240308

241309
names, symbols = list(), list()
242310
info = list()
243311
class_names = list()
244312

245-
for p in self.services.values():
313+
for p in self.parent.services.values():
246314
names.append(p.name)
247315
info.append(p.info if p.info else '')
248316
class_names.append(p.class_name)
@@ -251,7 +319,7 @@ def _service_doc(self, max_width=78, export='plain'):
251319

252320
# replace with latex math expressions if export is ``rest``
253321
if export == 'rest':
254-
symbols = [item.tex_name for item in self.services.values()]
322+
symbols = [item.tex_name for item in self.parent.services.values()]
255323
symbols = math_wrap(symbols, export=export)
256324
title = 'Services\n---------'
257325

@@ -272,21 +340,21 @@ def _service_doc(self, max_width=78, export='plain'):
272340

273341
def _constr_doc(self, max_width=78, export='plain'):
274342
# constraint documentation
275-
if len(self.constrs) == 0:
343+
if len(self.parent.constrs) == 0:
276344
return ''
277345

278346
# prepare temporary lists
279347
names, class_names, info = list(), list(), list()
280348

281-
for p in self.constrs.values():
349+
for p in self.parent.constrs.values():
282350
names.append(p.name)
283351
class_names.append(p.class_name)
284352
info.append(p.info if p.info else '')
285353

286354
# expressions based on output format
287355
expressions = []
288356
if export == 'rest':
289-
for p in self.constrs.values():
357+
for p in self.parent.constrs.values():
290358
expr = _tex_pre(self, p, self.parent.syms.tex_map)
291359
if p.is_eq:
292360
expr = f'{expr} = 0'
@@ -460,7 +528,7 @@ def _var_doc(self, max_width=78, export='plain'):
460528
# NOTE: this is for the optimization variables
461529
# not the _var_doc for ANDES parameters
462530
# variable documentation
463-
if len(self.vars) == 0:
531+
if len(self.parent.vars) == 0:
464532
return ''
465533

466534
# prepare temporary lists
@@ -469,7 +537,7 @@ def _var_doc(self, max_width=78, export='plain'):
469537
sources = list()
470538
units_rest = list()
471539

472-
for p in self.vars.values():
540+
for p in self.parent.vars.values():
473541
names.append(p.name)
474542
class_names.append(p.class_name)
475543
info.append(p.info if p.info else '')
@@ -493,11 +561,11 @@ def _var_doc(self, max_width=78, export='plain'):
493561

494562
# symbols based on output format
495563
if export == 'rest':
496-
symbols = [item.tex_name for item in self.vars.values()]
564+
symbols = [item.tex_name for item in self.parent.vars.values()]
497565
symbols = math_wrap(symbols, export=export)
498566
title = 'Vars\n----------------------------------'
499567
else:
500-
symbols = [item.name for item in self.vars.values()]
568+
symbols = [item.name for item in self.parent.vars.values()]
501569
title = 'Vars'
502570

503571
plain_dict = OrderedDict([('Name', names),
@@ -536,7 +604,7 @@ def _param_doc(self, max_width=78, export='plain'):
536604
str
537605
Tabulated output in a string
538606
"""
539-
if len(self.rparams) == 0:
607+
if len(self.parent.rparams) == 0:
540608
return ''
541609

542610
# prepare temporary lists
@@ -545,7 +613,7 @@ def _param_doc(self, max_width=78, export='plain'):
545613
sources = list()
546614
units_rest = list()
547615

548-
for p in self.rparams.values():
616+
for p in self.parent.rparams.values():
549617
names.append(p.name)
550618
class_names.append(p.class_name)
551619
info.append(p.info if p.info else '')
@@ -562,11 +630,11 @@ def _param_doc(self, max_width=78, export='plain'):
562630

563631
# symbols based on output format
564632
if export == 'rest':
565-
symbols = [item.tex_name for item in self.rparams.values()]
633+
symbols = [item.tex_name for item in self.parent.rparams.values()]
566634
symbols = math_wrap(symbols, export=export)
567635
title = 'Parameters\n----------------------------------'
568636
else:
569-
symbols = [item.name for item in self.rparams.values()]
637+
symbols = [item.name for item in self.parent.rparams.values()]
570638
title = 'Parameters'
571639

572640
plain_dict = OrderedDict([('Name', names),

0 commit comments

Comments
 (0)