Skip to content

Commit

Permalink
Add support for examples to typescript (#64)
Browse files Browse the repository at this point in the history
This modified the examples in a few ways:
1. One admonition per example. This is clearly necessary if the examples are
allowed to have text and not just code pens.
2. Don't insert a codepen in the jinja template. Instead, a DescriptionCode gets
a code pen and a DescriptionText or raw string does not.
  • Loading branch information
hoodmane authored Sep 25, 2023
1 parent dae27f1 commit 132f08b
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 41 deletions.
2 changes: 1 addition & 1 deletion sphinx_js/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class TopLevel:
#: Explanation of the deprecation (which implies True) or True or False
deprecated: Description | bool
#: List of preformatted textual examples
examples: list[str]
examples: Sequence[Description]
#: List of paths to also refer the reader to
see_alsos: list[str]
#: Explicitly documented sub-properties of the object, a la jsdoc's
Expand Down
6 changes: 5 additions & 1 deletion sphinx_js/jsdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
NO_DEFAULT,
Attribute,
Class,
DescriptionCode,
Exc,
Function,
Param,
Expand Down Expand Up @@ -378,7 +379,10 @@ def top_level_properties(
# class, so it gets filled out elsewhere.
line=doclet["meta"]["lineno"],
deprecated=doclet.get("deprecated", False),
examples=doclet.get("examples", []),
examples=[
[DescriptionCode("```js\n" + x + "\n```")]
for x in doclet.get("examples", [])
],
see_alsos=doclet.get("see", []),
properties=properties_to_ir(doclet.get("properties", [])),
)
Expand Down
8 changes: 4 additions & 4 deletions sphinx_js/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def render_description(self, description: Description) -> str:
start = f".. code-block:: {code_type}\n\n"
codeblock = textwrap.indent(mid, " " * 4)
end = "\n\n"
content.append(start + codeblock + end)
content.append("\n" + start + codeblock + end)
# A code pen
continue

Expand Down Expand Up @@ -389,7 +389,7 @@ def _template_vars(self, name: str, obj: Function) -> dict[str, Any]: # type: i
params=self._formal_params(obj),
fields=self._fields(obj),
description=self.render_description(obj.description),
examples=obj.examples,
examples=[self.render_description(x) for x in obj.examples],
deprecated=deprecated,
is_optional=obj.is_optional,
is_static=obj.is_static,
Expand Down Expand Up @@ -437,7 +437,7 @@ def _template_vars(self, name: str, obj: Class | Interface) -> dict[str, Any]:
name=name,
params=self._formal_params(constructor),
fields=self._fields(constructor),
examples=constructor.examples,
examples=[self.render_description(ex) for ex in constructor.examples],
deprecated=constructor.deprecated,
see_also=constructor.see_alsos,
exported_from=obj.exported_from,
Expand Down Expand Up @@ -552,7 +552,7 @@ def _template_vars(self, name: str, obj: Attribute) -> dict[str, Any]: # type:
deprecated=obj.deprecated,
is_optional=obj.is_optional,
see_also=obj.see_alsos,
examples=obj.examples,
examples=[self.render_description(ex) for ex in obj.examples],
type=self.render_type(obj.type),
content="\n".join(self._content),
)
Expand Down
12 changes: 4 additions & 8 deletions sphinx_js/templates/common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@
{% endmacro %}

{% macro examples(items) %}
{% if items -%}
.. admonition:: Example {%- if items|length > 1 -%} s {%- endif %}

{% for example in items -%}
.. code-block:: js
{% for example in items %}

{{ example|indent(6) }}
.. admonition:: Example

{% endfor %}
{%- endif %}
{{ example|indent(3) }}
{% endfor %}
{% endmacro %}

{% macro see_also(items) %}
Expand Down
4 changes: 2 additions & 2 deletions sphinx_js/typedoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ class TopLevelPropertiesDict(TypedDict):
description: Sequence[ir.DescriptionItem]
line: int | None
deprecated: Sequence[ir.DescriptionItem] | bool
examples: list[str]
examples: Sequence[ir.Description]
see_alsos: list[str]
properties: list[ir.Attribute]
exported_from: ir.Pathname | None
Expand All @@ -403,7 +403,7 @@ def _top_level_properties(self) -> TopLevelPropertiesDict:
line=self.sources[0].line if self.sources else None,
# These properties aren't supported by TypeDoc:
deprecated=deprecated,
examples=[],
examples=self.comment.get_tag_list("example"),
see_alsos=[],
properties=[],
exported_from=ir.Pathname(make_filepath_segments(self.filename)),
Expand Down
10 changes: 10 additions & 0 deletions tests/test_build_ts/source/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,13 @@ export function selfReferential(b: typeof selfReferential) {}
* @deprecated since v20!
*/
export function deprecatedFunction() {}


