-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
216 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# 插件入口文件,定义插件的版本和导出内容 | ||
__version__ = "0.1.0" | ||
from .plugin import BiDirectionalLinksPlugin | ||
|
||
__all__ = ["BiDirectionalLinksPlugin"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import re | ||
import logging | ||
from pathlib import Path | ||
|
||
class LinkProcessor: | ||
def __init__(self): | ||
self.includes = [".md", ".png", ".jpg", ".mp4", ".mp3"] # 支持的文件扩展名 | ||
|
||
def process_markdown(self, markdown, page, config, files, search_integration): | ||
""" | ||
处理 Markdown 中的双向链接语法,生成相应的 HTML 标签。 | ||
""" | ||
|
||
def replace_bi_directional_link(match): | ||
""" | ||
替换双向链接语法为 HTML 标签。 | ||
""" | ||
file_ref = match.group(1).strip() # 获取文件引用 | ||
text = match.group(3).strip() if match.group(3) else file_ref # 获取自定义文本 | ||
|
||
# 如果文件引用没有扩展名,默认添加 .md | ||
if not any(file_ref.endswith(ext) for ext in self.includes): | ||
file_ref += ".md" | ||
|
||
# 获取当前文件的路径 | ||
from_file = page.file.src_path | ||
|
||
# 使用 SearchIntegration 查找文件路径 | ||
file_path = search_integration.find_file(from_file, file_ref) | ||
if not file_path: | ||
logging.warning(f"未找到匹配的文件:'{file_ref}'。") | ||
return match.group(0) # 如果未找到文件,返回原始文本 | ||
else: | ||
logging.debug(f"找到文件:'{file_ref}' -> '{file_path}'。") # 添加调试日志 | ||
|
||
# 统一路径分隔符为正斜杠 | ||
file_path = file_path.replace("\\", "/") | ||
|
||
# 获取 site_url 的第二个路径段 | ||
site_url = config.get("site_url", "") | ||
base_path = "" | ||
if site_url: | ||
# 使用正则表达式提取第二个路径段 | ||
match = re.match(r"https?://[^/]+/([^/]+)/?", site_url) | ||
if match: | ||
base_path = match.group(1) # 提取第二个路径段 | ||
if base_path: | ||
base_path = f"/{base_path}" | ||
|
||
# 根据文件类型生成 HTML 标签 | ||
if file_path.endswith(".md"): | ||
file_path = file_path[:-3] # 去除 .md 扩展名 | ||
return f'<a href="{base_path}/{file_path}/">{text}</a>' # Markdown 文件生成链接 | ||
elif any(file_path.endswith(ext) for ext in [".png", ".jpg", ".gif"]): | ||
return f'<img src="{base_path}/{file_path}" alt="{text}">' # 图片文件生成图片标签 | ||
elif any(file_path.endswith(ext) for ext in [".mp4", ".webm"]): | ||
return f'<video controls><source src="{base_path}/{file_path}"></video>' # 视频文件生成视频标签 | ||
elif any(file_path.endswith(ext) for ext in [".mp3", ".wav"]): | ||
return f'<audio controls><source src="{base_path}/{file_path}"></audio>' # 音频文件生成音频标签 | ||
else: | ||
return match.group(0) # 其他文件类型返回原始文本 | ||
|
||
# 使用正则表达式匹配 [[file]] 和 [[file|text]] 语法 | ||
markdown = re.sub(r'!?\[\[([^|\]\n]+)(\|([^\]\n]+))?\]\]', replace_bi_directional_link, markdown) | ||
return markdown |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import logging | ||
from mkdocs.plugins import BasePlugin | ||
from .search_integration import SearchIntegration | ||
from .link_processor import LinkProcessor | ||
|
||
class BiDirectionalLinksPlugin(BasePlugin): | ||
def __init__(self): | ||
self.debug = False # 是否启用调试模式 | ||
self.search_integration = SearchIntegration() # Search 插件集成模块 | ||
self.link_processor = LinkProcessor() # 双向链接处理模块 | ||
|
||
def on_config(self, config): | ||
""" | ||
在 MkDocs 加载配置时调用,初始化插件配置。 | ||
""" | ||
# print("加载配置") | ||
if "bi_directional_links" in config.get("plugins", {}): | ||
plugin_config = config["plugins"]["bi_directional_links"] | ||
if isinstance(plugin_config, dict): # 确保 plugin_config 是字典 | ||
self.debug = plugin_config.get("debug", False) | ||
else: | ||
self.debug = False | ||
else: | ||
self.debug = False | ||
|
||
# 初始化 SearchIntegration | ||
self.search_integration.load_config(config) | ||
return config | ||
|
||
def on_files(self, files, config): | ||
""" | ||
在 MkDocs 加载文件列表时调用,初始化文件缓存。 | ||
""" | ||
# print("加载文件列表") | ||
self.search_integration.load_files(files) | ||
|
||
def on_page_markdown(self, markdown, page, config, files): | ||
""" | ||
在解析 Markdown 文件时调用,处理双向链接语法。 | ||
""" | ||
return self.link_processor.process_markdown(markdown, page, config, files, self.search_integration) |
81 changes: 81 additions & 0 deletions
81
build/lib/mkdocs_bi_directional_links/search_integration.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import os | ||
import logging | ||
from typing import List, Optional | ||
|
||
class SearchIntegration: | ||
def __init__(self): | ||
self.docs_dir = "" | ||
self.file_cache = {} # 文件名到路径的映射 | ||
|
||
def load_config(self, config): | ||
""" | ||
加载 MkDocs 配置,初始化 Search 插件。 | ||
""" | ||
self.docs_dir = config["docs_dir"] | ||
|
||
def load_files(self, files): | ||
""" | ||
加载文件列表,初始化文件缓存。 | ||
""" | ||
self._build_file_cache(files) | ||
|
||
def _build_file_cache(self, files): | ||
""" | ||
构建文件缓存。 | ||
""" | ||
for file in files: | ||
file_path = file.src_path.replace("\\", "/") | ||
file_name = os.path.basename(file_path) | ||
|
||
# 缓存文件名到路径的映射 | ||
if file_name not in self.file_cache: | ||
self.file_cache[file_name] = [file_path] | ||
else: | ||
self.file_cache[file_name].append(file_path) | ||
|
||
# self.print_cache() | ||
|
||
def find_file(self, from_file: str, file_ref: str) -> Optional[str]: | ||
""" | ||
查找文件路径。 | ||
""" | ||
from_file = from_file.replace("\\", "/") | ||
# print(f"查找文件:from_file={from_file}, file_ref={file_ref}") # 输出当前查找的文件 | ||
|
||
# 处理绝对路径 | ||
# if file_ref.startswith("/"): | ||
# abs_path = os.path.join(self.docs_dir, file_ref[1:]) | ||
# abs_path = abs_path.replace("\\", "/") | ||
# print(f"处理绝对路径:abs_path={abs_path}") # 输出绝对路径 | ||
# if os.path.isfile(abs_path): | ||
# return abs_path.replace("\\", "/") | ||
# return None | ||
|
||
# 处理直接链接(相对路径) | ||
# from_dir = os.path.dirname(from_file) | ||
# abs_path = os.path.join(from_dir, file_ref) | ||
# abs_path = abs_path.replace("\\", "/") | ||
# print(f"处理相对路径:from_dir={from_dir}, abs_path={abs_path}") # 输出相对路径 | ||
# if os.path.isfile(abs_path): | ||
# return abs_path.replace("\\", "/") | ||
|
||
# 处理 EzLink(需要搜索的链接) | ||
file_name = os.path.basename(file_ref) | ||
# print(f"处理 EzLink:file_name={file_name}") # 输出文件名 | ||
|
||
# 1. 快速文件缓存查找 | ||
if file_name in self.file_cache: | ||
# print(f"快速文件缓存查找:file_name={file_name}, 缓存={self.file_cache[file_name]}") # 输出缓存内容 | ||
# 如果有多个匹配项,直接返回第一个 | ||
return self.file_cache[file_name][0] | ||
|
||
# 2. 如果未找到文件,返回 None | ||
return None | ||
|
||
def print_cache(self): | ||
""" | ||
打印缓存内容。 | ||
""" | ||
print("文件名到路径的映射:") | ||
for file_name, paths in self.file_cache.items(): | ||
print(f"{file_name}: {paths}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import os | ||
|
||
def resolve_file_path(file_ref, current_file_path, base_dir): | ||
""" | ||
解析文件路径,支持相对路径和绝对路径。 | ||
""" | ||
# 解析相对路径 | ||
current_dir = os.path.dirname(os.path.join(base_dir, current_file_path)) | ||
file_path = os.path.normpath(os.path.join(current_dir, file_ref)) | ||
|
||
# 检查文件是否存在 | ||
if os.path.isfile(file_path): | ||
return file_path | ||
|
||
# 回退到基础目录 | ||
file_path = os.path.normpath(os.path.join(base_dir, file_ref)) | ||
if os.path.isfile(file_path): | ||
return file_path | ||
|
||
return None # 如果未找到文件,返回 None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters