Skip to content

Commit 5a645ab

Browse files
authored
Support for mdx (#64)
1 parent 264da1a commit 5a645ab

File tree

4 files changed

+77
-30
lines changed

4 files changed

+77
-30
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[metadata]
2-
description-file = README.md
2+
description_file = README.md
33
license_files = LICENSE
44

55
[bdist_wheel]

src/lazydocs/_about.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Information about this library. This file will automatically changed."""
22

3-
__version__ = "0.5.0-dev.bugfix"
3+
__version__ = "0.5.1"
44
# __author__
55
# __email__

src/lazydocs/_cli.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ def generate(
4242
False,
4343
help="If `True`, validate the docstrings via pydocstyle. Requires pydocstyle to be installed.",
4444
),
45+
output_format: Optional[str] = typer.Option(
46+
None,
47+
help="The output format for the creation of the markdown files. This may be 'md' or 'mdx'. Defaults to md.",
48+
)
49+
4550
) -> None:
4651
"""Generates markdown documentation for your Python project based on Google-style docstrings."""
4752

@@ -52,6 +57,7 @@ def generate(
5257
src_base_url=src_base_url,
5358
remove_package_prefix=remove_package_prefix,
5459
ignored_modules=ignored_modules,
60+
output_format=output_format,
5561
overview_file=overview_file,
5662
watermark=watermark,
5763
validate=validate,

src/lazydocs/generation.py

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
<a href="{path}"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square" /></a>
3333
"""
3434

35+
_MDX_SOURCE_BADGE_TEMPLATE = """
36+
<a href="{path}"><img align="right" style={{{{"float":"right"}}}} src="https://img.shields.io/badge/-source-cccccc?style=flat-square" /></a>
37+
"""
38+
3539
_SEPARATOR = """
3640
---
3741
"""
@@ -200,6 +204,7 @@ def to_md_file(
200204
out_path: str = ".",
201205
watermark: bool = True,
202206
disable_markdownlint: bool = True,
207+
is_mdx: bool = False
203208
) -> None:
204209
"""Creates an API docs file from a provided text.
205210
@@ -215,8 +220,13 @@ def to_md_file(
215220
return
216221

217222
md_file = filename
218-
if not filename.endswith(".md"):
219-
md_file = filename + ".md"
223+
224+
if is_mdx:
225+
if not filename.endswith(".mdx"):
226+
md_file = filename + ".mdx"
227+
else:
228+
if not filename.endswith(".md"):
229+
md_file = filename + ".md"
220230

221231
if disable_markdownlint:
222232
markdown_str = "<!-- markdownlint-disable -->\n" + markdown_str
@@ -521,7 +531,7 @@ def _get_src_path(self, obj: Any, append_base: bool = True) -> str:
521531

522532
return relative_path
523533

524-
def func2md(self, func: Callable, clsname: str = "", depth: int = 3) -> str:
534+
def func2md(self, func: Callable, clsname: str = "", depth: int = 3, is_mdx: bool = False) -> str:
525535
"""Takes a function (or method) and generates markdown docs.
526536
527537
Args:
@@ -602,11 +612,14 @@ def func2md(self, func: Callable, clsname: str = "", depth: int = 3) -> str:
602612
)
603613

604614
if path:
605-
markdown = _SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
615+
if is_mdx:
616+
markdown = _MDX_SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
617+
else:
618+
markdown = _SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
606619

607620
return markdown
608621

