Esempio n. 1
0
    def test_process_doxygen(self):
        s = dedent("""\
        /** This is another style of comments

        @system
        name: Alchemist
        input_ports:
        - lead
        output_ports:
        - gold
        @endsystem

        And then we have some more insightful documentation...

        @system
        name: Researcher
        input_ports:
        - ideas
        output_ports:
        - gold
        @endsystem */
        """)
        html_ish = mut.process_doxygen_system_tags(s)
        self.assertEqual(html_ish.count("\n<table"), 2)

        rst_ish = mut.process_doxygen_to_sphinx(s)
        self.assertEqual(rst_ish.count(".. pydrake_system::"), 2)
Esempio n. 2
0
    def test_html_works(self):
        s = R"""(
/** This is another style of comments

@system
name: Alchemist<br/><img src="photo.jpg" />
input_ports:
- lead
output_ports:
- <b>gold</b>
@endsystem */
)"""
        t = process_doxygen_system_tags(s)
        self.assertRegex(t, 'Alchemist<br/><img src="photo.jpg" />')
        self.assertRegex(t, '<b>gold</b>')
Esempio n. 3
0
    def test_asterisk_comment(self):
        s = R"""(
/** This is another style of comments

@system
name: Alchemist
input_ports:  // ignore
- lead
output_ports:
- gold
@endsystem */
)"""
        t = process_doxygen_system_tags(s)
        self.assertRegex(t, "\n<table")
        self.assertNotRegex(t, "ignore")
Esempio n. 4
0
    def test_line_asterisk_comment(self):
        s = R"""(
/** This is another style of comments
 *
 * @system
 * name: Alchemist
 * input_ports:  // ignore
 * - lead
 * output_ports:
 * - gold
 * @endsystem
 */
)"""
        t = process_doxygen_system_tags(s)
        self.assertRegex(t, r'\n \* <table')
        self.assertNotRegex(t, "ignore")
Esempio n. 5
0
    def test_triple_slash_comment(self):
        s = R"""()
/// This is one style of comments
///
/// @system
/// name: Adder // ignore
/// input_ports:
/// - input(0)
/// - ...
/// - input(N-1)
/// output_ports:
/// - sum
/// @endsystem
///
)"""
        t = process_doxygen_system_tags(s)
        self.assertRegex(t, "/// <table")
        self.assertNotRegex(t, "ignore")
Esempio n. 6
0
    def test_multiple_system_tags(self):
        s = R"""(
/** This is another style of comments

@system
name: Alchemist
input_ports:
- lead
output_ports:
- gold
@endsystem

And then we have some more insightful documentation...

@system
name: Researcher
input_ports:
- ideas
output_ports:
- gold
@endsystem */
)"""
        t = process_doxygen_system_tags(s)
        self.assertEqual(t.count("\n<table"), 2)
