Skip to content

Commit

Permalink
Page/global filters
Browse files Browse the repository at this point in the history
  • Loading branch information
daizutabi committed Jun 28, 2020
1 parent 749dcdd commit 80098a0
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 31 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

## [Unreleased]
### Added
- Global filters and page filters.

### Fixed
- Delete prefix in nav menu for heading mode.

## [1.0.9]
### Added
Expand Down
17 changes: 0 additions & 17 deletions docs/appendix/filter.md

This file was deleted.

15 changes: 15 additions & 0 deletions docs/examples/google_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,18 @@ In this example, note that:

* [Example Google Style Python Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google)
* [Example NumPy Style Python Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy)


## Heading Mode

The other mode to create documentation is heading. For example,

~~~markdown
## ![mkapi](google_style.ExampleClass)
~~~

create a `<h2>` tag for the `google_style.ExampleClass`.

## ![mkapi](google_style.ExampleClass)

Note that an ExampleClass item in nav menu is created.
15 changes: 15 additions & 0 deletions docs/examples/numpy_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,18 @@ In this example, note that:

* [Example Google Style Python Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google)
* [Example NumPy Style Python Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy)


## Heading Mode

The other mode to create documentation is heading. For example,

~~~markdown
## ![mkapi](numpy_style.ExampleClass)
~~~

create a `<h2>` tag for the `google_style.ExampleClass`.

## ![mkapi](numpy_style.ExampleClass)

Note that an ExampleClass item in nav menu is created.
99 changes: 99 additions & 0 deletions docs/usage/filter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Filters

<style type="text/css">
<!--
.mkapi-node {
border: 2px dashed #88AA88;
margin-left: 0px;
margin-bottom: 20px;
}
-->
</style>