609-
def class2md(self, cls: Any, depth: int = 2) -> str:
622+
def class2md(self, cls: Any, depth: int = 2, is_mdx: bool = False) -> str:
610623
"""Takes a class and creates markdown text to document its methods and variables.
611624
612625
Args:
@@ -646,7 +659,7 @@ def class2md(self, cls: Any, depth: int = 2) -> str:
646659
hasattr(cls.__init__, "__module__")
647660
and cls.__init__.__module__ == modname
648661
):
649-
init = self.func2md(cls.__init__, clsname=clsname)
662+
init = self.func2md(cls.__init__, clsname=clsname, is_mdx=is_mdx)
650663
else:
651664
init = ""
652665
except (ValueError, TypeError):
@@ -698,7 +711,7 @@ def class2md(self, cls: Any, depth: int = 2) -> str:
698711
# object module should be the same as the calling module
699712
and obj.__module__ == modname
700713
):
701-
function_md = self.func2md(obj, clsname=clsname, depth=depth + 1)
714+
function_md = self.func2md(obj, clsname=clsname, depth=depth + 1, is_mdx=is_mdx)
702715
if function_md:
703716
methods.append(_SEPARATOR + function_md)
704717

@@ -713,11 +726,14 @@ def class2md(self, cls: Any, depth: int = 2) -> str:
713726
)
714727

715728
if path:
716-
markdown = _SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
729+
if is_mdx:
730+
markdown = _MDX_SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
731+
else:
732+
markdown = _SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
717733

718734
return markdown
719735

720-
def module2md(self, module: types.ModuleType, depth: int = 1) -> str:
736+
def module2md(self, module: types.ModuleType, depth: int = 1, is_mdx: bool = False) -> str:
721737
"""Takes an imported module object and create a Markdown string containing functions and classes.
722738
723739
Args:
@@ -758,7 +774,7 @@ def module2md(self, module: types.ModuleType, depth: int = 1) -> str:
758774
and hasattr(obj, "__module__")
759775
and obj.__module__ == modname
760776
):
761-
class_markdown = self.class2md(obj, depth=depth + 1)
777+
class_markdown = self.class2md(obj, depth=depth + 1, is_mdx=is_mdx)
762778
if class_markdown:
763779
classes.append(_SEPARATOR + class_markdown)
764780
line_nos.append(_get_line_no(obj) or 0)
@@ -774,7 +790,7 @@ def module2md(self, module: types.ModuleType, depth: int = 1) -> str:
774790
and hasattr(obj, "__module__")
775791
and obj.__module__ == modname
776792
):
777-
function_md = self.func2md(obj, depth=depth + 1)
793+
function_md = self.func2md(obj, depth=depth + 1, is_mdx=is_mdx)
778794
if function_md:
779795
functions.append(_SEPARATOR + function_md)
780796
line_nos.append(_get_line_no(obj) or 0)
@@ -808,11 +824,14 @@ def module2md(self, module: types.ModuleType, depth: int = 1) -> str:
808824
)
809825

810826
if path:
811-
markdown = _SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
827+
if (is_mdx):
828+
markdown = _MDX_SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
829+
else:
830+
markdown = _SOURCE_BADGE_TEMPLATE.format(path=path) + markdown
812831

813832
return markdown
814833

815-
def import2md(self, obj: Any, depth: int = 1) -> str:
834+
def import2md(self, obj: Any, depth: int = 1, is_mdx: bool = False) -> str:
816835
"""Generates markdown documentation for a selected object/import.
817836
818837
Args:
@@ -823,16 +842,16 @@ def import2md(self, obj: Any, depth: int = 1) -> str:
823842
str: Markdown documentation of selected object.
824843
"""
825844
if inspect.isclass(obj):
826-
return self.class2md(obj, depth=depth)
845+
return self.class2md(obj, depth=depth, is_mdx=is_mdx)
827846
elif isinstance(obj, types.ModuleType):
828-
return self.module2md(obj, depth=depth)
847+
return self.module2md(obj, depth=depth, is_mdx=is_mdx)
829848
elif callable(obj):
830-
return self.func2md(obj, depth=depth)
849+
return self.func2md(obj, depth=depth, is_mdx=is_mdx)
831850
else:
832851
print(f"Could not generate markdown for object type {str(type(obj))}")
833852
return ""
834853

835-
def overview2md(self) -> str:
854+
def overview2md(self, is_mdx: bool = False) -> str:
836855
"""Generates a documentation overview file based on the generated docs."""
837856

838857
entries_md = ""
@@ -841,7 +860,10 @@ def overview2md(self) -> str:
841860
):
842861
full_name = obj["full_name"]
843862
if "module" in obj:
844-
link = "./" + obj["module"] + ".md#" + obj["anchor_tag"]
863+
if is_mdx:
864+
link = "./" + obj["module"] + ".mdx#" + obj["anchor_tag"]
865+
else:
866+
link = "./" + obj["module"] + ".md#" + obj["anchor_tag"]
845867
else:
846868
link = "#unknown"
847869