/**
* @example This is an example.
* @example This is another example.
* ```py
* Something python
* ```
*/
export function exampleFunction() {}
1 change: 1 addition & 0 deletions tests/test_build_ts/source/docs/example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. js:autofunction:: exampleFunction
18 changes: 18 additions & 0 deletions tests/test_build_ts/test_build_ts.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,24 @@ def test_deprecated(self):
),
)

def test_example(self):
self._file_contents_eq(
"example",
dedent(
"""\
exampleFunction()
Example:
This is an example.
Example: This is another example.
Something python
"""
),
)


class HtmlBuilderTests(SphinxBuildTestCase):
"""Tests which require an HTML build of our Sphinx tree, for checking
Expand Down
22 changes: 13 additions & 9 deletions tests/test_jsdoc_analysis/test_jsdoc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
from sphinx_js.ir import Attribute, Exc, Function, Param, Pathname, Return
from sphinx_js.ir import (
Attribute,
DescriptionCode,
Exc,
Function,
Param,
Pathname,
Return,
)
from sphinx_js.jsdoc import full_path_segments
from tests.testing import JsDocTestCase

Expand Down Expand Up @@ -105,10 +113,7 @@ def test_class(self):
15, # jsdoc 3.6.3
)
# We ignore examples and other fields from the class doclet so far. This could change someday.
assert cls.examples in (
["Example in class"], # jsdoc, 4.0.0
["Example in constructor"], # jsdoc 3.6.3
)
assert cls.examples == [[DescriptionCode(code="```js\nExample in class\n```")]]

# Members:
getter, private_method = cls.members # default constructor not included here
Expand All @@ -131,10 +136,9 @@ def test_class(self):
) # Same path as class. This might differ in different languages.
assert constructor.filename == "class.js"
assert constructor.description == "Constructor doc."
assert constructor.examples in (
["Example in class"], # jsdoc 4.0.0
["Example in constructor"], # jsdoc 3.6.3
)
assert constructor.examples == [
[DescriptionCode(code="```js\nExample in class\n```")]
]
assert constructor.params == [
Param(
name="ho",
Expand Down
68 changes: 52 additions & 16 deletions tests/test_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def test_render_description():
Code 2 has ``double ticks around it``.
Code 3 has a :sphinx:role:`before it`.
.. code-block:: js
A JS code pen!
Expand Down Expand Up @@ -279,19 +280,6 @@ def test_func_render_callouts(function_render):
Deprecated: v0.24
""",
)
assert function_render(examples=["ex1", "ex2"]) == DEFAULT_RESULT + setindent(
"""
.. admonition:: Examples
.. code-block:: js
ex1
.. code-block:: js
ex2
""",
)
assert function_render(see_alsos=["see", "this too"]) == DEFAULT_RESULT + setindent(
"""
.. seealso::
Expand Down Expand Up @@ -325,12 +313,60 @@ def test_all(function_render):
.. admonition:: Example
.. code-block:: js
ex1
ex1
.. seealso::
- :any:`see`
"""
)


def test_examples(function_render):
assert function_render(examples=["ex1", "ex2"]) == DEFAULT_RESULT + setindent(
"""
.. admonition:: Example
ex1
.. admonition:: Example
ex2
""",
)

assert function_render(
examples=[[DescriptionText(text="This is another example.\n")]]
) == DEFAULT_RESULT + setindent(
"""
.. admonition:: Example
This is another example.
"""
)

assert function_render(
examples=[
[DescriptionCode(code="```ts\nThis is an example.\n```")],
[
DescriptionText(text="This is another example.\n"),
DescriptionCode(code="```py\nSomething python\n```"),
],
]
) == DEFAULT_RESULT + setindent(
"""
.. admonition:: Example
.. code-block:: ts
This is an example.
.. admonition:: Example
This is another example.
.. code-block:: py
Something python
"""
)

0 comments on commit 132f08b

Please sign in to comment.