diff --git a/.gitignore b/.gitignore index 3806351343acbd0d70c46d708045009a11513ca6..8748abd6209fecc933a3aad50f754ee90fa277ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ out build +publish temp __pycache__ *.egg-info diff --git a/after_build.py b/after_build.py new file mode 100644 index 0000000000000000000000000000000000000000..8753c72e83d45baf66c8df316970b08134d2bc83 --- /dev/null +++ b/after_build.py @@ -0,0 +1,102 @@ +import os +from bs4 import BeautifulSoup + +path = "out\\doc\\" +api_path_list = [] + +for i in os.listdir(path): + if i.startswith("API_reference"): + api_path_list.append(path + i) + + +def find_html_files(path): + html_files = [] + for root, dirs, files in os.walk(path): + for file in files: + if file.endswith('.html'): + html_files.append(os.path.join(root, file)) + return html_files + + +def replace_version(file_path): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # 解析 HTML + soup = BeautifulSoup(content, "html.parser") + + # 查找 active 标签中的文本 + active_tag_list = soup.find_all("li", class_="active") + + # 筛选多余选项 + for i in active_tag_list: + active_content = i.text.strip() + if active_content.find("中文") == -1 and active_content.find("English") == -1: + break + # 获取version对应的标签 + version_tag = soup.find("a", string="Version") + + # 替换标签内容 + if version_tag: + version_tag.string = active_content + + # 将修改后的 HTML 写回文件 + with open(file_path, 'w', encoding='utf-8') as file: + file.write(soup.prettify()) + + +# 增加BSP相关版本选择器 +def add_bsp_selecter(file_path): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # 解析 HTML + soup = BeautifulSoup(content, "html.parser") + + toc_content_div = soup.find("div", id="toc-content") + + + # 创建一个新的 div 标签 + pagination_div = soup.new_tag('div', class_='pagination') + + # 创建 span 标签 + span_tag = soup.new_tag('span') + span_tag.string = '型号选择:' + + # 创建 select 标签 + select_tag = soup.new_tag('select', id='pageSelect') + + # 将 span 和 select 标签添加到 pagination_div 中 + pagination_div.append(span_tag) + pagination_div.append(select_tag) + + # 在 toc_content_div 之前插入新的 div 标签 + toc_content_div.insert_before(pagination_div) + + # 将修改后的 HTML 写回文件 + with open(file_path, 'w', encoding='utf-8') as file: + file.write(soup.prettify()) + + + +def main(): + html_files = [] + for path in api_path_list: + html_files += find_html_files(path) + + for file in html_files: + print(file) + replace_version(file) + + + bsp_filter = ["machine.I2C", "machine.SPI", "machine.Pin", "machine.UART", "machine.KeyPad", "misc.ADC"] + for path in api_path_list: + for i in bsp_filter: + if path.find(i) != -1: + print(path) + add_bsp_selecter(path) + + + +if __name__ == "__main__": + main() diff --git a/docs/API_reference/zh/peripherals/machine.SPI.md b/docs/API_reference/zh/peripherals/machine.SPI.md index 571c44606ad4726f5ad30c1c74f1d04b36a6c23a..17bf2b45e13e1f87e3c3760224fd6fb4fe86b593 100644 --- a/docs/API_reference/zh/peripherals/machine.SPI.md +++ b/docs/API_reference/zh/peripherals/machine.SPI.md @@ -88,7 +88,7 @@ -
class machine.I2C(I2Cn, MODE)
参数描述:
@@ -183,7 +183,35 @@ -SPI编号 | +CS引脚 | +CLK引脚 | +MOSI引脚 | +MISO引脚 | +
---|---|---|---|---|
SPI0 | +引脚58 | +引脚61 | +引脚59 | +引脚60 | +
SPI1 | +引脚4 | +引脚1 | +引脚3 | +引脚2 | +
SPI编号 | @@ -406,7 +434,62 @@
---|
SPI编号 | +Group | +CS引脚 | +CLK引脚 | +MOSI引脚 | +MISO引脚 | +
---|---|---|---|---|---|
SPI0 | +Group0 | +引脚31 | +引脚30 | +引脚32 | +引脚33 | +
SPI0 | +Group1 | +引脚52 | +引脚53 | +引脚50 | +引脚51 | +
SPI1 | +Group0 | +引脚52 | +引脚53 | +引脚50 | +引脚51 | +
SPI1 | +Group1 | +引脚69 | +引脚68 | +引脚85 | +引脚84 | +
SPI2 | +NULL | +引脚76 | +引脚77 | +引脚78 | +引脚16 | +
SPI编号 | @@ -489,7 +572,35 @@
---|
SPI编号 | +CS引脚 | +CLK引脚 | +MOSI引脚 | +MISO引脚 | +
---|---|---|---|---|
SPI0 | +引脚37 | +引脚40 | +引脚38 | +引脚39 | +
SPI1 | +引脚26 | +引脚27 | +引脚25 | +引脚24 | +
SPI编号 | @@ -678,7 +789,42 @@
---|
SPI编号 | +CS引脚 | +CLK引脚 | +MOSI引脚 | +MISO引脚 | +
---|---|---|---|---|
SPI0 | +引脚31 | +引脚30 | +引脚32 | +引脚33 | +
SPI1 | +引脚52 | +引脚53 | +引脚50 | +引脚51 | +
SPI2 | +引脚74 | +引脚75 | +引脚76 | +引脚77 | +
SPI编号 | diff --git a/publish.py b/publish.py new file mode 100644 index 0000000000000000000000000000000000000000..8ee29f3c91893e8343b6a8bff4ae0203073059ff --- /dev/null +++ b/publish.py @@ -0,0 +1,315 @@ +''' +@Time : 2025/1/19 10:07 +@File : publish.py +@Software: +@Desc : 根据releaes tag创建待编译的文件夹,同步更新文件夹下的配置文件, +@Desc : 1. 通过gitee api获取tag列表, 2. 通过tag列表对应的commit获取版本文件, 3. 创建待编译的文件夹, 4. 同步更新文件夹下的配置文件 5. 更新全局配置文件 + + +''' +import time +import json +import requests +import zipfile +import os, shutil +import subprocess +from bs4 import BeautifulSoup, NavigableString + + +repo_url = "https://gitee.com/qpy-doc-center/api_reference.git" +access_token = "affe431c03995bd7d5bd4683e6e23096" + + +def get_tag_list(): + tag_api_url = "https://gitee.com/api/v5/repos/{owner}/{repo}/tags?sort=updated&direction=asc&page=1".format(owner="qpy-doc-center", repo="api_reference") + headers = { + "Authorization": "token " + access_token, + "Content-Type": "application/json" + } + response = requests.get(tag_api_url, headers=headers) + if response.status_code == 200: + tag_list = [] + for i in response.json(): + tag_list.append({"name": i["name"], "commit_sha": i["commit"]["sha"]}) + return tag_list + + else: + print("请求失败, 状态码: ", response.status_code) + return [] + + +def get_commit_file(name, commit_sha): + commit_api_url = "https://gitee.com/api/v5/repos/{owner}/{repo}/zipball".format(owner="qpy-doc-center", repo="api_reference") + file_path = name + ".zip" + commit_api_url = commit_api_url + "?access_token=" + access_token + "&ref=" + commit_sha + headers = { + "Content-Type": "application/json" + } + response = requests.get(commit_api_url, headers=headers) + if response.status_code == 200: + with open(file_path, "wb") as f: + for chunk in response.iter_content(chunk_size=16384): + f.write(chunk) + return file_path + else: + print("请求失败, 状态码: ", response.status_code) + return None + + +def set_site(page): + with open("../site_config.json", "r", encoding="utf-8") as f: + site_data = json.load(f) + + # 新增中文页面路由和英文页面路由 + site_data["route"]["docs"][page] = "docs" + page + site_data["translate"]["docs"][page] = [{ + "url": page.replace("zh", "en"), + "src": "docs" + page.replace("zh", "en"), + }] + with open("../site_config.json", "w", encoding="utf-8") as f: + json.dump(site_data, f, ensure_ascii=False, indent=4) + + +def set_config(tag, src): + try: + # 修改中文页面的Version下拉框 + with open("../docs/" + src + "/zh/config.json", "r", encoding="utf-8") as f: + config_data = json.load(f) + + items = [] + for index, i in enumerate(tag): + folder_url = "latest" if index == len(tag) - 1 else i["name"] + if folder_url == "latest": + folder_url = "" # 不使用latest url,因为避免修改存量的链接 + else: + folder_url = "_" + folder_url # 带版本的链接 + items.insert(0, { + "url": "/API_reference" + folder_url + "/zh/", + "label": i["name"] + "(latest)" if index == len(tag) - 1 else i["name"] + }) + + config_data["navbar"] = { + "items":[{ + "label": "Version", + "position": "right", + "type": "list", + "items": items + }] + } + with open("../docs/" + src + "/zh/config.json", "w", encoding="utf-8") as f: + json.dump(config_data, f, ensure_ascii=False, indent=4) + + + + # 修改英文页面的Version下拉框 + with open("../docs/" + src + "/en/config.json", "r", encoding="utf-8") as f: + config_data = json.load(f) + + items = [] + for index, i in enumerate(tag): + folder_url = "latest" if index == len(tag) - 1 else i["name"] + if folder_url == "latest": + folder_url = "" # 不使用latest url,因为避免修改存量的链接 + else: + folder_url = "_" + folder_url # 带版本的链接 + items.insert(0, { + "url": "/API_reference" + folder_url + "/en/", + "label": i["name"] + "(latest)" if index == len(tag) - 1 else i["name"] + }) + + config_data["navbar"] = { + "items":[{ + "label": "Version", + "position": "right", + "type": "list", + "items": items + }] + } + with open("../docs/" + src + "/en/config.json", "w", encoding="utf-8") as f: + json.dump(config_data, f, ensure_ascii=False, indent=4) + + except: + pass + + +def publish(): + # 删除历史发布临时文件夹 + if os.path.exists("./publish"): + shutil.rmtree("./publish") + os.mkdir("./publish") # 创建发布文件夹 + os.chdir("./publish") + + # 删除当前目录下旧的api文件 + for i in os.listdir("../docs"): + if i.startswith("API_reference"): + shutil.rmtree("../docs/" + i) + + + # 获取API_reference tag列表 + tag_list = get_tag_list() + + for tag in tag_list: + zip_file = get_commit_file("API_reference_" + tag["name"], tag["commit_sha"]) + # uzip file to temp publish folder + if zip_file: + with zipfile.ZipFile(zip_file, "r") as zf: + zf.extractall(zip_file.split(".zip")[0]) + os.remove(zip_file) + + # 移动文件到docs文件夹 + release_file_list = os.listdir() + for index, item in enumerate(release_file_list): + # 最后一级文件夹更名为latest---20250314 删除该逻辑 调整为API_reference + if index == len(release_file_list) - 1: + for file in os.listdir(item): + print(item + "/" + file + "/en/", " =======>> ", "../docs/API_reference/en") + shutil.move(item + "/" + file + "/en/", "../docs/API_reference/en") + print(item + "/" + file + "/zh/", " =======>> ", "../docs/API_reference/zh") + shutil.move(item + "/" + file + "/zh/", "../docs/API_reference/zh") + + # 设置 site_config.json 站点页面路由 + set_site("/API_reference/zh") + # 设置页面版本切换菜单 + set_config(tag_list, "API_reference") + else: + for file in os.listdir(item): + print(item + "/" + file + "/en/", " =======>> ", "../docs/" + item + "/en") + shutil.move(item + "/" + file + "/en/", "../docs/" + item + "/en") + print(item + "/" + file + "/zh/", " =======>> ", "../docs/" + item + "/zh") + shutil.move(item + "/" + file + "/zh/", "../docs/" + item + "/zh") + + # 设置 site_config.json 站点页面路由 + set_site("/" + item + "/zh") + # 设置页面版本切换菜单 + set_config(tag_list, item) + + os.chdir("..") + +def run_teedoc_build(): + try: + # 执行 teedoc build 命令 + result = subprocess.Popen(['teedoc', 'build'], shell=True, cwd=os.getcwd(), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + # 打印命令的输出 + for line in result.stdout: + print(line.decode(encoding='utf-8', errors='ignore')) + + # 打印命令的错误信息(如果有) + if result.stderr: + print("命令错误:") + print(result.stderr) + + except subprocess.CalledProcessError as e: + # 如果命令执行失败,打印错误信息 + print(f"命令执行失败,错误代码: {e.returncode}") + print(f"错误信息: {e.stderr}") + + + + +def find_html_files(path): + html_files = [] + for root, dirs, files in os.walk(path): + for file in files: + if file.endswith('.html'): + html_files.append(os.path.join(root, file)) + return html_files + + +def replace_version(file_path): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # 解析 HTML + soup = BeautifulSoup(content, "html.parser") + + # 查找 active 标签中的文本 + active_tag_list = soup.find_all("li", class_="active") + + # 筛选多余选项 + for i in active_tag_list: + active_content = i.text.strip() + if active_content.startswith("V"): + break + # 获取version对应的标签 + version_tag = soup.find("a", string="Version") + + # 替换标签内容 + if version_tag: + version_tag.string = active_content + + # 将修改后的 HTML 写回文件 + with open(file_path, 'w', encoding='utf-8') as file: + file.write(soup.prettify()) + + +# 增加BSP相关版本选择器 +def add_bsp_selecter(file_path): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # 解析 HTML + soup = BeautifulSoup(content, "html.parser") + + toc_content_div = soup.find("div", id="toc_content") + + + # 创建一个新的 div 标签 + pagination_div = soup.new_tag('div', class_='pagination') + + # 创建 span 标签 + span_tag = soup.new_tag('span') + span_tag.string = '型号选择:' + + # 创建 select 标签 + select_tag = soup.new_tag('select', id='pageSelect') + + # 将 span 和 select 标签添加到 pagination_div 中 + pagination_div.append(span_tag) + pagination_div.append(select_tag) + + # 在 toc_content_div 之前插入新的 div 标签 + toc_content_div.insert_before(pagination_div) + toc_content_div.insert_before(NavigableString('\n')) + + + # 将修改后的 HTML 写回文件 + with open(file_path, 'w', encoding='utf-8') as file: + file.write(soup.prettify()) + + + +def main(): + path = "out\\doc\\" + api_path_list = [] + try: + for i in os.listdir(path): + if i.startswith("API_reference"): + api_path_list.append(path + i) + except Exception as e: + print("teedoc编译失败,未发现编译生成文件目录") + + # 获取所有api html列表 + html_files = [] + for path in api_path_list: + html_files += find_html_files(path) + + # 修改版本下拉选项 + for file in html_files: + print("replace_version: " + file) + replace_version(file) + + # 增加BSP相关版本选择器 + bsp_filter = ["machine.I2C", "machine.SPI", "machine.Pin", "machine.UART", "machine.KeyPad", "misc.ADC"] + for file in html_files: + for i in bsp_filter: + if file.find(i) != -1: + print("add_bsp_selecter: " + file) + add_bsp_selecter(file) + + + +if __name__ == "__main__": + publish() + run_teedoc_build() + main() diff --git a/readme_bsp.md b/readme_bsp.md new file mode 100644 index 0000000000000000000000000000000000000000..3c9c207d6d01836a0f9a6ce3ced5285a95ff8ff3 --- /dev/null +++ b/readme_bsp.md @@ -0,0 +1,99 @@ +# 文档中心API接口BSP分型号选择文档编写指南 + +## 概述 + +该文档描述如何编写BSP相关的md文档以达到文档页面可以选择型号来查看只包含对应型号BSP的文档 + +## 文档编写指南 + +针对文档中对于BSP部分的描述,需要使用表格、列表或者其他方式来展示不同平台的差异化参数的部分内容需要重新编写 + +编写后的内容会以html的形式呈现,但是文档本身还是markdown文件 + +需要注意的是对于不同形式的内容,需要使用不同的方法去编写 + +比如表格、无序列表、正文、 + +### 表格 + +原BSP的表格使用md格式编写,在一个表格中通过多行来区分平台之间的差异 + +新版文档中心中表格改为使用html编写,使用不同表格来区分不同平台 + +针对一个API文档中不同的表格,使用不同的html属性来区分 + +举例 + +'''html +
---|
class machine.I2C(I2Cn, MODE)
+
+参数描述:
+I2Cn
- I2C 通路索引号,int类型,说明如下:I2C0
: 0
- 通道0 I2C1
: 1
- 通道1 I2C2
: 2
- 通道2
MODE
- I2C 的工作模式,int类型,说明如下:STANDARD_MODE
: 0
- 标准模式FAST_MODE
:1
- 快速模式
class machine.I2C(I2Cn, MODE)
+
+参数描述:
+I2Cn
- I2C 通路索引号,int类型,说明如下:I2C0
: 0
- 通道0 I2C1
: 1
- 通道1 I2C2
: 2
- 通道2
MODE
- I2C 的工作模式,int类型,说明如下:STANDARD_MODE
: 0
- 标准模式FAST_MODE
:1
- 快速模式ENHANCED_FAST_MODE
:2
- 快速模式增强
class machine.I2C(I2Cn, MODE, [group])
+
+参数描述:
+I2Cn
- I2C 通路索引号,int类型,说明如下:I2C0
: 0
- 通道0 I2C1
: 1
- 通道1 I2C2
: 2
- 通道2
MODE
- I2C 的工作模式,int类型,说明如下:STANDARD_MODE
: 0
- 标准模式FAST_MODE
:1
- 快速模式
[group]
- 选择在不同管脚使用IIC,缺省值为0