def test_trim_empty_lines(self):
     self.assertEqual(
         IndentTrimmer.trim_empty_lines("\n  \n test\ntest2\n \n "),
         " test\ntest2")
     self.assertEqual(IndentTrimmer.trim_empty_lines("\n  \n\n "), "")
     self.assertEqual(IndentTrimmer.trim_empty_lines("\n  \n  test \n "),
                      "  test ")
Exemple #2
0
 def __init__(self, docstring):
     # type: (Text) -> None
     docstring = self._cleanup(docstring)
     docstring = IndentTrimmer.trim_empty_lines(docstring)
     docstring = IndentTrimmer.trim_text(docstring)
     lines = docstring.split("\n")
     self._lines = IndentTrimmer.trim_lines(lines)
 def test_trim_text(self):
     self.assertEqual(IndentTrimmer.trim_text("  asd\n asd\n   asd\n"),
                      " asd\nasd\n  asd\n")
     self.assertEqual(IndentTrimmer.trim_text("  asd\nasd\n   asd\n"),
                      "  asd\nasd\n   asd\n")
     self.assertEqual(IndentTrimmer.trim_text(" asd\n asd\n  asd\n"),
                      "asd\nasd\n asd\n")
 def test_trim_lines(self):
     self.assertEqual(
         IndentTrimmer.trim_lines(["  asd", " asd", "   asd"]),
         [" asd", "asd", "  asd"],
     )
     self.assertEqual(
         IndentTrimmer.trim_lines(["  asd", " asd", "", "   asd"]),
         [" asd", "asd", "", "  asd"],
     )
     self.assertEqual(
         IndentTrimmer.trim_lines(["  asd", "asd", "   asd", ""]),
         ["  asd", "asd", "   asd", ""],
     )
     self.assertEqual(IndentTrimmer.trim_lines([]), [])
Exemple #5
0
    def add_line_indent(self, section_name: str, line: str) -> None:
        """
        Add line respecting indent of the current section block.

        Arguments:
            section_name -- Target section title
            line -- Line to add
        """
        if section_name in self:
            section = self[section_name]
            if section.blocks and section.blocks[-1].lines:
                indent = IndentTrimmer.get_line_indent(section.blocks[-1].lines[-1])
                line = IndentTrimmer.indent_line(line, indent)

        self.add_line(section_name, line)
Exemple #6
0
    def render(self) -> str:
        """
        Render trimmed block lines.

        Returns:
            Block lines as a text.
        """
        lines = IndentTrimmer.trim_lines(self.lines)
        return "\n".join(lines)
    def _cleanup(docstring: str) -> str:
        """
        Fix multiline docstrings starting with no newline after quotes.

        Arguments:
            docstring -- Raw docstring.

        Returns:
            Aligned docstring.
        """
        if "\n" in docstring and docstring[0] != "\n":
            lines = docstring.split("\n")
            next_line_index = 1
            next_line = lines[next_line_index]
            while not next_line.strip() and next_line_index < len(lines) - 1:
                next_line_index += 1
                next_line = lines[next_line_index]

            indent = IndentTrimmer.get_line_indent(next_line)
            docstring = "\n{}{}".format(" " * indent, docstring)

        return IndentTrimmer.trim_text(docstring)
Exemple #8
0
    def get_toc_line(cls, line, level=0):
        # type: (Text, int) -> Text
        """
        Get ToC `line` of given `level`.

        Arguments:
            line -- Line to prepare.
            level -- Line level, starts with `0`.

        Returns:
            Ready to insert ToC line.
        """
        indent = cls.TOC_INDENT * level
        return IndentTrimmer.indent_line("- {}".format(line), indent)
Exemple #9
0
    def build_sections(self, content):
        # type: (Text) -> SectionMap
        """
        Parse docstring and split it to sections with arrays of strings.

        Arguments:
            content -- Object docstring.

        Returns:
            A dictionary where key is a section name and value is a list of string sof this
            section.
        """
        self._reset()

        for line in content.split("\n"):
            self._current_indent = IndentTrimmer.get_line_indent(line)
            line = line.strip()

            # adding new lines to a doctest code block
            if self._in_doctest_block:
                self._parse_doctest_line(line)
                continue

            # adding new lines to a tilde block
            if self._in_tilde_block:
                self._parse_tilde_block_line(line)
                continue

            # adding new lines to a code block
            if self._in_md_codeblock:
                self._parse_md_codeblock_line(line)
                continue

            # adding new lines to an indented code block
            if self._in_indent_codeblock:
                self._parse_indent_codeblock_line(line)
                continue

            # adding new block on empty line outside of a code block
            if not line:
                self._add_block()
                continue

            self._parse_line(line)

        if self._in_indent_codeblock:
            self._trim_empty_lines()
            self._add_line("```", indent=0)

        return self.section_map
Exemple #10
0
    def append(self, content):
        # type: (Text) -> None
        """
        Append `content` to the document.
        Handle trimming and sectioning the content and update
        `title` and `toc_section` fields.

        Arguments:
            content -- Text to add.
        """
        content = IndentTrimmer.trim_empty_lines(content)
        if not content:
            return

        if not self.subtitle and not self.sections and not content.startswith(
                "#"):
            self.subtitle = content
        else:
            self._sections.append(content)

        self._content = self._build_content()
Exemple #11
0
    def _get_function_def_lines(self, function_record: FunctionRecord) -> List[str]:
        """
        Get all function definition lines for comment type
        hints lookup.

        Removes indentation.

        Arguments:
            function_record -- Function record for source lookup.

        Returns:
            Function definition lines as an array.
        """
        assert isinstance(function_record.node, (ast.AsyncFunctionDef, ast.FunctionDef))

        result: List[str] = []
        start_index = function_record.line_number - 1
        end_index = function_record.node.body[0].lineno - 1
        result = self.source_lines[start_index:end_index]
        result = [i.rstrip("\n") for i in result]
        result = IndentTrimmer.trim_lines(result)
        return result
Exemple #12
0
    def read(self, source_path=None):
        # type: (Optional[Path]) -> None
        """
        Read and parse content from `source_path`.

        Arguments:
            source_path -- Input file path. If not provided - `path` is used.
        """
        path = source_path or self._path
        self._content = path.read_text()
        self._title = ""
        self._toc_section = ""
        title, content = extract_md_title(self._content)
        if title:
            self._title = title

        sections = content.split(self._section_separator)
        self._sections = []
        for section in sections:
            section = IndentTrimmer.trim_empty_lines(section)
            if not section:
                continue
            if self.is_toc(section) and not self._toc_section:
                self._toc_section = section
                if self._sections:
                    self._subtitle = self._section_separator.join(
                        self._sections)
                    self._sections = []
                continue

            self._sections.append(section)

        # extract subtitle from the first section if it is not a title
        if not self._subtitle and self._sections and not self._sections[
                0].startswith("#"):
            self._subtitle = self._sections.pop(0)
 def test_trim_line(self):
     self.assertEqual(IndentTrimmer.trim_line("   test", 2), " test")
     self.assertEqual(IndentTrimmer.trim_line(" test", 2), "test")
     self.assertEqual(IndentTrimmer.trim_line("test", 2), "test")
     self.assertEqual(IndentTrimmer.trim_line("   ", 2), " ")
 def test_get_line_indent(self):
     self.assertEqual(IndentTrimmer.get_line_indent("   test"), 3)
     self.assertEqual(IndentTrimmer.get_line_indent("test"), 0)
     self.assertEqual(IndentTrimmer.get_line_indent("  "), 2)
     self.assertEqual(IndentTrimmer.get_line_indent(""), 0)