File indexing completed on 2025-01-19 04:00:00

0001 import os
0002 import argparse
0003 from importlib.machinery import SourceFileLoader
0004 
0005 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
0006 doxpath = os.path.join(root, "docs", "dox")
0007 doxfile = os.path.join(doxpath, "scripts.dox")
0008 scriptpath = os.path.join(root, "bin")
0009 
0010 os.makedirs(doxpath, exist_ok=True)
0011 
0012 
0013 scripts = []
0014 
0015 for scriptfilename in os.listdir(scriptpath):
0016     if scriptfilename.endswith(".py"):
0017         module = SourceFileLoader(
0018             os.path.splitext(scriptfilename)[0],
0019             os.path.join(scriptpath, scriptfilename)
0020         ).load_module()
0021         if hasattr(module, "parser"):
0022             scripts.append(module)
0023 
0024 
0025 class DoxyHelpFormatter(argparse.HelpFormatter):
0026     class _Section(argparse.HelpFormatter._Section):
0027         def format_help(self):
0028             join = self.formatter._join_parts
0029             item_help = join([func(*args) for func, args in self.items])
0030 
0031             # return nothing if the section was empty
0032             if not item_help:
0033                 return ''
0034 
0035             # add the heading if the section was non-empty
0036             if self.heading is not argparse.SUPPRESS and self.heading is not None:
0037                 heading = r"""
0038 \subsubsection script_{name}_{id} {heading}
0039 
0040 """.format(
0041                     name=script.__name__,
0042                     id=self.heading.lower().replace(" ", "_"),
0043                     heading=self.heading
0044 )
0045             else:
0046                 heading = ''
0047 
0048             # join the section-initial newline, the heading and the help
0049             return join(['\n', heading, item_help, '\n'])
0050 
0051     def __init__(self, *a, **kw):
0052         super().__init__(*a, **kw)
0053         self.sectioned = False
0054 
0055     def start_section(self, heading):
0056         self.sectioned = True
0057         return super().start_section(heading)
0058 
0059     def _indent(self):
0060         pass
0061 
0062     def _dedent(self):
0063         pass
0064 
0065     def _format_usage(self, usage, actions, groups, prefix):
0066         return r"""
0067 \subsection script_{name}_usage Usage
0068 
0069 \code{{.unparsed}}
0070 {usage}
0071 \endcode
0072 
0073 \subsection script_{name}_options Options
0074 
0075 """.format(
0076             name=script.__name__,
0077             usage=super()._format_usage(usage, actions, groups, "").strip(),
0078 )
0079 
0080     def _metavar_formatter(self, action, default_metavar, doxyfy=False):
0081         wrapper = super()._metavar_formatter(action, default_metavar)
0082 
0083         if action.metavar is not None:
0084             result = action.metavar
0085         else:
0086             result = default_metavar
0087 
0088         if doxyfy:
0089             result = "@em @<%s@>" % result.lower()
0090         else:
0091             result = "<%s>" % result.lower()
0092 
0093         def format(tuple_size):
0094             return (result, ) * tuple_size
0095         return format
0096 
0097     def _format_args(self, action, default_metavar, doxyfy=False):
0098         get_metavar = self._metavar_formatter(action, default_metavar, doxyfy)
0099         if action.nargs is None:
0100             result = '%s' % get_metavar(1)
0101         elif action.nargs == argparse.OPTIONAL:
0102             result = '[%s]' % get_metavar(1)
0103         elif action.nargs == argparse.ZERO_OR_MORE:
0104             result = '[%s [%s ...]]' % get_metavar(2)
0105         elif action.nargs == argparse.ONE_OR_MORE:
0106             result = '%s [%s ...]' % get_metavar(2)
0107         elif action.nargs == argparse.REMAINDER:
0108             result = '...'
0109         elif action.nargs == argparse.PARSER:
0110             result = '%s ...' % get_metavar(1)
0111         else:
0112             formats = ['%s' for _ in range(action.nargs)]
0113             result = ' '.join(formats) % get_metavar(action.nargs)
0114         return result
0115 
0116     def _format_action_invocation(self, action, doxyfy=False):
0117         if not action.option_strings:
0118             default = self._get_default_metavar_for_positional(action)
0119             metavar, = self._metavar_formatter(action, default, doxyfy)(1)
0120             return metavar
0121         else:
0122             os = ", ".join(
0123                 ("@p " if doxyfy else "") + option_string.replace("--", "\\--")
0124                 for option_string in action.option_strings
0125             )
0126             default = self._get_default_metavar_for_optional(action)
0127             args_string = self._format_args(action, default, doxyfy)
0128 
0129             os += " " + args_string
0130 
0131             if action.default is not None and action.default is not argparse.SUPPRESS:
0132                 os += " =%s%s" % (
0133                     "@c " if doxyfy else "",
0134                     action.default
0135                 )
0136 
0137             return os
0138 
0139     def _format_action(self, action):
0140         out = "@par "
0141 
0142         out += self._format_action_invocation(action, True) + "\n@parblock\n"
0143 
0144         if action.help:
0145             out += self._expand_help(action) + "\n\n"
0146 
0147         if action.choices:
0148             out += "@b Choices:\n"
0149             for c in action.choices:
0150                 out += "@li @c %s\n" % c
0151             out += "\n"
0152 
0153         #for subaction in self._iter_indented_subactions(action):
0154             #parts.append(self._format_action(subaction))
0155 
0156         return out + "@endparblock \n\n"
0157 
0158     def add_text(self, text):
0159         if self.sectioned:
0160             return super().add_text(text)
0161 
0162 
0163 with open(doxfile, "w") as outf:
0164     outf.write(r"""
0165 /**
0166 \page scripts Scripts
0167 \brief Script files
0168 
0169 |Script|Description|
0170 |---|---|
0171 """)
0172 
0173     for script in scripts:
0174         outf.write("| \\subpage script_%s | %s |\n" % (
0175             script.__name__,
0176             script.parser.description.strip().splitlines()[0]
0177         ))
0178 
0179     outf.write("\n\n")
0180 
0181     for script in scripts:
0182         parser = script.parser
0183         parser.prog = os.path.basename(script.__file__)
0184         parser.formatter_class = DoxyHelpFormatter
0185         outf.write(r"""
0186 \page script_{name} {name}.py
0187 
0188 \section script_{name}_brief {name}.py
0189 
0190 {brief}
0191 
0192 {help}
0193         """.format(
0194             name=script.__name__,
0195             brief=parser.description,
0196             help=parser.format_help(),
0197         ))
0198 
0199         outf.write("\n")
0200 
0201     outf.write("\n*/")