Skip to content

Commit

Permalink
✨ 增加github'跳转功能
Browse files Browse the repository at this point in the history
  • Loading branch information
snowykami committed Aug 30, 2024
1 parent e927545 commit a36606a
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 22 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ litedoc <your_module_path> -o|--output <output_path>
-t|--theme: "vitepress" 主题,支持vitepress, vuepress, 默认vitepress
-s|--style: "google" 风格,支持google, numpy, reStructuredText, 默认google,但目前只实现了google,欢迎PR
-f|--frontmatter: #是否生成frontmatter,即文档的元数据,如title, description等, 格式为key1=value1,key2=value2, 空格用%20代替
-fd|--function_define: "func" 函数定义风格,输出的markdown显示的函数定义,Python原生为def
-md|--method_define: "method" 方法定义风格,输出的markdown显示的方法定义
-cd|--class_define: "class" 类定义风格,输出的markdown显示的类定义
-vd|--var_define: "var" 变量定义风格,输出的markdown显示的变量定义
-ad|--attr_define: "attr" 属性定义风格,输出的markdown显示的属性定义
-b|--base-url: "" 基础URL,用于生成文档中的跳转链接,通常指向Github仓库下的包路径根目录,
如果为空字符串将不生成,末尾带/,例如https://github.com/snowykami/mbcp/tree/main/mbcp/
-fd|--function-define: "func" 函数定义风格,输出的markdown显示的函数定义,Python原生为def
-md|--method-define: "method" 方法定义风格,输出的markdown显示的方法定义
-cd|--class-define: "class" 类定义风格,输出的markdown显示的类定义
-vd|--var-define: "var" 变量定义风格,输出的markdown显示的变量定义
-ad|--attr-define: "attr" 属性定义风格,输出的markdown显示的属性定义
-c|--contain-top # 是否包含顶部文件夹信息,即在输出目录再套一层module_path的basedir
-cs|--create_same # 是否在包下创建和包名相同的md文件储存__init__文件的内容(有同名文件时请勿使用,例如client/client.py)
-cs|--create-same # 是否在包下创建和包名相同的md文件储存__init__文件的内容(有同名文件时请勿使用,例如client/client.py)
```

在输出的目录下markdown文档是以模块原有的目录结构生成的,可以直接把输出内容放到目前主流的文档框架项目中,如VuePress,VitePress等,如果想优化用户体验,还可启用动态侧边栏
Expand Down
32 changes: 23 additions & 9 deletions litedoc/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,19 @@ def main():
parser = argparse.ArgumentParser(description="Generate documentation from Python modules.")
parser.add_argument("path", type=str, help="Path to the Python module or package.")
parser.add_argument("-o", "--output", default="doc-output", type=str, help="Output directory.")
parser.add_argument("-c", "--contain_top", action="store_true", help="Whether to contain top-level dir in output dir.")
parser.add_argument("-cs", "--create_same", action="store_true", help="Create same file with folder name")
parser.add_argument("-c", "--contain-top", action="store_true", help="Whether to contain top-level dir in output dir.")
parser.add_argument("-cs", "--create-same", action="store_true", help="Create same file with folder name")
parser.add_argument("-bu", "--base-url", default=None, type=str, help="base url of the document.")
parser.add_argument("-l", "--lang", default="zh_Hans", type=str, help="Languages of the document.")
parser.add_argument("-t", "--theme", default="vitepress", type=str, help="Theme of the document.")
parser.add_argument("-s", "--style", default="google", type=str, help="Style of the document.")
parser.add_argument("-f", "--frontmatter", default=None, type=str, help="Frontmatter of the document.")

parser.add_argument("-fd", "--function_define", default="func", type=str, help="Function define of the document.")
parser.add_argument("-md", "--method_define", default="method", type=str, help="Class function define of the document.")
parser.add_argument("-cd", "--class_define", default="class", type=str, help="Class define of the document.")
parser.add_argument("-vd", "--var_define", default="var", type=str, help="Variable define of the document.")
parser.add_argument("-ad", "--attr_define", default="attr", type=str, help="Attribute define of the document.")
parser.add_argument("-fd", "--function-define", default="func", type=str, help="Function define of the document.")
parser.add_argument("-md", "--method-define", default="method", type=str, help="Class function define of the document.")
parser.add_argument("-cd", "--class-define", default="class", type=str, help="Class define of the document.")
parser.add_argument("-vd", "--var-define", default="var", type=str, help="Variable define of the document.")
parser.add_argument("-ad", "--attr-define", default="attr", type=str, help="Attribute define of the document.")
# frontmatter 输入格式为 key1=value1,key2=value2, 空格用%20代替

args = parser.parse_args()
Expand All @@ -58,8 +59,21 @@ def main():
else:
frontmatter = None

generate_from_module(args.path, args.output, with_top=args.contain_top, lang=lang, theme=args.theme, style=args.style, frontmatter=frontmatter,
fd=args.function_define, md=args.method_define, cd=args.class_define, vd=args.var_define, ad=args.attr_define, cs=args.create_same)
generate_from_module(
args.path, args.output,
with_top=args.contain_top,
lang=lang,
theme=args.theme,
style=args.style,
frontmatter=frontmatter,
fd=args.function_define,
md=args.method_define,
cd=args.class_define,
vd=args.var_define,
ad=args.attr_define,
cs=args.create_same,
bu=args.base_url
)


if __name__ == '__main__':
Expand Down
4 changes: 4 additions & 0 deletions litedoc/i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"src" : "Source code",
"desc" : "Description",
"type" : "Type",
"view_on_github": "View on GitHub",
},
"zh-Hans": {
"docstring": {
Expand All @@ -33,6 +34,7 @@
"src" : "源代码",
"desc" : "说明",
"type" : "类型",
"view_on_github": "在GitHub上查看",
},
"zh-Hant": {
"docstring": {
Expand All @@ -46,6 +48,7 @@
"src" : "源碼",
"desc" : "説明",
"type" : "類型",
"view_on_github": "在GitHub上查看",
},
"ja" : {
"docstring": {
Expand All @@ -59,6 +62,7 @@
"src" : "ソースコード",
"desc" : "説明",
"type" : "タイプ",
"view_on_github": "GitHubで表示",
},
} # @litedoc-hide

Expand Down
2 changes: 1 addition & 1 deletion litedoc/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def generate_from_module(module_folder: str,
.replace(".py", "")
.replace(".__init__", ""))
# 获取模块信息
ast_parser = AstParser(open(pyfile_path, "r", encoding="utf-8").read(), title=title, style=style)
ast_parser = AstParser(open(pyfile_path, "r", encoding="utf-8").read(), title=title, style=style, file_path=no_module_name_pyfile_path)
# 生成markdown
config_front_matter = {
"title": title,
Expand Down
14 changes: 11 additions & 3 deletions litedoc/syntax/astparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@


class AstParser:
def __init__(self, code: str, title: Optional[str] = None, style: str = "google"):
def __init__(self, code: str, title: Optional[str] = None, style: str = "google", file_path: Optional[str] = None):
"""
从一个文件的代码解析AST
Args:
code: 代码
style: 注释风格
title: 模块标题
file_path: Python文件路径
"""
self.style = style
self.code = code
self.tree = ast.parse(code)
self.title = title
"""模块标题, 通常位于文件开头的单行注释, 会被解析为h1"""

self.file_path = file_path

self.description = parse(ast.get_docstring(self.tree), parser=self.style) if ast.get_docstring(self.tree) else None
"""模块描述, 通常位于文件开头的多行注释"""
self.classes: list[ClassNode] = []
Expand Down Expand Up @@ -151,7 +155,9 @@ def parse(self):
decorators=[ast.unparse(decorator).strip() for decorator in sub_node.decorator_list],
is_async=isinstance(sub_node, ast.AsyncFunctionDef),
src=ast.unparse(sub_node).strip(),
is_classmethod=True
is_classmethod=True,
lineno=sub_node.lineno,
module_file_path=self.file_path
))
elif isinstance(sub_node, (ast.Assign, ast.AnnAssign)):
if isinstance(sub_node, ast.Assign):
Expand Down Expand Up @@ -220,7 +226,9 @@ def parse(self):
return_=self.clear_quotes(ast.unparse(node.returns).strip()) if node.returns else TypeHint.NO_RETURN,
decorators=[ast.unparse(decorator).strip() for decorator in node.decorator_list],
is_async=isinstance(node, ast.AsyncFunctionDef),
src=ast.unparse(node).strip()
src=ast.unparse(node).strip(),
lineno=node.lineno,
module_file_path=self.file_path
)
self.functions.append(function_node)
self.all_nodes.append(function_node)
Expand Down
12 changes: 11 additions & 1 deletion litedoc/syntax/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class FunctionNode(BaseModel):
kw_defaults: list[ConstantNode] = []
defaults: list[ConstantNode] = []

lineno: int = 0
module_file_path: str = "" # 去头路径,不包含模块顶级文件夹

return_: str = TypeHint.NO_RETURN
decorators: list[str] = []
src: str
Expand Down Expand Up @@ -282,7 +285,14 @@ def markdown(self, lang: str, indent: int = 0, **kwargs) -> str:
else:
pass
# 源码展示
md += PREFIX + f"\n<details>\n<summary> <b>{get_text(lang, 'src')}</b> </summary>\n\n```python\n{self.src}\n```\n</details>\n\n"
if kwargs.get("bu", None):
# 源码链接
self.module_file_path = self.module_file_path.replace("\\", "/")
origin_url = kwargs.get("bu") + f"{self.module_file_path}#L{self.lineno}"
a_tag = f"\n\n[{get_text(lang, 'view_on_github')}]({origin_url})"
else:
a_tag = ""
md += PREFIX + f"\n<details>\n<summary> <b>{get_text(lang, 'src')}</b> </summary>{a_tag}\n\n```python\n{self.src}\n```\n</details>\n\n"

return md

Expand Down
4 changes: 2 additions & 2 deletions test_mkdoc.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
chcp 65001
litedoc tests/test_modules/mbcp -o docdist/api -l zh-Hans -fd def -md def -cd 类 -cs
litedoc tests/test_modules/mbcp -o docdist/en/api -l en -fd def -md def -cs
python -m litedoc tests/test_modules/mbcp -o docdist/api -l zh-Hans -fd def -md def -cd 类 -cs -bu https://github.com/snowykami/mbcp/tree/main/mbcp/
python -m litedoc tests/test_modules/mbcp -o docdist/en/api -l en -fd def -md def -cs -bu https://github.com/snowykami/mbcp/tree/main/mbcp/

0 comments on commit a36606a

Please sign in to comment.