{{ # cache:clear }}

```python hide
import sys

if '../../examples' not in sys.path:
sys.path.insert(0, '../../examples')
```

## List of Filters

### upper

Use upper case letters for package and module object.

~~~markdown
### ![mkapi](filter)
~~~

### ![mkapi](filter)

~~~markdown
### ![mkapi](filter|upper)
~~~

### ![mkapi](filter|upper)

### short

Remove prefix.

~~~markdown
![mkapi](filter.C)
~~~

![mkapi](filter.C)

~~~markdown
![mkapi](filter.C|short)
~~~

![mkapi](filter.C|short)


### strict

Show parameters and attributes even if their description is missing.

~~~markdown
![mkapi](filter.func|strict)
~~~

![mkapi](filter.func|strict)


## Scope of Filters

### Page Scope

For page scope filters, use empty object.

~~~markdown
![mkapi](|short)
~~~
~~~markdown
![mkapi](filter.gen)
~~~
~~~markdown
![mkapi](filter.C)
~~~

![mkapi](|short)
![mkapi](filter.gen)
![mkapi](filter.C)

### Global Scope

In `mkdocs.yaml`, select global filters:

~~~yml
# mkdocs.yml
plugins:
- search
- mkapi:
src_dirs: [examples]
filters: [short, strict]
~~~
2 changes: 1 addition & 1 deletion docs/usage/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ If you prefer upper case heading, use the `upper` filter.

## Display Members

`all` filter generates entire module documentation including class and function members. Note that Classes and Functions sections have links to the members
`all` filter generates entire module documentation including class and function members. Note that Classes and Functions sections have links to the members.

~~~
### ![mkapi](google_style|upper|all)
Expand Down
14 changes: 14 additions & 0 deletions examples/filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import Iterator


def func(x: int):
"""Function."""


def gen() -> Iterator[int]:
"""Generator."""
yield 1


class C:
"""Class."""
2 changes: 1 addition & 1 deletion mkapi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.0.9"
__version__ = "1.0.10"

from mkapi.core.module import get_module
from mkapi.core.node import get_node
Expand Down
18 changes: 15 additions & 3 deletions mkapi/core/page.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""This module provides a Page class that works with other converter."""
import re
from dataclasses import InitVar, dataclass, field
from typing import Iterator, List, Union
from typing import Iterator, List, Tuple, Union

from mkapi import utils
from mkapi.core import postprocess
Expand Down Expand Up @@ -30,8 +30,12 @@ class Page:
source: InitVar[str]
abs_src_path: str
abs_api_paths: List[str] = field(default_factory=list, repr=False)
filters: List[str] = field(default_factory=list, repr=False)
markdown: str = field(init=False, repr=False)
nodes: List[Union[Node, Code]] = field(default_factory=list, init=False, repr=False)
headings: List[Tuple[int, str]] = field(
default_factory=list, init=False, repr=False
)

def __post_init__(self, source):
self.markdown = "\n\n".join(self.split(source))
Expand All @@ -47,15 +51,21 @@ def resolve_link_from_base(self, base: Base):
def split(self, source: str) -> Iterator[str]:
cursor = 0
callback = self.resolve_link_from_base
for index, match in enumerate(MKAPI_PATTERN.finditer(source)):
index = 0
for match in MKAPI_PATTERN.finditer(source):
start, end = match.start(), match.end()
if cursor < start:
markdown = source[cursor:start].strip()
if markdown:
yield self.resolve_link(markdown)
cursor = end
heading, name = match.groups()
level = len(heading)
name, filters = utils.split_filters(name)
if not name:
self.filters = filters
continue
filters = utils.update_filters(self.filters, filters)
if "code" in filters:
code = get_code(name)
self.nodes.append(code)
Expand All @@ -66,8 +76,10 @@ def split(self, source: str) -> Iterator[str]:
postprocess.transform(node, filters)
self.nodes.append(node)
markdown = node.get_markdown(level, callback=callback)
if level:
self.headings.append((level, node.object.id))
yield node_markdown(index, markdown, filters)
cursor = end
index += 1
if cursor < len(source):
markdown = source[cursor:].strip()
if markdown:
Expand Down
9 changes: 6 additions & 3 deletions mkapi/plugins/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
logger = logging.getLogger("mkdocs")


def create_nav(config):
def create_nav(config, global_filters):
nav = config["nav"]
docs_dir = config["docs_dir"]
config_dir = os.path.dirname(config["config_file_path"])
Expand All @@ -20,12 +20,14 @@ def create_nav(config):
if isinstance(page, dict):
for key, value in page.items():
if isinstance(value, str) and value.startswith("mkapi/"):
page[key], abs_api_paths_ = collect(value, docs_dir, config_dir)
page[key], abs_api_paths_ = collect(
value, docs_dir, config_dir, global_filters
)
abs_api_paths.extend(abs_api_paths_)
return config, abs_api_paths


def collect(path: str, docs_dir: str, config_dir) -> Tuple[list, list]:
def collect(path: str, docs_dir: str, config_dir, global_filters) -> Tuple[list, list]:
_, api_path, *paths, package_path = path.split("/")
abs_api_path = os.path.join(docs_dir, api_path)
if os.path.exists(abs_api_path):
Expand All @@ -40,6 +42,7 @@ def collect(path: str, docs_dir: str, config_dir) -> Tuple[list, list]:
sys.path.insert(0, root)

package_path, filters = utils.split_filters(package_path)
filters = utils.update_filters(global_filters, filters)

module = get_module(package_path)
nav = []
Expand Down
16 changes: 12 additions & 4 deletions mkapi/plugins/mkdocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class MkapiPlugin(BasePlugin):
config_scheme = (
("src_dirs", config_options.Type(list, default=[])),
("on_config", config_options.Type(str, default="")),
("filters", config_options.Type(list, default=[])),
("callback", config_options.Type(str, default="")),
)
server = None
Expand All @@ -46,7 +47,9 @@ def on_config(self, config):
self.pages = {}
self.abs_api_paths = []
if not self.server:
config, self.abs_api_paths = mkapi.plugins.api.create_nav(config)
config, self.abs_api_paths = mkapi.plugins.api.create_nav(
config, self.config["filters"]
)
global_config["config"] = config
global_config["abs_api_paths"] = self.abs_api_paths
else:
Expand Down Expand Up @@ -109,7 +112,9 @@ def on_page_markdown(self, markdown, page, config, files):
"""Converts Markdown source to intermidiate version."""
abs_src_path = page.file.abs_src_path
clean_page_title(page)
page = Page(markdown, abs_src_path, self.abs_api_paths)
page = Page(
markdown, abs_src_path, self.abs_api_paths, filters=self.config["filters"]
)
self.pages[abs_src_path] = page
return page.markdown

Expand All @@ -125,6 +130,9 @@ def on_page_context(self, context, page, config, nav):
abs_src_path = page.file.abs_src_path
if abs_src_path in self.abs_api_paths:
clear_prefix(page.toc, 2)
else:
for level, id in self.pages[abs_src_path].headings:
clear_prefix(page.toc, level, id)
return context

def on_serve(self, server, config, builder):
Expand All @@ -135,9 +143,9 @@ def on_serve(self, server, config, builder):
return server


def clear_prefix(toc, level: int):
def clear_prefix(toc, level: int, id: str = ""):
for toc_item in toc:
if toc_item.level >= level:
if toc_item.level >= level and (not id or toc_item.title == id):
toc_item.title = toc_item.title.split(".")[-1]
clear_prefix(toc_item.children, level)
return
Expand Down
28 changes: 27 additions & 1 deletion mkapi/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import importlib
from typing import Any
from typing import Any, List


def get_indent(line: str) -> int:
Expand Down Expand Up @@ -57,9 +57,35 @@ def split_filters(name):
('a.b.c', [])
>>> split_filters("a.b.c|upper|strict")
('a.b.c', ['upper', 'strict'])
>>> split_filters("|upper|strict")
('', ['upper', 'strict'])
>>> split_filters("")
('', [])
"""
index = name.find("|")
if index == -1:
return name, []
name, filters = name[:index], name[index + 1 :]
return name, filters.split("|")


def update_filters(org: List[str], update: List[str]) -> List[str]:
"""
Examples:
>>> update_filters(['upper'], ['lower'])
['lower']
>>> update_filters(['lower'], ['upper'])
['upper']
>>> update_filters(['long'], ['short'])
['short']
>>> update_filters(['short'], ['long'])
['long']
"""
filters = org + update
for x, y in [["lower", "upper"], ["long", "short"]]:
if x in org and y in update:
del filters[filters.index(x)]
if y in org and x in update:
del filters[filters.index(y)]

return filters
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ nav:
- usage/module.md
- usage/inherit.md
- usage/page.md
- usage/filter.md
- usage/library.py
- usage/custom.md
- Appendix:
Expand All @@ -41,7 +42,6 @@ nav:
- appendix/inherit.md
- appendix/order.md
- appendix/decorator.md
- appendix/filter.md
- API: mkapi/api/mkapi|upper|strict

markdown_extensions:
Expand Down

0 comments on commit 80098a0

Please sign in to comment.