From de5a3c8013640f89218fca34938ccb6021608bcd Mon Sep 17 00:00:00 2001 From: ChangweiXu Date: Tue, 15 Feb 2022 13:43:54 +0800 Subject: [PATCH 1/2] changweixu: add vuepress md doc conversion pipeline script Signed-off-by: ChangweiXu --- docs_md_vuepress_pipeline/.gitignore | 147 ++++++++++ docs_md_vuepress_pipeline/run.py | 40 +++ docs_md_vuepress_pipeline/run.sh | 6 + .../step_1_parse_doc_tree.py | 128 +++++++++ .../step_2_enhance_json_info.py | 81 ++++++ docs_md_vuepress_pipeline/step_3_copy_md.py | 254 ++++++++++++++++++ 6 files changed, 656 insertions(+) create mode 100644 docs_md_vuepress_pipeline/.gitignore create mode 100644 docs_md_vuepress_pipeline/run.py create mode 100755 docs_md_vuepress_pipeline/run.sh create mode 100644 docs_md_vuepress_pipeline/step_1_parse_doc_tree.py create mode 100644 docs_md_vuepress_pipeline/step_2_enhance_json_info.py create mode 100644 docs_md_vuepress_pipeline/step_3_copy_md.py diff --git a/docs_md_vuepress_pipeline/.gitignore b/docs_md_vuepress_pipeline/.gitignore new file mode 100644 index 00000000..522bdaca --- /dev/null +++ b/docs_md_vuepress_pipeline/.gitignore @@ -0,0 +1,147 @@ + +# MacOS +.DS_Store + +# docs +docs/ +docs_vuepress/ +out/ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ diff --git a/docs_md_vuepress_pipeline/run.py b/docs_md_vuepress_pipeline/run.py new file mode 100644 index 00000000..da363148 --- /dev/null +++ b/docs_md_vuepress_pipeline/run.py @@ -0,0 +1,40 @@ +import datetime +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) +os.system('mkdir -p out/') +os.system('mkdir -p docs_vuepress/docs') + +INPUT_DOC_ROOT = os.path.join(os.getcwd(), 'docs/zh-cn') +OUTPUT_DOC_ROOT = os.path.join(os.getcwd(), 'docs_vuepress/docs') + +TIME_STAMP = datetime.datetime.now().timestamp() + +DOC_TREE_FILENAME = os.path.join(INPUT_DOC_ROOT, 'website-directory.md') +RAW_DOC_JSON_FILENAME = f'out/{TIME_STAMP}s1-raw.json' +NOT_FOUND_DOC_TREE_FILENAME = f'out/{TIME_STAMP}s1-not_found.txt' +ENHANCED_DOC_INDEX_FILENAME = f'out/{TIME_STAMP}s2-doc_index.json' +DOC_TABLE_FILENAME = f'out/{TIME_STAMP}s3-doc_table.json' + +POSTS_DOC_TABLE_FILENAME = f'out/{TIME_STAMP}s4-posts_table.json' +MODIFIED_LIST_FILENAME = f'out/{TIME_STAMP}s4-mod.json' +NOT_FOUND_LIST_FILENAME = f'out/{TIME_STAMP}s4-not_mod.json' + + +def main(): + parse_doc_tree_main(DOC_TREE_FILENAME, RAW_DOC_JSON_FILENAME) + check_file_list_existence(RAW_DOC_JSON_FILENAME, INPUT_DOC_ROOT, + NOT_FOUND_DOC_TREE_FILENAME) + enhance_json_info_main(RAW_DOC_JSON_FILENAME, ENHANCED_DOC_INDEX_FILENAME, + INPUT_DOC_ROOT) + copy_md_main(ENHANCED_DOC_INDEX_FILENAME, INPUT_DOC_ROOT, OUTPUT_DOC_ROOT, + MODIFIED_LIST_FILENAME, NOT_FOUND_LIST_FILENAME) + + +if __name__ == '__main__': + from step_1_parse_doc_tree import parse_doc_tree_main, check_file_list_existence + from step_2_enhance_json_info import enhance_json_info_main + from step_3_copy_md import copy_md_main + + main() diff --git a/docs_md_vuepress_pipeline/run.sh b/docs_md_vuepress_pipeline/run.sh new file mode 100755 index 00000000..bffb555e --- /dev/null +++ b/docs_md_vuepress_pipeline/run.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rm -rf docs/ +git clone git@gitee.com:openharmony/docs.git + +python run.py diff --git a/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py b/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py new file mode 100644 index 00000000..64ec3a10 --- /dev/null +++ b/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py @@ -0,0 +1,128 @@ +import codecs +import copy +import json +import os +import re +import string + +TITLE_LINK_REGEX_PATTERN = re.compile('\[(.*?)\]\((.*)\)') +TITLE_ONLY_REGEX_PATTERN = re.compile('\[(.*?)\]') + + +def parse_line(line: str): + if '——>' in line: + depth = line.count('——>') + line = line.replace('——>', '') + elif '#' in line: + depth = line.count('#') + line = line.replace('#', '') + else: + assert False + match = re.findall(TITLE_LINK_REGEX_PATTERN, line) + if match: + path = match[0][1] + match = match[0][0] + match = filter_title(match) + # print(match) # DEBUG + return {'depth': depth, 'title': match, 'md_path': path} + title_match = re.findall(TITLE_ONLY_REGEX_PATTERN, line) + if title_match: + line = title_match[0] + return {'depth': depth, 'title': line} + + +def filter_title(title: str): + title = title.replace(' ', '-') # ' ' + title = title.replace('\\', '') # '\' + title = title.replace('"', '') # "'" + return title + + +def plant_tree(lines_info: list) -> list: + current_depth = 1 + current_list = [] + depth_stack = [] + if len(lines_info) == 0: + return + index = 0 + while index < len(lines_info): + line_info = lines_info[index] + print(line_info, '; depth =', current_depth) # DEBUG + if line_info['depth'] > current_depth: + assert line_info['depth'] - 1 == current_depth + depth_stack.append(current_list) + current_json = copy.deepcopy(line_info) + current_list = [current_json] + current_depth += 1 + index += 1 + elif line_info['depth'] == current_depth: + current_json = copy.deepcopy(line_info) + current_list.append(current_json) + index += 1 + else: + child_list = current_list + current_list = depth_stack.pop() + current_list[-1]['children'] = child_list + current_depth -= 1 + continue + + while depth_stack: + child_list = current_list + current_list = depth_stack.pop() + current_list[-1]['children'] = child_list + + return current_list + + +def check_file_list_existence(input_file_list: str, input_doc_root: str, + output_file_list: str): + not_found_list = [] + + def _check_file_existence(json_list: list): + for json_dict in json_list: + if 'children' in json_dict: + _check_file_existence(json_dict['children']) + elif 'md_path' in json_dict: + file_abs_path = os.path.join(input_doc_root, + json_dict['md_path']) + if not os.path.exists(file_abs_path): + print(json_dict['title'], 'md 文件不存在!') + not_found_list.append(json_dict['md_path']) + else: + print(json_dict['title'], '没有 md 文件路径!') + not_found_list.append(f'{json_dict["title"]} :没有 md 文件路径') + + with codecs.open(input_file_list, 'r', encoding='utf-8') as inFile: + file_list = json.load(inFile) + + _check_file_existence(file_list) + + with codecs.open(output_file_list, 'w', encoding='utf-8') as outputFile: + for not_found_file in not_found_list: + outputFile.write(not_found_file) + outputFile.write('\n') + + assert len(not_found_list) == 0, '目录存在无效链接!' + + +def parse_doc_tree_main(input_filename, output_filename): + LINES_INFO = [] + ''' STEP 1a: 读取 md 文档树,记录每一行的信息 ''' + with codecs.open(input_filename, 'r', encoding='utf-8') as inputFile: + for line in inputFile: + line = line.translate({ord(c): None for c in string.whitespace}) + line = line.replace('@', '') + if not line: + continue + line_info = parse_line(line) + LINES_INFO.append(line_info) + # print(line_info) # DEBUG + ''' STEP 1b: 以深度为单位统计信息,使用 stack 数据结构 ''' + output_list = plant_tree(LINES_INFO) + + with codecs.open(output_filename, 'w', encoding='utf-8') as outputFile: + json.dump(output_list, outputFile, indent=2, ensure_ascii=False) + + +if __name__ == '__main__': + pass diff --git a/docs_md_vuepress_pipeline/step_2_enhance_json_info.py b/docs_md_vuepress_pipeline/step_2_enhance_json_info.py new file mode 100644 index 00000000..2e0734bd --- /dev/null +++ b/docs_md_vuepress_pipeline/step_2_enhance_json_info.py @@ -0,0 +1,81 @@ +import codecs +import json +import os +import random + +PERMALINK_SET = set() +PAGE_INDEX = {} + + +def doc_tree_to_index(json_list: list, parent_path: str='', parent_doc_id: str='/pages/') -> None: + for index, json_dict in enumerate(json_list): + file_name = f'{(index+1):02}.{json_dict["title"]}' + permalink = parent_doc_id + f'{(index+1):02x}' + if 'children' in json_dict: + doc_tree_to_index(json_dict['children'], os.path.join(parent_path, file_name), permalink) + else: + PAGE_INDEX[json_dict['md_path']] = { + # 'title': json_dict["title"], + 'target_path': os.path.join(parent_path, file_name) + '.md', + # 'permalink': permalink, + 'front matter': { + 'title': json_dict['title'], + 'permalink': permalink, + 'navbar': 'true', + 'sidebar': 'true', + 'prev': 'true', + 'next': 'true', + 'search': 'true', + 'article': 'true', + 'comment': 'false', + 'editLink': 'false' + } + } + assert permalink not in PERMALINK_SET, f'Duplicated permalink: {permalink}' + PERMALINK_SET.add(permalink) + + +def add_all_md_to_index(input_doc_root: str, parent_path: str='') -> None: + abs_parent_path = os.path.join(input_doc_root, parent_path) + files = os.listdir(abs_parent_path) + for file in files: + relative_path = os.path.join(parent_path, file) + if os.path.isdir(os.path.join(abs_parent_path, file)): + add_all_md_to_index(input_doc_root, relative_path) + elif file[-3:] == '.md': + if relative_path in PAGE_INDEX: + pass + else: + permalink = f'/pages/extra/{random.randint(0, 16777215):06x}/' + PAGE_INDEX[relative_path] = { + # 'title': file.replace('.md', ''), + 'target_path': os.path.join('_posts/zh-cn', relative_path), + # 'permalink': permalink, + 'front matter': { + 'title': file.replace('.md', ''), + 'permalink': permalink, + 'navbar': 'true', + 'sidebar': 'false', + 'prev': 'false', + 'next': 'false', + 'search': 'true', + 'article': 'true', + 'comment': 'false', + 'editLink': 'false', + } + } + + +def enhance_json_info_main(input_filename, output_filename, input_doc_root): + with codecs.open(input_filename, 'r', encoding='utf-8') as inFile: + INPUT_JSON_DICT = json.load(inFile) + + doc_tree_to_index(INPUT_JSON_DICT) + add_all_md_to_index(input_doc_root) + + with codecs.open(output_filename, 'w', encoding='utf-8') as outFile: + json.dump(PAGE_INDEX, outFile, indent=2, ensure_ascii=False) + + +if __name__ == '__main__': + pass diff --git a/docs_md_vuepress_pipeline/step_3_copy_md.py b/docs_md_vuepress_pipeline/step_3_copy_md.py new file mode 100644 index 00000000..19d5593b --- /dev/null +++ b/docs_md_vuepress_pipeline/step_3_copy_md.py @@ -0,0 +1,254 @@ +import codecs +import json +import os +import re + +MD_DOC_INDEX = None + +# MD_LINK_REGEX = re.compile('\[.*\]\((.*\.md)') # 误判情况: [xxx](xxx.md) xxx [xxx](xxx.md) +# MD_LINK_REGEX = re.compile('\[.*?\]\((.*?\.md)') # 误判情况: [xxx](https://xxx.com/xxx) xxx [xxx](xxx.md) +MD_LINK_REGEX = re.compile('\[[^\[]*?\]\(([^\[]*?\.md)') +MD_HTML_LINK_REGEX = re.compile('') +GIF_LINK_REGEX = re.compile('!\[.*\]\((.*\.gif)') +JPG_LINK_REGEX = re.compile('!\[.*\]\((.*\.jpg)') +PNG_LINK_REGEX = re.compile('!\[.*\]\((.*\.png)') + +modified_list = [] # 记录更改的文件信息 +not_modified_list = [] # 记录无主的文件信息 + + +def resolve_md_links(md_text: str, in_md_abs_path: str, out_md_abs_path: str, + input_doc_root: str, output_doc_root: str): + in_md_abs_pwd_path = '/'.join(in_md_abs_path.split('/')[:-1]) + + raw_lines = md_text.split('\n') + mod_lines = [] + replace_counter = 0 + failed_counter = 0 + + for lineno, line in enumerate(raw_lines): + md_link_patterns = [] + md_link_patterns += re.findall(MD_LINK_REGEX, line) + md_link_patterns += re.findall(MD_HTML_LINK_REGEX, line) + if len(md_link_patterns) == 0: + # 这一行是普通文本,regex 没找到 md 链接 + mod_lines.append(line) + continue + for pattern in md_link_patterns: + # 处理这一行中出现的所有 md 链接 pattern + if 'https://' in pattern: + # 特殊情况:https://,引用了网上的 md 文件 + # 解决方法:无视之 + not_modified_list.append({ + 'input_md': in_md_abs_path, + 'output_md': out_md_abs_path, + 'line_no': lineno + 1, + 'pattern': pattern, + 'handle': 'ignore', + }) + failed_counter += 1 + continue + + # 得到该文件链接指向的 工程目录绝对路径,清除掉所有 “.” “..” + # source_md_abs_path: 源 md 所在的绝对路径 + source_md_abs_path = os.path.normpath( + os.path.join(in_md_abs_pwd_path, pattern)) + # source_md_name: 源 md 文档的文件名 + source_md_name = source_md_abs_path.split('/')[-1] + # source_md_abs_pwd_path: 源 md 所在文件夹的绝对路径 + source_md_abs_pwd_path = '/'.join( + source_md_abs_path.split('/')[:-1]) + # source_md_rel_pwd_path: 源 md 所在文件夹(相对于 docs/zh-cn 根目录)的相对路径 + source_md_rel_pwd_path = source_md_abs_pwd_path.replace( + input_doc_root, '') + # source_md_rel_path: 源 md 文档的相对路径 + source_md_rel_path = os.path.join(source_md_rel_pwd_path, + source_md_name) + + if '.md' not in source_md_rel_path: + print(f'ERROR: {source_md_name}') + print(f'ERROR: {source_md_abs_path}') + print(f'ERROR: {source_md_abs_pwd_path}') + print(f'ERROR: {source_md_rel_path}') + print(f'ERROR: {source_md_rel_pwd_path}') + assert False + + if source_md_rel_path not in MD_DOC_INDEX: + # 如果没找到指定的 md,删掉此行,记录在案 + not_modified_list.append({ + 'input_md': in_md_abs_path, + 'output_md': out_md_abs_path, + 'line_no': lineno + 1, + 'pattern': pattern, + 'source_md_abs_path': source_md_abs_path, + 'source_md_rel_path': source_md_rel_path, + 'handle': 'delete', + }) + failed_counter += 1 + line = '' + continue + + # 如果找到了此 md,则替换相对链接为 permalink + md_permalink = MD_DOC_INDEX[source_md_rel_path]['front matter'][ + 'permalink'] + # 最后把跳转链接插入到 md 文档中 + line = line.replace(pattern, md_permalink) + + modified_list.append({ + 'input_md': in_md_abs_path, + 'output_md': out_md_abs_path, + 'line_no': lineno + 1, + 'pattern': pattern, + 'source_md_abs_path': source_md_abs_path, + 'source_md_rel_path': source_md_rel_path, + # 'target_md_abs_path': target_md_abs_path, + 'permalink': md_permalink, + }) + replace_counter += 1 + + mod_lines.append(line) + print(f'已完成:resolve_md_links(..., {in_md_abs_path}, {out_md_abs_path})' + ) # DEBUG + print( + f'\t成功替换了:{replace_counter}个 md 链接,未能成功替换:{failed_counter}个。') # DEBUG + + return '\n'.join(mod_lines) + + +def resolve_image_links(md_text, in_md_abs_path, out_md_abs_path, + input_doc_root, output_doc_root): + in_md_abs_pwd_path = '/'.join(in_md_abs_path.split('/')[:-1]) + + raw_lines = md_text.split('\n') + mod_lines = [] + replace_counter = 0 + failed_counter = 0 + for lineno, line in enumerate(raw_lines): + img_relative_path = [] + img_relative_path += re.findall(GIF_LINK_REGEX, line) + img_relative_path += re.findall(JPG_LINK_REGEX, line) + img_relative_path += re.findall(PNG_LINK_REGEX, line) + if len(img_relative_path) == 0: + # 这一行是普通文本,regex 没找到图片链接 + mod_lines.append(line) + else: + for pattern in img_relative_path: + if 'https://' in pattern: + # 特殊情况:https://,引用了网上的图片 + # 解决方法:无视之 + not_modified_list.append({ + 'input_md': in_md_abs_path, + 'output_md': out_md_abs_path, + 'line_no': lineno + 1, + 'pattern': pattern, + 'handle': 'ignore', + }) + failed_counter += 1 + continue + + # 得到该文件链接指向的 工程目录绝对路径,清除掉所有 “.” “..” + # source_img_path: 原图片所在的绝对路径(mv 命令的起点) + source_img_path = os.path.normpath( + os.path.join(in_md_abs_pwd_path, pattern)) + if not os.path.exists(source_img_path): + # 如果没找到指定的图片,删掉此行,记录在案 + not_modified_list.append({ + 'input_md': in_md_abs_path, + 'output_md': out_md_abs_path, + 'line_no': lineno + 1, + 'pattern': pattern, + 'source_img': source_img_path, + 'handle': 'delete', + }) + failed_counter += 1 + line = '' + continue + else: + # 如果在 image 文件列表内找到了此图片,则创建 images/... 文件夹, + # 移动图片文件到 images/...,更新相对路径,插入到 md 文档中 + # img_pwd_path: 原图片所在文件夹的绝对路径 + img_pwd_path = '/'.join(source_img_path.split('/')[:-1]) + # source_img_rel_path: 原图片所在文件夹的相对路径(相对于 docs repo root) + source_img_rel_path = img_pwd_path.replace( + input_doc_root, '') + # vdoing_img_pwd_path: 复制图片所在文件夹的相对路径(相对于 public 文件夹) + vdoing_img_pwd_path = os.path.join('images', + source_img_rel_path) + # target_img_pwd_path: 复制图片所在文件夹的绝对路径(mv 命令的 destination) + target_img_pwd_path = os.path.join(output_doc_root, + vdoing_img_pwd_path) + os.system(f'mkdir -p "{target_img_pwd_path}"') + os.system( + f'cp "{source_img_path}" "{target_img_pwd_path}"') + # raw_img_pwd_path: 原图片所在目录的相对路径(需要替换为相对于 public 文件夹的相对路径) + raw_img_pwd_path = '/'.join(pattern.split('/')[:-1]) + line = line.replace(raw_img_pwd_path, + '/' + vdoing_img_pwd_path) + modified_list.append({ + 'input_md': in_md_abs_path, + 'output_md': out_md_abs_path, + 'line_no': lineno + 1, + 'pattern': pattern, + 'source_image': source_img_path, + 'target_image': vdoing_img_pwd_path, + }) + replace_counter += 1 + mod_lines.append(line) + print(f'已完成:resolve_image_links(..., {in_md_abs_path}, {out_md_abs_path})' + ) # DEBUG + print(f'\t成功替换了:{replace_counter}个 image 链接,未能成功替换:{failed_counter}个。' + ) # DEBUG + + return '\n'.join(mod_lines) + + +def copy_md(json_list: dict, input_doc_root, output_doc_root): + for md_path, json_dict in json_list.items(): + input_md_path = os.path.join(input_doc_root, md_path) + + output_md_path = os.path.join(output_doc_root, + json_dict['target_path']) + output_md_pwd_path = '/'.join(output_md_path.split('/')[:-1]) + os.system(f'mkdir -p {output_md_pwd_path}') + + assert os.path.exists( + input_md_path), f'MD file doesn\'t exist: {input_md_path}' + + with codecs.open(input_md_path, 'r', encoding='utf-8') as inMd: + input_md_text = inMd.read() + output_md_text = resolve_md_links(input_md_text, input_md_path, + output_md_path, input_doc_root, + output_doc_root) + output_md_text = resolve_image_links(output_md_text, input_md_path, + output_md_path, input_doc_root, + output_doc_root) + + front_matter_list = ['---'] + [ + f'{k}: {v}' for k, v in json_dict['front matter'].items() + ] + ['---\n'] + front_matter_text = '\n'.join(front_matter_list) + + with codecs.open(output_md_path, 'w', encoding='utf-8') as outMd: + outMd.write(front_matter_text) + outMd.write(output_md_text) + + +def copy_md_main(input_filename, input_doc_root, output_doc_root, mod_list, + unfound_list): + global MD_DOC_INDEX + + # print(input_filename) # DEBUG + with codecs.open(input_filename, 'r', encoding='utf-8') as inFile: + MD_DOC_INDEX = json.load(inFile) + + os.system(f'rm -rf {output_doc_root}') + copy_md(MD_DOC_INDEX, input_doc_root, output_doc_root) + ''' 保存列表记录文件 ''' + with codecs.open(mod_list, 'w', encoding='utf-8') as mlf: + json.dump(modified_list, mlf, indent=2, ensure_ascii=False) + with codecs.open(unfound_list, 'w', encoding='utf-8') as nmlf: + json.dump(not_modified_list, nmlf, indent=2, ensure_ascii=False) + + +if __name__ == '__main__': + pass -- Gitee From 6400f8d58293377a6d79b54c81831eb6d2f0679d Mon Sep 17 00:00:00 2001 From: ChangweiXu Date: Tue, 15 Feb 2022 13:50:18 +0800 Subject: [PATCH 2/2] add license head to vuepress pipeline python scripts Signed-off-by: ChangweiXu --- docs_md_vuepress_pipeline/run.py | 28 +++++++++++++++++++ .../step_1_parse_doc_tree.py | 28 +++++++++++++++++++ .../step_2_enhance_json_info.py | 28 +++++++++++++++++++ docs_md_vuepress_pipeline/step_3_copy_md.py | 28 +++++++++++++++++++ 4 files changed, 112 insertions(+) diff --git a/docs_md_vuepress_pipeline/run.py b/docs_md_vuepress_pipeline/run.py index da363148..c385e426 100644 --- a/docs_md_vuepress_pipeline/run.py +++ b/docs_md_vuepress_pipeline/run.py @@ -1,3 +1,31 @@ +# Copyright (c) 2021 changwei@iscas.ac.cn +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + import datetime import os import sys diff --git a/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py b/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py index 64ec3a10..f5618c46 100644 --- a/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py +++ b/docs_md_vuepress_pipeline/step_1_parse_doc_tree.py @@ -1,3 +1,31 @@ +# Copyright (c) 2021 changwei@iscas.ac.cn +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + import codecs import copy import json diff --git a/docs_md_vuepress_pipeline/step_2_enhance_json_info.py b/docs_md_vuepress_pipeline/step_2_enhance_json_info.py index 2e0734bd..b154288c 100644 --- a/docs_md_vuepress_pipeline/step_2_enhance_json_info.py +++ b/docs_md_vuepress_pipeline/step_2_enhance_json_info.py @@ -1,3 +1,31 @@ +# Copyright (c) 2021 changwei@iscas.ac.cn +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + import codecs import json import os diff --git a/docs_md_vuepress_pipeline/step_3_copy_md.py b/docs_md_vuepress_pipeline/step_3_copy_md.py index 19d5593b..a0bfa9e1 100644 --- a/docs_md_vuepress_pipeline/step_3_copy_md.py +++ b/docs_md_vuepress_pipeline/step_3_copy_md.py @@ -1,3 +1,31 @@ +# Copyright (c) 2021 changwei@iscas.ac.cn +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + import codecs import json import os -- Gitee