@@ -857,7 +879,10 @@ def overview2md(self) -> str:
857879
for obj in list(filter(lambda d: d["type"] == "class", self.generated_objects)):
858880
module_name = obj["module"].split(".")[-1]
859881
name = module_name + "." + obj["full_name"]
860-
link = "./" + obj["module"] + ".md#" + obj["anchor_tag"]
882+
if is_mdx:
883+
link = "./" + obj["module"] + ".mdx#" + obj["anchor_tag"]
884+
else:
885+
link = "./" + obj["module"] + ".md#" + obj["anchor_tag"]
861886
description = obj["description"]
862887
entries_md += f"\n- [`{name}`]({link})"
863888
if description:
@@ -872,7 +897,10 @@ def overview2md(self) -> str:
872897
):
873898
module_name = obj["module"].split(".")[-1]
874899
name = module_name + "." + obj["full_name"]
875-
link = "./" + obj["module"] + ".md#" + obj["anchor_tag"]
900+
if is_mdx:
901+
link = "./" + obj["module"] + ".mdx#" + obj["anchor_tag"]
902+
else:
903+
link = "./" + obj["module"] + ".md#" + obj["anchor_tag"]
876904
description = obj["description"]
877905
entries_md += f"\n- [`{name}`]({link})"
878906
if description:
@@ -893,6 +921,7 @@ def generate_docs(
893921
src_base_url: Optional[str] = None,
894922
remove_package_prefix: bool = False,
895923
ignored_modules: Optional[List[str]] = None,
924+
output_format: Optional[str] = None,
896925
overview_file: Optional[str] = None,
897926
watermark: bool = True,
898927
validate: bool = False,
@@ -919,6 +948,10 @@ def generate_docs(
919948
if not ignored_modules:
920949
ignored_modules = list()
921950

951+
if output_format and output_format != 'md' and output_format != 'mdx':
952+
raise Exception(f"Unsupported output format: {output_format}. Choose either 'md' or 'mdx'.")
953+
is_mdx = output_format == 'mdx'
954+
922955
if not src_root_path:
923956
try:
924957
# Set src root path to git root
@@ -967,7 +1000,7 @@ def generate_docs(
9671000
try:
9681001
mod_spec = loader.find_spec(module_name)
9691002
mod = importlib.util.module_from_spec(mod_spec)
970-
module_md = generator.module2md(mod)
1003+
module_md = generator.module2md(mod, is_mdx=is_mdx)
9711004
if not module_md:
9721005
# Module md is empty -> ignore module and all submodules
9731006
# Add module to ignore list, so submodule will also be ignored
@@ -982,6 +1015,7 @@ def generate_docs(
9821015
mod.__name__,
9831016
out_path=output_path,
9841017
watermark=watermark,
1018+
is_mdx=is_mdx,
9851019
)
9861020
except Exception as ex:
9871021
print(
@@ -1005,7 +1039,7 @@ def generate_docs(
10051039
spec.loader.exec_module(mod) # type: ignore
10061040

10071041
if mod:
1008-
module_md = generator.module2md(mod)
1042+
module_md = generator.module2md(mod, is_mdx=is_mdx)
10091043
if stdout_mode:
10101044
print(module_md)
10111045
else:
@@ -1014,6 +1048,7 @@ def generate_docs(
10141048
module_name,
10151049
out_path=output_path,
10161050
watermark=watermark,
1051+
is_mdx=is_mdx,
10171052
)
10181053
else:
10191054
raise Exception(f"Failed to generate markdown for {path}")
@@ -1044,7 +1079,7 @@ def generate_docs(
10441079
try:
10451080
mod_spec = loader.find_spec(module_name)
10461081
mod = importlib.util.module_from_spec(mod_spec)
1047-
module_md = generator.module2md(mod)
1082+
module_md = generator.module2md(mod, is_mdx=is_mdx)
10481083

10491084
if not module_md:
10501085
# Module MD is empty -> ignore module and all submodules
@@ -1060,32 +1095,38 @@ def generate_docs(
10601095
mod.__name__,
10611096
out_path=output_path,
10621097
watermark=watermark,
1098+
is_mdx=is_mdx
10631099
)
10641100
except Exception as ex:
10651101
print(
10661102
f"Failed to generate docs for module {module_name}: "
10671103
+ repr(ex)
10681104
)
10691105
else:
1070-
import_md = generator.import2md(obj)
1106+
import_md = generator.import2md(obj, is_mdx=is_mdx)
10711107
if stdout_mode:
10721108
print(import_md)
10731109
else:
10741110
to_md_file(
1075-
import_md, path, out_path=output_path, watermark=watermark
1111+
import_md, path, out_path=output_path, watermark=watermark, is_mdx=is_mdx
10761112
)
10771113
else:
10781114
raise Exception(f"Failed to generate markdown for {path}.")
10791115

10801116
if overview_file and not stdout_mode:
1081-
if not overview_file.endswith(".md"):
1082-
overview_file = overview_file + ".md"
1117+
if is_mdx:
1118+
if not overview_file.endswith(".mdx"):
1119+
overview_file = overview_file + ".mdx"
1120+
else:
1121+
if not overview_file.endswith(".md"):
1122+
overview_file = overview_file + ".md"
10831123

10841124
to_md_file(
1085-
generator.overview2md(),
1125+
generator.overview2md(is_mdx=is_mdx),
10861126
overview_file,
10871127
out_path=output_path,
10881128
watermark=watermark,
1129+
is_mdx=is_mdx
10891130
)
10901131

10911132
# Write mkdocs pages file

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy