4487 lines
223 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="zh" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Content and ambitious, gentle yet firm.">
<meta name="author" content="王科文(Wcowin)">
<link rel="canonical" href="http://wcowin.work/Mkdocs-Wcowin/blog/websitebeauty/recommend/">
<link rel="prev" href="../Mkdocs-AI-Summary/">
<link rel="next" href="../reading_time/">
<link rel="icon" href="https://s2.loli.net/2025/02/12/aE5ovtzAlNTd9Uh.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.15">
<title>为MKdocs页面添加相关文章推荐 - Mkdocs中文教程</title>
<link rel="stylesheet" href="../../../assets/stylesheets/main.342714a4.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../../stylesheets/extra.css">
<link rel="stylesheet" href="../../../stylesheets/extra2.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Wcowin/Wcowin.github.io@main/docs/stylesheets/link.css">
<link rel="stylesheet" href="../../../stylesheets/customize.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Wcowin/Wcowin.github.io@main/docs/stylesheets/ziti.css">
<script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script id="__analytics">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e("js",new Date),e("config","G-29HZMNR0KG"),document.addEventListener("DOMContentLoaded",(function(){document.forms.search&&document.forms.search.query.addEventListener("blur",(function(){this.value&&e("event","search",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll("[type=submit]"))a.addEventListener("click",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute("data-md-value");e("event","feedback",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(".md-feedback__note [data-md-value='"+d+"']");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e("config","G-29HZMNR0KG",{page_path:t.pathname})}))}));var t=document.createElement("script");t.async=!0,t.src="https://www.googletagmanager.com/gtag/js?id=G-29HZMNR0KG",document.getElementById("__analytics").insertAdjacentElement("afterEnd",t)}</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#mkdocs" class="md-skip">
跳转至
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="页眉">
<a href="../../.." title="Mkdocs中文教程" class="md-header__button md-logo" aria-label="Mkdocs中文教程" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 89">
<path d="M3.136,17.387l0,42.932l42.932,21.467l-42.932,-64.399Z" />
<path d="M21.91,8l42.933,64.398l-18.775,9.388l-42.932,-64.399l18.774,-9.387Z" style="fill-opacity: 0.5" />
<path d="M67.535,17.387l-27.262,18.156l21.878,32.818l5.384,2.691l0,-53.665Z" />
<path d="M67.535,17.387l0,53.666l18.774,-9.388l0,-53.665l-18.774,9.387Z" style="fill-opacity: 0.25" />
</svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Mkdocs中文教程
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
为MKdocs页面添加相关文章推荐
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="关闭自动模式" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="关闭自动模式" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5 5 5 0 0 0-5-5"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="blue" data-md-color-accent="indigo" aria-label="切换至夜间模式" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="切换至夜间模式" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="切换至日间模式" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="切换至日间模式" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6m0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4M7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<div class="md-header__option">
<div class="md-select">
<button class="md-header__button md-icon" aria-label="选择当前语言">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M0 128c0-35.3 28.7-64 64-64h512c35.3 0 64 28.7 64 64v256c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64zm320 0v256h256V128zm-141.7 47.9c-3.2-7.2-10.4-11.9-18.3-11.9s-15.1 4.7-18.3 11.9l-64 144c-4.5 10.1.1 21.9 10.2 26.4s21.9-.1 26.4-10.2l8.9-20.1h73.6l8.9 20.1c4.5 10.1 16.3 14.6 26.4 10.2s14.6-16.3 10.2-26.4zM160 233.2l19 42.8h-38zM448 164c11 0 20 9 20 20v4h60c11 0 20 9 20 20s-9 20-20 20h-2l-1.6 4.5c-8.9 24.4-22.4 46.6-39.6 65.4.9.6 1.8 1.1 2.7 1.6l18.9 11.3c9.5 5.7 12.5 18 6.9 27.4s-18 12.5-27.4 6.9L467 333.8c-4.5-2.7-8.8-5.5-13.1-8.5-10.6 7.5-21.9 14-34 19.4l-3.6 1.6c-10.1 4.5-21.9-.1-26.4-10.2s.1-21.9 10.2-26.4l3.6-1.6c6.4-2.9 12.6-6.1 18.5-9.8L410 286.1c-7.8-7.8-7.8-20.5 0-28.3s20.5-7.8 28.3 0l14.6 14.6.5.5c12.4-13.1 22.5-28.3 29.8-45l-35.2.1h-72c-11 0-20-9-20-20s9-20 20-20h52v-4c0-11 9-20 20-20"/></svg>
</button>
<div class="md-select__inner">
<ul class="md-select__list">
<li class="md-select__item">
<a href="/" hreflang="zh" class="md-select__link">
简体中文
</a>
</li>
<li class="md-select__item">
<a href="/Mkdocs-Wcowin/en/" hreflang="en" class="md-select__link">
English
</a>
</li>
<li class="md-select__item">
<a href="/Mkdocs-Wcowin/ZH-TW/" hreflang="zh-TW" class="md-select__link">
China(TW)
</a>
</li>
</ul>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256l137.3-137.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg>
</label>
<nav class="md-search__options" aria-label="查找">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="分享" aria-label="分享" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
正在初始化搜索引擎
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/Wcowin/Mkdocs-Wcowin" title="前往仓库" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</div>
<div class="md-source__repository">
Mkdocs-Wcowin
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="标签" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item md-tabs__item--active">
<a href="../../MIT/" class="md-tabs__link">
MKdocs中文教程
</a>
</li>
<li class="md-tabs__item">
<a href="../../../develop/Markdown/markdown/" class="md-tabs__link">
建设MKdocs技能指北
</a>
</li>
<li class="md-tabs__item">
<a href="../../../tag/" class="md-tabs__link">
标签
</a>
</li>
<li class="md-tabs__item">
<a href="../../../liuyanban/" class="md-tabs__link">
留言板
</a>
</li>
<li class="md-tabs__item">
<a href="../../" class="md-tabs__link">
博客
</a>
</li>
<li class="md-tabs__item">
<a href="../../../link/" class="md-tabs__link">
友链
</a>
</li>
<li class="md-tabs__item">
<a href="../../../about/geren/" class="md-tabs__link">
关于
</a>
</li>
<li class="md-tabs__item">
<a href="https://wcowin.work" class="md-tabs__link">
个人博客
</a>
</li>
<li class="md-tabs__item">
<a href="https://github.com/new?template_name=Mkdocs-Wcowin&template_owner=Wcowin" class="md-tabs__link">
使用本主题
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="导航栏" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../.." title="Mkdocs中文教程" class="md-nav__button md-logo" aria-label="Mkdocs中文教程" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 89">
<path d="M3.136,17.387l0,42.932l42.932,21.467l-42.932,-64.399Z" />
<path d="M21.91,8l42.933,64.398l-18.775,9.388l-42.932,-64.399l18.774,-9.387Z" style="fill-opacity: 0.5" />
<path d="M67.535,17.387l-27.262,18.156l21.878,32.818l5.384,2.691l0,-53.665Z" />
<path d="M67.535,17.387l0,53.666l18.774,-9.388l0,-53.665l-18.774,9.387Z" style="fill-opacity: 0.25" />
</svg>
</a>
Mkdocs中文教程
</label>
<div class="md-nav__source">
<a href="https://github.com/Wcowin/Mkdocs-Wcowin" title="前往仓库" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</div>
<div class="md-source__repository">
Mkdocs-Wcowin
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_1" checked>
<label class="md-nav__link" for="__nav_1" id="__nav_1_label" tabindex="">
<span class="md-ellipsis">
MKdocs中文教程
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_1_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_1">
<span class="md-nav__icon md-icon"></span>
MKdocs中文教程
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../MIT/" class="md-nav__link">
<span class="md-ellipsis">
许可声明
</span>
<span class="md-status md-status--new"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_1_2" >
<label class="md-nav__link" for="__nav_1_2" id="__nav_1_2_label" tabindex="">
<span class="md-ellipsis">
MKdocs教程(三部曲)
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_1_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_1_2">
<span class="md-nav__icon md-icon"></span>
MKdocs教程(三部曲)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../Mkdocs/mkfirst/" class="md-nav__link">
<span class="md-ellipsis">
0.Mkdocs教程前言
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../Mkdocs/mkdocs1/" class="md-nav__link">
<span class="md-ellipsis">
1.利用Mkdocs部署静态网页
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../Mkdocs/mkdocs2/" class="md-nav__link">
<span class="md-ellipsis">
2.Mkdocs配置说明(mkdocs.yml)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../Mkdocs/mkdocs3/" class="md-nav__link">
<span class="md-ellipsis">
3.解决Github Pages部署mkdocs自定义域名失效的问题
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_1_3" checked>
<label class="md-nav__link" for="__nav_1_3" id="__nav_1_3_label" tabindex="">
<span class="md-ellipsis">
Mkdocs美化/补充
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_1_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_1_3">
<span class="md-nav__icon md-icon"></span>
Mkdocs美化/补充
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../Mkdocs-AI-Summary/" class="md-nav__link">
<span class="md-ellipsis">
MkDocs文档AI摘要
</span>
<span class="md-status md-status--new"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
添加相关推荐文章
</span>
<span class="md-status md-status--new"></span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
添加相关推荐文章
</span>
<span class="md-status md-status--new"></span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
<span class="md-ellipsis">
步骤
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
<span class="md-ellipsis">
效果如下
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../reading_time/" class="md-nav__link">
<span class="md-ellipsis">
添加阅读信息统计
</span>
<span class="md-status md-status--new"></span>
</a>
</li>
<li class="md-nav__item">
<a href="../../Mkdocs/mkdocsblog/" class="md-nav__link">
<span class="md-ellipsis">
添加Mkdocs博客
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../Mkdocs/linktech/" class="md-nav__link">
<span class="md-ellipsis">
如何给MKdocs添加友链
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../yuanjiaohua/" class="md-nav__link">
<span class="md-ellipsis">
网页圆角化设计
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mkcomments/" class="md-nav__link">
<span class="md-ellipsis">
添加评论系统(giscus为例)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../webtalknow/" class="md-nav__link">
<span class="md-ellipsis">
添加在线聊天
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../linktech/" class="md-nav__link">
<span class="md-ellipsis">
添加友链
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../header/" class="md-nav__link">
<span class="md-ellipsis">
添加顶部公告栏
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mkdocsfont/" class="md-nav__link">
<span class="md-ellipsis">
修改网站字体
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../shubiao/" class="md-nav__link">
<span class="md-ellipsis">
JS实现鼠标样式
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../backgroud/" class="md-nav__link">
<span class="md-ellipsis">
背景特效
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mkpdf/" class="md-nav__link">
<span class="md-ellipsis">
嵌入PDF文件
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../Relativeaddress/" class="md-nav__link">
<span class="md-ellipsis">
相对地址的一些问题
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../404/" class="md-nav__link">
<span class="md-ellipsis">
添加404页面
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../time/" class="md-nav__link">
<span class="md-ellipsis">
为MKdocs添加文章修订时间戳
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../footer/" class="md-nav__link">
<span class="md-ellipsis">
页脚设置
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../accelerate/" class="md-nav__link">
<span class="md-ellipsis">
加速网站访问的一些心得
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
建设MKdocs技能指北
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
建设MKdocs技能指北
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_1" >
<label class="md-nav__link" for="__nav_2_1" id="__nav_2_1_label" tabindex="0">
<span class="md-ellipsis">
Markdown
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_1">
<span class="md-nav__icon md-icon"></span>
Markdown
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../develop/Markdown/markdown/" class="md-nav__link">
<span class="md-ellipsis">
Markdown指南
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../develop/Markdown/MWeb/" class="md-nav__link">
<span class="md-ellipsis">
MWeb Pro
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../../develop/git/" class="md-nav__link">
<span class="md-ellipsis">
Git 实用技巧
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../develop/lighthouse/" class="md-nav__link">
<span class="md-ellipsis">
利用Lighthouse测试网站性能
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../develop/vercel/" class="md-nav__link">
<span class="md-ellipsis">
如何将 github pages 迁移到 vercel 上托管
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_5" >
<label class="md-nav__link" for="__nav_2_5" id="__nav_2_5_label" tabindex="0">
<span class="md-ellipsis">
设计美学
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_5">
<span class="md-nav__icon md-icon"></span>
设计美学
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../develop/designbeauty/db1/" class="md-nav__link">
<span class="md-ellipsis">
唐·诺曼—情感设计的三个层次
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../develop/designbeauty/my-to-desihn/" class="md-nav__link">
<span class="md-ellipsis">
我对设计的一些观点
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../../tag/" class="md-nav__link">
<span class="md-ellipsis">
标签
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../liuyanban/" class="md-nav__link">
<span class="md-ellipsis">
留言板
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5" >
<div class="md-nav__link md-nav__container">
<a href="../../" class="md-nav__link ">
<span class="md-ellipsis">
博客
</span>
</a>
<label class="md-nav__link " for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
博客
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5_2" >
<label class="md-nav__link" for="__nav_5_2" id="__nav_5_2_label" tabindex="0">
<span class="md-ellipsis">
归档
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_2">
<span class="md-nav__icon md-icon"></span>
归档
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../archive/2025/" class="md-nav__link">
<span class="md-ellipsis">
2025
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../archive/2024/" class="md-nav__link">
<span class="md-ellipsis">
2024
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../archive/2023/" class="md-nav__link">
<span class="md-ellipsis">
2023
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../archive/2022/" class="md-nav__link">
<span class="md-ellipsis">
2022
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../archive/2021/" class="md-nav__link">
<span class="md-ellipsis">
2021
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5_3" >
<label class="md-nav__link" for="__nav_5_3" id="__nav_5_3_label" tabindex="0">
<span class="md-ellipsis">
分类
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
分类
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../category/hello-world/" class="md-nav__link">
<span class="md-ellipsis">
Hello World
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../category/%E7%BD%91%E7%AB%99%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95/" class="md-nav__link">
<span class="md-ellipsis">
网站更新记录
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
友链
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
友链
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../link/" class="md-nav__link">
<span class="md-ellipsis">
友链
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
<span class="md-ellipsis">
关于
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
关于
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../about/geren/" class="md-nav__link">
<span class="md-ellipsis">
作者个人简介
</span>
<span class="md-status md-status--new"></span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../about/resume/" class="md-nav__link">
<span class="md-ellipsis">
个人简历
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../about/zcw/" class="md-nav__link">
<span class="md-ellipsis">
支持作者
</span>
<span class="md-status md-status--new"></span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../about/test/" class="md-nav__link">
<span class="md-ellipsis">
功能测试
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="https://wcowin.work" class="md-nav__link">
<span class="md-ellipsis">
个人博客
</span>
</a>
</li>
<li class="md-nav__item">
<a href="https://github.com/new?template_name=Mkdocs-Wcowin&template_owner=Wcowin" class="md-nav__link">
<span class="md-ellipsis">
使用本主题
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
<span class="md-ellipsis">
步骤
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
<span class="md-ellipsis">
效果如下
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<nav class="md-tags" >
<a href="../../../tag/#tag:mkdocs" class="md-tag">Mkdocs</a>
</nav>
<a href="https://github.com/Wcowin/Mkdocs-Wcowin/edit/main/docs/blog/websitebeauty/recommend.md" title="编辑此页" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://github.com/Wcowin/Mkdocs-Wcowin/raw/main/docs/blog/websitebeauty/recommend.md" title="查看本页的源代码" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<div class="admonition info">
<p class="admonition-title">📖 阅读信息</p>
<p>阅读时间:<strong>1</strong> 分钟 | 中文字符:<strong>63</strong> | 有效代码行数:<strong>419</strong></p>
</div>
<h1 id="mkdocs">为MKdocs页面添加相关文章推荐<a class="headerlink" href="#mkdocs" title="Permanent link">&para;</a></h1>
<h2 id="_1">步骤<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h2>
<p><code>mkdocs.yml</code>中需要覆写文件夹overrides(没有的话新建一个)</p>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span>
<span class="normal"><a href="#__codelineno-0-2">2</a></span>
<span class="normal"><a href="#__codelineno-0-3">3</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nt">theme</span><span class="p">:</span>
<a id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">material</span>
<a id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="w"> </span><span class="nt">custom_dir</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">docs/overrides</span>
</code></pre></div></td></tr></table></div>
<p>在docs/overrides/hooks/下新建一个<code>related_posts.py</code>文件即可,内容如下:</p>
<p>具体配置根据自己仓库情况自行修改</p>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-1-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-1-2"> 2</a></span>
<span class="normal"><a href="#__codelineno-1-3"> 3</a></span>
<span class="normal"><a href="#__codelineno-1-4"> 4</a></span>
<span class="normal"><a href="#__codelineno-1-5"> 5</a></span>
<span class="normal"><a href="#__codelineno-1-6"> 6</a></span>
<span class="normal"><a href="#__codelineno-1-7"> 7</a></span>
<span class="normal"><a href="#__codelineno-1-8"> 8</a></span>
<span class="normal"><a href="#__codelineno-1-9"> 9</a></span>
<span class="normal"><a href="#__codelineno-1-10"> 10</a></span>
<span class="normal"><a href="#__codelineno-1-11"> 11</a></span>
<span class="normal"><a href="#__codelineno-1-12"> 12</a></span>
<span class="normal"><a href="#__codelineno-1-13"> 13</a></span>
<span class="normal"><a href="#__codelineno-1-14"> 14</a></span>
<span class="normal"><a href="#__codelineno-1-15"> 15</a></span>
<span class="normal"><a href="#__codelineno-1-16"> 16</a></span>
<span class="normal"><a href="#__codelineno-1-17"> 17</a></span>
<span class="normal"><a href="#__codelineno-1-18"> 18</a></span>
<span class="normal"><a href="#__codelineno-1-19"> 19</a></span>
<span class="normal"><a href="#__codelineno-1-20"> 20</a></span>
<span class="normal"><a href="#__codelineno-1-21"> 21</a></span>
<span class="normal"><a href="#__codelineno-1-22"> 22</a></span>
<span class="normal"><a href="#__codelineno-1-23"> 23</a></span>
<span class="normal"><a href="#__codelineno-1-24"> 24</a></span>
<span class="normal"><a href="#__codelineno-1-25"> 25</a></span>
<span class="normal"><a href="#__codelineno-1-26"> 26</a></span>
<span class="normal"><a href="#__codelineno-1-27"> 27</a></span>
<span class="normal"><a href="#__codelineno-1-28"> 28</a></span>
<span class="normal"><a href="#__codelineno-1-29"> 29</a></span>
<span class="normal"><a href="#__codelineno-1-30"> 30</a></span>
<span class="normal"><a href="#__codelineno-1-31"> 31</a></span>
<span class="normal"><a href="#__codelineno-1-32"> 32</a></span>
<span class="normal"><a href="#__codelineno-1-33"> 33</a></span>
<span class="normal"><a href="#__codelineno-1-34"> 34</a></span>
<span class="normal"><a href="#__codelineno-1-35"> 35</a></span>
<span class="normal"><a href="#__codelineno-1-36"> 36</a></span>
<span class="normal"><a href="#__codelineno-1-37"> 37</a></span>
<span class="normal"><a href="#__codelineno-1-38"> 38</a></span>
<span class="normal"><a href="#__codelineno-1-39"> 39</a></span>
<span class="normal"><a href="#__codelineno-1-40"> 40</a></span>
<span class="normal"><a href="#__codelineno-1-41"> 41</a></span>
<span class="normal"><a href="#__codelineno-1-42"> 42</a></span>
<span class="normal"><a href="#__codelineno-1-43"> 43</a></span>
<span class="normal"><a href="#__codelineno-1-44"> 44</a></span>
<span class="normal"><a href="#__codelineno-1-45"> 45</a></span>
<span class="normal"><a href="#__codelineno-1-46"> 46</a></span>
<span class="normal"><a href="#__codelineno-1-47"> 47</a></span>
<span class="normal"><a href="#__codelineno-1-48"> 48</a></span>
<span class="normal"><a href="#__codelineno-1-49"> 49</a></span>
<span class="normal"><a href="#__codelineno-1-50"> 50</a></span>
<span class="normal"><a href="#__codelineno-1-51"> 51</a></span>
<span class="normal"><a href="#__codelineno-1-52"> 52</a></span>
<span class="normal"><a href="#__codelineno-1-53"> 53</a></span>
<span class="normal"><a href="#__codelineno-1-54"> 54</a></span>
<span class="normal"><a href="#__codelineno-1-55"> 55</a></span>
<span class="normal"><a href="#__codelineno-1-56"> 56</a></span>
<span class="normal"><a href="#__codelineno-1-57"> 57</a></span>
<span class="normal"><a href="#__codelineno-1-58"> 58</a></span>
<span class="normal"><a href="#__codelineno-1-59"> 59</a></span>
<span class="normal"><a href="#__codelineno-1-60"> 60</a></span>
<span class="normal"><a href="#__codelineno-1-61"> 61</a></span>
<span class="normal"><a href="#__codelineno-1-62"> 62</a></span>
<span class="normal"><a href="#__codelineno-1-63"> 63</a></span>
<span class="normal"><a href="#__codelineno-1-64"> 64</a></span>
<span class="normal"><a href="#__codelineno-1-65"> 65</a></span>
<span class="normal"><a href="#__codelineno-1-66"> 66</a></span>
<span class="normal"><a href="#__codelineno-1-67"> 67</a></span>
<span class="normal"><a href="#__codelineno-1-68"> 68</a></span>
<span class="normal"><a href="#__codelineno-1-69"> 69</a></span>
<span class="normal"><a href="#__codelineno-1-70"> 70</a></span>
<span class="normal"><a href="#__codelineno-1-71"> 71</a></span>
<span class="normal"><a href="#__codelineno-1-72"> 72</a></span>
<span class="normal"><a href="#__codelineno-1-73"> 73</a></span>
<span class="normal"><a href="#__codelineno-1-74"> 74</a></span>
<span class="normal"><a href="#__codelineno-1-75"> 75</a></span>
<span class="normal"><a href="#__codelineno-1-76"> 76</a></span>
<span class="normal"><a href="#__codelineno-1-77"> 77</a></span>
<span class="normal"><a href="#__codelineno-1-78"> 78</a></span>
<span class="normal"><a href="#__codelineno-1-79"> 79</a></span>
<span class="normal"><a href="#__codelineno-1-80"> 80</a></span>
<span class="normal"><a href="#__codelineno-1-81"> 81</a></span>
<span class="normal"><a href="#__codelineno-1-82"> 82</a></span>
<span class="normal"><a href="#__codelineno-1-83"> 83</a></span>
<span class="normal"><a href="#__codelineno-1-84"> 84</a></span>
<span class="normal"><a href="#__codelineno-1-85"> 85</a></span>
<span class="normal"><a href="#__codelineno-1-86"> 86</a></span>
<span class="normal"><a href="#__codelineno-1-87"> 87</a></span>
<span class="normal"><a href="#__codelineno-1-88"> 88</a></span>
<span class="normal"><a href="#__codelineno-1-89"> 89</a></span>
<span class="normal"><a href="#__codelineno-1-90"> 90</a></span>
<span class="normal"><a href="#__codelineno-1-91"> 91</a></span>
<span class="normal"><a href="#__codelineno-1-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-1-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-1-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-1-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-1-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-1-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-1-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-1-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-1-100">100</a></span>
<span class="normal"><a href="#__codelineno-1-101">101</a></span>
<span class="normal"><a href="#__codelineno-1-102">102</a></span>
<span class="normal"><a href="#__codelineno-1-103">103</a></span>
<span class="normal"><a href="#__codelineno-1-104">104</a></span>
<span class="normal"><a href="#__codelineno-1-105">105</a></span>
<span class="normal"><a href="#__codelineno-1-106">106</a></span>
<span class="normal"><a href="#__codelineno-1-107">107</a></span>
<span class="normal"><a href="#__codelineno-1-108">108</a></span>
<span class="normal"><a href="#__codelineno-1-109">109</a></span>
<span class="normal"><a href="#__codelineno-1-110">110</a></span>
<span class="normal"><a href="#__codelineno-1-111">111</a></span>
<span class="normal"><a href="#__codelineno-1-112">112</a></span>
<span class="normal"><a href="#__codelineno-1-113">113</a></span>
<span class="normal"><a href="#__codelineno-1-114">114</a></span>
<span class="normal"><a href="#__codelineno-1-115">115</a></span>
<span class="normal"><a href="#__codelineno-1-116">116</a></span>
<span class="normal"><a href="#__codelineno-1-117">117</a></span>
<span class="normal"><a href="#__codelineno-1-118">118</a></span>
<span class="normal"><a href="#__codelineno-1-119">119</a></span>
<span class="normal"><a href="#__codelineno-1-120">120</a></span>
<span class="normal"><a href="#__codelineno-1-121">121</a></span>
<span class="normal"><a href="#__codelineno-1-122">122</a></span>
<span class="normal"><a href="#__codelineno-1-123">123</a></span>
<span class="normal"><a href="#__codelineno-1-124">124</a></span>
<span class="normal"><a href="#__codelineno-1-125">125</a></span>
<span class="normal"><a href="#__codelineno-1-126">126</a></span>
<span class="normal"><a href="#__codelineno-1-127">127</a></span>
<span class="normal"><a href="#__codelineno-1-128">128</a></span>
<span class="normal"><a href="#__codelineno-1-129">129</a></span>
<span class="normal"><a href="#__codelineno-1-130">130</a></span>
<span class="normal"><a href="#__codelineno-1-131">131</a></span>
<span class="normal"><a href="#__codelineno-1-132">132</a></span>
<span class="normal"><a href="#__codelineno-1-133">133</a></span>
<span class="normal"><a href="#__codelineno-1-134">134</a></span>
<span class="normal"><a href="#__codelineno-1-135">135</a></span>
<span class="normal"><a href="#__codelineno-1-136">136</a></span>
<span class="normal"><a href="#__codelineno-1-137">137</a></span>
<span class="normal"><a href="#__codelineno-1-138">138</a></span>
<span class="normal"><a href="#__codelineno-1-139">139</a></span>
<span class="normal"><a href="#__codelineno-1-140">140</a></span>
<span class="normal"><a href="#__codelineno-1-141">141</a></span>
<span class="normal"><a href="#__codelineno-1-142">142</a></span>
<span class="normal"><a href="#__codelineno-1-143">143</a></span>
<span class="normal"><a href="#__codelineno-1-144">144</a></span>
<span class="normal"><a href="#__codelineno-1-145">145</a></span>
<span class="normal"><a href="#__codelineno-1-146">146</a></span>
<span class="normal"><a href="#__codelineno-1-147">147</a></span>
<span class="normal"><a href="#__codelineno-1-148">148</a></span>
<span class="normal"><a href="#__codelineno-1-149">149</a></span>
<span class="normal"><a href="#__codelineno-1-150">150</a></span>
<span class="normal"><a href="#__codelineno-1-151">151</a></span>
<span class="normal"><a href="#__codelineno-1-152">152</a></span>
<span class="normal"><a href="#__codelineno-1-153">153</a></span>
<span class="normal"><a href="#__codelineno-1-154">154</a></span>
<span class="normal"><a href="#__codelineno-1-155">155</a></span>
<span class="normal"><a href="#__codelineno-1-156">156</a></span>
<span class="normal"><a href="#__codelineno-1-157">157</a></span>
<span class="normal"><a href="#__codelineno-1-158">158</a></span>
<span class="normal"><a href="#__codelineno-1-159">159</a></span>
<span class="normal"><a href="#__codelineno-1-160">160</a></span>
<span class="normal"><a href="#__codelineno-1-161">161</a></span>
<span class="normal"><a href="#__codelineno-1-162">162</a></span>
<span class="normal"><a href="#__codelineno-1-163">163</a></span>
<span class="normal"><a href="#__codelineno-1-164">164</a></span>
<span class="normal"><a href="#__codelineno-1-165">165</a></span>
<span class="normal"><a href="#__codelineno-1-166">166</a></span>
<span class="normal"><a href="#__codelineno-1-167">167</a></span>
<span class="normal"><a href="#__codelineno-1-168">168</a></span>
<span class="normal"><a href="#__codelineno-1-169">169</a></span>
<span class="normal"><a href="#__codelineno-1-170">170</a></span>
<span class="normal"><a href="#__codelineno-1-171">171</a></span>
<span class="normal"><a href="#__codelineno-1-172">172</a></span>
<span class="normal"><a href="#__codelineno-1-173">173</a></span>
<span class="normal"><a href="#__codelineno-1-174">174</a></span>
<span class="normal"><a href="#__codelineno-1-175">175</a></span>
<span class="normal"><a href="#__codelineno-1-176">176</a></span>
<span class="normal"><a href="#__codelineno-1-177">177</a></span>
<span class="normal"><a href="#__codelineno-1-178">178</a></span>
<span class="normal"><a href="#__codelineno-1-179">179</a></span>
<span class="normal"><a href="#__codelineno-1-180">180</a></span>
<span class="normal"><a href="#__codelineno-1-181">181</a></span>
<span class="normal"><a href="#__codelineno-1-182">182</a></span>
<span class="normal"><a href="#__codelineno-1-183">183</a></span>
<span class="normal"><a href="#__codelineno-1-184">184</a></span>
<span class="normal"><a href="#__codelineno-1-185">185</a></span>
<span class="normal"><a href="#__codelineno-1-186">186</a></span>
<span class="normal"><a href="#__codelineno-1-187">187</a></span>
<span class="normal"><a href="#__codelineno-1-188">188</a></span>
<span class="normal"><a href="#__codelineno-1-189">189</a></span>
<span class="normal"><a href="#__codelineno-1-190">190</a></span>
<span class="normal"><a href="#__codelineno-1-191">191</a></span>
<span class="normal"><a href="#__codelineno-1-192">192</a></span>
<span class="normal"><a href="#__codelineno-1-193">193</a></span>
<span class="normal"><a href="#__codelineno-1-194">194</a></span>
<span class="normal"><a href="#__codelineno-1-195">195</a></span>
<span class="normal"><a href="#__codelineno-1-196">196</a></span>
<span class="normal"><a href="#__codelineno-1-197">197</a></span>
<span class="normal"><a href="#__codelineno-1-198">198</a></span>
<span class="normal"><a href="#__codelineno-1-199">199</a></span>
<span class="normal"><a href="#__codelineno-1-200">200</a></span>
<span class="normal"><a href="#__codelineno-1-201">201</a></span>
<span class="normal"><a href="#__codelineno-1-202">202</a></span>
<span class="normal"><a href="#__codelineno-1-203">203</a></span>
<span class="normal"><a href="#__codelineno-1-204">204</a></span>
<span class="normal"><a href="#__codelineno-1-205">205</a></span>
<span class="normal"><a href="#__codelineno-1-206">206</a></span>
<span class="normal"><a href="#__codelineno-1-207">207</a></span>
<span class="normal"><a href="#__codelineno-1-208">208</a></span>
<span class="normal"><a href="#__codelineno-1-209">209</a></span>
<span class="normal"><a href="#__codelineno-1-210">210</a></span>
<span class="normal"><a href="#__codelineno-1-211">211</a></span>
<span class="normal"><a href="#__codelineno-1-212">212</a></span>
<span class="normal"><a href="#__codelineno-1-213">213</a></span>
<span class="normal"><a href="#__codelineno-1-214">214</a></span>
<span class="normal"><a href="#__codelineno-1-215">215</a></span>
<span class="normal"><a href="#__codelineno-1-216">216</a></span>
<span class="normal"><a href="#__codelineno-1-217">217</a></span>
<span class="normal"><a href="#__codelineno-1-218">218</a></span>
<span class="normal"><a href="#__codelineno-1-219">219</a></span>
<span class="normal"><a href="#__codelineno-1-220">220</a></span>
<span class="normal"><a href="#__codelineno-1-221">221</a></span>
<span class="normal"><a href="#__codelineno-1-222">222</a></span>
<span class="normal"><a href="#__codelineno-1-223">223</a></span>
<span class="normal"><a href="#__codelineno-1-224">224</a></span>
<span class="normal"><a href="#__codelineno-1-225">225</a></span>
<span class="normal"><a href="#__codelineno-1-226">226</a></span>
<span class="normal"><a href="#__codelineno-1-227">227</a></span>
<span class="normal"><a href="#__codelineno-1-228">228</a></span>
<span class="normal"><a href="#__codelineno-1-229">229</a></span>
<span class="normal"><a href="#__codelineno-1-230">230</a></span>
<span class="normal"><a href="#__codelineno-1-231">231</a></span>
<span class="normal"><a href="#__codelineno-1-232">232</a></span>
<span class="normal"><a href="#__codelineno-1-233">233</a></span>
<span class="normal"><a href="#__codelineno-1-234">234</a></span>
<span class="normal"><a href="#__codelineno-1-235">235</a></span>
<span class="normal"><a href="#__codelineno-1-236">236</a></span>
<span class="normal"><a href="#__codelineno-1-237">237</a></span>
<span class="normal"><a href="#__codelineno-1-238">238</a></span>
<span class="normal"><a href="#__codelineno-1-239">239</a></span>
<span class="normal"><a href="#__codelineno-1-240">240</a></span>
<span class="normal"><a href="#__codelineno-1-241">241</a></span>
<span class="normal"><a href="#__codelineno-1-242">242</a></span>
<span class="normal"><a href="#__codelineno-1-243">243</a></span>
<span class="normal"><a href="#__codelineno-1-244">244</a></span>
<span class="normal"><a href="#__codelineno-1-245">245</a></span>
<span class="normal"><a href="#__codelineno-1-246">246</a></span>
<span class="normal"><a href="#__codelineno-1-247">247</a></span>
<span class="normal"><a href="#__codelineno-1-248">248</a></span>
<span class="normal"><a href="#__codelineno-1-249">249</a></span>
<span class="normal"><a href="#__codelineno-1-250">250</a></span>
<span class="normal"><a href="#__codelineno-1-251">251</a></span>
<span class="normal"><a href="#__codelineno-1-252">252</a></span>
<span class="normal"><a href="#__codelineno-1-253">253</a></span>
<span class="normal"><a href="#__codelineno-1-254">254</a></span>
<span class="normal"><a href="#__codelineno-1-255">255</a></span>
<span class="normal"><a href="#__codelineno-1-256">256</a></span>
<span class="normal"><a href="#__codelineno-1-257">257</a></span>
<span class="normal"><a href="#__codelineno-1-258">258</a></span>
<span class="normal"><a href="#__codelineno-1-259">259</a></span>
<span class="normal"><a href="#__codelineno-1-260">260</a></span>
<span class="normal"><a href="#__codelineno-1-261">261</a></span>
<span class="normal"><a href="#__codelineno-1-262">262</a></span>
<span class="normal"><a href="#__codelineno-1-263">263</a></span>
<span class="normal"><a href="#__codelineno-1-264">264</a></span>
<span class="normal"><a href="#__codelineno-1-265">265</a></span>
<span class="normal"><a href="#__codelineno-1-266">266</a></span>
<span class="normal"><a href="#__codelineno-1-267">267</a></span>
<span class="normal"><a href="#__codelineno-1-268">268</a></span>
<span class="normal"><a href="#__codelineno-1-269">269</a></span>
<span class="normal"><a href="#__codelineno-1-270">270</a></span>
<span class="normal"><a href="#__codelineno-1-271">271</a></span>
<span class="normal"><a href="#__codelineno-1-272">272</a></span>
<span class="normal"><a href="#__codelineno-1-273">273</a></span>
<span class="normal"><a href="#__codelineno-1-274">274</a></span>
<span class="normal"><a href="#__codelineno-1-275">275</a></span>
<span class="normal"><a href="#__codelineno-1-276">276</a></span>
<span class="normal"><a href="#__codelineno-1-277">277</a></span>
<span class="normal"><a href="#__codelineno-1-278">278</a></span>
<span class="normal"><a href="#__codelineno-1-279">279</a></span>
<span class="normal"><a href="#__codelineno-1-280">280</a></span>
<span class="normal"><a href="#__codelineno-1-281">281</a></span>
<span class="normal"><a href="#__codelineno-1-282">282</a></span>
<span class="normal"><a href="#__codelineno-1-283">283</a></span>
<span class="normal"><a href="#__codelineno-1-284">284</a></span>
<span class="normal"><a href="#__codelineno-1-285">285</a></span>
<span class="normal"><a href="#__codelineno-1-286">286</a></span>
<span class="normal"><a href="#__codelineno-1-287">287</a></span>
<span class="normal"><a href="#__codelineno-1-288">288</a></span>
<span class="normal"><a href="#__codelineno-1-289">289</a></span>
<span class="normal"><a href="#__codelineno-1-290">290</a></span>
<span class="normal"><a href="#__codelineno-1-291">291</a></span>
<span class="normal"><a href="#__codelineno-1-292">292</a></span>
<span class="normal"><a href="#__codelineno-1-293">293</a></span>
<span class="normal"><a href="#__codelineno-1-294">294</a></span>
<span class="normal"><a href="#__codelineno-1-295">295</a></span>
<span class="normal"><a href="#__codelineno-1-296">296</a></span>
<span class="normal"><a href="#__codelineno-1-297">297</a></span>
<span class="normal"><a href="#__codelineno-1-298">298</a></span>
<span class="normal"><a href="#__codelineno-1-299">299</a></span>
<span class="normal"><a href="#__codelineno-1-300">300</a></span>
<span class="normal"><a href="#__codelineno-1-301">301</a></span>
<span class="normal"><a href="#__codelineno-1-302">302</a></span>
<span class="normal"><a href="#__codelineno-1-303">303</a></span>
<span class="normal"><a href="#__codelineno-1-304">304</a></span>
<span class="normal"><a href="#__codelineno-1-305">305</a></span>
<span class="normal"><a href="#__codelineno-1-306">306</a></span>
<span class="normal"><a href="#__codelineno-1-307">307</a></span>
<span class="normal"><a href="#__codelineno-1-308">308</a></span>
<span class="normal"><a href="#__codelineno-1-309">309</a></span>
<span class="normal"><a href="#__codelineno-1-310">310</a></span>
<span class="normal"><a href="#__codelineno-1-311">311</a></span>
<span class="normal"><a href="#__codelineno-1-312">312</a></span>
<span class="normal"><a href="#__codelineno-1-313">313</a></span>
<span class="normal"><a href="#__codelineno-1-314">314</a></span>
<span class="normal"><a href="#__codelineno-1-315">315</a></span>
<span class="normal"><a href="#__codelineno-1-316">316</a></span>
<span class="normal"><a href="#__codelineno-1-317">317</a></span>
<span class="normal"><a href="#__codelineno-1-318">318</a></span>
<span class="normal"><a href="#__codelineno-1-319">319</a></span>
<span class="normal"><a href="#__codelineno-1-320">320</a></span>
<span class="normal"><a href="#__codelineno-1-321">321</a></span>
<span class="normal"><a href="#__codelineno-1-322">322</a></span>
<span class="normal"><a href="#__codelineno-1-323">323</a></span>
<span class="normal"><a href="#__codelineno-1-324">324</a></span>
<span class="normal"><a href="#__codelineno-1-325">325</a></span>
<span class="normal"><a href="#__codelineno-1-326">326</a></span>
<span class="normal"><a href="#__codelineno-1-327">327</a></span>
<span class="normal"><a href="#__codelineno-1-328">328</a></span>
<span class="normal"><a href="#__codelineno-1-329">329</a></span>
<span class="normal"><a href="#__codelineno-1-330">330</a></span>
<span class="normal"><a href="#__codelineno-1-331">331</a></span>
<span class="normal"><a href="#__codelineno-1-332">332</a></span>
<span class="normal"><a href="#__codelineno-1-333">333</a></span>
<span class="normal"><a href="#__codelineno-1-334">334</a></span>
<span class="normal"><a href="#__codelineno-1-335">335</a></span>
<span class="normal"><a href="#__codelineno-1-336">336</a></span>
<span class="normal"><a href="#__codelineno-1-337">337</a></span>
<span class="normal"><a href="#__codelineno-1-338">338</a></span>
<span class="normal"><a href="#__codelineno-1-339">339</a></span>
<span class="normal"><a href="#__codelineno-1-340">340</a></span>
<span class="normal"><a href="#__codelineno-1-341">341</a></span>
<span class="normal"><a href="#__codelineno-1-342">342</a></span>
<span class="normal"><a href="#__codelineno-1-343">343</a></span>
<span class="normal"><a href="#__codelineno-1-344">344</a></span>
<span class="normal"><a href="#__codelineno-1-345">345</a></span>
<span class="normal"><a href="#__codelineno-1-346">346</a></span>
<span class="normal"><a href="#__codelineno-1-347">347</a></span>
<span class="normal"><a href="#__codelineno-1-348">348</a></span>
<span class="normal"><a href="#__codelineno-1-349">349</a></span>
<span class="normal"><a href="#__codelineno-1-350">350</a></span>
<span class="normal"><a href="#__codelineno-1-351">351</a></span>
<span class="normal"><a href="#__codelineno-1-352">352</a></span>
<span class="normal"><a href="#__codelineno-1-353">353</a></span>
<span class="normal"><a href="#__codelineno-1-354">354</a></span>
<span class="normal"><a href="#__codelineno-1-355">355</a></span>
<span class="normal"><a href="#__codelineno-1-356">356</a></span>
<span class="normal"><a href="#__codelineno-1-357">357</a></span>
<span class="normal"><a href="#__codelineno-1-358">358</a></span>
<span class="normal"><a href="#__codelineno-1-359">359</a></span>
<span class="normal"><a href="#__codelineno-1-360">360</a></span>
<span class="normal"><a href="#__codelineno-1-361">361</a></span>
<span class="normal"><a href="#__codelineno-1-362">362</a></span>
<span class="normal"><a href="#__codelineno-1-363">363</a></span>
<span class="normal"><a href="#__codelineno-1-364">364</a></span>
<span class="normal"><a href="#__codelineno-1-365">365</a></span>
<span class="normal"><a href="#__codelineno-1-366">366</a></span>
<span class="normal"><a href="#__codelineno-1-367">367</a></span>
<span class="normal"><a href="#__codelineno-1-368">368</a></span>
<span class="normal"><a href="#__codelineno-1-369">369</a></span>
<span class="normal"><a href="#__codelineno-1-370">370</a></span>
<span class="normal"><a href="#__codelineno-1-371">371</a></span>
<span class="normal"><a href="#__codelineno-1-372">372</a></span>
<span class="normal"><a href="#__codelineno-1-373">373</a></span>
<span class="normal"><a href="#__codelineno-1-374">374</a></span>
<span class="normal"><a href="#__codelineno-1-375">375</a></span>
<span class="normal"><a href="#__codelineno-1-376">376</a></span>
<span class="normal"><a href="#__codelineno-1-377">377</a></span>
<span class="normal"><a href="#__codelineno-1-378">378</a></span>
<span class="normal"><a href="#__codelineno-1-379">379</a></span>
<span class="normal"><a href="#__codelineno-1-380">380</a></span>
<span class="normal"><a href="#__codelineno-1-381">381</a></span>
<span class="normal"><a href="#__codelineno-1-382">382</a></span>
<span class="normal"><a href="#__codelineno-1-383">383</a></span>
<span class="normal"><a href="#__codelineno-1-384">384</a></span>
<span class="normal"><a href="#__codelineno-1-385">385</a></span>
<span class="normal"><a href="#__codelineno-1-386">386</a></span>
<span class="normal"><a href="#__codelineno-1-387">387</a></span>
<span class="normal"><a href="#__codelineno-1-388">388</a></span>
<span class="normal"><a href="#__codelineno-1-389">389</a></span>
<span class="normal"><a href="#__codelineno-1-390">390</a></span>
<span class="normal"><a href="#__codelineno-1-391">391</a></span>
<span class="normal"><a href="#__codelineno-1-392">392</a></span>
<span class="normal"><a href="#__codelineno-1-393">393</a></span>
<span class="normal"><a href="#__codelineno-1-394">394</a></span>
<span class="normal"><a href="#__codelineno-1-395">395</a></span>
<span class="normal"><a href="#__codelineno-1-396">396</a></span>
<span class="normal"><a href="#__codelineno-1-397">397</a></span>
<span class="normal"><a href="#__codelineno-1-398">398</a></span>
<span class="normal"><a href="#__codelineno-1-399">399</a></span>
<span class="normal"><a href="#__codelineno-1-400">400</a></span>
<span class="normal"><a href="#__codelineno-1-401">401</a></span>
<span class="normal"><a href="#__codelineno-1-402">402</a></span>
<span class="normal"><a href="#__codelineno-1-403">403</a></span>
<span class="normal"><a href="#__codelineno-1-404">404</a></span>
<span class="normal"><a href="#__codelineno-1-405">405</a></span>
<span class="normal"><a href="#__codelineno-1-406">406</a></span>
<span class="normal"><a href="#__codelineno-1-407">407</a></span>
<span class="normal"><a href="#__codelineno-1-408">408</a></span>
<span class="normal"><a href="#__codelineno-1-409">409</a></span>
<span class="normal"><a href="#__codelineno-1-410">410</a></span>
<span class="normal"><a href="#__codelineno-1-411">411</a></span>
<span class="normal"><a href="#__codelineno-1-412">412</a></span>
<span class="normal"><a href="#__codelineno-1-413">413</a></span>
<span class="normal"><a href="#__codelineno-1-414">414</a></span>
<span class="normal"><a href="#__codelineno-1-415">415</a></span>
<span class="normal"><a href="#__codelineno-1-416">416</a></span>
<span class="normal"><a href="#__codelineno-1-417">417</a></span>
<span class="normal"><a href="#__codelineno-1-418">418</a></span>
<span class="normal"><a href="#__codelineno-1-419">419</a></span>
<span class="normal"><a href="#__codelineno-1-420">420</a></span>
<span class="normal"><a href="#__codelineno-1-421">421</a></span>
<span class="normal"><a href="#__codelineno-1-422">422</a></span>
<span class="normal"><a href="#__codelineno-1-423">423</a></span>
<span class="normal"><a href="#__codelineno-1-424">424</a></span>
<span class="normal"><a href="#__codelineno-1-425">425</a></span>
<span class="normal"><a href="#__codelineno-1-426">426</a></span>
<span class="normal"><a href="#__codelineno-1-427">427</a></span>
<span class="normal"><a href="#__codelineno-1-428">428</a></span>
<span class="normal"><a href="#__codelineno-1-429">429</a></span>
<span class="normal"><a href="#__codelineno-1-430">430</a></span>
<span class="normal"><a href="#__codelineno-1-431">431</a></span>
<span class="normal"><a href="#__codelineno-1-432">432</a></span>
<span class="normal"><a href="#__codelineno-1-433">433</a></span>
<span class="normal"><a href="#__codelineno-1-434">434</a></span>
<span class="normal"><a href="#__codelineno-1-435">435</a></span>
<span class="normal"><a href="#__codelineno-1-436">436</a></span>
<span class="normal"><a href="#__codelineno-1-437">437</a></span>
<span class="normal"><a href="#__codelineno-1-438">438</a></span>
<span class="normal"><a href="#__codelineno-1-439">439</a></span>
<span class="normal"><a href="#__codelineno-1-440">440</a></span>
<span class="normal"><a href="#__codelineno-1-441">441</a></span>
<span class="normal"><a href="#__codelineno-1-442">442</a></span>
<span class="normal"><a href="#__codelineno-1-443">443</a></span>
<span class="normal"><a href="#__codelineno-1-444">444</a></span>
<span class="normal"><a href="#__codelineno-1-445">445</a></span>
<span class="normal"><a href="#__codelineno-1-446">446</a></span>
<span class="normal"><a href="#__codelineno-1-447">447</a></span>
<span class="normal"><a href="#__codelineno-1-448">448</a></span>
<span class="normal"><a href="#__codelineno-1-449">449</a></span>
<span class="normal"><a href="#__codelineno-1-450">450</a></span>
<span class="normal"><a href="#__codelineno-1-451">451</a></span>
<span class="normal"><a href="#__codelineno-1-452">452</a></span>
<span class="normal"><a href="#__codelineno-1-453">453</a></span>
<span class="normal"><a href="#__codelineno-1-454">454</a></span>
<span class="normal"><a href="#__codelineno-1-455">455</a></span>
<span class="normal"><a href="#__codelineno-1-456">456</a></span>
<span class="normal"><a href="#__codelineno-1-457">457</a></span>
<span class="normal"><a href="#__codelineno-1-458">458</a></span>
<span class="normal"><a href="#__codelineno-1-459">459</a></span>
<span class="normal"><a href="#__codelineno-1-460">460</a></span>
<span class="normal"><a href="#__codelineno-1-461">461</a></span>
<span class="normal"><a href="#__codelineno-1-462">462</a></span>
<span class="normal"><a href="#__codelineno-1-463">463</a></span>
<span class="normal"><a href="#__codelineno-1-464">464</a></span>
<span class="normal"><a href="#__codelineno-1-465">465</a></span>
<span class="normal"><a href="#__codelineno-1-466">466</a></span>
<span class="normal"><a href="#__codelineno-1-467">467</a></span>
<span class="normal"><a href="#__codelineno-1-468">468</a></span>
<span class="normal"><a href="#__codelineno-1-469">469</a></span>
<span class="normal"><a href="#__codelineno-1-470">470</a></span>
<span class="normal"><a href="#__codelineno-1-471">471</a></span>
<span class="normal"><a href="#__codelineno-1-472">472</a></span>
<span class="normal"><a href="#__codelineno-1-473">473</a></span>
<span class="normal"><a href="#__codelineno-1-474">474</a></span>
<span class="normal"><a href="#__codelineno-1-475">475</a></span>
<span class="normal"><a href="#__codelineno-1-476">476</a></span>
<span class="normal"><a href="#__codelineno-1-477">477</a></span>
<span class="normal"><a href="#__codelineno-1-478">478</a></span>
<span class="normal"><a href="#__codelineno-1-479">479</a></span>
<span class="normal"><a href="#__codelineno-1-480">480</a></span>
<span class="normal"><a href="#__codelineno-1-481">481</a></span>
<span class="normal"><a href="#__codelineno-1-482">482</a></span>
<span class="normal"><a href="#__codelineno-1-483">483</a></span>
<span class="normal"><a href="#__codelineno-1-484">484</a></span>
<span class="normal"><a href="#__codelineno-1-485">485</a></span>
<span class="normal"><a href="#__codelineno-1-486">486</a></span>
<span class="normal"><a href="#__codelineno-1-487">487</a></span>
<span class="normal"><a href="#__codelineno-1-488">488</a></span>
<span class="normal"><a href="#__codelineno-1-489">489</a></span>
<span class="normal"><a href="#__codelineno-1-490">490</a></span>
<span class="normal"><a href="#__codelineno-1-491">491</a></span>
<span class="normal"><a href="#__codelineno-1-492">492</a></span>
<span class="normal"><a href="#__codelineno-1-493">493</a></span>
<span class="normal"><a href="#__codelineno-1-494">494</a></span>
<span class="normal"><a href="#__codelineno-1-495">495</a></span>
<span class="normal"><a href="#__codelineno-1-496">496</a></span>
<span class="normal"><a href="#__codelineno-1-497">497</a></span>
<span class="normal"><a href="#__codelineno-1-498">498</a></span>
<span class="normal"><a href="#__codelineno-1-499">499</a></span>
<span class="normal"><a href="#__codelineno-1-500">500</a></span>
<span class="normal"><a href="#__codelineno-1-501">501</a></span>
<span class="normal"><a href="#__codelineno-1-502">502</a></span>
<span class="normal"><a href="#__codelineno-1-503">503</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<a id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
<a id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="kn">from</span><span class="w"> </span><span class="nn">collections</span><span class="w"> </span><span class="kn">import</span> <span class="n">Counter</span><span class="p">,</span> <span class="n">defaultdict</span>
<a id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="kn">from</span><span class="w"> </span><span class="nn">textwrap</span><span class="w"> </span><span class="kn">import</span> <span class="n">dedent</span>
<a id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="kn">import</span><span class="w"> </span><span class="nn">hashlib</span>
<a id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="kn">import</span><span class="w"> </span><span class="nn">yaml</span>
<a id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="kn">from</span><span class="w"> </span><span class="nn">urllib.parse</span><span class="w"> </span><span class="kn">import</span> <span class="n">urlparse</span>
<a id="__codelineno-1-8" name="__codelineno-1-8"></a>
<a id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="c1"># 存储所有文章的信息和索引</span>
<a id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="n">article_index</span> <span class="o">=</span> <span class="p">{}</span>
<a id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="n">category_index</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<a id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="n">keyword_index</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
<a id="__codelineno-1-13" name="__codelineno-1-13"></a>
<a id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="c1"># 配置:需要索引的目录</span>
<a id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="n">INDEXED_DIRECTORIES</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;blog/&#39;</span><span class="p">,</span> <span class="s1">&#39;develop/&#39;</span><span class="p">]</span>
<a id="__codelineno-1-16" name="__codelineno-1-16"></a>
<a id="__codelineno-1-17" name="__codelineno-1-17"></a><span class="c1"># 配置:排除推荐的页面列表(支持精确匹配和模式匹配)</span>
<a id="__codelineno-1-18" name="__codelineno-1-18"></a><span class="n">EXCLUDED_PAGES</span> <span class="o">=</span> <span class="p">{</span>
<a id="__codelineno-1-19" name="__codelineno-1-19"></a> <span class="c1"># 精确路径匹配</span>
<a id="__codelineno-1-20" name="__codelineno-1-20"></a> <span class="s1">&#39;blog/index.md&#39;</span><span class="p">,</span>
<a id="__codelineno-1-21" name="__codelineno-1-21"></a> <span class="s1">&#39;develop/index.md&#39;</span><span class="p">,</span>
<a id="__codelineno-1-22" name="__codelineno-1-22"></a> <span class="c1"># 可以添加更多排除的页面</span>
<a id="__codelineno-1-23" name="__codelineno-1-23"></a> <span class="c1"># &#39;blog/special-page.md&#39;,</span>
<a id="__codelineno-1-24" name="__codelineno-1-24"></a><span class="p">}</span>
<a id="__codelineno-1-25" name="__codelineno-1-25"></a>
<a id="__codelineno-1-26" name="__codelineno-1-26"></a><span class="c1"># 配置:排除推荐的页面模式(支持通配符)</span>
<a id="__codelineno-1-27" name="__codelineno-1-27"></a><span class="n">EXCLUDED_PATTERNS</span> <span class="o">=</span> <span class="p">[</span>
<a id="__codelineno-1-28" name="__codelineno-1-28"></a> <span class="sa">r</span><span class="s1">&#39;.*\/index\.md$&#39;</span><span class="p">,</span> <span class="c1"># 排除所有 index.md 文件</span>
<a id="__codelineno-1-29" name="__codelineno-1-29"></a> <span class="sa">r</span><span class="s1">&#39;.*\/archive\.md$&#39;</span><span class="p">,</span> <span class="c1"># 排除所有 archive.md 文件</span>
<a id="__codelineno-1-30" name="__codelineno-1-30"></a> <span class="sa">r</span><span class="s1">&#39;blog\/posts?\/.*&#39;</span><span class="p">,</span> <span class="c1"># 排除 blog/post/ 和 blog/posts/ 目录下的所有文章</span>
<a id="__codelineno-1-31" name="__codelineno-1-31"></a> <span class="c1"># 可以添加更多模式</span>
<a id="__codelineno-1-32" name="__codelineno-1-32"></a> <span class="c1"># r&#39;blog\/draft\/.*&#39;, # 排除草稿目录</span>
<a id="__codelineno-1-33" name="__codelineno-1-33"></a><span class="p">]</span>
<a id="__codelineno-1-34" name="__codelineno-1-34"></a>
<a id="__codelineno-1-35" name="__codelineno-1-35"></a><span class="c1"># 配置:相似度阈值和权重</span>
<a id="__codelineno-1-36" name="__codelineno-1-36"></a><span class="n">SIMILARITY_CONFIG</span> <span class="o">=</span> <span class="p">{</span>
<a id="__codelineno-1-37" name="__codelineno-1-37"></a> <span class="s1">&#39;min_threshold&#39;</span><span class="p">:</span> <span class="mf">0.15</span><span class="p">,</span> <span class="c1"># 提高最低相似度阈值</span>
<a id="__codelineno-1-38" name="__codelineno-1-38"></a> <span class="s1">&#39;weights&#39;</span><span class="p">:</span> <span class="p">{</span>
<a id="__codelineno-1-39" name="__codelineno-1-39"></a> <span class="s1">&#39;keywords&#39;</span><span class="p">:</span> <span class="mf">0.35</span><span class="p">,</span> <span class="c1"># 关键词权重</span>
<a id="__codelineno-1-40" name="__codelineno-1-40"></a> <span class="s1">&#39;tags&#39;</span><span class="p">:</span> <span class="mf">0.30</span><span class="p">,</span> <span class="c1"># 标签权重</span>
<a id="__codelineno-1-41" name="__codelineno-1-41"></a> <span class="s1">&#39;categories&#39;</span><span class="p">:</span> <span class="mf">0.20</span><span class="p">,</span> <span class="c1"># 分类权重</span>
<a id="__codelineno-1-42" name="__codelineno-1-42"></a> <span class="s1">&#39;path&#39;</span><span class="p">:</span> <span class="mf">0.10</span><span class="p">,</span> <span class="c1"># 路径分类权重</span>
<a id="__codelineno-1-43" name="__codelineno-1-43"></a> <span class="s1">&#39;source_dir&#39;</span><span class="p">:</span> <span class="mf">0.05</span> <span class="c1"># 源目录权重</span>
<a id="__codelineno-1-44" name="__codelineno-1-44"></a> <span class="p">},</span>
<a id="__codelineno-1-45" name="__codelineno-1-45"></a> <span class="s1">&#39;title_similarity&#39;</span><span class="p">:</span> <span class="mf">0.25</span> <span class="c1"># 标题相似度权重</span>
<a id="__codelineno-1-46" name="__codelineno-1-46"></a><span class="p">}</span>
<a id="__codelineno-1-47" name="__codelineno-1-47"></a>
<a id="__codelineno-1-48" name="__codelineno-1-48"></a><span class="k">def</span><span class="w"> </span><span class="nf">is_page_excluded</span><span class="p">(</span><span class="n">file_path</span><span class="p">):</span>
<a id="__codelineno-1-49" name="__codelineno-1-49"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;检查页面是否应该排除推荐&quot;&quot;&quot;</span>
<a id="__codelineno-1-50" name="__codelineno-1-50"></a> <span class="c1"># 精确匹配检查</span>
<a id="__codelineno-1-51" name="__codelineno-1-51"></a> <span class="k">if</span> <span class="n">file_path</span> <span class="ow">in</span> <span class="n">EXCLUDED_PAGES</span><span class="p">:</span>
<a id="__codelineno-1-52" name="__codelineno-1-52"></a> <span class="k">return</span> <span class="kc">True</span>
<a id="__codelineno-1-53" name="__codelineno-1-53"></a>
<a id="__codelineno-1-54" name="__codelineno-1-54"></a> <span class="c1"># 模式匹配检查</span>
<a id="__codelineno-1-55" name="__codelineno-1-55"></a> <span class="k">for</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="n">EXCLUDED_PATTERNS</span><span class="p">:</span>
<a id="__codelineno-1-56" name="__codelineno-1-56"></a> <span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">file_path</span><span class="p">):</span>
<a id="__codelineno-1-57" name="__codelineno-1-57"></a> <span class="k">return</span> <span class="kc">True</span>
<a id="__codelineno-1-58" name="__codelineno-1-58"></a>
<a id="__codelineno-1-59" name="__codelineno-1-59"></a> <span class="k">return</span> <span class="kc">False</span>
<a id="__codelineno-1-60" name="__codelineno-1-60"></a>
<a id="__codelineno-1-61" name="__codelineno-1-61"></a><span class="k">def</span><span class="w"> </span><span class="nf">should_index_file</span><span class="p">(</span><span class="n">file_path</span><span class="p">):</span>
<a id="__codelineno-1-62" name="__codelineno-1-62"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;检查文件是否应该被索引&quot;&quot;&quot;</span>
<a id="__codelineno-1-63" name="__codelineno-1-63"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">file_path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;.md&#39;</span><span class="p">):</span>
<a id="__codelineno-1-64" name="__codelineno-1-64"></a> <span class="k">return</span> <span class="kc">False</span>
<a id="__codelineno-1-65" name="__codelineno-1-65"></a>
<a id="__codelineno-1-66" name="__codelineno-1-66"></a> <span class="c1"># 先检查是否被排除</span>
<a id="__codelineno-1-67" name="__codelineno-1-67"></a> <span class="k">if</span> <span class="n">is_page_excluded</span><span class="p">(</span><span class="n">file_path</span><span class="p">):</span>
<a id="__codelineno-1-68" name="__codelineno-1-68"></a> <span class="k">return</span> <span class="kc">False</span>
<a id="__codelineno-1-69" name="__codelineno-1-69"></a>
<a id="__codelineno-1-70" name="__codelineno-1-70"></a> <span class="c1"># 检查是否在指定目录下</span>
<a id="__codelineno-1-71" name="__codelineno-1-71"></a> <span class="k">for</span> <span class="n">directory</span> <span class="ow">in</span> <span class="n">INDEXED_DIRECTORIES</span><span class="p">:</span>
<a id="__codelineno-1-72" name="__codelineno-1-72"></a> <span class="k">if</span> <span class="n">file_path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">directory</span><span class="p">):</span>
<a id="__codelineno-1-73" name="__codelineno-1-73"></a> <span class="k">return</span> <span class="kc">True</span>
<a id="__codelineno-1-74" name="__codelineno-1-74"></a>
<a id="__codelineno-1-75" name="__codelineno-1-75"></a> <span class="k">return</span> <span class="kc">False</span>
<a id="__codelineno-1-76" name="__codelineno-1-76"></a>
<a id="__codelineno-1-77" name="__codelineno-1-77"></a><span class="k">def</span><span class="w"> </span><span class="nf">extract_keywords</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">title</span><span class="p">):</span>
<a id="__codelineno-1-78" name="__codelineno-1-78"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;提取文章中的关键词,改进算法&quot;&quot;&quot;</span>
<a id="__codelineno-1-79" name="__codelineno-1-79"></a> <span class="c1"># 移除YAML front matter</span>
<a id="__codelineno-1-80" name="__codelineno-1-80"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^---\s*\n.*?\n---\s*\n&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">re</span><span class="o">.</span><span class="n">DOTALL</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">MULTILINE</span><span class="p">)</span>
<a id="__codelineno-1-81" name="__codelineno-1-81"></a>
<a id="__codelineno-1-82" name="__codelineno-1-82"></a> <span class="c1"># 移除代码块</span>
<a id="__codelineno-1-83" name="__codelineno-1-83"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;```.*?```&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">re</span><span class="o">.</span><span class="n">DOTALL</span><span class="p">)</span>
<a id="__codelineno-1-84" name="__codelineno-1-84"></a> <span class="c1"># 移除HTML标签</span>
<a id="__codelineno-1-85" name="__codelineno-1-85"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;&lt;.*?&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
<a id="__codelineno-1-86" name="__codelineno-1-86"></a> <span class="c1"># 移除链接</span>
<a id="__codelineno-1-87" name="__codelineno-1-87"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\[.*?\]\(.*?\)&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
<a id="__codelineno-1-88" name="__codelineno-1-88"></a> <span class="c1"># 移除标题标记</span>
<a id="__codelineno-1-89" name="__codelineno-1-89"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^#+\s+&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">re</span><span class="o">.</span><span class="n">MULTILINE</span><span class="p">)</span>
<a id="__codelineno-1-90" name="__codelineno-1-90"></a>
<a id="__codelineno-1-91" name="__codelineno-1-91"></a> <span class="c1"># 合并标题和内容,标题权重更高</span>
<a id="__codelineno-1-92" name="__codelineno-1-92"></a> <span class="n">title_words</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\b\w+\b&#39;</span><span class="p">,</span> <span class="n">title</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span> <span class="o">*</span> <span class="mi">4</span> <span class="c1"># 增加标题权重</span>
<a id="__codelineno-1-93" name="__codelineno-1-93"></a> <span class="n">content_words</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\b\w+\b&#39;</span><span class="p">,</span> <span class="n">content</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<a id="__codelineno-1-94" name="__codelineno-1-94"></a> <span class="n">all_words</span> <span class="o">=</span> <span class="n">title_words</span> <span class="o">+</span> <span class="n">content_words</span>
<a id="__codelineno-1-95" name="__codelineno-1-95"></a>
<a id="__codelineno-1-96" name="__codelineno-1-96"></a> <span class="c1"># 扩展停用词列表(包含中英文)</span>
<a id="__codelineno-1-97" name="__codelineno-1-97"></a> <span class="n">stopwords</span> <span class="o">=</span> <span class="p">{</span>
<a id="__codelineno-1-98" name="__codelineno-1-98"></a> <span class="c1"># 英文停用词</span>
<a id="__codelineno-1-99" name="__codelineno-1-99"></a> <span class="s1">&#39;the&#39;</span><span class="p">,</span> <span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;an&#39;</span><span class="p">,</span> <span class="s1">&#39;in&#39;</span><span class="p">,</span> <span class="s1">&#39;on&#39;</span><span class="p">,</span> <span class="s1">&#39;at&#39;</span><span class="p">,</span> <span class="s1">&#39;to&#39;</span><span class="p">,</span> <span class="s1">&#39;for&#39;</span><span class="p">,</span> <span class="s1">&#39;of&#39;</span><span class="p">,</span> <span class="s1">&#39;and&#39;</span><span class="p">,</span> <span class="s1">&#39;or&#39;</span><span class="p">,</span> <span class="s1">&#39;is&#39;</span><span class="p">,</span> <span class="s1">&#39;are&#39;</span><span class="p">,</span> <span class="s1">&#39;was&#39;</span><span class="p">,</span> <span class="s1">&#39;were&#39;</span><span class="p">,</span>
<a id="__codelineno-1-100" name="__codelineno-1-100"></a> <span class="s1">&#39;be&#39;</span><span class="p">,</span> <span class="s1">&#39;been&#39;</span><span class="p">,</span> <span class="s1">&#39;have&#39;</span><span class="p">,</span> <span class="s1">&#39;has&#39;</span><span class="p">,</span> <span class="s1">&#39;had&#39;</span><span class="p">,</span> <span class="s1">&#39;do&#39;</span><span class="p">,</span> <span class="s1">&#39;does&#39;</span><span class="p">,</span> <span class="s1">&#39;did&#39;</span><span class="p">,</span> <span class="s1">&#39;will&#39;</span><span class="p">,</span> <span class="s1">&#39;would&#39;</span><span class="p">,</span> <span class="s1">&#39;could&#39;</span><span class="p">,</span> <span class="s1">&#39;should&#39;</span><span class="p">,</span>
<a id="__codelineno-1-101" name="__codelineno-1-101"></a> <span class="s1">&#39;this&#39;</span><span class="p">,</span> <span class="s1">&#39;that&#39;</span><span class="p">,</span> <span class="s1">&#39;these&#39;</span><span class="p">,</span> <span class="s1">&#39;those&#39;</span><span class="p">,</span> <span class="s1">&#39;with&#39;</span><span class="p">,</span> <span class="s1">&#39;from&#39;</span><span class="p">,</span> <span class="s1">&#39;by&#39;</span><span class="p">,</span> <span class="s1">&#39;as&#39;</span><span class="p">,</span> <span class="s1">&#39;can&#39;</span><span class="p">,</span> <span class="s1">&#39;but&#39;</span><span class="p">,</span> <span class="s1">&#39;not&#39;</span><span class="p">,</span> <span class="s1">&#39;if&#39;</span><span class="p">,</span> <span class="s1">&#39;it&#39;</span><span class="p">,</span>
<a id="__codelineno-1-102" name="__codelineno-1-102"></a> <span class="s1">&#39;they&#39;</span><span class="p">,</span> <span class="s1">&#39;them&#39;</span><span class="p">,</span> <span class="s1">&#39;their&#39;</span><span class="p">,</span> <span class="s1">&#39;you&#39;</span><span class="p">,</span> <span class="s1">&#39;your&#39;</span><span class="p">,</span> <span class="s1">&#39;we&#39;</span><span class="p">,</span> <span class="s1">&#39;our&#39;</span><span class="p">,</span> <span class="s1">&#39;my&#39;</span><span class="p">,</span> <span class="s1">&#39;me&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="s1">&#39;he&#39;</span><span class="p">,</span> <span class="s1">&#39;she&#39;</span><span class="p">,</span> <span class="s1">&#39;him&#39;</span><span class="p">,</span> <span class="s1">&#39;her&#39;</span><span class="p">,</span>
<a id="__codelineno-1-103" name="__codelineno-1-103"></a> <span class="c1"># 常见无意义词</span>
<a id="__codelineno-1-104" name="__codelineno-1-104"></a> <span class="s1">&#39;about&#39;</span><span class="p">,</span> <span class="s1">&#39;above&#39;</span><span class="p">,</span> <span class="s1">&#39;after&#39;</span><span class="p">,</span> <span class="s1">&#39;again&#39;</span><span class="p">,</span> <span class="s1">&#39;all&#39;</span><span class="p">,</span> <span class="s1">&#39;also&#39;</span><span class="p">,</span> <span class="s1">&#39;any&#39;</span><span class="p">,</span> <span class="s1">&#39;because&#39;</span><span class="p">,</span> <span class="s1">&#39;before&#39;</span><span class="p">,</span> <span class="s1">&#39;between&#39;</span><span class="p">,</span>
<a id="__codelineno-1-105" name="__codelineno-1-105"></a> <span class="s1">&#39;both&#39;</span><span class="p">,</span> <span class="s1">&#39;each&#39;</span><span class="p">,</span> <span class="s1">&#39;few&#39;</span><span class="p">,</span> <span class="s1">&#39;first&#39;</span><span class="p">,</span> <span class="s1">&#39;get&#39;</span><span class="p">,</span> <span class="s1">&#39;how&#39;</span><span class="p">,</span> <span class="s1">&#39;into&#39;</span><span class="p">,</span> <span class="s1">&#39;just&#39;</span><span class="p">,</span> <span class="s1">&#39;last&#39;</span><span class="p">,</span> <span class="s1">&#39;made&#39;</span><span class="p">,</span> <span class="s1">&#39;make&#39;</span><span class="p">,</span> <span class="s1">&#39;may&#39;</span><span class="p">,</span>
<a id="__codelineno-1-106" name="__codelineno-1-106"></a> <span class="s1">&#39;most&#39;</span><span class="p">,</span> <span class="s1">&#39;new&#39;</span><span class="p">,</span> <span class="s1">&#39;now&#39;</span><span class="p">,</span> <span class="s1">&#39;old&#39;</span><span class="p">,</span> <span class="s1">&#39;only&#39;</span><span class="p">,</span> <span class="s1">&#39;other&#39;</span><span class="p">,</span> <span class="s1">&#39;over&#39;</span><span class="p">,</span> <span class="s1">&#39;said&#39;</span><span class="p">,</span> <span class="s1">&#39;same&#39;</span><span class="p">,</span> <span class="s1">&#39;see&#39;</span><span class="p">,</span> <span class="s1">&#39;some&#39;</span><span class="p">,</span> <span class="s1">&#39;such&#39;</span><span class="p">,</span>
<a id="__codelineno-1-107" name="__codelineno-1-107"></a> <span class="s1">&#39;take&#39;</span><span class="p">,</span> <span class="s1">&#39;than&#39;</span><span class="p">,</span> <span class="s1">&#39;then&#39;</span><span class="p">,</span> <span class="s1">&#39;time&#39;</span><span class="p">,</span> <span class="s1">&#39;two&#39;</span><span class="p">,</span> <span class="s1">&#39;use&#39;</span><span class="p">,</span> <span class="s1">&#39;very&#39;</span><span class="p">,</span> <span class="s1">&#39;way&#39;</span><span class="p">,</span> <span class="s1">&#39;well&#39;</span><span class="p">,</span> <span class="s1">&#39;where&#39;</span><span class="p">,</span> <span class="s1">&#39;when&#39;</span><span class="p">,</span> <span class="s1">&#39;which&#39;</span><span class="p">,</span>
<a id="__codelineno-1-108" name="__codelineno-1-108"></a> <span class="s1">&#39;while&#39;</span><span class="p">,</span> <span class="s1">&#39;who&#39;</span><span class="p">,</span> <span class="s1">&#39;why&#39;</span><span class="p">,</span> <span class="s1">&#39;work&#39;</span><span class="p">,</span> <span class="s1">&#39;world&#39;</span><span class="p">,</span> <span class="s1">&#39;year&#39;</span><span class="p">,</span> <span class="s1">&#39;years&#39;</span><span class="p">,</span>
<a id="__codelineno-1-109" name="__codelineno-1-109"></a> <span class="c1"># 中文停用词</span>
<a id="__codelineno-1-110" name="__codelineno-1-110"></a> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
<a id="__codelineno-1-111" name="__codelineno-1-111"></a> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;可以&#39;</span><span class="p">,</span> <span class="s1">&#39;没有&#39;</span><span class="p">,</span> <span class="s1">&#39;什么&#39;</span><span class="p">,</span> <span class="s1">&#39;一个&#39;</span><span class="p">,</span> <span class="s1">&#39;自己&#39;</span><span class="p">,</span> <span class="s1">&#39;这个&#39;</span><span class="p">,</span> <span class="s1">&#39;那个&#39;</span><span class="p">,</span> <span class="s1">&#39;这些&#39;</span><span class="p">,</span> <span class="s1">&#39;那些&#39;</span><span class="p">,</span> <span class="s1">&#39;如果&#39;</span><span class="p">,</span> <span class="s1">&#39;因为&#39;</span><span class="p">,</span> <span class="s1">&#39;所以&#39;</span>
<a id="__codelineno-1-112" name="__codelineno-1-112"></a> <span class="p">}</span>
<a id="__codelineno-1-113" name="__codelineno-1-113"></a>
<a id="__codelineno-1-114" name="__codelineno-1-114"></a> <span class="c1"># 过滤单词:长度&gt;=2不在停用词中不是纯数字</span>
<a id="__codelineno-1-115" name="__codelineno-1-115"></a> <span class="n">words</span> <span class="o">=</span> <span class="p">[</span><span class="n">w</span> <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">all_words</span>
<a id="__codelineno-1-116" name="__codelineno-1-116"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">w</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">stopwords</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">w</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()]</span>
<a id="__codelineno-1-117" name="__codelineno-1-117"></a>
<a id="__codelineno-1-118" name="__codelineno-1-118"></a> <span class="c1"># 返回词频最高的15个词</span>
<a id="__codelineno-1-119" name="__codelineno-1-119"></a> <span class="k">return</span> <span class="n">Counter</span><span class="p">(</span><span class="n">words</span><span class="p">)</span><span class="o">.</span><span class="n">most_common</span><span class="p">(</span><span class="mi">15</span><span class="p">)</span>
<a id="__codelineno-1-120" name="__codelineno-1-120"></a>
<a id="__codelineno-1-121" name="__codelineno-1-121"></a><span class="k">def</span><span class="w"> </span><span class="nf">extract_metadata</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
<a id="__codelineno-1-122" name="__codelineno-1-122"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;提取文章元数据支持YAML front matter&quot;&quot;&quot;</span>
<a id="__codelineno-1-123" name="__codelineno-1-123"></a> <span class="n">metadata</span> <span class="o">=</span> <span class="p">{</span>
<a id="__codelineno-1-124" name="__codelineno-1-124"></a> <span class="s1">&#39;title&#39;</span><span class="p">:</span> <span class="s2">&quot;未命名&quot;</span><span class="p">,</span>
<a id="__codelineno-1-125" name="__codelineno-1-125"></a> <span class="s1">&#39;description&#39;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<a id="__codelineno-1-126" name="__codelineno-1-126"></a> <span class="s1">&#39;tags&#39;</span><span class="p">:</span> <span class="p">[],</span>
<a id="__codelineno-1-127" name="__codelineno-1-127"></a> <span class="s1">&#39;categories&#39;</span><span class="p">:</span> <span class="p">[],</span>
<a id="__codelineno-1-128" name="__codelineno-1-128"></a> <span class="s1">&#39;disable_related&#39;</span><span class="p">:</span> <span class="kc">False</span> <span class="c1"># 新增:是否禁用相关推荐</span>
<a id="__codelineno-1-129" name="__codelineno-1-129"></a> <span class="p">}</span>
<a id="__codelineno-1-130" name="__codelineno-1-130"></a>
<a id="__codelineno-1-131" name="__codelineno-1-131"></a> <span class="c1"># 尝试解析YAML front matter</span>
<a id="__codelineno-1-132" name="__codelineno-1-132"></a> <span class="n">yaml_match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^---\s*\n(.*?)\n---\s*\n&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">DOTALL</span><span class="p">)</span>
<a id="__codelineno-1-133" name="__codelineno-1-133"></a> <span class="k">if</span> <span class="n">yaml_match</span><span class="p">:</span>
<a id="__codelineno-1-134" name="__codelineno-1-134"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-1-135" name="__codelineno-1-135"></a> <span class="n">yaml_content</span> <span class="o">=</span> <span class="n">yaml_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-1-136" name="__codelineno-1-136"></a> <span class="n">yaml_data</span> <span class="o">=</span> <span class="n">yaml</span><span class="o">.</span><span class="n">safe_load</span><span class="p">(</span><span class="n">yaml_content</span><span class="p">)</span>
<a id="__codelineno-1-137" name="__codelineno-1-137"></a> <span class="k">if</span> <span class="n">yaml_data</span><span class="p">:</span>
<a id="__codelineno-1-138" name="__codelineno-1-138"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">yaml_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;title&#39;</span><span class="p">,</span> <span class="s1">&#39;未命名&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s1">&#39;&quot;</span><span class="se">\&#39;</span><span class="s1">&#39;</span><span class="p">)</span>
<a id="__codelineno-1-139" name="__codelineno-1-139"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;description&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">yaml_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;description&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s1">&#39;&quot;</span><span class="se">\&#39;</span><span class="s1">&#39;</span><span class="p">)</span>
<a id="__codelineno-1-140" name="__codelineno-1-140"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;disable_related&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">yaml_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;disable_related&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<a id="__codelineno-1-141" name="__codelineno-1-141"></a>
<a id="__codelineno-1-142" name="__codelineno-1-142"></a> <span class="c1"># 处理tags</span>
<a id="__codelineno-1-143" name="__codelineno-1-143"></a> <span class="n">tags</span> <span class="o">=</span> <span class="n">yaml_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;tags&#39;</span><span class="p">,</span> <span class="p">[])</span>
<a id="__codelineno-1-144" name="__codelineno-1-144"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tags</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<a id="__codelineno-1-145" name="__codelineno-1-145"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">tag</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">tags</span><span class="p">]</span>
<a id="__codelineno-1-146" name="__codelineno-1-146"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tags</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<a id="__codelineno-1-147" name="__codelineno-1-147"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">tag</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">tags</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="n">tag</span><span class="o">.</span><span class="n">strip</span><span class="p">()]</span>
<a id="__codelineno-1-148" name="__codelineno-1-148"></a>
<a id="__codelineno-1-149" name="__codelineno-1-149"></a> <span class="c1"># 处理categories</span>
<a id="__codelineno-1-150" name="__codelineno-1-150"></a> <span class="n">categories</span> <span class="o">=</span> <span class="n">yaml_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;categories&#39;</span><span class="p">,</span> <span class="p">[])</span>
<a id="__codelineno-1-151" name="__codelineno-1-151"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">categories</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<a id="__codelineno-1-152" name="__codelineno-1-152"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">cat</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">cat</span> <span class="ow">in</span> <span class="n">categories</span><span class="p">]</span>
<a id="__codelineno-1-153" name="__codelineno-1-153"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">categories</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<a id="__codelineno-1-154" name="__codelineno-1-154"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">cat</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">cat</span> <span class="ow">in</span> <span class="n">categories</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="n">cat</span><span class="o">.</span><span class="n">strip</span><span class="p">()]</span>
<a id="__codelineno-1-155" name="__codelineno-1-155"></a> <span class="k">except</span> <span class="n">yaml</span><span class="o">.</span><span class="n">YAMLError</span><span class="p">:</span>
<a id="__codelineno-1-156" name="__codelineno-1-156"></a> <span class="k">pass</span> <span class="c1"># 如果YAML解析失败使用默认值</span>
<a id="__codelineno-1-157" name="__codelineno-1-157"></a>
<a id="__codelineno-1-158" name="__codelineno-1-158"></a> <span class="c1"># 如果YAML解析失败回退到正则表达式</span>
<a id="__codelineno-1-159" name="__codelineno-1-159"></a> <span class="k">if</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;未命名&quot;</span><span class="p">:</span>
<a id="__codelineno-1-160" name="__codelineno-1-160"></a> <span class="n">title_match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^title:\s*(.+)$&#39;</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">MULTILINE</span><span class="p">)</span>
<a id="__codelineno-1-161" name="__codelineno-1-161"></a> <span class="k">if</span> <span class="n">title_match</span><span class="p">:</span>
<a id="__codelineno-1-162" name="__codelineno-1-162"></a> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">title_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s1">&#39;&quot;</span><span class="se">\&#39;</span><span class="s1">&#39;</span><span class="p">)</span>
<a id="__codelineno-1-163" name="__codelineno-1-163"></a>
<a id="__codelineno-1-164" name="__codelineno-1-164"></a> <span class="k">return</span> <span class="n">metadata</span>
<a id="__codelineno-1-165" name="__codelineno-1-165"></a>
<a id="__codelineno-1-166" name="__codelineno-1-166"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_category_from_path</span><span class="p">(</span><span class="n">file_path</span><span class="p">):</span>
<a id="__codelineno-1-167" name="__codelineno-1-167"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;从文件路径提取分类&quot;&quot;&quot;</span>
<a id="__codelineno-1-168" name="__codelineno-1-168"></a> <span class="n">parts</span> <span class="o">=</span> <span class="n">file_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
<a id="__codelineno-1-169" name="__codelineno-1-169"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">:</span>
<a id="__codelineno-1-170" name="__codelineno-1-170"></a> <span class="k">return</span> <span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># blog/category/file.md 或 develop/category/file.md格式</span>
<a id="__codelineno-1-171" name="__codelineno-1-171"></a> <span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<a id="__codelineno-1-172" name="__codelineno-1-172"></a> <span class="k">return</span> <span class="n">parts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># blog 或 develop</span>
<a id="__codelineno-1-173" name="__codelineno-1-173"></a> <span class="k">return</span> <span class="s2">&quot;未分类&quot;</span>
<a id="__codelineno-1-174" name="__codelineno-1-174"></a>
<a id="__codelineno-1-175" name="__codelineno-1-175"></a><span class="k">def</span><span class="w"> </span><span class="nf">calculate_content_hash</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
<a id="__codelineno-1-176" name="__codelineno-1-176"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;计算内容哈希,用于检测内容变化&quot;&quot;&quot;</span>
<a id="__codelineno-1-177" name="__codelineno-1-177"></a> <span class="k">return</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="n">content</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<a id="__codelineno-1-178" name="__codelineno-1-178"></a>
<a id="__codelineno-1-179" name="__codelineno-1-179"></a><span class="k">def</span><span class="w"> </span><span class="nf">on_files</span><span class="p">(</span><span class="n">files</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span>
<a id="__codelineno-1-180" name="__codelineno-1-180"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;预处理所有文章,建立索引&quot;&quot;&quot;</span>
<a id="__codelineno-1-181" name="__codelineno-1-181"></a> <span class="k">global</span> <span class="n">article_index</span><span class="p">,</span> <span class="n">category_index</span><span class="p">,</span> <span class="n">keyword_index</span>
<a id="__codelineno-1-182" name="__codelineno-1-182"></a>
<a id="__codelineno-1-183" name="__codelineno-1-183"></a> <span class="c1"># 清空索引</span>
<a id="__codelineno-1-184" name="__codelineno-1-184"></a> <span class="n">article_index</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<a id="__codelineno-1-185" name="__codelineno-1-185"></a> <span class="n">category_index</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<a id="__codelineno-1-186" name="__codelineno-1-186"></a> <span class="n">keyword_index</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<a id="__codelineno-1-187" name="__codelineno-1-187"></a>
<a id="__codelineno-1-188" name="__codelineno-1-188"></a> <span class="n">processed_count</span> <span class="o">=</span> <span class="mi">0</span>
<a id="__codelineno-1-189" name="__codelineno-1-189"></a> <span class="n">excluded_count</span> <span class="o">=</span> <span class="mi">0</span>
<a id="__codelineno-1-190" name="__codelineno-1-190"></a>
<a id="__codelineno-1-191" name="__codelineno-1-191"></a> <span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
<a id="__codelineno-1-192" name="__codelineno-1-192"></a> <span class="k">if</span> <span class="n">should_index_file</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">):</span>
<a id="__codelineno-1-193" name="__codelineno-1-193"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-1-194" name="__codelineno-1-194"></a> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">abs_src_path</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<a id="__codelineno-1-195" name="__codelineno-1-195"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<a id="__codelineno-1-196" name="__codelineno-1-196"></a>
<a id="__codelineno-1-197" name="__codelineno-1-197"></a> <span class="c1"># 提取元数据</span>
<a id="__codelineno-1-198" name="__codelineno-1-198"></a> <span class="n">metadata</span> <span class="o">=</span> <span class="n">extract_metadata</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<a id="__codelineno-1-199" name="__codelineno-1-199"></a>
<a id="__codelineno-1-200" name="__codelineno-1-200"></a> <span class="c1"># 检查是否禁用相关推荐</span>
<a id="__codelineno-1-201" name="__codelineno-1-201"></a> <span class="k">if</span> <span class="n">metadata</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;disable_related&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
<a id="__codelineno-1-202" name="__codelineno-1-202"></a> <span class="n">excluded_count</span> <span class="o">+=</span> <span class="mi">1</span>
<a id="__codelineno-1-203" name="__codelineno-1-203"></a> <span class="k">continue</span>
<a id="__codelineno-1-204" name="__codelineno-1-204"></a>
<a id="__codelineno-1-205" name="__codelineno-1-205"></a> <span class="c1"># 再次检查是否在排除列表中(双重检查)</span>
<a id="__codelineno-1-206" name="__codelineno-1-206"></a> <span class="k">if</span> <span class="n">is_page_excluded</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">):</span>
<a id="__codelineno-1-207" name="__codelineno-1-207"></a> <span class="n">excluded_count</span> <span class="o">+=</span> <span class="mi">1</span>
<a id="__codelineno-1-208" name="__codelineno-1-208"></a> <span class="k">continue</span>
<a id="__codelineno-1-209" name="__codelineno-1-209"></a>
<a id="__codelineno-1-210" name="__codelineno-1-210"></a> <span class="c1"># 提取关键词</span>
<a id="__codelineno-1-211" name="__codelineno-1-211"></a> <span class="n">keywords</span> <span class="o">=</span> <span class="n">extract_keywords</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">])</span>
<a id="__codelineno-1-212" name="__codelineno-1-212"></a>
<a id="__codelineno-1-213" name="__codelineno-1-213"></a> <span class="c1"># 获取分类</span>
<a id="__codelineno-1-214" name="__codelineno-1-214"></a> <span class="n">path_category</span> <span class="o">=</span> <span class="n">get_category_from_path</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">)</span>
<a id="__codelineno-1-215" name="__codelineno-1-215"></a>
<a id="__codelineno-1-216" name="__codelineno-1-216"></a> <span class="c1"># 构建文章信息</span>
<a id="__codelineno-1-217" name="__codelineno-1-217"></a> <span class="n">article_info</span> <span class="o">=</span> <span class="p">{</span>
<a id="__codelineno-1-218" name="__codelineno-1-218"></a> <span class="s1">&#39;title&#39;</span><span class="p">:</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">],</span>
<a id="__codelineno-1-219" name="__codelineno-1-219"></a> <span class="s1">&#39;description&#39;</span><span class="p">:</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;description&#39;</span><span class="p">],</span>
<a id="__codelineno-1-220" name="__codelineno-1-220"></a> <span class="s1">&#39;tags&#39;</span><span class="p">:</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">],</span>
<a id="__codelineno-1-221" name="__codelineno-1-221"></a> <span class="s1">&#39;categories&#39;</span><span class="p">:</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">],</span>
<a id="__codelineno-1-222" name="__codelineno-1-222"></a> <span class="s1">&#39;path_category&#39;</span><span class="p">:</span> <span class="n">path_category</span><span class="p">,</span>
<a id="__codelineno-1-223" name="__codelineno-1-223"></a> <span class="s1">&#39;keywords&#39;</span><span class="p">:</span> <span class="n">keywords</span><span class="p">,</span>
<a id="__codelineno-1-224" name="__codelineno-1-224"></a> <span class="s1">&#39;url&#39;</span><span class="p">:</span> <span class="n">file</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
<a id="__codelineno-1-225" name="__codelineno-1-225"></a> <span class="s1">&#39;path&#39;</span><span class="p">:</span> <span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">,</span>
<a id="__codelineno-1-226" name="__codelineno-1-226"></a> <span class="s1">&#39;content_hash&#39;</span><span class="p">:</span> <span class="n">calculate_content_hash</span><span class="p">(</span><span class="n">content</span><span class="p">),</span>
<a id="__codelineno-1-227" name="__codelineno-1-227"></a> <span class="s1">&#39;source_dir&#39;</span><span class="p">:</span> <span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># blog 或 develop</span>
<a id="__codelineno-1-228" name="__codelineno-1-228"></a> <span class="p">}</span>
<a id="__codelineno-1-229" name="__codelineno-1-229"></a>
<a id="__codelineno-1-230" name="__codelineno-1-230"></a> <span class="c1"># 添加到主索引</span>
<a id="__codelineno-1-231" name="__codelineno-1-231"></a> <span class="n">article_index</span><span class="p">[</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">]</span> <span class="o">=</span> <span class="n">article_info</span>
<a id="__codelineno-1-232" name="__codelineno-1-232"></a>
<a id="__codelineno-1-233" name="__codelineno-1-233"></a> <span class="c1"># 添加到分类索引</span>
<a id="__codelineno-1-234" name="__codelineno-1-234"></a> <span class="n">category_index</span><span class="p">[</span><span class="n">path_category</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">)</span>
<a id="__codelineno-1-235" name="__codelineno-1-235"></a> <span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]:</span>
<a id="__codelineno-1-236" name="__codelineno-1-236"></a> <span class="k">if</span> <span class="n">category</span><span class="p">:</span> <span class="c1"># 确保分类不为空</span>
<a id="__codelineno-1-237" name="__codelineno-1-237"></a> <span class="n">category_index</span><span class="p">[</span><span class="n">category</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">)</span>
<a id="__codelineno-1-238" name="__codelineno-1-238"></a>
<a id="__codelineno-1-239" name="__codelineno-1-239"></a> <span class="c1"># 添加到关键词索引</span>
<a id="__codelineno-1-240" name="__codelineno-1-240"></a> <span class="k">for</span> <span class="n">keyword</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">keywords</span><span class="p">:</span>
<a id="__codelineno-1-241" name="__codelineno-1-241"></a> <span class="n">keyword_index</span><span class="p">[</span><span class="n">keyword</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">)</span>
<a id="__codelineno-1-242" name="__codelineno-1-242"></a> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]:</span>
<a id="__codelineno-1-243" name="__codelineno-1-243"></a> <span class="k">if</span> <span class="n">tag</span><span class="p">:</span> <span class="c1"># 确保标签不为空</span>
<a id="__codelineno-1-244" name="__codelineno-1-244"></a> <span class="n">keyword_index</span><span class="p">[</span><span class="n">tag</span><span class="o">.</span><span class="n">lower</span><span class="p">()]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">)</span>
<a id="__codelineno-1-245" name="__codelineno-1-245"></a>
<a id="__codelineno-1-246" name="__codelineno-1-246"></a> <span class="n">processed_count</span> <span class="o">+=</span> <span class="mi">1</span>
<a id="__codelineno-1-247" name="__codelineno-1-247"></a>
<a id="__codelineno-1-248" name="__codelineno-1-248"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<a id="__codelineno-1-249" name="__codelineno-1-249"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;❌ 处理文件 </span><span class="si">{</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="si">}</span><span class="s2"> 时出错: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<a id="__codelineno-1-250" name="__codelineno-1-250"></a>
<a id="__codelineno-1-251" name="__codelineno-1-251"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;✅ 已索引 </span><span class="si">{</span><span class="n">processed_count</span><span class="si">}</span><span class="s2"> 篇文章 (blog + develop)&quot;</span><span class="p">)</span>
<a id="__codelineno-1-252" name="__codelineno-1-252"></a> <span class="k">if</span> <span class="n">excluded_count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a id="__codelineno-1-253" name="__codelineno-1-253"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;📝 排除 </span><span class="si">{</span><span class="n">excluded_count</span><span class="si">}</span><span class="s2"> 篇禁用推荐或在排除列表中的文章&quot;</span><span class="p">)</span>
<a id="__codelineno-1-254" name="__codelineno-1-254"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;📊 分类数量: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">category_index</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<a id="__codelineno-1-255" name="__codelineno-1-255"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;🔤 关键词数量: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">keyword_index</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<a id="__codelineno-1-256" name="__codelineno-1-256"></a> <span class="k">return</span> <span class="n">files</span>
<a id="__codelineno-1-257" name="__codelineno-1-257"></a>
<a id="__codelineno-1-258" name="__codelineno-1-258"></a><span class="k">def</span><span class="w"> </span><span class="nf">on_page_markdown</span><span class="p">(</span><span class="n">markdown</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<a id="__codelineno-1-259" name="__codelineno-1-259"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;为每篇文章添加相关推荐&quot;&quot;&quot;</span>
<a id="__codelineno-1-260" name="__codelineno-1-260"></a> <span class="n">page</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;page&#39;</span><span class="p">]</span>
<a id="__codelineno-1-261" name="__codelineno-1-261"></a> <span class="n">config</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;config&#39;</span><span class="p">]</span>
<a id="__codelineno-1-262" name="__codelineno-1-262"></a>
<a id="__codelineno-1-263" name="__codelineno-1-263"></a> <span class="c1"># 检查是否应该处理这个页面</span>
<a id="__codelineno-1-264" name="__codelineno-1-264"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">should_index_file</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">):</span>
<a id="__codelineno-1-265" name="__codelineno-1-265"></a> <span class="k">return</span> <span class="n">markdown</span>
<a id="__codelineno-1-266" name="__codelineno-1-266"></a>
<a id="__codelineno-1-267" name="__codelineno-1-267"></a> <span class="c1"># 检查是否被排除</span>
<a id="__codelineno-1-268" name="__codelineno-1-268"></a> <span class="k">if</span> <span class="n">is_page_excluded</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">):</span>
<a id="__codelineno-1-269" name="__codelineno-1-269"></a> <span class="k">return</span> <span class="n">markdown</span>
<a id="__codelineno-1-270" name="__codelineno-1-270"></a>
<a id="__codelineno-1-271" name="__codelineno-1-271"></a> <span class="c1"># 检查文章元数据是否禁用推荐</span>
<a id="__codelineno-1-272" name="__codelineno-1-272"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-1-273" name="__codelineno-1-273"></a> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">abs_src_path</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<a id="__codelineno-1-274" name="__codelineno-1-274"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<a id="__codelineno-1-275" name="__codelineno-1-275"></a> <span class="n">metadata</span> <span class="o">=</span> <span class="n">extract_metadata</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<a id="__codelineno-1-276" name="__codelineno-1-276"></a> <span class="k">if</span> <span class="n">metadata</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;disable_related&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
<a id="__codelineno-1-277" name="__codelineno-1-277"></a> <span class="k">return</span> <span class="n">markdown</span>
<a id="__codelineno-1-278" name="__codelineno-1-278"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<a id="__codelineno-1-279" name="__codelineno-1-279"></a> <span class="k">pass</span> <span class="c1"># 如果读取失败,继续处理</span>
<a id="__codelineno-1-280" name="__codelineno-1-280"></a>
<a id="__codelineno-1-281" name="__codelineno-1-281"></a> <span class="c1"># 获取相关文章</span>
<a id="__codelineno-1-282" name="__codelineno-1-282"></a> <span class="n">related_articles</span> <span class="o">=</span> <span class="n">get_related_articles</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">src_path</span><span class="p">,</span> <span class="n">max_count</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<a id="__codelineno-1-283" name="__codelineno-1-283"></a>
<a id="__codelineno-1-284" name="__codelineno-1-284"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">related_articles</span><span class="p">:</span>
<a id="__codelineno-1-285" name="__codelineno-1-285"></a> <span class="k">return</span> <span class="n">markdown</span>
<a id="__codelineno-1-286" name="__codelineno-1-286"></a>
<a id="__codelineno-1-287" name="__codelineno-1-287"></a> <span class="c1"># 从 config 中获取 site_url 并解析出基本路径</span>
<a id="__codelineno-1-288" name="__codelineno-1-288"></a> <span class="n">site_url</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;site_url&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<a id="__codelineno-1-289" name="__codelineno-1-289"></a> <span class="n">base_path</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">site_url</span><span class="p">)</span><span class="o">.</span><span class="n">path</span> <span class="k">if</span> <span class="n">site_url</span> <span class="k">else</span> <span class="s1">&#39;/&#39;</span>
<a id="__codelineno-1-290" name="__codelineno-1-290"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">base_path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">):</span>
<a id="__codelineno-1-291" name="__codelineno-1-291"></a> <span class="n">base_path</span> <span class="o">+=</span> <span class="s1">&#39;/&#39;</span>
<a id="__codelineno-1-292" name="__codelineno-1-292"></a>
<a id="__codelineno-1-293" name="__codelineno-1-293"></a> <span class="c1"># 构建推荐HTML - 针对Safari浏览器优化</span>
<a id="__codelineno-1-294" name="__codelineno-1-294"></a> <span class="n">recommendation_html</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
<a id="__codelineno-1-295" name="__codelineno-1-295"></a>
<a id="__codelineno-1-296" name="__codelineno-1-296"></a> <span class="c1"># 添加CSS样式特别针对Safari浏览器优化</span>
<a id="__codelineno-1-297" name="__codelineno-1-297"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="s2">&quot;&quot;&quot;&lt;style&gt;</span>
<a id="__codelineno-1-298" name="__codelineno-1-298"></a><span class="s2">.related-posts {</span>
<a id="__codelineno-1-299" name="__codelineno-1-299"></a><span class="s2"> margin-top: 1.5rem;</span>
<a id="__codelineno-1-300" name="__codelineno-1-300"></a><span class="s2"> padding-top: 0.75rem;</span>
<a id="__codelineno-1-301" name="__codelineno-1-301"></a><span class="s2"> border-top: 1px solid rgba(0,0,0,0.1);</span>
<a id="__codelineno-1-302" name="__codelineno-1-302"></a><span class="s2"> max-height: none !important; /* 防止Safari错误计算高度 */</span>
<a id="__codelineno-1-303" name="__codelineno-1-303"></a><span class="s2"> overflow: visible !important; /* 防止内容被截断 */</span>
<a id="__codelineno-1-304" name="__codelineno-1-304"></a><span class="s2">}</span>
<a id="__codelineno-1-305" name="__codelineno-1-305"></a><span class="s2">.related-posts h3 {</span>
<a id="__codelineno-1-306" name="__codelineno-1-306"></a><span class="s2"> margin-top: 0;</span>
<a id="__codelineno-1-307" name="__codelineno-1-307"></a><span class="s2"> margin-bottom: 0.5rem;</span>
<a id="__codelineno-1-308" name="__codelineno-1-308"></a><span class="s2"> font-size: 1.2rem;</span>
<a id="__codelineno-1-309" name="__codelineno-1-309"></a><span class="s2"> font-weight: 500;</span>
<a id="__codelineno-1-310" name="__codelineno-1-310"></a><span class="s2"> line-height: 1.3;</span>
<a id="__codelineno-1-311" name="__codelineno-1-311"></a><span class="s2">}</span>
<a id="__codelineno-1-312" name="__codelineno-1-312"></a><span class="s2">.related-posts ul {</span>
<a id="__codelineno-1-313" name="__codelineno-1-313"></a><span class="s2"> margin: 0 0 0.5rem 0 !important; /* 强制覆盖可能的冲突样式 */</span>
<a id="__codelineno-1-314" name="__codelineno-1-314"></a><span class="s2"> padding-left: 1.5rem;</span>
<a id="__codelineno-1-315" name="__codelineno-1-315"></a><span class="s2"> list-style-position: outside;</span>
<a id="__codelineno-1-316" name="__codelineno-1-316"></a><span class="s2">}</span>
<a id="__codelineno-1-317" name="__codelineno-1-317"></a><span class="s2">.related-posts li {</span>
<a id="__codelineno-1-318" name="__codelineno-1-318"></a><span class="s2"> margin-bottom: 0.25rem;</span>
<a id="__codelineno-1-319" name="__codelineno-1-319"></a><span class="s2"> line-height: 1.4;</span>
<a id="__codelineno-1-320" name="__codelineno-1-320"></a><span class="s2">}</span>
<a id="__codelineno-1-321" name="__codelineno-1-321"></a><span class="s2">/* 暗色模式适配 */</span>
<a id="__codelineno-1-322" name="__codelineno-1-322"></a><span class="s2">[data-md-color-scheme=&quot;slate&quot;] .related-posts {</span>
<a id="__codelineno-1-323" name="__codelineno-1-323"></a><span class="s2"> border-top-color: rgba(255,255,255,0.1);</span>
<a id="__codelineno-1-324" name="__codelineno-1-324"></a><span class="s2">}</span>
<a id="__codelineno-1-325" name="__codelineno-1-325"></a><span class="s2">/* Safari特定修复 */</span>
<a id="__codelineno-1-326" name="__codelineno-1-326"></a><span class="s2">@supports (-webkit-hyphens:none) {</span>
<a id="__codelineno-1-327" name="__codelineno-1-327"></a><span class="s2"> .related-posts {</span>
<a id="__codelineno-1-328" name="__codelineno-1-328"></a><span class="s2"> display: block;</span>
<a id="__codelineno-1-329" name="__codelineno-1-329"></a><span class="s2"> position: relative;</span>
<a id="__codelineno-1-330" name="__codelineno-1-330"></a><span class="s2"> height: auto !important;</span>
<a id="__codelineno-1-331" name="__codelineno-1-331"></a><span class="s2"> }</span>
<a id="__codelineno-1-332" name="__codelineno-1-332"></a><span class="s2"> .related-posts ul {</span>
<a id="__codelineno-1-333" name="__codelineno-1-333"></a><span class="s2"> position: static;</span>
<a id="__codelineno-1-334" name="__codelineno-1-334"></a><span class="s2"> }</span>
<a id="__codelineno-1-335" name="__codelineno-1-335"></a><span class="s2">}</span>
<a id="__codelineno-1-336" name="__codelineno-1-336"></a><span class="s2">&lt;/style&gt;</span>
<a id="__codelineno-1-337" name="__codelineno-1-337"></a><span class="s2">&quot;&quot;&quot;</span>
<a id="__codelineno-1-338" name="__codelineno-1-338"></a>
<a id="__codelineno-1-339" name="__codelineno-1-339"></a> <span class="c1"># 简化且兼容的HTML结构</span>
<a id="__codelineno-1-340" name="__codelineno-1-340"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="s1">&#39;&lt;div class=&quot;related-posts&quot;&gt;</span><span class="se">\n</span><span class="s1">&#39;</span>
<a id="__codelineno-1-341" name="__codelineno-1-341"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="s1">&#39;&lt;h3&gt;📚 相关文章推荐&lt;/h3&gt;</span><span class="se">\n</span><span class="s1">&#39;</span>
<a id="__codelineno-1-342" name="__codelineno-1-342"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="s1">&#39;&lt;ul&gt;</span><span class="se">\n</span><span class="s1">&#39;</span>
<a id="__codelineno-1-343" name="__codelineno-1-343"></a>
<a id="__codelineno-1-344" name="__codelineno-1-344"></a> <span class="k">for</span> <span class="n">score</span><span class="p">,</span> <span class="n">article_info</span> <span class="ow">in</span> <span class="n">related_articles</span><span class="p">:</span>
<a id="__codelineno-1-345" name="__codelineno-1-345"></a> <span class="n">title</span> <span class="o">=</span> <span class="n">article_info</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span>
<a id="__codelineno-1-346" name="__codelineno-1-346"></a> <span class="n">relative_url</span> <span class="o">=</span> <span class="n">article_info</span><span class="p">[</span><span class="s1">&#39;url&#39;</span><span class="p">]</span>
<a id="__codelineno-1-347" name="__codelineno-1-347"></a> <span class="c1"># 拼接基本路径和文章相对URL并确保路径分隔符正确</span>
<a id="__codelineno-1-348" name="__codelineno-1-348"></a> <span class="n">full_url</span> <span class="o">=</span> <span class="p">(</span><span class="n">base_path</span> <span class="o">+</span> <span class="n">relative_url</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;//&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">)</span>
<a id="__codelineno-1-349" name="__codelineno-1-349"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="sa">f</span><span class="s1">&#39;&lt;li&gt;&lt;a href=&quot;</span><span class="si">{</span><span class="n">full_url</span><span class="si">}</span><span class="s1">&quot;&gt;</span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s1">&lt;/a&gt;&lt;/li&gt;</span><span class="se">\n</span><span class="s1">&#39;</span>
<a id="__codelineno-1-350" name="__codelineno-1-350"></a>
<a id="__codelineno-1-351" name="__codelineno-1-351"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="s1">&#39;&lt;/ul&gt;</span><span class="se">\n</span><span class="s1">&#39;</span>
<a id="__codelineno-1-352" name="__codelineno-1-352"></a> <span class="n">recommendation_html</span> <span class="o">+=</span> <span class="s1">&#39;&lt;/div&gt;</span><span class="se">\n</span><span class="s1">&#39;</span>
<a id="__codelineno-1-353" name="__codelineno-1-353"></a>
<a id="__codelineno-1-354" name="__codelineno-1-354"></a> <span class="c1"># 确保没有多余的空行</span>
<a id="__codelineno-1-355" name="__codelineno-1-355"></a> <span class="k">return</span> <span class="n">markdown</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span> <span class="o">+</span> <span class="n">recommendation_html</span>
<a id="__codelineno-1-356" name="__codelineno-1-356"></a>
<a id="__codelineno-1-357" name="__codelineno-1-357"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_related_articles</span><span class="p">(</span><span class="n">current_path</span><span class="p">,</span> <span class="n">max_count</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
<a id="__codelineno-1-358" name="__codelineno-1-358"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取相关文章,使用改进的算法&quot;&quot;&quot;</span>
<a id="__codelineno-1-359" name="__codelineno-1-359"></a> <span class="k">if</span> <span class="n">current_path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">article_index</span><span class="p">:</span>
<a id="__codelineno-1-360" name="__codelineno-1-360"></a> <span class="k">return</span> <span class="p">[]</span>
<a id="__codelineno-1-361" name="__codelineno-1-361"></a>
<a id="__codelineno-1-362" name="__codelineno-1-362"></a> <span class="n">current_article</span> <span class="o">=</span> <span class="n">article_index</span><span class="p">[</span><span class="n">current_path</span><span class="p">]</span>
<a id="__codelineno-1-363" name="__codelineno-1-363"></a> <span class="n">similarities</span> <span class="o">=</span> <span class="p">[]</span>
<a id="__codelineno-1-364" name="__codelineno-1-364"></a>
<a id="__codelineno-1-365" name="__codelineno-1-365"></a> <span class="c1"># 获取当前文章的关键信息</span>
<a id="__codelineno-1-366" name="__codelineno-1-366"></a> <span class="n">current_title</span> <span class="o">=</span> <span class="n">current_article</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<a id="__codelineno-1-367" name="__codelineno-1-367"></a> <span class="n">current_tags</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">tag</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">current_article</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">tag</span><span class="p">)</span>
<a id="__codelineno-1-368" name="__codelineno-1-368"></a> <span class="n">current_categories</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">cat</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">cat</span> <span class="ow">in</span> <span class="n">current_article</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">cat</span><span class="p">)</span>
<a id="__codelineno-1-369" name="__codelineno-1-369"></a>
<a id="__codelineno-1-370" name="__codelineno-1-370"></a> <span class="k">for</span> <span class="n">path</span><span class="p">,</span> <span class="n">article_info</span> <span class="ow">in</span> <span class="n">article_index</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<a id="__codelineno-1-371" name="__codelineno-1-371"></a> <span class="k">if</span> <span class="n">path</span> <span class="o">==</span> <span class="n">current_path</span><span class="p">:</span>
<a id="__codelineno-1-372" name="__codelineno-1-372"></a> <span class="k">continue</span>
<a id="__codelineno-1-373" name="__codelineno-1-373"></a>
<a id="__codelineno-1-374" name="__codelineno-1-374"></a> <span class="c1"># 过滤掉标题为&quot;未命名&quot;的文章</span>
<a id="__codelineno-1-375" name="__codelineno-1-375"></a> <span class="k">if</span> <span class="n">article_info</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;未命名&quot;</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">article_info</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span>
<a id="__codelineno-1-376" name="__codelineno-1-376"></a> <span class="k">continue</span>
<a id="__codelineno-1-377" name="__codelineno-1-377"></a>
<a id="__codelineno-1-378" name="__codelineno-1-378"></a> <span class="c1"># 再次检查是否在排除列表中(双重检查)</span>
<a id="__codelineno-1-379" name="__codelineno-1-379"></a> <span class="k">if</span> <span class="n">is_page_excluded</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<a id="__codelineno-1-380" name="__codelineno-1-380"></a> <span class="k">continue</span>
<a id="__codelineno-1-381" name="__codelineno-1-381"></a>
<a id="__codelineno-1-382" name="__codelineno-1-382"></a> <span class="c1"># 计算相似度</span>
<a id="__codelineno-1-383" name="__codelineno-1-383"></a> <span class="n">score</span> <span class="o">=</span> <span class="n">calculate_similarity</span><span class="p">(</span><span class="n">current_article</span><span class="p">,</span> <span class="n">article_info</span><span class="p">)</span>
<a id="__codelineno-1-384" name="__codelineno-1-384"></a>
<a id="__codelineno-1-385" name="__codelineno-1-385"></a> <span class="c1"># 标题相似度加权</span>
<a id="__codelineno-1-386" name="__codelineno-1-386"></a> <span class="n">title_similarity</span> <span class="o">=</span> <span class="n">calculate_title_similarity</span><span class="p">(</span><span class="n">current_title</span><span class="p">,</span> <span class="n">article_info</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<a id="__codelineno-1-387" name="__codelineno-1-387"></a> <span class="k">if</span> <span class="n">title_similarity</span> <span class="o">&gt;</span> <span class="mf">0.3</span><span class="p">:</span> <span class="c1"># 标题有一定相似度</span>
<a id="__codelineno-1-388" name="__codelineno-1-388"></a> <span class="n">score</span> <span class="o">+=</span> <span class="n">title_similarity</span> <span class="o">*</span> <span class="n">SIMILARITY_CONFIG</span><span class="p">[</span><span class="s1">&#39;title_similarity&#39;</span><span class="p">]</span>
<a id="__codelineno-1-389" name="__codelineno-1-389"></a>
<a id="__codelineno-1-390" name="__codelineno-1-390"></a> <span class="c1"># 应用最低阈值</span>
<a id="__codelineno-1-391" name="__codelineno-1-391"></a> <span class="k">if</span> <span class="n">score</span> <span class="o">&gt;</span> <span class="n">SIMILARITY_CONFIG</span><span class="p">[</span><span class="s1">&#39;min_threshold&#39;</span><span class="p">]:</span>
<a id="__codelineno-1-392" name="__codelineno-1-392"></a> <span class="n">similarities</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">score</span><span class="p">,</span> <span class="n">article_info</span><span class="p">))</span>
<a id="__codelineno-1-393" name="__codelineno-1-393"></a>
<a id="__codelineno-1-394" name="__codelineno-1-394"></a> <span class="c1"># 按相似度排序</span>
<a id="__codelineno-1-395" name="__codelineno-1-395"></a> <span class="n">similarities</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-1-396" name="__codelineno-1-396"></a>
<a id="__codelineno-1-397" name="__codelineno-1-397"></a> <span class="c1"># 多样性优化:确保不同分类的文章都有机会被推荐</span>
<a id="__codelineno-1-398" name="__codelineno-1-398"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">similarities</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">max_count</span> <span class="o">*</span> <span class="mi">2</span><span class="p">:</span>
<a id="__codelineno-1-399" name="__codelineno-1-399"></a> <span class="c1"># 按分类分组</span>
<a id="__codelineno-1-400" name="__codelineno-1-400"></a> <span class="n">category_groups</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<a id="__codelineno-1-401" name="__codelineno-1-401"></a> <span class="k">for</span> <span class="n">score</span><span class="p">,</span> <span class="n">article</span> <span class="ow">in</span> <span class="n">similarities</span><span class="p">:</span>
<a id="__codelineno-1-402" name="__codelineno-1-402"></a> <span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">article</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]:</span>
<a id="__codelineno-1-403" name="__codelineno-1-403"></a> <span class="k">if</span> <span class="n">category</span><span class="p">:</span>
<a id="__codelineno-1-404" name="__codelineno-1-404"></a> <span class="n">category_groups</span><span class="p">[</span><span class="n">category</span><span class="o">.</span><span class="n">lower</span><span class="p">()]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">score</span><span class="p">,</span> <span class="n">article</span><span class="p">))</span>
<a id="__codelineno-1-405" name="__codelineno-1-405"></a>
<a id="__codelineno-1-406" name="__codelineno-1-406"></a> <span class="c1"># 从每个分类中选取最相关的文章</span>
<a id="__codelineno-1-407" name="__codelineno-1-407"></a> <span class="n">diverse_results</span> <span class="o">=</span> <span class="p">[]</span>
<a id="__codelineno-1-408" name="__codelineno-1-408"></a> <span class="n">used_paths</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<a id="__codelineno-1-409" name="__codelineno-1-409"></a>
<a id="__codelineno-1-410" name="__codelineno-1-410"></a> <span class="c1"># 首先添加最相关的文章</span>
<a id="__codelineno-1-411" name="__codelineno-1-411"></a> <span class="k">if</span> <span class="n">similarities</span><span class="p">:</span>
<a id="__codelineno-1-412" name="__codelineno-1-412"></a> <span class="n">top_score</span><span class="p">,</span> <span class="n">top_article</span> <span class="o">=</span> <span class="n">similarities</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<a id="__codelineno-1-413" name="__codelineno-1-413"></a> <span class="n">diverse_results</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">top_score</span><span class="p">,</span> <span class="n">top_article</span><span class="p">))</span>
<a id="__codelineno-1-414" name="__codelineno-1-414"></a> <span class="n">used_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">top_article</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">])</span>
<a id="__codelineno-1-415" name="__codelineno-1-415"></a>
<a id="__codelineno-1-416" name="__codelineno-1-416"></a> <span class="c1"># 然后从每个分类中添加最相关的文章</span>
<a id="__codelineno-1-417" name="__codelineno-1-417"></a> <span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">category_groups</span><span class="o">.</span><span class="n">keys</span><span class="p">()):</span>
<a id="__codelineno-1-418" name="__codelineno-1-418"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">diverse_results</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">max_count</span><span class="p">:</span>
<a id="__codelineno-1-419" name="__codelineno-1-419"></a> <span class="k">break</span>
<a id="__codelineno-1-420" name="__codelineno-1-420"></a>
<a id="__codelineno-1-421" name="__codelineno-1-421"></a> <span class="k">for</span> <span class="n">score</span><span class="p">,</span> <span class="n">article</span> <span class="ow">in</span> <span class="n">category_groups</span><span class="p">[</span><span class="n">category</span><span class="p">]:</span>
<a id="__codelineno-1-422" name="__codelineno-1-422"></a> <span class="k">if</span> <span class="n">article</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">used_paths</span><span class="p">:</span>
<a id="__codelineno-1-423" name="__codelineno-1-423"></a> <span class="n">diverse_results</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">score</span><span class="p">,</span> <span class="n">article</span><span class="p">))</span>
<a id="__codelineno-1-424" name="__codelineno-1-424"></a> <span class="n">used_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">article</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">])</span>
<a id="__codelineno-1-425" name="__codelineno-1-425"></a> <span class="k">break</span>
<a id="__codelineno-1-426" name="__codelineno-1-426"></a>
<a id="__codelineno-1-427" name="__codelineno-1-427"></a> <span class="c1"># 如果还有空位,从剩余的高分文章中填充</span>
<a id="__codelineno-1-428" name="__codelineno-1-428"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">diverse_results</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">max_count</span><span class="p">:</span>
<a id="__codelineno-1-429" name="__codelineno-1-429"></a> <span class="k">for</span> <span class="n">score</span><span class="p">,</span> <span class="n">article</span> <span class="ow">in</span> <span class="n">similarities</span><span class="p">:</span>
<a id="__codelineno-1-430" name="__codelineno-1-430"></a> <span class="k">if</span> <span class="n">article</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">used_paths</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">diverse_results</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">max_count</span><span class="p">:</span>
<a id="__codelineno-1-431" name="__codelineno-1-431"></a> <span class="n">diverse_results</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">score</span><span class="p">,</span> <span class="n">article</span><span class="p">))</span>
<a id="__codelineno-1-432" name="__codelineno-1-432"></a> <span class="n">used_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">article</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">])</span>
<a id="__codelineno-1-433" name="__codelineno-1-433"></a>
<a id="__codelineno-1-434" name="__codelineno-1-434"></a> <span class="c1"># 重新按相似度排序</span>
<a id="__codelineno-1-435" name="__codelineno-1-435"></a> <span class="n">diverse_results</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-1-436" name="__codelineno-1-436"></a> <span class="k">return</span> <span class="n">diverse_results</span><span class="p">[:</span><span class="n">max_count</span><span class="p">]</span>
<a id="__codelineno-1-437" name="__codelineno-1-437"></a>
<a id="__codelineno-1-438" name="__codelineno-1-438"></a> <span class="k">return</span> <span class="n">similarities</span><span class="p">[:</span><span class="n">max_count</span><span class="p">]</span>
<a id="__codelineno-1-439" name="__codelineno-1-439"></a>
<a id="__codelineno-1-440" name="__codelineno-1-440"></a><span class="k">def</span><span class="w"> </span><span class="nf">calculate_title_similarity</span><span class="p">(</span><span class="n">title1</span><span class="p">,</span> <span class="n">title2</span><span class="p">):</span>
<a id="__codelineno-1-441" name="__codelineno-1-441"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;计算两个标题的相似度&quot;&quot;&quot;</span>
<a id="__codelineno-1-442" name="__codelineno-1-442"></a> <span class="c1"># 分词</span>
<a id="__codelineno-1-443" name="__codelineno-1-443"></a> <span class="n">words1</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\b\w+\b&#39;</span><span class="p">,</span> <span class="n">title1</span><span class="p">))</span>
<a id="__codelineno-1-444" name="__codelineno-1-444"></a> <span class="n">words2</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\b\w+\b&#39;</span><span class="p">,</span> <span class="n">title2</span><span class="p">))</span>
<a id="__codelineno-1-445" name="__codelineno-1-445"></a>
<a id="__codelineno-1-446" name="__codelineno-1-446"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">words1</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">words2</span><span class="p">:</span>
<a id="__codelineno-1-447" name="__codelineno-1-447"></a> <span class="k">return</span> <span class="mi">0</span>
<a id="__codelineno-1-448" name="__codelineno-1-448"></a>
<a id="__codelineno-1-449" name="__codelineno-1-449"></a> <span class="c1"># 计算Jaccard相似度</span>
<a id="__codelineno-1-450" name="__codelineno-1-450"></a> <span class="n">intersection</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">words1</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">words2</span><span class="p">))</span>
<a id="__codelineno-1-451" name="__codelineno-1-451"></a> <span class="n">union</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">words1</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">words2</span><span class="p">))</span>
<a id="__codelineno-1-452" name="__codelineno-1-452"></a>
<a id="__codelineno-1-453" name="__codelineno-1-453"></a> <span class="k">if</span> <span class="n">union</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a id="__codelineno-1-454" name="__codelineno-1-454"></a> <span class="k">return</span> <span class="mi">0</span>
<a id="__codelineno-1-455" name="__codelineno-1-455"></a>
<a id="__codelineno-1-456" name="__codelineno-1-456"></a> <span class="k">return</span> <span class="n">intersection</span> <span class="o">/</span> <span class="n">union</span>
<a id="__codelineno-1-457" name="__codelineno-1-457"></a>
<a id="__codelineno-1-458" name="__codelineno-1-458"></a><span class="k">def</span><span class="w"> </span><span class="nf">calculate_similarity</span><span class="p">(</span><span class="n">article1</span><span class="p">,</span> <span class="n">article2</span><span class="p">):</span>
<a id="__codelineno-1-459" name="__codelineno-1-459"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;计算两篇文章的相似度&quot;&quot;&quot;</span>
<a id="__codelineno-1-460" name="__codelineno-1-460"></a> <span class="n">score</span> <span class="o">=</span> <span class="mi">0</span>
<a id="__codelineno-1-461" name="__codelineno-1-461"></a> <span class="n">weights</span> <span class="o">=</span> <span class="n">SIMILARITY_CONFIG</span><span class="p">[</span><span class="s1">&#39;weights&#39;</span><span class="p">]</span>
<a id="__codelineno-1-462" name="__codelineno-1-462"></a>
<a id="__codelineno-1-463" name="__codelineno-1-463"></a> <span class="c1"># 1. 关键词相似度</span>
<a id="__codelineno-1-464" name="__codelineno-1-464"></a> <span class="n">keywords1</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">article1</span><span class="p">[</span><span class="s1">&#39;keywords&#39;</span><span class="p">])</span>
<a id="__codelineno-1-465" name="__codelineno-1-465"></a> <span class="n">keywords2</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">article2</span><span class="p">[</span><span class="s1">&#39;keywords&#39;</span><span class="p">])</span>
<a id="__codelineno-1-466" name="__codelineno-1-466"></a> <span class="n">common_keywords</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">keywords1</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="o">&amp;</span> <span class="nb">set</span><span class="p">(</span><span class="n">keywords2</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
<a id="__codelineno-1-467" name="__codelineno-1-467"></a>
<a id="__codelineno-1-468" name="__codelineno-1-468"></a> <span class="k">if</span> <span class="n">common_keywords</span><span class="p">:</span>
<a id="__codelineno-1-469" name="__codelineno-1-469"></a> <span class="c1"># 考虑关键词的频率和重要性</span>
<a id="__codelineno-1-470" name="__codelineno-1-470"></a> <span class="n">keyword_score</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="nb">min</span><span class="p">(</span><span class="n">keywords1</span><span class="p">[</span><span class="n">kw</span><span class="p">],</span> <span class="n">keywords2</span><span class="p">[</span><span class="n">kw</span><span class="p">])</span> <span class="k">for</span> <span class="n">kw</span> <span class="ow">in</span> <span class="n">common_keywords</span><span class="p">)</span>
<a id="__codelineno-1-471" name="__codelineno-1-471"></a> <span class="c1"># 关键词匹配数量的奖励</span>
<a id="__codelineno-1-472" name="__codelineno-1-472"></a> <span class="n">keyword_count_bonus</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">common_keywords</span><span class="p">)</span> <span class="o">/</span> <span class="nb">max</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">keywords1</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mf">0.5</span>
<a id="__codelineno-1-473" name="__codelineno-1-473"></a> <span class="n">score</span> <span class="o">+=</span> <span class="p">(</span><span class="n">keyword_score</span> <span class="o">+</span> <span class="n">keyword_count_bonus</span><span class="p">)</span> <span class="o">*</span> <span class="n">weights</span><span class="p">[</span><span class="s1">&#39;keywords&#39;</span><span class="p">]</span>
<a id="__codelineno-1-474" name="__codelineno-1-474"></a>
<a id="__codelineno-1-475" name="__codelineno-1-475"></a> <span class="c1"># 2. 标签相似度</span>
<a id="__codelineno-1-476" name="__codelineno-1-476"></a> <span class="n">tags1</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">tag</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">article1</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">tag</span><span class="p">)</span>
<a id="__codelineno-1-477" name="__codelineno-1-477"></a> <span class="n">tags2</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">tag</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">article2</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">tag</span><span class="p">)</span>
<a id="__codelineno-1-478" name="__codelineno-1-478"></a>
<a id="__codelineno-1-479" name="__codelineno-1-479"></a> <span class="k">if</span> <span class="n">tags1</span> <span class="ow">and</span> <span class="n">tags2</span><span class="p">:</span> <span class="c1"># 确保两篇文章都有标签</span>
<a id="__codelineno-1-480" name="__codelineno-1-480"></a> <span class="n">tag_overlap</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tags1</span> <span class="o">&amp;</span> <span class="n">tags2</span><span class="p">)</span>
<a id="__codelineno-1-481" name="__codelineno-1-481"></a> <span class="n">tag_ratio</span> <span class="o">=</span> <span class="n">tag_overlap</span> <span class="o">/</span> <span class="nb">max</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">tags1</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span> <span class="c1"># 相对重叠比例</span>
<a id="__codelineno-1-482" name="__codelineno-1-482"></a> <span class="n">tag_score</span> <span class="o">=</span> <span class="n">tag_overlap</span> <span class="o">*</span> <span class="mi">8</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">tag_ratio</span><span class="p">)</span> <span class="c1"># 增加重叠比例奖励</span>
<a id="__codelineno-1-483" name="__codelineno-1-483"></a> <span class="n">score</span> <span class="o">+=</span> <span class="n">tag_score</span> <span class="o">*</span> <span class="n">weights</span><span class="p">[</span><span class="s1">&#39;tags&#39;</span><span class="p">]</span>
<a id="__codelineno-1-484" name="__codelineno-1-484"></a>
<a id="__codelineno-1-485" name="__codelineno-1-485"></a> <span class="c1"># 3. 分类相似度</span>
<a id="__codelineno-1-486" name="__codelineno-1-486"></a> <span class="n">categories1</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">cat</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">cat</span> <span class="ow">in</span> <span class="n">article1</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">cat</span><span class="p">)</span>
<a id="__codelineno-1-487" name="__codelineno-1-487"></a> <span class="n">categories2</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">cat</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">cat</span> <span class="ow">in</span> <span class="n">article2</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">cat</span><span class="p">)</span>
<a id="__codelineno-1-488" name="__codelineno-1-488"></a>
<a id="__codelineno-1-489" name="__codelineno-1-489"></a> <span class="k">if</span> <span class="n">categories1</span> <span class="ow">and</span> <span class="n">categories2</span><span class="p">:</span> <span class="c1"># 确保两篇文章都有分类</span>
<a id="__codelineno-1-490" name="__codelineno-1-490"></a> <span class="n">category_overlap</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">categories1</span> <span class="o">&amp;</span> <span class="n">categories2</span><span class="p">)</span>
<a id="__codelineno-1-491" name="__codelineno-1-491"></a> <span class="n">category_ratio</span> <span class="o">=</span> <span class="n">category_overlap</span> <span class="o">/</span> <span class="nb">max</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">categories1</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-1-492" name="__codelineno-1-492"></a> <span class="n">category_score</span> <span class="o">=</span> <span class="n">category_overlap</span> <span class="o">*</span> <span class="mi">12</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">category_ratio</span><span class="p">)</span>
<a id="__codelineno-1-493" name="__codelineno-1-493"></a> <span class="n">score</span> <span class="o">+=</span> <span class="n">category_score</span> <span class="o">*</span> <span class="n">weights</span><span class="p">[</span><span class="s1">&#39;categories&#39;</span><span class="p">]</span>
<a id="__codelineno-1-494" name="__codelineno-1-494"></a>
<a id="__codelineno-1-495" name="__codelineno-1-495"></a> <span class="c1"># 4. 路径分类相似度</span>
<a id="__codelineno-1-496" name="__codelineno-1-496"></a> <span class="k">if</span> <span class="n">article1</span><span class="p">[</span><span class="s1">&#39;path_category&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="n">article2</span><span class="p">[</span><span class="s1">&#39;path_category&#39;</span><span class="p">]:</span>
<a id="__codelineno-1-497" name="__codelineno-1-497"></a> <span class="n">score</span> <span class="o">+=</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">weights</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">]</span>
<a id="__codelineno-1-498" name="__codelineno-1-498"></a>
<a id="__codelineno-1-499" name="__codelineno-1-499"></a> <span class="c1"># 5. 同源目录加分</span>
<a id="__codelineno-1-500" name="__codelineno-1-500"></a> <span class="k">if</span> <span class="n">article1</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;source_dir&#39;</span><span class="p">)</span> <span class="o">==</span> <span class="n">article2</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;source_dir&#39;</span><span class="p">):</span>
<a id="__codelineno-1-501" name="__codelineno-1-501"></a> <span class="n">score</span> <span class="o">+=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">weights</span><span class="p">[</span><span class="s1">&#39;source_dir&#39;</span><span class="p">]</span>
<a id="__codelineno-1-502" name="__codelineno-1-502"></a>
<a id="__codelineno-1-503" name="__codelineno-1-503"></a> <span class="k">return</span> <span class="n">score</span>
</code></pre></div></td></tr></table></div>
<h2 id="_2">效果如下<a class="headerlink" href="#_2" title="Permanent link">&para;</a></h2>
<style>
.related-posts {
margin-top: 1.5rem;
padding-top: 0.75rem;
border-top: 1px solid rgba(0,0,0,0.1);
max-height: none !important; /* 防止Safari错误计算高度 */
overflow: visible !important; /* 防止内容被截断 */
}
.related-posts h3 {
margin-top: 0;
margin-bottom: 0.5rem;
font-size: 1.2rem;
font-weight: 500;
line-height: 1.3;
}
.related-posts ul {
margin: 0 0 0.5rem 0 !important; /* 强制覆盖可能的冲突样式 */
padding-left: 1.5rem;
list-style-position: outside;
}
.related-posts li {
margin-bottom: 0.25rem;
line-height: 1.4;
}
/* 暗色模式适配 */
[data-md-color-scheme="slate"] .related-posts {
border-top-color: rgba(255,255,255,0.1);
}
/* Safari特定修复 */
@supports (-webkit-hyphens:none) {
.related-posts {
display: block;
position: relative;
height: auto !important;
}
.related-posts ul {
position: static;
}
}
</style>
<div class="related-posts">
<h3>📚 相关文章推荐</h3>
<ul>
<li><a href="/Mkdocs-Wcowin/blog/websitebeauty/footer/">页脚设置</a></li>
<li><a href="/Mkdocs-Wcowin/blog/websitebeauty/Mkdocs-AI-Summary/">MkDocs文档AI摘要</a></li>
<li><a href="/Mkdocs-Wcowin/blog/websitebeauty/reading_time/">Mkdocs 阅读时间插件</a></li>
<li><a href="/Mkdocs-Wcowin/blog/Mkdocs/mkdocs1/">利用Mkdocs部署静态网页至GitHubpages</a></li>
<li><a href="/Mkdocs-Wcowin/blog/Mkdocs/mkdocs2/">Mkdocs部署静态网页至GitHub pages配置说明(mkdocs.yml)</a></li>
</ul>
</div>
<!--
Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
<!-- Render date of last update -->
<!-- Render date of creation -->
<!-- ---------------------------------------------------------------------- -->
<!-- Render authors -->
<!-- ---------------------------------------------------------------------- -->
<!-- Render committers from GitHub -->
<!-- Render committers from GitLab -->
<!-- Render committers -->
<!-- ---------------------------------------------------------------------- -->
<!-- Determine date of last update -->
<!-- Determine date of creation -->
<!-- Source file information -->
<aside class="md-source-file">
<!-- Date of last update -->
<span class="md-source-file__fact">
<span class="md-icon" title="最后更新">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg>
</span>
<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="2025年7月15日 15:51:46 UTC">2025-07-15</span>
</span>
<!-- Date of creation -->
<!-- Authors (git-authors plugin) -->
<!-- Authors (git-committers plugin) -->
<span class="md-source-file__fact">
<span class="md-icon" title="贡献者">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2"/></svg>
</span>
<span>GitHub</span>
<nav>
<a
href="https://github.com/Wcowin"
class="md-author"
title="@Wcowin"
>
<img
src="https://avatars.githubusercontent.com/u/99159173?v=4&size=72"
alt="Wcowin"
/>
</a>
<!-- More authors -->
</nav>
</span>
</aside>
<!--
Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
<!-- Determine feedback configuration -->
<!-- Determine whether to show feedback -->
<!-- Was this page helpful? -->
<form class="md-feedback" name="feedback" hidden>
<fieldset>
<legend class="md-feedback__title">
此页面有帮助吗?
</legend>
<div class="md-feedback__inner">
<!-- Feedback ratings -->
<div class="md-feedback__list">
<button
class="md-feedback__icon md-icon"
type="submit"
title="This page was helpful"
data-md-value="1"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 9v12H1V9zm4 12a2 2 0 0 1-2-2V9c0-.55.22-1.05.59-1.41L14.17 1l1.06 1.06c.27.27.44.64.44 1.05l-.03.32L14.69 8H21a2 2 0 0 1 2 2v2c0 .26-.05.5-.14.73l-3.02 7.05C19.54 20.5 18.83 21 18 21zm0-2h9.03L21 12v-2h-8.79l1.13-5.32L9 9.03z"/></svg>
</button>
<button
class="md-feedback__icon md-icon"
type="submit"
title="This page could be improved"
data-md-value="0"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 15V3h4v12zM15 3a2 2 0 0 1 2 2v10c0 .55-.22 1.05-.59 1.41L9.83 23l-1.06-1.06c-.27-.27-.44-.64-.44-1.06l.03-.31.95-4.57H3a2 2 0 0 1-2-2v-2c0-.26.05-.5.14-.73l3.02-7.05C4.46 3.5 5.17 3 6 3zm0 2H5.97L3 12v2h8.78l-1.13 5.32L15 14.97z"/></svg>
</button>
</div>
<!-- Feedback rating notes (shown after submission) -->
<div class="md-feedback__note">
<div data-md-value="1" hidden>
<!-- Determine title -->
<!-- Replace {url} and {title} placeholders in note -->
谢谢你的反馈!
</div>
<div data-md-value="0" hidden>
<!-- Determine title -->
<!-- Replace {url} and {title} placeholders in note -->
Thanks for your feedback! Help us improve this page by using our <a href="https://marketingplatform.google.com/about/analytics/" target="_blank" rel="noopener">feedback form</a>.
</div>
</div>
</div>
</fieldset>
</form>
<!--
Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
<!-- Comment system -->
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
回到页面顶部
</button>
</main>
<!-- Footer -->
<footer class="md-footer">
<!-- Link to previous and/or next page - 移到最上面 -->
<nav
class="md-footer__inner md-grid"
aria-label="页脚"
>
<!-- Link to previous page -->
<a
href="../Mkdocs-AI-Summary/"
class="md-footer__link md-footer__link--prev"
aria-label="上一页: MkDocs文档AI摘要"
>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256l137.3-137.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction"> 上一页 </span>
<div class="md-ellipsis">MkDocs文档AI摘要</div>
</div>
</a>
<!-- Link to next page -->
<a
href="../reading_time/"
class="md-footer__link md-footer__link--next"
aria-label="下一页: 添加阅读信息统计"
>
<div class="md-footer__title">
<span class="md-footer__direction"> 下一页 </span>
<div class="md-ellipsis">添加阅读信息统计</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<!-- Further information -->
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="footer-wrapper">
<!-- 访问统计区域 -->
<div class="footer-content">
<div class="footer-visit-count">
<div class="footer-item">
<!-- <span class="footer-icon">👀</span> -->
<span>本站访问量:</span>
<span id="finicount_views" class="footer-highlight"></span>
</div>
<div class="footer-item">
<!-- <span class="footer-icon">📝</span> -->
<a
href="https://icp.gov.moe/?keyword=20230640"
target="_blank"
rel="noopener noreferrer"
class="icp-link"
>萌ICP备20230640号</a>
</div>
<div class="footer-item runtime-info">
<!-- <span class="footer-icon">⏱️</span> -->
<span>本站已经运行</span>
<span id="box1" class="footer-highlight"></span>
</div>
</div>
</div>
<!-- 移动端简洁布局 (仿 footercopy.html) -->
<div class="footer-visit-count-mobile">
<span>本站访问量:</span>
<span id="finicount_views_mobile" class="footer-highlight"></span>
|
<a
href="https://icp.gov.moe/?keyword=20230640"
target="_blank"
rel="noopener noreferrer"
class="icp-link"
>萌ICP备20230640号</a>
<!-- |&nbsp; -->
<span class="runtime-info">
<span>本站已经运行</span>
<span id="box1_mobile"></span>
</span>
</div>
<!-- 版权信息和社交媒体水平布局 -->
<div class="footer-bottom-section">
<div class="md-footer-copyright">
<p>Copyright © 2022-2025 Wcowin</p>
<p>Made with <a href="https://squidfunk.github.io/mkdocs-material/" style="color: #518FC1; text-decoration: none;">Material for MkDocs</a></p>
</div>
<div class="footer-social">
<div class="md-social">
<a href="https://s1.imagehub.cc/images/2024/02/02/bb9ee71b03ee7a3b87caad5cc4bcebff.jpeg" target="_blank" rel="noopener" title="Wechat" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M385.2 167.6c6.4 0 12.6.3 18.8 1.1C387.4 90.3 303.3 32 207.7 32 100.5 32 13 104.8 13 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 72.9-154 165.3-154m-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2.1-14.7 14.6-24.4 29.3-24.4m-136.4 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4 0 14.6-9.6 24.2-24.4 24.2M563 319.4c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S305 460.7 397.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6C534 402.1 563 363.2 563 319.4m-219.1-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.7 19.6-24.4 19.6m107.1 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3.1 10-9.9 19.6-24.4 19.6"/></svg>
</a>
<a href="https://t.me/wecowin" target="_blank" rel="noopener" title="telegram" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M248 8C111.033 8 0 119.033 0 256s111.033 248 248 248 248-111.033 248-248S384.967 8 248 8m114.952 168.66c-3.732 39.215-19.881 134.378-28.1 178.3-3.476 18.584-10.322 24.816-16.948 25.425-14.4 1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25 5.342-39.5 3.652-3.793 67.107-61.51 68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608 69.142-14.845 10.194-26.894 9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7 18.45-13.7 108.446-47.248 144.628-62.3c68.872-28.647 83.183-33.623 92.511-33.789 2.052-.034 6.639.474 9.61 2.885a10.45 10.45 0 0 1 3.53 6.716 43.8 43.8 0 0 1 .417 9.769"/></svg>
</a>
<a href="https://twitter.com/wcowin_" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8l164.9-188.5L26.8 48h145.6l100.5 132.9zm-24.8 373.8h39.1L151.1 88h-42z"/></svg>
</a>
<a href="https://github.com/Wcowin" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
<a href="mailto:<wangkewen821@gmail.com>" target="_blank" rel="noopener" title="" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M64 112c-8.8 0-16 7.2-16 16v22.1l172.5 141.6c20.7 17 50.4 17 71.1 0L464 150.1V128c0-8.8-7.2-16-16-16zM48 212.2V384c0 8.8 7.2 16 16 16h384c8.8 0 16-7.2 16-16V212.2L322 328.8c-38.4 31.5-93.7 31.5-132 0zM0 128c0-35.3 28.7-64 64-64h384c35.3 0 64 28.7 64 64v256c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64z"/></svg>
</a>
<a href="https://space.bilibili.com/1407028951/lists/4566631?type=series" target="_blank" rel="noopener" title="space.bilibili.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M488.6 104.1c16.7 18.1 24.4 39.7 23.3 65.7v202.4c-.4 26.4-9.2 48.1-26.5 65.1-17.2 17-39.1 25.9-65.5 26.7H92.02c-26.45-.8-48.21-9.8-65.28-27.2C9.682 419.4.767 396.5 0 368.2V169.8c.767-26 9.682-47.6 26.74-65.7C43.81 87.75 65.57 78.77 92.02 78h29.38L96.05 52.19c-5.75-5.73-8.63-13-8.63-21.79 0-8.8 2.88-16.06 8.63-21.797C101.8 2.868 109.1 0 117.9 0q13.2 0 21.9 8.603L213.1 78h88l74.5-69.397C381.7 2.868 389.2 0 398 0q13.2 0 21.9 8.603c5.7 5.737 8.6 12.997 8.6 21.797 0 8.79-2.9 16.06-8.6 21.79L394.6 78h29.3c26.4.77 48 9.75 64.7 26.1m-38.8 69.7c-.4-9.6-3.7-17.4-10.7-23.5-5.2-6.1-14-9.4-22.7-9.8H96.05c-9.59.4-17.45 3.7-23.58 9.8-6.14 6.1-9.4 13.9-9.78 23.5v194.4c0 9.2 3.26 17 9.78 23.5s14.38 9.8 23.58 9.8H416.4c9.2 0 17-3.3 23.3-9.8s9.7-14.3 10.1-23.5zm-264.3 42.7c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2-6.2 6.3-14 9.5-23.6 9.5s-17.5-3.2-23.6-9.5-9.4-14-9.8-23.2v-33.3c.4-9.1 3.8-16.9 10.1-23.2s13.2-9.6 23.3-10c9.2.4 17 3.7 23.3 10m191.5 0c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2s-14 9.5-23.6 9.5-17.4-3.2-23.6-9.5c-7-6.3-9.4-14-9.7-23.2v-33.3c.3-9.1 3.7-16.9 10-23.2s14.1-9.6 23.3-10c9.2.4 17 3.7 23.3 10"/></svg>
</a>
</div>
</div>
</div>
</div>
<script>
(function() {
// 避免变量冲突,将所有代码包装在立即执行函数中
function timingTime() {
const start = "2023-10-14T00:00:00";
const startTime = new Date(start).getTime();
const now = Date.now();
let diff = Math.floor((now - startTime) / 1000);
const days = Math.floor(diff / 86400);
diff %= 86400;
const hours = Math.floor(diff / 3600);
diff %= 3600;
const minutes = Math.floor(diff / 60);
const seconds = diff % 60;
return `${days}${hours}${minutes}${seconds}`;
}
// 简化的计时器更新函数
function updateTime() {
const el = document.getElementById("box1");
const elMobile = document.getElementById("box1_mobile");
const time = timingTime();
if (el) el.textContent = time;
if (elMobile) elMobile.textContent = time;
}
// 加载访问量计数器
async function loadVisitCounter() {
try {
const script = document.createElement('script');
script.src = '//finicounter.eu.org/finicounter.js';
script.async = true;
script.onerror = function() {
console.log('访问量计数器加载失败,使用备用显示');
const desktop = document.getElementById("finicount_views");
const mobile = document.getElementById("finicount_views_mobile");
if (desktop) desktop.textContent = '统计中...';
if (mobile) mobile.textContent = '统计中...';
};
document.head.appendChild(script);
} catch (e) {
console.log('访问量计数器初始化失败:', e);
}
}
// 同步访问量显示
function syncVisitCount() {
const desktop = document.getElementById("finicount_views");
const mobile = document.getElementById("finicount_views_mobile");
if (desktop && mobile && desktop.textContent && desktop.textContent !== '加载中...') {
mobile.textContent = desktop.textContent;
}
}
// 监听访问量更新
function setupVisitCountObserver() {
try {
const observer = new MutationObserver(syncVisitCount);
const visitCountTarget = document.getElementById("finicount_views");
if (visitCountTarget) {
observer.observe(visitCountTarget, { childList: true, subtree: true });
}
} catch (e) {
console.log('访问量监听器设置失败:', e);
}
}
// 初始化所有功能
function init() {
// 启动计时器
updateTime();
setInterval(updateTime, 1000);
// 加载访问量计数器
loadVisitCounter();
// 设置访问量同步
setupVisitCountObserver();
// 调试信息
console.log('页脚功能已启动');
console.log('当前时间:', timingTime());
}
// 确保DOM加载完成后再初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>
<style>
/* 页脚背景配色方案 - 可根据喜好选择 */
/* 方案1: 现代深蓝灰色调 (当前使用) */
.md-footer {
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
}
.md-footer-meta {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
}
/* 方案2: 优雅紫色调 (取消注释使用)
.md-footer {
background: linear-gradient(135deg, #2d1b69 0%, #4c1d95 100%);
}
.md-footer-meta {
background: linear-gradient(135deg, #1e1b4b 0%, #2d1b69 100%);
}
*/
/* 方案3: 温暖深绿色调 (取消注释使用)
.md-footer {
background: linear-gradient(135deg, #14532d 0%, #166534 100%);
}
.md-footer-meta {
background: linear-gradient(135deg, #052e16 0%, #14532d 100%);
}
*/
/* 方案4: 经典深灰色调 (取消注释使用)
.md-footer {
background: linear-gradient(135deg, #374151 0%, #4b5563 100%);
}
.md-footer-meta {
background: linear-gradient(135deg, #1f2937 0%, #374151 100%);
}
*/
/* 整体页脚容器 */
.footer-wrapper {
width: 100%;
padding: 0.2rem 0;
text-align: center;
}
/* 版权信息和社交媒体水平布局 */
.footer-bottom-section {
max-width: 900px;
margin: 0.4rem auto 0;
padding: 0.4rem 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.15);
display: flex;
justify-content: space-between;
align-items: center;
}
/* 版权信息 */
.md-footer-copyright {
text-align: left;
font-size: 0.75rem;
opacity: 0.8;
line-height: 1.2;
}
/* 社交媒体图标 */
.footer-social {
display: -webkit-flex;
display: flex;
gap: 0.3rem;
-webkit-align-items: center;
align-items: center;
}
/* Safari兼容性修复 */
.footer-social .md-social__link svg {
-webkit-transform: translateZ(0);
transform: translateZ(0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
opacity: 1 !important;
visibility: visible !important;
pointer-events: auto;
}
/* 强制Safari显示SVG图标 */
.footer-social .md-social__link {
opacity: 1 !important;
visibility: visible !important;
}
/* 内容区域样式 */
.footer-content {
max-width: 900px;
margin: 0 auto;
padding: 0.4rem 0 0;
}
.footer-visit-count {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
font-size: 0.75rem;
color: var(--md-footer-fg-color--light);
}
.footer-item {
display: flex;
align-items: center;
justify-content: center;
padding: 0.4rem 0.8rem;
border-radius: 16px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
min-width: 160px;
font-size: 0.8rem;
transition: all 0.2s ease;
}
.footer-item:hover {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(81, 143, 193, 0.4);
transform: translateY(-1px);
}
.footer-icon {
margin-right: 0.5rem;
font-size: 1rem;
}
.footer-highlight {
color: #939ba2;
font-weight: 600;
margin-left: 0.3rem;
}
.icp-link {
color: inherit;
text-decoration: none;
}
.icp-link:hover {
color: #518FC1;
}
/* 社交媒体图标样式 - 仅桌面端 */
@media (min-width: 76.1875em) {
.footer-social .md-social__link {
padding: 0.3rem;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.1);
width: 2rem;
height: 2rem;
display: -webkit-inline-flex;
display: inline-flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.footer-social .md-social__link svg {
width: 1.2rem;
height: 1.2rem;
fill: currentColor;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
.footer-social .md-social__link:hover {
background: rgba(81, 143, 193, 0.2);
border-color: rgba(81, 143, 193, 0.4);
}
}
/* 移动端社交媒体图标样式 - 恢复默认样式 */
@media (max-width: 76.1875em) {
.footer-social .md-social__link {
padding: 0.4rem;
background: transparent;
border: none;
width: auto;
height: auto;
display: inline-block;
border-radius: 0;
-webkit-transition: color 0.2s ease;
transition: color 0.2s ease;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.footer-social .md-social__link:hover {
background: transparent;
border: none;
color: var(--md-accent-fg-color);
}
.footer-social .md-social__link svg {
width: 1.6rem;
height: 1.6rem;
fill: currentColor;
-webkit-flex-shrink: 0;
flex-shrink: 0;
display: block;
}
}
/* 导航链接样式 */
.md-footer__link {
transition: opacity 0.2s ease;
}
.md-footer__link:hover {
opacity: 1;
}
/* 移动端响应式 - 使用 footercopy.html 样式 */
@media (max-width: 76.1875em) {
/* 隐藏桌面端的卡片式布局 */
.footer-visit-count {
display: none;
}
.footer-bottom-section {
flex-direction: column;
gap: 0.6rem;
text-align: center;
}
.md-footer-copyright {
text-align: center;
font-size: 0.75rem;
}
.footer-social .md-social__link {
width: 1.8rem;
height: 1.8rem;
}
/* 显示移动端的简洁布局 */
.footer-visit-count-mobile {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 0.4em 0.8em;
padding: 0.2em 0;
font-size: 0.75rem;
color: var(--md-footer-fg-color--light);
text-align: center;
}
.footer-visit-count-mobile > * {
white-space: nowrap;
}
.footer-visit-count-mobile .icp-link {
color: var(--md-footer-fg-color--light);
text-decoration: none;
}
.footer-visit-count-mobile .icp-link:hover {
color: #596875;
text-decoration: underline;
}
/* .runtime-info {
display: none; 移动端隐藏运行时间
} */
}
/* 桌面端隐藏移动端布局 */
@media (min-width: 76.1875em) {
.footer-visit-count-mobile {
display: none;
}
}
@media (min-width: 768px) {
.footer-visit-count {
flex-direction: row;
justify-content: center;
gap: 2rem;
}
}
/* 深色模式适配 */
[data-md-color-scheme="slate"] .md-footer {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
}
[data-md-color-scheme="slate"] .md-footer-meta {
background: linear-gradient(135deg, #020617 0%, #0f172a 100%);
}
[data-md-color-scheme="slate"] .footer-item {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.12);
}
[data-md-color-scheme="slate"] .footer-item:hover {
background: rgba(255, 255, 255, 0.12);
border-color: rgba(81, 143, 193, 0.3);
}
[data-md-color-scheme="slate"] .footer-social .md-social__link {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.12);
}
</style>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../../..", "features": ["announce.dismiss", "navigation.tracking", "navigation.tabs", "navigation.sections", "navigation.top", "navigation.footer", "search.suggest", "search.highlight", "search.share", "navigation.expand", "navigation.indexes", "content.tabs.link", "content.tooltips", "content.code.copy", "content.action.edit", "content.action.view", "content.code.annotate"], "search": "../../../assets/javascripts/workers/search.d50fe291.min.js", "tags": null, "translations": {"clipboard.copied": "\u5df2\u590d\u5236", "clipboard.copy": "\u590d\u5236", "search.result.more.one": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.other": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 # \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.term.missing": "\u7f3a\u5c11", "select.version": "\u9009\u62e9\u5f53\u524d\u7248\u672c"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.56ea9cef.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/Wcowin/Wcowin.github.io@main/docs/javascripts/extra.js"></script>
<script src="../../../javascripts/mathjax.js"></script>
<script src="https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script src="https://cdn.jsdelivr.net/gh/Wcowin/Wcowin.github.io@main/docs/javascripts/view.js"></script>
</body>
</html>