Skip to content

Commit 65d343d

Browse files
committed
feat(generation): add markdown output of documentation
1 parent 6ba890b commit 65d343d

34 files changed

+311
-115
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212

1313
steps:
1414
- name: Checkout
15-
uses: actions/checkout@v2
15+
uses: actions/checkout@v4
1616

1717
- name: Checkout std
1818
uses: actions/checkout@v2

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ python3 -m arkdoc --help
2828

2929
- `@brief <description>`: a single brief declaration is expected
3030
- `@param <name> <description>`: multiple `@param` declaration can be written
31-
- `@details <description>`: a single detailled declaration is expected
31+
- `@details <description>`: a single detailed declaration is expected
3232
- `=begin` / code block / `=end`: a single code block (it can contain multiple lines) is expected
3333
- `@author <url>,<url>,...`: the url to the profiles of the authors must be separated by commas, spaces can be added
34-
- any line not starting with a `@<keyword>` will be ignored, unless it is enclosed in a `=begin`/`=end` bloc
34+
- any line not starting with a `@<keyword>` will be ignored, unless it is enclosed in a `=begin`/`=end` block
3535

3636
## Example
3737

@@ -44,18 +44,15 @@ python3 -m arkdoc --help
4444
# (import "List.ark")
4545
# (let collection [1 2 5 12])
4646
# (list:forEach collection (fun (element) {
47-
# (print element)
48-
# }))
47+
# (print element) }))
4948
# =end
5049
# @author https://github.com/SuperFola
5150
(let list:forEach (fun (_L _func) {
5251
(mut _index 0)
5352
(while (< _index (len _L)) {
5453
(mut _element (@ _L _index))
5554
(_func _element)
56-
(set _index (+ 1 _index))
57-
})
58-
}))
55+
(set _index (+ 1 _index)) })}))
5956
```
6057

6158
## The project architecture

arkdoc/__main__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from . import logger
1010
from .logger_utils import LogLevel
1111
from .reader import parse_all_in
12-
from .generator import HTMLGenerator
12+
from .generator import HTMLGenerator, MDGenerator
1313

1414

1515
EXIT_SUCCESS = 0
@@ -58,7 +58,7 @@ def compute(args) -> bool:
5858
prefix = os.path.splitext(os.path.basename(p.filename))[0].lower()
5959
for doc in p.extract_documentation():
6060
if doc.source == Source.ArkScript:
61-
kw, name, *args = doc.signature()
61+
kw, name, args = doc.signature()
6262
if kw == "$" or kw == "macro":
6363
# macro! (handling both $ and macro for retro compatibility for now (21/05/2025))
6464
functions.append(name)
@@ -74,6 +74,9 @@ def compute(args) -> bool:
7474
if args.html:
7575
gen = HTMLGenerator(parsers, args.html, args.ark_version, args.root_dir)
7676
gen()
77+
elif args.markdown:
78+
gen = MDGenerator(parsers, args.markdown, args.ark_version, args.root_dir)
79+
gen()
7780
else:
7881
logger.error("Missing generator!")
7982
return False
@@ -98,6 +101,7 @@ def main() -> int:
98101
help="Extract only the function names, print them on separate lines and exit",
99102
)
100103
cli.add_argument("--html", type=str, help="Output folder for the HTML docs")
104+
cli.add_argument("--markdown", type=str, help="Output folder for the Markdown docs")
101105
cli.add_argument(
102106
"--root-dir", type=str, default="", help="The root dir for the links"
103107
)

arkdoc/generator/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22

33
from . import specification
44
from .utils import documentation_to_specification
5+
from .formatter import Formatter
56
from .base import Generator
67
from .html import HTMLGenerator
8+
from .markdown import MDGenerator

arkdoc/generator/base.py

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@
55
from typing import List
66
from pathlib import Path
77

8-
from . import specification as spec
8+
from . import specification as spec, Formatter
99
from . import documentation_to_specification
1010
from .. import logger
1111
from ..parser import Parser
1212

1313

1414
class Generator:
1515
def __init__(
16-
self,
17-
parsers: List[Parser],
18-
template_folder: Path,
19-
pattern: str,
20-
output: str,
21-
ark_version: str,
22-
root: str,
16+
self,
17+
parsers: List[Parser],
18+
template_folder: Path,
19+
formatter: Formatter,
20+
pattern: str,
21+
output: str,
22+
ark_version: str,
23+
root: str,
2324
):
2425
self.template_folder = template_folder
26+
self.formatter = formatter
2527
self.templates = {
2628
file.name: file.read_text("utf-8") for file in template_folder.glob(pattern)
2729
}
@@ -54,6 +56,51 @@ def _create_files_list(self, parsers: List[Parser]):
5456
def generate_index(self):
5557
raise NotImplementedError
5658

59+
def generate_sections(self, functions: List[spec.Function], with_hr: bool=False):
60+
sections = ""
61+
62+
for func in functions:
63+
authors = (
64+
self.formatter.div(
65+
self.formatter.h4(self.formatter.plural("Author", len(func.desc.authors))),
66+
", ".join(
67+
[self.formatter.a(f"@{a.split('/')[-1]}", a) for a in func.desc.authors]
68+
),
69+
)
70+
if func.desc.authors
71+
else ""
72+
)
73+
parameters = (
74+
self.formatter.div(
75+
self.formatter.h4(self.formatter.plural("Parameter", len(func.desc.params))),
76+
self.formatter.ul(
77+
[
78+
f"{self.formatter.inline_code(p.name)}: {p.desc}"
79+
for p in func.desc.params
80+
]
81+
),
82+
)
83+
if func.desc.params
84+
else ""
85+
)
86+
content = self.formatter.div(
87+
self.formatter.div(self.formatter.inline_code(func.signature)),
88+
self.formatter.div(func.desc.brief),
89+
self.formatter.new_line(),
90+
self.formatter.div(self.formatter.b("Note"), ": ", func.desc.details) if func.desc.details else "",
91+
parameters,
92+
authors,
93+
)
94+
if func.desc.code:
95+
content += self.formatter.div(self.formatter.h4("Example"), self.formatter.code(func.desc.code))
96+
sections += self.formatter.section(
97+
func.name,
98+
(self.formatter.hr() if with_hr else "") + content,
99+
anchor=self.formatter.anchorize(func.name)
100+
)
101+
102+
return sections
103+
57104
def generate_one(self, path: str, functions: List[spec.Function]):
58105
raise NotImplementedError
59106

arkdoc/generator/formatter.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from typing import List
2+
3+
4+
class Formatter:
5+
def plural(self, name: str, qu: int) -> str:
6+
return f"{name}{'s' if qu > 1 else ''}"
7+
8+
def anchorize(self, name: str) -> str:
9+
return name.lower().replace(" ", "-")
10+
11+
def nav_item(self, name: str, anchor: str) -> str:
12+
raise NotImplementedError
13+
14+
def a(self, name: str, path: str) -> str:
15+
raise NotImplementedError
16+
17+
def b(self, content: str) -> str:
18+
raise NotImplementedError
19+
20+
def inline_code(self, content: str) -> str:
21+
raise NotImplementedError
22+
23+
def code(self, content: str) -> str:
24+
raise NotImplementedError
25+
26+
def section(self, title: str, content: str, anchor: str = "") -> str:
27+
raise NotImplementedError
28+
29+
def ul(self, content: List[str]) -> str:
30+
raise NotImplementedError
31+
32+
def div(self, *args: str) -> str:
33+
raise NotImplementedError
34+
35+
def h1(self, name: str) -> str:
36+
raise NotImplementedError
37+
38+
def h2(self, name: str) -> str:
39+
raise NotImplementedError
40+
41+
def h3(self, name: str) -> str:
42+
raise NotImplementedError
43+
44+
def h4(self, name: str) -> str:
45+
raise NotImplementedError
46+
47+
def hr(self) -> str:
48+
raise NotImplementedError
49+
50+
def new_line(self) -> str:
51+
raise NotImplementedError

0 commit comments

Comments
 (0)