diff --git a/docs/util/cmdref.py b/docs/util/cmdref.py index 89982d75f..e471ea46d 100644 --- a/docs/util/cmdref.py +++ b/docs/util/cmdref.py @@ -115,12 +115,11 @@ class CommandUsageNode(TocNode): ] def handle_signature(self, sig: str, signode: addnodes.desc_signature): - try: - cmd, use = sig.split('::') - except ValueError: - cmd, use = sig, '' - signode['fullname'] = sig - usage = self.options.get('usage', use or sig) + parts = sig.split('::') + if len(parts) > 2: parts.pop(0) + use = parts[-1] + signode['fullname'] = '::'.join(parts) + usage = self.options.get('usage', use) if usage: signode['tocname'] = usage signode += addnodes.desc_name(text=usage) @@ -145,46 +144,16 @@ class CommandUsageNode(TocNode): idx, 1)) -class CommandOptionGroupNode(TocNode): +class CommandOptionGroupNode(CommandUsageNode): """A custom node that describes a group of related options""" name = 'cmdoptiongroup' - option_spec = TocNode.option_spec + option_spec = CommandUsageNode.option_spec doc_field_types = [ Field('opt', ('option',), label='', rolename='option') ] - - def handle_signature(self, sig: str, signode: addnodes.desc_signature): - try: - cmd, name = sig.split('::') - except ValueError: - cmd, name = '', sig - signode['fullname'] = sig - if name: - signode['tocname'] = name - signode += addnodes.desc_name(text=name) - return signode['fullname'] - - def add_target_and_index( - self, - name: str, - sig: str, - signode: addnodes.desc_signature - ) -> None: - idx = ".".join(name.split("::")) - signode['ids'].append(idx) - if 'noindex' not in self.options: - tocname: str = signode.get('tocname', name) - objs = self.env.domaindata[self.domain]['objects'] - # (name, sig, typ, docname, anchor, prio) - objs.append((name, - tocname, - type(self).name, - self.env.docname, - idx, - 1)) def transform_content(self, contentnode: addnodes.desc_content) -> None: """hack `:option -thing: desc` into a proper option list""" diff --git a/docs/util/newcmdref.py b/docs/util/newcmdref.py index 0a4874714..d4b6aff82 100644 --- a/docs/util/newcmdref.py +++ b/docs/util/newcmdref.py @@ -16,7 +16,8 @@ logger = logging.getLogger(__name__) # cmd signature cmd_ext_sig_re = re.compile( - r'''^ ([\w$._]+?) # module name + r'''^ ([\w/]+::)? # optional group + ([\w$._]+?) # module name (?:\.([\w_]+))? # optional: thing name (::[\w_]+)? # attribute \s* $ # and nothing more @@ -47,23 +48,22 @@ class YosysCmd: name: str title: str content: list[YosysCmdContentListing] + source_file: str experimental_flag: bool def __init__( self, name:str = "", title:str = "", content: list[dict[str]] = [], + source_file:str = 'unknown', experimental_flag: bool = False ) -> None: self.name = name self.title = title self.content = [YosysCmdContentListing(**c) for c in content] + self.source_file = source_file self.experimental_flag = experimental_flag - @property - def source_file(self) -> str: - return "" - @property def source_line(self) -> int: return 0 @@ -86,7 +86,7 @@ class YosysCmdGroupDocumenter(Documenter): def cmd_lib(self) -> dict[str, list[str] | dict[str]]: if not self.__cmd_lib: self.__cmd_lib = {} - cmds_obj: dict[str, dict[str, list[str] | dict[str]]] + cmds_obj: dict[str, dict[str, dict[str]]] try: with open(self.config.cmds_json, "r") as f: cmds_obj = json.loads(f.read()) @@ -96,8 +96,19 @@ class YosysCmdGroupDocumenter(Documenter): type = 'cmdref', subtype = 'cmd_lib' ) - else: - for (name, obj) in cmds_obj.get(self.lib_key, {}).items(): + cmds_obj = {} + for (name, obj) in cmds_obj.get('cmds', {}).items(): + if self.lib_key == 'groups': + source_file: str = obj.get('source_file', 'unknown') + if source_file == 'unknown': + source_group = 'unknown' + else: + source_group = str(Path(source_file).parent) + try: + self.__cmd_lib[source_group].append(name) + except KeyError: + self.__cmd_lib[source_group] = [name,] + else: self.__cmd_lib[name] = obj return self.__cmd_lib @@ -139,25 +150,10 @@ class YosysCmdGroupDocumenter(Documenter): return self.modname def add_directive_header(self, sig: str) -> None: - domain = getattr(self, 'domain', 'cmd') - directive = getattr(self, 'directivetype', 'group') - name = self.format_name() - sourcename = self.get_sourcename() - cmd_list = self.object - - # cmd definition - self.add_line(f'.. {domain}:{directive}:: {sig}', sourcename) - self.add_line(f' :caption: {name}', sourcename) - - if self.options.noindex: - self.add_line(' :noindex:', sourcename) + pass def add_content(self, more_content: Any | None) -> None: - # groups have no native content - # add additional content (e.g. from document), if present - if more_content: - for line, src in zip(more_content.data, more_content.items): - self.add_line(line, src[0], src[1]) + pass def filter_members( self, @@ -290,13 +286,14 @@ class YosysCmdDocumenter(YosysCmdGroupDocumenter): def parse_name(self) -> bool: try: matched = cmd_ext_sig_re.match(self.name) - modname, thing, attribute = matched.groups() + group, modname, thing, attribute = matched.groups() except AttributeError: logger.warning(('invalid signature for auto%s (%r)') % (self.objtype, self.name), type='cmdref') return False self.modname = modname + self.groupname = group or '' self.attribute = attribute or '' self.fullname = ((self.modname) + (thing or '')) @@ -364,19 +361,15 @@ class YosysCmdDocumenter(YosysCmdGroupDocumenter): for content in self.object.content: render(content) + if self.get_sourcename() != 'unknown': + self.add_line('\n', source_name) + self.add_line(f'.. note:: Help text automatically generated from :file:`{source_name}`', source_name) + # add additional content (e.g. from document), if present if more_content: for line, src in zip(more_content.data, more_content.items): self.add_line(line, src[0], src[1]) - # fields - self.add_line('\n', source_name) - field_attrs = ["properties", ] - for field in field_attrs: - attr = getattr(self.object, field, []) - for val in attr: - self.add_line(f':{field} {val}:', source_name) - def get_object_members( self, want_all: bool diff --git a/kernel/register.cc b/kernel/register.cc index d3e3a7396..eb0e56137 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -1045,6 +1045,7 @@ struct HelpPass : public Pass { for (auto content : cmd_help.get_content()) json.value(content->to_json()); json.end_array(); + json.entry("source_file", cmd_help.source_file()); json.entry("experimental_flag", experimental_flag); json.end_object(); }