mirror of
https://github.com/jaywcjlove/reference.git
synced 2025-06-17 04:31:22 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
bd082908d8 | |||
dd8a3cb26d | |||
6d0801a9da | |||
6290b9eae0 | |||
9479626194 | |||
ad4b2e9119 | |||
d48341cecb | |||
5aec989c14 | |||
13492fe556 | |||
d145aaa0b0 | |||
531c01d62e | |||
0a160d22d8 |
15
.github/ISSUE_TEMPLATE/cheatsheet-request.md
vendored
15
.github/ISSUE_TEMPLATE/cheatsheet-request.md
vendored
@ -5,21 +5,16 @@ title: '备忘清单 请求: '
|
||||
labels: request
|
||||
assignees: jaywcjlove
|
||||
---
|
||||
备忘清单标题 备忘清单
|
||||
【备忘清单标题】 备忘清单
|
||||
===
|
||||
|
||||
这是您可以在 Quick Reference 备忘清单上使用的参考!【备忘清单介绍】
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 卡片 1
|
||||
如果有一张备忘单(速查表) [`参考这里`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 为仓库贡献。
|
||||
|
||||
### 卡片 2
|
||||
|
||||
### 卡片 3
|
||||
|
||||
另见
|
||||
提供参考资料地址
|
||||
----
|
||||
|
||||
- [参考地址](https://xxx.com)
|
||||
- [参考地址 1](https://xxx.com)
|
||||
- [官网地址](https://xxx.com)
|
@ -16,6 +16,26 @@ Contributing 贡献
|
||||
|
||||
只需要 `标题<h1>` 和`介绍`(标题下面)。脚本会自动识别,通过 GitHub Actions 自动发布 [`Quick Reference`](https://jaywcjlove.github.io/reference) 网站。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```bash
|
||||
.
|
||||
├── CONTRIBUTING.md # 贡献说明
|
||||
├── Dockerfile
|
||||
├── LICENSE
|
||||
├── README.md # Home(首页) 内容
|
||||
├── dist # 编译后的静态资源目录
|
||||
├── docs # Markdown 文档(快速参考备忘清单【速查表】)
|
||||
│ ├── bash.md
|
||||
│ ├── ....
|
||||
│ └── yaml.md
|
||||
├── package.json
|
||||
└── scripts # MD 转 HTML 的编译脚本
|
||||
├── assets # 存放首页 svg 图标文件资源,与 `dosc` 文件名对应
|
||||
├── ....
|
||||
└── watch.mjs
|
||||
```
|
||||
|
||||
## CSS 类注释
|
||||
|
||||
[`Quick Reference`](https://jaywcjlove.github.io/reference) 使用 [`@wcj/markdown-to-html`](https://github.com/jaywcjlove/markdown-to-html) 转换 `Markdown`,并使用 [`rehype-attr`](https://github.com/jaywcjlove/rehype-attr) 插件让其支持通过其注释语法添加类和样式。 此外,您可以在 Quick Reference 备忘清单上使用样式参考:https://jaywcjlove.github.io/reference/docs/quickreference.html
|
||||
@ -34,6 +54,13 @@ Contributing 贡献
|
||||
<!--rehype:class=home-card-->
|
||||
```
|
||||
|
||||
首页导航图标存放在 `scripts/assets` 目录中,如果你的备忘清单定义为 `docs/cron.md`,那么你的图标就定义为 `cron.svg` 存放到 `scripts/assets` 目录中,重新编译首页当行菜单就拥有了图标。
|
||||
|
||||
- 图标存放在 [`scripts/assets`](https://github.com/jaywcjlove/reference/blob/main/scripts/assets) 目录中
|
||||
- 图片名称与清单名称保持一致 `cron.md` -> `cron.svg` (注意大小写)
|
||||
- SVG 图标尺寸 `<svg height="1em" width="1em"`
|
||||
- SVG 图标颜色使用继承颜色值 `<svg fill="currentColor"`
|
||||
|
||||
## 本地开发
|
||||
|
||||
```bash
|
||||
|
@ -9,10 +9,10 @@ Quick Reference
|
||||
<!--rehype:ignore:end-->
|
||||
|
||||
<!--rehype:ignore:start-->
|
||||
[](https://jaywcjlove.github.io/reference)
|
||||
[](https://jaywcjlove.github.io/reference)
|
||||
<!--rehype:ignore:end-->
|
||||
|
||||
为开发人员分享快速参考备忘清单(主要是方便自己),在看到 [Reference](https://github.com/Randy8080/reference) 快速参考备忘单,感觉非常简单,造轮子使命感突然来了,造个中文版本的,为了方便自己的技术栈查阅,立马撸起来 :)。如果您发现此处的备忘单不合适,您可以通过提交 [PR](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 来修复它或提供更好的备忘清单,只针对【中文】用户。以下是开源天使提供的一些备忘清单和快速参考 :)。
|
||||
为开发人员分享快速参考备忘清单【速查表】 _(主要是方便自己)_,在看到 [Reference](https://github.com/Randy8080/reference) 快速参考备忘单,感觉非常简单,造轮子使命感突然来了,造个中文版本的,为了方便自己的技术栈查阅,立马撸起来 :)。如果您发现此处的备忘单不合适,您可以通过提交 [PR](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 来修复它或提供更好的备忘清单,只针对【中文】用户。以下是开源天使提供的一些备忘清单和快速参考 :)。
|
||||
|
||||
## 编程
|
||||
|
||||
@ -102,8 +102,8 @@ Quick Reference
|
||||
|
||||
上面的列表没有看到你想要的? 您是否正在寻找一些备忘清单或参考资料,或者您有一些片段备忘清单要分享,这是一个最好的机会!
|
||||
|
||||
[`请求添加备忘单`](https://github.com/jaywcjlove/reference/issues/new?title=【备忘清单】+请求%3A+&labels=request&template=cheatsheet-request.md&assignee=jaywcjlove)<!--rehype:class=home-button&style=margin-top:2rem&target=__blank-->
|
||||
[`我有一张备忘单`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)<!--rehype:class=home-button text-grey&target=__blank-->
|
||||
[`请求添加备忘单(速查表)`](https://github.com/jaywcjlove/reference/issues/new?title=【备忘清单】+请求%3A+&labels=request&template=cheatsheet-request.md&assignee=jaywcjlove)<!--rehype:class=home-button&style=margin-top:2rem&target=__blank-->
|
||||
[`我有一张备忘单(速查表)`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)<!--rehype:class=home-button text-grey&target=__blank-->
|
||||
<!--rehype:style=margin-top:3rem-->
|
||||
|
||||
<!--rehype:ignore:start-->
|
||||
|
@ -34,11 +34,9 @@ NAME = "John" # => Error (关于空间)
|
||||
|
||||
### 注释
|
||||
|
||||
```bash
|
||||
# 这是一个内联 Bash 注释。
|
||||
```
|
||||
|
||||
```shell
|
||||
# 这是一个内联 Bash 注释。
|
||||
|
||||
: '
|
||||
这是一个
|
||||
非常整洁的评论
|
||||
|
@ -340,7 +340,7 @@ env:
|
||||
myHexNumber: ${{ 0xff }}
|
||||
myExponentialNumber: ${{ -2.99e-2 }}
|
||||
myString: Mona the Octocat
|
||||
myStringInBraces: ${{ 'It''s open source!' }}
|
||||
myStringInBraces: ${{ 'It''s source!' }}
|
||||
```
|
||||
|
||||
### 函数 contains
|
||||
@ -375,6 +375,7 @@ startsWith('Hello world', 'He') // 返回 true
|
||||
format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')
|
||||
// 返回 '{Hello Mona the Octocat!}'.
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
另见: [函数 format](https://docs.github.com/cn/actions/learn-github-actions/expressions#format)
|
||||
|
||||
@ -815,6 +816,24 @@ steps:
|
||||
|
||||
您可以使用 `shell` 关键字覆盖运行器操作系统中的默认 `shell` 设置
|
||||
|
||||
### 一些 actions 推荐
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
[`create-tag-action`](https://github.com/jaywcjlove/create-tag-action) | 根据 package.json 创建 `Tag` / `Release`
|
||||
[`changelog-generator`](https://github.com/jaywcjlove/changelog-generator) | 生成 `changelog` 日志
|
||||
[`github-action-modify-file-content`](https://github.com/jaywcjlove/github-action-modify-file-content) | 修改仓库文件内容
|
||||
[`github-action-contributors`](https://github.com/jaywcjlove/github-action-contributors) | 生成贡献(contributors.svg)图片
|
||||
[`generated-badges`](https://github.com/jaywcjlove/generated-badges) | 生成徽章(Badges)图片
|
||||
[`coverage-badges-cli`](https://github.com/jaywcjlove/coverage-badges-cli) | 生成覆盖率徽章(Badges)图片
|
||||
[`action-ejs`](https://github.com/jaywcjlove/action-ejs) | 基于 ejs 生成 HTML
|
||||
[`github-action-package`](https://github.com/jaywcjlove/github-action-package) | 修改 JSON 文件内容
|
||||
[`markdown-to-html-cli`](https://github.com/jaywcjlove/markdown-to-html-cli) | Markdown 转换成 HTML
|
||||
[`ncipollo/release-action`](https://github.com/ncipollo/release-action) | 创建 `Release`
|
||||
[`peaceiris/actions-gh-pages`](https://github.com/peaceiris/actions-gh-pages) | 将文件或文件夹内容提交到 `gh-pages` 分支
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
|
@ -38,6 +38,7 @@ export HOMEBREW_INSTALL_FROM_API=1
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew install git` | `安装`一个包
|
||||
`brew reinstall git` | 重新`安装`一个包
|
||||
`brew uninstall git` | `删除`/`卸载`软件包
|
||||
`brew upgrade git` | 升级包
|
||||
:--- :---
|
||||
@ -46,9 +47,6 @@ export HOMEBREW_INSTALL_FROM_API=1
|
||||
`brew switch git 2.5.0` | 更改版本
|
||||
:--- :---
|
||||
`brew list --versions git` | 看看你有什么版本
|
||||
:--- :---
|
||||
`brew help` | 打印帮助信息
|
||||
`brew help <sub-command>` | 打印子命令的帮助信息
|
||||
|
||||
### 更多包命令
|
||||
|
||||
@ -119,6 +117,13 @@ $ brew search <text>
|
||||
$ brew info <formula>
|
||||
```
|
||||
|
||||
### 帮助命令
|
||||
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew help` | 打印帮助信息
|
||||
`brew help <sub-command>` | 打印子命令的帮助信息
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
|
@ -8,11 +8,11 @@ HTTP 状态码
|
||||
|
||||
### Means
|
||||
|
||||
- [1xx: Informational](#1xx-information) _这意味着已收到请求并且该过程正在继续_<!--rehype:tooltips-->
|
||||
- [2xx: Success](#2xx-successful) _这意味着该操作已成功接收、理解和接受_<!--rehype:tooltips-->
|
||||
- [3xx: Redirection](#3xx-redirection) _这意味着必须采取进一步行动才能完成请求_<!--rehype:tooltips-->
|
||||
- [4xx: Client Error](#4xx-client-error) _这意味着请求包含不正确的语法或无法完成_<!--rehype:tooltips-->
|
||||
- [5xx: Server Error](#5xx-server-error) _这意味着服务器未能满足明显有效的请求_<!--rehype:tooltips-->
|
||||
- [1xx: Informational](#1xx-信息) _这意味着已收到请求并且该过程正在继续_<!--rehype:tooltips-->
|
||||
- [2xx: Success](#2xx-成功的) _这意味着该操作已成功接收、理解和接受_<!--rehype:tooltips-->
|
||||
- [3xx: Redirection](#3xx-重定向) _这意味着必须采取进一步行动才能完成请求_<!--rehype:tooltips-->
|
||||
- [4xx: Client Error](#4xx-客户端错误) _这意味着请求包含不正确的语法或无法完成_<!--rehype:tooltips-->
|
||||
- [5xx: Server Error](#5xx-服务器错误) _这意味着服务器未能满足明显有效的请求_<!--rehype:tooltips-->
|
||||
|
||||
### 2xx. 成功的
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
@ -58,8 +58,8 @@ HTTP 状态码
|
||||
### 3xx. 重定向
|
||||
|
||||
* [300: Multiple Choices](https://tools.ietf.org/html/rfc7231#section-6.4.1) _一个链接列表。 用户可以选择一个链接并转到该位置。 最多五个地址_<!--rehype:tooltips-->
|
||||
* [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url _<!--rehype:tooltips-->
|
||||
* [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url _<!--rehype:tooltips-->
|
||||
* [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url_<!--rehype:tooltips-->
|
||||
* [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
|
||||
* [303: See Other](https://tools.ietf.org/html/rfc7231#section-6.4.4) _请求的页面可以在不同的 url 下找到_<!--rehype:tooltips-->
|
||||
* [304: Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) _这是对 If-Modified-Since 或 If-None-Match 标头的响应代码,其中 URL 自指定日期以来未修改_<!--rehype:tooltips-->
|
||||
* [305: Use Proxy](https://tools.ietf.org/html/rfc7231#section-6.4.5) _请求的 URL 必须通过 Location 标头中提到的代理访问_<!--rehype:tooltips-->
|
||||
@ -128,4 +128,4 @@ HTTP 状态码
|
||||
- [List of FTP server return codes](https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes) _(wikipedia.org)_
|
||||
- [HTTP概述](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview) _(mozilla.org)_
|
||||
- [Help for HTTP error 403: “Forbidden”](http://www.getnetgoing.com/HTTP-403.html) _(getnetgoing.com)_
|
||||
- [实用的 RESTful API 最佳实践](https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) _(vinaysahni.com)_
|
||||
- [实用的 RESTful API 最佳实践](https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) _(vinaysahni.com)_
|
||||
|
@ -54,7 +54,6 @@ Semver 备忘清单
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 连字符范围
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
| 范围 | 描述 |
|
||||
| --- | --- |
|
||||
@ -80,6 +79,43 @@ Semver 备忘清单
|
||||
|
||||
如果左边是部分的(例如,`1.2`),则假定缺少的部分为`0`(例如,` 1.2.0`)。
|
||||
|
||||
### 有效的语义版本
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
```js
|
||||
0.0.4
|
||||
1.2.3
|
||||
10.20.30
|
||||
1.1.2-prerelease+meta
|
||||
1.1.2+meta
|
||||
1.1.2+meta-valid
|
||||
1.0.0-alpha
|
||||
1.0.0-beta
|
||||
1.0.0-alpha.beta
|
||||
1.0.0-alpha.beta.1
|
||||
1.0.0-alpha.1
|
||||
1.0.0-alpha0.valid
|
||||
1.0.0-alpha.0valid
|
||||
1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay
|
||||
1.0.0-rc.1+build.1
|
||||
2.0.0-rc.1+build.123
|
||||
1.2.3-beta
|
||||
10.2.3-DEV-SNAPSHOT
|
||||
1.2.3-SNAPSHOT-123
|
||||
1.0.0
|
||||
2.0.0
|
||||
1.1.7
|
||||
2.0.0+build.1848
|
||||
2.0.1-alpha.1227
|
||||
1.0.0-alpha+beta
|
||||
1.2.3----RC-SNAPSHOT.12.9.1--.12+788
|
||||
1.2.3----R-S.12.9.1--.12+meta
|
||||
1.2.3----RC-SNAPSHOT.12.9.1--.12
|
||||
1.0.0+0.build.1-rc.10000aaa-kk-0.1
|
||||
99999999999999999999999.999999999999999999.99999999999999999
|
||||
1.0.0-0A.is.legal
|
||||
```
|
||||
|
||||
### 组合范围
|
||||
|
||||
| 范围 | 描述 |
|
||||
@ -88,13 +124,8 @@ Semver 备忘清单
|
||||
| `0.14.x \|\| 15.x.x` | 或 (双竖线分隔) |
|
||||
<!--rehype:className=shortcuts show-header-->
|
||||
|
||||
### 预发布
|
||||
|
||||
```
|
||||
1.2.3-prerelease+build
|
||||
```
|
||||
|
||||
### 解释
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
| 范围 | 描述 |
|
||||
| --- | --- |
|
||||
@ -104,6 +135,13 @@ Semver 备忘清单
|
||||
| `1.x.x` | 表示定义了公共 API |
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 预发布
|
||||
|
||||
```
|
||||
1.2.3-prerelease+build
|
||||
1.1.2-prerelease+meta
|
||||
```
|
||||
|
||||
|
||||
另见
|
||||
----
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wcj/reference",
|
||||
"version": "1.10.0",
|
||||
"version": "1.11.0",
|
||||
"description": "为开发人员分享快速参考备忘单(主要是方便自己)。",
|
||||
"author": "jaywcjlove",
|
||||
"license": "MIT",
|
||||
|
3
scripts/assets/menu.svg
Normal file
3
scripts/assets/menu.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg aria-hidden="true" fill="currentColor" height="1em" width="1em" viewBox="0 0 16 16" version="1.1" data-view-component="true">
|
||||
<path fill-rule="evenodd" d="M2 4a1 1 0 100-2 1 1 0 000 2zm3.75-1.5a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5zm0 5a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5zm0 5a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5zM3 8a1 1 0 11-2 0 1 1 0 012 0zm-1 6a1 1 0 100-2 1 1 0 000 2z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 416 B |
@ -1,6 +1,9 @@
|
||||
import markdown from '@wcj/markdown-to-html';
|
||||
import rehypeDocument from 'rehype-document';
|
||||
import remarkGemoji from 'remark-gemoji';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import rehypeAttrs from 'rehype-attr';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
||||
import rehypeSlug from 'rehype-slug';
|
||||
import { htmlTagAddAttri } from './nodes/htmlTagAddAttri.mjs';
|
||||
@ -9,7 +12,7 @@ import { header } from './nodes/header.mjs';
|
||||
import { rehypeUrls } from './utils/rehypeUrls.mjs';
|
||||
import { tooltips } from './utils/tooltips.mjs';
|
||||
import { homeCardIcons } from './utils/homeCardIcons.mjs';
|
||||
import { getTocsTree } from './utils/getTocsTree.mjs';
|
||||
import { getTocsTree, getTocsTitleNode, getTocsTitleNodeWarpper, addTocsInWarp } from './utils/getTocsTree.mjs';
|
||||
import { rehypeTitle } from './utils/rehypeTitle.mjs';
|
||||
import { anchorPoint } from './utils/anchorPoint.mjs';
|
||||
import { rehypePreviewHTML } from './utils/rehypePreviewHTML.mjs';
|
||||
@ -29,18 +32,29 @@ export function create(str = '', options = {}) {
|
||||
rehypePlugins: [
|
||||
rehypeSlug,
|
||||
rehypeAutolinkHeadings,
|
||||
[rehypeDocument, {
|
||||
title: `${title ? `${title} & ` : ''} ${subTitle} Quick Reference`,
|
||||
css: [ ...options.css ],
|
||||
link: [
|
||||
{rel: 'icon', href: favicon, type: 'image/svg+xml'}
|
||||
],
|
||||
meta: [
|
||||
{ description: `${description}为开发人员分享快速参考备忘单。` },
|
||||
{ keywords: `Quick,Reference,cheatsheet,${!options.isHome && options.filename || ''}` }
|
||||
]
|
||||
}],
|
||||
[rehypeDocument, {
|
||||
title: `${title ? `${title} & ` : ''} ${subTitle} Quick Reference`,
|
||||
css: [ ...options.css ],
|
||||
link: [
|
||||
{rel: 'icon', href: favicon, type: 'image/svg+xml'}
|
||||
],
|
||||
meta: [
|
||||
{ description: `${description}为开发人员分享快速参考备忘单。` },
|
||||
{ keywords: `Quick,Reference,cheatsheet,${!options.isHome && options.filename || ''}` }
|
||||
]
|
||||
}]
|
||||
],
|
||||
filterPlugins: (type, plugins = []) => {
|
||||
if (type === 'rehype') {
|
||||
const dt = plugins.filter(plug => {
|
||||
return /(rehypeRaw)/.test(plug.name) ? false : true;
|
||||
});
|
||||
// 放在 rehypeDocument 前面
|
||||
dt.unshift(rehypeRaw)
|
||||
return dt;
|
||||
}
|
||||
return plugins
|
||||
},
|
||||
rewrite: (node, index, parent) => {
|
||||
rehypePreviewHTML(node, parent);
|
||||
rehypeTitle(node, options.filename);
|
||||
@ -48,11 +62,19 @@ export function create(str = '', options = {}) {
|
||||
tooltips(node, index, parent);
|
||||
htmlTagAddAttri(node, options);
|
||||
rehypeUrls(node);
|
||||
if (node.type === 'element' && node.tagName === 'body') {
|
||||
node.children = getTocsTree([ ...node.children ]);
|
||||
node.children.unshift(header(options));
|
||||
node.children.push(footer());
|
||||
node.children.push(anchorPoint());
|
||||
if (node.children) {
|
||||
if (node.type === 'element' && node.tagName === 'body') {
|
||||
const tocsData = getTocsTree([ ...node.children ]);
|
||||
if (!options.isHome) {
|
||||
const tocsMenus = getTocsTitleNode([...tocsData]);
|
||||
node.children = addTocsInWarp([...tocsData], getTocsTitleNodeWarpper(tocsMenus))
|
||||
} else {
|
||||
node.children = tocsData;
|
||||
}
|
||||
node.children.unshift(header(options));
|
||||
node.children.push(footer());
|
||||
node.children.push(anchorPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ body {
|
||||
--color-accent-emphasis: #0969da;
|
||||
--color-attention-subtle: #fff8c5;
|
||||
--color-danger-fg: #cf222e;
|
||||
--box-shadow: 109 109 109;
|
||||
}
|
||||
|
||||
[data-color-mode*='dark'], [data-color-mode*='dark'] body {
|
||||
@ -112,6 +113,7 @@ body {
|
||||
--color-accent-emphasis: #1f6feb;
|
||||
--color-attention-subtle: rgba(187,128,9,0.15);
|
||||
--color-danger-fg: #f85149;
|
||||
--box-shadow: 0 0 0;
|
||||
}
|
||||
|
||||
body {
|
||||
@ -474,6 +476,64 @@ a.text-grey {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3rem;
|
||||
position: relative;
|
||||
}
|
||||
.menu-tocs {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 88;
|
||||
display: inline-flex;
|
||||
}
|
||||
.menu-tocs:hover > .menu-modal {
|
||||
display: block;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.3rem;
|
||||
max-height: 100vh;
|
||||
overflow: auto;
|
||||
background-color: var(--color-canvas-subtle);
|
||||
box-shadow: 0 8px 24px rgba(var(--box-shadow)/0.2);
|
||||
}
|
||||
.menu-tocs > .menu-btn {
|
||||
border: 1px solid var(--color-border-default);
|
||||
display: flex;
|
||||
border-radius: 0.3rem;
|
||||
padding: 0.3rem 0.4rem;
|
||||
font-size: 1.3rem;
|
||||
margin-left: -3rem;
|
||||
margin-top: 0.3rem;
|
||||
position: absolute;
|
||||
}
|
||||
.menu-tocs > .menu-modal {
|
||||
width: 260px;
|
||||
position:absolute;
|
||||
display: none;
|
||||
margin-left: -1rem;
|
||||
}
|
||||
.menu-tocs > .menu-modal a + a {
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.menu-tocs > .menu-modal a:hover {
|
||||
background-color: var(--color-neutral-muted);
|
||||
}
|
||||
.menu-tocs > .menu-modal a.is-active-link {
|
||||
background-color: var(--color-border-muted);
|
||||
text-decoration-color: #10b981;
|
||||
}
|
||||
.menu-tocs > .menu-modal a {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
padding: 0.3rem 0.5rem;
|
||||
}
|
||||
|
||||
.menu-tocs > .menu-modal a.leve2 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.menu-tocs > .menu-modal a.leve3 {
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
.menu-tocs > .menu-modal a.leve4, .menu-tocs > .menu-modal a.leve5, .menu-tocs > .menu-modal a.leve6 {
|
||||
padding-left: 2.1rem;
|
||||
}
|
||||
|
||||
.wrap-header.h2wrap > h2 {
|
||||
|
@ -3,6 +3,7 @@ const scripts = `
|
||||
if(('onhashchange' in window) && ((typeof document.documentMode==='undefined') || document.documentMode==8)) {
|
||||
window.onhashchange = function () {
|
||||
anchorPoint()
|
||||
updateAnchor()
|
||||
};
|
||||
}
|
||||
function anchorPoint() {
|
||||
@ -16,6 +17,26 @@ function anchorPoint() {
|
||||
}
|
||||
}
|
||||
anchorPoint();
|
||||
|
||||
function updateAnchor(element) {
|
||||
const anchorContainer = document.querySelectorAll('.menu-tocs .menu-modal a.tocs-link');
|
||||
anchorContainer.forEach((tocanchor) => {
|
||||
tocanchor.classList.remove('is-active-link');
|
||||
});
|
||||
const anchor = element || document.querySelector(\`a.tocs-link[href='\${decodeURIComponent(window.location.hash)}']\`);
|
||||
console.log('anchor', anchor)
|
||||
if (anchor) {
|
||||
anchor.classList.add('is-active-link');
|
||||
}
|
||||
}
|
||||
// toc 定位
|
||||
updateAnchor()
|
||||
const anchor = document.querySelectorAll('.menu-tocs .menu-modal a.tocs-link');
|
||||
anchor.forEach((item) => {
|
||||
item.addEventListener('click', (e) => {
|
||||
updateAnchor()
|
||||
})
|
||||
})
|
||||
`;
|
||||
|
||||
export function anchorPoint() {
|
||||
|
@ -1,8 +1,11 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import rehypeParse from 'rehype-parse';
|
||||
import {unified} from 'unified';
|
||||
import { VFile } from 'vfile';
|
||||
|
||||
export const ICONS_PATH = path.resolve(process.cwd(), 'scripts/assets')
|
||||
|
||||
export function getSVGNode(iconPath, space = 'svg') {
|
||||
const svgStr = fs.readFileSync(iconPath);
|
||||
const processor = unified().use(rehypeParse,{ fragment: true, space })
|
||||
|
@ -1,5 +1,71 @@
|
||||
import path from 'path';
|
||||
import { panelAddNumber } from './panelAddNumber.mjs';
|
||||
import { getChilds, getHeader } from './childs.mjs';
|
||||
import { ICONS_PATH, getSVGNode } from './getSVGNode.mjs';
|
||||
|
||||
export const titleNum = (tagName = '') => Number(tagName.replace(/^h/, ''));
|
||||
|
||||
export function getTocsTitleNode(arr = [], result = []) {
|
||||
arr.forEach(({ tagName, type, properties, children }) => {
|
||||
if (/^h[23456]/.test(tagName)) {
|
||||
const num = titleNum(tagName)
|
||||
const props = { 'aria-hidden': "true", class: `leve${num} tocs-link`, href: '#' + (properties.id || '') }
|
||||
result.push({ tagName: 'a', type, properties: props, children: (children || []).filter(m => m.type === 'text') })
|
||||
} else if (children?.length > 0) {
|
||||
result = result.concat(getTocsTitleNode(children))
|
||||
}
|
||||
});
|
||||
return result
|
||||
}
|
||||
|
||||
export function addTocsInWarp(tocsData = [], menuData, isDone = false) {
|
||||
const childs = tocsData.map((item) => {
|
||||
if (item.properties?.class?.includes('h1wrap-body')) {
|
||||
isDone = true;
|
||||
}
|
||||
if (!isDone && item.children) {
|
||||
item.children = addTocsInWarp([...item.children], menuData, isDone)
|
||||
}
|
||||
return item
|
||||
});
|
||||
if (isDone) {
|
||||
childs.splice(1, 0, menuData);
|
||||
}
|
||||
return childs
|
||||
}
|
||||
|
||||
export const getTocsTitleNodeWarpper = (children = []) => {
|
||||
const iconPath = path.resolve(ICONS_PATH, `menu.svg`);
|
||||
const svgNode = getSVGNode(iconPath);
|
||||
return {
|
||||
type: 'element',
|
||||
tagName: 'div',
|
||||
properties: {
|
||||
class: 'menu-tocs',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'div',
|
||||
properties: {
|
||||
class: 'menu-btn',
|
||||
},
|
||||
children: [
|
||||
// { type: 'text', value: 'menu' }
|
||||
...svgNode
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'div',
|
||||
properties: {
|
||||
class: 'menu-modal',
|
||||
},
|
||||
children: children
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/** Markdown 文档转成树形结构 */
|
||||
export function getTocsTree(arr = [], result = []) {
|
||||
@ -14,9 +80,7 @@ export function getTocsTree(arr = [], result = []) {
|
||||
if (level === -1) {
|
||||
level = toc.number;
|
||||
}
|
||||
const titleNum = Number(toc.tagName?.replace(/^h/, ''));
|
||||
|
||||
if (toc.number === level && titleNum === level) {
|
||||
if (toc.number === level && titleNum(toc.tagName) === level) {
|
||||
const header = getHeader(data.slice(n), level);
|
||||
const wrapCls = ['wrap'];
|
||||
const headerCls = ['wrap-header', `h${level}wrap`];
|
||||
|
@ -1,8 +1,6 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { getSVGNode } from './getSVGNode.mjs';
|
||||
|
||||
export const ICONS_PATH = path.resolve(process.cwd(), 'scripts/assets')
|
||||
import { getSVGNode, ICONS_PATH } from './getSVGNode.mjs';
|
||||
|
||||
export function homeCardIcons(node, parent, isHome) {
|
||||
if (isHome && node && node.type === 'element' && node.properties?.class?.includes('home-card')) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { getSVGNode } from './getSVGNode.mjs';
|
||||
import { ICONS_PATH } from './homeCardIcons.mjs';
|
||||
import { getSVGNode, ICONS_PATH } from './getSVGNode.mjs';
|
||||
|
||||
export function rehypeTitle(node, iconName) {
|
||||
if (node.type === 'element' && node.tagName === 'h1' && iconName !== 'index') {
|
||||
|
Reference in New Issue
Block a user