Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google style docstring code block is not rendered correctly #296

Open
ShawnHymel opened this issue Jul 7, 2023 · 1 comment
Open

Google style docstring code block is not rendered correctly #296

ShawnHymel opened this issue Jul 7, 2023 · 1 comment
Assignees
Labels

Comments

@ShawnHymel
Copy link

ShawnHymel commented Jul 7, 2023

Environment

  • Pydoc-Markdown Version: 4.8.2
  • Python Version: v3.10.11
  • Operating System: macOS 13.4.1

Describe the bug

Using a Google-style code block retains its indentation and does not render correctly in markdown (VS Code and GitHub rendering).

Simple Python example (in src/module-test.py):

from typing import Union, Optional, Any

def str_test(
    in_str: Any,
    num: int
) -> str:
    """
    Prints something to the screen and adds 'something' to the end.

    Args:
        in_str (Any): any string
        num: Number of times to add 'something' at the end in order to test
            how this darn thing works

    Returns:
        str: String with 'something' added

    Raises:

    Example:

        How to use:

        ```python
        # A comment
        msg = str_test("Hello", 2)
        print(msg)
        ```

    """

    msg = str(in_str)
    for i in range(num):
        msg = f"{msg} something"
    return msg

if __name__ == "__main__":
    text = str_test("hello", 2)
    print(text)

Produce markdown with:

pydoc-markdown -I src/ '{renderer: {type: markdown, escape_html_in_docstring: false}}' > module-test.md

module-test.md has the following:

<a id="module-test"></a>

# module-test

<a id="module-test.str_test"></a>

#### str\_test

```python
def str_test(in_str: Any, num: int) -> str
```

Prints something to the screen and adds 'something' to the end.

**Arguments**:

- `in_str` _Any_ - any string
- `num` - Number of times to add 'something' at the end in order to test
  how this darn thing works
  

**Returns**:

- `str` - String with 'something' added
  

**Raises**:

  

**Example**:

  
  How to use:
  
    ```python
    # A comment
    msg = str_test("Hello", 2)
    print(msg)
    ```

The extra indentation on the code block renders the backticks as follows:

Screenshot 2023-07-07 at 11 46 29 AM

I've tried many different combinations of with/without backticks and indentations. It either renders as shown above or does not render the code block at all (treated as markdown text).

Any idea on how to format the Google-style docstring to make the code block render correctly?

Expected behavior

Google-style docstring with "Examples:" section should render correctly in markdown.

@lraubuch
Copy link

lraubuch commented Jul 4, 2024

I had a quick solution, which I didn't put as a pull request as it seemed a bit hacky and I didn't check the tests, but for me it worked.
I simply added 4 lines to the google processor
Hope this helps in resolving the issue.

def _process(self, node: docspec.ApiObject):
        if not node.docstring:
            return

        lines = []
        current_lines: t.List[str] = []
        in_codeblock = False
        keyword = None

        def _commit():
            if keyword:
                generate_sections_markdown(lines, {keyword: current_lines})
            else:
                lines.extend(current_lines)
            current_lines.clear()

        for line in node.docstring.content.split("\n"):
            if line.lstrip().startswith("```"):
                in_codeblock = not in_codeblock
                current_lines.append(line)
                continue

            if in_codeblock:
                current_lines.append(line)
                continue

            line = line.strip()
            if line in self._keywords_map:
                _commit()
                keyword = self._keywords_map[line]
                if keyword == 'Examples' or keyword == 'Example':
                    current_lines.append('```python')
                continue

            if keyword is None:
                lines.append(line)
                continue

            for param_re in self._param_res:
                param_match = param_re.match(line)
                if param_match:
                    if "type" in param_match.groupdict():
                        current_lines.append("- `{param}` _{type}_ - {desc}".format(**param_match.groupdict()))
                    else:
                        current_lines.append("- `{param}` - {desc}".format(**param_match.groupdict()))
                    break

            if not param_match:
                current_lines.append("  {line}".format(line=line))
        if keyword == 'Examples' or keyword == 'Example':
            current_lines.append('```')
        _commit()
        node.docstring.content = "\n".join(lines)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants