Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Deploy VitePress site to Pages

on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Install dependencies
run: npm ci

- name: Normalize markdown links
run: npm run docs:fix-links

- name: Build with VitePress
run: npm run docs:build

Comment thread
liueggy marked this conversation as resolved.
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
with:
path: .vitepress/dist

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
.vitepress/cache/
.vitepress/dist/
dist/
.omx/
.DS_Store
57 changes: 57 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { defineConfig } from 'vitepress';
import { buildNav, buildRewrites, buildSidebar } from '../scripts/docs-tools.mjs';

export default defineConfig({
vite: {
ssr: {
noExternal: ['element-plus']
}
},
lang: 'zh-CN',
title: 'Embed Book',
description: '嵌入式软件开发全景知识库,覆盖 C 语言、驱动开发、RTOS、Embedded Linux、IoT 与 AI on MCU。',
base: '/Embed_book/',
srcExclude: ['README.md', 'LICENSE.md', '.omx/**', 'node_modules/**'],
cleanUrls: true,
rewrites: buildRewrites(),
ignoreDeadLinks: [/^http:\/\/localhost:\d+/],
lastUpdated: true,
head: [
['meta', { name: 'theme-color', content: '#0f172a' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:title', content: 'Embed Book' }],
['meta', { property: 'og:description', content: '为嵌入式软件学习打造的可阅读、可导航静态文档站。' }]
],
themeConfig: {
siteTitle: 'Embed Book',
logo: '/1.png',
nav: buildNav(),
sidebar: buildSidebar(),
socialLinks: [
{ icon: 'github', link: 'https://github.com/liueggy/Embed_book' }
],
search: {
provider: 'local'
},
outline: {
level: [2, 3],
label: '本页目录'
},
docFooter: {
prev: '上一页',
next: '下一页'
},
returnToTopLabel: '返回顶部',
sidebarMenuLabel: '导航',
darkModeSwitchLabel: '主题',
lightModeSwitchTitle: '切换到浅色模式',
darkModeSwitchTitle: '切换到深色模式',
lastUpdated: {
text: '最后更新于'
},
footer: {
message: '以 GitHub Pages 发布,使用 VitePress 构建。',
copyright: 'Content under CC BY-NC-SA 4.0 where applicable.'
}
}
});
98 changes: 98 additions & 0 deletions .vitepress/theme/components/Breadcrumb.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useData, useRoute, withBase } from 'vitepress';

const route = useRoute();
const { frontmatter } = useData();

interface Crumb {
text: string;
link?: string;
}

const sectionNameMap: Record<string, string> = {
'01-C语言基础与进阶': 'C 语言基础与进阶',
'02-嵌入式系统基础知识': '嵌入式系统基础知识',
'03-驱动开发与外设编程': '驱动开发与外设编程',
'04-实时操作系统': '实时操作系统',
'05-EmbeddedLinux': 'Embedded Linux',
'06-NetworkIot': '网络通信与物联网',
'07-Debug_Optimization': '调试与性能优化',
'08-项目实战与工具链': '项目实战与工具链',
'09-2025_AI_on_MCU': '2025 AI on MCU',
'嵌入式图形 Qt 开发': '嵌入式图形 Qt 开发',
'面试题与面经': '面试题与面经',
'books': '资源下载'
};

const crumbs = computed<Crumb[]>(() => {
const path = route.path;

// Don't show breadcrumb on home page
if (path === '/' || path === '') return [];

// Also skip if it's the home layout
if (frontmatter.value.layout === 'home') return [];

const items: Crumb[] = [{ text: '首页', link: '/' }];

// Decode the path for matching
const decoded = decodeURIComponent(path);
const segments = decoded.replace(/^\//, '').replace(/\/$/, '').split('/');

if (segments.length === 0) return items;

// First segment is typically the section dir
const sectionDir = segments[0];
const sectionName = sectionNameMap[sectionDir];

if (sectionName) {
if (segments.length === 1 || (segments.length === 1 && decoded.endsWith('/'))) {
items.push({ text: sectionName });
} else {
items.push({
text: sectionName,
link: `/${encodeURIComponent(sectionDir)}/`
});
// Page name - remove .html extension if present
const pageName = segments[segments.length - 1].replace(/\.html$/, '');
items.push({ text: pageName });
}
} else {
// Fallback for other pages like study-map, resources
const pageName = segments[segments.length - 1].replace(/\.html$/, '');
items.push({ text: pageName });
}

return items;
});
</script>

<template>
<el-breadcrumb v-if="crumbs.length > 0" separator="/" class="doc-breadcrumb">
<el-breadcrumb-item
v-for="(crumb, index) in crumbs"
:key="index"
>
<a v-if="crumb.link" :href="withBase(crumb.link)">{{ crumb.text }}</a>
<span v-else>{{ crumb.text }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</template>

<style scoped>
.doc-breadcrumb {
margin-bottom: 16px;
padding: 8px 0;
font-size: 13px;
}

.doc-breadcrumb a {
color: var(--vp-c-brand-1);
text-decoration: none;
}

.doc-breadcrumb a:hover {
text-decoration: underline;
}
</style>
Loading