Skip to content

Commit

Permalink
Merged upstream/main into feat/sidebar-options
Browse files Browse the repository at this point in the history
  • Loading branch information
gadenbuie committed Oct 16, 2024
2 parents e8a624f + 8d7ade2 commit ddd25d5
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: "${{ matrix.python-version }}"
python-version: "3.10"
- name: Install dev dependencies
run: |
python -m pip install --upgrade pip
Expand Down
19 changes: 12 additions & 7 deletions quartodoc/builder/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,6 @@ def _fetch_members(self, el: Auto, obj: dc.Object | dc.Alias):
if obj.is_module and obj.exports is not None:
options = {k: v for k, v in options.items() if v.is_exported}

if el.include:
raise NotImplementedError("include argument currently unsupported.")

if el.exclude:
raise NotImplementedError("exclude argument currently unsupported.")

if not el.include_private:
options = {k: v for k, v in options.items() if not k.startswith("_")}

Expand Down Expand Up @@ -407,7 +401,18 @@ def _fetch_members(self, el: Auto, obj: dc.Object | dc.Alias):
if not el.include_functions:
options = {k: v for k, v in options.items() if not v.is_function}

return sorted(options)
if el.include:
raise NotImplementedError("include argument currently unsupported.")

if el.exclude:
options = {k: v for k, v in options.items() if k not in el.exclude}

if el.member_order == "alphabetical":
return sorted(options)
elif el.member_order == "source":
return list(options)
else:
raise ValueError(f"Unsupported value of member_order: {el.member_order}")


class _PagePackageStripper(PydanticTransformer):
Expand Down
10 changes: 8 additions & 2 deletions quartodoc/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,11 @@ class AutoOptions(_Base):

# other options ----
include: Optional[str] = None
exclude: Optional[str] = None
exclude: Optional[list[str]] = None
dynamic: Union[None, bool, str] = None
children: ChoicesChildren = ChoicesChildren.embedded
package: Union[str, None, MISSING] = MISSING()
member_order: Literal["alphabetical", "source"] = "alphabetical"
member_options: Optional["AutoOptions"] = None

# for tracking fields users manually specify
Expand All @@ -249,6 +250,7 @@ class Auto(AutoOptions):
path the object, and short is the name of the object (i.e. no periods).
members:
A list of members, such as attributes or methods on a class, to document.
If members is specified, no other includes or excludes are applied.
include_private:
Whether to include members starting with "_"
include_imports:
Expand All @@ -266,7 +268,8 @@ class Auto(AutoOptions):
include:
(Not implemented). A list of members to include.
exclude:
(Not implemented). A list of members to exclude.
A list of members to exclude. This is performed last, in order to subtract
from the results of options like include_functions.
dynamic:
Whether to dynamically load docstring. By default docstrings are loaded
using static analysis. dynamic may be a string pointing to another object,
Expand All @@ -275,6 +278,9 @@ class Auto(AutoOptions):
Style for presenting members. Either separate, embedded, or flat.
package:
If specified, object lookup will be relative to this path.
member_order:
Order to present members in, either "alphabetical" or "source" order.
Defaults to alphabetical sorting.
member_options:
Options to apply to members. These can include any of the options above.
Expand Down
7 changes: 5 additions & 2 deletions quartodoc/renderers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ def escape(val: str):
return f"`{val}`"


def sanitize(val: str, allow_markdown=False):
def sanitize(val: str, allow_markdown=False, escape_quotes=False):
# sanitize common tokens that break tables
res = val.replace("\n", " ").replace("|", "\\|")

# sanitize elements that get turned into smart quotes
res = res.replace("'", r"\'").replace('"', r"\"")
# this is to avoid defaults that are strings having their
# quotes screwed up.
if escape_quotes:
res = res.replace("'", r"\'").replace('"', r"\"")

# sanitize elements that can get interpreted as markdown links
# or citations
Expand Down
30 changes: 18 additions & 12 deletions quartodoc/renderers/md_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class ParamRow:
def to_definition_list(self):
name = self.name
anno = self.annotation
desc = self.description
default = sanitize(str(self.default))
desc = sanitize(self.description, allow_markdown=True)
default = sanitize(str(self.default), escape_quotes=True)

