From 5763a8467999bf47784b9fe9aa76548f46c6dcfd Mon Sep 17 00:00:00 2001 From: snowy Date: Thu, 29 Aug 2024 15:05:02 +0800 Subject: [PATCH] =?UTF-8?q?:memo:=20=E6=9E=84=E5=BB=BA=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-docs.yml | 2 +- .gitignore | 4 +- docs/api/mp_math/equation.md | 4 +- docs/api/mp_math/line.md | 52 ++--- docs/api/mp_math/plane.md | 48 ++-- docs/api/mp_math/point.md | 4 +- docs/api/mp_math/utils.md | 16 +- docs/api/mp_math/vector.md | 24 +- docs/api/presets/model/index.md | 4 +- docs/en/api/mp_math/equation.md | 4 +- docs/en/api/mp_math/line.md | 52 ++--- docs/en/api/mp_math/plane.md | 48 ++-- docs/en/api/mp_math/point.md | 4 +- docs/en/api/mp_math/utils.md | 16 +- docs/en/api/mp_math/vector.md | 24 +- docs/en/api/presets/model/index.md | 4 +- docs/ja/api/mp_math/equation.md | 4 +- docs/ja/api/mp_math/line.md | 52 ++--- docs/ja/api/mp_math/plane.md | 48 ++-- docs/ja/api/mp_math/point.md | 4 +- docs/ja/api/mp_math/utils.md | 16 +- docs/ja/api/mp_math/vector.md | 24 +- docs/ja/api/presets/model/index.md | 4 +- docs/zht/api/mp_math/equation.md | 4 +- docs/zht/api/mp_math/line.md | 52 ++--- docs/zht/api/mp_math/plane.md | 48 ++-- docs/zht/api/mp_math/point.md | 4 +- docs/zht/api/mp_math/utils.md | 16 +- docs/zht/api/mp_math/vector.md | 24 +- docs/zht/api/presets/model/index.md | 4 +- litedoc/__init__.py | 10 - litedoc/__main__.py | 46 ---- litedoc/docstring/__init__.py | 10 - litedoc/docstring/docstring.py | 154 ------------- litedoc/docstring/parser.py | 192 --------------- litedoc/i18n.py | 131 ----------- litedoc/output.py | 107 --------- litedoc/style/__init__.py | 10 - litedoc/style/markdown.py | 59 ----- litedoc/syntax/astparser.py | 293 ----------------------- litedoc/syntax/node.py | 314 ------------------------- litedoc/translator.py | 47 ---- main.py | 46 ---- make_docs.py | 10 - mkdoc.py | 346 ---------------------------- pyproject.toml | 4 + 46 files changed, 312 insertions(+), 2081 deletions(-) delete mode 100644 litedoc/__init__.py delete mode 100644 litedoc/__main__.py delete mode 100644 litedoc/docstring/__init__.py delete mode 100644 litedoc/docstring/docstring.py delete mode 100644 litedoc/docstring/parser.py delete mode 100644 litedoc/i18n.py delete mode 100644 litedoc/output.py delete mode 100644 litedoc/style/__init__.py delete mode 100644 litedoc/style/markdown.py delete mode 100644 litedoc/syntax/astparser.py delete mode 100644 litedoc/syntax/node.py delete mode 100644 litedoc/translator.py delete mode 100644 main.py delete mode 100644 make_docs.py delete mode 100644 mkdoc.py diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 8ca6ba1..42e75cd 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -39,7 +39,7 @@ jobs: - name: Setup API markdown run: |- - python -m pip install pydantic + python -m pip install litedoc python -m litedoc mbcp -o docs/api -l zh-Hans python -m litedoc mbcp -o docs/en/api -l en python -m litedoc mbcp -o docs/ja/api -l ja diff --git a/.gitignore b/.gitignore index a8698e9..60bf0bf 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,6 @@ pdm.lock node_modules/ docs/.vitepress/dist -docs/.vitepress/cache \ No newline at end of file +docs/.vitepress/cache + +litedoc/ \ No newline at end of file diff --git a/docs/api/mp_math/equation.md b/docs/api/mp_math/equation.md index bd20f55..4c55564 100644 --- a/docs/api/mp_math/equation.md +++ b/docs/api/mp_math/equation.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.equation **说明**: 求N元函数一阶偏导函数。这玩意不太稳定,慎用。 -**返回**: 偏导函数 - **参数**: > - func: 函数 > - var: 变量位置,可为整数(一阶偏导)或整数元组(高阶偏导) > - epsilon: 偏移量 +**返回**: 偏导函数 + **引发**: > - ValueError 无效变量类型 diff --git a/docs/api/mp_math/line.md b/docs/api/mp_math/line.md index dbdde85..fd5fad2 100644 --- a/docs/api/mp_math/line.md +++ b/docs/api/mp_math/line.md @@ -35,12 +35,12 @@ def __init__(self, point: 'Point3', direction: 'Vector3'): **说明**: 判断两条直线是否近似相等。 -**返回**: 是否近似相等 - **参数**: > - other: 另一条直线 > - epsilon: 误差 +**返回**: 是否近似相等 +
源代码 @@ -65,11 +65,11 @@ def approx(self, other: 'Line3', epsilon: float=APPROX) -> bool: **说明**: 计算直线和直线之间的夹角。 -**返回**: 夹角弧度 - **参数**: > - other: 另一条直线 +**返回**: 夹角弧度 + **引发**: > - TypeError 不支持的类型 @@ -98,11 +98,11 @@ def cal_angle(self, other: 'Line3') -> 'AnyAngle': **说明**: 计算直线和直线或点之间的距离。 -**返回**: 距离 - **参数**: > - other: 平行直线或点 +**返回**: 距离 + **引发**: > - TypeError 不支持的类型 @@ -144,11 +144,11 @@ def cal_distance(self, other: 'Line3 | Point3') -> float: **说明**: 计算两条直线的交点。 -**返回**: 交点 - **参数**: > - other: 另一条直线 +**返回**: 交点 + **引发**: > - ValueError 直线平行 > - ValueError 直线不共面 @@ -183,11 +183,11 @@ def cal_intersection(self, other: 'Line3') -> 'Point3': **说明**: 计算直线经过指定点p的垂线。 -**返回**: 垂线 - **参数**: > - point: 指定点 +**返回**: 垂线 +
源代码 @@ -211,11 +211,11 @@ def cal_perpendicular(self, point: 'Point3') -> 'Line3': **说明**: 获取直线上的点。同一条直线,但起始点和方向向量不同,则同一个t对应的点不同。 -**返回**: 点 - **参数**: > - t: 参数t +**返回**: 点 +
源代码 @@ -262,12 +262,12 @@ def get_parametric_equations(self) -> tuple[OneSingleVarFunc, OneSingleVarFunc, **说明**: 判断两条直线是否近似平行。 -**返回**: 是否近似平行 - **参数**: > - other: 另一条直线 > - epsilon: 误差 +**返回**: 是否近似平行 +
源代码 @@ -292,11 +292,11 @@ def is_approx_parallel(self, other: 'Line3', epsilon: float=1e-06) -> bool: **说明**: 判断两条直线是否平行。 -**返回**: 是否平行 - **参数**: > - other: 另一条直线 +**返回**: 是否平行 +
源代码 @@ -320,11 +320,11 @@ def is_parallel(self, other: 'Line3') -> bool: **说明**: 判断两条直线是否共线。 -**返回**: 是否共线 - **参数**: > - other: 另一条直线 +**返回**: 是否共线 +
源代码 @@ -348,11 +348,11 @@ def is_collinear(self, other: 'Line3') -> bool: **说明**: 判断点是否在直线上。 -**返回**: 是否在直线上 - **参数**: > - point: 点 +**返回**: 是否在直线上 +
源代码 @@ -377,11 +377,11 @@ def is_point_on(self, point: 'Point3') -> bool: **说明**: 判断两条直线是否共面。 充要条件:两直线方向向量的叉乘与两直线上任意一点的向量的点积为0。 -**返回**: 是否共面 - **参数**: > - other: 另一条直线 +**返回**: 是否共面 +
源代码 @@ -438,12 +438,12 @@ def simplify(self): **说明**: 工厂函数 由两点构造直线。 -**返回**: 直线 - **参数**: > - p1: 点1 > - p2: 点2 +**返回**: 直线 +
源代码 @@ -470,11 +470,11 @@ def from_two_points(cls, p1: 'Point3', p2: 'Point3') -> 'Line3': **说明**: 计算两条直线点集合的交集。重合线返回自身,平行线返回None,交线返回交点。 -**返回**: 交点 - **参数**: > - other: 另一条直线 +**返回**: 交点 +
源代码 diff --git a/docs/api/mp_math/plane.md b/docs/api/mp_math/plane.md index f5e2232..2680472 100644 --- a/docs/api/mp_math/plane.md +++ b/docs/api/mp_math/plane.md @@ -41,11 +41,11 @@ def __init__(self, a: float, b: float, c: float, d: float): **说明**: 判断两个平面是否近似相等。 -**返回**: 是否近似相等 - **参数**: > - other: 另一个平面 +**返回**: 是否近似相等 +
源代码 @@ -79,11 +79,11 @@ def approx(self, other: 'Plane3') -> bool: **说明**: 计算平面与平面之间的夹角。 -**返回**: 夹角弧度 - **参数**: > - other: 另一个平面 +**返回**: 夹角弧度 + **引发**: > - TypeError 不支持的类型 @@ -117,11 +117,11 @@ def cal_angle(self, other: 'Line3 | Plane3') -> 'AnyAngle': **说明**: 计算平面与平面或点之间的距离。 -**返回**: 距离 - **参数**: > - other: 另一个平面或点 +**返回**: 距离 + **引发**: > - TypeError 不支持的类型 @@ -155,11 +155,11 @@ def cal_distance(self, other: 'Plane3 | Point3') -> float: **说明**: 计算两平面的交线。 -**返回**: 两平面的交线 - **参数**: > - other: 另一个平面 +**返回**: 两平面的交线 +
源代码 @@ -200,11 +200,11 @@ def cal_intersection_line3(self, other: 'Plane3') -> 'Line3': **说明**: 计算平面与直线的交点。 -**返回**: 交点 - **参数**: > - other: 不与平面平行或在平面上的直线 +**返回**: 交点 + **引发**: > - ValueError 平面与直线平行或重合 @@ -237,11 +237,11 @@ def cal_intersection_point3(self, other: 'Line3') -> 'Point3': **说明**: 计算平行于该平面且过指定点的平面。 -**返回**: 所求平面 - **参数**: > - point: 指定点 +**返回**: 所求平面 +
源代码 @@ -265,11 +265,11 @@ def cal_parallel_plane3(self, point: 'Point3') -> 'Plane3': **说明**: 判断两个平面是否平行。 -**返回**: 是否平行 - **参数**: > - other: 另一个平面 +**返回**: 是否平行 +
源代码 @@ -319,12 +319,12 @@ def normal(self) -> 'Vector3': **说明**: 工厂函数 由点和法向量构造平面(点法式构造)。 -**返回**: 平面 - **参数**: > - point: 平面上的一点 > - normal: 法向量 +**返回**: 平面 +
源代码 @@ -353,13 +353,13 @@ def from_point_and_normal(cls, point: 'Point3', normal: 'Vector3') -> 'Plane3': **说明**: 工厂函数 由三点构造平面。 -**返回**: 平面 - **参数**: > - p1: 点1 > - p2: 点2 > - p3: 点3 +**返回**: 平面 +
源代码 @@ -390,12 +390,12 @@ def from_three_points(cls, p1: 'Point3', p2: 'Point3', p3: 'Point3') -> 'Plane3' **说明**: 工厂函数 由两直线构造平面。 -**返回**: 平面 - **参数**: > - l1: 直线1 > - l2: 直线2 +**返回**: 平面 +
源代码 @@ -426,12 +426,12 @@ def from_two_lines(cls, l1: 'Line3', l2: 'Line3') -> 'Plane3': **说明**: 工厂函数 由点和直线构造平面。 -**返回**: 平面 - **参数**: > - point: 面上一点 > - line: 面上直线,不包含点 +**返回**: 平面 +
源代码 @@ -485,11 +485,11 @@ def __and__(self, other: 'Plane3') -> 'Line3 | None': **说明**: 取两平面的交集(人话:交线) -**返回**: 不平行平面的交线,平面平行返回None - **参数**: > - other: +**返回**: 不平行平面的交线,平面平行返回None +
源代码 diff --git a/docs/api/mp_math/point.md b/docs/api/mp_math/point.md index 29a99bb..48b49ea 100644 --- a/docs/api/mp_math/point.md +++ b/docs/api/mp_math/point.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **说明**: 判断两个点是否近似相等。 -**返回**: 是否近似相等 - **参数**: > - other: > - epsilon: +**返回**: 是否近似相等 +
源代码 diff --git a/docs/api/mp_math/utils.md b/docs/api/mp_math/utils.md index 46193dc..62cff23 100644 --- a/docs/api/mp_math/utils.md +++ b/docs/api/mp_math/utils.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.utils **说明**: 区间限定函数 -**返回**: 限制后的值 - **参数**: > - x: 待限定的值 > - min_: 最小值 > - max_: 最大值 +**返回**: 限制后的值 +
源代码 @@ -40,13 +40,13 @@ def clamp(x: float, min_: float, max_: float) -> float: **说明**: 判断两个数是否近似相等。或包装一个实数,用于判断是否近似于0。 -**返回**: 是否近似相等 - **参数**: > - x: 数1 > - y: 数2 > - epsilon: 误差 +**返回**: 是否近似相等 +
源代码 @@ -72,12 +72,12 @@ def approx(x: float, y: float=0.0, epsilon: float=APPROX) -> bool: **说明**: 获取数的符号。 -**返回**: 符号 + - "" - **参数**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**返回**: 符号 + - "" +
源代码 @@ -109,12 +109,12 @@ def sign(x: float, only_neg: bool=False) -> str: 1 -> +1 0 -> "" -**返回**: 符号 + - "" - **参数**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**返回**: 符号 + - "" +
源代码 diff --git a/docs/api/mp_math/vector.md b/docs/api/mp_math/vector.md index daa9400..5ae08b6 100644 --- a/docs/api/mp_math/vector.md +++ b/docs/api/mp_math/vector.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **说明**: 判断两个向量是否近似相等。 -**返回**: 是否近似相等 - **参数**: > - other: > - epsilon: +**返回**: 是否近似相等 +
源代码 @@ -69,11 +69,11 @@ def approx(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **说明**: 计算两个向量之间的夹角。 -**返回**: 夹角 - **参数**: > - other: 另一个向量 +**返回**: 夹角 +
源代码 @@ -101,11 +101,11 @@ def cal_angle(self, other: 'Vector3') -> 'AnyAngle': 其余结果的模为平行四边形的面积。 -**返回**: 行列式的结果 - **参数**: > - other: +**返回**: 行列式的结果 +
源代码 @@ -141,12 +141,12 @@ def cross(self, other: 'Vector3') -> 'Vector3': **说明**: 判断两个向量是否近似平行。 -**返回**: 是否近似平行 - **参数**: > - other: 另一个向量 > - epsilon: 允许的误差 +**返回**: 是否近似平行 +
源代码 @@ -171,11 +171,11 @@ def is_approx_parallel(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **说明**: 判断两个向量是否平行。 -**返回**: 是否平行 - **参数**: > - other: 另一个向量 +**返回**: 是否平行 +
源代码 @@ -370,11 +370,11 @@ def __add__(self, other): **说明**: 判断两个向量是否相等。 -**返回**: 是否相等 - **参数**: > - other: +**返回**: 是否相等 +
源代码 diff --git a/docs/api/presets/model/index.md b/docs/api/presets/model/index.md index 49a994d..94ce1f7 100644 --- a/docs/api/presets/model/index.md +++ b/docs/api/presets/model/index.md @@ -9,12 +9,12 @@ title: mbcp.presets.model **说明**: 生成球体上的点集。 -**返回**: List[Point3]: 球体上的点集。 - **参数**: > - radius: > - density: +**返回**: List[Point3]: 球体上的点集。 +
源代码 diff --git a/docs/en/api/mp_math/equation.md b/docs/en/api/mp_math/equation.md index 6a8b9f6..d562887 100644 --- a/docs/en/api/mp_math/equation.md +++ b/docs/en/api/mp_math/equation.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.equation **Description**: 求N元函数一阶偏导函数。这玩意不太稳定,慎用。 -**Return**: 偏导函数 - **Arguments**: > - func: 函数 > - var: 变量位置,可为整数(一阶偏导)或整数元组(高阶偏导) > - epsilon: 偏移量 +**Return**: 偏导函数 + **Raises**: > - ValueError 无效变量类型 diff --git a/docs/en/api/mp_math/line.md b/docs/en/api/mp_math/line.md index 8009a9b..dde9c52 100644 --- a/docs/en/api/mp_math/line.md +++ b/docs/en/api/mp_math/line.md @@ -35,12 +35,12 @@ def __init__(self, point: 'Point3', direction: 'Vector3'): **Description**: 判断两条直线是否近似相等。 -**Return**: 是否近似相等 - **Arguments**: > - other: 另一条直线 > - epsilon: 误差 +**Return**: 是否近似相等 +
Source code @@ -65,11 +65,11 @@ def approx(self, other: 'Line3', epsilon: float=APPROX) -> bool: **Description**: 计算直线和直线之间的夹角。 -**Return**: 夹角弧度 - **Arguments**: > - other: 另一条直线 +**Return**: 夹角弧度 + **Raises**: > - TypeError 不支持的类型 @@ -98,11 +98,11 @@ def cal_angle(self, other: 'Line3') -> 'AnyAngle': **Description**: 计算直线和直线或点之间的距离。 -**Return**: 距离 - **Arguments**: > - other: 平行直线或点 +**Return**: 距离 + **Raises**: > - TypeError 不支持的类型 @@ -144,11 +144,11 @@ def cal_distance(self, other: 'Line3 | Point3') -> float: **Description**: 计算两条直线的交点。 -**Return**: 交点 - **Arguments**: > - other: 另一条直线 +**Return**: 交点 + **Raises**: > - ValueError 直线平行 > - ValueError 直线不共面 @@ -183,11 +183,11 @@ def cal_intersection(self, other: 'Line3') -> 'Point3': **Description**: 计算直线经过指定点p的垂线。 -**Return**: 垂线 - **Arguments**: > - point: 指定点 +**Return**: 垂线 +
Source code @@ -211,11 +211,11 @@ def cal_perpendicular(self, point: 'Point3') -> 'Line3': **Description**: 获取直线上的点。同一条直线,但起始点和方向向量不同,则同一个t对应的点不同。 -**Return**: 点 - **Arguments**: > - t: 参数t +**Return**: 点 +
Source code @@ -262,12 +262,12 @@ def get_parametric_equations(self) -> tuple[OneSingleVarFunc, OneSingleVarFunc, **Description**: 判断两条直线是否近似平行。 -**Return**: 是否近似平行 - **Arguments**: > - other: 另一条直线 > - epsilon: 误差 +**Return**: 是否近似平行 +
Source code @@ -292,11 +292,11 @@ def is_approx_parallel(self, other: 'Line3', epsilon: float=1e-06) -> bool: **Description**: 判断两条直线是否平行。 -**Return**: 是否平行 - **Arguments**: > - other: 另一条直线 +**Return**: 是否平行 +
Source code @@ -320,11 +320,11 @@ def is_parallel(self, other: 'Line3') -> bool: **Description**: 判断两条直线是否共线。 -**Return**: 是否共线 - **Arguments**: > - other: 另一条直线 +**Return**: 是否共线 +
Source code @@ -348,11 +348,11 @@ def is_collinear(self, other: 'Line3') -> bool: **Description**: 判断点是否在直线上。 -**Return**: 是否在直线上 - **Arguments**: > - point: 点 +**Return**: 是否在直线上 +
Source code @@ -377,11 +377,11 @@ def is_point_on(self, point: 'Point3') -> bool: **Description**: 判断两条直线是否共面。 充要条件:两直线方向向量的叉乘与两直线上任意一点的向量的点积为0。 -**Return**: 是否共面 - **Arguments**: > - other: 另一条直线 +**Return**: 是否共面 +
Source code @@ -438,12 +438,12 @@ def simplify(self): **Description**: 工厂函数 由两点构造直线。 -**Return**: 直线 - **Arguments**: > - p1: 点1 > - p2: 点2 +**Return**: 直线 +
Source code @@ -470,11 +470,11 @@ def from_two_points(cls, p1: 'Point3', p2: 'Point3') -> 'Line3': **Description**: 计算两条直线点集合的交集。重合线返回自身,平行线返回None,交线返回交点。 -**Return**: 交点 - **Arguments**: > - other: 另一条直线 +**Return**: 交点 +
Source code diff --git a/docs/en/api/mp_math/plane.md b/docs/en/api/mp_math/plane.md index 976e9af..a02fa06 100644 --- a/docs/en/api/mp_math/plane.md +++ b/docs/en/api/mp_math/plane.md @@ -41,11 +41,11 @@ def __init__(self, a: float, b: float, c: float, d: float): **Description**: 判断两个平面是否近似相等。 -**Return**: 是否近似相等 - **Arguments**: > - other: 另一个平面 +**Return**: 是否近似相等 +
Source code @@ -79,11 +79,11 @@ def approx(self, other: 'Plane3') -> bool: **Description**: 计算平面与平面之间的夹角。 -**Return**: 夹角弧度 - **Arguments**: > - other: 另一个平面 +**Return**: 夹角弧度 + **Raises**: > - TypeError 不支持的类型 @@ -117,11 +117,11 @@ def cal_angle(self, other: 'Line3 | Plane3') -> 'AnyAngle': **Description**: 计算平面与平面或点之间的距离。 -**Return**: 距离 - **Arguments**: > - other: 另一个平面或点 +**Return**: 距离 + **Raises**: > - TypeError 不支持的类型 @@ -155,11 +155,11 @@ def cal_distance(self, other: 'Plane3 | Point3') -> float: **Description**: 计算两平面的交线。 -**Return**: 两平面的交线 - **Arguments**: > - other: 另一个平面 +**Return**: 两平面的交线 +
Source code @@ -200,11 +200,11 @@ def cal_intersection_line3(self, other: 'Plane3') -> 'Line3': **Description**: 计算平面与直线的交点。 -**Return**: 交点 - **Arguments**: > - other: 不与平面平行或在平面上的直线 +**Return**: 交点 + **Raises**: > - ValueError 平面与直线平行或重合 @@ -237,11 +237,11 @@ def cal_intersection_point3(self, other: 'Line3') -> 'Point3': **Description**: 计算平行于该平面且过指定点的平面。 -**Return**: 所求平面 - **Arguments**: > - point: 指定点 +**Return**: 所求平面 +
Source code @@ -265,11 +265,11 @@ def cal_parallel_plane3(self, point: 'Point3') -> 'Plane3': **Description**: 判断两个平面是否平行。 -**Return**: 是否平行 - **Arguments**: > - other: 另一个平面 +**Return**: 是否平行 +
Source code @@ -319,12 +319,12 @@ def normal(self) -> 'Vector3': **Description**: 工厂函数 由点和法向量构造平面(点法式构造)。 -**Return**: 平面 - **Arguments**: > - point: 平面上的一点 > - normal: 法向量 +**Return**: 平面 +
Source code @@ -353,13 +353,13 @@ def from_point_and_normal(cls, point: 'Point3', normal: 'Vector3') -> 'Plane3': **Description**: 工厂函数 由三点构造平面。 -**Return**: 平面 - **Arguments**: > - p1: 点1 > - p2: 点2 > - p3: 点3 +**Return**: 平面 +
Source code @@ -390,12 +390,12 @@ def from_three_points(cls, p1: 'Point3', p2: 'Point3', p3: 'Point3') -> 'Plane3' **Description**: 工厂函数 由两直线构造平面。 -**Return**: 平面 - **Arguments**: > - l1: 直线1 > - l2: 直线2 +**Return**: 平面 +
Source code @@ -426,12 +426,12 @@ def from_two_lines(cls, l1: 'Line3', l2: 'Line3') -> 'Plane3': **Description**: 工厂函数 由点和直线构造平面。 -**Return**: 平面 - **Arguments**: > - point: 面上一点 > - line: 面上直线,不包含点 +**Return**: 平面 +
Source code @@ -485,11 +485,11 @@ def __and__(self, other: 'Plane3') -> 'Line3 | None': **Description**: 取两平面的交集(人话:交线) -**Return**: 不平行平面的交线,平面平行返回None - **Arguments**: > - other: +**Return**: 不平行平面的交线,平面平行返回None +
Source code diff --git a/docs/en/api/mp_math/point.md b/docs/en/api/mp_math/point.md index 0533243..05f3ee5 100644 --- a/docs/en/api/mp_math/point.md +++ b/docs/en/api/mp_math/point.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **Description**: 判断两个点是否近似相等。 -**Return**: 是否近似相等 - **Arguments**: > - other: > - epsilon: +**Return**: 是否近似相等 +
Source code diff --git a/docs/en/api/mp_math/utils.md b/docs/en/api/mp_math/utils.md index aaee23c..2015cb4 100644 --- a/docs/en/api/mp_math/utils.md +++ b/docs/en/api/mp_math/utils.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.utils **Description**: 区间限定函数 -**Return**: 限制后的值 - **Arguments**: > - x: 待限定的值 > - min_: 最小值 > - max_: 最大值 +**Return**: 限制后的值 +
Source code @@ -40,13 +40,13 @@ def clamp(x: float, min_: float, max_: float) -> float: **Description**: 判断两个数是否近似相等。或包装一个实数,用于判断是否近似于0。 -**Return**: 是否近似相等 - **Arguments**: > - x: 数1 > - y: 数2 > - epsilon: 误差 +**Return**: 是否近似相等 +
Source code @@ -72,12 +72,12 @@ def approx(x: float, y: float=0.0, epsilon: float=APPROX) -> bool: **Description**: 获取数的符号。 -**Return**: 符号 + - "" - **Arguments**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**Return**: 符号 + - "" +
Source code @@ -109,12 +109,12 @@ def sign(x: float, only_neg: bool=False) -> str: 1 -> +1 0 -> "" -**Return**: 符号 + - "" - **Arguments**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**Return**: 符号 + - "" +
Source code diff --git a/docs/en/api/mp_math/vector.md b/docs/en/api/mp_math/vector.md index 2b01d71..6656698 100644 --- a/docs/en/api/mp_math/vector.md +++ b/docs/en/api/mp_math/vector.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **Description**: 判断两个向量是否近似相等。 -**Return**: 是否近似相等 - **Arguments**: > - other: > - epsilon: +**Return**: 是否近似相等 +
Source code @@ -69,11 +69,11 @@ def approx(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **Description**: 计算两个向量之间的夹角。 -**Return**: 夹角 - **Arguments**: > - other: 另一个向量 +**Return**: 夹角 +
Source code @@ -101,11 +101,11 @@ def cal_angle(self, other: 'Vector3') -> 'AnyAngle': 其余结果的模为平行四边形的面积。 -**Return**: 行列式的结果 - **Arguments**: > - other: +**Return**: 行列式的结果 +
Source code @@ -141,12 +141,12 @@ def cross(self, other: 'Vector3') -> 'Vector3': **Description**: 判断两个向量是否近似平行。 -**Return**: 是否近似平行 - **Arguments**: > - other: 另一个向量 > - epsilon: 允许的误差 +**Return**: 是否近似平行 +
Source code @@ -171,11 +171,11 @@ def is_approx_parallel(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **Description**: 判断两个向量是否平行。 -**Return**: 是否平行 - **Arguments**: > - other: 另一个向量 +**Return**: 是否平行 +
Source code @@ -370,11 +370,11 @@ def __add__(self, other): **Description**: 判断两个向量是否相等。 -**Return**: 是否相等 - **Arguments**: > - other: +**Return**: 是否相等 +
Source code diff --git a/docs/en/api/presets/model/index.md b/docs/en/api/presets/model/index.md index b7b158c..e563645 100644 --- a/docs/en/api/presets/model/index.md +++ b/docs/en/api/presets/model/index.md @@ -9,12 +9,12 @@ title: mbcp.presets.model **Description**: 生成球体上的点集。 -**Return**: List[Point3]: 球体上的点集。 - **Arguments**: > - radius: > - density: +**Return**: List[Point3]: 球体上的点集。 +
Source code diff --git a/docs/ja/api/mp_math/equation.md b/docs/ja/api/mp_math/equation.md index 0e771ec..9f74dd9 100644 --- a/docs/ja/api/mp_math/equation.md +++ b/docs/ja/api/mp_math/equation.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.equation **説明**: 求N元函数一阶偏导函数。这玩意不太稳定,慎用。 -**戻り値**: 偏导函数 - **引数**: > - func: 函数 > - var: 变量位置,可为整数(一阶偏导)或整数元组(高阶偏导) > - epsilon: 偏移量 +**戻り値**: 偏导函数 + **例外**: > - ValueError 无效变量类型 diff --git a/docs/ja/api/mp_math/line.md b/docs/ja/api/mp_math/line.md index 8cd9bf9..4195dcc 100644 --- a/docs/ja/api/mp_math/line.md +++ b/docs/ja/api/mp_math/line.md @@ -35,12 +35,12 @@ def __init__(self, point: 'Point3', direction: 'Vector3'): **説明**: 判断两条直线是否近似相等。 -**戻り値**: 是否近似相等 - **引数**: > - other: 另一条直线 > - epsilon: 误差 +**戻り値**: 是否近似相等 +
ソースコード @@ -65,11 +65,11 @@ def approx(self, other: 'Line3', epsilon: float=APPROX) -> bool: **説明**: 计算直线和直线之间的夹角。 -**戻り値**: 夹角弧度 - **引数**: > - other: 另一条直线 +**戻り値**: 夹角弧度 + **例外**: > - TypeError 不支持的类型 @@ -98,11 +98,11 @@ def cal_angle(self, other: 'Line3') -> 'AnyAngle': **説明**: 计算直线和直线或点之间的距离。 -**戻り値**: 距离 - **引数**: > - other: 平行直线或点 +**戻り値**: 距离 + **例外**: > - TypeError 不支持的类型 @@ -144,11 +144,11 @@ def cal_distance(self, other: 'Line3 | Point3') -> float: **説明**: 计算两条直线的交点。 -**戻り値**: 交点 - **引数**: > - other: 另一条直线 +**戻り値**: 交点 + **例外**: > - ValueError 直线平行 > - ValueError 直线不共面 @@ -183,11 +183,11 @@ def cal_intersection(self, other: 'Line3') -> 'Point3': **説明**: 计算直线经过指定点p的垂线。 -**戻り値**: 垂线 - **引数**: > - point: 指定点 +**戻り値**: 垂线 +
ソースコード @@ -211,11 +211,11 @@ def cal_perpendicular(self, point: 'Point3') -> 'Line3': **説明**: 获取直线上的点。同一条直线,但起始点和方向向量不同,则同一个t对应的点不同。 -**戻り値**: 点 - **引数**: > - t: 参数t +**戻り値**: 点 +
ソースコード @@ -262,12 +262,12 @@ def get_parametric_equations(self) -> tuple[OneSingleVarFunc, OneSingleVarFunc, **説明**: 判断两条直线是否近似平行。 -**戻り値**: 是否近似平行 - **引数**: > - other: 另一条直线 > - epsilon: 误差 +**戻り値**: 是否近似平行 +
ソースコード @@ -292,11 +292,11 @@ def is_approx_parallel(self, other: 'Line3', epsilon: float=1e-06) -> bool: **説明**: 判断两条直线是否平行。 -**戻り値**: 是否平行 - **引数**: > - other: 另一条直线 +**戻り値**: 是否平行 +
ソースコード @@ -320,11 +320,11 @@ def is_parallel(self, other: 'Line3') -> bool: **説明**: 判断两条直线是否共线。 -**戻り値**: 是否共线 - **引数**: > - other: 另一条直线 +**戻り値**: 是否共线 +
ソースコード @@ -348,11 +348,11 @@ def is_collinear(self, other: 'Line3') -> bool: **説明**: 判断点是否在直线上。 -**戻り値**: 是否在直线上 - **引数**: > - point: 点 +**戻り値**: 是否在直线上 +
ソースコード @@ -377,11 +377,11 @@ def is_point_on(self, point: 'Point3') -> bool: **説明**: 判断两条直线是否共面。 充要条件:两直线方向向量的叉乘与两直线上任意一点的向量的点积为0。 -**戻り値**: 是否共面 - **引数**: > - other: 另一条直线 +**戻り値**: 是否共面 +
ソースコード @@ -438,12 +438,12 @@ def simplify(self): **説明**: 工厂函数 由两点构造直线。 -**戻り値**: 直线 - **引数**: > - p1: 点1 > - p2: 点2 +**戻り値**: 直线 +
ソースコード @@ -470,11 +470,11 @@ def from_two_points(cls, p1: 'Point3', p2: 'Point3') -> 'Line3': **説明**: 计算两条直线点集合的交集。重合线返回自身,平行线返回None,交线返回交点。 -**戻り値**: 交点 - **引数**: > - other: 另一条直线 +**戻り値**: 交点 +
ソースコード diff --git a/docs/ja/api/mp_math/plane.md b/docs/ja/api/mp_math/plane.md index 3a30a2a..e44abb1 100644 --- a/docs/ja/api/mp_math/plane.md +++ b/docs/ja/api/mp_math/plane.md @@ -41,11 +41,11 @@ def __init__(self, a: float, b: float, c: float, d: float): **説明**: 判断两个平面是否近似相等。 -**戻り値**: 是否近似相等 - **引数**: > - other: 另一个平面 +**戻り値**: 是否近似相等 +
ソースコード @@ -79,11 +79,11 @@ def approx(self, other: 'Plane3') -> bool: **説明**: 计算平面与平面之间的夹角。 -**戻り値**: 夹角弧度 - **引数**: > - other: 另一个平面 +**戻り値**: 夹角弧度 + **例外**: > - TypeError 不支持的类型 @@ -117,11 +117,11 @@ def cal_angle(self, other: 'Line3 | Plane3') -> 'AnyAngle': **説明**: 计算平面与平面或点之间的距离。 -**戻り値**: 距离 - **引数**: > - other: 另一个平面或点 +**戻り値**: 距离 + **例外**: > - TypeError 不支持的类型 @@ -155,11 +155,11 @@ def cal_distance(self, other: 'Plane3 | Point3') -> float: **説明**: 计算两平面的交线。 -**戻り値**: 两平面的交线 - **引数**: > - other: 另一个平面 +**戻り値**: 两平面的交线 +
ソースコード @@ -200,11 +200,11 @@ def cal_intersection_line3(self, other: 'Plane3') -> 'Line3': **説明**: 计算平面与直线的交点。 -**戻り値**: 交点 - **引数**: > - other: 不与平面平行或在平面上的直线 +**戻り値**: 交点 + **例外**: > - ValueError 平面与直线平行或重合 @@ -237,11 +237,11 @@ def cal_intersection_point3(self, other: 'Line3') -> 'Point3': **説明**: 计算平行于该平面且过指定点的平面。 -**戻り値**: 所求平面 - **引数**: > - point: 指定点 +**戻り値**: 所求平面 +
ソースコード @@ -265,11 +265,11 @@ def cal_parallel_plane3(self, point: 'Point3') -> 'Plane3': **説明**: 判断两个平面是否平行。 -**戻り値**: 是否平行 - **引数**: > - other: 另一个平面 +**戻り値**: 是否平行 +
ソースコード @@ -319,12 +319,12 @@ def normal(self) -> 'Vector3': **説明**: 工厂函数 由点和法向量构造平面(点法式构造)。 -**戻り値**: 平面 - **引数**: > - point: 平面上的一点 > - normal: 法向量 +**戻り値**: 平面 +
ソースコード @@ -353,13 +353,13 @@ def from_point_and_normal(cls, point: 'Point3', normal: 'Vector3') -> 'Plane3': **説明**: 工厂函数 由三点构造平面。 -**戻り値**: 平面 - **引数**: > - p1: 点1 > - p2: 点2 > - p3: 点3 +**戻り値**: 平面 +
ソースコード @@ -390,12 +390,12 @@ def from_three_points(cls, p1: 'Point3', p2: 'Point3', p3: 'Point3') -> 'Plane3' **説明**: 工厂函数 由两直线构造平面。 -**戻り値**: 平面 - **引数**: > - l1: 直线1 > - l2: 直线2 +**戻り値**: 平面 +
ソースコード @@ -426,12 +426,12 @@ def from_two_lines(cls, l1: 'Line3', l2: 'Line3') -> 'Plane3': **説明**: 工厂函数 由点和直线构造平面。 -**戻り値**: 平面 - **引数**: > - point: 面上一点 > - line: 面上直线,不包含点 +**戻り値**: 平面 +
ソースコード @@ -485,11 +485,11 @@ def __and__(self, other: 'Plane3') -> 'Line3 | None': **説明**: 取两平面的交集(人话:交线) -**戻り値**: 不平行平面的交线,平面平行返回None - **引数**: > - other: +**戻り値**: 不平行平面的交线,平面平行返回None +
ソースコード diff --git a/docs/ja/api/mp_math/point.md b/docs/ja/api/mp_math/point.md index 1478e02..4f3f837 100644 --- a/docs/ja/api/mp_math/point.md +++ b/docs/ja/api/mp_math/point.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **説明**: 判断两个点是否近似相等。 -**戻り値**: 是否近似相等 - **引数**: > - other: > - epsilon: +**戻り値**: 是否近似相等 +
ソースコード diff --git a/docs/ja/api/mp_math/utils.md b/docs/ja/api/mp_math/utils.md index c5a8402..1e3542e 100644 --- a/docs/ja/api/mp_math/utils.md +++ b/docs/ja/api/mp_math/utils.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.utils **説明**: 区间限定函数 -**戻り値**: 限制后的值 - **引数**: > - x: 待限定的值 > - min_: 最小值 > - max_: 最大值 +**戻り値**: 限制后的值 +
ソースコード @@ -40,13 +40,13 @@ def clamp(x: float, min_: float, max_: float) -> float: **説明**: 判断两个数是否近似相等。或包装一个实数,用于判断是否近似于0。 -**戻り値**: 是否近似相等 - **引数**: > - x: 数1 > - y: 数2 > - epsilon: 误差 +**戻り値**: 是否近似相等 +
ソースコード @@ -72,12 +72,12 @@ def approx(x: float, y: float=0.0, epsilon: float=APPROX) -> bool: **説明**: 获取数的符号。 -**戻り値**: 符号 + - "" - **引数**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**戻り値**: 符号 + - "" +
ソースコード @@ -109,12 +109,12 @@ def sign(x: float, only_neg: bool=False) -> str: 1 -> +1 0 -> "" -**戻り値**: 符号 + - "" - **引数**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**戻り値**: 符号 + - "" +
ソースコード diff --git a/docs/ja/api/mp_math/vector.md b/docs/ja/api/mp_math/vector.md index 0224e82..4a7e77f 100644 --- a/docs/ja/api/mp_math/vector.md +++ b/docs/ja/api/mp_math/vector.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **説明**: 判断两个向量是否近似相等。 -**戻り値**: 是否近似相等 - **引数**: > - other: > - epsilon: +**戻り値**: 是否近似相等 +
ソースコード @@ -69,11 +69,11 @@ def approx(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **説明**: 计算两个向量之间的夹角。 -**戻り値**: 夹角 - **引数**: > - other: 另一个向量 +**戻り値**: 夹角 +
ソースコード @@ -101,11 +101,11 @@ def cal_angle(self, other: 'Vector3') -> 'AnyAngle': 其余结果的模为平行四边形的面积。 -**戻り値**: 行列式的结果 - **引数**: > - other: +**戻り値**: 行列式的结果 +
ソースコード @@ -141,12 +141,12 @@ def cross(self, other: 'Vector3') -> 'Vector3': **説明**: 判断两个向量是否近似平行。 -**戻り値**: 是否近似平行 - **引数**: > - other: 另一个向量 > - epsilon: 允许的误差 +**戻り値**: 是否近似平行 +
ソースコード @@ -171,11 +171,11 @@ def is_approx_parallel(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **説明**: 判断两个向量是否平行。 -**戻り値**: 是否平行 - **引数**: > - other: 另一个向量 +**戻り値**: 是否平行 +
ソースコード @@ -370,11 +370,11 @@ def __add__(self, other): **説明**: 判断两个向量是否相等。 -**戻り値**: 是否相等 - **引数**: > - other: +**戻り値**: 是否相等 +
ソースコード diff --git a/docs/ja/api/presets/model/index.md b/docs/ja/api/presets/model/index.md index 993edda..ecdea59 100644 --- a/docs/ja/api/presets/model/index.md +++ b/docs/ja/api/presets/model/index.md @@ -9,12 +9,12 @@ title: mbcp.presets.model **説明**: 生成球体上的点集。 -**戻り値**: List[Point3]: 球体上的点集。 - **引数**: > - radius: > - density: +**戻り値**: List[Point3]: 球体上的点集。 +
ソースコード diff --git a/docs/zht/api/mp_math/equation.md b/docs/zht/api/mp_math/equation.md index 1ea5a2b..e8327e6 100644 --- a/docs/zht/api/mp_math/equation.md +++ b/docs/zht/api/mp_math/equation.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.equation **説明**: 求N元函数一阶偏导函数。这玩意不太稳定,慎用。 -**返回**: 偏导函数 - **變數説明**: > - func: 函数 > - var: 变量位置,可为整数(一阶偏导)或整数元组(高阶偏导) > - epsilon: 偏移量 +**返回**: 偏导函数 + **抛出**: > - ValueError 无效变量类型 diff --git a/docs/zht/api/mp_math/line.md b/docs/zht/api/mp_math/line.md index 5d00e23..e367dfd 100644 --- a/docs/zht/api/mp_math/line.md +++ b/docs/zht/api/mp_math/line.md @@ -35,12 +35,12 @@ def __init__(self, point: 'Point3', direction: 'Vector3'): **説明**: 判断两条直线是否近似相等。 -**返回**: 是否近似相等 - **變數説明**: > - other: 另一条直线 > - epsilon: 误差 +**返回**: 是否近似相等 +
源碼 @@ -65,11 +65,11 @@ def approx(self, other: 'Line3', epsilon: float=APPROX) -> bool: **説明**: 计算直线和直线之间的夹角。 -**返回**: 夹角弧度 - **變數説明**: > - other: 另一条直线 +**返回**: 夹角弧度 + **抛出**: > - TypeError 不支持的类型 @@ -98,11 +98,11 @@ def cal_angle(self, other: 'Line3') -> 'AnyAngle': **説明**: 计算直线和直线或点之间的距离。 -**返回**: 距离 - **變數説明**: > - other: 平行直线或点 +**返回**: 距离 + **抛出**: > - TypeError 不支持的类型 @@ -144,11 +144,11 @@ def cal_distance(self, other: 'Line3 | Point3') -> float: **説明**: 计算两条直线的交点。 -**返回**: 交点 - **變數説明**: > - other: 另一条直线 +**返回**: 交点 + **抛出**: > - ValueError 直线平行 > - ValueError 直线不共面 @@ -183,11 +183,11 @@ def cal_intersection(self, other: 'Line3') -> 'Point3': **説明**: 计算直线经过指定点p的垂线。 -**返回**: 垂线 - **變數説明**: > - point: 指定点 +**返回**: 垂线 +
源碼 @@ -211,11 +211,11 @@ def cal_perpendicular(self, point: 'Point3') -> 'Line3': **説明**: 获取直线上的点。同一条直线,但起始点和方向向量不同,则同一个t对应的点不同。 -**返回**: 点 - **變數説明**: > - t: 参数t +**返回**: 点 +
源碼 @@ -262,12 +262,12 @@ def get_parametric_equations(self) -> tuple[OneSingleVarFunc, OneSingleVarFunc, **説明**: 判断两条直线是否近似平行。 -**返回**: 是否近似平行 - **變數説明**: > - other: 另一条直线 > - epsilon: 误差 +**返回**: 是否近似平行 +
源碼 @@ -292,11 +292,11 @@ def is_approx_parallel(self, other: 'Line3', epsilon: float=1e-06) -> bool: **説明**: 判断两条直线是否平行。 -**返回**: 是否平行 - **變數説明**: > - other: 另一条直线 +**返回**: 是否平行 +
源碼 @@ -320,11 +320,11 @@ def is_parallel(self, other: 'Line3') -> bool: **説明**: 判断两条直线是否共线。 -**返回**: 是否共线 - **變數説明**: > - other: 另一条直线 +**返回**: 是否共线 +
源碼 @@ -348,11 +348,11 @@ def is_collinear(self, other: 'Line3') -> bool: **説明**: 判断点是否在直线上。 -**返回**: 是否在直线上 - **變數説明**: > - point: 点 +**返回**: 是否在直线上 +
源碼 @@ -377,11 +377,11 @@ def is_point_on(self, point: 'Point3') -> bool: **説明**: 判断两条直线是否共面。 充要条件:两直线方向向量的叉乘与两直线上任意一点的向量的点积为0。 -**返回**: 是否共面 - **變數説明**: > - other: 另一条直线 +**返回**: 是否共面 +
源碼 @@ -438,12 +438,12 @@ def simplify(self): **説明**: 工厂函数 由两点构造直线。 -**返回**: 直线 - **變數説明**: > - p1: 点1 > - p2: 点2 +**返回**: 直线 +
源碼 @@ -470,11 +470,11 @@ def from_two_points(cls, p1: 'Point3', p2: 'Point3') -> 'Line3': **説明**: 计算两条直线点集合的交集。重合线返回自身,平行线返回None,交线返回交点。 -**返回**: 交点 - **變數説明**: > - other: 另一条直线 +**返回**: 交点 +
源碼 diff --git a/docs/zht/api/mp_math/plane.md b/docs/zht/api/mp_math/plane.md index f3d51ee..7846201 100644 --- a/docs/zht/api/mp_math/plane.md +++ b/docs/zht/api/mp_math/plane.md @@ -41,11 +41,11 @@ def __init__(self, a: float, b: float, c: float, d: float): **説明**: 判断两个平面是否近似相等。 -**返回**: 是否近似相等 - **變數説明**: > - other: 另一个平面 +**返回**: 是否近似相等 +
源碼 @@ -79,11 +79,11 @@ def approx(self, other: 'Plane3') -> bool: **説明**: 计算平面与平面之间的夹角。 -**返回**: 夹角弧度 - **變數説明**: > - other: 另一个平面 +**返回**: 夹角弧度 + **抛出**: > - TypeError 不支持的类型 @@ -117,11 +117,11 @@ def cal_angle(self, other: 'Line3 | Plane3') -> 'AnyAngle': **説明**: 计算平面与平面或点之间的距离。 -**返回**: 距离 - **變數説明**: > - other: 另一个平面或点 +**返回**: 距离 + **抛出**: > - TypeError 不支持的类型 @@ -155,11 +155,11 @@ def cal_distance(self, other: 'Plane3 | Point3') -> float: **説明**: 计算两平面的交线。 -**返回**: 两平面的交线 - **變數説明**: > - other: 另一个平面 +**返回**: 两平面的交线 +
源碼 @@ -200,11 +200,11 @@ def cal_intersection_line3(self, other: 'Plane3') -> 'Line3': **説明**: 计算平面与直线的交点。 -**返回**: 交点 - **變數説明**: > - other: 不与平面平行或在平面上的直线 +**返回**: 交点 + **抛出**: > - ValueError 平面与直线平行或重合 @@ -237,11 +237,11 @@ def cal_intersection_point3(self, other: 'Line3') -> 'Point3': **説明**: 计算平行于该平面且过指定点的平面。 -**返回**: 所求平面 - **變數説明**: > - point: 指定点 +**返回**: 所求平面 +
源碼 @@ -265,11 +265,11 @@ def cal_parallel_plane3(self, point: 'Point3') -> 'Plane3': **説明**: 判断两个平面是否平行。 -**返回**: 是否平行 - **變數説明**: > - other: 另一个平面 +**返回**: 是否平行 +
源碼 @@ -319,12 +319,12 @@ def normal(self) -> 'Vector3': **説明**: 工厂函数 由点和法向量构造平面(点法式构造)。 -**返回**: 平面 - **變數説明**: > - point: 平面上的一点 > - normal: 法向量 +**返回**: 平面 +
源碼 @@ -353,13 +353,13 @@ def from_point_and_normal(cls, point: 'Point3', normal: 'Vector3') -> 'Plane3': **説明**: 工厂函数 由三点构造平面。 -**返回**: 平面 - **變數説明**: > - p1: 点1 > - p2: 点2 > - p3: 点3 +**返回**: 平面 +
源碼 @@ -390,12 +390,12 @@ def from_three_points(cls, p1: 'Point3', p2: 'Point3', p3: 'Point3') -> 'Plane3' **説明**: 工厂函数 由两直线构造平面。 -**返回**: 平面 - **變數説明**: > - l1: 直线1 > - l2: 直线2 +**返回**: 平面 +
源碼 @@ -426,12 +426,12 @@ def from_two_lines(cls, l1: 'Line3', l2: 'Line3') -> 'Plane3': **説明**: 工厂函数 由点和直线构造平面。 -**返回**: 平面 - **變數説明**: > - point: 面上一点 > - line: 面上直线,不包含点 +**返回**: 平面 +
源碼 @@ -485,11 +485,11 @@ def __and__(self, other: 'Plane3') -> 'Line3 | None': **説明**: 取两平面的交集(人话:交线) -**返回**: 不平行平面的交线,平面平行返回None - **變數説明**: > - other: +**返回**: 不平行平面的交线,平面平行返回None +
源碼 diff --git a/docs/zht/api/mp_math/point.md b/docs/zht/api/mp_math/point.md index 781e36c..cd762de 100644 --- a/docs/zht/api/mp_math/point.md +++ b/docs/zht/api/mp_math/point.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **説明**: 判断两个点是否近似相等。 -**返回**: 是否近似相等 - **變數説明**: > - other: > - epsilon: +**返回**: 是否近似相等 +
源碼 diff --git a/docs/zht/api/mp_math/utils.md b/docs/zht/api/mp_math/utils.md index 6f9bfb1..32312ca 100644 --- a/docs/zht/api/mp_math/utils.md +++ b/docs/zht/api/mp_math/utils.md @@ -7,13 +7,13 @@ title: mbcp.mp_math.utils **説明**: 区间限定函数 -**返回**: 限制后的值 - **變數説明**: > - x: 待限定的值 > - min_: 最小值 > - max_: 最大值 +**返回**: 限制后的值 +
源碼 @@ -40,13 +40,13 @@ def clamp(x: float, min_: float, max_: float) -> float: **説明**: 判断两个数是否近似相等。或包装一个实数,用于判断是否近似于0。 -**返回**: 是否近似相等 - **變數説明**: > - x: 数1 > - y: 数2 > - epsilon: 误差 +**返回**: 是否近似相等 +
源碼 @@ -72,12 +72,12 @@ def approx(x: float, y: float=0.0, epsilon: float=APPROX) -> bool: **説明**: 获取数的符号。 -**返回**: 符号 + - "" - **變數説明**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**返回**: 符号 + - "" +
源碼 @@ -109,12 +109,12 @@ def sign(x: float, only_neg: bool=False) -> str: 1 -> +1 0 -> "" -**返回**: 符号 + - "" - **變數説明**: > - x: 数 > - only_neg: 是否只返回负数的符号 +**返回**: 符号 + - "" +
源碼 diff --git a/docs/zht/api/mp_math/vector.md b/docs/zht/api/mp_math/vector.md index aa2029e..14c33bc 100644 --- a/docs/zht/api/mp_math/vector.md +++ b/docs/zht/api/mp_math/vector.md @@ -38,12 +38,12 @@ def __init__(self, x: float, y: float, z: float): **説明**: 判断两个向量是否近似相等。 -**返回**: 是否近似相等 - **變數説明**: > - other: > - epsilon: +**返回**: 是否近似相等 +
源碼 @@ -69,11 +69,11 @@ def approx(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **説明**: 计算两个向量之间的夹角。 -**返回**: 夹角 - **變數説明**: > - other: 另一个向量 +**返回**: 夹角 +
源碼 @@ -101,11 +101,11 @@ def cal_angle(self, other: 'Vector3') -> 'AnyAngle': 其余结果的模为平行四边形的面积。 -**返回**: 行列式的结果 - **變數説明**: > - other: +**返回**: 行列式的结果 +
源碼 @@ -141,12 +141,12 @@ def cross(self, other: 'Vector3') -> 'Vector3': **説明**: 判断两个向量是否近似平行。 -**返回**: 是否近似平行 - **變數説明**: > - other: 另一个向量 > - epsilon: 允许的误差 +**返回**: 是否近似平行 +
源碼 @@ -171,11 +171,11 @@ def is_approx_parallel(self, other: 'Vector3', epsilon: float=APPROX) -> bool: **説明**: 判断两个向量是否平行。 -**返回**: 是否平行 - **變數説明**: > - other: 另一个向量 +**返回**: 是否平行 +
源碼 @@ -370,11 +370,11 @@ def __add__(self, other): **説明**: 判断两个向量是否相等。 -**返回**: 是否相等 - **變數説明**: > - other: +**返回**: 是否相等 +
源碼 diff --git a/docs/zht/api/presets/model/index.md b/docs/zht/api/presets/model/index.md index a7286eb..b00a35e 100644 --- a/docs/zht/api/presets/model/index.md +++ b/docs/zht/api/presets/model/index.md @@ -9,12 +9,12 @@ title: mbcp.presets.model **説明**: 生成球体上的点集。 -**返回**: List[Point3]: 球体上的点集。 - **變數説明**: > - radius: > - density: +**返回**: List[Point3]: 球体上的点集。 +
源碼 diff --git a/litedoc/__init__.py b/litedoc/__init__.py deleted file mode 100644 index 31a9761..0000000 --- a/litedoc/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午12:52 -@Author : snowykami -@Email : snowykami@outlook.com -@File : __init__.py.py -@Software: PyCharm -""" \ No newline at end of file diff --git a/litedoc/__main__.py b/litedoc/__main__.py deleted file mode 100644 index 3237c38..0000000 --- a/litedoc/__main__.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午4:08 -@Author : snowykami -@Email : snowykami@outlook.com -@File : __main__.py -@Software: PyCharm -""" -# command line tool -# args[0] path -# -o|--output output path -# -l|--lang zh-Hans en jp default zh-Hans - - -import argparse -import os -import sys - -from litedoc.output import generate_from_module - - -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("-l", "--lang", nargs='+', default=["zh-Hans"], type=str, help="Languages of the document.") - - args = parser.parse_args() - - if not os.path.exists(args.path): - print(f"Error: The path {args.path} does not exist.") - sys.exit(1) - - if not os.path.exists(args.output): - os.makedirs(args.output) - - langs = args.lang - for lang in langs: - generate_from_module(args.path, args.output, with_top=args.contain_top, lang=lang) - - -if __name__ == '__main__': - main() diff --git a/litedoc/docstring/__init__.py b/litedoc/docstring/__init__.py deleted file mode 100644 index 323b116..0000000 --- a/litedoc/docstring/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午1:46 -@Author : snowykami -@Email : snowykami@outlook.com -@File : __init__.py.py -@Software: PyCharm -""" \ No newline at end of file diff --git a/litedoc/docstring/docstring.py b/litedoc/docstring/docstring.py deleted file mode 100644 index 4348a31..0000000 --- a/litedoc/docstring/docstring.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午1:46 -@Author : snowykami -@Email : snowykami@outlook.com -@File : docstring.py -@Software: PyCharm -""" -from typing import Optional - -from pydantic import BaseModel, Field - -from litedoc.i18n import get_text - - -class Attr(BaseModel): - name: str - type: str = "" - desc: str = "" - - -class Args(BaseModel): - name: str - type: str = "" - desc: str = "" - - -class Return(BaseModel): - desc: str = "" - - -class Exception_(BaseModel): - name: str - desc: str = "" - - -class Raise(BaseModel): - exceptions: list[Exception_] = [] - - -class Example(BaseModel): - desc: str = "" - input: str = "" - output: str = "" - - -class Docstring(BaseModel): - desc: str = "" - args: list[Args] = [] - attrs: list[Attr] = [] - return_: Optional[Return] = None - raise_: list[Exception_] = [] - example: list[Example] = [] - - def add_desc(self, desc: str): - if self.desc == "": - self.desc = desc - else: - self.desc += "\n" + desc - - def add_arg(self, name: str, type_: str = "", desc: str = ""): - self.args.append(Args(name=name, type=type_, desc=desc)) - - def add_attrs(self, name: str, type_: str = "", desc: str = ""): - self.attrs.append(Attr(name=name, type=type_, desc=desc)) - - def add_return(self, desc: str = ""): - self.return_ = Return(desc=desc) - - def add_raise(self, name: str, desc: str = ""): - self.raise_.append(Exception_(name=name, desc=desc)) - - def add_example(self, desc: str = "", input_: str = "", output: str = ""): - self.example.append(Example(desc=desc, input=input_, output=output)) - - def reduction(self) -> str: - """ - 通过解析结果还原docstring - Args: - - Returns: - - """ - ret = "" - ret += self.desc + "\n" - if self.args: - ret += "Args:\n" - for arg in self.args: - ret += f" {arg.name}: {arg.type}\n {arg.desc}\n" - if self.attrs: - ret += "Attributes:\n" - for attr in self.attrs: - ret += f" {attr.name}: {attr.type}\n {attr.desc}\n" - if self.return_: - ret += "Returns:\n" - ret += f" {self.return_.desc}\n" - - if self.raise_: - ret += "Raises:\n" - for exception in self.raise_: - ret += f" {exception.name}\n {exception.desc}\n" - - if self.example: - ret += "Examples:\n" - for example in self.example: - ret += f" {example.desc}\n Input: {example.input}\n Output: {example.output}\n" - - return ret - - def markdown(self, lang: str, indent: int = 4, is_classmethod: bool = False) -> str: - """ - 生成markdown文档 - Args: - is_classmethod: - lang: - indent: - - Returns: - - """ - PREFIX = "" * indent - ret = "" - # ret += self.desc + "\n\n" - # print(self.reduction()) - # print(self.desc, self.return_) - # 单数属性 - if self.desc: - ret += PREFIX + f"\n**{get_text(lang, 'desc')}**: {self.desc}\n" - if self.return_ is not None: - ret += PREFIX + f"\n**{get_text(lang, 'docstring.return')}**: {self.return_.desc}\n" - - # 复数属性 - if self.args: - ret += PREFIX + f"\n**{get_text(lang, 'docstring.args')}**:\n" - for arg in self.args: - ret += PREFIX + f"> - {arg.name}: {arg.type} {arg.desc}\n" - if self.attrs: - ret += PREFIX + f"\n**{get_text(lang, 'docstring.attrs')}**:\n" - for attr in self.attrs: - ret += PREFIX + f"> - {attr.name}: {attr.type} {attr.desc}\n" - if self.raise_: - ret += PREFIX + f"\n**{get_text(lang, 'docstring.raises')}**:\n" - for exception in self.raise_: - ret += PREFIX + f"> - {exception.name} {exception.desc}\n" - if self.example: - ret += PREFIX + f"\n**{get_text(lang, 'docstring.example')}**:\n" - for example in self.example: - ret += PREFIX + f" - {example.desc}\n> **{get_text(lang, 'docs.input')}**: {example.input}\n> **{get_text(lang, 'docs.output')}**: {example.output}\n" - return ret - - def __str__(self): - return self.desc diff --git a/litedoc/docstring/parser.py b/litedoc/docstring/parser.py deleted file mode 100644 index 24b7c20..0000000 --- a/litedoc/docstring/parser.py +++ /dev/null @@ -1,192 +0,0 @@ -""" -Google docstring parser for Python. -""" -from typing import Optional - -from litedoc.docstring.docstring import Docstring - - -class Parser: - ... - - -class GoogleDocstringParser(Parser): - _tokens = { - "Args" : "args", - "Arguments" : "args", - "参数" : "args", - - "Return" : "return", - "Returns" : "return", - "返回" : "return", - - "Attribute" : "attribute", - "Attributes" : "attribute", - "属性" : "attribute", - - "Raises" : "raises", - "Raise" : "raises", - "引发" : "raises", - - "Example" : "example", - "Examples" : "example", - "示例" : "example", - - "Yields" : "yields", - "Yield" : "yields", - "产出" : "yields", - - "Requires" : "requires", - "Require" : "requires", - "需要" : "requires", - - "FrontMatter": "front_matter", - "前言" : "front_matter", - } - - def __init__(self, docstring: str, indent: int = 4): - self.lines = docstring.splitlines() - self.indent = indent - self.lineno = 0 # Current line number - self.char = 0 # Current character position - - self.docstring = Docstring() - - def read_line(self, move: bool = True) -> str: - """ - 每次读取一行 - Args: - move: 是否移动指针 - Returns: - """ - if self.lineno >= len(self.lines): - return "" - line = self.lines[self.lineno] - if move: - self.lineno += 1 - return line - - def match_token(self) -> Optional[str]: - """ - 解析下一行的token - Returns: - - """ - for token in self._tokens: - line = self.read_line(move=False) - if line.strip().startswith(token): - self.lineno += 1 - return self._tokens[token] - return None - - def parse_args(self): - """ - 依次解析后面的参数行,直到缩进小于等于当前行的缩进 - """ - while line := self.match_next_line(): - if ":" in line: - name, desc = line.split(":", 1) - self.docstring.add_arg(name.strip(), desc.strip()) - else: - self.docstring.add_arg(line.strip()) - - def parse_return(self): - """ - 解析返回值行 - """ - if line := self.match_next_line(): - self.docstring.add_return(line.strip()) - - def parse_raises(self): - """ - 解析异常行 - """ - while line := self.match_next_line(): - if ":" in line: - name, desc = line.split(":", 1) - self.docstring.add_raise(name.strip(), desc.strip()) - else: - self.docstring.add_raise(line.strip()) - - def parse_example(self): - """ - 解析示例行 - """ - while line := self.match_next_line(): - if ":" in line: - name, desc = line.split(":", 1) - self.docstring.add_example(name.strip(), desc.strip()) - else: - self.docstring.add_example(line.strip()) - - def parse_attrs(self): - """ - 解析属性行 - """ - while line := self.match_next_line(): - if ":" in line: - name, desc = line.split(":", 1) - self.docstring.add_attrs(name.strip(), desc.strip()) - else: - self.docstring.add_attrs(line.strip()) - - def match_next_line(self) -> Optional[str]: - """ - 在一个子解析器中,解析下一行,直到缩进小于等于当前行的缩进 - Returns: - """ - line = self.read_line(move=False) - if line.startswith(" " * self.indent): - self.lineno += 1 - return line[self.indent:] - else: - return None - - def parse(self) -> Docstring: - """ - 逐行解析,直到遇到EOS - - 最开始未解析到的内容全部加入desc - - Returns: - - """ - add_desc = True - while self.lineno < len(self.lines): - token = self.match_token() - if token is None and add_desc: - self.docstring.add_desc(self.lines[self.lineno].strip()) - - if token is not None: - add_desc = False - - match token: - case "args": - self.parse_args() - case "return": - self.parse_return() - case "attribute": - self.parse_attrs() - case "raises": - self.parse_raises() - case "example": - self.parse_example() - case _: - self.lineno += 1 - - return self.docstring - - -class NumpyDocstringParser(Parser): - ... - - -class ReStructuredParser(Parser): - ... - - -def parse(docstring: str, parser: str = "google", indent: int = 4) -> Docstring: - if parser == "google": - return GoogleDocstringParser(docstring, indent).parse() - else: - raise ValueError(f"Unknown parser: {parser}") diff --git a/litedoc/i18n.py b/litedoc/i18n.py deleted file mode 100644 index c45aea5..0000000 --- a/litedoc/i18n.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Internationalization module. -""" -from typing import Optional, TypeAlias - -NestedDict: TypeAlias = dict[str, 'str | NestedDict'] - -i18n_dict: dict[str, NestedDict] = { - "en" : { - "docstring": { - "args" : "Arguments", - "return" : "Return", - "attribute": "Attribute", - "raises" : "Raises", - "example" : "Examples", - "yields" : "Yields", - }, - "src": "Source code", - "desc": "Description", - "type": "Type", - }, - "zh-Hans": { - "docstring": { - "args" : "参数", - "return" : "返回", - "attribute": "属性", - "raises" : "引发", - "example" : "示例", - "yields" : "产出", - }, - "src": "源代码", - "desc": "说明", - "type": "类型", - }, - "zh-Hant": { - "docstring": { - "args" : "變數説明", - "return" : "返回", - "attribute": "屬性", - "raises" : "抛出", - "example" : "範例", - "yields" : "產出", - }, - "src": "源碼", - "desc": "説明", - "type": "類型", - }, - "ja" : { - "docstring": { - "args" : "引数", - "return" : "戻り値", - "attribute": "属性", - "raises" : "例外", - "example" : "例", - "yields" : "生成", - }, - "src": "ソースコード", - "desc": "説明", - "type": "タイプ", - }, -} - - -def flat_i18n_dict(data: dict[str, NestedDict]) -> dict[str, dict[str, str]]: - """ - Flatten i18n_dict. - Examples: - ```python - { - "en": { - "docs": { - "key1": "val1", - "key2": "val2", - } - } - } - ``` - - to - - ```python - { - "en": { - "docs.key1": "val1", - "docs.key2": "val2", - } - } - ``` - Returns: - """ - ret: dict[str, dict[str, str]] = {} - - def _flat(_lang_data: NestedDict) -> dict[str, str]: - res = {} - for k, v in _lang_data.items(): - if isinstance(v, dict): - for kk, vv in _flat(v).items(): - res[f"{k}.{kk}"] = vv - else: - res[k] = v - return res - - for lang, lang_data in data.items(): - ret[lang] = _flat(lang_data) - - return ret - - -i18n_flat_dict = flat_i18n_dict(i18n_dict) - - -def get_text(lang: str, key: str, default: Optional[str] = None, fallback: Optional[str] = "en") -> str: - """ - Get text from i18n_dict. - Args: - lang: language name - key: text key - default: default text, if None return fallback language or key - fallback: fallback language, priority is higher than default - Returns: - str: text - """ - if lang in i18n_flat_dict: - if key in i18n_flat_dict[lang]: - return i18n_flat_dict[lang][key] - - if fallback is not None: - return i18n_flat_dict.get(fallback, {}).get(key, default or key) - else: - return default or key diff --git a/litedoc/output.py b/litedoc/output.py deleted file mode 100644 index ddf5750..0000000 --- a/litedoc/output.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午3:59 -@Author : snowykami -@Email : snowykami@outlook.com -@File : output.py -@Software: PyCharm -""" -import os.path - -from litedoc.style.markdown import generate -from litedoc.syntax.astparser import AstParser - - -def write_to_file(content: str, output: str) -> None: - """ - Write content to file. - - Args: - content: str, content to write. - output: str, path to output file. - """ - if not os.path.exists(os.path.dirname(output)): - os.makedirs(os.path.dirname(output)) - - with open(output, "w", encoding="utf-8") as f: - f.write(content) - - -def get_file_list(module_folder: str): - file_list = [] - for root, dirs, files in os.walk(module_folder): - for file in files: - if file.endswith((".py", ".pyi")): - file_list.append(os.path.join(root, file)) - return file_list - - -def get_relative_path(base_path: str, target_path: str) -> str: - """ - 获取相对路径 - Args: - base_path: 基础路径 - target_path: 目标路径 - """ - return os.path.relpath(target_path, base_path) - - -def generate_from_module(module_folder: str, output_dir: str, with_top: bool = False, lang: str = "zh-Hans", ignored_paths=None): - """ - 生成文档 - Args: - module_folder: 模块文件夹 - output_dir: 输出文件夹 - with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md - ignored_paths: 忽略的路径 - lang: 语言 - """ - if ignored_paths is None: - ignored_paths = [] - file_data: dict[str, str] = {} # 路径 -> 字串 - - file_list = get_file_list(module_folder) - - # 清理输出目录 - if not os.path.exists(output_dir): - os.makedirs(output_dir) - - replace_data = { - "__init__": "index", - ".py" : ".md", - } - - for pyfile_path in file_list: - if any(ignored_path.replace("\\", "/") in pyfile_path.replace("\\", "/") for ignored_path in ignored_paths): - continue - - no_module_name_pyfile_path = get_relative_path(module_folder, pyfile_path) # 去头路径 - - # markdown相对路径 - rel_md_path = pyfile_path if with_top else no_module_name_pyfile_path - for rk, rv in replace_data.items(): - rel_md_path = rel_md_path.replace(rk, rv) - - abs_md_path = os.path.join(output_dir, rel_md_path) - - # 获取模块信息 - ast_parser = AstParser(open(pyfile_path, "r", encoding="utf-8").read()) - - # 生成markdown - - front_matter = { - "title" : pyfile_path.replace("\\", "/"). - replace("/", "."). - replace(".py", ""). - replace(".__init__", ""), - - } - - md_content = generate(ast_parser, lang=lang, frontmatter=front_matter) - print(f"Generate {pyfile_path} -> {abs_md_path}") - file_data[abs_md_path] = md_content - - for fn, content in file_data.items(): - write_to_file(content, fn) diff --git a/litedoc/style/__init__.py b/litedoc/style/__init__.py deleted file mode 100644 index fb9c65f..0000000 --- a/litedoc/style/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午3:39 -@Author : snowykami -@Email : snowykami@outlook.com -@File : __init__.py.py -@Software: PyCharm -""" \ No newline at end of file diff --git a/litedoc/style/markdown.py b/litedoc/style/markdown.py deleted file mode 100644 index 61ce035..0000000 --- a/litedoc/style/markdown.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午3:39 -@Author : snowykami -@Email : snowykami@outlook.com -@File : markdown.py -@Software: PyCharm -""" -from typing import Optional - -from litedoc.syntax.astparser import AstParser -from litedoc.syntax.node import * -from litedoc.i18n import get_text - - -def generate(parser: AstParser, lang: str, frontmatter: Optional[dict] = None) -> str: - """ - Generate markdown style document from ast - You can modify this function to generate markdown style that enjoys you - Args: - parser: - lang: language - frontmatter: - Returns: - markdown style document - """ - if frontmatter is not None: - md = "---\n" - for k, v in frontmatter.items(): - md += f"{k}: {v}\n" - md += "---\n" - else: - md = "" - - # var > func > class - - """遍历函数""" - for func in parser.functions: - if func.name.startswith("_"): - continue - md += func.markdown(lang) - - """遍历类""" - - for cls in parser.classes: - md += cls.markdown(lang) - - """遍历变量""" - for var in parser.variables: - md += f"### ***var*** `{var.name} = {var.value}`\n\n" - if var.type != TypeHint.NO_TYPEHINT: - md += f"- **{get_text(lang, 'type')}**: `{var.type}`\n\n" - - if var.docs is not None: - md += f"- **{get_text(lang, 'desc')}**: {var.docs}\n\n" - - return md diff --git a/litedoc/syntax/astparser.py b/litedoc/syntax/astparser.py deleted file mode 100644 index 3007ff1..0000000 --- a/litedoc/syntax/astparser.py +++ /dev/null @@ -1,293 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午2:13 -@Author : snowykami -@Email : snowykami@outlook.com -@File : astparser.py -@Software: PyCharm -""" -import ast -import inspect - -from .node import * -from ..docstring.parser import parse - -class AstParser: - def __init__(self, code: str): - self.code = code - self.tree = ast.parse(code) - - self.classes: list[ClassNode] = [] - self.functions: list[FunctionNode] = [] - self.variables: list[AssignNode] = [] - - self.parse() - - @staticmethod - def clear_quotes(s: str) -> str: - """ - 去除类型注解中的引号 - Args: - s: - Returns: - """ - return s.replace("'", "").replace('"', "") - - def get_line_content(self, lineno: int, ignore_index_out: bool = True) -> str: - """获取代码行内容 - Args: - lineno: 行号 - ignore_index_out: 是否忽略索引越界 - Returns: - 代码行内容 - """ - if ignore_index_out: - if lineno < 1 or lineno > len(self.code.split("\n")): - return "" - return self.code.split("\n")[lineno - 1] - - @staticmethod - def match_line_docs(linecontent: str) -> str: - """匹配行内注释 - Args: - linecontent: 行内容 - Returns: - 文档字符串 - """ - in_string = False - string_char = '' - for i, char in enumerate(linecontent): - if char in ('"', "'"): - if in_string: - if char == string_char: - in_string = False - else: - in_string = True - string_char = char - elif char == '#' and not in_string: - return linecontent[i + 1:].strip() - return "" - - def parse(self): - for node in ast.walk(self.tree): - if isinstance(node, ast.ClassDef): - if not self._is_module_level_class(node): - continue - - class_node = ClassNode( - name=node.name, - docs=parse(ast.get_docstring(node)) if ast.get_docstring(node) else None, - inherits=[ast.unparse(base) for base in node.bases] - ) - self.classes.append(class_node) - - # 继续遍历类内部的函数 - for sub_node in node.body: - if isinstance(sub_node, (ast.FunctionDef, ast.AsyncFunctionDef)): - class_node.methods.append(FunctionNode( - name=sub_node.name, - docs=parse(ast.get_docstring(sub_node)) if ast.get_docstring(sub_node) else None, - posonlyargs=[ - ArgNode( - name=arg.arg, - type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT, - ) - for arg in sub_node.args.posonlyargs - ], - args=[ - ArgNode( - name=arg.arg, - type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT, - ) - for arg in sub_node.args.args - ], - kwonlyargs=[ - ArgNode( - name=arg.arg, - type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT, - ) - for arg in sub_node.args.kwonlyargs - ], - kw_defaults=[ - ConstantNode( - value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT - ) - for default in sub_node.args.kw_defaults - ], - defaults=[ - ConstantNode( - value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT - ) - for default in sub_node.args.defaults - ], - return_=self.clear_quotes(ast.unparse(sub_node.returns).strip()) if sub_node.returns else TypeHint.NO_RETURN, - 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 - )) - # elif isinstance(sub_node, (ast.Assign, ast.AnnAssign)): - # if isinstance(sub_node, ast.Assign): - # class_node.attrs.append(AttrNode( - # name=sub_node.targets[0].id, # type: ignore - # type=TypeHint.NO_TYPEHINT, - # value=ast.unparse(sub_node.value).strip() - # )) - # elif isinstance(sub_node, ast.AnnAssign): - # class_node.attrs.append(AttrNode( - # name=sub_node.target.id, - # type=ast.unparse(sub_node.annotation).strip(), - # value=ast.unparse(sub_node.value).strip() if sub_node.value else TypeHint.NO_DEFAULT - # )) - # else: - # raise ValueError(f"Unsupported node type: {type(sub_node)}") - - elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): - # 仅打印模块级别的函数 - if not self._is_module_level_function(node): - continue - - self.functions.append(FunctionNode( - name=node.name, - docs=parse(ast.get_docstring(node)) if ast.get_docstring(node) else None, - posonlyargs=[ - ArgNode( - name=arg.arg, - type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT, - ) - for arg in node.args.posonlyargs - ], - args=[ - ArgNode( - name=arg.arg, - type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT, - ) - for arg, default in zip(node.args.args, node.args.defaults) - ], - kwonlyargs=[ - ArgNode( - name=arg.arg, - type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT, - ) - for arg in node.args.kwonlyargs - ], - kw_defaults=[ - ConstantNode( - value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT - ) - for default in node.args.kw_defaults - ], - defaults=[ - ConstantNode( - value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT - ) - for default in node.args.defaults - ], - 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() - )) - - elif isinstance(node, (ast.Assign, ast.AnnAssign)): - if not self._is_module_level_variable2(node): - continue - else: - pass - lineno = node.lineno - prev_line = self.get_line_content(lineno - 1).strip() - curr_line = self.get_line_content(lineno).strip() - next_line = self.get_line_content(lineno + 1).strip() - - # 获取文档字符串,优先检测下行""" - if next_line.startswith('"""'): - docs = next_line[3:-3] - elif prev_line.startswith('"""'): - docs = prev_line[3:-3] - else: - curr_docs = self.match_line_docs(curr_line) - if curr_docs: - docs = curr_docs - else: - docs = None - - # if isinstance(node, ast.Assign): - # for target in node.targets: - # if isinstance(target, ast.Name): - # self.variables.append(AssignNode( - # name=target.id, - # value=ast.unparse(node.value).strip(), - # type=ast.unparse(node.annotation).strip() if isinstance(node, ast.AnnAssign) else TypeHint.NO_TYPEHINT - # )) - if isinstance(node, ast.AnnAssign): - self.variables.append(AssignNode( - name=node.target.id, - value=ast.unparse(node.value).strip() if node.value else TypeHint.NO_DEFAULT, - type=ast.unparse(node.annotation).strip(), - docs=docs - )) - - def _is_module_level_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef): - for parent in ast.walk(self.tree): - if isinstance(parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): - if node in parent.body: - return False - return True - - def _is_module_level_class(self, node: ast.ClassDef): - for parent in ast.walk(self.tree): - if isinstance(parent, ast.ClassDef): - if node in parent.body: - return False - return True - - def _is_module_level_variable(self, node: ast.Assign | ast.AnnAssign): - """在类方法或函数内部的变量不会被记录""" - - # for parent in ast.walk(self.tree): - # if isinstance(parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): - # if node in parent.body: - # return False - # else: - # for sub_node in parent.body: - # if isinstance(sub_node, (ast.FunctionDef, ast.AsyncFunctionDef)): - # if node in sub_node.body: - # return False - # return True - # 递归检查 - def _check(_node, _parent): - if isinstance(_parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): - if _node in _parent.body: - return False - else: - for sub_node in _parent.body: - if isinstance(sub_node, (ast.FunctionDef, ast.AsyncFunctionDef)): - return _check(_node, sub_node) - return True - - for parent in ast.walk(self.tree): - if not _check(node, parent): - return False - return True - - def _is_module_level_variable2(self, node: ast.Assign | ast.AnnAssign) -> bool: - """ - 检查变量是否在模块级别定义。 - """ - for parent in ast.walk(self.tree): - if isinstance(parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): - if node in parent.body: - return False - return True - - def __str__(self): - s = "" - for cls in self.classes: - s += f"class {cls.name}:\n" - for func in self.functions: - s += f"def {func.name}:\n" - for var in self.variables: - s += f"{var.name} = {var.value}\n" - return s diff --git a/litedoc/syntax/node.py b/litedoc/syntax/node.py deleted file mode 100644 index 4891b10..0000000 --- a/litedoc/syntax/node.py +++ /dev/null @@ -1,314 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午2:14 -@Author : snowykami -@Email : snowykami@outlook.com -@File : node.py -@Software: PyCharm -""" -from typing import Literal, Optional -from enum import Enum - -from pydantic import BaseModel, Field - -from litedoc.docstring.docstring import Docstring -from litedoc.i18n import get_text - - -class TypeHint: - NO_TYPEHINT = "NO_TYPE_HINT" - NO_DEFAULT = "NO_DEFAULT" - NO_RETURN = "NO_RETURN" - - -class AssignNode(BaseModel): - """ - AssignNode is a pydantic model that represents an assignment. - Attributes: - name: str - The name of the assignment. - type: str = "" - The type of the assignment. - value: str - The value of the assignment. - """ - name: str - type: str = "" - value: str - docs: Optional[str] = "" - - -class ArgNode(BaseModel): - """ - ArgNode is a pydantic model that represents an argument. - Attributes: - name: str - The name of the argument. - type: str = "" - The type of the argument. - default: str = "" - The default value of the argument. - """ - name: str - type: str = TypeHint.NO_TYPEHINT - - -class AttrNode(BaseModel): - """ - AttrNode is a pydantic model that represents an attribute. - Attributes: - name: str - The name of the attribute. - type: str = "" - The type of the attribute. - value: str = "" - The value of the attribute - """ - name: str - type: str = "" - value: str = "" - - -class ImportNode(BaseModel): - """ - ImportNode is a pydantic model that represents an import statement. - Attributes: - name: str - The name of the import statement. - as_: str = "" - The alias of the import - """ - name: str - as_: str = "" - - -class ConstantNode(BaseModel): - """ - ConstantNode is a pydantic model that represents a constant. - Attributes: - value: str - The value of the constant. - """ - value: str - - -class FunctionNode(BaseModel): - """ - FunctionNode is a pydantic model that represents a function. - Attributes: - name: str - The name of the function. - docs: str = "" - The docstring of the function. - args: list[ArgNode] = [] - The arguments of the function. - return_: ReturnNode = None - The return value of the function. - decorators: list[str] = [] - The decorators of the function. - is_async: bool = False - Whether the function is asynchronous. - """ - name: str - docs: Optional[Docstring] = None - - posonlyargs: list[ArgNode] = [] - args: list[ArgNode] = [] - kwonlyargs: list[ArgNode] = [] - kw_defaults: list[ConstantNode] = [] - defaults: list[ConstantNode] = [] - - return_: str = TypeHint.NO_RETURN - decorators: list[str] = [] - src: str - is_async: bool = False - is_classmethod: bool = False - - magic_methods: dict[str, str] = { - "__add__" : "+", - "__radd__" : "+", - "__sub__" : "-", - "__rsub__" : "-", - "__mul__" : "*", - "__rmul__" : "*", - "__matmul__" : "@", - "__rmatmul__": "@", - "__mod__" : "%", - "__truediv__": "/", - "__rtruediv__": "/", - "__neg__" : "-", - } # 魔术方法, 例如运算符 - - def is_private(self): - """ - Check if the function or method is private. - Returns: - bool: True if the function or method is private, False otherwise. - """ - return self.name.startswith("_") - - def is_builtin(self): - """ - Check if the function or method is a builtin function or method. - Returns: - bool: True if the function or method is a builtin function or method, False otherwise. - """ - return self.name.startswith("__") and self.name.endswith("__") - - def markdown(self, lang: str, indent: int = 0) -> str: - """ - Args: - indent: int - The number of spaces to indent the markdown. - lang: str - The language of the - Returns: - markdown style document - """ - self.complete_default_args() - PREFIX = "" * indent - # if is_classmethod: - # PREFIX = "- #" - func_type = "func" if not self.is_classmethod else "method" - - md = "" - # 装饰器部分 - if len(self.decorators) > 0: - for decorator in self.decorators: - md += PREFIX + f"### `@{decorator}`\n" - - if self.is_async: - md += PREFIX + f"### *async {func_type}* " - else: - md += PREFIX + f"### *{func_type}* " - - # code start - # 配对位置参数和位置参数默认值,无默认值用TypeHint.NO_DEFAULT - args: list[str] = [] # 可直接", ".join(args)得到位置参数部分 - arg_i = 0 - - if len(self.posonlyargs) > 0: - for arg in self.posonlyargs: - arg_text = f"{arg.name}" - if arg.type != TypeHint.NO_TYPEHINT: - arg_text += f": {arg.type}" - arg_default = self.defaults[arg_i].value - if arg_default != TypeHint.NO_DEFAULT: - arg_text += f" = {arg_default}" - args.append(arg_text) - arg_i += 1 - # 加位置参数分割符 / - args.append("/") - - for arg in self.args: - arg_text = f"{arg.name}" - if arg.type != TypeHint.NO_TYPEHINT: - arg_text += f": {arg.type}" - arg_default = self.defaults[arg_i].value - if arg_default != TypeHint.NO_DEFAULT: - arg_text += f" = {arg_default}" - args.append(arg_text) - arg_i += 1 - - if len(self.kwonlyargs) > 0: - # 加关键字参数分割符 * - args.append("*") - for arg, kw_default in zip(self.kwonlyargs, self.kw_defaults): - arg_text = f"{arg.name}" - if arg.type != TypeHint.NO_TYPEHINT: - arg_text += f": {arg.type}" - if kw_default.value != TypeHint.NO_DEFAULT: - arg_text += f" = {kw_default.value}" - args.append(arg_text) - - """魔法方法""" - if self.name in self.magic_methods: - if len(args) == 2: - md += f"`{args[0]} {self.magic_methods[self.name]} {args[1]}" - elif len(args) == 1: - md += f"`{self.magic_methods[self.name]} {args[0]}" - if self.return_ != TypeHint.NO_RETURN: - md += f" => {self.return_}" - else: - md += f"`{self.name}(" # code start - md += ", ".join(args) + ")" - if self.return_ != TypeHint.NO_RETURN: - md += f" -> {self.return_}" - - md += "`\n\n" # code end - - """此处预留docstring""" - if self.docs is not None: - md += f"\n{self.docs.markdown(lang, indent)}\n" - else: - pass - # 源码展示 - md += PREFIX + f"\n
\n {get_text(lang, 'src')} \n\n```python\n{self.src}\n```\n
\n\n" - - return md - - def complete_default_args(self): - """ - 补全位置参数默认值,用无默认值插入 - Returns: - - """ - num = len(self.args) + len(self.posonlyargs) - len(self.defaults) - self.defaults = [ConstantNode(value=TypeHint.NO_DEFAULT) for _ in range(num)] + self.defaults - - def __str__(self): - return f"def {self.name}({', '.join([f'{arg.name}: {arg.type} = {arg.default}' for arg in self.args])}) -> {self.return_}" - - -class ClassNode(BaseModel): - """ - ClassNode is a pydantic model that represents a class. - Attributes: - name: str - The name of the class. - docs: str = "" - The docstring of the class. - attrs: list[AttrNode] = [] - The attributes of the class. - methods: list[MethodNode] = [] - The methods of the class. - inherits: list["ClassNode"] = [] - The classes that the class inherits from - """ - name: str - docs: Optional[Docstring] = None - attrs: list[AttrNode] = [] - methods: list[FunctionNode] = [] - inherits: list[str] = [] - - def markdown(self, lang: str) -> str: - """ - 返回类的markdown文档 - Args: - lang: str - The language of the - Returns: - markdown style document - """ - hidden_methods = [ - "__str__", - "__repr__", - ] - md = "" - md += f"### **class** `{self.name}" - if len(self.inherits) > 0: - md += f"({', '.join([cls for cls in self.inherits])})" - md += "`\n" - for method in self.methods: - if method.name in hidden_methods: - continue - md += method.markdown(lang, 2) - for attr in self.attrs: - if attr.type == TypeHint.NO_TYPEHINT: - md += f"#### ***attr*** `{attr.name} = {attr.value}`\n\n" - else: - md += f"#### ***attr*** `{attr.name}: {attr.type} = {attr.value}`\n\n" - - return md diff --git a/litedoc/translator.py b/litedoc/translator.py deleted file mode 100644 index d9f93e0..0000000 --- a/litedoc/translator.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/29 下午12:02 -@Author : snowykami -@Email : snowykami@outlook.com -@File : translator.py -@Software: PyCharm -""" -from typing import Optional - -from translate import Translator # type: ignore - -# 特殊映射语言 -i18n_lang2googletrans_lang = { - "zh-Hans": "zh-cn", - "zh-Hant": "zh-tw", - "en" : "en", -} - - -def get_google_lang(lang: str) -> str: - """ - Get google translate language - Args: - lang: language - Returns: - google translate language - """ - return i18n_lang2googletrans_lang.get(lang, lang) - - -def translate(text: str, lang: str, source_lang: str) -> str: - """ - Translate text to target language - Args: - source_lang: - text: text - lang: target language - Returns: - translated text - """ - if lang == source_lang: - return text - google_lang = get_google_lang(lang) - return Translator(to_lang=google_lang, from_lang=source_lang).translate(text) diff --git a/main.py b/main.py deleted file mode 100644 index 724f01b..0000000 --- a/main.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import overload - - -class Vector: - def __init__(self, x: float, y: float, z: float): - """ - 向量 - Args: - x: x轴分量 - y: y轴分量 - z: z轴分量 - """ - self.x = x - self.y = y - self.z = z - @overload - def __mul__(self, other: float) -> 'Vector': - ... - - @overload - def __mul__(self, other: 'Vector') -> float: - ... - - def __mul__(self, other): - """ - 点乘和数乘 - Args: - other: - - Returns: - """ - if isinstance(other, (float, int)): - return Vector(self.x * other, self.y * other, self.z * other) - elif isinstance(other, Vector): - return self.x * other.x + self.y * other.y + self.z * other.z - else: - raise TypeError(f"unsupported operand type(s) for *: 'Vector' and '{type(other)}'") - - def __rmul__(self, other: float) -> 'Vector': - return self.__mul__(other) - - -v: Vector = Vector(1, 2, 3) * 3.0 -v2: Vector = 3.0 * Vector(1, 2, 3) - -print(v, v2) \ No newline at end of file diff --git a/make_docs.py b/make_docs.py deleted file mode 100644 index 54a1301..0000000 --- a/make_docs.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/28 下午12:50 -@Author : snowykami -@Email : snowykami@outlook.com -@File : make_docs.py -@Software: PyCharm -""" \ No newline at end of file diff --git a/mkdoc.py b/mkdoc.py deleted file mode 100644 index 72bf946..0000000 --- a/mkdoc.py +++ /dev/null @@ -1,346 +0,0 @@ -# -*- coding: utf-8 -*- -""" -MkDocs文档生成脚本 -用法 python docs/mkdoc.py -""" - -import ast -import os -import shutil -from typing import Any -from enum import Enum -from pydantic import BaseModel - -NO_TYPE_ANY = "Any" -NO_TYPE_HINT = "NoTypeHint" - - -class DefType(Enum): - FUNCTION = "function" - METHOD = "method" - STATIC_METHOD = "staticmethod" - CLASS_METHOD = "classmethod" - PROPERTY = "property" - - -class FunctionInfo(BaseModel): - name: str - args: list[tuple[str, str]] - return_type: str - docstring: str - source_code: str = "" - - type: DefType - """若为类中def,则有""" - is_async: bool - - -class AttributeInfo(BaseModel): - name: str - type: str - value: Any = None - docstring: str = "" - - -class ClassInfo(BaseModel): - name: str - docstring: str - methods: list[FunctionInfo] - attributes: list[AttributeInfo] - inherit: list[str] - - -class ModuleInfo(BaseModel): - module_path: str - """点分割模块路径 例如 liteyuki.bot""" - - functions: list[FunctionInfo] - classes: list[ClassInfo] - attributes: list[AttributeInfo] - docstring: str - - -def get_relative_path(base_path: str, target_path: str) -> str: - """ - 获取相对路径 - Args: - base_path: 基础路径 - target_path: 目标路径 - """ - return os.path.relpath(target_path, base_path) - - -def write_to_files(file_data: dict[str, str]): - """ - 输出文件 - Args: - file_data: 文件数据 相对路径 - """ - - for rp, data in file_data.items(): - - if not os.path.exists(os.path.dirname(rp)): - os.makedirs(os.path.dirname(rp)) - with open(rp, 'w', encoding='utf-8') as f: - f.write(data) - - -def get_file_list(module_folder: str): - file_list = [] - for root, dirs, files in os.walk(module_folder): - for file in files: - if file.endswith((".py", ".pyi")): - file_list.append(os.path.join(root, file)) - return file_list - - -def get_module_info_normal(file_path: str, ignore_private: bool = True) -> ModuleInfo: - """ - 获取函数和类 - Args: - file_path: Python 文件路径 - ignore_private: 忽略私有函数和类 - Returns: - 模块信息 - """ - - with open(file_path, 'r', encoding='utf-8') as file: - file_content = file.read() - tree = ast.parse(file_content) - - dot_sep_module_path = file_path.replace(os.sep, '.').replace(".py", "").replace(".pyi", "") - module_docstring = ast.get_docstring(tree) - - module_info = ModuleInfo( - module_path=dot_sep_module_path, - functions=[], - classes=[], - attributes=[], - docstring=module_docstring if module_docstring else "" - ) - - for node in ast.walk(tree): - if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): - # 模块函数 且不在类中 若ignore_private=True则忽略私有函数 - if not any(isinstance(parent, ast.ClassDef) for parent in ast.iter_child_nodes(node)) and (not ignore_private or not node.name.startswith('_')): - - # 判断第一个参数是否为self或cls,后期用其他办法优化 - if node.args.args: - first_arg = node.args.args[0] - if first_arg.arg in ("self", "cls"): - continue - - function_docstring = ast.get_docstring(node) - - func_info = FunctionInfo( - name=node.name, - args=[(arg.arg, ast.unparse(arg.annotation) if arg.annotation else NO_TYPE_ANY) for arg in node.args.args], - return_type=ast.unparse(node.returns) if node.returns else "None", - docstring=function_docstring if function_docstring else "", - type=DefType.FUNCTION, - is_async=isinstance(node, ast.AsyncFunctionDef), - source_code=ast.unparse(node) - ) - module_info.functions.append(func_info) - - elif isinstance(node, ast.ClassDef): - # 模块类 - class_docstring = ast.get_docstring(node) - - class_info = ClassInfo( - name=node.name, - docstring=class_docstring if class_docstring else "", - methods=[], - attributes=[], - inherit=[ast.unparse(base) for base in node.bases] - ) - - for class_node in node.body: - # methods [instance, static, class, property],保留__init__方法 - if isinstance(class_node, ast.FunctionDef) and (not ignore_private or not class_node.name.startswith('_') or class_node.name == "__init__"): - method_docstring = ast.get_docstring(class_node) - def_type = DefType.METHOD - if class_node.decorator_list: - if any(isinstance(decorator, ast.Name) and decorator.id == "staticmethod" for decorator in class_node.decorator_list): - def_type = DefType.STATIC_METHOD - elif any(isinstance(decorator, ast.Name) and decorator.id == "classmethod" for decorator in class_node.decorator_list): - def_type = DefType.CLASS_METHOD - elif any(isinstance(decorator, ast.Name) and decorator.id == "property" for decorator in class_node.decorator_list): - def_type = DefType.PROPERTY - class_info.methods.append(FunctionInfo( - name=class_node.name, - args=[(arg.arg, ast.unparse(arg.annotation) if arg.annotation else NO_TYPE_ANY) for arg in class_node.args.args], - return_type=ast.unparse(class_node.returns) if class_node.returns else "None", - docstring=method_docstring if method_docstring else "", - type=def_type, - is_async=isinstance(class_node, ast.AsyncFunctionDef), - source_code=ast.unparse(class_node) - )) - # attributes - elif isinstance(class_node, ast.Assign): - for target in class_node.targets: - if isinstance(target, ast.Name): - class_info.attributes.append(AttributeInfo( - name=target.id, - type=ast.unparse(class_node.value) - )) - module_info.classes.append(class_info) - - elif isinstance(node, ast.Assign): - # 检查是否在类或函数中 - if not any(isinstance(parent, (ast.ClassDef, ast.FunctionDef)) for parent in ast.iter_child_nodes(node)): - # 模块属性变量 - for target in node.targets: - if isinstance(target, ast.Name) and (not ignore_private or not target.id.startswith('_')): - attr_type = NO_TYPE_HINT - if isinstance(node.value, ast.AnnAssign) and node.value.annotation: - attr_type = ast.unparse(node.value.annotation) - module_info.attributes.append(AttributeInfo( - name=target.id, - type=attr_type, - value=ast.unparse(node.value) if node.value else None - )) - - return module_info - - -def generate_markdown(module_info: ModuleInfo, front_matter=None, lang: str = "zh-CN") -> str: - """ - 生成模块的Markdown - 你可在此自定义生成的Markdown格式 - Args: - module_info: 模块信息 - front_matter: 自定义选项title, index, icon, category - lang: 语言 - Returns: - Markdown 字符串 - """ - - content = "" - - front_matter = "---\n" + "\n".join([f"{k}: {v}" for k, v in front_matter.items()]) + "\n---\n\n" - - content += front_matter - - # 模块函数 - for func in module_info.functions: - args_with_type = [f"{arg[0]}: {arg[1]}" if arg[1] else arg[0] for arg in func.args] - content += f"### ***{'async ' if func.is_async else ''}def*** `{func.name}({', '.join(args_with_type)}) -> {func.return_type}`\n\n" - - func.docstring = func.docstring.replace("\n", "\n\n") - content += f"{func.docstring}\n\n" - - # 函数源代码可展开区域 - content += f"
\n源代码\n\n```python\n{func.source_code}\n```\n
\n\n" - - # 类 - for cls in module_info.classes: - if cls.inherit: - inherit = f"({', '.join(cls.inherit)})" if cls.inherit else "" - content += f"### ***class*** `{cls.name}{inherit}`\n\n" - else: - content += f"### ***class*** `{cls.name}`\n\n" - - cls.docstring = cls.docstring.replace("\n", "\n\n") - content += f"{cls.docstring}\n\n" - for method in cls.methods: - # 类函数 - - if method.type != DefType.METHOD: - args_with_type = [f"{arg[0]}: {arg[1]}" if arg[1] else arg[0] for arg in method.args] - content += f"###   ***@{method.type.value}***\n" - else: - # self不加类型提示 - args_with_type = [f"{arg[0]}: {arg[1]}" if arg[1] and arg[0] != "self" else arg[0] for arg in method.args] - content += f"###   ***{'async ' if method.is_async else ''}def*** `{method.name}({', '.join(args_with_type)}) -> {method.return_type}`\n\n" - - method.docstring = method.docstring.replace("\n", "\n\n") - content += f" {method.docstring}\n\n" - # 函数源代码可展开区域 - - if lang == "zh-CN": - TEXT_SOURCE_CODE = "源代码" - else: - TEXT_SOURCE_CODE = "Source Code" - - content += f"
\n{TEXT_SOURCE_CODE}\n\n```python\n{method.source_code}\n```\n
\n\n" - for attr in cls.attributes: - content += f"###   ***attr*** `{attr.name}: {attr.type}`\n\n" - - # 模块属性 - for attr in module_info.attributes: - if attr.type == NO_TYPE_HINT: - content += f"### ***var*** `{attr.name} = {attr.value}`\n\n" - else: - content += f"### ***var*** `{attr.name}: {attr.type} = {attr.value}`\n\n" - - attr.docstring = attr.docstring.replace("\n", "\n\n") - content += f"{attr.docstring}\n\n" - - return content - - -def generate_docs(module_folder: str, output_dir: str, with_top: bool = False, lang: str = "zh-CN", ignored_paths=None): - """ - 生成文档 - Args: - module_folder: 模块文件夹 - output_dir: 输出文件夹 - with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md - ignored_paths: 忽略的路径 - lang: 语言 - """ - if ignored_paths is None: - ignored_paths = [] - file_data: dict[str, str] = {} # 路径 -> 字串 - - file_list = get_file_list(module_folder) - - # 清理输出目录 - shutil.rmtree(output_dir, ignore_errors=True) - os.mkdir(output_dir) - - replace_data = { - "__init__": "index", - ".py" : ".md", - } - - for pyfile_path in file_list: - if any(ignored_path.replace("\\", "/") in pyfile_path.replace("\\", "/") for ignored_path in ignored_paths): - continue - - no_module_name_pyfile_path = get_relative_path(module_folder, pyfile_path) # 去头路径 - - # markdown相对路径 - rel_md_path = pyfile_path if with_top else no_module_name_pyfile_path - for rk, rv in replace_data.items(): - rel_md_path = rel_md_path.replace(rk, rv) - - abs_md_path = os.path.join(output_dir, rel_md_path) - - # 获取模块信息 - module_info = get_module_info_normal(pyfile_path) - - # 生成markdown - - if "index" in abs_md_path: - front_matter = { - "title" : module_info.module_path.replace(".__init__", ""), - } - else: - front_matter = { - "title" : module_info.module_path - } - - md_content = generate_markdown(module_info, front_matter) - print(f"Generate {pyfile_path} -> {abs_md_path}") - file_data[abs_md_path] = md_content - - write_to_files(file_data) - - -# 入口脚本 -if __name__ == '__main__': - # 这里填入你的模块路径 - generate_docs('mbcp', 'docs/api', with_top=False, ignored_paths=["liteyuki/plugins"], lang="zh-CN") - # generate_docs('mbcp', 'docs/en/api', with_top=False, ignored_paths=["liteyuki/plugins"], lang="en") diff --git a/pyproject.toml b/pyproject.toml index 07f6ef8..72baba0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,3 +26,7 @@ distribution = true dev = [ "translate>=3.6.1", ] +[[tool.pdm.source]] +name = "pypi" +url = "https://pypi.org/simple" +include_packages = ["litedoc"] \ No newline at end of file