Skip to content

Commit 885d10a

Browse files
authored
Merge pull request #1 from d-chris/develop
pre release
2 parents 4d207e1 + 9ce8a2e commit 885d10a

File tree

8 files changed

+612
-11
lines changed

8 files changed

+612
-11
lines changed

README.md

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
# jinja2-pdoc
22

3+
[![Github](https://img.shields.io/website?url=https%3A%2F%2Fgithub.com%2Fd-chris%2Fjinja2_pdoc&logo=github&label=github)
4+
](https://www.github.com/d-chris/jinja2_pdoc)
5+
[![PyPI - License](https://img.shields.io/pypi/l/pathlibutil)](https://raw.githubusercontent.com/d-chris/jinja2_pdoc/main/LICENSE)
36
---
47

58
[`jinja2`](https://www.pypi.org/project/jinja2) extension based on [`pdoc`](https://pypi.org/project/pdoc/) to embedd python code directly from modules or files into your `jinja` template.
69

710
## Installation
811

9-
```bash
12+
```cmd
1013
pip install jinja2_pdoc
1114
```
1215

16+
## Usage
17+
18+
- [CLI](#command-line)
19+
- [Library](#library)
20+
1321
## Syntax
1422

15-
see [Example](#code) down below
1623

1724
```jinja2
1825
{% pdoc <module>::<object>:<pdoc_attr[.str_attr]> %}
1926
```
27+
see also [Example](#library)
2028

2129
### `<module>`
2230

@@ -55,27 +63,55 @@ Example:
5563
Example:
5664

5765
```jinja2
58-
{% pdoc pathlib::Path:docstring.source %}
66+
{% pdoc pathlib::Path:docstring %}
5967
```
6068

61-
### `str_attr`
69+
### `[.str_attr]`
6270

6371
optional `str` functions can be added to `<pdoc_attr>` with a dot
6472

6573
- `dedent` - removes common leading whitespace, see `textwrap.dedent`
6674
- `upper` - converts to upper case
6775
- `lower` - converts to lower case
68-
- ...
6976

7077
Example:
7178

7279
```jinja2
73-
{% pdoc pathlib::Path:docstring.dedent %}
80+
{% pdoc pathlib::Path.open:code.dedent %}
7481
```
7582

76-
## Usage
83+
## Examples
84+
85+
### Command Line
86+
87+
```cmd
88+
>>> jinja2pdoc .\examples\ --force
89+
90+
rendering.. example.md
91+
```
92+
93+
```cmd
7794
78-
### Code
95+
>>> jinja2pdoc --help
96+
97+
Usage: jinja2pdoc [OPTIONS] INPUT [OUTPUT]
98+
99+
Render jinja2 templates from a input directory or file and write to a output
100+
directory.
101+
102+
if the `input` is a directory, all files with a matching `pattern` are
103+
renderd.
104+
105+
if no `output` is given, the current working directory is used.
106+
107+
Options:
108+
-p, --pattern TEXT template search pattern for directories
109+
-f, --force overwrite existing files
110+
-n, --newline TEXT newline character
111+
--help Show this message and exit..
112+
```
113+
114+
### Library
79115

80116
python code to render a template directly from a string
81117

@@ -90,23 +126,25 @@ s = """
90126
embedd python code directly from pathlib using a jinja2 extension based on pdoc
91127
92128
## docstring from pathlib.Path
93-
{% pdoc pathlib::Path:docstring.dedent -%}
129+
130+
{% pdoc pathlib::Path:docstring %}
94131
95132
## source from pathlib.Path.open
133+
96134
```python
97135
{% pdoc pathlib::Path.open:source.dedent -%}
98136
```
99137
"""
100138

101139
code = env.from_string(textwrap.dedent(s)).render()
102140

103-
Path("jinja2_pdoc.md").write_text(code)
141+
Path("example.md").write_text(code)
104142

105143
```
106144

107145
### Result
108146

109-
output of the code above
147+
output of the [code](#library) above
110148

111149
````markdown
112150
# jinja2-pdoc

examples/example.md.jinja2

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# jinja2-pdoc
2+
3+
embedd python code directly from pathlib using a jinja2 extension based on pdoc
4+
5+
## docstring from pathlib.Path
6+
7+
{% pdoc pathlib::Path:docstring %}
8+
9+
## source from pathlib.Path.open
10+
11+
```python
12+
{% pdoc pathlib::Path.open:source.dedent -%}
13+
```

jinja2_pdoc/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import jinja2
2+
import pdoc
3+
4+
from jinja2_pdoc.extension import PdocJinja2
5+
6+
__all__ = ["PdocJinja2", "jinja2", "pdoc"]

jinja2_pdoc/cli.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from pathlib import Path
2+
from typing import Generator, Iterable, Tuple
3+
4+
import click
5+
6+
from jinja2_pdoc import PdocJinja2, jinja2
7+
8+
9+
def eof_newline(content: str, eof: str = "\n") -> str:
10+
"""
11+
make sure the file content ends with a newline if specified.
12+
"""
13+
if content.endswith(eof) or not eof:
14+
return content
15+
16+
return content + eof
17+
18+
19+
def load_files(
20+
files: Iterable[Path], out_dir: Path, force: bool
21+
) -> Generator[Tuple[str, Path], None, None]:
22+
"""
23+
iterates over files and yield `(content, out_file)` if its not existing.
24+
25+
if `force` is True, all files are proessed.
26+
"""
27+
for file in files:
28+
out = out_dir.joinpath(file.stem).resolve()
29+
30+
if not out.is_file() or force:
31+
yield (file.read_text(), out)
32+
click.echo(f"rendering.. {out}")
33+
else:
34+
click.echo(f"skip....... {out}")
35+
else:
36+
click.echo("\n......done")
37+
38+
39+
@click.command()
40+
@click.argument("input", type=click.Path(exists=True))
41+
@click.argument("output", type=click.Path(file_okay=False), default=Path.cwd())
42+
@click.option(
43+
"-p",
44+
"--pattern",
45+
default="*.jinja2",
46+
help="template search pattern for directories",
47+
)
48+
@click.option("-f", "--force", is_flag=True, help="overwrite existing files")
49+
@click.option(
50+
"-n",
51+
"--newline",
52+
default="\n",
53+
help="newline character",
54+
)
55+
def main(
56+
input: str,
57+
output: str = ".",
58+
pattern: str = "*.jinja2",
59+
force: bool = False,
60+
newline: str = "\n",
61+
) -> None:
62+
"""
63+
Render jinja2 templates from a input directory or file and
64+
write to a output directory.
65+
66+
if the `input` is a directory, all files with a matching `pattern` are renderd.
67+
68+
if no `output` is given, the current working directory is used.
69+
"""
70+
71+
env = jinja2.Environment(extensions=[PdocJinja2])
72+
73+
input = Path(input)
74+
output = Path(output)
75+
output.mkdir(parents=True, exist_ok=True)
76+
77+
if input.is_file():
78+
files = [
79+
input,
80+
]
81+
else:
82+
files = input.rglob(pattern)
83+
84+
for content, file in load_files(files, output, force):
85+
code = env.from_string(content).render()
86+
file.write_text(eof_newline(code, newline))
87+
88+
89+
if __name__ == "__main__":
90+
main()

0 commit comments

Comments
 (0)