part_name = (
Span(Strong(name), Attr(classes=["parameter-name"]))
Expand All @@ -77,7 +77,7 @@ def to_definition_list(self):
# in the table display format, not description lists....
# by this stage _required_ is basically a special token to indicate
# a required argument.
if default is not None:
if self.default is not None:
part_default_sep = Span(" = ", Attr(classes=["parameter-default-sep"]))
part_default = Span(default, Attr(classes=["parameter-default"]))
else:
Expand All @@ -100,13 +100,15 @@ def to_definition_list(self):

def to_tuple(self, style: Literal["parameters", "attributes", "returns"]):
name = self.name
description = sanitize(self.description, allow_markdown=True)

if style == "parameters":
default = "_required_" if self.default is None else escape(self.default)
return (name, self.annotation, self.description, default)
return (name, self.annotation, description, default)
elif style == "attributes":
return (name, self.annotation, self.description)
return (name, self.annotation, description)
elif style == "returns":
return (name, self.annotation, self.description)
return (name, self.annotation, description)

raise NotImplementedError(f"Unsupported table style: {style}")

Expand Down Expand Up @@ -217,7 +219,7 @@ def render_annotation(self, el: str) -> str:
el:
An object representing a type annotation.
"""
return sanitize(el)
return sanitize(el, escape_quotes=True)

@dispatch
def render_annotation(self, el: None) -> str:
Expand Down Expand Up @@ -563,6 +565,9 @@ def render(self, el: dc.Parameter):
res = f"{glob}{name}: {annotation} = {el.default}"
elif annotation:
res = f"{glob}{name}: {annotation}"
else:
res = f"{glob}{name}"

elif has_default:
res = f"{glob}{name}={el.default}"
else:
Expand Down Expand Up @@ -595,8 +600,9 @@ def render(self, el: ds.DocstringSectionParameters):
@dispatch
def render(self, el: ds.DocstringParameter) -> ParamRow:
annotation = self.render_annotation(el.annotation)
clean_desc = sanitize(el.description, allow_markdown=True)
return ParamRow(el.name, clean_desc, annotation=annotation, default=el.default)
return ParamRow(
el.name, el.description, annotation=annotation, default=el.default
)

# attributes ----

Expand All @@ -611,7 +617,7 @@ def render(self, el: ds.DocstringSectionAttributes):
def render(self, el: ds.DocstringAttribute) -> ParamRow:
return ParamRow(
el.name,
sanitize(el.description or "", allow_markdown=True),
el.description or "",
annotation=self.render_annotation(el.annotation),
)

Expand Down Expand Up @@ -680,7 +686,7 @@ def render(self, el: ds.DocstringReturn):
# similar to DocstringParameter, but no name or default
return ParamRow(
el.name,
sanitize(el.description, allow_markdown=True),
el.description,
annotation=self.render_annotation(el.annotation),
)

Expand All @@ -689,7 +695,7 @@ def render(self, el: ds.DocstringRaise) -> ParamRow:
# similar to DocstringParameter, but no name or default
return ParamRow(
None,
sanitize(el.description, allow_markdown=True),
el.description,
annotation=self.render_annotation(el.annotation),
)

Expand Down
64 changes: 34 additions & 30 deletions quartodoc/tests/__snapshots__/test_renderers.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
tests.example_signature.a_complex_signature(
x: list[C | int | None]
y: pathlib.Pathlib
z
)
```

## Parameters {.doc-section .doc-section-parameters}

| Name | Type | Description | Default |
|--------|--------------------------------------------------------------------------------------|-----------------|------------|
| x | [list](`list`)\[[C](`quartodoc.tests.example_signature.C`) \| [int](`int`) \| None\] | The x parameter | _required_ |
| y | [pathlib](`pathlib`).[Pathlib](`pathlib.Pathlib`) | The y parameter | _required_ |
| Name | Type | Description | Default |
|--------|--------------------------------------------------------------------------------------|-------------------------------|------------|
| x | [list](`list`)\[[C](`quartodoc.tests.example_signature.C`) \| [int](`int`) \| None\] | The x parameter | _required_ |
| y | [pathlib](`pathlib`).[Pathlib](`pathlib.Pathlib`) | The y parameter | _required_ |
| z | | The z parameter (unannotated) | _required_ |
'''
# ---
# name: test_render_annotations_complex_no_interlinks
Expand All @@ -26,15 +28,17 @@
tests.example_signature.a_complex_signature(
x: list[C | int | None]
y: pathlib.Pathlib
z
)
```

## Parameters {.doc-section .doc-section-parameters}

| Name | Type | Description | Default |
|--------|--------------------------|-----------------|------------|
| x | list\[C \| int \| None\] | The x parameter | _required_ |
| y | pathlib.Pathlib | The y parameter | _required_ |
| Name | Type | Description | Default |
|--------|--------------------------|-------------------------------|------------|
| x | list\[C \| int \| None\] | The x parameter | _required_ |
| y | pathlib.Pathlib | The y parameter | _required_ |
| z | | The z parameter (unannotated) | _required_ |
'''
# ---
# name: test_render_doc_class[embedded]
Expand Down Expand Up @@ -483,77 +487,77 @@
List
# Parameters {.doc-section .doc-section-parameters}

<code>[**int**]{.parameter-name} [:]{.parameter-annotation-sep} []{.parameter-annotation} [ = ]{.parameter-default-sep} [None]{.parameter-default}</code>
<code>[**int**]{.parameter-name} [:]{.parameter-annotation-sep} []{.parameter-annotation}</code>

: A description.

# Returns {.doc-section .doc-section-returns}

<code>[]{.parameter-name} [:]{.parameter-annotation-sep} [int]{.parameter-annotation} [ = ]{.parameter-default-sep} [None]{.parameter-default}</code>
<code>[]{.parameter-name} [:]{.parameter-annotation-sep} [int]{.parameter-annotation}</code>

: A description.

# Attributes {.doc-section .doc-section-attributes}

<code>[**int**]{.parameter-name} [:]{.parameter-annotation-sep} []{.parameter-annotation} [ = ]{.parameter-default-sep} [None]{.parameter-default}</code>
<code>[**int**]{.parameter-name} [:]{.parameter-annotation-sep} []{.parameter-annotation}</code>

: A description.
'''
# ---
# name: test_render_numpydoc_section_return[name: int\n A description.]
# name: test_render_numpydoc_section_return[name: int\n A `"description"`.]
'''
Code
Parameters
---
name: int
A description.
A `"description"`.

Returns
---
name: int
A description.
A `"description"`.

Attributes
---
name: int
A description.
A `"description"`.

Default
# Parameters {.doc-section .doc-section-parameters}

| Name | Type | Description | Default |
|--------|--------|----------------|------------|
| name | | A description. | _required_ |
| Name | Type | Description | Default |
|--------|--------|--------------------|------------|
| name | | A `"description"`. | _required_ |

# Returns {.doc-section .doc-section-returns}

| Name | Type | Description |
|--------|--------|----------------|
| name | int | A description. |
| Name | Type | Description |
|--------|--------|--------------------|
| name | int | A `"description"`. |

# Attributes {.doc-section .doc-section-attributes}

| Name | Type | Description |
|--------|--------|----------------|
| name | int | A description. |
| Name | Type | Description |
|--------|--------|--------------------|
| name | int | A `"description"`. |

List
# Parameters {.doc-section .doc-section-parameters}

<code>[**name**]{.parameter-name} [:]{.parameter-annotation-sep} []{.parameter-annotation} [ = ]{.parameter-default-sep} [None]{.parameter-default}</code>
<code>[**name**]{.parameter-name} [:]{.parameter-annotation-sep} []{.parameter-annotation}</code>

: A description.
: A `"description"`.

# Returns {.doc-section .doc-section-returns}

<code>[**name**]{.parameter-name} [:]{.parameter-annotation-sep} [int]{.parameter-annotation} [ = ]{.parameter-default-sep} [None]{.parameter-default}</code>
<code>[**name**]{.parameter-name} [:]{.parameter-annotation-sep} [int]{.parameter-annotation}</code>

: A description.
: A `"description"`.

# Attributes {.doc-section .doc-section-attributes}

<code>[**name**]{.parameter-name} [:]{.parameter-annotation-sep} [int]{.parameter-annotation} [ = ]{.parameter-default-sep} [None]{.parameter-default}</code>
<code>[**name**]{.parameter-name} [:]{.parameter-annotation-sep} [int]{.parameter-annotation}</code>

: A description.
: A `"description"`.
'''
# ---
4 changes: 3 additions & 1 deletion quartodoc/tests/example_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ class C:
...


def a_complex_signature(x: "list[C | int | None]", y: "pathlib.Pathlib"):
def a_complex_signature(x: "list[C | int | None]", y: "pathlib.Pathlib", z):
"""
Parameters
----------
x:
The x parameter
y:
The y parameter
z:
The z parameter (unannotated)
"""
Loading

0 comments on commit ddd25d5

Please sign in to comment.