def parse_maintainers()

in sphinx/maintainers_include.py [0:0]


    def parse_maintainers(self, path):
        """Parse all the MAINTAINERS lines into ReST for human-readability"""

        result = list()
        result.append(".. _maintainers:")
        result.append("")

        # Poor man's state machine.
        descriptions = False
        maintainers = False
        subsystems = False

        # Field letter to field name mapping.
        field_letter = None
        fields = dict()

        prev = None
        field_prev = ""
        field_content = ""

        for line in open(path):
            # Have we reached the end of the preformatted Descriptions text?
            if descriptions and line.startswith('Maintainers'):
                descriptions = False
                # Ensure a blank line following the last "|"-prefixed line.
                result.append("")

            # Start subsystem processing? This is to skip processing the text
            # between the Maintainers heading and the first subsystem name.
            if maintainers and not subsystems:
                if re.search('^[A-Z0-9]', line):
                    subsystems = True

            # Drop needless input whitespace.
            line = line.rstrip()

            # Linkify all non-wildcard refs to ReST files in Documentation/.
            pat = '(Documentation/([^\s\?\*]*)\.rst)'
            m = re.search(pat, line)
            if m:
                # maintainers.rst is in a subdirectory, so include "../".
                line = re.sub(pat, ':doc:`%s <../%s>`' % (m.group(2), m.group(2)), line)

            # Check state machine for output rendering behavior.
            output = None
            if descriptions:
                # Escape the escapes in preformatted text.
                output = "| %s" % (line.replace("\\", "\\\\"))
                # Look for and record field letter to field name mappings:
                #   R: Designated *reviewer*: FullName <address@domain>
                m = re.search("\s(\S):\s", line)
                if m:
                    field_letter = m.group(1)
                if field_letter and not field_letter in fields:
                    m = re.search("\*([^\*]+)\*", line)
                    if m:
                        fields[field_letter] = m.group(1)
            elif subsystems:
                # Skip empty lines: subsystem parser adds them as needed.
                if len(line) == 0:
                    continue
                # Subsystem fields are batched into "field_content"
                if line[1] != ':':
                    # Render a subsystem entry as:
                    #   SUBSYSTEM NAME
                    #   ~~~~~~~~~~~~~~

                    # Flush pending field content.
                    output = field_content + "\n\n"
                    field_content = ""

                    # Collapse whitespace in subsystem name.
                    heading = re.sub("\s+", " ", line)
                    output = output + "%s\n%s" % (heading, "~" * len(heading))
                    field_prev = ""
                else:
                    # Render a subsystem field as:
                    #   :Field: entry
                    #           entry...
                    field, details = line.split(':', 1)
                    details = details.strip()

                    # Mark paths (and regexes) as literal text for improved
                    # readability and to escape any escapes.
                    if field in ['F', 'N', 'X', 'K']:
                        # But only if not already marked :)
                        if not ':doc:' in details:
                            details = '``%s``' % (details)

                    # Comma separate email field continuations.
                    if field == field_prev and field_prev in ['M', 'R', 'L']:
                        field_content = field_content + ","

                    # Do not repeat field names, so that field entries
                    # will be collapsed together.
                    if field != field_prev:
                        output = field_content + "\n"
                        field_content = ":%s:" % (fields.get(field, field))
                    field_content = field_content + "\n\t%s" % (details)
                    field_prev = field
            else:
                output = line

            # Re-split on any added newlines in any above parsing.
            if output != None:
                for separated in output.split('\n'):
                    result.append(separated)

            # Update the state machine when we find heading separators.
            if line.startswith('----------'):
                if prev.startswith('Descriptions'):
                    descriptions = True
                if prev.startswith('Maintainers'):
                    maintainers = True

            # Retain previous line for state machine transitions.
            prev = line

        # Flush pending field contents.
        if field_content != "":
            for separated in field_content.split('\n'):
                result.append(separated)

        output = "\n".join(result)
        # For debugging the pre-rendered results...
        #print(output, file=open("/tmp/MAINTAINERS.rst", "w"))

        self.state_machine.insert_input(
          statemachine.string2lines(output), path)