Esempio n. 7
0
def process_doxygen_commands(s):
    # Doxygen tags
    cpp_group = r'([\w:*()]+)'
    param_group = r'([\[\w,\]]+)'

    s = re.sub(r'[@\\][cp]\s+%s' % cpp_group, r'``\1``', s)
    s = re.sub(r'[@\\](?:a|e|em)\s+%s' % cpp_group, r'*\1*', s)
    s = re.sub(r'[@\\]b\s+%s' % cpp_group, r'**\1**', s)
    s = re.sub(r'[@\\]param%s?\s+%s' % (param_group, cpp_group),
               r'\n\n$Parameter ``\2``:\n\n', s)
    s = re.sub(r'[@\\]tparam%s?\s+%s' % (param_group, cpp_group),
               r'\n\n$Template parameter ``\2``:\n\n', s)
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\]retval\s+%s' % cpp_group,
               r'\n\n$Returns ``\1``:\n\n', s)

    # Ordering is significant for command names with a common prefix.
    for in_, out_ in (
        ('result', 'Returns'),
        ('returns', 'Returns'),
        ('return', 'Returns'),
        ('attention', 'Attention'),
        ('authors', 'Authors'),
        ('author', 'Authors'),
        ('bug', 'Bug report'),
        ('copyright', 'Copyright'),
        ('date', 'Date'),
        ('deprecated', 'Deprecated'),
        ('exception', 'Raises'),
        ('invariant', 'Invariant'),
        ('note', 'Note'),
        ('post', 'Postcondition'),
        ('pre', 'Precondition'),
        ('remarks', 'Remark'),
        ('remark', 'Remark'),
        ('sa', 'See also'),
        ('see', 'See also'),
        ('since', 'Since'),
        ('extends', 'Extends'),
        ('throws', 'Raises'),
        ('throw', 'Raises'),
        ('test', 'Test case'),
        ('todo', 'Todo'),
        ('version', 'Version'),
        ('warning', 'Warning'),
    ):
        s = re.sub(r'[@\\]%s\s*' % in_, r'\n\n$%s:\n\n' % out_, s)

    s = re.sub(r'[@\\]details\s*', r'\n\n', s)
    s = re.sub(r'[@\\](?:brief|short)\s*', r'', s)
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\]ref\s+', r'', s)

    for start_, end_ in (
        ('code', 'endcode'),
        ('verbatim', 'endverbatim')
    ):
        s = re.sub(r'[@\\]%s(?:\{\.\w+\})?\s?(.*?)\s?[@\\]%s' % (start_, end_),
                   r"```\n\1\n```\n", s, flags=re.DOTALL)

    s = process_doxygen_system_tags(s, add_rst_preamble=True)

    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\](?:end)?htmlonly\s+', r'', s)

    # These commands are always prefixed with an @ sign.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'@[{}]\s*', r'', s)

    # Doxygen list commands.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\](?:arg|li)\s+', r'\n\n* ', s)

    # Doxygen sectioning commands.
    s = replace_with_header(r'[@\\]section\s+\w+\s+(.*)', '=', s)
    s = replace_with_header(r'[@\\]subsection\s+\w+\s+(.*)', '-', s)
    s = re.sub(r'[@\\]subsubsection\s+\w+\s+(.*)', r'\n**\1**\n', s)

    # Doxygen LaTeX commands.
    s = re.sub(r'[@\\]f\$\s*(.*?)\s*[@\\]f\$', r':math:`\1`', s,
               flags=re.DOTALL)
    s = re.sub(r'[@\\]f\[\s*(.*?)\s*[@\\]f\]', r'\n\n.. math:: \1\n\n', s,
               flags=re.DOTALL)
    s = re.sub(r'[@\\]f\{([\w*]+)\}\s*(.*?)\s*[@\\]f\}',
               r'\n\n.. math:: \\begin{\1}\2\\end{\1}\n\n', s, flags=re.DOTALL)

    # Drake-specific Doxygen aliases.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\]default\s+', r'\n$*Default:* ', s)

    # Omit tparam scalar type boilerplate; the python documentation already
    # presents this information in a more useful manner.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\]tparam_default_scalar\s+', r'', s)
    s = re.sub(r'[@\\]tparam_nonsymbolic_scalar\s+', r'', s)
    s = re.sub(r'[@\\]tparam_double_only\s+', r'', s)

    # Remove these commands that take no argument. Ordering is significant for
    # command names with a common prefix.
    for cmd_ in (
        '~english',
        '~',
        'callergraph',
        'callgraph',
        'hidecallergraph',
        'hidecallgraph',
        'hideinitializer',
        'nosubgrouping',
        'privatesection',
        'private',
        'protectedsection',
        'protected',
        'publicsection',
        'public',
        'pure',
        'showinitializer',
        'static',
        'tableofcontents',
    ):
        s = re.sub(r'[@\\]%s\s+' % cmd_, r'', s)

    # Remove these commands and their one optional single-word argument.
    # TODO (betsymcphail): Not tested
    for cmd_ in [
        'dir',
        'file',
    ]:
        s = re.sub(r'[@\\]%s( +[\w:./]+)?\s+' % cmd_, r'', s)

    # Remove these commands and their one optional single-line argument.
    # TODO (betsymcphail): Not tested
    for cmd_ in [
        'mainpage',
        'name'
        'overload',
    ]:
        s = re.sub(r'[@\\]%s( +.*)?\s+' % cmd_, r'', s)

    # Remove these commands and their one single-word argument. Ordering is
    # significant for command names with a common prefix.
    for cmd_ in [
        'anchor',
        'copybrief',
        'copydetails',
        'copydoc',
        'def',
        'dontinclude',
        'enum',
        'example',
        'extends',
        'htmlinclude',
        'idlexcept',
        'implements',
        'includedoc',
        'includelineno',
        'include',
        'latexinclude',
        'memberof',
        'namespace',
        'package',
        'relatedalso',
        'related',
        'relatesalso',
        'relates',
        'verbinclude',
    ]:
        s = re.sub(r'[@\\]%s\s+[\w:.]+\s+' % cmd_, r'', s)

    # Remove these commands and their one single-line argument. Ordering is
    # significant for command names with a common prefix.
    for cmd_ in [
        'addindex',
        'fn',
        'ingroup',
        'line',
        'property',
        'skipline',
        'skip',
        'typedef',
        'until',
        'var',
    ]:
        s = re.sub(r'[@\\]%s\s+.*\s+' % cmd_, r'', s)

    # Remove this command and its one single-word argument and one
    # optional single-word argument.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\]headerfile\s+[\w:.]+( +[\w:.]+)?\s+', r'', s)

    # Remove these commands and their one single-word argument and one
    # optional single-line argument.
    # TODO (betsymcphail): Not tested
    for cmd_ in [
        'addtogroup',
        'weakgroup',
    ]:
        s = re.sub(r'[@\\]%s\s+[\w:.]( +.*)?\s+' % cmd_, r'', s)

    # Remove these commands and their one single-word argument and one
    # single-line argument. Ordering is significant for command names with a
    # common prefix.
    # TODO (betsymcphail): Not tested
    for cmd_ in [
        'snippetdoc',
        'snippetlineno',
        'snippet',
    ]:
        s = re.sub(r'[@\\]%s\s+[\w:.]\s+.*\s+' % cmd_, r'', s)

    # Remove these commands and their one single-word argument and two
    # optional single-word arguments.
    for cmd_ in [
        'category',
        'class',
        'interface',
        'protocol',
        'struct',
        'union',
    ]:
        s = re.sub(r'[@\\]%s\s+[\w:.]+( +[\w:.]+){0,2}\s+' % cmd_, r'', s)

    # Remove these commands and their one single-word argument, one optional
    # quoted argument, and one optional single-word arguments.
    # TODO (betsymcphail): Not tested
    for cmd_ in [
        'diafile',
        'dotfile',
        'mscfile',
    ]:
        s = re.sub(
           r'[@\\]%s\s+[\w:.]+(\s+".*?")?(\s+[\w:.]+=[\w:.]+)?s+' % cmd_,
           r'', s)

    # Remove these pairs of commands and any text in between.
    for start_, end_ in (
        ('cond', 'endcond'),
        ('docbookonly', 'enddocbookonly'),
        ('dot', 'enddot'),
        ('internal', 'endinternal'),
        ('latexonly', 'endlatexonly'),
        ('manonly', 'endmanonly'),
        ('msc', 'endmsc'),
        ('rtfonly', 'endrtfonly'),
        ('secreflist', 'endsecreflist'),
        ('startuml', 'enduml'),
        ('xmlonly', 'endxmlonly'),
    ):
        s = re.sub(r'[@\\]%s\s?(.*?)\s?[@\\]%s' % (start_, end_), r'', s,
                   flags=re.DOTALL)

        # Some command pairs may bridge multiple comment blocks, so individual
        # start and end commands may appear alone.
        s = re.sub(r'[@\\]%s\s+' % start_, r'', s)
        s = re.sub(r'[@\\]%s\s+' % end_, r'', s)

    # Remove auto-linking character. Be sure to remove only leading % signs.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'(\s+)%(\S+)', r'\1\2', s)

    # Doxygen escaped characters.
    # TODO (betsymcphail): Not tested
    s = re.sub(r'[@\\]n\s+', r'\n\n', s)

    # Ordering of ---, --, @, and \ is significant.
    # TODO (betsymcphail): Not tested
    for escaped_ in (
        '---',
        '--',
        '::',
        r'\.',
        '"',
        '&',
        '#',
        '%',
        '<',
        '>',
        r'\$',
        '@',
        r'\\',
    ):
        s = re.sub(r'[@\\](%s)' % escaped_, r'\1', s)

    return s