Compare commits

..

268 Commits

Author SHA1 Message Date
63739bff97 chore: update workflows config. 2022-11-13 23:26:22 +08:00
a4650ba20b released v1.20.0 2022-11-13 23:25:29 +08:00
304fca65aa feat: add latex.md #47 2022-11-13 23:20:45 +08:00
7dab4bc821 feat: add dart.md #58 2022-11-13 16:19:51 +08:00
a3a03dc5cf doc: add strcut and enum in the rust (#53)
* content: add strcut and enum in the rust

* update

* update
2022-11-13 14:20:13 +08:00
c4027826df doc: modify README.md. 2022-11-13 06:19:40 +00:00
ec5de21ad8 doc: modify CONTRIBUTING.md. 2022-11-13 06:19:39 +00:00
2d29bce40d feat: add php.md #57 2022-11-13 14:18:33 +08:00
45916503c1 doc: update ffmpeg.md #56 2022-11-13 03:53:34 +08:00
7dab833cb5 doc: update quickreference.md. 2022-11-13 03:46:04 +08:00
2787e80dd2 doc: modify README.md. 2022-11-12 18:48:34 +00:00
51377308ab doc: modify CONTRIBUTING.md. 2022-11-12 18:48:34 +00:00
5660ad20dd chore: update contributors. 2022-11-13 02:47:29 +08:00
0917f70be8 doc: add fliter in the ffmpeg (#56) 2022-11-13 00:09:24 +08:00
dcbdaea754 typo: fix typo content in the vim (#52) 2022-11-12 18:01:57 +08:00
144f263ad0 doc: update typescript.md. 2022-11-12 14:28:27 +08:00
ef5a27f5a1 doc: update typescript.md. 2022-11-12 14:26:09 +08:00
82457e896e fix: 修正选择器的真正含义 update css.md (#51) 2022-11-12 12:38:48 +08:00
d796def71c website: update style. 2022-11-12 09:18:22 +08:00
8cb9a8eaa4 doc: update regex.md 2022-11-12 09:17:56 +08:00
739697937d doc: fix error in regex.md 2022-11-12 01:22:29 +08:00
4ce6660ca8 doc: update rust.md #50 #49 2022-11-12 00:53:33 +08:00
5677612d9d doc: add some content in the rust.md (#50) 2022-11-12 00:40:56 +08:00
6d24b1b957 released v1.19.0 2022-11-11 22:53:32 +08:00
72d3bd8d42 doc: update rust.md #48 2022-11-11 17:31:47 +08:00
2d4a9604cf doc: add vec and fix some errors in the rust (#48) 2022-11-11 17:25:02 +08:00
7a22e7cda2 doc: update package.json.md. (#46) 2022-11-11 14:29:17 +08:00
85071d3204 doc: update npm.md 2022-11-11 14:28:31 +08:00
c4694ed832 doc: update package.json.md. (#46) 2022-11-11 13:44:09 +08:00
906cbdd152 doc: add exports in the package.json (#46) 2022-11-11 13:25:07 +08:00
a38f6d8f85 doc: update ffmpeg.md (#18) (#45) 2022-11-11 11:08:00 +08:00
2037e0f6b9 doc: add about ffmpeg's content (#45)
* content: add about ffmpeg's content

* update

* update
2022-11-11 11:00:44 +08:00
bb2cff4f9b chore: update markdownlint config. (#42) 2022-11-11 01:56:28 +08:00
b3c47e2b2d feat: add graphql.md. 2022-11-11 01:53:11 +08:00
5701da6e5b chore: format markdown code. (#42)
* format: fix markdown

* update: fix markdown

* update: fix cron problems

* update: delete .markdownlintignore

* update

* chore: add tab -> 4 space

* chore: fix tab -> 2 in the .editorconfig
2022-11-11 01:51:54 +08:00
ea80136db3 fix: Fix markdown lint command error. (#40 #41) 2022-11-10 13:07:37 +08:00
aa26be4186 chore: fix markdown file automatically (#41)
* update

* update
2022-11-10 12:51:20 +08:00
2b1d33a5db feat: add ruby.md cheatsheet. (#35) 2022-11-10 01:10:23 +08:00
dbf8ac4fb2 chore: solve the use of pnpm not part of the package (#38) 2022-11-09 23:33:40 +08:00
f2f1ef8c52 chore: add the lock file of pnpm and yarn in the .gitignore (#37)
* add the lock file of pnpm and yarn in the .gitignore

* dockerignore
2022-11-09 21:39:24 +08:00
748ed480f4 doc: update systemd.md. 2022-11-09 16:44:52 +08:00
7c2338ea76 website: update style. 2022-11-09 16:24:59 +08:00
90c9fefa51 feat: add systemd.md cheatsheet. (#34) 2022-11-09 15:26:24 +08:00
29f3b971d2 feat: add Tmux.md cheatsheet. (#33) 2022-11-09 14:59:23 +08:00
b2aabe4291 feat: add <red> tag style. 2022-11-09 14:47:22 +08:00
04e6e16a97 doc: update ansible.md (#31) 2022-11-09 11:56:07 +08:00
3db12d6cce doc: update toml.md. 2022-11-09 11:56:07 +08:00
3f0b60187c doc: fix code highlight (#28) 2022-11-09 11:55:55 +08:00
bead2f0e3b doc: update ansible.md (#31)
* update ansible inventory静态分组用法

* Update ansible.md
2022-11-09 11:44:17 +08:00
816f49004f Update ffmpeg.md (#30)
编辑视频剪切部分示例
2022-11-09 11:25:48 +08:00
12b84b8368 doc: Update README.md 2022-11-09 00:40:06 +08:00
56b4b78d7d released v1.18.0 2022-11-09 00:36:52 +08:00
f28c93b918 feat: add jq.md (#27) 2022-11-09 00:26:10 +08:00
0bfe15e4dc feat: add PostgreSQL cheatsheet. (#26) 2022-11-08 14:57:37 +08:00
c1394813bc doc: update README.md (#25) 2022-11-08 13:42:30 +08:00
06c6229cac doc: update css.md. 2022-11-08 11:35:17 +08:00
04dd94d6f8 doc: update cargo.md. 2022-11-08 00:50:27 +08:00
5f19d3feee doc: update ffmpeg.md (#24) 2022-11-07 19:52:29 +08:00
e48fd74c38 doc: update ffmpeg.md. (#24) 2022-11-07 19:50:00 +08:00
7c7f25bf9f released v1.17.0 2022-11-07 18:06:02 +08:00
2dde0c4408 doc: Update npm.md. 2022-11-07 17:40:08 +08:00
a2d7cd6e7b doc: Update npm.md. 2022-11-07 17:36:13 +08:00
10366e3317 doc: update nginx.md. 2022-11-07 16:59:00 +08:00
4bf8a55bf3 chore: add matlab logo. 2022-11-07 16:16:37 +08:00
0101ef71d0 doc: update quickreference.md. 2022-11-07 16:11:49 +08:00
aa38a0e765 doc: update css.md. 2022-11-07 16:04:39 +08:00
4a1eb6964d doc: update yum.md. 2022-11-07 11:40:32 +08:00
f6ff51be15 doc: update cargo.md. 2022-11-07 11:40:13 +08:00
6c89718254 doc: update docker.md. 2022-11-07 09:41:57 +08:00
8c79a648a4 feat: add yum.md cheatsheet. 2022-11-07 01:15:13 +08:00
f021d73b77 doc: update README.md 2022-11-06 23:39:00 +08:00
c060c36559 doc: update curl.md. 2022-11-06 23:25:58 +08:00
39aa2c4387 feat: add xcode.md cheatsheet. 2022-11-06 23:18:12 +08:00
aeca8351bd doc: update ffmpeg.md (#18) 2022-11-06 23:02:37 +08:00
d7d6b0d447 doc: update ffmpeg.md (#18) 2022-11-06 22:49:56 +08:00
4d69a0ef24 doc: update ansible.md (#23) 2022-11-06 22:18:16 +08:00
bafc15d17e released v1.16.0 2022-11-06 22:12:36 +08:00
68069fbf01 doc: Update README.md 2022-11-06 22:11:35 +08:00
ca3cf85666 doc: update README.md (#23) 2022-11-06 22:10:12 +08:00
040af8095f doc: update ansible.md (#23) 2022-11-06 22:07:24 +08:00
d1dea83330 feat: add ansible cheatsheet. (#23) 2022-11-06 20:51:51 +08:00
4503b28837 doc: update cargo.md. 2022-11-05 21:26:39 +08:00
02d0a495a6 feat: add matlab.md cheatsheet (#21). 2022-11-04 21:06:49 +08:00
c66d1c0294 chore: add .dockerignore file. 2022-11-04 13:02:33 +08:00
f2d43d65df website: fix style issue. 2022-11-04 13:02:16 +08:00
009c50760c website: Support math formula display. (#21) 2022-11-04 13:01:39 +08:00
f683ca5294 feat: add cargo cheatsheet. 2022-11-04 00:34:06 +08:00
04369f05d3 doc: update vue.md (#10) 2022-11-03 19:16:33 +08:00
ae04c01eb4 doc: update quickreference.md. 2022-11-03 16:51:53 +08:00
e66c1c57fd feat: add rust.md cheatsheet (#20). 2022-11-03 15:32:56 +08:00
c7df917009 feat: add conan.md cheatsheet. 2022-11-03 13:33:02 +08:00
a5744c23b7 doc: update README.md 2022-11-03 11:49:39 +08:00
d8ab87b0e0 feat: add default prompt changes. 2022-11-03 11:49:21 +08:00
e87ce59a88 doc: update sed.md. 2022-11-03 11:03:44 +08:00
428d8488f3 doc: update vue.md (#10). 2022-11-03 10:26:24 +08:00
e84c69f8b9 website: update style. 2022-11-03 01:20:38 +08:00
3cdc2685e6 doc: update vue.md (#10). 2022-11-03 01:09:38 +08:00
df3e04ba92 doc: update vue.md (#10). 2022-11-03 01:08:45 +08:00
4662fb8071 feat: add cmake.md cheatsheet (#19). 2022-11-03 00:27:39 +08:00
600dbc6fef feat: add gmail.md cheatsheet. 2022-11-02 23:23:20 +08:00
559fd4bd12 released v1.15.0 2022-11-02 22:19:21 +08:00
05be6476ca doc: update ffmpeg.md (#18). 2022-11-02 22:07:01 +08:00
75a0acfc5d doc: update ffmpeg.md (#18). 2022-11-02 22:03:00 +08:00
40d15647e0 doc: update ffmpeg.md (#18). 2022-11-02 21:55:42 +08:00
f19dcdf8c4 feat: add ffmpeg.md cheatsheet (#18). 2022-11-02 21:16:11 +08:00
b5f2969044 feat: add emacs.md. 2022-11-02 19:46:55 +08:00
4311bd4ed8 doc: update docker.md (#13). 2022-11-02 16:43:57 +08:00
c049ca33c4 doc: update docker.md (#13). 2022-11-02 16:36:26 +08:00
3d2c9cd978 chore: add python logo. (#13) 2022-11-02 16:32:30 +08:00
80fa7c64c3 feat: add python.md cheatsheet (#13). 2022-11-02 16:06:48 +08:00
2fbf2151b6 doc: update docker.md. 2022-11-02 13:21:08 +08:00
115a7215a5 chore: update cheatsheet-request.md. 2022-11-02 09:38:39 +08:00
a24cf740e2 doc: update README.md. 2022-11-02 01:42:17 +08:00
bd3839f648 doc: update CONTRIBUTING.md. 2022-11-02 01:41:57 +08:00
6f2da75d94 doc: update golang.md. 2022-11-02 00:26:04 +08:00
ffe4293418 doc: update quickreference.md. 2022-11-01 23:11:51 +08:00
af19ee8a8d chore: update cheatsheet-request.md. 2022-11-01 23:02:31 +08:00
a52d7d4b15 doc: update djiango.md (#16) 2022-11-01 22:46:23 +08:00
b63edf46f8 doc: update djiango.md (#16) 2022-11-01 22:24:45 +08:00
4caec0d065 feat: add djiango.md cheatsheet (#16). 2022-11-01 21:22:20 +08:00
6d602f3e89 doc: update git.md. 2022-11-01 16:35:25 +08:00
ff9d38de17 doc: update git.md. (#15) 2022-11-01 16:13:55 +08:00
ca5ddf74a0 doc: Update git.md 2022-11-01 14:34:49 +08:00
5c0f89908e doc: Update git.md 2022-11-01 14:33:46 +08:00
0fde136208 doc: Update git.md 2022-11-01 14:31:51 +08:00
8438b91448 doc: update yarn.md. 2022-11-01 10:03:14 +08:00
075b69e9ed doc: Update npm.md. 2022-11-01 09:58:29 +08:00
f14ae527b0 feat: add yarn.md cheatsheet. 2022-11-01 01:28:00 +08:00
4f68d94311 released v1.14.0 2022-11-01 00:40:33 +08:00
10d7679216 website: udpate style. 2022-11-01 00:40:00 +08:00
516ff9af69 website: update style. 2022-11-01 00:23:50 +08:00
a9896a265f feat: add java.md cheatsheet. (#12) 2022-11-01 00:20:36 +08:00
5f533d8332 chore: update issue template. (#12) 2022-10-31 16:40:12 +08:00
f60826e6da website: adjust the layout. 2022-10-31 16:38:04 +08:00
b258494776 feat: add es6.md cheatsheet. 2022-10-31 15:18:50 +08:00
8586f8a212 fix: fix show number line issue. 2022-10-31 09:45:21 +08:00
f8a706064a fix: fix show number line issue. 2022-10-31 09:25:55 +08:00
48b5d0fba3 released v1.13.0 2022-10-31 00:17:26 +08:00
18b276097d doc: update awk.md. 2022-10-31 00:16:43 +08:00
333891b7c3 doc: update awk.md. 2022-10-31 00:14:50 +08:00
e145ecc715 doc: update awk.md. 2022-10-31 00:11:50 +08:00
1e4b812bc3 doc: update awk.md. 2022-10-31 00:11:04 +08:00
909527deec feat: add awk.md cheatsheet. 2022-10-31 00:10:06 +08:00
ce02da885e doc: update css.md. 2022-10-30 23:13:21 +08:00
fb464bd4ff doc: update css.md. 2022-10-30 23:10:39 +08:00
9a2b43372a style: update website style. 2022-10-30 21:45:22 +08:00
42130cf58e released v1.12.0 2022-10-30 21:39:56 +08:00
cbc94665a5 feat: add mime.md cheatsheet. 2022-10-30 21:36:12 +08:00
2c808c7c8d feat: add iso-639-1.md cheatsheet. 2022-10-30 18:52:35 +08:00
6aa07fc077 doc: update lsof.md. 2022-10-30 17:24:27 +08:00
444f0d850c feat: update lsof.md cheatsheet. 2022-10-30 03:10:42 +08:00
8f087e03ff feat: add lsof.md cheatsheet. 2022-10-30 03:06:45 +08:00
37c9f23952 released v1.11.1 2022-10-30 02:15:36 +08:00
cb704eed88 fix: fix preview html meta issue. 2022-10-30 02:14:38 +08:00
75fece7aab feat: add vue.md cheatsheet. (#10) 2022-10-30 01:44:38 +08:00
3966175a39 doc: Update npm.md. 2022-10-30 00:54:02 +08:00
0c03059cde doc: Fix npm access public [<package>] 公开包 (#11) 2022-10-29 23:32:35 +08:00
efae1dc846 doc: add mysql.md cheatsheet. 2022-10-29 01:33:05 +08:00
4132a13a96 chore: format script code. 2022-10-29 00:24:39 +08:00
bd082908d8 released v1.11.0 (#9) 2022-10-28 22:09:23 +08:00
dd8a3cb26d feat: add tocs feature & fix page element generation issue (#9). 2022-10-28 22:07:12 +08:00
6d0801a9da chore: update CONTRIBUTING.md. 2022-10-28 13:54:09 +08:00
6290b9eae0 doc: Correct the anchor(http-status-code) (#8) 2022-10-28 13:05:55 +08:00
9479626194 doc: update docs/github-actions.md. 2022-10-28 11:57:50 +08:00
ad4b2e9119 doc: Update README.md 2022-10-28 11:14:16 +08:00
d48341cecb chore: update CONTRIBUTING.md. 2022-10-28 11:14:16 +08:00
5aec989c14 chore: update issue template. 2022-10-28 11:14:16 +08:00
13492fe556 docs(http-status-code): md '_' conversion error (#7) 2022-10-28 11:12:33 +08:00
d145aaa0b0 doc: update semver.md. 2022-10-27 17:33:07 +08:00
531c01d62e doc: update homebrew.md. 2022-10-27 13:13:45 +08:00
0a160d22d8 doc: Update README.md 2022-10-26 10:12:18 +08:00
0a070e996c released v1.10.0 2022-10-25 17:33:47 +08:00
54faf5c19c doc: update ini.md. 2022-10-25 17:32:34 +08:00
09f57d1848 feat: add ini.md cheatsheet. 2022-10-25 17:03:30 +08:00
f875a335e1 feat: add swiftui.md cheatsheet. 2022-10-25 14:47:18 +08:00
b743110c9d doc: update toml.md. 2022-10-24 16:43:32 +08:00
d1c9871504 released v1.9.0 2022-10-23 22:48:23 +08:00
a478fbb888 feat: HTML code preview is supported in markdown. 2022-10-23 22:27:07 +08:00
fdcfcb287b feat: quickreference add auto-wrap class. 2022-10-22 22:37:46 +08:00
3003e3db66 doc: update chmod.md. 2022-10-22 15:59:49 +08:00
ca1f5ad470 doc: update chmod.md. 2022-10-22 15:57:01 +08:00
d0d371b165 doc: update README.md. 2022-10-22 02:14:16 +08:00
54b7faee00 doc: add contributing info. 2022-10-22 02:11:55 +08:00
8d7cc05f4d released v1.8.0 2022-10-22 01:58:05 +08:00
4498add1f2 doc: update resolutions.md. 2022-10-22 01:57:38 +08:00
6c8e56ad61 feat: add resolutions.md cheatsheet. 2022-10-22 01:43:33 +08:00
ef976825e4 feat: add netcat.svg cheatsheet. 2022-10-22 00:33:16 +08:00
9d3a061bff feat: add netstat.md cheatsheet. 2022-10-21 23:49:09 +08:00
cd1be27fae doc: update sass.md. 2022-10-21 17:38:46 +08:00
9774884614 feat: add sass.md cheatsheet. 2022-10-21 17:36:31 +08:00
c357f95bf0 doc: update github-actions.md. 2022-10-21 14:50:10 +08:00
b37c268882 released v1.7.0 2022-10-20 18:00:41 +08:00
7edba8e207 feat: add stylus.md cheatsheet. 2022-10-20 17:52:33 +08:00
efbd007801 doc: update lessjs.md. 2022-10-20 16:15:50 +08:00
f01c001040 feat: add lessjs.md cheatsheet. 2022-10-20 16:13:16 +08:00
727d47725f released v1.6.0 2022-10-19 23:44:50 +08:00
4e764197c7 feat: add github-actions.md cheatsheet. 2022-10-19 23:38:12 +08:00
64400ea686 style: update home page. 2022-10-19 19:34:59 +08:00
a540fb7fd9 feat: add homebrew.md sheatsheet. 2022-10-19 16:26:54 +08:00
71d2bfce9a doc: update curl.md. 2022-10-19 00:02:18 +08:00
5685eb285a feat: add koajs.md sheatsheet. 2022-10-18 23:36:25 +08:00
227a7a7149 style: update website style. 2022-10-18 21:40:24 +08:00
a7c1d81698 style: update website style. 2022-10-18 21:38:31 +08:00
e876e96430 feat: add curl.md sheatsheet. 2022-10-18 18:21:17 +08:00
cb5f742608 feat: add expressjs.md. 2022-10-18 17:11:30 +08:00
fc04f53b36 released v1.5.0 2022-10-18 01:23:26 +08:00
2303f3143f doc: update colors-named.md. 2022-10-18 01:22:06 +08:00
6e10f42d0d feat: add colors-named.md. 2022-10-18 01:07:41 +08:00
d6a7ca3d7f doc: update webstorm.md. 2022-10-17 23:55:57 +08:00
90e7f14e78 doc: update swift.md. 2022-10-17 23:35:48 +08:00
bc0868020a doc: update javascript.md. 2022-10-17 23:25:30 +08:00
2175ce6241 feat: add swift.md. 2022-10-17 19:45:37 +08:00
46fb45e643 released v1.4.0 2022-10-16 03:40:54 +08:00
3ec4dc496a doc: update README.md. 2022-10-16 03:39:58 +08:00
19caaad574 feat: add golang.md sheatsheet. 2022-10-16 03:35:13 +08:00
4122b48f76 website: add anchor positioning style. 2022-10-16 02:22:53 +08:00
57e41a7fd6 released v1.3.0 2022-10-16 01:25:11 +08:00
9832aea099 feat: add css.md cheatsheet. 2022-10-16 01:21:33 +08:00
dcb0c1667c chore: update package.json. 2022-10-15 13:33:34 +08:00
25a9ba86fa doc: update docs/lerna.md. 2022-10-15 13:32:34 +08:00
cadc7dad14 website: title auto add icon. 2022-10-15 13:32:12 +08:00
a24f6a91a4 doc: update lerna.md. 2022-10-15 12:36:02 +08:00
0f091beebd website: update website style. 2022-10-14 18:04:45 +08:00
2c276e72ac feat: add lerna.md cheatsheet. 2022-10-14 18:02:55 +08:00
313df63ce2 website: add ul.style-arrow style. 2022-10-14 17:57:54 +08:00
9e3b2b913f feat(build): add style-list-arrow className. 2022-10-14 16:30:07 +08:00
ce71a63350 doc: update package.json.md. 2022-10-14 11:07:10 +08:00
96c50ca289 doc: Update README.md 2022-10-13 18:00:38 +08:00
4460aa9246 doc: update docs/c.md 2022-10-13 16:40:26 +08:00
877a763274 doc: update docs/c.md. 2022-10-13 16:31:20 +08:00
15c899a89f doc: update docs/c.md. 2022-10-13 16:15:18 +08:00
4275ee8ace doc: update http-status-code.md. 2022-10-13 14:41:23 +08:00
7db4389708 feat: add c.md cheatsheet. 2022-10-13 01:19:47 +08:00
3b8415f692 chore: update workflows config. 2022-10-12 21:43:05 +08:00
6baf60a095 doc: update docker.md. 2022-10-12 17:23:53 +08:00
489f29bb14 feat: add htop.md cheatsheet. 2022-10-12 17:09:52 +08:00
1dad75e9b2 doc: update README.md 2022-10-12 15:04:18 +08:00
bf286ba518 released v1.2.0 2022-10-12 15:00:59 +08:00
fb96ea19c5 chore: update workflows config. 2022-10-12 14:59:35 +08:00
03a4241228 feat: add html.md cheatsheet. 2022-10-12 14:56:55 +08:00
c661cfa852 doc: update . (#5) 2022-10-12 10:31:35 +08:00
31df164656 doc: update vue2.md. (#5) 2022-10-11 16:39:10 +08:00
327e35baf7 doc: update quickreference.md. 2022-10-11 15:00:30 +08:00
518249913e doc: update vue2.md. (#5) 2022-10-11 14:50:42 +08:00
078df00bf5 doc: update vue2.md. (#5) 2022-10-11 11:13:35 +08:00
79b5f6da26 doc: update vue2.md. (#5) 2022-10-11 09:39:47 +08:00
878990a290 doc: update vue2.md. (#5) 2022-10-11 09:09:15 +08:00
f55c4219c4 doc: update vue2.md. (#5) 2022-10-11 00:51:54 +08:00
502aa0ab15 doc: update vue2.md. (#5) 2022-10-11 00:31:09 +08:00
81001e2594 doc: update vue2.md. (#5) 2022-10-11 00:15:31 +08:00
da18c16d26 doc: update vue2.md. (#5) 2022-10-11 00:03:13 +08:00
9168e56f39 feat: add vue2.md cheatsheet. 2022-10-10 23:16:24 +08:00
32f0936c36 feat: add grep.md cheatsheet. 2022-10-10 21:48:53 +08:00
9cf8737419 feat: add screen.md cheatsheet. 2022-10-10 21:22:44 +08:00
d903719a33 feat: add quickreference.md cheatsheet. 2022-10-09 21:27:49 +08:00
593662f3c6 doc: Update react.md. 2022-10-09 00:56:32 +08:00
a5ec6ff25c released v1.1.0 2022-10-09 00:48:45 +08:00
a34e5372fe website: update home page style. 2022-10-09 00:47:39 +08:00
b0eb01e566 website: update home page style. 2022-10-09 00:39:30 +08:00
2fcd80f34d feat: add styled-components.md cheatsheet. 2022-10-08 23:55:59 +08:00
6eb1ef3260 doc: update nginx.md cheatsheet. 2022-10-08 13:01:45 +08:00
1ee5910d86 doc: update jest.md 2022-10-08 03:44:42 +08:00
c221cd1ac3 feat: add nginx.md cheatsheet. 2022-10-08 03:18:36 +08:00
f1d7c9e585 doc: update docker.md. 2022-10-07 01:35:14 +08:00
f13778aa5a feat: add yaml.md cheatsheet. 2022-10-07 01:18:23 +08:00
45a20dd749 feat: add emmet.md cheatsheet. 2022-10-07 00:48:40 +08:00
c19283b71f feat: add sublime-text.md cheatsheet. 2022-10-06 21:10:45 +08:00
9a5e90d6e6 feat: update quickreference.md. 2022-10-06 12:10:56 +08:00
237 changed files with 46157 additions and 1051 deletions

27
.dockerignore Normal file
View File

@ -0,0 +1,27 @@
.github
.husky
docs
scripts
node_modules
package-lock.json
pnpm-lock.yaml
yarn.lock
.DS_Store
.cache
.vscode
.idea
.snap
.env
*.bak
*.tem
*.temp
#.swp
*.*~
~*.*
# IDEA
*.iml
*.ipr
*.iws

7
.editorconfig Normal file
View File

@ -0,0 +1,7 @@
root = true
[./docs/*.md]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true

View File

@ -1,25 +1,24 @@
---
name: 🤙 备忘单请求
about: 请求添加备忘单和参考。
title: '备忘清单 请求: '
name: 🤙 备忘单请求
about: 请求添加备忘单和参考。
title: '请求添加备忘清单: '
labels: request
assignees: jaywcjlove
---
备忘清单标题 备忘清单
===
这是您可以在 Quick Reference 备忘清单上使用的参考!【备忘清单介绍】
您可以在这里简单的提供一些资料,方便我们在 Quick Reference 中添加您想添加的备忘清单(速查表)。
入门
---
【请您在这里介绍一下工具或者语言,这很重要】
### 卡片 1
- [ ] 如果你有一张不错的备忘清单(速查表) [`参考这里`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 为仓库贡献。
- [ ] 如果您不方便贡献,请在下方参考资料中提供链接地址,方便共建备忘清单(速查表)
- [x] 这里为您提供了 Markdown 排版[示例教程](https://jaywcjlove.github.io/reference/docs/quickreference.html)
### 卡片 2
#### 提供参考资料地址
### 卡片 3
提供更多参考资料有助于我们整理成备忘清单(速查表)
另见
----
- 提供参考地址 https://jaywcjlove.github.io/reference
- 提供官网地址 https://jaywcjlove.github.io/reference
- [参考地址](https://xxx.com)
_⚠ 注意: 随着内容越来越多可能甚至找不到这个工具或者语言的官网请您在这里提供以便大家共同参与贡献内容_

View File

@ -16,6 +16,28 @@ jobs:
- run: npm install
- run: npm run build
- name: Generate Contributors Images
uses: jaywcjlove/github-action-contributors@main
id: contributors
with:
filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\])
output: dist/CONTRIBUTORS.svg
avatarSize: 42
- name: Modify CONTRIBUTING.md
uses: jaywcjlove/github-action-modify-file-content@main
with:
path: CONTRIBUTING.md
body: |
${{steps.contributors.outputs.htmlTable}}
- name: Modify README.md
uses: jaywcjlove/github-action-modify-file-content@main
with:
path: README.md
body: |
${{steps.contributors.outputs.htmlList}}
- name: Create Tag
id: create_tag
uses: jaywcjlove/create-tag-action@main
@ -45,8 +67,8 @@ jobs:
name: ${{ steps.create_tag.outputs.version }}
tag: ${{ steps.create_tag.outputs.version }}
body: |
${{ steps.changelog.outputs.compareurl }}
Documentation ${{ needs.build.outputs.create_tag_version }}: https://raw.githack.com/jaywcjlove/reference/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html
Comparing Changes: ${{ steps.changelog.outputs.compareurl }}
${{ steps.changelog.outputs.changelog }}

2
.gitignore vendored
View File

@ -2,6 +2,8 @@ build
dist
node_modules
package-lock.json
pnpm-lock.yaml
yarn.lock
.DS_Store
.cache

4
.husky/pre-commit Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install lint-staged

4
.lintstagedrc Normal file
View File

@ -0,0 +1,4 @@
{
"**/*.{mjs,css,json,prettierrc,lintstagedrc}": ["prettier --write"],
"./docs/*.md": ["npx markdownlint-cli --fix ./docs"]
}

12
.markdownlint.json Normal file
View File

@ -0,0 +1,12 @@
{
"MD003": false,
"MD013": false,
"MD014": false,
"MD024": false,
"MD033": false,
"MD040": false,
"MD010": {
"code_blocks": true,
"spaces_per_tab": 2
}
}

5
.prettierignore Normal file
View File

@ -0,0 +1,5 @@
package.json
coverage
dist
build
docs

9
.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120,
"overrides": [
{ "files": ".prettierrc", "options": { "parser": "json" } },
{ "files": ".lintstagedrc", "options": { "parser": "json" } }
]
}

View File

@ -14,11 +14,31 @@ Contributing 贡献
这是您可以在 Quick Reference 备忘清单上使用的样式参考!【备忘清单介绍】
```
只需要 `标题<h1>``介绍`(标题下面)。脚本会自动识别,通过 GitHub Actions 自动发布 [`Quick Reference`](https://jaywcjlove.github.io/reference) 网站。
只需要 `标题<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
[`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,10 +54,78 @@ 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"`
### 提示配置
```markdown
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing-->
```
添加 `contributing` 类名,会在卡片下方添加 _`👆待完善需要您的参与`_,添加 `data-info=👆看看还缺点儿什么?`,更换默认提示文本。
```markdown
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=tag&data-lang=Python-->
```
添加 `class=tag&data-lang=Python` 类名和参数,会在卡片右上角标记 _`Python`_
## 本地开发
```bash
npm i # 安装依赖
npm run build # 编译输出 HTML
npm run start # 监听 md 文件编译输出 HTML
```
```
或者你也可以使用 `pnpm` 或者 `yarn` 做为包管理器
## 贡献
请参阅[贡献指南](./CONTRIBUTING.md)了解如何开始。一如既往,感谢我们出色的贡献者!
<!--GAMFC--><a href="https://github.com/jaywcjlove" title="小弟调调™">
<img src="https://avatars.githubusercontent.com/u/1680273?v=4" width="42;" alt="小弟调调™"/>
</a>
<a href="https://github.com/Jack-Zhang-1314" title="fw_qaq">
<img src="https://avatars.githubusercontent.com/u/82551626?v=4" width="42;" alt="fw_qaq"/>
</a>
<a href="https://github.com/catcto" title="喵仙人">
<img src="https://avatars.githubusercontent.com/u/5467932?v=4" width="42;" alt="喵仙人"/>
</a>
<a href="https://github.com/demigodliu" title="DemigodLiu">
<img src="https://avatars.githubusercontent.com/u/30372735?v=4" width="42;" alt="DemigodLiu"/>
</a>
<a href="https://github.com/JetSquirrel" title="JetSquirrel">
<img src="https://avatars.githubusercontent.com/u/20291255?v=4" width="42;" alt="JetSquirrel"/>
</a>
<a href="https://github.com/gaoxiaoduan" title="coderduan">
<img src="https://avatars.githubusercontent.com/u/69953511?v=4" width="42;" alt="coderduan"/>
</a>
<a href="https://github.com/hweining" title="hweining">
<img src="https://avatars.githubusercontent.com/u/8973985?v=4" width="42;" alt="hweining"/>
</a>
<a href="https://github.com/liliangrong777" title="liliangrong777">
<img src="https://avatars.githubusercontent.com/u/58727146?v=4" width="42;" alt="liliangrong777"/>
</a>
<a href="https://github.com/onewesong" title="onewesong">
<img src="https://avatars.githubusercontent.com/u/17920822?v=4" width="42;" alt="onewesong"/>
</a>
<a href="https://github.com/ryanhex53" title="ryanhex53">
<img src="https://avatars.githubusercontent.com/u/360426?v=4" width="42;" alt="ryanhex53"/>
</a>
<a href="https://github.com/zxx-457" title="zxx-457">
<img src="https://avatars.githubusercontent.com/u/114141362?v=4" width="42;" alt="zxx-457"/>
</a><!--GAMFC-END-->
上图贡献者列表,由 [contributors](https://github.com/jaywcjlove/github-action-contributors) 自动生成贡献者图片。
## License
MIT © [Kenny Wong](https://github.com/jaywcjlove)

173
README.md
View File

@ -8,52 +8,138 @@ Quick Reference
[![Docker Pulls](https://img.shields.io/docker/pulls/wcjiang/reference)](https://hub.docker.com/r/wcjiang/reference)
<!--rehype:ignore:end-->
为开发人员分享快速参考备忘清单(主要是方便自己),在看到 [Reference](https://github.com/Randy8080/reference) 快速参考备忘单,感觉非常简单,造轮子使命感突然来了,造个中文版本的,为了方便自己的技术栈查阅,立马撸起来 :)。
<!--rehype:ignore:start-->
[![Quick Reference](https://user-images.githubusercontent.com/1680273/200623638-280ac85b-0cfa-4c60-bae3-ae14231acc6f.png)](https://jaywcjlove.github.io/reference)
<!--rehype:ignore:end-->
如果您发现此处的备忘单不合适,您可以通过提交 [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) 来修复它或提供更好的备忘清单,只针对【中文】用户。以下是开源天使提供的一些备忘清单和快速参考 :)。
## 正在建设中...
坑已挖,需要您的参与完善和贡献!🙏
<!--rehype:style=padding-bottom: 23px;-->
[Ansible](./docs/ansible.md)<!--rehype:style=background: rgb(238 0 0/var(\-\-bg\-opacity));&class=contributing tag&data-lang=RedHad&data-info=👆看看还缺点儿什么?-->
[CMake](./docs/cmake.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));&class=contributing-->
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing tag&data-lang=Python-->
[FFmpeg](./docs/ffmpeg.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));&class=contributing-->
[LaTeX](./docs/latex.md)<!--rehype:style=background: rgb(0 128 128/var(\-\-bg\-opacity));&class=contributing-->
[MATLAB](./docs/matlab.md)<!--rehype:style=background: rgb(0 118 168/var(\-\-bg\-opacity));&class=contributing-->
[Vue 3 ](./docs/vue.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));&class=contributing-->
<!--rehype:class=home-card-->
## 编程
[Bash](./docs/bash.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
[C](./docs/c.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));-->
[Dart](./docs/dart.md)<!--rehype:style=background: rgb(64 196 255/var(\-\-bg\-opacity));-->
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
[JavaScript](./docs/javascript.md)<!--rehype:style=background: rgb(203 183 31/var(\-\-bg\-opacity));-->
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));&class=tag&data-lang=Docker-->
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing tag&data-lang=Python-->
[Golang](./docs/golang.md)<!--rehype:style=background: rgb(39 160 193/var(\-\-bg\-opacity));-->
[GraphQL](./docs/graphql.md)<!--rehype:style=background: rgb(214 66 146/var(\-\-bg\-opacity));-->
[INI](./docs/ini.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
[JSON](./docs/json.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173/var(\-\-bg\-opacity));-->
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
[Java](./docs/java.md)<!--rehype:style=background: rgb(211 55 49/var(\-\-bg\-opacity));&class=contributing&data-info=👆看看还缺点儿什么?-->
[LaTeX](./docs/latex.md)<!--rehype:style=background: rgb(0 128 128/var(\-\-bg\-opacity));&class=contributing-->
[Markdown](./docs/markdown.md)<!--rehype:style=background: rgb(103 61 156/var(\-\-bg\-opacity));-->
[TypeScript](./docs/typescript.md)<!--rehype:style=background: rgb(49 120 198/var(\-\-bg\-opacity));-->
[MySQL](./docs/mysql.md)<!--rehype:style=background: rgb(1 117 143/var(\-\-bg\-opacity));&class=tag&data-lang=SQL-->
[MATLAB](./docs/matlab.md)<!--rehype:style=background: rgb(0 118 168/var(\-\-bg\-opacity));&class=contributing-->
[PHP](./docs/php.md)<!--rehype:style=background: rgb(79 91 147/var(\-\-bg\-opacity));-->
[Python](./docs/python.md)<!--rehype:style=background: rgb(43 91 132/var(\-\-bg\-opacity));-->
[PostgreSQL](./docs/postgres.md)<!--rehype:style=background: rgb(43 109 163/var(\-\-bg\-opacity));&class=tag&data-lang=SQL-->
[Ruby](./docs/ruby.md)<!--rehype:style=background: rgb(204 52 45/var(\-\-bg\-opacity));-->
[Rust](./docs/rust.md)<!--rehype:style=background: rgb(71 71 71/var(\-\-bg\-opacity));-->
[Swift](./docs/swift.md)<!--rehype:style=background: rgb(240 81 57/var(\-\-bg\-opacity));-->
[SwiftUI](./docs/swiftui.md)<!--rehype:style=background: rgb(10 127 247/var(\-\-bg\-opacity));&class=tag&data-lang=swift-->
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
[YAML](./docs/yaml.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
<!--rehype:class=home-card-->
## 工具包
## 前端
[CSS 3](./docs/css.md)<!--rehype:style=background: rgb(35 115 205/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
[Electron](./docs/electron.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
[Emmet](./docs/emmet.md)<!--rehype:style=background: rgb(122 203 23/var(\-\-bg\-opacity));-->
[ES 6](./docs/es6.md)<!--rehype:style=background: rgb(122 203 23/var(\-\-bg\-opacity));&class=tag&data-lang=JS-->
[Styled Components](./docs/styled-components.md)<!--rehype:style=background: rgb(221 60 184/var(\-\-bg\-opacity));-->
[Stylus](./docs/stylus.md)<!--rehype:style=background: rgb(109 161 63/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
[Sass](./docs/sass.md)<!--rehype:style=background: rgb(207 100 154/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
[HTML](./docs/html.md)<!--rehype:style=background: rgb(228 77 39/var(\-\-bg\-opacity));-->
[JavaScript](./docs/javascript.md)<!--rehype:style=background: rgb(203 183 31/var(\-\-bg\-opacity));-->
[Less.js](./docs/lessjs.md)<!--rehype:style=background: rgb(29 54 93/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173/var(\-\-bg\-opacity));-->
[RegEx 正则表达式](./docs/regex.md)<!--rehype:style=background: rgb(149 36 155/var(\-\-bg\-opacity));-->
[TypeScript](./docs/typescript.md)<!--rehype:style=background: rgb(49 120 198/var(\-\-bg\-opacity));-->
[Vue 2](./docs/vue2.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));-->
[Vue 3 ](./docs/vue.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));&class=contributing-->
<!--rehype:class=home-card-->
## Nodejs
[Express.js](./docs/expressjs.md)<!--rehype:style=background: rgb(95 151 206/var(\-\-bg\-opacity));-->
[Jest](./docs/jest.md)<!--rehype:style=background: rgb(153 66 91/var(\-\-bg\-opacity));-->
[Koa.js](./docs/koajs.md)<!--rehype:style=background: rgb(95 151 206/var(\-\-bg\-opacity));-->
[Lerna](./docs/lerna.md)<!--rehype:style=background: rgb(192 132 252/var(\-\-bg\-opacity));-->
[npm](./docs/npm.md)<!--rehype:style=background: rgb(203 2 0/var(\-\-bg\-opacity));-->
[package.json](./docs/package.json.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
[Semver](./docs/semver.md)<!--rehype:style=background: rgb(106 111 141/var(\-\-bg\-opacity));-->
[Sketch](./docs/sketch.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));-->
[Jest](./docs/jest.md)<!--rehype:style=background: rgb(153 66 91/var(\-\-bg\-opacity));-->
[RegEx](./docs/regex.md)<!--rehype:style=background: rgb(149 36 155/var(\-\-bg\-opacity));-->
[VSCode](./docs/vscode.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
[Vim](./docs/vim.md)<!--rehype:style=background: rgb(9 150 8/var(\-\-bg\-opacity));-->
[XPath](./docs/xpath.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
[Yarn](./docs/yarn.md)<!--rehype:style=background: rgb(33 136 182/var(\-\-bg\-opacity));-->
<!--rehype:class=home-card-->
## Linux 命令
## 工具
[Chmod](./docs/chmod.md)<!--rehype:style=background: rgb(239 68 113/var(\-\-bg\-opacity));-->
[Emacs](./docs/emacs.md)<!--rehype:style=background: rgb(98 36 134/var(\-\-bg\-opacity));-->
[Gmail](./docs/gmail.md)<!--rehype:style=background: rgb(234 67 54/var(\-\-bg\-opacity));-->
[nginx](./docs/nginx.md)<!--rehype:style=background: rgb(0 153 0/var(\-\-bg\-opacity));-->
[Semver](./docs/semver.md)<!--rehype:style=background: rgb(106 111 141/var(\-\-bg\-opacity));-->
[Sketch](./docs/sketch.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));&class=tag&data-lang=macOS-->
[Sublime Text](./docs/sublime-text.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));-->
[VSCode](./docs/vscode.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
[Vim](./docs/vim.md)<!--rehype:style=background: rgb(9 150 8/var(\-\-bg\-opacity));-->
[WebStorm](./docs/webstorm.md)<!--rehype:style=background: rgb(32 148 220/var(\-\-bg\-opacity));-->
[XPath](./docs/xpath.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
[Xcode](./docs/xcode.md)<!--rehype:style=background: rgb(24 151 233/var(\-\-bg\-opacity));&class=tag&data-lang=macOS-->
<!--rehype:class=home-card-->
## 命令
[Ansible](./docs/ansible.md)<!--rehype:style=background: rgb(238 0 0/var(\-\-bg\-opacity));&class=contributing tag&data-lang=RedHad&data-info=👆看看还缺点儿什么?-->
[Awk](./docs/awk.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Conan](./docs/conan.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));&class=tag&data-lang=C/C++-->
[Cargo](./docs/cargo.md)<!--rehype:style=background: rgb(71 71 71/var(\-\-bg\-opacity));&class=tag&data-lang=Rust-->
[Curl](./docs/curl.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Chmod](./docs/chmod.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Cron](./docs/cron.md)<!--rehype:style=background: rgb(239 68 68/var(\-\-bg\-opacity));-->
[CMake](./docs/cmake.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));&class=contributing-->
[Git](./docs/git.md)<!--rehype:style=background: rgb(215 89 62/var(\-\-bg\-opacity));-->
[find](./docs/find.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Grep](./docs/grep.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Find](./docs/find.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[FFmpeg](./docs/ffmpeg.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));&class=contributing-->
[Htop](./docs/htop.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Home Brew](./docs/homebrew.md)<!--rehype:style=background: rgb(252 185 87/var(\-\-bg\-opacity));&class=tag&data-lang=macOS-->
[Netstat](./docs/netstat.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[jq](./docs/jq.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=JSON-->
[Lsof](./docs/lsof.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Netcat](./docs/netcat.md)<!--rehype:style=background: rgb(4 92 135/var(\-\-bg\-opacity));-->
[Sed](./docs/sed.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Systemd](./docs/systemd.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[SSH](./docs/ssh.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
[Screen](./docs/screen.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
[Tmux](./docs/tmux.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
[YUM](./docs/yum.md)<!--rehype:style=background: rgb(86 86 123/var(\-\-bg\-opacity));-->
<!--rehype:class=home-card-->
## 其它
[Quick Reference](./docs/quickreference.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Quick Reference](./docs/quickreference.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=排版说明-->
[Github Actions](./docs/github-actions.md)<!--rehype:style=background: rgb(121 184 255/var(\-\-bg\-opacity));-->
[Colors Named](./docs/colors-named.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
[HTTP 状态码](./docs/http-status-code.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[HTML 字符实体](./docs/html-char.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[HTML 字符实体](./docs/html-char.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=HTML-->
[ISO 639-1 Language Code](./docs/iso-639-1.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Emoji](./docs/emoji.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[MIME types](./docs/mime.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
[Resolutions](./docs/resolutions.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
<!--rehype:class=home-card-->
## 看到缺少什么了吗?
@ -61,10 +147,53 @@ 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:wrap-style=text-align: center;max-width: 650px;margin: 0 auto;&class=home-title-reset-->
请参阅 [Quick Reference](./docs/quickreference.md) 了解如何开始。一如既往,感谢我们出色的贡献者!
<!--rehype:style=padding-bottom:1rem;-->
<!--GAMFC--><a href="https://github.com/jaywcjlove" title="小弟调调™">
<img src="https://avatars.githubusercontent.com/u/1680273?v=4" width="42;" alt="小弟调调™"/>
</a>
<a href="https://github.com/Jack-Zhang-1314" title="fw_qaq">
<img src="https://avatars.githubusercontent.com/u/82551626?v=4" width="42;" alt="fw_qaq"/>
</a>
<a href="https://github.com/catcto" title="喵仙人">
<img src="https://avatars.githubusercontent.com/u/5467932?v=4" width="42;" alt="喵仙人"/>
</a>
<a href="https://github.com/demigodliu" title="DemigodLiu">
<img src="https://avatars.githubusercontent.com/u/30372735?v=4" width="42;" alt="DemigodLiu"/>
</a>
<a href="https://github.com/JetSquirrel" title="JetSquirrel">
<img src="https://avatars.githubusercontent.com/u/20291255?v=4" width="42;" alt="JetSquirrel"/>
</a>
<a href="https://github.com/gaoxiaoduan" title="coderduan">
<img src="https://avatars.githubusercontent.com/u/69953511?v=4" width="42;" alt="coderduan"/>
</a>
<a href="https://github.com/hweining" title="hweining">
<img src="https://avatars.githubusercontent.com/u/8973985?v=4" width="42;" alt="hweining"/>
</a>
<a href="https://github.com/liliangrong777" title="liliangrong777">
<img src="https://avatars.githubusercontent.com/u/58727146?v=4" width="42;" alt="liliangrong777"/>
</a>
<a href="https://github.com/onewesong" title="onewesong">
<img src="https://avatars.githubusercontent.com/u/17920822?v=4" width="42;" alt="onewesong"/>
</a>
<a href="https://github.com/ryanhex53" title="ryanhex53">
<img src="https://avatars.githubusercontent.com/u/360426?v=4" width="42;" alt="ryanhex53"/>
</a>
<a href="https://github.com/zxx-457" title="zxx-457">
<img src="https://avatars.githubusercontent.com/u/114141362?v=4" width="42;" alt="zxx-457"/>
</a><!--GAMFC-END-->
贡献者列表,由 [contributors](https://github.com/jaywcjlove/github-action-contributors) 自动生成
<!--rehype:style=padding-top:1rem;-->
<!--rehype:ignore:start-->
## License

402
docs/ansible.md Normal file
View File

@ -0,0 +1,402 @@
Ansible 备忘清单
====
此快速参考备忘单提供了使用 [Ansible](https://ansible.com) 的各种方法。
入门
---
### 安装
安装命令 | 环境
:-|-
`brew install ansible` | macos
`yum install -y ansible` | centos
`pip install ansible` | python
---
- [Ansible 官方文档](https://docs.ansible.com)
### 配置位置
文件路径 | 说明
:-|-
`/etc/ansible/ansible.cfg` | 系统范围的配置
`~/ansible.cfg` | 用户特定的配置
`$pwd/ansible.cfg` | 当前目录下的配置
### Inventory文件(hosts列表)
#### 静态Inventory
`/etc/ansible/hosts`
```INI
mail.example.com
[webservers]
foo.example.com
bar.example.com
```
### Inventory 主机组使用多个IP和域名
```
[web]
172.18.12.5[1:4]
[webservers]
www[01:50].example.com
```
### Inventory 主机组使用子主机组
```ini
[usa:children]
southeast
northeast
southwest
northwest
```
### 给多台主机设置变量
`group variables`
如果组中的所有主机共享一个变量值,则可以一次将该变量应用于整个组
```ini
[atlanta]
host1
host2
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
```
## 命令行(ad-hoc)
### ansible
检查Inventory是否生效
```shell
$ ansible all --list-hosts
```
ping所有目标
```shell
$ ansible all -m ping
```
ping本地(不使用SSH连接)
```shell
$ ansible all -i localhost, -e '{"ansible_connection": "local"}' -m ping
```
<!--rehype:className=wrap-text -->
本地执行命令
```shell
$ ansible all -i localhost, -e '{"ansible_connection": "local"}' -a 'hostname'
```
<!--rehype:className=wrap-text -->
获取本地主机的信息
```shell
$ ansible all -i localhost, -e '{"ansible_connection": "local"}' -m setup
```
<!--rehype:className=wrap-text -->
获取远程到本地
```shell
$ ansible target -m fetch -a "src=/tmp/seq dest=/tmp/seq"
```
<!--rehype:className=wrap-text -->
拷贝本地到远程
```shell
$ ansible target -m copy -a "src=/tmp/seq dest=/tmp/seq"
```
<!--rehype:className=wrap-text -->
### Ansible 命令帮助
<!--rehype:wrap-class=col-span-2 row-span-3-->
```bash
$ ansible
$ ansible <host-pattern> [options]
```
---
:- | -
:- | -
`-a MODULE_ARGS`, `--args=MODULE_ARGS` | 模块参数
`--ask-vault-pass` | 询问保险库密码
`-B SECONDS`, `--background=SECONDS` | 异步运行X 秒后失败 (默认=N/A)
`-C`, `--check` | 不要做任何改变;相反,尝试预测可能发生的一些变化
`-D`, `--diff` | 更改(小)文件和模板时,显示这些文件中的差异; 与 `--check` 配合使用效果很好
`-e EXTRA_VARS`, `--extra-vars=EXTRA_VARS` | 将附加变量设置为 key=value 或 YAML/JSON
`-f FORKS`, `--forks=FORKS` | 指定要使用的并行进程数 (default=5)
`-h`, `--help` | 显示此帮助信息并退出
`-i INVENTORY`, `--inventory-file=INVENTORY` | 指定清单主机路径(默认=/etc/ansible/hosts)或逗号分隔的主机列表
`-l SUBSET`, `--limit=SUBSET` | 进一步将选定主机限制为其他模式
`--list-hosts` | 输出匹配主机列表;不执行任何其他操作
`-m MODULE_NAME`, `--module-name=MODULE_NAME` | 要执行的模块名称 (default=command)
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径 (default=None)
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
`-o`, `--one-line` | 压缩输出
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名; 使用 - 用于标准输出
`-P POLL_INTERVAL`, `--poll=POLL_INTERVAL` | 如果使用 -B 则设置轮询间隔(default=15)
`--syntax-check` | 对 playbook 执行语法检查,但不要执行它
`-t TREE`, `--tree=TREE` | 将输出记录到此目录
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
`--version` | 显示程序的版本号并退出
控制谁以及如何连接到主机,连接选项:
:- | -
:- | -
`-k`, `--ask-pass` | 询问连接密码
`--private-key=PRIVATE_KEY_FILE`, `--key-file=PRIVATE_KEY_FILE` | 使用此文件来验证连接
`-u REMOTE_USER`, `--user=REMOTE_USER` | 以此用户身份连接(default=None)
`-c CONNECTION`, `--connection=CONNECTION` | 要使用的连接类型 (default=smart)
`-T TIMEOUT`, `--timeout=TIMEOUT` | 以秒为单位覆盖连接超时 (default=10)
`--ssh-common-args=SSH_COMMON_ARGS` | 指定要传递给 sftp/scp/ssh 的常用参数 (e.g. ProxyCommand)
`--sftp-extra-args=SFTP_EXTRA_ARGS` | 指定仅传递给 sftp 的额外参数 (e.g. -f, -l)
`--scp-extra-args=SCP_EXTRA_ARGS` | 指定仅传递给 `scp` 的额外参数 (e.g. -l)
`--ssh-extra-args=SSH_EXTRA_ARGS` | 指定仅传递给 `ssh` 的额外参数 (e.g. -R)
控制您成为目标主机上的用户的方式和用户,特权升级选项:
:- | -
:- | -
`-s`, `--sudo` | 使用 sudo (nopasswd) 运行操作(已弃用,使用 become)
`-U SUDO_USER`, `--sudo-user=SUDO_USER` | 所需的 sudo 用户(默认=root)(已弃用,使用 become)
`-S`, `--su` | 使用 su 运行操作(已弃用,使用 become)
`-R SU_USER`, `--su-user=SU_USER` | 以该用户身份使用 su 运行操作(默认 = root)(已弃用,使用 become)
`-b`, `--become` | 使用 become 运行操作(不暗示密码提示)
`--become-method=BECOME_METHOD` | 要使用的权限提升方法(默认=sudo),有效选择:[ sudo | su | pbrun | pfexec | runas | doas | dzdo ]
`--become-user=BECOME_USER` | 以该用户身份运行操作(默认=root)
`--ask-sudo-pass` | 询问 sudo 密码(已弃用,使用 become)
`--ask-su-pass` | 询问 su 密码(已弃用,使用 become)
`-K`, `--ask-become-pass` | 要求提权密码
### Ansible Galaxy 工具
```bash
$ ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
```
<!--rehype:className=wrap-text-->
---
:- | -
:- | -
`-h`, `--help` | 显示此帮助信息并退出
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
`--version` | 显示程序的版本号并退出
<!--rehype:className=style-list-->
---
```bash
$ ansible-galaxy search --author <AUTHOR>
$ ansible-galaxy search --platforms <PLATFORM>
$ ansible-galaxy search --galaxy-tags <TAG>
$ ansible-galaxy info <ROLE>
$ ansible-galaxy install <ROLE> -p <ROLE_DIRECTORY>
$ ansible-galaxy install -r <ROLE1> <ROLE2> <ROLE3> ...
$ ansible-galaxy list
$ ansible-galaxy remove <ROLE>
$ ansible-galaxy init <ROLE>
$ ansible-galaxy init --offline <ROLE>
```
<!--rehype:className=wrap-text-->
### ansible-doc
在本地访问文档
```bash
$ ansible-doc
$ ansible-doc [options] [module...]
```
---
:- | -
:- | -
`-h`, `--help` | 显示此帮助信息并退出
`-l`, `--list` | 列出可用模块
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径 (default=None)
`-s`, `--snippet` | 显示指定模块的剧本片段
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
`--version` | 显示程序的版本号并退出
<!--rehype:className=style-list-->
### ansible-vault
```bash
$ ansible-vault
$ ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] vaultfile.yml
```
---
:- | -
:- | -
`--ask-vault-pass` | 询问保险库密码
`-h`, `--help` | 显示此帮助信息并退出
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名; 使用 - 用于标准输出
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
`--version` | 显示程序的版本号并退出
<!--rehype:className=style-list-->
### ansible-playbook
<!--rehype:wrap-class=row-span-2-->
```bash
$ ansible-playbook
$ ansible-playbook playbook.yml
```
---
:- | -
:- | -
`--ask-vault-pass` | 询问保险库密码
`-C`, `--check` | 不要做任何改变;相反,尝试预测可能发生的一些变化
`-D`, `--diff` | 更改(小)文件和模板时,显示这些文件中的差异;与 `--check` 配合使用效果很好
`-e EXTRA_VARS`, `--extra-vars=EXTRA_VARS` | 将附加变量设置为 key=value 或 YAML/JSON
`--flush-cache` | 清除事实缓存
`--force-handlers` | 即使任务失败也运行处理程序
`-f FORKS`, `--forks=FORKS` | 指定要使用的并行进程数(默认值=5
`-h`, `--help` | 显示此帮助信息并退出
`-i INVENTORY`, `--inventory-file=INVENTORY` | 指定清单主机路径(默认=/etc/ansible/hosts或逗号分隔的主机列表
`-l SUBSET`, `--limit=SUBSET` | 进一步将选定主机限制为其他模式
`--list-hosts` | 输出匹配主机列表;不执行任何其他操作
`--list-tags` | 列出所有可用的标签
`--list-tasks` | 列出所有将要执行的任务
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径(默认=无)
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名;使用 - 用于标准输出
`--skip-tags=SKIP_TAGS` | 只运行标签与这些值不匹配的播放和任务
`--start-at-task=START_AT_TASK` | 在匹配此名称的任务处启动剧本
`--step` | 一步一步:在运行前确认每个任务
`--syntax-check` | 对 playbook 执行语法检查,但不要执行它
`-t TAGS`, `--tags=TAGS` | 只运行带有这些值标记的播放和任务
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
`--version` | 显示程序的版本号并退出
<!--rehype:className=style-list-->
连接选项:
:- | -
:- | -
`-k`, `--ask-pass` | 询问连接密码
`--private-key=PRIVATE_KEY_FILE`, `--key-file=PRIVATE_KEY_FILE` | 使用此文件来验证连接
`-u REMOTE_USER`, `--user=REMOTE_USER` | 以此用户身份连接(默认=None)
`-c CONNECTION`, `--connection=CONNECTION` | 要使用的连接类型(默认=smart)
`-T TIMEOUT`, `--timeout=TIMEOUT` | 以秒为单位覆盖连接超时(默认值 = 10)
`--ssh-common-args=SSH_COMMON_ARGS` | 指定要传递给 sftp/scp/ssh 的常用参数(例如 ProxyCommand)
`--sftp-extra-args=SFTP_EXTRA_ARGS` | 指定仅传递给 sftp 的额外参数(例如 -f、-l)
`--scp-extra-args=SCP_EXTRA_ARGS` | 指定仅传递给 scp 的额外参数(例如 -l)
`--ssh-extra-args=SSH_EXTRA_ARGS` | 指定仅传递给 ssh 的额外参数(例如 -R)
<!--rehype:className=style-list-->
特权升级选项:
:- | -
:- | -
`-s`, `--sudo` | 使用 sudo (nopasswd) 运行操作(已弃用,使用 become)
`-U SUDO_USER`, `--sudo-user=SUDO_USER` | 所需的 sudo 用户(默认=root)(已弃用使用become)
`-S`, `--su` | 使用 su 运行操作(已弃用,使用 become)
`-R SU_USER`, `--su-user=SU_USER` | 以该用户身份使用 su 运行操作(默认 = root)(已弃用使用become)
`-b`, `--become` | 使用 become 运行操作(不暗示密码提示)
`--become-method=BECOME_METHOD` | 要使用的权限提升方法(默认=sudo),有效选择:[ sudo \| su \| pbrun \| pfexec \| runas \| doas \| dzdo ]
`--become-user=BECOME_USER` | 以该用户身份运行操作(默认=root)
`--ask-sudo-pass` | 询问 sudo 密码(已弃用,使用 become)
`--ask-su-pass` | 询问 su 密码(已弃用,使用 become)
`-K`, `--ask-become-pass` | 要求提权密码
<!--rehype:className=style-list-->
### ansible-pull
<!--rehype:wrap-class=row-span-2-->
```bash
$ ansible-pull
$ ansible-pull -U <repository> [options]
```
---
:- | -
:- | -
`--accept-host-key` | 如果尚未添加,则添加 repo url 的主机密钥
`--ask-vault-pass` | 询问保险库密码
`-C CHECKOUT`, `--checkout=CHECKOUT` | 分支/标签/提交结帐。默认为存储库模块的行为。
`-d DEST`, `--directory=DEST` | 签出存储库的目录
`-e EXTRA_VARS`, `--extra-vars=EXTRA_VARS` | 将附加变量设置为 key=value 或 YAML/JSON
`-f`, `--force` | 即使无法更新存储库也运行 playbook
`--full` | 做一个完整的克隆,而不是一个浅的
`-h`, `--help` | 显示此帮助信息并退出
`-i INVENTORY`, `--inventory-file=INVENTORY` | 指定清单主机路径(默认=/etc/ansible/hosts)或逗号分隔的主机列表
`-l SUBSET`, `--limit=SUBSET` | 进一步将选定主机限制为其他模式
`--list-hosts` | 输出匹配主机列表;不执行任何其他操作
`-m MODULE_NAME`, `--module-name=MODULE_NAME` | 存储库模块名称ansible 将使用它来签出 repo。默认是 git
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径(默认=无)
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
`-o`, `--only-if-changed` | 仅在存储库已更新时才运行 playbook
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名;使用 - 用于标准输出
`--purge` | 剧本运行后清除结帐
`--skip-tags=SKIP_TAGS` | 只运行标签与这些值不匹配的播放和任务
`-s SLEEP`, `--sleep=SLEEP` | 在开始之前休眠随机间隔(在 0 到 n 秒之间)。这是分散 git 请求的有用方法
`-t TAGS`, `--tags=TAGS` | 只运行带有这些值标记的播放和任务
`-U URL`, `--url=URL` | 剧本存储库的 URL
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
`--verify-commit` | 验证签出提交的 GPG 签名,如果失败则中止运行 playbook。这就需要对应的VCS模块来支持这样的操作
`--version` | 显示程序的版本号并退出
<!--rehype:className=style-list-->
连接选项:
:- | -
:- | -
`-k`, `--ask-pass` | 询问连接密码
`--private-key=PRIVATE_KEY_FILE`, `--key-file=PRIVATE_KEY_FILE` | 使用此文件来验证连接
`-u REMOTE_USER`, `--user=REMOTE_USER` | 以此用户身份连接(默认=无)
`-c CONNECTION`, `--connection=CONNECTION` | 要使用的连接类型(默认=智能)
`-T TIMEOUT`, `--timeout=TIMEOUT` | 以秒为单位覆盖连接超时(默认值 = 10)
`--ssh-common-args=SSH_COMMON_ARGS` | 指定要传递给 sftp/scp/ssh 的常用参数(例如 ProxyCommand)
`--sftp-extra-args=SFTP_EXTRA_ARGS` | 指定仅传递给 sftp 的额外参数(例如 -f、-l)
`--scp-extra-args=SCP_EXTRA_ARGS` | 指定仅传递给 scp 的额外参数(例如 -l)
`--ssh-extra-args=SSH_EXTRA_ARGS` | 指定仅传递给 ssh 的额外参数(例如 -R)
<!--rehype:className=style-list-->
特权升级选项:
:- | -
:- | -
`--ask-sudo-pass` | 询问 sudo 密码(已弃用使用become)
`--ask-su-pass` | 询问 su 密码(已弃用使用become)
`-K`, `--ask-become-pass` | 要求提权密码
<!--rehype:className=style-list-->
<!-- ### ansible-playbook -->
<!-- todo -->
另见
---
[Getting started with Ansible](https://docs.ansible.com/ansible/latest/getting_started/index.html)
[Introduction to ad hoc commands](https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html)
[Ansible cheatsheet](https://github.com/luckylittle/ansible-cheatsheet/blob/master/ansible-cheatsheet.txt)

786
docs/awk.md Normal file
View File

@ -0,0 +1,786 @@
Awk 备忘清单
===
这是 [GNU awk](https://www.gnu.org/software/gawk/manual/gawk.html) 的单页快速参考备忘单,其中涵盖了常用的 `awk` 表达式和命令。
入门
------
### 试试
该程序可用于选择文件中的特定记录并对其执行操作
```shell
$ awk -F: '{print $1, $NF}' /etc/passwd
```
----
| - | - | - |
|---|---------------|---------------------------|
| | `-F:` | 冒号作为分隔符 |
| | `{...}` | awk 程序 |
| | `print` | 打印当前记录 |
| | `$1` | 第一个字段 |
| | `$NF` | 最后一个字段 |
| | `/etc/passwd` | 输入数据文件 |
### Awk 程序
```bash
BEGIN {<初始化>}
<pattern 1> {<计划动作>}
<pattern 2> {<计划动作>}
...
END {< 最后的动作 >}
```
#### 示例
```bash
awk '
BEGIN { print "\n>>>Start" }
!/(login|shutdown)/ { print NR, $0 }
END { print "<<<END\n" }
' /etc/passwd
```
### 变量
<!--rehype:wrap-class=row-span-2-->
```bash
$1 $2/$(NF-1) $3/$NF
▼ ▼ ▼
┌──────┬──────────────┬───────┐
$0/NR ▶ │ ID │ WEBSITE │ URI │
├──────┼──────────────┼───────┤
$0/NR ▶ │ 1 │ baidu.com │ awk │
├──────┼──────────────┼───────┤
$0/NR ▶ │ 2 │ google.com │ 25
└──────┴──────────────┴───────┘
```
----
```shell
# 第一个和最后一个字段
awk -F: '{print $1,$NF}' /etc/passwd
# 带行号
awk -F: '{print NR, $0}' /etc/passwd
# 倒数第二个字段
awk -F: '{print $(NF-1)}' /etc/passwd
# 自定义字符串
awk -F: '{print $1 "=" $6}' /etc/passwd
```
查看: [Awk 变量](#awk-变量)
### Awk 程序示例
<!--rehype:wrap-class=row-span-2 col-span-2-->
```shell
awk 'BEGIN {print "hello world"}' # 打印 "hello world"
awk -F: '{print $1}' /etc/passwd # -F: 指定字段分隔符
# /pattern/ 仅对匹配的模式执行操作
awk -F: '/root/ {print $1}' /etc/passwd
# BEGIN 块在开始时执行一次
awk -F: 'BEGIN { print "uid"} { print $1 }' /etc/passwd
# END 块在最后执行一次
awk -F: '{print $1} END { print "-done-"}' /etc/passwd
```
### 条件
```bash
awk -F: '$3>30 {print $1}' /etc/passwd
```
查看: [Conditions 条件](#awk-条件)
### 生成 1000 个空格
```shell
awk 'BEGIN{
while (a++ < 1000)
s=s " ";
print s
}'
```
查看: [Loops](#awk-循环)
### 数组 Arrays
```shell
awk 'BEGIN {
fruits["mango"] = "yellow";
fruits["orange"] = "orange"
for(fruit in fruits) {
print fruit " 的颜色是 " fruits[fruit]
}
}'
```
查看: [Awk 数组](#awk-数组)
### 函数 Functions
```shell
# => 5
awk 'BEGIN{print length("hello")}'
# => HELLO
awk 'BEGIN{print toupper("hello")}'
# => hel
awk 'BEGIN{print substr("hello", 1, 3)}'
```
查看: [Functions](#awk-函数)
Awk 变量
---------
### 内置变量
:- | :-
:- | :-
`$0` | 全线
`$1, $2...$NF` | 第一个,第二个……最后一个字段
`NR` | 记录总数(`N`umber of `R`ecords)
`NF` | N个字段(`N`number of `F`ields)
`OFS` | `O`utput `F`ield `S`eparator<br> 输出字段分隔符 _(default " ")_
`FS` | input `F`ield `S`eparator <br> 输入字段分隔符 _(default " ")_
`ORS` | `O`utput `R`ecord `S`eparator <br> 输出记录分隔符 _(default "\n")_
`RS` | input `R`ecord `S`eparator <br> 输入记录分隔符 _(default "\n")_
`FILENAME` | 文件名
### 表达式
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`$1 == "root"` | 第一个字段等于根
`{print $(NF-1)}` | 倒数第二个字段
`NR!=1{print $0}` | 从第 2 条记录开始
`NR > 3` | 从第 4 条记录开始
`NR == 1` | 第一次记录
`END{print NR}` | 总记录
`BEGIN{print OFMT}` | 输出格式
`{print NR, $0}` | 行号
`{print NR " " $0}` | 行号(选项卡)
`{$1 = NR; print}` | 用行号替换第一个字段
`$NF > 4` | 最后一个字段 > 4
`NR % 2 == 0` | 甚至记录
`NR==10, NR==20` | 记录 10 到 20
`BEGIN{print ARGC}` | 总 `arguments`
`ORS=NR%5?",":"\n"` | 连接记录
### 示例
<!--rehype:wrap-class=row-span-2-->
打印总和和平均值
```shell
awk -F: '{sum += $3}
END { print sum, sum/NR }
' /etc/passwd
```
打印参数
```shell
awk 'BEGIN {
for (i = 1; i < ARGC; i++)
print ARGV[i] }' a b c
```
输出字段分隔符为逗号
```shell
awk 'BEGIN { FS=":";OFS=","}
{print $1,$2,$3,$4}' /etc/passwd
```
匹配位置
```shell
awk 'BEGIN {
if (match("One Two Three", "Tw"))
print RSTART }'
```
匹配时长
```shell
awk 'BEGIN {
if (match("One Two Three", "re"))
print RLENGTH }'
```
### 仅限 GNU awk
:- | :-
:- | :-
`ENVIRON` | 环境变量
`IGNORECASE` | 忽略大小写
`CONVFMT` | 转换格式
`ERRNO` | 系统错误
`FIELDWIDTHS` | 固定宽度字段
### 环境变量
:- | :-
:- | :-
`ARGC` | 数字或参数
`ARGV` | 参数数组
`FNR` | 文件记录数(`F`ile `N`umber of `R`ecords)
`OFMT` | 数字格式 _(default "%.6g")_
`RSTART` | 字符串中的位置
`RLENGTH` | 比赛时长
`SUBSEP` | 多维数组分隔符 _(default "\034")_
`ARGIND` | 参数索引
### 定义变量
```shell
awk -v var1="Hello" -v var2="Wold" '
END {print var1, var2}
' </dev/null
```
#### 使用 shell 变量
```shell
awk -v varName="$PWD" '
END {print varName}' </dev/null
```
Awk 运算符
---------
### 运算符
:- | :-
:- | :-
`{print $1}` | 第一个字段
`$2 == "foo"` | 等于
`$2 != "foo"` | 不等于
`"foo" in array` | 在数组中
#### 正则表达式
:- | :-
:- | :-
| `/regex/` | 行匹配|
| `!/regex/` | 行不匹配|
| `$1 ~ /regex/` | 字段匹配|
| `$1 !~ /regex/` | 字段不匹配|
#### 更多条件
:- | :-
:- | :-
`($2 <= 4 \|\| $3 < 20)` | 或者
`($1 == 4 && $3 < 20)` | 和
### 运算符
#### 算术运算
- `+`
- `-`
- `*`
- `/`
- `%`
- `++`
- `--`
<!--rehype:className=cols-3 style-none-->
#### 速记作业
- `+=`
- `-=`
- `*=`
- `/=`
- `%=`
<!--rehype:className=cols-3 style-none-->
#### 比较运算符
- `==`
- `!=`
- `<`
- `>`
- `<=`
- `>=`
<!--rehype:className=cols-3 style-none-->
### 示例
```shell
awk 'BEGIN {
if ("foo" ~ "^fo+$")
print "Fooey!";
}'
```
#### 不匹配
```shell
awk 'BEGIN {
if ("boo" !~ "^fo+$")
print "Boo!";
}'
```
#### 如果在数组中
```shell
awk 'BEGIN {
assoc["foo"] = "bar";
assoc["bar"] = "baz";
if ("foo" in assoc)
print "Fooey!";
}'
```
Awk 函数
----------
### 常用功能
<!--rehype:wrap-class=col-span-2-->
函数 | 描述
:- | :-
`index(s,t)` | 字符串 `s` 中出现字符串 `t` 的位置,如果未找到则为 `0`
`length(s)` | 字符串 `s` 的长度(如果没有 `arg`,则为 `$0`)
`rand` | `0``1` 之间的随机数
`substr(s,index,len)` | 返回从索引开始的 `s``len-char` 子字符串(从 `1` 开始计数)
`srand` | 为 `rand` 设置种子并返回之前的种子
`int(x)` | 将 `x` 截断为整数值
`split(s,a,fs)` | 将字符串 `s` 拆分为数组 `a``fs` 拆分,返回 `a` 的长度
`match(s,r)` | 字符串 `s` 中出现正则表达式 `r` 的位置,如果未找到,则为 `0`
`sub(r,t,s)` | 将 `t` 替换为字符串 `s` 中第一次出现的正则表达式 `r`(如果未给出 `s`,则替换为 `$0`)
`gsub(r,t,s)` | 用 `t` 替换字符串 `s` 中所有出现的正则表达式 `r`
`system(cmd)` | 执行cmd并返回退出状态
`tolower(s)` | 字符串 `s` 转小写
`toupper(s)` | 字符串 `s` 转大写
`getline` | 将 `$0` 设置为当前输入文件中的下一个输入记录
### 用户定义函数
```shell
awk '
# 返回最小数量
function find_min(num1, num2){
if (num1 < num2)
return num1
return num2
}
# 返回最大数量
function find_max(num1, num2){
if (num1 > num2)
return num1
return num2
}
# 主功能
function main(num1, num2){
result = find_min(num1, num2)
print "Minimum =", result
result = find_max(num1, num2)
print "Maximum =", result
}
# 脚本执行从这里开始
BEGIN {
main(10, 60)
}
'
```
Awk 数组
---------
### 带索引的数组
```shell
awk 'BEGIN {
arr[0] = "foo";
arr[1] = "bar";
print(arr[0]); # => foo
delete arr[0];
print(arr[0]); # => ""
}'
```
### 带键的数组
```shell
awk 'BEGIN {
assoc["foo"] = "bar";
assoc["bar"] = "baz";
print("baz" in assoc); # => 0
print("foo" in assoc); # => 1
}'
```
### 带拆分的数组
```shell
awk 'BEGIN {
split("foo:bar:baz", arr, ":");
for (key in arr)
print arr[key];
}'
```
### 带有排序的数组
```shell
awk 'BEGIN {
arr[0] = 3
arr[1] = 2
arr[2] = 4
n = asort(arr)
for (i = 1; i <= n ; i++)
print(arr[i])
}'
```
### 多维
```shell
awk 'BEGIN {
multidim[0,0] = "foo";
multidim[0,1] = "bar";
multidim[1,0] = "baz";
multidim[1,1] = "boo";
}'
```
### 多维迭代
```shell
awk 'BEGIN {
array[1,2]=3;
array[2,3]=5;
for (comb in array) {
split(comb,sep,SUBSEP);
print sep[1], sep[2],
array[sep[1],sep[2]]
}
}'
```
Awk 条件
----------
### if-else 语句
```shell
awk -v count=2 'BEGIN {
if (count == 1)
print "Yes";
else
print "Huh?";
}'
```
#### 三元运算符
```shell
awk -v count=2 'BEGIN {
print (count==1) ? "Yes" : "Huh?";
}'
```
### 存在
```shell
awk 'BEGIN {
assoc["foo"] = "bar";
assoc["bar"] = "baz";
if ("foo" in assoc)
print "Fooey!";
}'
```
#### 不存在
```shell
awk 'BEGIN {
assoc["foo"] = "bar";
assoc["bar"] = "baz";
if ("Huh" in assoc == 0 )
print "Huh!";
}'
```
### switch
```shell
awk -F: '{
switch (NR * 2 + 1) {
case 3:
case "11":
print NR - 1
break
case /2[[:digit:]]+/:
print NR
default:
print NR + 1
case -1:
print NR * -1
}
}' /etc/passwd
```
Awk 循环
----------
### for...i
```shell
awk 'BEGIN {
for (i = 0; i < 10; i++)
print "i=" i;
}'
```
#### 1 到 100 之间的 2 的幂
```shell
awk 'BEGIN {
for (i = 1; i <= 100; i *= 2)
print i
}'
```
### for...in
```shell
awk 'BEGIN {
assoc["key1"] = "val1"
assoc["key2"] = "val2"
for (key in assoc)
print assoc[key];
}'
```
#### Arguments
```shell
awk 'BEGIN {
for (argnum in ARGV)
print ARGV[argnum];
}' a b c
```
### 示例
<!--rehype:wrap-class=row-span-3-->
#### 反向记录
```shell
awk -F: '{ x[NR] = $0 }
END {
for (i = NR; i > 0; i--)
print x[i]
}
' /etc/passwd
```
#### 反向字段
```shell
awk -F: '{
for (i = NF; i > 0; i--)
printf("%s ",$i);
print ""
}' /etc/passwd
```
#### 按记录求和
```shell
awk -F: '{
s=0;
for (i = 1; i <= NF; i++)
s += $i;
print s
}' /etc/passwd
```
#### 总结整个文件
```shell
awk -F: '
{for (i = 1; i <= NF; i++)
s += $i;
};
END{print s}
' /etc/passwd
```
### while
<!--rehype:wrap-class=row-span-2-->
```shell
awk 'BEGIN {
while (a < 10) {
print "- " " concatenation: " a
a++;
}
}'
```
#### do...while
```shell
awk '{
i = 1
do {
print $0
i++
} while (i <= 5)
}' /etc/passwd
```
### Break
```shell
awk 'BEGIN {
break_num = 5
for (i = 0; i < 10; i++) {
print i
if (i == break_num)
break
}
}'
```
### Continue
```shell
awk 'BEGIN {
for (x = 0; x <= 10; x++) {
if (x == 5 || x == 6)
continue
printf "%d ", x
}
print ""
}'
```
Awk 格式化打印
---------
### 用法
#### 右对齐
```shell
awk 'BEGIN{printf "|%10s|\n", "hello"}'
# | hello|
```
#### 左对齐
```shell
awk 'BEGIN{printf "|%-10s|\n", "hello"}'
# |hello |
```
### 通用说明符
特征符 | 描述
:- | :-
`c` | ASCII 字符
`d` | 十进制整数
`e`, `E`, `f` | 浮点格式
`o` | 无符号八进制值
`s` | 细绳
`%` | 文字百分比
### Space 空间
```shell
awk -F: '{
printf "%-10s %s\n", $1, $(NF-1)
}' /etc/passwd | head -n 3
```
输出
```shell
root /root
bin /bin
daemon /sbin
```
### Header 标题头
```shell
awk -F: 'BEGIN {
printf "%-10s %s\n", "User", "Home"
printf "%-10s %s\n", "----","----"}
{ printf "%-10s %s\n", $1, $(NF-1) }
' /etc/passwd | head -n 5
```
输出
```shell
User Home
---- ----
root /root
bin /bin
daemon /sbin
```
各种各样的
-------------
### 正则表达式元字符
- `\`
- `^`
- `$`
- `.`
- `[`
- `]`
- `|`
- `(`
- `)`
- `*`
- `+`
- `?`
<!--rehype:className=cols-3 style-none-->
### 转义序列
:- | :-
:- | :-
`\b` | 退格
`\f` | 换页
`\n` | 换行(换行)
`\r` | 回车
`\t` | 水平选项卡
`\v` | 垂直选项卡
### 运行脚本
```shell
$ cat demo.awk
#!/usr/bin/awk -f
BEGIN { x = 23 }
{ x += 2 }
END { print x }
$ awk -f demo.awk /etc/passwd
69
```
另见
--------
- [GNU awk 用户指南](https://www-zeuthen.desy.de/dv/documentation/unixguide/infohtml/gawk/gawk.html) _(www-zeuthen.desy.de)_
- [AWK cheatsheet](https://gist.github.com/Rafe/3102414) _(gist.github.com)_

View File

@ -34,11 +34,9 @@ NAME = "John" # => Error (关于空间)
### 注释
```bash
# 这是一个内联 Bash 注释。
```
```shell
# 这是一个内联 Bash 注释。
: '
这是一个
非常整洁的评论
@ -66,7 +64,6 @@ NAME = "John" # => Error (关于空间)
见:[特殊参数](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)
### 函数
```bash
@ -206,7 +203,7 @@ DIRPATH=${SRC%$BASEPATH}
echo $DIRPATH # => "/path/to/"
```
### Transform
### Transform
```bash
STR="HELLO WORLD!"
@ -222,7 +219,7 @@ echo "${ARR[@],}" # => hello world
echo "${ARR[@]^}" # => Hello World
```
Bash 数组
Bash 数组
------
### 定义数组
@ -249,14 +246,14 @@ Numbers+=(4 5) # 附加 => 1 2 3 4 5
:- | -
:- | -
`${Fruits[0]}` | 第一个元素
`${Fruits[-1]}` | 最后一个元素
`${Fruits[*]}` | 所有元素
`${Fruits[@]}` | 所有元素
`${#Fruits[@]}` | 总数
`${#Fruits}` | 第一节长度
`${#Fruits[3]}` | 第n个长度
`${Fruits[@]:3:2}` | 范围
`${Fruits[0]}` | 第一个元素
`${Fruits[-1]}` | 最后一个元素
`${Fruits[*]}` | 所有元素
`${Fruits[@]}` | 所有元素
`${#Fruits[@]}` | 总数
`${#Fruits}` | 第一节长度
`${#Fruits[3]}` | 第n个长度
`${Fruits[@]:3:2}` | 范围
`${!Fruits[@]}` | 所有 Key
### 迭代 Iteration
@ -267,7 +264,9 @@ for e in "${Fruits[@]}"; do
echo $e
done
```
#### With index
```bash
for i in "${!Fruits[@]}"; do
printf "%s\t%s\n" "$i" "${Fruits[$i]}"
@ -445,7 +444,6 @@ fi
`[[ f1 -ot f2 ]]` | f2 早于 f1
`[[ f1 -ef f2 ]]` | 相同的文件
### 更多条件
条件 | 描述
@ -453,7 +451,7 @@ fi
`[[ -o noclobber ]]` | 如果启用 OPTION
`[[ ! EXPR ]]` | 不是 Not
`[[ X && Y ]]` | 和 And
`[[ X \|\| Y ]]` | 或者 Or
`[[ X \|\| Y ]]` | 或者 Or
### 逻辑和,或
@ -556,7 +554,7 @@ until [ $count -gt 10 ]; do
done
```
### 永远
### 永远
```bash
while true; do
@ -572,7 +570,6 @@ while :; do
done
```
### 正在读取行
```bash
@ -722,8 +719,7 @@ Bash 历史
`!!` 可以替换为任何有效的扩展,即 `!cat`、`!-2`、`!42` 等。
各种各样的
各种各样的
-------------
### 数值计算
@ -743,7 +739,6 @@ $(($RANDOM%200)) # Random number 0..199
pwd # still in first directory
```
### 检查命令
```bash
@ -767,7 +762,6 @@ python hello.py &>/dev/null # 标准输出和标准错误到空null
python hello.py < foo.txt # 将 foo.txt 提供给 python 的标准输入
```
### 来源相对
```bash
@ -793,7 +787,6 @@ case "$1" in
esac
```
### 陷阱错误
<!--rehype:wrap-class=col-span-2-->
@ -864,7 +857,6 @@ fi
见[特殊参数](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)。
### grep 检查
<!--rehype:wrap-class=col-span-2-->
@ -874,11 +866,10 @@ if grep -q 'foo' ~/.bash_history; then
fi
```
### 反斜杠转义
<!--rehype:wrap-class=row-span-2-->
- &nbsp;
- &nbsp;
- \!
- \"
- \#
@ -965,11 +956,11 @@ echo "${args[@]}"
另见
----
* [Shell 教程](https://jaywcjlove.github.io/shell-tutorial) _(jaywcjlove.github.io)_
* [Devhints](https://devhints.io/bash) _(devhints.io)_
* [Bash-hackers wiki](http://wiki.bash-hackers.org/) _(bash-hackers.org)_
* [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
* [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_
* [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_
* [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_
* [shell - Standard Shell](https://devmanual.gentoo.org/tools-reference/bash/index.html) _(devmanual.gentoo.org)_
- [Shell 教程](https://jaywcjlove.github.io/shell-tutorial) _(jaywcjlove.github.io)_
- [Devhints](https://devhints.io/bash) _(devhints.io)_
- [Bash-hackers wiki](http://wiki.bash-hackers.org/) _(bash-hackers.org)_
- [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
- [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_
- [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_
- [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_
- [shell - Standard Shell](https://devmanual.gentoo.org/tools-reference/bash/index.html) _(devmanual.gentoo.org)_

1332
docs/c.md Normal file

File diff suppressed because it is too large Load Diff

432
docs/cargo.md Normal file
View File

@ -0,0 +1,432 @@
Cargo 备忘清单
===
此快速参考备忘清单 [Cargo](https://conan.io/) 提供了编译 [Rust](./rust.md) 常用命令和示例
入门
--------
### 安装/升级 Rust 和 Cargo
```bash
$ curl -sSf https://static.rust-lang.org/rustup.sh | sh
```
<!--rehype:className=wrap-text-->
在 Linux 和 macOS 系统上,这可以通过以上方命令完成
- [Cargo 开源仓库](https://github.com/rust-lang/cargo) _(github.com)_
- [Cargo 官网](https://doc.rust-lang.org/cargo) _(doc.rust-lang.org)_
- [Cargo 官网(中文)](https://www.rustwiki.org.cn/zh-CN/cargo/index.html) _(rustwiki.org.cn)_
- [Rust 社区的 crate 仓库](https://crates.io/) _(crates.io)_
### 命令说明
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`cargo version` | 显示版本信息以确认 Cargo 已安装
`cargo new` | 创建一个新项目
`cargo test` | 在项目中运行单元测试
`cargo check` | 快速编译项目,无需生成二进制文件来检查错误
`cargo fmt` | 自动格式化代码
`cargo build` | 编译一个项目
`cargo run` | 一步编译和运行项目
`cargo clippy --all-targets -- --D warnings` | Linter 检查错误
`cargo tarpaulin --ignore-tests` | 检查代码覆盖率
### 切换源
<!--rehype:wrap-class=col-span-2&style=background:#e91e63;--->
```bash
$ touch ~/.cargo/config # 添加配置文件
$ vim ~/.cargo/config # 编辑配置文件
```
配置文件 `config` 内容
```toml
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'tuna' # 👈 如果需要提交包注释配置源
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
# registry = "git://mirrors.ustc.edu.cn/crates.io-index"
```
💥 注意切换源需要删除缓存目录
```bash
$ rm -rf ~/.cargo/.package-cache # ⚠️ 删除缓存目录内容
```
### 创建新项目
<!--rehype:wrap-class=row-span-3-->
```bash
$ cargo new hello_world --bin
```
---
- `--bin` 正在制作一个二进制程序
- `--lib` 正在创建一个库(lib)
得到如下目录:
```bash
$ cd hello_world
$ tree .
.
├── Cargo.toml
└── src
└── main.rs
```
`Cargo.toml` 被称为一个 `manifest` 元清单,它包含了 `Cargo` 编译项目所需的所有元数据
```toml
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"
[dependencies]
```
入口文件 `src/main.rs`
```rust
fn main() {
println!("Hello, world!");
}
```
运行编译生成 `hello_world` 二进制文件
```bash
$ cargo build
# 文件放入 `target/release` 目录
$ cargo build --release
```
然后运行它:
```bash
$ ./target/debug/hello_world
Hello, world!
```
也可以直接使用 `cargo run`,它会自行`编译``运行`它:
```bash
$ cargo run
Running `target/hello_world`
Hello, world!
```
### 项目目录
```bash
.
├── Cargo.lock
├── Cargo.toml
├── benches # 基准目录
│ └── large-input.rs
├── examples # 示例
│ └── simple.rs
├── src # 源代码
│ ├── bin
│ │ └── another_executable.rs
│ ├── lib.rs # 默认库
│ └── main.rs # 入口文件
└── tests # 集成测试
└── some-integration-tests.rs
```
### 编译测试
```bash
# 编译输出二进制文件,放入 `target/debug` 目录
$ cargo build
# 输出二进制文件,放入 `target/release` 目录
$ cargo build --release
$ cargo run # 编译并运行
$ cargo test # 运行您的测试
$ cargo test foo # 传递过滤器,来运行特定测试
```
### 配置目标
<!--rehype:wrap-class=row-span-2-->
```toml
[package]
# ...
[lib]
# 生成目标与库的名称. 本该默认是包名, 替换所有破折号为 下划线. (Rust `extern crate` 声明会参考该名因此该值必须是可用的有效Rust标识符)
name = "foo"
# 该字段,指向 crate 的入口(位置), 路径相对于 `Cargo.toml`.
path = "src/lib.rs"
# 一个给目标启用单元测试 的 标志. 会被 `cargo test`使用.
test = true
# 一个给目标启用文档测试 的 标志. 只与库相关, 不会影响其他部分。会被 `cargo test`使用.
doctest = true
# 一个给目标启用基准 的 标志. 会被 `cargo bench`使用.
bench = true
# 一个给目标启用文档 的 标志. 会被 `cargo doc`使用.
doc = true
# 若该目标为 编译器扩展, 那要把该字段设为 true以让 Cargo 正确编译和,可用于所有依赖项.
plugin = false
# 若该目标为 "macros 1.1" 程序宏, 那要把该字段设为 true
proc-macro = false
# 若设为 false, `cargo test` 会为 rustc 省略 `--test` 标志, 这阻止它生成测试工具 这在二进制存在,构建管理测试运行器本身的情况下,有用.
harness = true
# 若设置了,那 目标会使用一个与`[package]`配置不同的版本, 也许是,编译一个库 2018年版本或编译单元测试的2015年版本. 默认情况下所有目标都使用`[package]`中指定的版本进行编译。
edition = '2015'
```
<!--rehype:className=wrap-text-->
### 来源配置
```toml
# `source` 表下,就是存储有关要更换的来源名称
[source]
# 在`source` 表格之下的,可为一定数量的有关来源名称. 示例下面就,定义了一个新源, 叫 `my-awesome-source`,其内容来自本地,`vendor`目录 ,其相对于包含 `.cargo/config` 文件的目录
[source.my-awesome-source]
directory = "vendor"
# Git sources 也指定一个 branch/tag/rev
git = "https://example.com/path/to/repo"
# branch = "master"
# tag = "v1.0.1"
# rev = "313f44e8"
# crates.io 默认源 在"crates-io"名称下,且在这里我们使用 `replace-with` 字段指明 默认源更换成"my-awesome-source"源
[source.crates-io]
replace-with = "my-awesome-source"
```
<!--rehype:className=wrap-text -->
### 配置
```toml
# 每个源都有自己的表格,名称即是表名
[source.the-source-name]
# 命令 `the-source-name` 会被 `another-source`取代
replace-with = "another-source"
# 有几种可用的源定义(接下来有所描述)
registry = "https://example.com/path/to/index"
local-registry = "path/to/registry"
directory = "path/to/vendor"
```
<!--rehype:className=wrap-text -->
更换源的配置通过完成 `.cargo/config`,上面是全套可用字段
包相关命令
---
### init/new
<!--rehype:wrap-class=row-span-2-->
创建一个新的 `cargo`
```bash
$ cargo init [options] [path]
$ cargo new [options] [path]
```
- `--bin` 创建具有二进制目标 (src/main.rs) 的包(默认行为)
- `--lib` 使用库目标 (src/lib.rs) 创建一个包
- `--edition edition` 指定要使用的 Rust 版本。默认值为 `2021`。可能的值2015、2018、2021
- `--name name` 设置包名。默认为目录名称
- `--vcs vcs` 为给定的版本控制系统git、hg、pijul 或fossil初始化一个新的 VCS 存储库,或者根本不初始化任何版本控制(无)
- `--registry registry` 限制仅发布到该注册表
<!--rehype:className=style-arrow-->
```bash
$ cargo new foo
```
### 安装包
<!--rehype:wrap-class=row-span-2-->
```bash
# 从 crates.io 安装或升级软件包:
$ cargo install ripgrep
# 在当前目录安装或重新安装包:
$ cargo install --path .
# 查看已安装包的列表:
$ cargo install --list
```
---
- `--vers version`
- `--version version` 指定要安装的版本
- `--git url` 用于安装指定 crate 的 Git URL
- `--branch branch` 从 git 安装时要使用的分支
- `--tag tag` 从 git 安装时使用的标记
- `--rev sha` 从 git 安装时使用的特定提交
- `--path path` 要安装的本地 crate 的文件系统路径
- `--list` 列出所有已安装的软件包及其版本
- `-f`, `--force` 强制覆盖现有的 crate 或二进制文件
### 搜索包
```bash
$ cargo search [options] [query...]
```
- `--limit limit` 限制结果数量(默认值10最大值100)
- `--index index` 要使用的注册表索引的 URL
- `--registry registry` 要使用的注册表的名称
```bash
$ cargo search serde
```
### 卸载包
```bash
$ cargo uninstall [options] [spec...]
```
- `-p`, `--package spec...` 要卸载的软件包
- `--bin name...` 仅卸载二进制名称
- `--root dir` 从中卸载软件包的目录
```bash
$ cargo uninstall ripgrep
```
发布命令
---
### 登录
```bash
$ cargo login [options] [token]
```
---
:-|:-
:-|:-
`--registry` | 要使用的注册表的名称
---
:-|:-
:-|:-
`-v`, `--verbose` | 启用更加详细的输出
`-q`, `--quiet` | 不输出Cargo的日志信息
`--color when` | 输出内容的颜色 `auto`, `always`, `never`
### 所有者
```bash
# 列出包的所有者:
$ cargo owner --list foo
# 邀请所有者加入包:
$ cargo owner --add username foo
# 从包中删除所有者:
$ cargo owner --remove username foo
```
---
:-|:-
:-|:-
`--token token` | 身份验证时使用的 API 令牌
`--index index` | 要使用的注册表索引的 URL
### 打包 & 发布公共选项
<!--rehype:wrap-class=row-span-3-->
选择包
- `-p spec...`, `--package spec...` Package 指定包
- `--workspace` Package 工作区中的全体成员
- `--exclude SPEC...` 排除指定包
编译选项
- `--target triple` 为指定架构执行 Package
- `--target-dir directory` 用于存放生成的工件以及中间文件的目录
特性选择
- `--features features` 传递以空格或者逗号分隔的列表,其中给出要启用的特性
- `--all-features` 为给定的包启用全部可用特性
- `--no-default-features` 不启用给定包的default特性
清单选项
- `--manifest-path path` 用于指定 Cargo.toml 文件的路径
- `--frozen`, `--locked` 这两个选项用于保证Cargo.lock文件是最新的
- `--offline` 禁止Cargo访问网络
混杂选项
- `-j N`, `--jobs N` 要并行运行的作业数量
### 打包
将本地包打包为可分发的压缩文件
```bash
$ cargo package [options]
```
---
- `-l`, `--list` 输出包中包含的文件(不实际进行打包)。
- `--no-verify` 构建包时不进行校验。
- `--no-metadata` 忽略 缺少可读的元信息(如描述信息或采用的授权协议) 时产生的警告。
- `--allow-dirty` 允许打包 在版本控制系统中仍有未提交内容 的包。
### 发布
<!--rehype:wrap-class=row-span-2-->
```bash
$ cargo publish [options]
```
发布选项
- `--dry-run` 在不上传的情况下执行所有检查
- `--token token` 身份验证时使用的 API 令牌
- `--no-verify` 不要通过构建内容来验证内容
- `--allow-dirty` 允许打包具有未提交的 VCS 更改的工作目录
- `--index index` 要使用的注册表索引的 URL
- `--registry registry` 要发布到的注册表的名称
打包选择
- `-p spec`, `--package spec` 要发布的包
### yank
从服务器的索引中删除以前发布的 crate 版本
```bash
$ cargo yank --vers 1.0.7 foo
```
- `--vers version` 要 yank 或 un-yank 的版本
- `--undo` 撤消 yank将版本放回索引中
- `--token token` 身份验证时使用的 API 令牌
- `--index index` 要使用的注册表索引的 URL
- `--registry registry` 要使用的注册表名称
另见
---
- [The Cargo Book](https://doc.rust-lang.org/stable/cargo/) _(doc.rust-lang.org)_
- [Cargo 手册 中文版](https://www.rustwiki.org.cn/zh-CN/cargo/index.html) _(rustwiki.org.cn)_

View File

@ -31,10 +31,21 @@ $ chmod -R 755 my_directory
### Chmod 生成器
```html
```html preview
<div>
权限:<input type="text" id="num" placeholder="777" maxlength="3" style="padding: 0.3rem 0.3rem;" /> <input type="text" id="let" placeholder="rwxrwxrwx" maxlength="9" style="padding: 0.3rem 0.3rem;" />
</div>
```
---
&nbsp; | User | Group | Other
:- | :- | :- | :-
读 _(Read)_ | <input checked id="1" type="checkbox"></input> | <input checked id="4" type="checkbox"></input> | <input checked id="7" type="checkbox"></input>
写 _(Write)_ | <input checked id="2" type="checkbox"></input> | <input checked id="5" type="checkbox"></input> | <input checked id="8" type="checkbox"></input>
执行 _(Execute)_ | <input checked id="3" type="checkbox"></input> | <input checked id="6" type="checkbox"></input> | <input checked id="9" type="checkbox"></input>
<!--rehype:className=show-header-->
Chmod 生成器允许您以数字和符号的形式快速、直观地生成权限。
### 通用权限
@ -96,7 +107,6 @@ d rwx r-x r-x
| `a` | 全部,和 ugo 一样 |
<!--rehype:className=show-header-->
### 权限
| 缩写 | 权限 | 值 |
@ -127,7 +137,6 @@ Chmod 示例
| `-` | 删除 |
| `=` | 设置 |
### chmod 600
```shell
@ -263,4 +272,234 @@ $ find /path -type f -exec chmod 644 {} \;
另见
----
* [使用 chmod 修改文件权限](https://www.linode.com/docs/guides/modify-file-permissions-with-chmod/) _(linode.com)_
* [使用 chmod 修改文件权限](https://www.linode.com/docs/guides/modify-file-permissions-with-chmod/) _(linode.com)_
<!--rehype:ignore:start-->
以下是 Chmod 生成器 JS 代码(代码用于网站请忽略不要删除)
---
<!--rehype:ignore:end-->
```html preview
<!-- Chmod 生成器 JS 代码 -->
<script type="text/javascript">
const reg_num = /^[0-7]{3}$/; // 一些正则表达式来检查 num 输入
const reg_let = /^([r\-]{1}[w\-]{1}[x\-]{1}){3}$/; // 一些正则表达式来检查文本输入
function checkBoxHandle() {
change_occured(true, false, false);
// get rid of bad input classes
document.getElementById('num').classList.remove('bad-input');
document.getElementById('let').classList.remove('bad-input');
}
window.addEventListener("DOMContentLoaded", function () {
// loop over all the check boxes
for (let i = 1; i < 10; i++) {
let checkBox = document.getElementById(`${i}`);
checkBox.addEventListener('change', function () {
change_occured(true, false, false);
// get rid of bad input classes
document.getElementById('num').classList.remove('bad-input');
document.getElementById('let').classList.remove('bad-input');
});
}
// the octal input
let num_input = document.getElementById('num');
let num_fn = function () {
// check for bad input
if (!reg_num.test(this.value)) {
this.classList.add('bad-input');
} else {
this.classList.remove('bad-input');
change_occured(false, true, false);
}
};
num_input.addEventListener('change', num_fn);
num_input.addEventListener('keyup', num_fn);
// the let input
let let_input = document.getElementById('let');
let let_fn = function () {
// check for bad input
if (!reg_let.test(this.value)) {
this.classList.add('bad-input');
} else {
this.classList.remove('bad-input');
change_occured(false, false, true);
}
};
let_input.addEventListener('change',let_fn);
let_input.addEventListener('keyup',let_fn);
});
/* SETUP
r-4-1 r-4-4 r-4-7
w-2-2 w-2-5 w-2-8
x-1-3 x-1-6 x-1-9
*/
// define a function that runs when a change occures
function change_occured(caller_was_check, caller_was_num, caller_was_let) {
let num1 = 0, num2 = 0, num3 = 0; // these are the three numbers for the octal
let perm_string = ''; // holds the permision string ex. rw-x--r--
if (caller_was_check) {
// loop over all the check boxes and get the permisions
for (let i = 1; i < 10; i++) {
let checkBox = document.getElementById(`${i}`);
if (checkBox.checked) { // if checked
let current_perm = check_to_octal_and_text(i);
perm_string += `${current_perm.perm_let}`;
if (i <= 3) {
num1 += current_perm.perm_num;
} else if (i <= 6) {
num2 += current_perm.perm_num;
} else {
num3 += current_perm.perm_num;
}
} else { // if not checked
perm_string += '-';
}
}
// set the permision input text
document.getElementById('let').value = perm_string;
document.getElementById('num').value = `${num1}${num2}${num3}`;
} else if (caller_was_num) {
// get the individual numbers
let num_input_val = document.getElementById('num').value;
num1 = num_input_val.substring(0, 1);
num2 = num_input_val.substring(1, 2);
num3 = num_input_val.substring(2, 3);
// set the checkboxes and get the perm string
perm_string += octal_to_check_and_txt(num1, 0); //Owner
perm_string += octal_to_check_and_txt(num2, 1); //Owner
perm_string += octal_to_check_and_txt(num3, 2); //Owner
// set the permision input text
document.getElementById('let').value = perm_string;
} else if (caller_was_let) {
// get the text input
let perm_text = document.getElementById('let').value;
num1 = text_to_check_and_octal(perm_text.substring(0, 3), 0)
num2 = text_to_check_and_octal(perm_text.substring(3, 6), 3)
num3 = text_to_check_and_octal(perm_text.substring(6, 9), 6)
// set the octal value
document.getElementById('num').value = `${num1}${num2}${num3}`;
}
}
// define a function to converts the checkbox # to the respective permissions
// returns perm_num, perm_let
function check_to_octal_and_text(check_num) {
let perm_num = 0;
let perm_let = '-';
switch (check_num) {
case 1:
case 4:
case 7:
perm_num = 4;
perm_let = 'r';
break;
case 2:
case 5:
case 8:
perm_num = 2;
perm_let = 'w';
break;
case 3:
case 6:
case 9:
perm_num = 1;
perm_let = 'x';
break;
default:
perm_num = 0;
perm_let = '-';
}
// return values
return {
perm_num,
perm_let
};
}
/**
Takes a number 1-7 and which class it is in:
0 = owner
1 = Group
2 = Public
Returns: perm text (ex. "rwx") and sets the appropriate checkboxes
*/
function octal_to_check_and_txt(octal_num, class_num) {
let perm_text = '';
let offset = class_num * 3;
switch (octal_num) {
case '1':
document.getElementById(`${1 + offset}`).checked = false;
document.getElementById(`${2 + offset}`).checked = false;
document.getElementById(`${3 + offset}`).checked = true;
perm_text = '--x';
break;
case '2':
document.getElementById(`${1 + offset}`).checked = false;
document.getElementById(`${2 + offset}`).checked = true;
document.getElementById(`${3 + offset}`).checked = false;
perm_text = '-w-';
break;
case '3':
document.getElementById(`${1 + offset}`).checked = false;
document.getElementById(`${2 + offset}`).checked = true;
document.getElementById(`${3 + offset}`).checked = true;
perm_text = '-wx';
break;
case '4':
document.getElementById(`${1 + offset}`).checked = true;
document.getElementById(`${2 + offset}`).checked = false;
document.getElementById(`${3 + offset}`).checked = false;
perm_text = 'r--';
break;
case '5':
document.getElementById(`${1 + offset}`).checked = true;
document.getElementById(`${2 + offset}`).checked = false;
document.getElementById(`${3 + offset}`).checked = true;
perm_text = 'r-x';
break;
case '6':
document.getElementById(`${1 + offset}`).checked = true;
document.getElementById(`${2 + offset}`).checked = true;
document.getElementById(`${3 + offset}`).checked = false;
perm_text = 'rw-';
break;
case '7':
document.getElementById(`${1 + offset}`).checked = true;
document.getElementById(`${2 + offset}`).checked = true;
document.getElementById(`${3 + offset}`).checked = true;
perm_text = 'rwx';
break;
default:
document.getElementById(`${1 + offset}`).checked = false;
document.getElementById(`${2 + offset}`).checked = false;
document.getElementById(`${3 + offset}`).checked = false;
perm_text = '---';
}
return perm_text;
}
/**
Takes 3 letters (r, w, x, - ex. 'rw-') and an offset (0,3,6)
Returns the octal num and sets the appropriate checkboxes
*/
function text_to_check_and_octal(letters, offset) {
let perm_num = 0; // the octal number to return
// add up the oct num and set the check boxes
for (let i = 0; i < 3; i++) {
current_let = letters.substring(i, i + 1);
if (current_let == 'r') {
document.getElementById(`${i + 1 + offset}`).checked = true;
perm_num += 4;
} else if (current_let == 'w') {
document.getElementById(`${i + 1 + offset}`).checked = true;
perm_num += 2;
} else if (current_let == 'x') {
document.getElementById(`${i + 1 + offset}`).checked = true;
perm_num += 1;
} else {
document.getElementById(`${i + 1 + offset}`).checked = false;
}
}
return perm_num;
}
</script>
```

114
docs/cmake.md Normal file
View File

@ -0,0 +1,114 @@
CMake 备忘清单
===
本清单提供了对 CMake 的入门简要概述,以及 CMake 常用示例
入门
---
### Hello CMake
CMake 是一个用于配置跨平台源代码项目应该如何配置的工具建立在给定的平台上。
```bash
├┈ CMakeLists.txt # 希望运行的 CMake 命令
╰┈ main.cpp # 带有 main 的源文件
```
在此项目上运行 `CMake` 时,系统会要求您提供二进制目录,运行 `CMake` 不会创建最终的可执行文件,而是会为 `Visual Studio``XCode``makefile` 生成项目文件。 使用这些工具构建该项目
#### CMakeLists.txt
```cmake
# 设置可以使用的最低 CMake 版本
cmake_minimum_required(VERSION 3.5)
# 设置项目名称
project (hello_cmake)
# 添加可执行文件
add_executable(hello_cmake main.cpp)
```
#### main.cpp
```c
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "Hello CMake!" << std::endl;
return 0;
}
```
#### 编译示例
```bash
$ mkdir build # 创建 build 目录
$ cd build # 进入目录
$ cmake .. # 目录的上一级目录运行命令
$ ./hello_cmake # 运行生成的 hello_cmake
Hello CMake!
```
### cmake
<!--rehype:wrap-class=col-span-2-->
生成项目构建系统
```bash
$ cmake [<options>] <path-to-source | path-to-existing-build>bash
$ cmake [<options>] -S <path-to-source> -B <path-to-build>
```
建立一个项目
```bash
$ cmake --build <dir> [<options>] [-- <build-tool-options>]
```
安装项目
```bash
$ cmake --install <dir> [<options>]
```
打开一个项目
```bash
$ cmake --open <dir>
```
运行脚本
```bash
$ cmake [-D <var>=<value>]... -P <cmake-script-file>
```
运行命令行工具
```bash
$ cmake -E <command> [<options>]
```
运行查找包工具
```bash
$ cmake --find-package [<options>]
```
运行工作流预设
```bash
$ cmake --workflow [<options>]
```
查看帮助
```bash
$ cmake --help[-<topic>]
```
另见
----
- [CMake Examples](http://ttroy50.github.io/cmake-examples/) _(ttroy50.github.io)_

1602
docs/colors-named.md Normal file

File diff suppressed because it is too large Load Diff

227
docs/conan.md Normal file
View File

@ -0,0 +1,227 @@
Conan 备忘清单
===
这个 [Conan](https://conan.io/) 快速参考备忘清单显示了它的常用命令使用清单
入门
---
### 介绍
Conan 是开源、去中心化和多平台的软件包,管理器来创建和共享您的所有本机二进制文件
- [Conan 官网](https://conan.io/)
#### 安装
```bash
$ pip install conan
$ pip install conan --upgrade
```
初始化配置文件
```bash
$ conan config init
```
### 显示本地客户端配置
Conan 应用配置
```bash
# 查看 Conan 主目录
$ conan config home
# 显示部分或全部配置项
$ conan config get [<section>.<config>]
# 显示完整的 conan.conf 文件
$ conan config get
# 在“日志”部分显示“级别”项
$ conan config get log.level
```
配置文件的内容(例如默认值)
```bash
$ conan profile show default
```
远程存储库
```bash
$ conan remote list
```
### 添加和修改配置
安装配置集合
```bash
$ conan config install <url>
$ conan config install ./my_config.conf
```
更改单个配置值
```bash
$ conan config set general.revisions_enabled=1
```
<!--rehype:className=wrap-text -->
添加遥控器
```bash
$ conan remote add my_remote <url>
```
提供远程凭据
```bash
$ conan user -p <password> -r my_remote <username>
```
<!--rehype:className=wrap-text -->
### 显示来自 inspect 或 reference 的信息
显示 `conanfile.py` 的属性
```bash
$ conan inspect <path> -a <attribute>
```
显示 `conanfile.py` 的内容以供参考
```bash
$ conan get <reference>
```
显示 `recipe` 的依赖关系图信息
```bash
$ conan info <path_or_reference>
```
### 搜索包
<!--rehype:wrap-class=col-span-2-->
在远程搜索包
```bash
# 列出本地缓存中的包名称
$ conan search
$ conan search <package>/<revision>@<user>/<channel> # 输出取决于给出了多少包引用。
# 支持通配符
[--table=file.html] # 将输出保存在 HTML 文件中
[-r=<remote>] # 查看远程存储库(默认为本地缓存)
$ conan search mylib/1.0@user/channel # 显示本地缓存中 mylib/1.0@user/channel 的所有包
$ conan search "zlib/*" -r=all # 在所有远程中显示所有版本的 zlib
$ conan search zlib -r conan-center
# 显示包的修订:
$ conan search <package>/<revision>@<user>/<channel> --revisions
```
### 安装包
<!--rehype:wrap-class=row-span-2-->
仅使用参考安装包
```bash
$ conan install <package_reference>
```
从 conanfile 安装软件包列表
```bash
$ cat conanfile.txt
[requires]
zlib/1.2.11
$ conan install <path_to_conanfile>
```
通过生成器在构建系统中使用包
```bash
$ cat conanfile.txt
[requires]
zlib/1.2.11
[generators]
cmake_find_package
msbuild
make
```
安装需求并生成文件
```bash
$ mkdir build && cd build
$ conan install ..
```
运行您的构建系统(以下之一)
```bash
$ cmake .. && cmake --build .
$ msbuild myproject.sln
$ make
```
### 创建一个包
从模板创建配方 (conanfile.py)
```bash
$ conan new <reference> -m <template>
```
只需将配方导出到本地缓存
```bash
$ conan export <path_to_conanfile>
```
从 recipe 为一种配置创建包
也隐含地安装和导出步骤
```bash
$ conan create . -pr <profile>
```
### 检查包裹
完整打印包装配方:
```bash
$ conan get <package>/<revision>@<user>/<channel>
$ conan get boost/1.74.0
```
<!--rehype:className=wrap-text -->
包装配方的打印属性:
```bash
$ conan inspect <package>/<revision>@<user>/<channel>
$ conan inspect boost/1.74.0
```
<!--rehype:className=wrap-text -->
请参阅 [conan get](https://docs.conan.io/en/latest/reference/commands/consumer/get.html) 和 [conan inspect](https://docs.conan.io/en/latest/reference/commands/misc/inspect.html) 参考
### Lockfiles
创建一个锁文件:
```bash
$ conan lock create <package>/conanfile.py --user=<user> --channel=<channel>
```
<!--rehype:className=wrap-text -->
`conan create``conan install` 期间使用 lockfile
```bash
$ conan <command> --lockfile conan.lock
```
查看 [conan lock](https://docs.conan.io/en/latest/reference/commands/misc/lock.html) 参考

View File

@ -1,7 +1,6 @@
Cron 备忘清单
===
[Cron](https://en.wikipedia.org/wiki/Cron) 最适合安排重复性任务。 可以使用关联的 at 实用程序来完成一次性任务的调度。
Crontab 格式
@ -27,7 +26,7 @@ Min Hour Day Mon Weekday
└───────────────────── 分钟 (0..59)
```
------
-------
| 字段 | 范围 | 特殊字符 |
|--------------|--------|--------------------|
@ -38,7 +37,6 @@ Min Hour Day Mon Weekday
| 星期几 | 0 - 6 | , - * ? / L # |
<!--rehype:className=show-header -->
### 示例
| Example | Description |
@ -56,7 +54,6 @@ Min Hour Day Mon Weekday
| `0 0 0 1 1 *` | 每年 1 月 1 日(每年) |
| `@reboot` | 每次重启 _(非标准)_ |
### 特殊字符串
| 特殊字符串 | 意义 |
@ -64,14 +61,13 @@ Min Hour Day Mon Weekday
| @reboot | 运行一次,在系统启动时 _非标准_ |
| @yearly | 每年运行一次“0 0 1 1 *” _非标准_ |
| @annually | (与@yearly 相同_非标准_ |
| @monthly | 每月运行一次“0 0 1 * *_非标准_ |
| @weekly | 每周运行一次“0 0 * * 0” _非标准_ |
| @daily | 每天运行一次“0 0 * * *” _非标准_ |
| @monthly | 每月运行一次“0 0 1 \* \*” _非标准_ |
| @weekly | 每周运行一次“0 0 \* \* 0” _非标准_ |
| @daily | 每天运行一次“0 0 \* \* \*” _非标准_ |
| @midnight | (与@daily 相同_非标准_ |
| @hourly | 每小时运行一次“0 * * * *_非标准_ |
| @hourly | 每小时运行一次“0 \* \* \* \*_非标准_ |
<!--rehype:className=show-header -->
### Crontab 命令
| - | - |
@ -82,7 +78,6 @@ Min Hour Day Mon Weekday
| `crontab -v` | 显示您上次编辑 crontab 文件的时间。 _非标准_ |
| `echo "@reboot echo hi" | crontab` | 轻松添加任务 |
### 特殊字符
<!--rehype:wrap-class=col-span-2-->
@ -95,11 +90,11 @@ Min Hour Day Mon Weekday
`L` | 仅允许用于 `月份中的某天``星期几` 字段,`星期几` 中的 `2L` 表示每个月的最后一个星期二
`井号 (#)` | 仅允许用于 `星期几` 字段,后面必须在 1 到 5 的范围内。例如,`4#1` 表示给定月份的“第一个星期四”。
`问号(?)` | 可以代替“*”并允许用于月份和星期几。使用仅限于 cron 表达式中的 `月份中的某天``星期几`
<!--rehype:className=show-header -->
<!--rehype:className=show-header auto-wrap-->
另见
----
## Also see
* [Devhints](https://devhints.io/cron) _(devhints.io)_
* [Crontab Generator](https://crontab-generator.org/) _(crontab-generator.org)_
* [Crontab guru](https://crontab.guru/) _(crontab.guru)_
- [Devhints](https://devhints.io/cron) _(devhints.io)_
- [Crontab Generator](https://crontab-generator.org/) _(crontab-generator.org)_
- [Crontab guru](https://crontab.guru/) _(crontab.guru)_

1436
docs/css.md Normal file

File diff suppressed because it is too large Load Diff

284
docs/curl.md Normal file
View File

@ -0,0 +1,284 @@
Curl 备忘清单
===
此 [Curl](https://github.com/curl/curl) 备忘清单包含命令和一些常见的 Curl 技巧示例。
入门
----
### 介绍
Curl 是一种在服务器之间传输数据的工具,支持协议,包括 HTTP/FTP/IMAP/LDAP/POP3/SCP/SFTP/SMB/SMTP 等
- [Curl GitHub 源码仓库](https://github.com/curl/curl) _(github.com)_
- [Curl 官方网站](https://curl.se/) _(curl.se)_
### Options
<!--rehype:wrap-class=col-span-2 row-span-2-->
```bash
-o <file> # --output: 写入文件
-u user:pass # --user: 验证
```
---
```bash
-v # --verbose: 在操作期间使 curl 冗长
-vv # 更冗长
-s # --silent: 不显示进度表或错误
-S # --show-error: 与 --silent (-sS) 一起使用时,显示错误但没有进度表
```
---
```bash
-i # --include: 在输出中包含 HTTP 标头
-I # --head: 仅标头
```
### 请求
```bash
-X POST # --request
-L # 如果页面重定向,请点击链接
-F # --form: multipart/form-data 的 HTTP POST 数据
```
<!--rehype:className=wrap-text -->
### 数据
```bash
# --data: HTTP post 数据
# URL 编码(例如status="Hello")
-d 'data'
# --data 通过文件
-d @file
# --get: 通过 get 发送 -d 数据
-G
```
### 头信息 Headers
```bash
-A <str> # --user-agent
-b name=val # --cookie
-b FILE # --cookie
-H "X-Foo: y" # --header
--compressed # 使用 deflate/gzip
```
### SSL
```bash
--cacert <file>
--capath <dir>
```
```bash
-E, --cert <cert> # --cert: 客户端证书文件
--cert-type # der/pem/eng
-k, --insecure # 对于自签名证书
```
#### 安装
```bash
apk add --update curl # alpine linux 中安装
```
示例
----
<!--rehype:body-class=cols-6-->
### CURL GET/HEAD
<!--rehype:wrap-class=col-span-4 row-span-2-->
命令 | 说明
:- | :-
`curl -I https://www.baidu.com` | `curl` 发请求
`curl -v -I https://www.baidu.com` | 带有详细信息的 `curl` 发请求
`curl -X GET https://www.baidu.com` | 使用显式 http 方法进行 `curl`
`curl --noproxy 127.0.0.1 http://www.stackoverflow.com` | 没有 http 代理的 `curl`
`curl --connect-timeout 10 -I -k https://www.baidu.com` | `curl` 默认没有超时
`curl --verbose --header "Host: www.mytest.com:8182" www.baidu.com` | `curl` 得到额外的标题
`curl -k -v https://www.google.com` | `curl` 获取带有标题的响应
<!--rehype:class=auto-wrap-->
### 多文件上传
<!--rehype:wrap-class=col-span-2-->
```bash
$ curl -v -include \
--form key1=value1 \
--form upload=@localfilename URL
```
### 为 curl 响应美化 json 输出
<!--rehype:wrap-class=col-span-2-->
```bash
$ curl -XGET http://${elasticsearch_ip}:9200/_cluster/nodes | python -m json.tool
```
<!--rehype:className=wrap-text -->
### CURL POST
<!--rehype:wrap-class=col-span-4-->
命令 | 说明
:- | :-
`curl -d "name=username&password=123456" <URL>` | `curl` 发请求
`curl <URL> -H "content-type: application/json" -d "{ \"woof\": \"bark\"}"` | `curl` 发送 json
<!--rehype:class=auto-wrap-->
### CURL 脚本安装 rvm
<!--rehype:wrap-class=col-span-2-->
```shell
curl -sSL https://get.rvm.io | bash
```
### CURL 高级
<!--rehype:wrap-class=col-span-6-->
命令 | 说明
:- | :-
`curl -L -s http://ipecho.net/plain, curl -L -s http://whatismijnip.nl` | 获取我的公共 `IP`
`curl -u $username:$password http://repo.dennyzhang.com/README.txt` | 带凭证的 `curl`
`curl -v -F key1=value1 -F upload=@localfilename <URL>` | `curl` 上传
`curl -k -v --http2 https://www.google.com/` | 使用 http2 curl
`curl -T cryptopp552.zip -u test:test ftp://10.32.99.187/` | curl `ftp` 上传
`curl -u test:test ftp://10.32.99.187/cryptopp552.zip -o cryptopp552.zip` | curl `ftp` 下载
`curl -v -u admin:admin123 --upload-file package1.zip http://mysever:8081/dir/package1.zip` | 使用凭证 `curl` 上传
<!--rehype:class=auto-wrap-->
### 检查网站响应时间
<!--rehype:wrap-class=col-span-4-->
```shell
curl -s -w \
'\nLookup time:\t%{time_namelookup}\nConnect time:\t%{time_connect}\nAppCon time:\t%{time_appconnect}\nRedirect time:\t%{time_redirect}\nPreXfer time:\t%{time_pretransfer}\nStartXfer time:\t%{time_starttransfer}\n\nTotal time:\t%{time_total}\n' \
-o /dev/null https://www.google.com
```
<!--rehype:className=wrap-text -->
### 使用 Curl 检查远程资源是否可用
<!--rehype:wrap-class=col-span-2-->
```bash
curl -o /dev/null --silent -Iw "%{http_code}" https://example.com/my.remote.tarball.gz
```
<!--rehype:className=wrap-text -->
### 正在下载文件
<!--rehype:wrap-class=col-span-3-->
```bash
curl https://example.com | \
grep --only-matching 'src="[^"]*.[png]"' | \
cut -d\" -f2 | \
while read i; do curl https://example.com/"${i}" \
-o "${i##*/}"; done
```
从站点下载所有 PNG 文件使用GNU grep
### 下载文件,保存文件而不更改其名称
<!--rehype:wrap-class=col-span-3-->
```bash
curl --remote-name "https://example.com/linux-distro.iso"
```
重命名文件
```bash
curl --remote-name "http://example.com/index.html" --output foo.html
```
### 继续部分下载
<!--rehype:wrap-class=col-span-3-->
```bash
curl --remote-name --continue-at - "https://example.com/linux-distro.iso"
```
<!--rehype:className=wrap-text -->
### 从多个域下载文件
<!--rehype:wrap-class=col-span-3-->
```bash
curl "https://www.{example,w3,iana}.org/index.html" --output "file_#1.html"
```
<!--rehype:className=wrap-text -->
### 下载一系列文件
<!--rehype:wrap-class=col-span-3-->
```bash
curl "https://{foo,bar}.com/file_[1-4].webp" --output "#1_#2.webp"
```
<!--rehype:className=wrap-text -->
下载一系列文件(输出`foo_file1.webp``foo_file2.webp…bar_file1_webp`等)
### 将输出重定向到文件
<!--rehype:wrap-class=col-span-3-->
```bash
$ curl http://url/file > file
```
### 基本认证
<!--rehype:wrap-class=col-span-3-->
```bash
$ curl --user username:password http://example.com/
$ curl -u username:password http://example.com/
```
### 写入文件而不是标准输出
<!--rehype:wrap-class=col-span-2-->
```bash
$ curl -o file http://url/file
$ curl --output file http://url/file
```
### 下载头信息
```bash
$ curl -I url
# 显示头信息
```
### 将输出写入名为远程文件的文件
<!--rehype:wrap-class=col-span-2-->
```bash
$ curl -o file http://url/file
$ curl --output file http://url/file
```
### 执行远程脚本
<!--rehype:wrap-class=col-span-2-->
```bash
$ curl -s http://url/myscript.sh
```
### 配置文件
<!--rehype:wrap-class=col-span-2-->
```bash
curl -K file
# 从文件中读取配置
curl --config file
$HOME/.curlrc # 类 UNIX 系统中的默认配置文件
```

598
docs/dart.md Normal file
View File

@ -0,0 +1,598 @@
Dart 备忘清单
===
包含最重要概念、功能、方法等的 [Dart](https://dart.dev/) 备忘单。初学者的完整快速参考
入门
-----
### 安装 Dart
<!--rehype:wrap-class=row-span-2-->
#### Windows
```bash
C:\> choco install dart-sdk # Windows
```
#### Linux
执行以下一次性设置
```bash
$ sudo apt-get update
$ sudo apt-get install apt-transport-https
$ wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/dart.gpg
$ echo 'deb [signed-by=/usr/share/keyrings/dart.gpg arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main' | sudo tee /etc/apt/sources.list.d/dart_stable.list
```
安装 Dart SDK
```bash
$ sudo apt-get update
$ sudo apt-get install dart
```
#### Mac
```bash
$ brew tap dart-lang/dart
$ brew install dart
```
### hello.dart
```dart
// 应用执行开始的顶级函数
void main() {
print("Hello World!"); // 打印到控制台
}
```
每个应用程序都有一个 `main()` 函数
#### Windows
```bash
$ dart compile exe hellow.dart
$ time ./hello.exe
Hello World!
```
### 变量
```dart
int x = 2; // 显式键入
var p = 5; // 类型推断 - 具有类型推断的通用var
dynamic z = 8; // 变量可以采用任何类型
z = "cool"; // cool
// 如果您从不打算更改变量,请使用 final 或 const
// 像这样的东西:
final email = "temid@gmail.com";
// 与 var 相同,但不能重新分配
final String email = "temid@gmail.com";
// 你不能改变价值
const qty = 5; // 编译时常数
```
### 数据类型
<!--rehype:wrap-class=row-span-2-->
```dart
// 整数,范围 -2^63 到 2^63 - 1
int age = 20;
// 浮点数字
double height = 1.85;
// 您还可以将变量声明为 num
// x 可以同时具有 int 和 double 值
num x = 1;
num += 2.5;
print(num); // 打印: 3.5
String name = "Nicola";
bool isFavourite = true;
bool isLoaded = false;
```
### 注释
```dart
// 这是一条正常的单行注释
/// 这是一个文档注释,用于文档库,
/// 类及其成员。 IDE 和 dartdoc 等工具
/// doc 特别注释。
/* 也支持此类注释 */
```
### 字符串插值
```dart
// 可以对字符串类型使用单引号或双引号
var firstName = 'Nicola';
var lastName = "Tesla";
// 可以用 $ 将变量嵌入到字符串中
String fullName = "$firstName $lastName";
// 与 + 连接
var name = "Albert " + "Einstein";
String upperCase = '${firstName.toUpperCase()}';
print(upperCase); // 打印: NICOLA
```
<!--rehype:className=wrap-text -->
### 导入 Imports
```dart
// 导入核心库
import 'dart:math';
// 从外部包导入库
import 'package:test/test.dart';
// 导入文件
import 'path/to/my_other_file.dart';
```
操作符
-------
### 算术运算符
<!--rehype:wrap-class=row-span-2-->
```dart
print(2 + 3); // 打印: 5
print(2 - 3); // 打印: -1
print(2 * 3); // 打印: 6
print(5 / 2); // 打印: 2.5 - 结果是 double
print(5 ~/ 2); // 打印: 2 - 结果是n int
print(5 % 2); // 打印: 1 - 余
int a = 1, b;
```
----
```dart
// 增
b = ++a; // 前增量 - 在 b 获得其值之前增加 a
b = a++; // 后增量 - 在 b 获得它的值之后增加 a
// 递
b = --a; // 前减量 - 在 b 获得它的值之前减少 a
b = a--; // 后减量 - 在 b 获得它的值之后递减 a
```
### 逻辑运算符
<!--rehype:wrap-class=col-span-2-->
```dart
// !expr 反转表达式(将 false 更改为 true反之亦然
// || 逻辑或
// && 逻辑与
bool isOutOfStock = false;
int quantity = 3;
if (!isOutOfStock && (quantity == 2 || quantity == 3)) {
// ...Order the product...
}
```
### 等式和关系运算符
```dart
print(2 == 2); // 打印: true - 平等的
print(2 != 3); // 打印: true - 不相等
print(3 > 2); // 打印: true - 比...更棒
print(2 < 3); // 打印: true - 少于
print(3 >= 3); // 打印: true - 大于或等于
print(2 <= 3); // 打印: true - 小于或等于
```
控制流:条件
------
### if 和 else if
```dart
if(age < 18){
print("Teen");
} else if( age > 18 && age <60){
print("Adult");
} else {
print("Old");
}
```
### switch case
```dart
enum Pet {dog, cat}
Pet myPet = Pet.dog;
switch(myPet){
case Pet.dog:
print('My Pet is Dog.');
break;
case Pet.cat:
print('My Pet is Cat.');
break;
default:
print('I don\'t have a Pet');
}
// 打印: My Pet is Dog.
```
控制流:循环
-----
### while 循环
```dart
while (!dreamsAchieved) {
workHard();
}
```
循环迭代之前的 `while` 循环检查条件
### do-while 循环
```dart
do {
workHard();
} while (!dreamsAchieved);
```
`do-while` 循环在执行循环内的语句后验证条件
### for 循环
```dart
for(int i=0; i< 10; i++){
print(i);
}
var numbers = [1,2,3];
// 列表的 for-in 循环
for(var number in numbers){
print(number);
}
```
Collections
------------
### Lists
<!--rehype:wrap-class=col-span-2-->
```dart
// 有序的对象组
var list = [1, 2, 3];
print(list.length); //Print: 3
print(list[1]); //Print: 2
// 列表声明和初始化的其他方式
List<String> cities = <String>["New York", "Mumbai", "Tokyo"];
// 创建一个编译时常量的列表
const constantCities = const ["New York", "Mumbai", "Tokyo"];
```
### Maps
<!--rehype:wrap-class=row-span-2-->
```dart
// 映射是关联键和值的对象
var person = Map<String, String>();
// 要初始化地图,请执行以下操作:
person['firstName'] = 'Nicola';
person['lastName'] = 'Tesla';
print(person);
// 打印: {firstName:Nicola, lastName:Tesla}
print(person['lastName']);
// 打印: Tesla
var nobleGases = {
// Key: Value
2: 'helium',
10: 'neon',
18: 'argon',
};
```
### Sets
<!--rehype:wrap-class=col-span-2-->
```dart
// Dart 中的集合是唯一项的无序集合
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
// 创建一个空集
var names = <String>{};
Set<String> names = {}; // 这也有效
//var names = {}; // 创建地图,而不是集合
```
函数
------
### 函数示例
```dart
// dart 中的函数是对象并且有一个类型
int add(int a, int b){
return a+b;
}
// 函数可以分配给变量
int sum = add(2,3); // 回报5
// 可以作为参数传递给其他函数
int totalSum = add(2, add(2,3)); // 返回7
```
### 箭头语法 (=>)
```dart
// 只包含一个表达式的函数,您可以使用简写语法
bool isFav(Product product) => favProductsList.contains(product);
```
<!--rehype:className=wrap-text-->
### Anonymous (lambda) functions
```dart
// 没有名字的小单行函数
int add(a,b) => a+b;
// lambda 函数大多作为参数传递给其他函数
const list = [
'apples', 'bananas', 'oranges'
];
list.forEach(
(item) =>
print('${list.indexOf(item)}: $item')
);
// 打印: 0: apples 1: bananas 2: oranges
```
<!--rehype:className=wrap-text-->
类和对象
----------
### 类 Class
```dart
class Cat {
String name;
// 方法
void voice(){
print("Meow");
}
}
```
### 对象 Object
```dart
// 类的实例
// 在 myCat 下面是 Cat 类的对象
void main(){
Cat myCat = Cat();
myCat.name = "Kitty";
myCat.voice(); // 打印: Meow
}
```
### 构造函数
```dart
class Cat {
String name;
Cat(this.name);
}
void main(){
Cat myCat = Cat("Kitty");
print(myCat.name); // 打印: Kitty
}
```
### 抽象类
```dart
// 抽象类——不能实例化的类
// 这个类被声明为抽象的,因此不能被实例化
abstract class AbstractContainer {
// 定义构造函数、字段、方法...
void updateChildren(); // 抽象方法
}
```
### Getters Setters
```dart
// 提供对对象属性的读写访问
class Cat {
String name;
// getter
String get catName {
return name;
}
// setter
void set catName(String name){
this.name = name;
}
}
```
隐式接口
------------
### 一个基本的界面
<!--rehype:wrap-class=col-span-2-->
```dart
// 一个人。隐式接口包含 greet()。
class Person {
// 在接口中,但仅在此库中可见。
final String _name;
// 不在接口中,因为这是一个构造函数。
Person(this._name);
// 在接口中
String greet(String who) => 'Hello, $who. I am $_name.';
}
// Person 接口的实现。
class Impostor implements Person {
String get _name => '';
String greet(String who) => 'Hi $who. Do you know who I am?';
}
String greetBob(Person person) => person.greet('Bob');
void main() {
print(greetBob(Person('Kathy')));
// 打印: Hello, Bob. I am Kathy.
print(greetBob(Impostor()));
// 打印: Hi Bob. Do you know who I am?
}
```
### 扩展类
```dart
class Phone {
void use(){
_call();
_sendMessage();
}
}
// 使用 extends 创建子类
class SmartPhone extends Phone {
void use(){
// 使用 super 来引用超类
super.use();
_takePhotos();
_playGames();
}
}
```
异常
-----
### Throw
```dart
// 抛出 throws 或引发 raises 和异常 exception
throw IntegerDivisionByZeroException();
// 你也可以抛出任意对象
throw "Product out of stock!";
```
### Catch
```dart
try {
int c = 3/0;
print(c);
} on IntegerDivisionByZeroException {
// 一个特定的异常
print('Can not divide integer by 0.')
} on Exception catch (e) {
// 任何其他异常情况
print('Unknown exception: $e');
} catch (e) {
// 没有指定类型,处理所有
print('Something really unknown: $e');
}
```
### Finally
```dart
// 确保某些代码无论是否抛出异常都能运行
try {
cookFood();
} catch (e) {
print('Error: $e'); // 先处理异常
} finally {
cleanKitchen(); // 然后清理
}
```
Futures
------------
### Async Await
```dart
// 异步函数:它们在设置可能耗时的操作后返回
// async 和 await 关键字支持异步编程
Future<String> login() {
String userName="Temidjoy";
return
Future.delayed(
Duration(seconds: 4), () => userName
);
}
// 异步
main() async {
print('Authenticating please wait...');
print(await userName());
}
```
各种各样的
------------
### Null 和 Null 感知
<!--rehype:wrap-class=col-span-2-->
```dart
int x; // 任何对象的初始值为 null
// ?? 空感知运算符
x ??=6; // ??= 赋值运算符,仅当变量当前为 null 时才为其赋值
print(x); // 打印: 6
x ??=3;
print(x); // 打印: 6 - 结果仍然是 6
print(null ?? 10); // 打印: 10。如果不为空则显示左侧的值否则返回右侧的值
```
### 三元运算符
```dart
// 条件 ? 条件如果为真 : 条件如果为假
bool isAvailable;
isAvailable ? orderproduct() : addToFavourite();
```
<!--rehype:className=wrap-text-->
### 条件属性访问
<!--rehype:wrap-class=col-span-2-->
```dart
userObject?.userName
// 上面的代码片段等效于以下代码:
(userObject != null) ? userObject.userName : null
// 您可以将 ? 的多种用途链接起来。一起在一个表达式中
userObject?.userName?.toString()
// 如果 userObject 或 userObject.userName 为 null则前面的代码返回 null 并且从不调用 toString()
```
### 级联符号 (..)
<!--rehype:wrap-class=row-span-2-->
```dart
// 允许您对同一对象进行一系列操作
// 而不是这样做
var user = User();
user.name = "Nicola";
user.email = "nicola@g.c";
user.age = 24;
// 你可以这样做
var user = User()
..name = "Nicola"
..email = "nicola@g.c"
..age = 24;
```
### 扩展运算符 (...)
```dart
// 将多个值插入到集合中
var list = [1, 2, 3];
var list2 = [0, ...list];
print(list2.length); // 打印: 4
```
另见
----
- [Dart 官方文档](https://dart.dev/) _(dart.dev)_

781
docs/djiango.md Normal file
View File

@ -0,0 +1,781 @@
Django 备忘清单
===
Django 是 Python 的一款 Web 框架,本备忘单旨在快速理解 [Django](https://www.djangoproject.com/) 所涉及的主要概念,提供了最常用的 API 示例参考
入门
----
### 准备环境
<!--rehype:wrap-class=row-span-1-->
```bash
$ python --version
# Python 3.9.2
$ pip --version
# pip 20.2.3 from c:\python39\lib\site-packages\pip (python 3.9)
```
<!--rehype:className=wrap-text -->
如果你没有安装 PIP你可以从这个页面下载并安装它<https://pypi.org/project/pip/>
### 入门
<!--rehype:wrap-class=row-span-4-->
- 创建虚拟环境
```bash
$ py -m venv myproject # Windows
$ python -m venv myproject # Unix/MacOS
```
- 其中包含子文件夹和文件,如下所示
```bash
myproject
├┈Include
├┈Lib
├┈Scripts
╰┈pyvenv.cfg
```
- 以下命令来激活环境
```bash
# Windows:
myproject\Scripts\activate.bat
# Unix/MacOS:
source myproject/bin/activate
```
- 提示符中看到以下结果:
```bash
# Windows:
(myproject) C:\Users\Your Name>
# Unix/MacOS:
(myproject) ... $
```
- 安装 Django
```bash
# Windows:
(myproject) C:\Users\Name>py -m pip install Django
# Unix/MacOS:
(myproject) ... $ python -m pip install Django
```
<!--rehype:className=wrap-text -->
<!--rehype:className=style-timeline-->
### 创建项目
<!--rehype:wrap-class=row-span-3-->
```bash
$ django-admin startproject myworld
```
创建了一个 `myworld` 文件夹,内容如下:
```bash
myworld
├┈ manage.py
╰┈ myworld/
├┈ __init__.py
├┈ asgi.py
├┈ settings.py
├┈ urls.py
╰┈ wsgi.py
```
运行 Django 项目
```bash
$ py manage.py runserver # Windows
$ python manage.py runserver # Unix/MacOS
```
打开一个新的浏览器窗口并在地址栏中输入 127.0.0.1:8000
### 检查 Django 版本
```bash
(myproject) C:\Users\Your Name>django-admin --version
# 4.0.3
```
### 创建应用
<!--rehype:wrap-class=row-span-2-->
```bash
$ py manage.py startapp members
```
项目中创建了一个名为 `members` 的文件夹,内容如下:
```bash
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ migrations/
┆ ╰┈ __init__.py
├┈ __init__.py
├┈ admin.py
├┈ apps.py
├┈ models.py
├┈ tests.py
╰┈ views.py
```
首先,看一下名为 `views.py` 的文件。这是我们收集发送回正确响应所需的信息的地方。
### 应用目录介绍
- `Django` 接收 URL检查 `urls.py` 文件,并调用与 URL 匹配的视图。
- 位于 `views.py` 中的视图检查相关模型。
- 模型是从 `models.py` 文件中导入的。
- 然后视图将数据发送到模板文件夹中的指定模板。
- 模板包含 `HTML` 和 `Django` 标记,并使用数据将完成的 `HTML` 内容返回给浏览器
### 视图
Django 视图是接受 `http` 请求并返回 `http` 响应的 `Python` 函数,就像 `HTML` 文档一样。
使用 `Django` 的网页充满了不同任务和任务的视图。
视图通常放在一个名为 `views.py` 的文件中,该文件位于应用程序的文件夹中。
您的 `members` 文件夹中有一个 `views.py`,如下所示:
```PY
from django.shortcuts import render
# Create your views here.
```
找到它并打开它,并将内容替换为:
```PY
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello world!")
```
这是一个关于如何将响应发送回浏览器的简单示例。
但是我们如何执行视图呢? 好吧,我们必须通过 URL 调用视图。
### URLs
在与 `views.py` 文件相同的文件夹中创建一个名为 `urls.py` 的文件,并在其中输入以下代码:
```py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
```
刚刚创建的 `urls.py` 文件是特定于成员应用程序的。我们还必须在根目录 `myworld` 中进行一些路由。
在 `myworld` 文件夹中有一个名为 `urls.py` 的文件,打开该文件并在 `import` 语句中添加 `include` 模块,并在列表中添加一个 `path()` 函数。文件将如下所示:
```py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('members/', include('members.urls')),
path('admin/', admin.site.urls),
]
```
如果服务器未运行,请导航到 `/myworld` 文件夹并在命令提示符下执行此命令:
```bash
$ py manage.py runserver
```
在浏览器窗口的地址栏中输入 `127.0.0.1:8000/members/`
### 模板
<!--rehype:wrap-class=row-span-2-->
在 `members` 文件夹中创建一个 `templates` 文件夹,并创建一个名为 `myfirst.html` 的 `HTML` 文件。文件结构应该是这样的:
```bash
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
╰┈ templates/
╰┈ myfirst.html
```
打开 `HTML` 文件并插入以下内容:
```html
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
<p>欢迎来到我的第一个 Django 项目!</p>
</body>
</html>
```
修改视图 `members/views.py`
```py
from django.http import HttpResponse
from django.template import loader
def index(request):
template = loader.get_template('myfirst.html')
return HttpResponse(template.render())
```
#### 更改设置
为了能够处理比“Hello World”更复杂的东西我们必须告诉 `Django` 一个新的应用程序已创建
这是在 `myworld` 文件夹的 `myworld/settings.py` 文件中完成的。查找 `INSTALLED_APPS[]` 列表并添加成员应用程序,如下所示:
```py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'members.apps.MembersConfig'
]
```
然后运行这个命令:
```bash
$ py manage.py migrate
```
通过导航到 `/myworld` 文件夹启动服务器并执行以下命令:
```bash
$ py manage.py runserver
```
在浏览器窗口的地址栏中输入 127.0.0.1:8000/members/
### 创建表(模型)
<!--rehype:wrap-class=col-span-2-->
在 `/members/` 文件夹中,打开 `models.py` 文件。要在我们的数据库中添加成员表,首先创建一个成员类,并描述其中的表字段:
```py
from django.db import models
class Members(models.Model):
firstname = models.CharField(max_length=255)
lastname = models.CharField(max_length=255)
```
然后导航到 `/myworld/` 文件夹并运行以下命令:
```bash
$ py manage.py makemigrations members
# Migrations for 'members':
# members\migrations\0001_initial.py
# - Create model Members
```
创建一个包含任何新更改的文件并将该文件存储在 `/migrations/` 文件夹中。下次运行 `py manage.py migrate` 时Django 将根据迁移文件夹中新文件的内容创建并执行一条 SQL 语句。运行迁移命令:
```bash
$ py manage.py migrate
```
从模型创建的 SQL 语句是:
```sql
CREATE TABLE "members_members" (
"id" INT NOT NULL PRIMARY KEY AUTOINCREMENT,
"firstname" varchar(255) NOT NULL,
"lastname" varchar(255) NOT NULL
);
```
Django 模板
---
### 模板变量
<!--rehype:wrap-class=col-span-2 row-span-2-->
```django
<!-- template.html -->
<h1>你好 {{ firstname }},你好吗?</h1>
```
在视图 (`views.py`) 中创建变量,上面示例中的变量 `firstname` 通过视图发送到模板:
```py
from django.http import HttpResponse
from django.template import loader
def testing(request):
template = loader.get_template('template.html')
context = {
'firstname': '狂徒张三',
}
return HttpResponse(template.render(context, request))
```
### 模板中创建变量
```django
{% with firstname="Tobias" %}
<h1>你好 {{ firstname }},你好吗?</h1>
```
### 数组循环
```django
<ul>
{% for x in mymembers %}
<li>{{ x.firstname }}</li>
{% endfor %}
</ul>
```
### 模板标签参考
<!--rehype:wrap-class=row-span-5-->
标签 | 描述
:- | :-
`autoescape` | 指定自动转义模式是打开还是关闭
`block` | 指定块部分
`comment` | 指定注释部分
`csrf_token` | 保护表单免受跨站点请求伪造
`cycle` | 指定要在循环的每个循环中使用的内容
`debug` | 指定调试信息
`extends` | 指定父模板
`filter` | 在返回之前过滤内容
`firstof` | 返回第一个非空变量
`for` | 指定一个 for 循环
`if` | 指定一个 if 语句
`ifchanged` | 仅当自上次迭代以来值已更改时才输出块<br> _(用于 for 循环)_
`include` | 指定包含的内容/模板
`load` | 从另一个库加载模板标签
`lorem` | 输出随机文本
`now` | 输出当前日期/时间
`regroup` | 按组对对象进行排序
`resetcycle` | 循环使用,重置循环
`spaceless` | 删除 HTML 标签之间的空格
`templatetag` | 输出指定的模板标签
`url` | 返回 URL 的绝对 URL 部分
`verbatim` | 指定不应由模板引擎呈现的内容
`widthratio` | 给定值和最大值之间的比率计算宽度值
`with` | 指定要在块中使用的变量
<!--rehype:className=show-header-->
### If 语句
```django
{% if greeting == 1 %}
<h1>Hello</h1>
{% elif greeting == 2 %}
<h1>Welcome</h1>
{% else %}
<h1>Goodbye</h1>
{% endif %}
```
### For 循环
<!--rehype:wrap-class=row-span-2-->
```django
{% for x in cars %}
<h1>{{ x.brand }}</h1>
<p>{{ x.model }}</p>
<p>{{ x.year }}</p>
{% endfor %}
```
数据 cars 空的展示内容:
```django
<ul>
{% for x in cars %}
<h1>{{ x.brand }}</h1>
<p>{{ x.model }}</p>
<p>{{ x.year }}</p>
{% empty %}
<li>No members</li>
{% endfor %}
</ul>
```
### 循环变量
<!--rehype:wrap-class=row-span-2-->
- `forloop.counter` 当前循环,从 1 开始
- `forloop.counter0` 当前循环,从 0 开始
- `forloop.first` 循环是否在其第一次循环中
- `forloop.last` 循环是否在其最后一次循环中
- `forloop.parentloop`
- `forloop.revcounter` 如果从末尾开始并向后计数,则以 1 结束
- `forloop.revcounter0` 如果从末尾开始并向后计数,则以 0 结束
### 过滤值
```django
<h1>你好 {{ firstname|upper }},你好吗?</h1>
```
返回带有大写字母的变量名
### 注释
<!--rehype:wrap-class=row-span-2-->
```django
<h1>欢迎大家{# 较小的注释 #}</h1>
{% comment %}
<h1>欢迎女士们先生们</h1>
{% endcomment %}
```
#### 注释描述
```django
<h1>欢迎大家{# 较小的注释 #}</h1>
{% comment "这是最初的欢迎信息" %}
<h1>欢迎女士们先生们</h1>
{% endcomment %}
```
注释允许您拥有应该被忽略的代码部分
### 双过滤值
```django
<h1>你好 {{ firstname|first|upper }},你好吗?</h1>
```
返回变量 `firstname` 的第一个字符,小写
### 过滤器标签
```django
{% filter upper %}
<h1>Hello everyone, how are you?</h1>
{% endfilter %}
```
返回内容大写
### cycle
<!--rehype:wrap-class=col-span-2 row-span-3-->
如果你想为每次循环使用新的背景颜色,你可以使用 `cycle` 标签来做到这一点
```django
<ul>
{% for x in members %}
<li style='background-color:{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' %}'>
{{ x.firstname }}
</li>
{% endfor %}
</ul>
```
将参数值保存在变量中,以便以后使用:
```django
<ul>
{% for x in members %}
{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' as bgcolor silent %}
<li style='background-color:{{ bgcolor }}'>
{{ x.firstname }}
</li>
{% endfor %}
</ul>
```
你注意到 `silent` 关键字了吗? 确保添加这个,否则参数值将在输出中显示两次
```django
<ul>
{% for x in members %}
{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' as bgcolor silent %}
{% if forloop.counter == 3 %}
{% resetcycle %}
{% endif %}
<li style='background-color:{{ bgcolor }}'>
{{ x.firstname }}
</li>
{% endfor %}
</ul>
```
您可以使用 `{% resetcycle %}` 标签强制循环重新开始
### 每一行添加行号
```django
{% filter upper|linenumbers %}Hello!
my name is
Emil.
What is your name?{% endfilter %}
```
返回内容`大写`并在每一行添加`行号`
### 导入模板
`footer.html`:
```django
<p>您已到达本页底部,感谢您抽出宝贵时间</p>
```
`template.html`:
```django
<h1>Hello</h1>
<p>此页面包含模板中的页脚</p>
{% include 'footer.html' %}
```
### 导入模板传入变量
`mymenu.html`:
```django
<div>HOME | {{ me }} | ABOUT | FORUM | {{ sponsor }}</div>
```
<!--rehype:className=wrap-text -->
`template.html`:
```django
{% include mymenu.html with me="张三" sponsor="Reference" %}
<h1>Welcome</h1>
<p>This is my webpage</p>
```
<!--rehype:className=wrap-text -->
### 过滤器参考
<!--rehype:wrap-class=col-span-2 row-span-2-->
Keyword | 描述
:- | :-
`add` | 添加指定的值
`addslashes` | 在任何引号字符之前添加一个斜杠,以转义字符串
`capfirst` | 返回大写的第一个字母
`center` | 使值在指定宽度的中间居中
`cut` | 删除任何指定的字符或短语
`date` | 以指定格式返回日期
`default` | 如果值为 `False`,则返回指定值
`default_if_none` | 如果值为 `None`,则返回指定的值
`dictsort` | 按给定值对字典进行排序
`dictsortreversed` | 按给定值对字典进行反向排序
`divisibleby` | 如果该值可以除以指定的数字,则返回 `True`,否则返回 `False`
`escape` | 从字符串中转义 `HTML` 代码
`escapejs` | 从字符串中转义 `JavaScript` 代码
`filesizeformat` | 将数字返回为文件大小格式
`first` | 返回对象的第一项(对于字符串,返回第一个字符)
`floatformat` | 将浮点数四舍五入到指定的小数位数,默认为一位小数
`force_escape` | 从字符串中转义 `HTML` 代码
`get_digit` | 返回数字的特定数字
`iriencode` | 将 `IRI` 转换为 `URL` 友好字符串
`join` | 将列表中的项目返回为字符串
`json_script` | 将一个对象返回为由 `<script></script>` 标签包围的 `JSON` 对象
`last` | 返回对象的最后一项(对于字符串,返回最后一个字符)
`length` | 返回对象中的项目数,或字符串中的字符数
`length_is` | 如果长度与指定的数字相同,则返回 `True`
`linebreaks` | 返回带有 `<br>` 而不是换行符和 `<p>` 而不是多个换行符的文本
`linebreaksbr` | 返回带有 `<br>` 的文本,而不是换行符
`linenumbers` | 返回每行带有行号的文本
`ljust` | 根据指定的宽度左对齐值
`lower` | 以小写字母返回文本
`make_list` | 将值转换为列表对象
`phone2numeric` | 将带字母的电话号码转换为数字电话号码
`pluralize` | 如果指定的数值不是 `1`,则在值的末尾添加一个 `s`
`pprint` |
`random` | 返回对象的随机项
`rjust` | 根据指定的宽度右对齐值
`safe` | 标记此文本是安全的,不应进行 `HTML` 转义
`safeseq` | 将对象的每个项目标记为安全且项目不应进行 `HTML` 转义
`slice` | 返回文本或对象的指定切片
`slugify` | 将文本转换为一个长字母数字小写单词
`stringformat` | 将值转换为指定格式
`striptags` | 从文本中删除 `HTML` 标记
`time` | 以指定格式返回时间
`timesince` | 返回两个日期时间之间的差
`timeuntil` | 返回两个日期时间之间的差
`title` | 文本中每个单词的第一个字符大写,所有其他字符都转换为小写
`truncatechars` | 将字符串缩短为指定数量的字符
`truncatechars_html` | 将字符串缩短为指定数量的字符,而不考虑任何 `HTML` 标记的长度
`truncatewords` | 将字符串缩短为指定数量的单词
`truncatewords_html` | 将字符串缩短为指定数量的单词,而不考虑任何 `HTML` 标记
`unordered_list` | 将对象的项目返回为无序列的 `HTML` 列表
`upper` | 以大写字母返回文本
`urlencode` | `URL` 对字符串进行编码
`urlize` | 将字符串中的任何 `URL` 作为 `HTML` 链接返回
`urlizetrunc` | 将字符串中的任何 `URL` 作为 `HTML` 链接返回,但会将链接缩短为指定的字符数
`wordcount` | 返回文本中的单词数
`wordwrap` | 以指定的字符数换行
`yesno` | 将布尔值转换为指定值
`i18n` |
`l10n` |
`tz` |
### 字段查询参考
Keyword | 描述
:- | :-
`contains` | 包含短语
`icontains` | 与包含相同,但不区分大小写
`date` | 匹配日期
`day` | 匹配日期(日期1-31)(日期)
`endswith` | 以。。结束
`iendswith` | 与 endwidth 相同,但不区分大小写
`exact` | 完全匹配
`iexact` | 与精确相同,但不区分大小写
`in` | 匹配其中一个值
`isnull` | 匹配 NULL 值
`gt` | 比...更棒
`gte` | 大于或等于
`hour` | 匹配一个小时(对于日期时间)
`lt` | 少于
`lte` | 小于或等于
`minute` | 匹配一分钟(对于日期时间)
`month` | 匹配一个月(日期)
`quarter` | 匹配一年中的一个季度 (1-4)(用于日期)
`range` | 之间的匹配
`regex` | 匹配正则表达式
`iregex` | 与正则表达式相同,但不区分大小写
`second` | 匹配一秒(对于日期时间)
`startswith` | 以 ... 开始
`istartswith` | 与 `startswith` 相同,但不区分大小写
`time` | 匹配时间(用于日期时间)
`week` | 匹配周数 (`1-53`)(用于日期)
`week_day` | 匹配一周中的某一天 (1-7) 1 是星期日
`iso_week_day` | 匹配 ISO 8601 星期几 (1-7) 1 是星期一
`year` | 匹配一年(日期)
`iso_year` | 匹配 ISO 8601 年份(日期)
添加静态文件
---
### 添加 CSS 文件
```bash {7}
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ templates/
├┈ static/
╰┈ myfirst.css
```
打开 `CSS` 文件 (`members/static/myfirst.css`) 并插入以下内容:
```css
body {
background-color: lightblue;
font-family: verdana;
}
```
修改模板 (`members/templates/template.html`) 引入 css 文件
```django {1,4}
{% load static %}
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="{% static 'myfirst.css' %}">
<body>
```
<!--rehype:className=wrap-text -->
### 添加 JS 文件
```bash {7}
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ templates/
├┈ static/
╰┈ myfirst.js
```
打开 `JS` 文件 (`members/static/myfirst.js`) 并插入以下内容:
```js
function myFunction() {
alert("Hello from a static file!");
}
```
修改模板 (`members/templates/template.html`) 引入 `JS` 文件
```django {1,4,6}
{% load static %}
<!DOCTYPE html>
<html>
<script src="{% static 'myfirst.js' %}"></script>
<body>
<button onclick="myFunction()">Click me!</button>
```
<!--rehype:className=wrap-text -->
### 添加图片文件
```bash {7}
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ templates/
├┈ static/
╰┈ pineapple.jpg
```
打开 `JS` 文件 (`members/static/pineapple.jpg`) 并插入以下内容:
```js
function myFunction() {
alert("Hello from a static file!");
}
```
修改模板 (`members/templates/template.html`) 引入 `jpg` 文件
```django {1,5}
{% load static %}
<!DOCTYPE html>
<html>
<body>
<img src="{% static 'pineapple.jpg' %}">
</body>
</html>
```
<!--rehype:className=wrap-text -->
另见
----
- [Django 官网](https://www.djangoproject.com/) _(djangoproject.com)_
- [Django 教程](https://www.runoob.com/django/django-tutorial.html) _(runoob.com)_
- [Django 框架教程](http://c.biancheng.net/django/) _(biancheng.net)_
- [Django 4 中文教程](https://www.w3cschool.cn/django4/) _(w3cschool.cn)_
- [Django Tutorial](https://www.w3schools.com/django/index.php) _(w3schools.com)_

View File

@ -21,16 +21,16 @@ $ docker run -d -p 80:80 docker/getting-started
- `-p 80:80` - 将端口 80 映射到容器中的端口 80
- `docker/getting-started` - 要使用的镜像
在前台创建并运行容器
```shell
$ docker run -it -p 8001:8080 --name my-nginx nginx
$ docker run -it -p --rm 8001:8080 --name my-nginx nginx
```
----
- `-it` - 交互式 bash 模式
- `--rm` - 容器终止运行后自动删除容器文件
- `-p 8001:8080` - 将 `8001` 端口映射到容器中的 `8080` 端口
- `--name my-nginx` - 指定名称
- `nginx` - 要使用的镜像
@ -85,7 +85,6 @@ Docker 容器
`docker stats nginx-server` | 容器资源使用
`docker diff nginx-server` | 列出对容器所做的更改
### 创建容器
```shell
@ -133,6 +132,7 @@ Docker 镜像
<!--rehype:body-class=cols-2-->
### 操控
<!--rehype:wrap-class=row-span-2-->
| `Example` | Description |
|-----------|-----------|
@ -158,6 +158,12 @@ $ docker build -f myOtherDockerfile .
$ curl example.com/remote/Dockerfile | docker build -f - .
```
### 删除 \<none> 镜像
```bash
$ docker rmi -f $(docker images | grep "none" | awk '{print $3}')
```
Docker 网络
----
<!--rehype:body-class=cols-2-->
@ -227,21 +233,21 @@ docker network create -d overlay \
| Docker 语法 | 说明 |
|------------|------|
`docker search search_word` | 在 docker hub 中搜索镜像。
`docker pull user/image ` | 从 docker hub 下载镜像。
`docker login ` | 向 docker hub 进行身份验证
`docker push user/image ` | 将镜像上传到 docker hub。
`docker pull user/image` | 从 docker hub 下载镜像。
`docker login` | 向 docker hub 进行身份验证
`docker push user/image` | 将镜像上传到 docker hub。
### 注册表命令
### 镜像仓库命令
<!--rehype:wrap-class=row-span-3-->
登录到注册表
登录到镜像仓库
```shell
$ docker login
$ docker login localhost:8080
```
注册表注销
镜像仓库注销
```shell
$ docker logout
@ -291,9 +297,367 @@ $ docker volume ls
$ docker volume prune
```
### Docker Compose
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`docker-compose up` | 创建和启动容器
`docker-compose up -d` | 以分离模式创建和启动容器
`docker-compose down` | 停止和删除容器、网络、映像和卷
`docker-compose logs` | 查看容器的输出
`docker-compose restart` | 重启所有服务
`docker-compose pull` | 拉取所有图片服务
`docker-compose build` | 构建所有图像服务
`docker-compose config` | 验证并查看 Compose 文件
`docker-compose scale <service_name>=<replica>` | 规模特殊服务
`docker-compose top` | 显示正在运行的进程
`docker-compose run -rm -p 2022:22 web bash` | 启动 Web 服务并运行 bash 作为其命令,删除旧容器。
### Docker Services
:- | :-
:- | :-
`docker service create <options> <image> <command>` | 创建新服务
`docker service inspect --pretty <service_name>` | 显示详细信息服务
`docker service ls` | 列出服务
`docker service ps` | 列出服务的任务
`docker service scale <service_name>=<replica>` | 规模特殊服务
`docker service update <options> <service_name>` | 更新服务选项
### Docker Stack
:- | :-
:- | :-
`docker stack ls` | 列出此 Docker 主机上所有正在运行的应用程序
`docker stack deploy -c <composefile> <appname>` | 运行指定的 Compose 文件
`docker stack services <appname>` | 列出与应用关联的服务
`docker stack ps <appname>` | 列出与应用关联的正在运行的容器
`docker stack rm <appname>` | 拆掉一个应用程序
### Docker Machine
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`docker-machine create --driver virtualbox myvm1` | 创建虚拟机Mac、Win7、Linux
`docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1` | Win10
`docker-machine env myvm1` | 查看有关您的节点的基本信息
`docker-machine ssh myvm1 "docker node ls"` | 列出集群中的节点
`docker-machine ssh myvm1 "docker node inspect <node ID>"` | 检查节点
`docker-machine ssh myvm1 "docker swarm join-token -q worker"` | 查看加入令牌
`docker-machine ssh myvm1` | 打开与 VM 的 SSH 会话; 输入“exit”结束
`docker-machine ssh myvm2 "docker swarm leave"` | 让工人离开群体
`docker-machine ssh myvm1 "docker swarm leave -f"` | 让主人离开,杀群
`docker-machine start myvm1` | 启动当前未运行的 VM
`docker-machine stop $(docker-machine ls -q)` | 停止所有正在运行的虚拟机
`docker-machine rm $(docker-machine ls -q)` | 删除所有虚拟机及其磁盘映像
`docker-machine scp docker-compose.yml myvm1:~` | 将文件复制到节点的主目录
`docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"` | 部署应用
### docker 主要命令
:- | :-
:- | :-
`attach` | 将本地标准输入、输出和错误流附加到正在运行的容器
`build` | 从 Dockerfile 构建镜像
`commit` | 从容器的更改创建新图像
`cp` | 在容器和本地文件系统之间复制文件/文件夹
`create` | 创建一个新容器
`diff` | 检查容器文件系统上文件或目录的更改
`events` | 从服务器获取实时事件
`exec` | 在正在运行的容器中运行命令
`export` | 将容器的文件系统导出为 tar 存档
`history` | 显示图像的历史
`images` | 列出图像
`import` | 从 tarball 导入内容以创建文件系统映像
`info` | 显示系统范围的信息
`inspect` | 返回有关 Docker 对象的低级信息
`kill` | 杀死一个或多个正在运行的容器
`load` | 从 tar 存档或 STDIN 加载图像
`login` | 登录到 Docker 注册表
`logout` | 从 Docker 注册表中注销
`logs` | 获取容器的日志
`pause` | 暂停一个或多个容器内的所有进程
`port` | 列出容器的端口映射或特定映射
`ps` | 列出容器
`pull` | 从注册表中提取图像或存储库
`push` | 将图像或存储库推送到注册表
`rename` | 重命名容器
`restart` | 重启一个或多个容器
`rm` | 移除一个或多个容器
`rmi` | 移除一张或多张图片
`run` | 在新容器中运行命令
`save` | 将一个或多个图像保存到 tar 存档(默认流式传输到 STDOUT
`search` | 在 `Docker Hub` 中搜索图像
`start` | 启动一个或多个停止的容器
`stats` | 显示容器资源使用统计的实时流
`stop` | 停止一个或多个正在运行的容器
`tag` | 创建一个引用 SOURCE_IMAGE 的标记 TARGET_IMAGE
`top` | 显示容器的运行进程
`unpause` | 取消暂停一个或多个容器中的所有进程
`update` | 更新一个或多个容器的配置
`version` | 显示 Docker 版本信息
`wait` | 阻塞直到一个或多个容器停止,然后打印它们的退出代码
### docker run/create
<!--rehype:wrap-class=row-span-3-->
```bash
--add-host list # 添加自定义主机到 IP 映射 (host:ip)
-a, --attach list # 连接到 STDIN、STDOUT 或 STDERR
--blkio-weight uint16 # 块 IO相对权重介于 10 和 1000 之间,或 0 禁用(默认 0
--blkio-weight-device list # 块 IO 权重(相对设备权重)(默认 []
--cap-add list # 添加 Linux 功能
--cap-drop list # 放弃 Linux 功能
--cgroup-parent string # 容器的可选父 cgroup
--cgroupns string # 要使用的 Cgroup 命名空间(主机|私有)
# 'host': 在 Docker 主机的 cgroup 命名空间中运行容器
# 'private': 在自己的私有 cgroup 命名空间中运行容器
# '': 使用由守护进程上的
# default-cgroupns-mode 选项配置的 cgroup 命名空间(默认)
--cidfile string # 将容器 ID 写入文件
--cpu-period int # 限制 CPU CFS完全公平调度器周期
--cpu-quota int # 限制 CPU CFS完全公平调度器配额
--cpu-rt-period int # 以微秒为单位限制 CPU 实时周期
--cpu-rt-runtime int # 以微秒为单位限制 CPU 实时运行时间
-c, --cpu-shares int # CPU 份额(相对权重)
--cpus decimal # CPU 数量
--cpuset-cpus string # 允许执行的 CPU (0-3, 0,1)
--cpuset-mems string # 允许执行的 MEM (0-3, 0,1)
--device list # 将主机设备添加到容器
--device-cgroup-rule list # 将规则添加到 cgroup 允许的设备列表
--device-read-bps list # 限制设备的读取速率(每秒字节数)(默认 []
--device-read-iops list # 限制设备的读取速率(每秒 IO默认 []
--device-write-bps list # 限制设备的写入速率(每秒字节数)(默认 []
--device-write-iops list # 限制设备的写入速率(每秒 IO默认 []
--disable-content-trust # 跳过图像验证(默认为 true
--dns list # 设置自定义 DNS 服务器
--dns-option list # 设置 DNS 选项
--dns-search list # 设置自定义 DNS 搜索域
--domainname string # 容器 NIS 域名
--entrypoint string # 覆盖图像的默认入口点
-e, --env list # 设置环境变量
--env-file list # 读入环境变量文件
--expose list # 公开一个端口或一系列端口
--gpus gpu-request # 要添加到容器中的 GPU 设备(“全部”以传递所有 GPU
--group-add list # 添加其他组以加入
--health-cmd string # 运行以检查运行状况的命令
--health-interval duration # 运行检查之间的时间 (ms|s|m|h) (默认 0s)
--health-retries int # 需要报告不健康的连续失败
--health-start-period duration # 开始健康重试倒计时之前容器初始化的开始时间ms|s|m|h默认 0s
--health-timeout duration # 允许运行一项检查的最长时间 (ms|s|m|h) (默认 0s)
--help # 打印使用
-h, --hostname string # 容器主机名
--init # 在容器内运行一个 init 来转发信号并收获进程
-i, --interactive # 即使没有连接,也保持 STDIN 打开
--ip string # IPv4 地址(例如 172.30.100.104
--ip6 string # IPv6 地址例如2001:db8::33
--ipc string # 要使用的 IPC 模式
--isolation string # 容器隔离技术
--kernel-memory bytes # 内核内存限制
-l, --label list # 在容器上设置元数据
--label-file list # 读入以行分隔的标签文件
--link list # 添加到另一个容器的链接
--link-local-ip list # 容器 IPv4/IPv6 链路本地地址
--log-driver string # 容器的日志记录驱动程序
--log-opt list # 日志驱动程序选项
--mac-address string # 容器 MAC 地址(例如 92:d0:c6:0a:29:33
-m, --memory bytes # 内存限制
--memory-reservation bytes # 内存软限制
--memory-swap bytes # 交换限制等于内存加上交换:'-1' 启用无限交换
--memory-swappiness int # 调整容器内存交换0 到 100默认 -1
--mount mount # 将文件系统挂载附加到容器
--name string # 为容器分配名称
--network network # 将容器连接到网络
--network-alias list # 为容器添加网络范围的别名
--no-healthcheck # 禁用任何容器指定的 HEALTHCHECK
--oom-kill-disable # 禁用 OOM 杀手
--oom-score-adj int # 调整主机的 OOM 首选项(-1000 到 1000
--pid string # 要使用的 PID 命名空间
--pids-limit int # 调整容器 pids 限制(设置 -1 表示无限制)
--platform string # 如果服务器支持多平台,则设置平台
--privileged # 授予此容器扩展权限
-p, --publish list # 将容器的端口发布到主机
-P, --publish-all # 将所有暴露的端口发布到随机端口
--pull string # 创建前拉取图像("always"|"missing"|"never")(默认"missing")
--read-only # 将容器的根文件系统挂载为只读
--restart string # 容器退出时应用的重启策略(默认“否”)
--rm # 容器退出时自动移除
--runtime string # 用于此容器的运行时
--security-opt list # 安全选项
--shm-size bytes # /dev/shm 的大小
--stop-signal string # 停止容器的信号默认“SIGTERM”
--stop-timeout int # 停止容器的超时(以秒为单位)
--storage-opt list # 容器的存储驱动程序选项
--sysctl map # Sysctl 选项(默认 map[]
--tmpfs list # 挂载 tmpfs 目录
-t, --tty # 分配一个伪 TTY
--ulimit ulimit # ulimit 选项(默认 []
-u, --user string # 用户名或 UID格式<name|uid>[:<group|gid>]
--userns string # 要使用的用户命名空间
--uts string # 要使用的 UTS 命名空间
-v, --volume list # 绑定挂载卷
--volume-driver string # 容器的可选卷驱动程序
--volumes-from list # 从指定容器挂载卷
-w, --workdir string # 容器内的工作目录
```
`run`/`create` 大部分参数一致
### docker 全局参数
```bash
--config string # 客户端配置文件的位置(默认“~/.docker”
-c, --context string # 用于连接到守护程序的上下文的名称(
# 覆盖 DOCKER_HOST 环境变量和使用“docker context use”设置的默认上下文
-D, --debug # 启用调试模式
-H, --host list # 要连接的守护进程套接字
-l, --log-level string # 设置日志级别("debug"\|"info"\|"warn"\|"error"\|"fatal") 默认“info”
--tls # 使用 TLS 由 --tlsverify 暗示
--tlscacert string # 仅由该 CA 签署的信任证书(默认为“~/.docker/ca.pem”
--tlscert string # TLS证书文件路径默认“~/.docker/cert.pem”
--tlskey string # TLS 密钥文件的路径(默认为“~/.docker/key.pem”
--tlsverify # 使用 TLS 并验证远程
-v, --version # 打印版本信息并退出
```
### docker 管理命令
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`docker builder` | 管理构建
`docker buildx*` | Docker BuildxDocker Inc.v0.7.1
`docker compose*` | Docker ComposeDocker Inc.v2.2.3
`docker config` | 管理 Docker 配置
`docker container` | 管理容器
`docker context` | 管理上下文
`docker image` | 管理图像
`docker manifest` | 管理 Docker 镜像清单和清单列表
`docker network` | 管理网络
`docker node` | 管理 Swarm 节点
`docker plugin` | 管理插件
`docker scan*` | Docker 扫描Docker Inc.v0.16.0
`docker secret` | 管理 Docker 机密
`docker service` | 管理服务
`docker stack` | 管理 Docker 堆栈
`docker swarm` | 管理群
`docker system` | 管理 Docker
`docker trust` | 管理对 Docker 映像的信任
`docker volume` | 管理卷
### docker images
```bash
-a, --all 显示所有图像(默认隐藏中间图像)
--digests 显示摘要
-f, --filter filter 根据提供的条件过滤输出
--format string 使用 Go 模板打印漂亮的图像
--no-trunc 不要截断输出
-q, --quiet 仅显示图像 ID
```
Docker 示例
---
<!--rehype:body-class=cols-2-->
### Docker Web 管理工具 portainer
```bash
$ docker run -d --name portainer \
-p 8000:8000 \
-p 9443:9443 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/portainer:/data \
portainer/portainer-ee:latest
```
### 在线代码编辑器 Code Server
```bash
$ mkdir -p ~/.config
$ docker run -it --name code-server \
-p 127.0.0.1:8080:8080 \
-v "$HOME/.config/code-server:/home/coder/.config" \
-v "$PWD:/home/coder/project" \
-u "$(id -u):$(id -g)" \
-e "DOCKER_USER=$USER" \
codercom/code-server:latest
```
### MySQL
```bash
$ docker run --name mysql \
-p 3306:3306 \
-v $HOME/mysql/conf.d:/etc/mysql/conf.d \
-v $HOME/mysql/data:/var/lib/mysql \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7.23
```
### Redis
```bash
$ docker run -d --name myredis \
-v $HOME/redis/conf:/usr/local/etc/redis \
-v /etc/localtime:/etc/localtime:ro \
redis redis-server /usr/local/etc/redis/redis.conf
```
### Nginx
```bash
$ docker run --name my-nginx \
-v "$HOME/nginx/nginx.conf:/etc/nginx/nginx.conf:ro" \
-v "$HOME/nginx/html:/usr/share/nginx/html:ro" \
-p 8080:80 \
-d nginx
```
### PostgreSQL
```bash
$ docker run --name my-postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v $HOME/nginx/mount:/var/lib/postgresql/data \
-d postgres
```
### 媒体管理工具 Dim
```bash
$ docker run --name my-dim \
-p 8000:8000/tcp \
-v $HOME/.config/dim:/opt/dim/config \
-v $HOME/dim/media:/media:ro \
-d ghcr.io/dusk-labs/dim:dev
```
[Github](https://github.com/Dusk-Labs/dim)
### Gitlab
```bash
$ docker run -d --name gitlab \
--hostname gitlab.example.com \
--publish 8443:443 --publish 8081:80 -p 2222:22 \
--restart always \
--volume $HOME/gitlab/config:/etc/gitlab \
--volume $HOME/gitlab/logs:/var/log/gitlab \
--volume $HOME/gitlab/data:/var/opt/gitlab \
-v /etc/localtime:/etc/localtime \
--shm-size 256m \
gitlab/gitlab-ce:latest
```
另见
----
- [Dockerfile 备忘清单](./dockerfile.md) _(github.io)_
- [Docker 官方入门教程](https://docs.docker.com/get-started/) _(docker.com)_
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_

View File

@ -110,6 +110,7 @@ RUN true | false # 将脱离管道
`CMD ["executable","param1","param2"]` | (exec 形式,这是首选形式)
`CMD ["param1","param2"]` | (作为 ENTRYPOINT 的默认参数)
`CMD command param1 param2` | (shell形式)
<!--rehype:class=auto-wrap-->
```dockerfile
EXPOSE 5900
@ -185,6 +186,7 @@ temp?
`*/temp*` | 在根的任何直接子目录中<br />排除名称以 `temp` 开头的文件和目录
`*/*/temp*` | 从根以下两级的任何子目录中<br />排除以 `temp` 开头的文件和目录
`temp?` | 排除根目录中名称为<br /> `temp` 的单字符扩展名的文件和目录
<!--rehype:class=auto-wrap-->
如果此文件存在,排除与其中的模式匹配的文件和目录,有利于避免 `ADD``COPY` 将敏感文件添加到镜像中。匹配是使用 Go 的 [filepath.Match](https://golang.org/pkg/path/filepath#Match) 规则完成的。
@ -203,6 +205,7 @@ temp?
`CMD command param1 param2` | 设置默认命令
`ENV <key>=<value> ...` | 设置环境变量
`EXPOSE <port> [<port>/<protocol>...]` | 运行时侦听指定的网络端口
<!--rehype:class=auto-wrap-->
### 服务静态网站的最小 Docker 镜像
<!--rehype:wrap-class=col-span-2-->
@ -229,4 +232,4 @@ CMD ["/busybox", "httpd", "-f", "-v", "-p", "3000", "-c", "httpd.conf"]
- [Dockerfile reference](https://docs.docker.com/engine/reference/builder/) _(docker.com)_
- [Docker 备忘清单](./docker.md) _(github.io)_
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_

749
docs/electron.md Normal file
View File

@ -0,0 +1,749 @@
Electron 备忘清单
====
此快速参考备忘单提供了 Electron v21 API 说明和使用示例。
入门
----
### 快速开始
<!--rehype:wrap-class=row-span-4-->
[Electron](https://www.electronjs.org/) 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架
#### 创建你的应用程序
- 安装
```bash
mkdir my-app && cd my-app
npm init
```
在项目根目录会生成 `package.json`
```json
{
"name": "my-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"author": "Jane Doe",
"license": "MIT"
}
```
- 安装依赖包
```bash
npm install --save-dev electron
```
- 添加开发模式打开您的应用命令
```js
"scripts": {
"start": "electron ."
}
```
- 运行命令,启动应用程序
```bash
npm start
```
入口都是 `main` 文件。这个文件控制了主进程它运行在一个完整的Node.js环境中
- 创建 `index.html` 页面
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
```
- 窗口中打开您的页面
```js
const {
app,
BrowserWindow
} = require('electron');
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
});
win.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow()
})
```
<!--rehype:className=style-timeline-->
### 关闭所有窗口时退出应用
```js
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
```
### 创建无边框窗口
```js
const win = new BrowserWindow({
frame: false
})
```
### 自定义标题栏样式
```js
const win = new BrowserWindow({
titleBarStyle: 'hidden'
})
```
### 控制红绿灯 (macOS)
```js
const win = new BrowserWindow({
titleBarStyle: 'customButtonsOnHover'
})
```
### 通过预加载脚本从渲染器访问 Node.js
<!--rehype:wrap-class=col-span-2-->
创建一个名为 preload.js 的新脚本如下
```js
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
```
在创建窗口方法中传递 `preload` 参数
```js
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
```
### 将的 process.versions 对象暴露给渲染器
```js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld(
'versions', {
// 能暴露的不仅仅是函数,我们还可以暴露变量
node:
() => process.versions.node,
chrome:
() => process.versions.chrome,
electron:
() => process.versions.electron,
}
);
```
通过 `preload.js` 脚本将 `versions` 这一全局变量暴露给渲染器
### 启用拼写检查器
```js
const myWindow = new BrowserWindow({
webPreferences: {
spellcheck: true
}
})
```
设置拼写检查器以检查英语 和 法语
```js
myWindow.session
.setSpellCheckerLanguages([
'en-US', 'fr'
])
```
app
---
<!--rehype:body-class=cols-6-->
### 事件绑定方法使用示例
<!--rehype:wrap-class=col-span-3-->
```js
const { app } = require('electron');
app.on('session-created', (session) => {
console.log(session);
})
// 立即重启当前实例并向新的实例添加新的命令行参数的示例
app.relaunch({
args: process.argv.slice(1).concat(['--relaunch']);
})
app.exit(0);
```
### 方法
<!--rehype:wrap-class=col-span-3 row-span-4-->
:- | :-
:- | :-
`quit` | 尝试关闭所有窗口 [#](https://www.electronjs.org/zh/docs/latest/api/app#appquit)
`exit` | 使用 exitCode 立即退出 [#](https://www.electronjs.org/zh/docs/latest/api/app#appexitexitcode)
`relaunch` | 当前实例退出,重启应用 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprelaunchoptions)
`isReady` | 已完成初始化返回 boolean [#](https://www.electronjs.org/zh/docs/latest/api/app#appisready)
`whenReady` | 初始化完成 [#](https://www.electronjs.org/zh/docs/latest/api/app#appwhenready)
`focus` | 获得焦点/激活的 app [#](https://www.electronjs.org/zh/docs/latest/api/app#appfocusoptions)
`hide` | 隐藏所有的应用窗口,不是最小化 [#](https://www.electronjs.org/zh/docs/latest/api/app#apphide-macos)
`isHidden` _(mac)_ | 所有窗口是否都被隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/app#appishidden)
`show` _(mac)_ | 显示隐藏后的应用程序窗口 [#](https://www.electronjs.org/zh/docs/latest/api/app#appshow-macos)
`setAppLogsPath` | 设置或创建一个您的应用程序日志目录 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetapplogspathpath)
`getAppPath` | 获取当前应用程序目录 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetapppath)
`getPath(name)` | 与 name 关联的目录或文件的路径 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetpathname)
`getFileIcon` | 一个 NativeImage 类型的应用图标 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetfileiconpath-options)
`setPath(name)` | 重写 name 的路径特定文件夹或文件 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetpathname-path)
`getVersion` | 应用程序的版本号 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetversion)
`getName` | 应用程序的名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetname)
`setName` | 设置当前应用程序的名字 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetname)
`getLocale` | 当前应用程序区域 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetlocale)
`getLocaleCountryCode` | 获取双字母 [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) 国家代码 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetlocalecountrycode)
`getSystemLocale` | 当前系统语言环境 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetsystemlocale)
`addRecentDocument` _(win/mac)_ | 最近打开的文件列表添加新路径 [#](https://www.electronjs.org/zh/docs/latest/api/app#appaddrecentdocumentpath-macos-windows)
`clearRecentDocuments` _(win/mac)_ | 清空最近打开的文档列表[#](https://www.electronjs.org/zh/docs/latest/api/app#appclearrecentdocuments)
`setAsDefaultProtocolClient` | 设置协议(URI scheme)默认处理程序 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetasdefaultprotocolclientprotocol-path-args)
`removeAsDefaultProtocolClient` | 移除默认处理器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appremoveasdefaultprotocolclientprotocol-path-args-macos-windows)
`isDefaultProtocolClient` | 可执行程序是否是协议 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisdefaultprotocolclientprotocol-path-args)
`getApplicationNameForProtocol` | 返回默认处理器的应用程序名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetapplicationnameforprotocolurl)
`getApplicationInfoForProtocol` _(win/mac)_ | 返回包含应用程序名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetapplicationinfoforprotocolurl-macos-windows)
`setUserTasks` _(win)_ | 添加 tasks 到Jump List的Tasks类别 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetusertaskstasks-windows)
`getJumpListSettings` _(win)_ | 获取跳转列表 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetjumplistsettings-windows)
`setJumpList` _(win)_ | 设置跳转列表 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetjumplistcategories-windows)
`requestSingleInstanceLock` | 返回应用程序实例是否成功取了锁 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprequestsingleinstancelockadditionaldata)
`hasSingleInstanceLock` | 返回应用实例当前是否持有单例锁 [#](https://www.electronjs.org/zh/docs/latest/api/app#apphassingleinstancelock)
`releaseSingleInstanceLock` | 释放所有创建的锁 [#](https://www.electronjs.org/zh/docs/latest/api/app#appreleasesingleinstancelock)
`setUserActivity` _(mac)_ | 创建 NSUserActivity 并将其设置为当前活动 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetuseractivitytype-userinfo-webpageurl-macos)
`getCurrentActivityType` _(mac)_ | 正在运行的 activity 的类型 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetcurrentactivitytype-macos)
`invalidateCurrentActivity` _(mac)_ | 使当前的Handoff用户活动无效 [#](https://www.electronjs.org/zh/docs/latest/api/app#appinvalidatecurrentactivity-macos)
`resignCurrentActivity` _(mac)_ | 将当前 Handoff 用户活动标记为非活动,但不使其失效 [#](https://www.electronjs.org/zh/docs/latest/api/app#appresigncurrentactivity-macos)
`updateCurrentActivity` _(mac)_ | 将项目从 用户信息 合并到其当前 用户信息 字典中 [#](https://www.electronjs.org/zh/docs/latest/api/app#appupdatecurrentactivitytype-userinfo-macos)
`setAppUserModelId` _(win)_ | 改变当前应用的 Application User Model ID 为 id [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetappusermodelidid-windows)
`setActivationPolicy` _(mac)_ | 为给定应用设置激活策略 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetactivationpolicypolicy-macos)
`importCertificate` _(linux)_ | 将 pkcs12 格式的证书导入到平台证书库 [#](https://www.electronjs.org/zh/docs/latest/api/app#appimportcertificateoptions-callback-linux)
`configureHostResolver` | 配置主机解析器 (DNS 和 DNS-over-HTTPS) [#](https://www.electronjs.org/zh/docs/latest/api/app#appconfigurehostresolveroptions)
`disableHardwareAcceleration` | 禁用当前应用程序的硬件加速 [#](https://www.electronjs.org/zh/docs/latest/api/app#appdisablehardwareacceleration)
`disableDomainBlockingFor3DAPIs` | GPU 进程频繁崩溃,在每个域的基础上重新启动,禁用该行为 [#](https://www.electronjs.org/zh/docs/latest/api/app#appdisabledomainblockingfor3dapis)
`getAppMetrics` | 返回 [ProcessMetric[]](https://www.electronjs.org/zh/docs/latest/api/structures/process-metric) [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetappmetrics)
`getGPUFeatureStatus` | 返回 [GPUFeatureStatus](https://www.electronjs.org/zh/docs/latest/api/structures/gpu-feature-status) [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetgpufeaturestatus)
`getGPUInfo` | GPU 信息 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetgpuinfoinfotype)
`setBadgeCount` _(mac/linux)_ | 应用设置计数器角标 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetbadgecountcount-linux-macos)
`getBadgeCount` _(mac/linux)_ | 获取计数器(badge)显示的当前值 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetbadgecount-linux-macos)
`isUnityRunning` _(linux)_ | 前桌面环境是否为 Unity 启动器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisunityrunning)
`getLoginItemSettings` _(mac/win)_ | 为 openAtLogin 设置相同的参数已确保正确的设置 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetloginitemsettingsoptions-macos-windows)
`setLoginItemSettings` _(mac/win)_ | 传递指定应用程序名称的参数 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetloginitemsettingssettings-macos-windows)
`isAccessibilitySupportEnabled` _(mac/win)_ | 是否开启了辅助功能 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisaccessibilitysupportenabled-macos-windows)
`setAccessibilitySupportEnabled` _(mac/win)_ | 启用或禁用访问权限树视图 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetaccessibilitysupportenabledenabled-macos-windows)
`showAboutPanel` | 显示程序的"关于"面板选项 [#](https://www.electronjs.org/zh/docs/latest/api/app#appshowaboutpanel)
`setAboutPanelOptions` | 设置 "关于" 面板选项 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetaboutpaneloptionsoptions)
`isEmojiPanelSupported` | 当前操作系统是否支持本地 emoji 选择器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisemojipanelsupported)
`showEmojiPanel` _(mac/win)_ | 打开系统自身的emjio选取器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appshowemojipanel)
`startAccessingSecurityScopedResource` _(mac)_ | 开始访问安全范围内的资源 [#](https://www.electronjs.org/zh/docs/latest/api/app#appstartaccessingsecurityscopedresourcebookmarkdata-macos)
`enableSandbox` | 在应用程序上启用完全沙盒模式 [#](https://www.electronjs.org/zh/docs/latest/api/app#appenablesandbox)
`isInApplicationsFolder` _(mac)_ | 是否从系统应用程序文件夹运行 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisinapplicationsfolder-macos)
`moveToApplicationsFolder` _(mac)_ | [#](https://www.electronjs.org/zh/docs/latest/api/app#appmovetoapplicationsfolderoptions-macos)
`isSecureKeyboardEntryEnabled` _(mac)_ | 是否已启用安全键盘输入 [#](https://www.electronjs.org/zh/docs/latest/api/app#appissecurekeyboardentryenabled-macos)
`setSecureKeyboardEntryEnabled` _(mac)_ | 在应用中启用安全键盘输入 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetsecurekeyboardentryenabledenabled-macos)
### 启动时激活主实例窗口的示例
<!--rehype:wrap-class=col-span-3-->
```js
const { app } = require('electron');
let myWindow = null;
const additionalData = { myKey: 'myValue' };
const gotTheLock = app.requestSingleInstanceLock(additionalData);
if (!gotTheLock) {
app.quit();
} else {
app.on(
'second-instance',
(event, commandLine, workingDirectory, additionalData) => {
// 输出从第二个实例中接收到的数据
console.log(additionalData);
// 有人试图运行第二个实例,我们应该关注我们的窗口
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore();
myWindow.focus();
}
}
)
// 创建 myWindow, 加载应用的其余部分, etc...
app.whenReady().then(() => {
myWindow = createWindow();
})
}
```
### 事件
<!--rehype:wrap-class=col-span-3-->
:- | :-
:- | :-
`will-finish-launching` | 基础的启动的时候被触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-will-finish-launching)
`ready` | 完成初始化时,触发一次 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-ready)
`window-all-closed` | 在程序关闭窗口前发信号 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-window-all-closed)
`before-quit` | 当所有窗口被关闭后触发,应用程序将退出 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-before-quit)
`will-quit` | 所有窗口被关闭后触发,应用程序将退出 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-will-quit)
`quit` | 在应用程序退出时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-quit)
`open-file` _(mac)_ | 在应用中打开一个文件时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-open-file-macos)
`open-url` _(mac)_ | 应用中打开一个 URL 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-open-url-macos)
`activate` _(mac)_ | 当应用被激活时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-activate-macos)
`did-become-active` _(mac)_ | 不同设备的活动想要恢复时在切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-did-become-active-macos)
`continue-activity` _(mac)_ | 不同设备的活动通过 Handoff 想要恢复时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-continue-activity-macos)
`will-continue-activity` _(mac)_ | 恢复来自不同设备的活动之前在切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-will-continue-activity-macos)
`continue-activity-error` _(mac)_ | 不同设备的活动无法恢复时在切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-continue-activity-error-macos)
`activity-was-continued` _(mac)_ | 活动在另一个设备上成功恢复后切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-activity-was-continued-macos)
`update-activity-state` _(mac)_ | 当即将在另一台设备上恢复切换时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-update-activity-state-macos)
`new-window-for-tab` _(mac)_ | 用户点击原生的 macOS 新标签按钮时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-new-window-for-tab-macos)
`browser-window-blur` | 当 browserWindow 变得模糊时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-browser-window-blur)
`browser-window-focus` | 当 browserWindow 获得焦点时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-browser-window-focus)
`browser-window-created` | 创建新的 browserWindow 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-browser-window-created)
`web-contents-created` | 创建新的 webContents 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-web-contents-created)
`certificate-error` | 当对 url 的 certificate 证书验证失败触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-certificate-error)
`select-client-certificate` | 当一个客户证书被请求的时候发出 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-select-client-certificate)
`login` | 当 webContents 要进行基本身份验证时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-login)
`gpu-info-update` | 每当有 GPU 信息更新时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-gpu-info-update)
~~`gpu-process-crashed`~~ ~~废弃~~ | 当 gpu 进程崩溃或关闭(杀死)时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-gpu-process-crashed-已废弃)
~~`renderer-process-crashed`~~ ~~废弃~~ | 渲染器进程崩溃或关闭(杀死)时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-renderer-process-crashed-已废弃)
`render-process-gone` | 渲染器进程意外消失时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-render-process-gone)
`child-process-gone` | 子进程意外消失时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-child-process-gone)
`accessibility-support-changed` | 当 Chrome 的辅助功能状态改变时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-accessibility-support-changed--macos---windows-)
`session-created` | 创建了一个新的 session 后被触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-session-created)
`second-instance` | 在你的应用程序的首个实例中触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-second-instance)
### 属性
<!--rehype:wrap-class=col-span-3-->
:- | :-
:- | :-
`accessibilitySupportEnabled` _(mac/win)_ | 是否开启了辅助功能 [#](https://www.electronjs.org/zh/docs/latest/api/app#appaccessibilitysupportenabled-macos-windows)
`applicationMenu` | 传递 Menu 来给此属性赋值 [#](https://www.electronjs.org/zh/docs/latest/api/app#appapplicationmenu)
`badgeCount` _(mac/linux)_ | 返回应用角标计数的 Integer 属性 [#](https://www.electronjs.org/zh/docs/latest/api/app#appbadgecount-linux-macos)
`commandLine` | Chromium 使用的命令行参数 [#](https://www.electronjs.org/zh/docs/latest/api/app#appcommandline-只读)
`dock` _(mac/只读)_ | 用户dock中对应用图标进行操作 [#](https://www.electronjs.org/zh/docs/latest/api/app#appdock-macos-只读)
`isPackaged` _(只读)_ | 应用是否已经打包 [#](https://www.electronjs.org/zh/docs/latest/api/app#appispackaged-只读)
`name` | 当前应用程序的名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appname)
`userAgentFallback` | 全局回退的用户代理字符串 [#](https://www.electronjs.org/zh/docs/latest/api/app#appuseragentfallback)
~~`runningUnderRosettaTranslation`~~ _(mac)_ | 提示下载应用程序的 arm64 版本 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprunningunderrosettatranslation-macos-只读-弃用)
`runningUnderARM64Translation` _(mac/win)_ | 前应用正在使用 ARM64 运行环境 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprunningunderarm64translation-只读-macos-windows)
BrowserWindow
----
<!--rehype:body-class=cols-6-->
### 参数
<!--rehype:wrap-class=col-span-3 row-span-2-->
:- | :-
:- | :-
`width` _整数_ | 窗口的宽度(以像素为单位)。默认值 _(800)_
`height` _整数_ | 窗口的高度(以像素为单位)。默认值 _(600)_
`x` _整数_ (**可选**) | 窗口相对于屏幕左侧偏移量。默认值窗口居中
`y` _整数_ (**可选**) | 窗口相对于屏幕顶端偏移量。默认值窗口居中
`useContentSize` _boolean_ | _(宽)_ 和 _(高)_ 设置为web页面的尺寸。默认值 _(false)_
`center` _boolean_ | 窗口是否在屏幕居中。默认值 _(false)_
`minHeight` _整数_ | 窗口的最小高度。默认值 _(0)_
`maxWidth` _整数_ | 窗口的最大宽度。默认值不限
`maxHeight` _整数_ | 窗口的最大高度。默认值不限
`resizable` _boolean_ | 窗口大小是否可调整。默认值 _(true)_
`movable` _boolean_ _(win/mac)_ | 窗口是否可移动。默认值 _(true)_
`minimizable` _boolean_ _(win/mac)_ | 窗口是否可最小化。默认值 _(true)_
`maximizable` _boolean_ _(win/mac)_ | 窗口是否最大化。默认值 _(true)_
`closable` _boolean_ _(win/mac)_ | 窗口是否可关闭。默认值 _(true)_
`focusable` _boolean_ | 窗口是否可以聚焦. 默认值 _(true)_。在 Windows 中设置 _(focusable: false)_ 也意味着设置了 _(skipTaskbar: true)_ 在 Linux 中设置 _(focusable: false)_ 时窗口停止与 wm 交互, 并且窗口将始终置顶
`alwaysOnTop` _boolean_ | 窗口是否永远在别的窗口的上面。默认值 _(false)_
`fullscreen` _boolean_ | 窗口是否全屏。为 _(false)_ 时 macOS 上按钮将被隐藏或禁用。默认值 _(false)_
`fullscreenable` _boolean_ | 窗口是否可以进入全屏状态。macOS上最大化/缩放按钮是否可用 默认值 _(true)_
`simpleFullscreen` _boolean_ _(mac)_ | 在 macOS 上使用 pre-Lion 全屏。默认值 _(false)_
`skipTaskbar` _boolean_ _(win/mac)_ | 是否在任务栏中显示窗口。默认值 _(false)_
`kiosk` _boolean_ | 窗口是否进入kiosk模式。默认值 _(false)_
`title` _string_ | 默认窗口标题 默认为 _("Electron")_ 。如果由 _(loadURL())_ 加载的HTML文件中含有标签 _(&lt;title&gt;)_ ,此属性将被忽略
`icon` _NativeImage/string_ | 窗口图标。在 Windows 上推荐使用 _(ICO)_ 图标来获得最佳的视觉效果, 默认使用可执行文件的图标
`show` _boolean_ | 窗口是否在创建时显示。默认值 _(true)_
`paintWhenInitiallyHidden` _boolean_ | 当 _(show)_ 为 _(false)_ 并且渲染器刚刚被创建时,它是否应激活。为了让 _(document.visibilityState)_ 在 _(show: false)_ 的情况下第一次加载时正确地工作,你应该把这个设置成 _(false)_。设置为 _(false)_ 将会导致 _(ready-to-show)_ 事件不触发。默认值 _(true)_
`frame` _boolean_ | 设置为 _(false)_ 时可以创建一个无边框窗口,默认值 _(true)_
`parent` _BrowserWindow_ | 指定父窗口 默认值 _(null)_
`modal` _boolean_ | 当前是否为模态窗口。只有当窗口是子窗口时才起作用。默认值 _(false)_
`acceptFirstMouse` _boolean_ _(mac)_ | 点击 非活动窗口是否会穿透到 web contents。默认值 _(false)_
`disableAutoHideCursor` _boolean_ | 是否在打字时隐藏光标。默认值 _(false)_
`autoHideMenuBar` _boolean_ | 自动隐藏菜单栏除非按了_(Alt)_键。默认值 _(false)_
`enableLargerThanScreen` _boolean_ _(mac)_ | 使窗口尺寸可大于屏幕的大小。其他操作系统默认允许大于屏幕的窗口。默认值 _(false)_
`backgroundColor` _string_ | 窗口背景色,格式为 Hex, RGB, RGBA, HSL, HSLA 或 CSS 命名颜色。如果 _(transparent)_ 设置为 _(true)_则支持 #AARRGGBB 格式的透明。默认值 _(#FFF)_白色
`hasShadow` _boolean_ | 窗口是否有阴影. 默认值 _(true)_
`opacity` _number_ _(win/mac)_ | 设置窗口的初始透明度,在 0.0(全透明)和 1.0(完全不透明)之间 。 目前仅在 Windows 和 macOS上实现。
`darkTheme` _boolean_ | 强制窗口使用深色主题只在部分GTK+3桌面环境下有效。 默认值 _(false)_.
`transparent` _boolean_ | 使窗口 <a href="/zh/docs/latest/tutorial/window-customization#create-transparent-windows">透明</a>。 默认值 _(false)_. 在Windows上仅在无边框窗口下起作用。
`type` _string_ | 窗口的类型, 默认为普通窗口. 更多信息见下文
`visualEffectState` _string_ _(mac)_ | 在 macOS 上指定外观应如何响应窗口活动状态。 必须与 _(vibrancy)_ 属性一起使用。 可能的值有
`visualEffectState.followWindow` | 当窗口处于激活状态时,后台应自动显示为激活状态,当窗口处于非激活状态时,后台应自动显示为非激活状态。 默认为该值。
`visualEffectState.active` | 后台应一直显示为激活状态。
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
`titleBarStyle.hidden` | 在一个隐藏的标题栏和一个全尺寸大小的内容窗口中取得结果。 在 macOS 内, 窗口将一直拥有位于左上的标准窗口控制器 _(“traffic lights”)_。 在 Windows上当与 _(titleBarOverlay: true)_ 合并时,它将激活窗口控件叠加(详情请参阅 _(titleBarOverlay)_),否则将不会显示窗口控件。
`titleBarStyle.hiddenInset` _(mac)_ | 隐藏标题栏,使用窗口边缘稍微小的红绿灯按钮替代。
`titleBarStyle.customButtonsOnHover` _(mac)_ | 隐藏的标题栏的全尺寸的内容窗口, 红绿灯按钮在鼠标悬停在窗口左上方时显示。**注意:**此选项目前是实验性的。
`trafficLightPosition` _Point_ _(mac)_ | 在无边框窗口中设置灯绿灯按钮位置。
`roundedCorners` _boolean_ _(mac)_ | 无边框窗口在 macOS 上,是否应该有圆角。 默认值为 _(true)_。 属性设置为 _(false)_ ,将阻止窗口是可全屏的。
~~`fullscreenWindowTitle`~~ _boolean_ _(mac)_ ~~_已弃用_~~ | _titleBarStyle_ 设置为 _(hiddenInset)_ 时,在 macOS 全屏模式下标题栏显示标题。默认值为 _(false)_.
`thickFrame` _boolean_ | 对 Windows 上的无框窗口使用 _(WS_THICKFRAME)_ 样式,会增加标准窗口框架。 设置为 _(false)_ 时将移除窗口的阴影和动画. 默认值为 _(true)_。
`vibrancy` _string_ _(mac)_ | 为窗口添加一种类型的动态效果,仅 macOS。 可以是 _(appearance-based)__(light)__(dark)__(titlebar)__(selection)__(menu)__(popover)__(sidebar)__(medium-light)__(ultra-dark)__(header)__(sheet)__(window)__(hud)__(fullscreen-ui)__(tooltip)__(content)__(under-window)_ 或 _(under-page)_。 请注意 _(appearance-based)__(light)__(dark)__(medium-light)_ 和 _(ultra-dark)_ 已弃用,在 macOS Catalina (10.15) 中已经移除。
`zoomToPageWidth` _boolean_ _(mac)_ | 在 macOS 上控制,当按住 option 点击工具栏绿色红绿灯按钮或点击窗口 &gt; 放大菜单项的行为。 如果为 _(true)_窗口为将会缩放到适合宽度若为 _(false)_ 将会放大到屏幕宽度。 这也会影响,直接调用 _(maximize())_ 的行为。 默认值为 _(false)_.
`tabbingIdentifier` _string_ _(mac)_ | 选项卡组名称允许在原生选择卡中打开窗口macOS 10.12+ 支持。 Windows 中,有相同选项卡标识的将会组合在一起。 这会添加一个原生新增选项卡按钮到你窗口的选项卡栏,同时 _(app)_ 和窗口允许接收 _(new-window-for-tab)_ 事件。
`webPreferences` _Object_ | 网页功能设置。
`webPreferences.devTools` _boolean_ | 是否开启 DevTools. 如果设置为 _(false)_, 则无法使用 _(BrowserWindow.webContents.openDevTools ())_ 打开 DevTools。 默认值为 _(true)_。
`webPreferences.nodeIntegration` _boolean_ | 是否启用Node integration. 默认值为 _(false)_.
`webPreferences.nodeIntegrationInWorker` _boolean_ | 是否在Web工作器中启用了Node集成. 默认值为 _(false)_. 更多内容参见 [多线程](https://www.electronjs.org/docs/latest/tutorial/multithreading)
`webPreferences.nodeIntegrationInSubFrames` _boolean_ **_实验性_**| 是否允许在子页面(iframe)或子窗口(child window)中集成Node.js 预先加载的脚本会被注入到每一个iframe你可以用 _(process.isMainFrame)_ 来判断当前是否处于主框架main frame中。
`webPreferences.preload` _string_ | 在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志[参考示例](https://www.electronjs.org/docs/latest/api/context-bridge#exposing-node-global-symbols)
`webPreferences.sandbox` _boolean_ | 如果设置该参数, 沙箱的渲染器将与窗口关联, 使它与Chromium OS-level 的沙箱兼容, 并禁用 Node. js 引擎。 它与 _(nodeIntegration)_ 的选项不同,且预加载脚本的 API 也有限制。[更多详情](https://www.electronjs.org/docs/latest/tutorial/sandbox)
`webPreferences.session` | [Session](https://www.electronjs.org/docs/latest/api/session#class-session) 设置页面的 session 而不是直接忽略 Session 对象, 也可用 _(partition)_ 选项来代替,它接受一个 partition 字符串. 同时设置了_(session)_ 和 _(partition)_时, _(session)_ 的优先级更高. 默认使用默认的 session.
`webPreferences.partition` | string (optional) - 通过 session 的 partition 字符串来设置界面session. 如果 _(partition)_ 以 _(persist:)_开头, 该页面将使用持续的 session并在所有页面生效且使用同一个_(partition)_. 如果没有 _(persist:)_ 前缀, 页面将使用 in-memory session. 通过分配相同的 _(partition)_, 多个页可以共享同一会话。 默认使用默认的 session.
`webPreferences.zoomFactor` _number_ | 页面的默认缩放系数, _(3.0)_ 表示 _(300%)_。 默认值为 _(1.0)_.
`webPreferences.javascript` _boolean_ | 是否启用 JavaScript 支持。 默认值为 _(true)_。
`webPreferences.webSecurity` _boolean_ | 当设置为 _(false)_, 它将禁用同源策略 (通常用来测试网站), 如果此选项不是由开发者设置的,还会把 _(allowRunningInsecureContent)_设置为 _(true)_. 默认值为 _(true)_
`webPreferences.allowRunningInsecureContent` _boolean_ | 允许一个 https 页面运行来自http url的JavaScript, CSS 或 plugins。 默认值为 _(false)_
`webPreferences.images` _boolean_ | 允许加载图片。 默认值为 _(true)_
`webPreferences.imageAnimationPolicy` _string_ | 指定如何运行图像动画 (比如: GIF等). 可以是 _(animate)_, _(animateOnce)_ 或 _(noAnimation)_。默认值为 _(animate)_
`webPreferences.textAreasAreResizable` _boolean_ | 允许调整 TextArea 元素大小。 默认值为 _(true)_
`webPreferences.webgl` _boolean_ | 启用 WebGL 支持。 默认值为 _(true)_
`webPreferences.plugins` _boolean_ | 是否应该启用插件。 默认值为 _(false)_
`webPreferences.experimentalFeatures` _boolean_ | 启用 Chromium 的实验功能。 默认值为 _(false)_
`webPreferences.scrollBounce` _boolean_ _(mac)_ | 启用滚动回弹(橡皮筋)效果。 默认值为 _(false)_
`webPreferences.enableBlinkFeatures`_string_ | 以 _(逗号)_ 分隔的需要启用的特性列表,譬如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
`webPreferences.disableBlinkFeatures` _string_ | 以 _(,)_ 分隔的禁用特性列表, 如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
`defaultFontFamily` _Object_ | 为 font-family 设置默认字体
`defaultFontFamily.standard` _string_ |默认值为 _(Times New Roman)_
`defaultFontFamily.serif` _string_ | 默认值为 _(Times New Roman)_
`defaultFontFamily.sansSerif` _string_ | 默认值为 _(Arial)_
`defaultFontFamily.monospace` _string_ | 默认值为 _(Courier New)_
`defaultFontFamily.cursive` _string_ | 默认值为 _(Script)_
`defaultFontFamily.fantasy` _string_ | 默认值为 _(Impact)_
`defaultFontSize` _Integer_ | 默认值为 _(16)_
`defaultMonospaceFontSize` _Integer_ | 默认值为 _(13)_
`minimumFontSize` _Integer_ | 默认值为 _(0)_
`defaultEncoding` _string_ | 默认值为 _(ISO-8859-1)_
`backgroundThrottling` _boolean_ | 是否在页面成为背景时限制动画和计时器。 这也会影响到 _[Visibility API](https://www.electronjs.org/docs/latest/api/browser-window#page-visibility)_。默认值为 _(true)_
`offscreen` _boolean_ | 是否绘制和渲染可视区域外的窗口。默认值为 _(false)_。更多详情, 请参见 [offscreen rendering tutorial](https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering)
`contextIsolation` _boolean_ | 是否在独立 JavaScript 环境中运行 Electron API和指定的_(preload)_ 脚本。默认为 _(true)_。 _(预加载)_脚本所运行的上下文环境只能访问其自身专用的 _(文档)_ 和全局 _(窗口)_其自身一系列内置的JavaScript (_(Array)_, _(Object)_, _(JSON)_, 等等) 也是如此,这些对于已加载的内容都是不可见的。 Electron API 将只在_(预加载)_脚本中可用在已加载页面中不可用。 这个选项应被用于加载可能不被信任的远程内容时来确保加载的内容无法篡改_(预加载)_脚本和任何正在使用的Electron api。 该选项使用的是与[Chrome内容脚本](https://developer.chrome.com/extensions/content_scripts#execution-environment)相同的技术。你可以在开发者工具Console选项卡内顶部组合框中选择 'Electron Isolated Context'条目来访问这个上下文
`webviewTag` _boolean_ | 是否启用 [_(&lt;webview&gt;)_ tag](https://www.electronjs.org/docs/latest/api/webview-tag)标签。默认值为 _(false)_。**注意:** 为 _(&lt; webview&gt;)_ 配置的 _(preload)_ 脚本在执行时将启用节点集成, 因此应确保远程或不受信任的内容无法创建恶意的 _(preload)_ 脚本 。 可以使用 [webContents](https://www.electronjs.org/docs/latest/api/web-contents) 上的 _(will-attach-webview)_ 事件对 _(preload)_ 脚本进行剥离, 并验证或更改 _(&lt;webview&gt;)_ 的初始设置
`additionalArguments` _string[]_ | strin一个将被附加到当前应用程序的渲染器进程中_(process.argv)_的字符串列表。可用于将少量的数据传递到渲染器进程预加载脚本中。
`safeDialogs` _boolean_ | 是否启用浏览器样式的持续对话框保护。 默认值为 _(false)_
`safeDialogsMessage` _string_ | 当持续对话框保护被触发时显示的消息。 如果没有定义,那么将使用缺省的消息。注意:当前缺省消息是英文,并没有本地化
`disableDialogs` _boolean_ | 是否完全禁用对话框。 覆盖 _(safeDialogs)_。 默认值为 _(false)_
`navigateOnDragDrop` _boolean_ | 将文件或链接拖放到页面上时是否触发页面跳转。 默认值为 _(false)_
`autoplayPolicy` _string_ | 窗口中内容要使用的自动播放策略,值可以是 _(no-user-gesture-required)_, _(user-gesture-required)_, _(document-user-activation-required)_。默认为 _(no-user-gesture-required)_
`disableHtmlFullscreenWindowResize` _boolean_ | 是否阻止窗口在进入 HTML 全屏时调整大小。默认值为 _(false)_
`accessibleTitle` _string_ | 仅提供给如屏幕读取器等辅助工具的替代标题字符串。此字符串不直接对用户可见
`spellcheck` _boolean_ | 是否启用内置拼写检查器。 默认值为 _(true)_
`enableWebSQL` _boolean_ | 是否启用 [WebSQL api](https://www.w3.org/TR/webdatabase/)。 默认值为 _(true)_
`v8CacheOptions` _string_ | 强制 blink 使用 v8 代码缓存策略。 可接受的值为:
`v8CacheOptions.none` | 禁用代码缓存
`v8CacheOptions.code` | 基于启发式代码缓存
`v8CacheOptions.bypassHeatCheck` | 绕过启发式代码缓存,但使用懒编译。
`v8CacheOptions.bypassHeatCheckAndEagerCompile` | 与上面相同,除了编译是及时的。 默认策略是 _(code)_
`enablePreferredSizeMode` _boolean_ | 是否启用首选大小模式。 首选大小是包含文档布局所需的最小大小--无需滚动。 启用该属性将导致在首选大小发生变化时,在 _(WebContents)_ 上触发 _(preferred-size-changed)_ 事件。默认值为 _(false)_
`titleBarOverlay` _Object/Boolean_ | 当在 macOS 使用无框窗口结合 _(win.setWindowButtonVisibility(true))_ 或使用 _(titleBarStyle)_ 以便标准窗口控制 (在 macOS为 "traffic lights") 可见,此属性将启用 Window Controls Overlay [JavaScript APIs](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis) 和 [CSS Environment Variables](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables)。指定 _(true)_ 将导致覆盖默认系统颜色。 默认值为 _(false)_
`color` _String_ _(win)_ | 启用窗口控制时覆盖面的 CSS 颜色 默认是系统颜色
`symbolColor` _String_ _(win)_ | 启用时窗口控制中符号的 CSS 颜色 默认是系统颜色
`height` _Integer_ _(win/mac)_ | 标题栏和 Window Controls Overlay以像素为单位。 默认值为系统高度
<!--rehype:className=style-list-->
### 实例事件
<!--rehype:wrap-class=col-span-3-->
```js
const { BrowserWindow } = require('electron')
const child = new BrowserWindow({ modal: true, show: false })
child.loadURL('https://github.com')
child.once('ready-to-show', () => {
child.show()
})
```
----
:- | :-
:- | :-
`page-title-updated` | 文档更改标题时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-page-title-updated)
`close` | 在窗口要关闭的时候触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-close)
`closed` | 在窗口关闭时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-closed)
`session-end` _(win)_ | 因为强制关机/重启/会话注销而导致窗口会话结束时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-session-end-windows)
`unresponsive` | 网页变得未响应时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-unresponsive)
`responsive` | 未响应的页面变成响应时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-responsive)
`blur` | 当窗口失去焦点时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-blur)
`focus` | 当窗口获得焦点时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-focus)
`show` | 当窗口显示时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-show)
`hide` | 当窗口隐藏时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-hide)
`ready-to-show` | 当页面已经渲染完成(还没有显示)窗口可以被显示时触发[#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-ready-to-show)
`maximize` | 窗口最大化时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-maximize)
`unmaximize` | 当窗口从最大化状态退出时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-unmaximize)
`minimize` | 窗口最小化时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-minimize)
`restore` | 当窗口从最小化状态恢复时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-restore)
`will-resize` _(mac/win)_ | 调整窗口大小前触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-will-resize-macos-windows)
`resize` | 调整窗口大小后触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-resize)
`resized` _(mac/win)_ | 当窗口完成调整大小后触发一次 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件resized-macos-windows)
`will-move` _(mac/win)_ | 窗口移动前触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-will-move-macos-windows)
`move` | 窗口移动到新位置时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-move)
`moved` _(mac/win)_ | 当窗口移动到新位置时触发一次 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-moved-macos-windows)
`enter-full-screen` | 窗口进入全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-enter-full-screen)
`leave-full-screen` | 窗口离开全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-leave-full-screen)
`enter-html-full-screen` | 窗口进入由HTML API 触发的全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-enter-html-full-screen)
`leave-html-full-screen` | 窗口离开由HTML API触发的全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-leave-html-full-screen)
`always-on-top-changed` | 设置或取消设置窗口总是在其他窗口的顶部显示时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-always-on-top-changed)
`app-command` | 请求一个应用程序命令时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-app-command-windows__linux)
`scroll-touch-begin` _(mac)_ | 滚轮事件阶段开始时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-scroll-touch-begin-macos)
`scroll-touch-end` _(mac)_ | 滚轮事件阶段结束时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-scroll-touch-end-macos)
`scroll-touch-edge` _(mac)_ | 滚轮事件阶段到达元素边缘时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-scroll-touch-edge-macos)
`swipe` | 三指滑动时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-swipe-macos)
`rotate-gesture` _(mac)_ | 在触控板旋转手势上触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-rotate-gesture-macos)
`sheet-begin` _(mac)_ | 窗口打开sheet(工作表) 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-sheet-begin-macos)
`sheet-end` _(mac)_ | 窗口关闭sheet(工作表) 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-sheet-end-macos)
`new-window-for-tab` _(mac)_ | 当点击了系统的新标签按钮时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-new-window-for-tab-macos)
`system-context-menu` _(win)_ | 当系统上下文菜单在窗口上触发时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-system-context-menu-windows)
### 实例方法
<!--rehype:wrap-class=col-span-3 row-span-3-->
:- | :-
:- | :-
`win.destroy()` | 强制关闭窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#windestroy)
`win.close()` | 尝试关闭窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winclose)
`win.focus()` | 聚焦于窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfocus)
`win.blur()` | 取消窗口的聚焦 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winblur)
`win.isFocused()` | 判断窗口是否聚焦 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfocused)
`win.isDestroyed()` | 判断窗口是否被销毁 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisdestroyed)
`win.show()` | 显示并聚焦于窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshow)
`win.showInactive()` | 显示但不聚焦于窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshowinactive)
`win.hide()` | 隐藏窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winhide)
`win.isVisible()` | 判断窗口是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisvisible)
`win.isModal()` | 判断是否为模态窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismodal)
`win.maximize()` | 最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmaximize)
`win.unmaximize()` | 取消窗口最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winunmaximize)
`win.isMaximized()` | 判断窗口是否最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismaximized)
`win.minimize()` | 最小化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winminimize)
`win.restore()` | 窗口最小化状态恢复到以前的状态 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winrestore)
`win.isMinimized()` | 判断窗口是否最小化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisminimized)
`win.setFullScreen(flag)` | 设置窗口是否应处于全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetfullscreenflag)
`win.isFullScreen()` | 窗口当前是否已全屏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfullscreen)
`win.setSimpleFullScreen(flag)` _(mac)_ | 进入或离开简单的全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetsimplefullscreenflag-macos)
`win.isSimpleFullScreen()` | 窗口是否为简单全屏模式(pre-Lion) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winissimplefullscreen-macos)
`win.isNormal()` | 窗口是否处于正常状态(未最大化,未最小化,不在全屏模式下) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisnormal)
`win.setAspectRatio(aspectRatio[, extraSize])` | 为内容视图保持的宽高比 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetaspectratioaspectratio-extrasize)
`win.setBackgroundColor(backgroundColor)` | 颜色,格式为 HexRGBRGBAHSLHSLA 或 CSS 命名颜色 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetbackgroundcolorbackgroundcolor)
`win.previewFile(path[, displayName])` _(mac)_ | 要用 QuickLook 预览的文件的绝对路径 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winpreviewfilepath-displayname-macos)
`win.closeFilePreview()` _(mac)_ | 关闭当前打开的 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winclosefilepreview-macos)
`win.setBounds(bounds[, animate])` | 重置窗口,并且移动窗口到指定的位置 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetboundsbounds-animate)
`win.getBounds()` | 表示窗口的 `bounds` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbounds)
`win.getBackgroundColor()` | 格式获取窗口的背景色,格式为 Hex (`#RRGGBB`) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbackgroundcolor)
`win.setContentBounds(bounds[, animate])` | 调整窗口的工作区 (如网页) 的大小并将其移动到所提供的边界。 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetcontentboundsbounds-animate)
`win.getContentBounds()` | 窗口客户端区域的 `bounds` `对象` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetcontentbounds)
`win.getNormalBounds()` | 包含正常状态下的窗口大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetnormalbounds)
`win.setEnabled(enable)` | 禁用或者启用窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetenabledenable)
`win.isEnabled()` | 窗口是否启用 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisenabled)
`win.setSize(width, height[, animate])` | 调整窗口的 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetsizewidth-height-animate)
`win.getSize()` | 包含窗口的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetsize)
`win.setContentSize(width, height[, animate])` | 将窗口的工作区 (如网页) 的大小调整为 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetcontentsizewidth-height-animate)
`win.getContentSize()` | 包含窗口的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetcontentsize)
`win.setMinimumSize(width, height)` | 设置窗口最小化的 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetminimumsizewidth-height)
`win.getMinimumSize()` | 包含窗口最小化的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetminimumsize)
`win.setMaximumSize(width, height)` | 设置窗口最大化的 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmaximumsizewidth-height)
`win.getMaximumSize()` | 包含窗口最大化的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetmaximumsize)
`win.setResizable(resizable)` | 设置用户是否可以手动调整窗口大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetresizableresizable)
`win.isResizable()` | 用户是否可以手动调整窗口大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisresizable)
`win.setMovable(movable)` _(mac/win)_ | 设置用户是否可以移动窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmovablemovable-macos-windows)
`win.isMovable()` _(mac/win)_ | 窗口是否可以被用户拖动,在 Linux 上总是返回 `true` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismovable-macos-windows)
`win.setMinimizable(minimizable)` _(mac/win)_ | 设置用户是否可以手动将窗口最小化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetminimizableminimizable-macos-windows)
`win.isMinimizable()` _(mac/win)_ | 用户是否可以手动最小化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisminimizable-macos-windows)
`win.setMaximizable(maximizable)` _(mac/win)_ | 设置用户是否可以手动最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmaximizablemaximizable-macos-windows)
`win.isMaximizable()` _(mac/win)_ | 窗口是否可以最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismaximizable-macos-windows)
`win.setFullScreenable(fullscreenable)` | 设置最大化/缩放窗口按钮是切换全屏模式还是最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetfullscreenablefullscreenable)
`win.isFullScreenable()` | 最大化/缩放窗口按钮是切换全屏模式还是最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfullscreenable)
`win.setClosable(closable)` _(mac/win)_ | 设置用户是否可以手动关闭窗口。 在Linux上不起作用 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetclosableclosable-macos-windows)
`win.isClosable()` _(mac/win)_ | 窗口是否被用户关闭了 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisclosable-macos-windows)
`win.setAlwaysOnTop(flag[, level][, relativeLevel])` | 设置窗口是否应始终显示在其他窗口的前面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetalwaysontopflag-level-relativelevel)
`win.isAlwaysOnTop()` | 当前窗口是否始终在其它窗口之前 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisalwaysontop)
`win.moveAbove(mediaSourceId)` | 将窗口按z轴顺序移动到源窗口前面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmoveabovemediasourceid)
`win.moveTop()` | 无论焦点如何, 将窗口移至顶端(z轴上的顺序) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmovetop)
`win.center()` | 将窗口移动到屏幕中央 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wincenter)
`win.setPosition(x, y[, animate])` | 将窗口移动到 `x` 和 `y` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetpositionx-y-animate)
`win.getPosition()` | 返回一个包含当前窗口位置的数组 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetposition)
`win.setTitle(title)` | 将原生窗口的标题更改为 `title` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettitletitle)
`win.getTitle()` | 网页的标题可以与原生窗口的标题不同 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingettitle)
`win.setSheetOffset(offsetY[, offsetX])` _(mac/win)_ | 改变macOS上sheet组件的附着点默认情况下sheet贴在窗口边框正下方 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetsheetoffsetoffsety-offsetx-macos)
`win.flashFrame(flag)` | 启动或停止闪烁窗口, 以吸引用户的注意 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winflashframeflag)
`win.setSkipTaskbar(skip)` _(mac/win)_ | 使窗口不显示在任务栏中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetskiptaskbarskip-macos-windows)
`win.setKiosk(flag)` | 进入或离开 kiosk 模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetkioskflag)
`win.isKiosk()` | 判断窗口是否处于kiosk模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winiskiosk)
`win.isTabletMode()` _(win)_ | 此 API 返回 窗口是否在平板电脑模式下,并且 调整大小 事件可以用于监听对平板模式的更改 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winistabletmode-windows)
`win.getMediaSourceId()` | DesktopCapturerSource 的 `id` 格式的窗口 `id` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetmediasourceid)
`win.getNativeWindowHandle()` | 窗口的平台特定句柄 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetnativewindowhandle)
`win.hookWindowMessage(message, callback)` _(win)_ | 钩住窗口消息。 当消息到达 WndProc 时调用 callback [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winhookwindowmessagemessage-callback-windows)
`win.isWindowMessageHooked(message)` _(win)_ | 返回 boolean - true 或false具体取决于是否钩挂了消息 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winiswindowmessagehookedmessage-windows)
`win.unhookWindowMessage(message)` _(win)_ | 取消窗口信息的钩子 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winunhookwindowmessagemessage-windows)
`win.unhookAllWindowMessages()` _(win)_ | 取消所有窗口信息的钩子 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winunhookallwindowmessages-windows)
`win.setRepresentedFilename(filename)` _(mac)_ | 设置窗口所代表的文件的路径名,并且将这个文件的图标放在窗口标题栏上 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetrepresentedfilenamefilename-macos)
`win.getRepresentedFilename()` _(mac)_ | 获取窗口当前文件路径 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetrepresentedfilename-macos)
`win.setDocumentEdited(edited)` _(mac)_ | 明确指出窗口文档是否可以编辑如果设置为true则将标题栏的图标变成灰色 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetdocumenteditededited-macos)
`win.isDocumentEdited()` _(mac)_ | 判断当前窗口文档是否可编辑 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisdocumentedited-macos)
`win.focusOnWebView()` | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfocusonwebview)
`win.blurWebView()` | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winblurwebview)
`win.capturePage([rect])` | 在 rect 内捕获页面的快照 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wincapturepagerect)
`win.loadURL(url[, options])` | 加载页面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winloadurlurl-options)
`win.loadFile(filePath[, options])` | 加载页面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winloadfilefilepath-options)
`win.reload()` | 与 `webContents.reload` 相同 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winreload)
`win.setMenu(menu)` _(win/linux)_ | 将 `menu` 设置为窗口的菜单栏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmenumenu-linux-windows)
`win.removeMenu()` _(win)_ | 删除窗口的菜单栏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winremovemenu-linux-windows)
`win.setProgressBar(progress[, options])` | 设置进度条的进度值 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetprogressbarprogress-options)
`win.setOverlayIcon(overlay, description)` _(win)_ | 设置进度条的进度值。 有效范围为 `[0, 1.0]` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetoverlayiconoverlay-description-windows)
`win.setHasShadow(hasShadow)` | 设置窗口是否有阴影 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsethasshadowhasshadow)
`win.hasShadow()` | 判断窗口是否有阴影 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winhasshadow)
`win.setOpacity(opacity)` _(win/mac)_ | 设置窗口的不透明度。 在Linux上不起作用。 超出界限的数值被限制在 `[0, 1]` 范围内 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetopacityopacity-windows-macos)
`win.getOpacity()` | 介于 `0.0` (完全透明) 和 `1.0` (完全不透明) 之间。在Linux上始终返回 `1` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetopacity)
`win.setShape(rects)` _(win/linux)_ | 对窗口形状的设置决定了窗口内系统允许绘制与用户交互的区域 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetshaperects-windows-linux-实验性)
`win.setThumbarButtons(buttons)` _(win)_ | 将指定的一组按钮添加到菜单栏的缩图工具栏上 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetthumbarbuttonsbuttons-windows)
`win.setThumbnailClip(region)` _(win)_ | 将窗口的区域设置为在任务栏中悬停在窗口上方时显示的缩略图图像 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetthumbnailclipregion-windows)
`win.setThumbnailToolTip(toolTip)` _(win)_ | 设置在任务栏中悬停在窗口缩略图上时显示的工具提示 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetthumbnailtooltiptooltip-windows)
`win.setAppDetails(options)` _(win)_ | 设置窗口任务栏按钮的属性 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetappdetailsoptions-windows)
`win.showDefinitionForSelection()` _(mac)_ | 和 `webContents.showDefinitionForSelection()` 相同 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshowdefinitionforselection-macos)
`win.setIcon(icon)` _(win/linux)_ | 设置窗口图标 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winseticonicon-windows-linux)
`win.setWindowButtonVisibility(visible)` _(mac)_ | 设置是否窗口交通灯需要显示 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetwindowbuttonvisibilityvisible-macos)
`win.setAutoHideMenuBar(hide)` _(win/linux)_ | 设置窗口菜单栏是否自动隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetautohidemenubarhide-windows-linux)
`win.isMenuBarAutoHide()` _(win/linux)_ | 判断窗口的菜单栏是否自动隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismenubarautohide-windows-linux)
`win.setMenuBarVisibility(visible)` _(win/linux)_ | 设置菜单栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmenubarvisibilityvisible-windows-linux)
`win.isMenuBarVisible()` _(win/linux)_ | 判断窗口的菜单栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismenubarvisible-windows-linux)
`win.setVisibleOnAllWorkspaces(visible[, options])` _(mac/linux)_ | 设置窗口是否在所有工作空间上可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetvisibleonallworkspacesvisible-options-macos-linux)
`win.isVisibleOnAllWorkspaces()` _(mac/linux)_ | 判断窗口是否在所有工作空间上可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisvisibleonallworkspaces-macos-linux)
`win.setIgnoreMouseEvents(ignore[, options])` | 忽略窗口内的所有鼠标事件 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetignoremouseeventsignore-options)
`win.setContentProtection(enable)` _(mac/linux)_ | 防止窗口内容被其他应用捕获 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetcontentprotectionenable-macos-windows)
`win.setFocusable(focusable)` _(mac/linux)_ | 设置窗口是否可聚焦 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetfocusablefocusable-macos-windows)
`win.isFocusable()` _(mac/linux)_ | 返回当前窗口是否可以作为焦点被选中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfocusable-macos-windows)
`win.setParentWindow(parent)` | 设置 `parent` 为当前窗口的父窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetparentwindowparent)
`win.getParentWindow()` | 返回 BrowserWindow/null - 如果没有父窗口则为 `null` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetparentwindow)
`win.getChildWindows()` | 返回 `BrowserWindow[]` - 首页的子窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetchildwindows)
`win.setAutoHideCursor(autoHide)` _(mac)_ | 设置输入时是否隐藏光标 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetautohidecursorautohide-macos)
`win.selectPreviousTab()` _(mac)_ | 当启用本地选项卡,并且窗口中有另一个标签时,选择上一个选项卡 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winselectprevioustab-macos)
`win.selectNextTab()` _(mac)_ | 当启用本地选项卡,并且窗口中有另一个标签时,选择下一个选项卡 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winselectnexttab-macos)
`win.mergeAllWindows()` _(mac)_ | 当启用本地选项卡并且存在多个打开窗口时,将所有窗口合并到一个带有多个选项卡的窗口中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmergeallwindows-macos)
`win.moveTabToNewWindow()` _(mac)_ | 如果启用了本机选项卡并且当前窗口中有多个选项卡,则将当前选项卡移动到新窗口中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmovetabtonewwindow-macos)
`win.toggleTabBar()` _(mac)_ | 如果启用了本机选项卡并且当前窗口中只有一个选项卡,则切换选项卡栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wintoggletabbar-macos)
`win.addTabbedWindow(browserWindow)` _(mac)_ | 在该窗口中添加一个窗口作为选项卡,位于窗口实例的选项卡之后 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winaddtabbedwindowbrowserwindow-macos)
`win.setVibrancy(type)` _(mac)_ | 在浏览器窗口中添加一个动态特效。 传递 null 或空字符串将会移除窗口上的动态效果 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetvibrancytype-macos)
`win.setTrafficLightPosition(position)` _(mac)_ | 在无框窗口中设置自定义控制按钮的位置 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettrafficlightpositionposition-macos)
`win.getTrafficLightPosition()` _(mac)_ | 在无框窗口中自定义控制按钮的位置 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingettrafficlightposition-macos)
`win.setTouchBar(touchBar)` _(mac)_ | 设置窗口的触摸条布局 设置为 null 或undefined将清除触摸条 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettouchbartouchbar-macos)
`win.setBrowserView(browserView)` _(实验)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetbrowserviewbrowserview-实验)
`win.getBrowserView()` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbrowserview-实验功能)
`win.addBrowserView(browserView)` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winaddbrowserviewbrowserview-实验功能)
`win.removeBrowserView(browserView)` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winremovebrowserviewbrowserview-实验功能)
`win.setTopBrowserView(browserView)` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettopbrowserviewbrowserview-实验功能)
`win.getBrowserViews()` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbrowserviews-实验功能)
`win.setTitleBarOverlay(options)` _(win)_ | 在已开启 Window Controls Overlay 的窗口上,此方法将更新标题栏叠加层的样式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettitlebaroverlayoptions-windows)
<!--rehype:className=style-list-->
### 静态方法
<!--rehype:wrap-class=col-span-3-->
:- | :-
:- | :-
`BrowserWindow.getAllWindows()` | 所有打开的窗口的数组 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowgetallwindows)
`BrowserWindow.getFocusedWindow()` | 当前获得焦点的窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowgetfocusedwindow)
`BrowserWindow.fromWebContents(webContents)` | 拥有给定 webContents 窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowfromwebcontentswebcontents)
`BrowserWindow.fromBrowserView(browserView)` | 拥有给定 browserView 窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowfrombrowserviewbrowserview)
`BrowserWindow.fromId(id)` | 带有给定 id 的窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowfromidid)
### 实例属性
<!--rehype:wrap-class=col-span-3-->
```js
const { BrowserWindow } = require('electron')
// 本例中 `win` 是我们的实例
const win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL('https://github.com')
```
----
:- | :-
:- | :-
`win.webContents` | 此窗口拥有的 WebContents 对象 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winwebcontents-只读)
`win.id` | 代表了窗口的唯一ID [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winid-只读)
`win.autoHideMenuBar` | 决定窗口菜单栏是否自动隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winautohidemenubar)
`win.simpleFullScreen` | 决定窗口是否处于简单(pre-Lion) 全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsimplefullscreen)
`win.fullScreen` | 决定窗口是否处于全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfullscreen)
`win.focusable` | 确定窗口是否可作为焦点被选中的属性 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfocusable-windows-macos)
`win.visibleOnAllWorkspaces` | 决定窗口是否在所有工作区中可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winvisibleonallworkspaces-macos-linux)
`win.shadow` | 决定窗口是否显示阴影 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshadow)
`win.menuBarVisible` | 决定菜单栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmenubarvisible-windows-linux)
`win.kiosk` | 决定窗口是否处于kiosk模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winkiosk)
`win.documentEdited` | 指明窗口文档是否已被编辑 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#windocumentedited-macos)
`win.representedFilename` | 确定窗口代表的文件的路径名 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winrepresentedfilename-macos)
`win.title` | 用于确定原生窗口的标题 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wintitle)
`win.minimizable` | 决定窗口是否可被用户手动最小化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winminimizable-macos-windows)
`win.maximizable` | 决定窗口是否可被用户手动最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmaximizable-macos-windows)
`win.fullScreenable` | 决定是切换全屏模式还是最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfullscreenable)
`win.resizable` | 决定窗口是否可被用户手动调整大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winresizable)
`win.closable` | 决定窗口是否可被用户手动关闭 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winclosable-macos-windows)
`win.movable` | 决定窗口是否可被用户移动 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmovable-macos-windows)
`win.excludedFromShownWindowsMenu` | 决定窗口是否从 Windows 菜单排除 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winexcludedfromshownwindowsmenu-macos)
`win.accessibleTitle` | 定义一个仅为辅助工具提供的替代标题 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winaccessibletitle)
另见
---
- [Electron 备忘清单](https://simulatedgreg.github.io/electron-cheatsheet/) _(simulatedgreg.github.io)_

524
docs/emacs.md Normal file
View File

@ -0,0 +1,524 @@
Emacs 备忘清单
====
[Emacs](https://www.gnu.org/software/emacs) 是可扩展的、可定制的、自记录的实时显示文本编辑器。此参考适用于 Emacs 27+
入门
----
### 启动 Emacs
要进入 Emacs只需输入其名称
```shell
$ emacs
```
------
:- | :-
:- | :-
`C-z` | 挂起 Emacs
`C-x` `C-c` | 永久退出 Emacs
<!--rehype:className=shortcuts-->
### 全局描述
:- | :-
:- | :-
`C-<key>` | 表示按住控件,然后按 `<key>`
`M-<key>` | 表示按 `Esc` 一次,然后按 `<key>`
<!--rehype:className=shortcuts-->
注意:本备忘单遵循上述规则
### 移动
<!--rehype:wrap-class=row-span-2-->
返回 | 向前 | 要移动的实体
:- | :- | :-
`C-b` | `C-f` | Haracter
`M-b` | `M-f` | 单词
`C-p` | `C-n` | 线
`C-a` | `C-e` | 行开头<br/>_或结尾_
`M-a` | `M-e` | 句子
`M-{` | `M-}` | 段落
`C-x` `[` | `C-x` `]` | 页
`C-M-b` | `C-M-f` | Sexp
`C-M-a` | `C-M-e` | 功能
`M-<` | `M->` | 缓冲区开始<br>_或结束_
<!--rehype:className=shortcuts show-header-->
### 案例变更
:- | :-
:- | :-
`M-u` | 大写单词
`M-l` | 小写单词
`M-c` | 大写单词
`C-x` `C-u` | 大写区域
`C-x` `C-l` | 小写区域
<!--rehype:className=shortcuts-->
### 文件
:- | :-
:- | :-
`C-x` `C-f` | 将文件读入 Emacs
`C-x` `C-s` | 将文件保存回磁盘
`C-x` `s` | 保存所有文件
`C-x` `i` | 将另一个文件的内容插入此缓冲区
`C-x` `C-v` | 将此文件替换为您的文件
`C-x` `C-w` | 将缓冲区写入指定文件
`C-x` `C-q` | 切换缓冲区的只读状态
<!--rehype:className=shortcuts-->
### 错误恢复
:- | :-
:- | :-
`C-g` | 中止部分键入或执行的命令
`M-x` 恢复会话 | 恢复因系统崩溃而丢失的文件
`C-x` `u` `C-_` `C-/` | 撤消不需要的更改
`M-x` 恢复缓冲器 | 将缓冲区恢复到其原始内容
`C-l` | 重绘垃圾屏幕
<!--rehype:className=shortcuts-->
### Transposing
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`C-t` | 转置字符
`M-t` | 转置词
`C-x` `C-t` | 转置线
`C-M-t` | 转置性别
<!--rehype:className=shortcuts-->
#### Scroll
:- | :-
:- | :-
`C-v` | 滚动到下一个屏幕
`M-v` | 滚动到上一个屏幕
`C-x` `<` | 向左滚动
`C-x` `>` | 向右滚动
`C-l` | 将当前行滚动到 <br> _center, top, bottom_
<!--rehype:className=shortcuts-->
#### 跳转
:- | :-
:- | :-
`M-g` `g` | 转到行
`M-g` `c` | 转到字符
`M-m` | 返回缩进
<!--rehype:className=shortcuts-->
### 标记
:- | :-
:- | :-
`C-@` `C-SPC` | 在标记在这里
`C-x` `C-x` | 交换点和标记
`M-@` | 设置标记 arg 单词
`M-h` | 标记段落
`C-x` `C-p` | 标记页面
`C-M-@` | 标记性
`C-M-h` | 标记功能
`C-x` `h` | 标记整个缓冲区
<!--rehype:className=shortcuts-->
### 杀死和删除
<!--rehype:wrap-class=row-span-2-->
向后 | 向前 | 要杀死的实体
:- | :- | :-
`DEL` | `C-d` | 字符 <br>_(删除)_
`M-DEL` | `M-d` | 单词
`M-0` `C-k` | `C-k` | 行 <br/> _(到结尾)_
`C-x` `DEL` | `M-k` | 句子
`M--` `C-M-k` | `C-M-k` | 性爱
<!--rehype:className=shortcuts show-header-->
#### 杀死
:- | :-
:- | :-
`C-W` | 杀死区域 C-w
`M-w` | 复制区域杀死环
`M-z` char | 杀死下一次出现的字符
`C-y` | 拉回最后一个被杀的东西
`M-y` | 用之前的杀戮替换最后的猛拉
<!--rehype:className=shortcuts-->
### 获得帮助
:- | :-
:- | :-
`C-x` `1` | 删除帮助窗口
`C-M-v` | 滚动帮助窗口
`C-h` `a` | Apropos显示匹配字符串的命令
`C-h` `k` | 描述一个键运行的功能
`C-h` `f` | 描述一个函数
`C-h` `m` | 获取特定于模式的信息
<!--rehype:className=shortcuts-->
帮助系统很简单。键入 `C-h`(或 `F1`)并按照说明进行操作。如果您是第一次使用,请键入 `C-h` `t` 以获得教程
### 多个窗口
<!--rehype:wrap-class=col-span-2 row-span-2-->
当显示两个命令时,第二个命令是用于框架而不是窗口的类似命令
:- | :- | :-
:- | :- | :-
`C-x` `5` `1` | `C-x` `1` | 删除所有其他窗口
`C-x` `5` `2` | `C-x` `2` | 拆分窗口,上方和下方
`C-x` `5` `0` | `C-x` `0` | 删除此窗口
<!--rehype:className=shortcuts-->
:- | :- | :-
:- | :- | :-
&nbsp; | `C-x` `3` | 拆分窗口,并排
&nbsp; | `C-M-v` | 滚动其他窗口
<!--rehype:className=shortcuts-->
:- | :- | :-
:- | :- | :-
`C-x` `5` `o` | `C-x` `o` | 将光标切换到另一个窗口
`C-x` `5` `b` | `C-x` `4` `b` | 在其他窗口中选择缓冲区
`C-x` `5` `C-o` | `C-x` `4` `C-o` | 在其他窗口中显示缓冲区
`C-x` `5` `f` | `C-x` `4` `f` | 在其他窗口中查找文件
`C-x` `5` `r` | `C-x` `4` `r` | 在其他窗口中以只读方式查找文件
`C-x` `5` `d` | `C-x` `4` `d` | 在其他窗口中运行 Dired
`C-x` `5` `.` | `C-x` `4` `.` | 在其他窗口中查找标签
<!--rehype:className=shortcuts-->
:- | :- | :-
:- | :- | :-
&nbsp; | `C-x` `^` | 让窗户变高
&nbsp; | `C-x` `{` | 缩小窗口
&nbsp; | `C-x` `}` | 让窗口变宽
<!--rehype:className=shortcuts-->
### 格式化
:- | :-
:- | :-
`TAB` | 缩进当前行(取决于模式)
`C-M-\` | 缩进区域(取决于模式)
`C-M-q` | 缩进 sexp取决于模式
`C-x` `TAB` | 缩进区域刚性 arg 列
`M-;` | 缩进评论
`C-o` | 在点后插入换行符
`C-M-o` | 将其余行垂直向下移动
`C-x` `C-o` | 删除点周围的空行
`M-^` | 与上一个加入行(带 arg下一个
`M-\` | 删除点周围的所有空白
`M-SPC` | 在点上正好放一个空格
`M-q` | 填写段落
`C-x` `f` | 将填充列设置为 arg
`C-x` `.` | 设置每行开头的前缀
`M-o` | 设置面
<!--rehype:className=shortcuts-->
### 信息
<!--rehype:wrap-class=row-span-3-->
:- | :-
:- | :-
`C-h` `i` | 输入信息文档阅读器
`C-h` `S` | 在 Info 中查找指定的函数或变量
<!--rehype:className=shortcuts-->
#### 在节点内移动
:- | :-
:- | :-
`SPC` | 向前滚动
`DEL` | 反向滚动
`b` | 节点的开始
<!--rehype:className=shortcuts-->
#### 在节点之间移动
:- | :-
:- | :-
`n` | 下一个节点
`p` | 上一个节点
`u` | 提升
`m` | 按名称选择菜单项
`n` | 按编号 (19) 选择第 n 个菜单项
`f` | 遵循交叉引用(用 l 返回)
`l` | 返回您看到的最后一个节点
`d` | 返回目录节点
`t` | 转到信息文件的顶部节点
`g` | 按名称转到任何节点
<!--rehype:className=shortcuts-->
#### 其他
:- | :-
:- | :-
`h` | 运行信息教程
`i` | 在索引中查找主题
`s` | 搜索节点以查找正则表达式
`q` | 退出信息
<!--rehype:className=shortcuts-->
### 小缓冲区
<!--rehype:wrap-class=row-span-2-->
以下键在 `minibuffer` 中定义
:- | :-
:- | :-
`TAB` | 尽可能完成
`SPC` | 最多完成一个单词
`RET` | 完成并执行
`?` | 显示可能的完成
`M-p` | 获取先前的 `minibuffer` 输入
`M-n` | 获取稍后的 `minibuffer` 输入或默认值
`M-r` | 正则表达式向后搜索历史
`M-s` | 正则表达式向前搜索历史
`C-g` | 中止命令
<!--rehype:className=shortcuts-->
键入 `C-x` `ESC` `ESC` 以编辑并重复使用 `minibuffer` 的最后一个命令。键入 `F10` 以激活文本终端上的菜单栏项
### 标签
:- | :-
:- | :-
`M-.` | 查找标签(定义)
`C-u` `M-.` | 查找标签的下一个出现
`M-x` 访问标签表 | 指定一个新的标签文件
`M-x` 标签搜索 | 正则表达式搜索标签表中的所有文件
`M-x` 标签查询替换 | 对所有文件运行查询替换
`M-,` | 继续最后一个标签搜索或查询替换
<!--rehype:className=shortcuts-->
### 缓冲器
:- | :-
:- | :-
`C-x` `b` | 选择另一个缓冲区
`C-x` `C-b` | 列出所有缓冲区
`C-x` `k` | 杀死一个缓冲区
<!--rehype:className=shortcuts-->
### 矩形
:- | :-
:- | :-
`C-x` `r` `r` | 复制矩形进行注册
`C-x` `r` `k` | 杀死矩形
`C-x` `r` `y` | 拉长矩形
`C-x` `r` `o` | 打开矩形,向右移动文本
`C-x` `r` `c` | 空白矩形
`C-x` `r` `t` | 用字符串为每一行添加前缀
<!--rehype:className=shortcuts-->
### 键盘宏
:- | :-
:- | :-
`C-x` `(` | 开始定义键盘宏
`C-x` `)` | 结束键盘宏定义
`C-x` `e` | 执行最后定义的键盘宏
`C-u` `C-x` `(` | 附加到最后一个键盘宏
`M-x` name-last-kbd-macro | 命名最后一个键盘宏
`M-x` insert-kbd-macro | 在缓冲区中插入 Lisp 定义
<!--rehype:className=shortcuts-->
Emacs 搜索
------
### 正则表达式(常用)
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`.` `(dot)` | 除换行符外的任何单个字符
`*` | 零次或多次重复
`+` | 一次或多次重复
`?` | 零次或一次重复
`\` | 引用特殊字符
`\c` | 引用正则表达式特殊字符 c
`\|` | 替代(“或”)
`\(...\)` | 分组
`\(:?...\)` | 害羞的分组
`\(:NUM...\)` | 显式编号分组
`\n` | 与第 n 组相同的文本
`\b` | 在断字时
`\B` | 不在断字
### 正则表达式(条目)
开始 | 结束 | 实体
:- | :- | :-
`^` | `$` | 行
`\<` | `\>` | 单词
`\_<` | `\_>` | 象征
`\` | `\` | 缓冲
<!--rehype:className=show-header-->
### 正则表达式(冲突)
这些 | 其他 | class
:- | :- | :-
`[...]` | `[^...]` | 显式集
`\w` | `\W` | 单词语法字符
`\sc` | `\Sc` | 具有语法 c 的字符
`\cc` | `\Cc` | 类别 c 的字符
<!--rehype:className=show-header-->
### 增量搜索
:- | :-
:- | :-
`C-s` | 向前搜索
`C-r` | 向后搜索
`C-M-s` | 正则表达式搜索
`C-M-r` | 反向正则表达式搜索
`M-p` | 选择上一个搜索字符串
`M-n` | 选择下一个稍后搜索字符串
`RET` | 退出增量搜索
`DEL` | 最后一个字符的撤消效果
`C-g` | 中止当前搜索
<!--rehype:className=shortcuts-->
再次使用 `C-s``C-r` 在任一方向重复搜索。 如果 Emacs 仍在搜索,`C-g` 只取消不匹配的部分
### 查询替换
:- | :-
:- | :-
`M-%` | 以交互方式替换文本字符串
`M-x` regexp | 使用正则表达式
`SPC` / `y` | 替换这个,继续下一个
`,` | 换这个,别动
`DEL` / `n` | 不更换就跳到下一个
`!` | 替换所有剩余的匹配项
`^` | 回到上一场比赛
`RET` | 退出查询替换
`C-r` | 进入递归编辑C-M-c 退出)
<!--rehype:className=shortcuts-->
杂项
----
### Shell
:- | :-
:- | :-
`M-!` | 执行一个shell命令
`M-&` | 异步执行shell命令
`M-` | 在区域上运行 shell 命令
`C-u` `M-` | 通过 shell 命令过滤区域
`M-x` shell | 在window shell中启动一个shell
<!--rehype:className=shortcuts-->
### 国际字符集
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`C-x` `RET` `l` | 指定主要语言
`M-x` list-input-methods | 显示所有输入法
`C-\` | 启用或禁用输入法
`C-x` `RET` `c` | 为下一个命令设置编码系统
`M-x` list-coding-systems | 显示所有编码系统
`M-x` prefer-coding-system | 选择首选的编码系统
<!--rehype:className=shortcuts-->
### 寄存器
:- | :-
:- | :-
`C-x` `r` `s` | 在寄存器中保存区域
`C-x` `r` `i` | 将寄存器内容插入缓冲区
`C-x` `r` `SPC` | 将点的值保存在寄存器中
`C-x` `r` `j` | 跳转到保存在寄存器中的点
<!--rehype:className=shortcuts-->
### 各种各样的
:- | :-
:- | :-
`C-u` num | 数值参数
`M--` | 否定论点
`C-q` char | 带引号的插页
<!--rehype:className=shortcuts-->
### 处理 Emacs Lisp 的命令
:- | :-
:- | :-
`C-x` `C-e` | 评估点前的性
`C-M-x` | 评估电流定义
`M-x` eval-region | 评估区
`M-:` | 读取和评估 minibuffer
`M-x` load-library | 从加载路径加载 Lisp 库
<!--rehype:className=shortcuts-->
### 简单的定制
:- | :-
:- | :-
`M-x` `customize` | 自定义变量和面
在 Emacs Lisp 中进行全局键绑定:
```emacs
(global-set-key (kbd "C-c g") search-forward)
(global-set-key (kbd "M-#") query-replace-regexp)
```
<!--rehype:className=wrap-text -->
### 缩写
:- | :-
:- | :-
`C-x` `a` `g` | 添加全局缩写
`C-x` `a` `l` | 添加模式本地缩写
`C-x` `a` `i` `g` | 为这个缩写添加全局扩展
`C-x` `a` `i` `l` | 为这个缩写添加模式本地扩展
`C-x` `a` `e` | 显式扩展缩写
`M-/` | 动态扩展前一个单词
<!--rehype:className=shortcuts-->
### 拼写检查
:- | :-
:- | :-
`M-$` | 检查当前单词的拼写
`M-x` ispell 地区 | 检查区域内所有单词的拼写
`M-x` ispell 缓冲区 | 检查整个缓冲区的拼写
`M-x` flyspell 模式 | 切换即时拼写检查
<!--rehype:className=shortcuts-->
### 编写命令
<!--rehype:wrap-class=col-span-2-->
#### 语法
```emacs
(defun command-name (args)
"documentation" (interactive "template")
body)
```
<!--rehype:className=wrap-text -->
#### 示例
```emacs
(defun this-line-to-top-of-window (line)
"Reposition current line to top of window.
With prefix argument LINE, put point on LINE."
(interactive "P")
(recenter (if (null line)
0
(prefix-numeric-value line))))
```

2401
docs/emmet.md Normal file

File diff suppressed because it is too large Load Diff

748
docs/es6.md Normal file
View File

@ -0,0 +1,748 @@
ES2015+ 备忘清单
===
快速浏览 ES2015、ES2016、ES2017、ES2018 及以后的 JavaScript 新特性
常用
---
### 块范围
<!--rehype:wrap-class=row-span-2-->
#### Let
```js {2,4}
function fn () {
let x = 0
if (true) {
let x = 1 // 只在这个`if`里面
}
}
```
#### Const
```js
const a = 1
```
`let` 是新的 `var`。 常量(`const`) 就像 `let` 一样工作,但不能重新分配。
请参阅:[Let 和 const](https://babeljs.io/learn-es2015/#let--const)
### 反引号字符串
<!--rehype:wrap-class=row-span-2-->
#### 插值
```js
const message = `Hello ${name}`
```
#### 多行字符串
```js
const str = `
hello
world
`
```
模板和多行字符串。
请参阅:[模板字符串](https://babeljs.io/learn-es2015/#template-strings)
### 二进制和八进制文字
```js
let bin = 0b1010010
let oct = 0o755
```
请参阅:[二进制和八进制文字](https://babeljs.io/learn-es2015/#binary-and-octal-literals)
### 指数运算符
```js {1}
const byte = 2 ** 8
// 同: Math.pow(2, 8)
```
### 新方法
#### 新的字符串方法
```js
"hello".repeat(3)
"hello".includes("ll")
"hello".startsWith("he")
"hello".padStart(8) // " hello"
"hello".padEnd(8) // "hello "
"hello".padEnd(8, '!') // hello!!!
"\u1E9B\u0323".normalize("NFC")
```
#### 新的数字方法
```js
Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false
```
#### 新的 Math 方法
```js
Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
```
#### 新的 Array 方法
```js
// 返回一个真实的数组
Array.from(document.querySelectorAll("*"))
// 类似于 new Array(...),但没有特殊的单参数行为
Array.of(1, 2, 3)
```
请参阅: [新方法](https://babeljs.io/learn-es2015/#math--number--string--object-apis)
### 类
```js
class Circle extends Shape {
```
#### 构造函数
```js {1}
constructor (radius) {
this.radius = radius
}
```
#### 方法
```js {1}
getArea () {
return Math.PI * 2 * this.radius
}
```
#### 调用超类方法
```js {2}
expand (n) {
return super.expand(n) * Math.PI
}
```
#### 静态方法
```js {1}
static createFromDiameter(diameter) {
return new Circle(diameter / 2)
}
}
```
原型的语法糖。
请参阅: [类](https://babeljs.io/learn-es2015/#classes)
Promises
--------
### 做出承诺
```js {1}
new Promise((resolve, reject) => {
if (ok) { resolve(result) }
else { reject(error) }
})
```
用于异步编程。
请参阅:[Promises](https://babeljs.io/learn-es2015/#promises)
### 使用 Promises
```js {2,3}
promise
.then((result) => { ··· })
.catch((error) => { ··· })
```
### 在 finally 中使用 Promise
```js {4}
promise
.then((result) => { ··· })
.catch((error) => { ··· })
.finally(() => {
/* 独立于成功/错误的逻辑 */
})
```
当承诺被履行或被拒绝时,处理程序被调用
### Promise 函数
```js
Promise.all(···)
Promise.race(···)
Promise.reject(···)
Promise.resolve(···)
```
### Async-await
```js {2,3}
async function run () {
const user = await getUser()
const tweets = await getTweets(user)
return [user, tweets]
}
```
`async` 函数是使用函数的另一种方式。
请参阅:[异步函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
解构 Destructuring
-------------
### 解构赋值
#### Arrays
```js {1}
const [first, last] = ['Nikola', 'Tesla']
```
#### Objects
```js {1}
let {title, author} = {
title: 'The Silkworm',
author: 'R. Galbraith'
}
```
支持匹配数组和对象。
请参阅:[解构](https://babeljs.io/learn-es2015/#destructuring)
### 默认值
```js
const scores = [22, 33]
const [math = 50, sci = 50, arts = 50] = scores
```
----
```js
// Result:
// math === 22, sci === 33, arts === 50
```
可以在解构数组或对象时分配默认值
### 函数参数
```js {1}
function greet({ name, greeting }) {
console.log(`${greeting}, ${name}!`)
}
```
----
```js
greet({ name: 'Larry', greeting: 'Ahoy' })
```
对象和数组的解构也可以在函数参数中完成
### 默认值
```js {1}
function greet({ name = 'Rauno' } = {}) {
console.log(`Hi ${name}!`);
}
```
----
```js
greet() // Hi Rauno!
greet({ name: 'Larry' }) // Hi Larry!
```
### 重新分配键
```js {1}
function printCoordinates({ left: x, top: y }) {
console.log(`x: ${x}, y: ${y}`)
}
```
----
```js
printCoordinates({ left: 25, top: 90 })
```
此示例将 `x` 分配给 `left` 键的值
### 循环
```js {1}
for (let {title, artist} of songs) {
···
}
```
赋值表达式也在循环中工作
### 对象解构
```js {1}
const { id, ...detail } = song;
```
使用 `rest(...)` 运算符单独提取一些键和对象中的剩余键
扩展运算符 Spread
------
### 对象扩展
#### 与对象扩展
```js {2}
const options = {
...defaults,
visible: true
}
```
#### 没有对象扩展
```js
const options = Object.assign(
{}, defaults,
{ visible: true })
```
对象扩展运算符允许您从其他对象构建新对象。
请参阅:[对象传播](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)
### 数组扩展
#### 具有数组扩展
```js {2,3}
const users = [
...admins,
...editors,
'rstacruz'
]
```
#### 没有数组扩展
```js
const users = admins
.concat(editors)
.concat([ 'rstacruz' ])
```
扩展运算符允许您以相同的方式构建新数组。
请参阅:[扩展运算符](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)
函数 Functions
---------
### 函数参数
<!--rehype:wrap-class=row-span-3-->
#### 默认参数
```js {1}
function greet (name = 'Jerry') {
return `Hello ${name}`
}
```
#### Rest 参数
```js {1}
function fn(x, ...y) {
// y 是一个数组
return x * y.length
}
```
#### 扩展
```js {1}
fn(...[1, 2, 3])
// 与 fn(1, 2, 3) 相同
```
Default(默认), rest, spread(扩展)。
请参阅:[函数参数](https://babeljs.io/learn-es2015/#default--rest--spread)
### 箭头函数
<!--rehype:wrap-class=row-span-3-->
#### 箭头函数
```js {1}
setTimeout(() => {
···
})
```
#### 带参数
```js {1}
readFile('text.txt', (err, data) => {
...
})
```
#### 隐式返回
```js {1,4,5,6}
arr.map(n => n*2)
// 没有花括号 = 隐式返回
// 同: arr.map(function (n) { return n*2 })
arr.map(n => ({
result: n*2
}))
// 隐式返回对象需要在对象周围加上括号
```
类似函数,但保留了 `this`。
请参阅:[箭头函数](https://babeljs.io/learn-es2015/#arrows-and-lexical-this)
### 参数设置默认值
```js
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
```
### 与解构赋值默认值结合使用
```js
function foo({x, y = 5} = {}) {
console.log(x, y);
}
foo() // undefined 5
```
### name 属性
```js
function foo() {}
foo.name // "foo"
```
Objects
-------
### 速记语法
```js
module.exports = { hello, bye }
```
同下:
```js
module.exports = {
hello: hello, bye: bye
}
```
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
### 方法
```js {2}
const App = {
start () {
console.log('running')
}
}
// 同: App = { start: function () {···} }
```
请参阅:[对象文字增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
### Getters and setters
```js {2,5}
const App = {
get closed () {
return this.status === 'closed'
},
set closed (value) {
this.status = value ? 'closed' : 'open'
}
}
```
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
### 计算属性名称
```js {3}
let event = 'click'
let handlers = {
[`on${event}`]: true
}
// 同: handlers = { 'onclick': true }
```
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
### 提取值
```js {3,5}
const fatherJS = { age: 57, name: "张三" }
Object.values(fatherJS)
// [57, "张三"]
Object.entries(fatherJS)
// [["age", 57], ["name", "张三"]]
```
Modules 模块
-------
### Imports 导入
```js
import 'helpers'
// 又名: require('···')
```
----
```js
import Express from 'express'
// 又名: const Express = require('···').default || require('···')
```
----
```js
import { indent } from 'helpers'
// 又名: const indent = require('···').indent
```
----
```js
import * as Helpers from 'helpers'
// 又名: const Helpers = require('···')
```
----
```js
import { indentSpaces as indent } from 'helpers'
// 又名: const indent = require('···').indentSpaces
```
`import` 是新的 `require()`。
请参阅:[Module imports](https://babeljs.io/learn-es2015/#modules)
### Exports 导出
```js
export default function () { ··· }
// 又名: module.exports.default = ···
```
----
```js
export function mymethod () { ··· }
// 又名: module.exports.mymethod = ···
```
----
```js
export const pi = 3.14159
// 又名: module.exports.pi = ···
```
----
```js
const firstName = 'Michael';
const lastName = 'Jackson';
const year = 1958;
export { firstName, lastName, year };
```
----
```js
export * from "lib/math";
```
`export` 是新的`module.exports`。
请参阅:[Module exports](https://babeljs.io/learn-es2015/#modules)
### `as` 关键字重命名
```js {2,8,12-14}
import {
lastName as surname // 导入重命名
} from './profile.js';
function v1() { ... }
function v2() { ... }
export { v1 as default };
// 等同于 export default v1;
export {
v1 as streamV1, // 导出重命名
v2 as streamV2, // 导出重命名
v2 as streamLatestVersion // 导出重命名
};
```
### 动态加载模块
```js
button.addEventListener('click', event => {
import('./dialogBox.js')
.then(dialogBox => {
dialogBox.open();
})
.catch(error => {
/* Error handling */
})
});
```
[ES2020提案](https://github.com/tc39/proposal-dynamic-import) 引入 `import()` 函数
### import() 允许模块路径动态生成
```js
const main = document.querySelector('main')
import(`./modules/${someVariable}.js`)
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
```
### import.meta
[ES2020](https://github.com/tc39/proposal-import-meta) 为 `import` 命令添加了一个元属性 `import.meta`,返回当前模块的元信息
```js
new URL('data.txt', import.meta.url)
```
Node.js 环境中,`import.meta.url`返回的总是本地路径,即 `file:URL` 协议的字符串,比如 `file:///home/user/foo.js`
Generators
----------
### Generator 函数
```js
function* idMaker () {
let id = 0
while (true) { yield id++ }
}
```
----
```js
let gen = idMaker()
gen.next().value // → 0
gen.next().value // → 1
gen.next().value // → 2
```
情况很复杂。
请参阅:[Generators](https://babeljs.io/learn-es2015/#generators)
### For..of + 迭代器(iterator)
<!--rehype:wrap-class=row-span-2-->
```js
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur }
}
}
}
}
for (var n of fibonacci) {
// 在 1000 处截断序列
if (n > 1000) break;
console.log(n);
}
```
用于迭代生成器和数组。
请参阅:[For..of iteration](https://babeljs.io/learn-es2015/#iterators--forof)
### 与 Iterator 接口的关系
```js
var gen = {};
gen[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...gen] // => [1, 2, 3]
```
`Generator` 函数赋值给 `Symbol.iterator` 属性,从而使得 `gen` 对象具有了 `Iterator` 接口,可以被 `...` 运算符遍历了
### Symbol.iterator 属性
```js
function* gen() { /* some code */ }
var g = gen();
g[Symbol.iterator]() === g // true
```
`gen` 是一个 `Generator` 函数,调用它会生成一个遍历器对象`g`。它的 `Symbol.iterator` 属性,也是一个遍历器对象生成函数,执行后返回它自己
另见
---
- [Learn ES2015](https://babeljs.io/docs/en/learn/) _(babeljs.io)_
- [ECMAScript 6 功能概述](https://github.com/lukehoban/es6features#readme) _(github.com)_
- [ECMAScript 6 入门教程 (阮一峰)](https://es6.ruanyifeng.com/) _(ruanyifeng.com)_

414
docs/expressjs.md Normal file
View File

@ -0,0 +1,414 @@
Express 备忘清单
===
这是用于 Node.js 的快速、不拘一格、极简主义的 Web 框架,包含 [Express.js](http://expressjs.com/) 的 API 参考列表和一些示例。
入门
---
### Hello World
<!--rehype:wrap-class=row-span-2-->
- 创建项目,添加 `package.json` 配置
```bash
$ mkdir myapp # 创建目录
$ cd myapp # 进入目录
$ npm init -y # 初始化一个配置
```
- 安装依赖
```bash
$ npm install express # 安装依赖
```
- 入口文件 `index.js` 添加代码:
```js
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`监听端口${port}示例应用`)
})
```
- 使用以下命令运行应用程序
```bash
$ node index.js
```
<!--rehype:className=style-timeline-->
### express -h
<!--rehype:wrap-class=row-span-2-->
```bash
Usage: express [options] [dir]
Options:
-h, --help 输出使用信息
--version 输出版本号
-e, --ejs 添加 ejs 引擎支持
--hbs 添加 hbs 引擎支持
--pug 添加 pug 引擎支持
-H, --hogan 添加 hogan.js 引擎支持
--no-view 无视图引擎生成
-v, --view <engine> 添加视图 <engine> 支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认jade)
-c, --css <engine> 添加样式表 <engine> 支持 (less|stylus|compass|sass) (默认css)
--git 添加 .gitignore
-f, --force 强制非空目录
```
<!--rehype:className=wrap-text -->
创建一个 `myapp` 的项目
```bash
$ express --view=pug myapp
# 运行应用程序
$ DEBUG=myapp:* npm start
```
### express()
:- | :-
:- | :-
`express.json()` | [#](http://expressjs.com/en/4x/api.html#express.json)
`express.raw()` | [#](http://expressjs.com/en/4x/api.html#express.raw)
`express.Router()` | [#](http://expressjs.com/en/4x/api.html#express.router)
`express.static()` | [#](http://expressjs.com/en/4x/api.html#express.static)
`express.text()` | [#](http://expressjs.com/en/4x/api.html#express.text)
`express.urlencoded()` | [#](http://expressjs.com/en/4x/api.html#express.urlencoded)
### Router
:- | :-
:- | :-
`router.all()` | [#](http://expressjs.com/en/4x/api.html#router.all)
`router.METHOD()` | [#](http://expressjs.com/en/4x/api.html#router.METHOD)
`router.param()` | [#](http://expressjs.com/en/4x/api.html#router.param)
`router.route()` | [#](http://expressjs.com/en/4x/api.html#router.route)
`router.use()` | [#](http://expressjs.com/en/4x/api.html#router.use)
### Application
```js
var express = require('express')
var app = express()
console.dir(app.locals.title)
// => 'My App'
console.dir(app.locals.email)
// => 'me@myapp.com'
```
#### **属性**
:- | :-
:- | :-
`app.locals` | 应用程序中的局部变量 [#](http://expressjs.com/en/4x/api.html#app.locals)
`app.mountpath` | 安装子应用程序的路径模式 [#](http://expressjs.com/en/4x/api.html#app.mountpath)
#### **Events**
:- | :-
:- | :-
`mount` | 子应用挂载到父应用上,子应用上触发事件 [#](http://expressjs.com/en/4x/api.html#app.onmount)
#### **方法**
:- | :-
:- | :-
`app.all()` | [#](http://expressjs.com/en/4x/api.html#app.all)
`app.delete()` | [#](http://expressjs.com/en/4x/api.html#app.delete.method)
`app.disable()` | [#](http://expressjs.com/en/4x/api.html#app.disable)
`app.disabled()` | [#](http://expressjs.com/en/4x/api.html#app.disabled)
`app.enable()` | [#](http://expressjs.com/en/4x/api.html#app.enable)
`app.enabled()` | [#](http://expressjs.com/en/4x/api.html#app.enabled)
`app.engine()` | [#](http://expressjs.com/en/4x/api.html#app.engine)
`app.get(name)` | [#](http://expressjs.com/en/4x/api.html#app.get)
`app.get(path, callback)` | [#](http://expressjs.com/en/4x/api.html#app.get.method)
`app.listen()` | [#](http://expressjs.com/en/4x/api.html#app.listen)
`app.METHOD()` | [#](http://expressjs.com/en/4x/api.html#app.METHOD)
`app.param()` | [#](http://expressjs.com/en/4x/api.html#app.param)
`app.path()` | [#](http://expressjs.com/en/4x/api.html#app.path)
`app.post()` | [#](http://expressjs.com/en/4x/api.html#app.post.method)
`app.put()` | [#](http://expressjs.com/en/4x/api.html#app.put.method)
`app.render()` | [#](http://expressjs.com/en/4x/api.html#app.render)
`app.route()` | [#](http://expressjs.com/en/4x/api.html#app.route)
`app.set()` | [#](http://expressjs.com/en/4x/api.html#app.set)
`app.use()` | [#](http://expressjs.com/en/4x/api.html#app.use)
### Request
#### 属性
:- | :-
:- | :-
`req.app` | [#](http://expressjs.com/en/4x/api.html#req.app)
`req.baseUrl` | [#](http://expressjs.com/en/4x/api.html#req.baseUrl)
`req.body` | [#](http://expressjs.com/en/4x/api.html#req.body)
`req.cookies` | [#](http://expressjs.com/en/4x/api.html#req.cookies)
`req.fresh` | [#](http://expressjs.com/en/4x/api.html#req.fresh)
`req.hostname` | [#](http://expressjs.com/en/4x/api.html#req.hostname)
`req.ip` | [#](http://expressjs.com/en/4x/api.html#req.ip)
`req.ips` | [#](http://expressjs.com/en/4x/api.html#req.ips)
`req.method` | [#](http://expressjs.com/en/4x/api.html#req.method)
`req.originalUrl` | [#](http://expressjs.com/en/4x/api.html#req.originalUrl)
`req.params` | [#](http://expressjs.com/en/4x/api.html#req.params)
`req.path` | [#](http://expressjs.com/en/4x/api.html#req.path)
`req.protocol` | [#](http://expressjs.com/en/4x/api.html#req.protocol)
`req.query` | [#](http://expressjs.com/en/4x/api.html#req.query)
`req.route` | [#](http://expressjs.com/en/4x/api.html#req.route)
`req.secure` | [#](http://expressjs.com/en/4x/api.html#req.secure)
`req.signedCookies` | [#](http://expressjs.com/en/4x/api.html#req.signedCookies)
`req.stale` | [#](http://expressjs.com/en/4x/api.html#req.stale)
`req.subdomains` | [#](http://expressjs.com/en/4x/api.html#req.subdomains)
`req.xhr` | [#](http://expressjs.com/en/4x/api.html#req.xhr)
#### 方法
:- | :-
:- | :-
`req.accepts()` | [#](http://expressjs.com/en/4x/api.html#req.accepts)
`req.acceptsCharsets()` | [#](http://expressjs.com/en/4x/api.html#req.acceptsCharsets)
`req.acceptsEncodings()` | [#](http://expressjs.com/en/4x/api.html#req.acceptsEncodings)
`req.acceptsLanguages()` | [#](http://expressjs.com/en/4x/api.html#req.acceptsLanguages)
`req.get()` | 获取HTTP 请求头字段 [#](http://expressjs.com/en/4x/api.html#req.get)
`req.is()` | [#](http://expressjs.com/en/4x/api.html#req.is)
`req.param()` | [#](http://expressjs.com/en/4x/api.html#req.param)
`req.range()` | [#](http://expressjs.com/en/4x/api.html#req.range)
### Response
```js
app.get('/', function (req, res) {
console.dir(res.headersSent) // false
res.send('OK')
console.dir(res.headersSent) // true
})
```
#### 属性
:- | :-
:- | :-
`res.app` | [#](http://expressjs.com/en/4x/api.html#res.app)
`res.headersSent` | [#](http://expressjs.com/en/4x/api.html#res.headersSent)
`res.locals` | [#](http://expressjs.com/en/4x/api.html#res.locals)
#### 方法
:- | :-
:- | :-
`res.append()` | [#](http://expressjs.com/en/4x/api.html#res.append)
`res.attachment()` | [#](http://expressjs.com/en/4x/api.html#res.attachment)
`res.cookie()` | [#](http://expressjs.com/en/4x/api.html#res.cookie)
`res.clearCookie()` | [#](http://expressjs.com/en/4x/api.html#res.clearCookie)
`res.download()` | 提示要下载的文件 [#](http://expressjs.com/en/4x/api.html#res.download)
`res.end()` | 结束响应过程 [#](http://expressjs.com/en/4x/api.html#res.end)
`res.format()` | [#](http://expressjs.com/en/4x/api.html#res.format)
`res.get()` | [#](http://expressjs.com/en/4x/api.html#res.get)
`res.json()` | 发送 JSON 响应 [#](http://expressjs.com/en/4x/api.html#res.json)
`res.jsonp()` | 发送带有 JSONP 支持的响应 [#](http://expressjs.com/en/4x/api.html#res.jsonp)
`res.links()` | [#](http://expressjs.com/en/4x/api.html#res.links)
`res.location()` | [#](http://expressjs.com/en/4x/api.html#res.location)
`res.redirect()` | 重定向请求 [#](http://expressjs.com/en/4x/api.html#res.redirect)
`res.render()` | 渲染视图模板 [#](http://expressjs.com/en/4x/api.html#res.render)
`res.send()` | 发送各种类型的响应 [#](http://expressjs.com/en/4x/api.html#res.send)
`res.sendFile()` | 将文件作为八位字节流发送 [#](http://expressjs.com/en/4x/api.html#res.sendFile)
`res.sendStatus()` | [#](http://expressjs.com/en/4x/api.html#res.sendStatus)
`res.set()` | [#](http://expressjs.com/en/4x/api.html#res.set)
`res.status()` | [#](http://expressjs.com/en/4x/api.html#res.status)
`res.type()` | [#](http://expressjs.com/en/4x/api.html#res.type)
`res.vary()` | [#](http://expressjs.com/en/4x/api.html#res.vary)
示例
----
### Router
<!--rehype:wrap-class=row-span-2-->
为传递给此路由器的任何请求调用
```js
router.use(function (req, res, next) {
// .. 这里有一些逻辑 .. 像任何其他中间件一样
next()
})
```
将处理任何以 `/events` 结尾的请求
```js
// 取决于路由器在哪里 "use()"
router.get('/events', (req, res, next) => {
// ..
})
```
### Response
`res` 对象表示 `Express` 应用程序在收到 HTTP 请求时发送的 HTTP 响应
```js
app.get('/user/:id', (req, res) => {
res.send('user ' + req.params.id)
})
```
### Request
`req` 对象表示 `HTTP` 请求并具有请求查询字符串、参数、正文、HTTP 标头等的属性
```js
app.get('/user/:id', (req, res) => {
res.send('user ' + req.params.id)
})
```
### res.end()
```js
res.end()
res.status(404).end()
```
结束响应过程。这个方法其实来自 Node 核心,具体是 `http.ServerResponse` 的 `response.end()` 方法
### res.json([body])
```js
res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })
```
### app.all
```js
app.all('/secret', function (req, res, next) {
console.log('访问秘密部分...')
next() // 将控制权传递给下一个处理程序
})
```
### app.delete
```js
app.delete('/', function (req, res) {
res.send('DELETE request to homepage')
})
```
### app.disable(name)
```js
app.disable('trust proxy')
app.get('trust proxy')
// => false
```
### app.disabled(name)
```js
app.disabled('trust proxy')
// => true
app.enable('trust proxy')
app.disabled('trust proxy')
// => false
```
### app.engine(ext, callback)
```js
var engines = require('consolidate')
app.engine('haml', engines.haml)
app.engine('html', engines.hogan)
```
### app.listen([port[, host[, backlog]]][, callback])
```js
var express = require('express')
var app = express()
app.listen(3000)
```
### 路由
```js
const express = require('express')
const app = express()
// 向主页发出 GET 请求时响应“hello world”
app.get('/', (req, res) => {
res.send('hello world')
})
```
```js
// GET 方法路由
app.get('/', (req, res) => {
res.send('GET request to the homepage')
})
// POST 方法路由
app.post('/', (req, res) => {
res.send('POST request to the homepage')
})
```
### 中间件
```js
function logOriginalUrl (req, res, next) {
console.log('ReqURL:', req.originalUrl)
next()
}
function logMethod (req, res, next) {
console.log('Request Type:', req.method)
next()
}
const log = [logOriginalUrl, logMethod]
app.get('/user/:id', log,
(req, res, next)=>{
res.send('User Info')
}
)
```
### 使用模版
```js
app.set('view engine', 'pug')
```
在 `views` 目录下创建一个名为 `index.pug` 的 `Pug` 模板文件,内容如下
```pug
html
head
title= title
body
h1= message
```
创建一个路由来渲染 `index.pug` 文件。如果未设置视图引擎属性,则必须指定视图文件的扩展名
```js
app.get('/', (req, res) => {
res.render('index', {
title: 'Hey', message: 'Hello there!'
})
})
```

728
docs/ffmpeg.md Normal file
View File

@ -0,0 +1,728 @@
FFmpeg 备忘清单
===
本备忘清单是 [FFmpeg](https://ffmpeg.org/) 中常见视频处理操作的备忘清单
FFmpeg 参考
---
### 安装
<!--rehype:wrap-class=row-span-2-->
Linux
```
$ apt-get install ffmpeg
$ yum install ffmpeg
```
MacOS
```bash
$ brew install ffmpeg
```
### 示例
<!--rehype:wrap-class=row-span-2-->
mp4 转 avi:
```bash
$ ffmpeg -i input.mp4 output.avi
```
webm 转 mp4:
```bash
$ ffmpeg -i movie.webm movie.mp4
```
### 全局选项
:- | -
:- | -
`-y` | 覆盖输出文件
`-n` | 不要覆盖输出文件
### 主要选项
:- | -
:- | -
`-f fmt` | 强制输入或输出文件格式
`-i fName` | 输入文件名,未指定显示内容流的摘要
`-c codecName` | 指定编解码器 [输入或输出]
`-fs Nbytes` | 以 Nbytes 指定最大输出文件大小
### 基础参数
:- | -
:- | -
`-codecs` | 列出可用编码
`-formats` | 列出支持的格式
`-protocols` | 列出支持的协议
`-i input.mp4` | 指定输入文件
`-c:v libx264` | 指定视频编码
`-c:a aac` | 指定音频编码
`-vcodec libx264` | 旧写法
`-acodec aac` | 旧写法
`-fs SIZE` | 指定文件大小
### 视频参数
<!--rehype:wrap-class=col-span-2 row-span-2-->
:- | -
:- | -
`-b bRate` | 设置视频比特率(单位 kbit/s)
`-fixaspect` | 固定纵横比
`-bt tolerance` | 设置视频比特率容差(单位 kbit/s)
`-maxrate bRate` | 设置最大视频比特率容差(单位 kbit/s)
`-minrate bRate` | 设置最小视频比特率容差(单位 kbit/s)
`-bufsize size` | 设置速率控制缓冲区大小(以 kByte 为单位)
`-sameq` | 使用与源相同的视频质量(意味着 VBR)
`-newvideo` | 将新的视频流添加到当前输出流
`-aspect RATIO` | 纵横比(4:3、16:9 或 1.25)
`-r RATE` | 每秒帧率
`-s WIDTHxHEIGHT` | 帧大小
`-vn` | 没有视频
### 码率设置
```bash
-b:v 1M # 视频比特率(1M = 1Mbit/s)
-b:a 1M # 音频比特率(1M = 1Mbit/s)
```
### 尺寸规格
:- | - | - | -
:- | - | - | -
`K``k` | 103 | 1000 字节 | 千字节 Kilobytes
`M` | 106 | 1000000 字节 | 兆字节 Megabytes
`G` | 109 | 1000000000 | 千兆字节 Gigabytes
`Ki` | 210 | 1024 | 千字节 Kibibyte
`Mi` | 220 | 1048576 | 兆字节 Mebibyte
`Gi` | 230 | 1073741824 | Gibibyte
### 音频参数
<!--rehype:wrap-class=col-span-2-->
:- | -
:- | -
`-ab bRate` | 设置音频比特率(单位 kbit/s)
`-aframes N` | 设置要录制的音频帧数 [-frames:a 的别名]
`-aq q` | 设置音频质量(特定于编解码器VBR) [-q:a 的别名]
`-an` | 禁用录音
`-acodec codec` | 设置音频编解码器。[-codec:a 的别名] 使用 'copy' 复制流。
`-vol` | 以 256 的倍数更改音频音量,其中 256 = 100%(正常)音量。例如 512 = 200%
`-newaudio` | 将新的音频流添加到当前输出流
`-alang code` | 设置当前音频流的 ISO 639 语言代码(3 个字母)
视频编辑
---
<!--rehype:body-class=cols-2-->
### 剪切视频部分
<!--rehype:wrap-class=col-span-2-->
```bash
# 从1分45秒开始剪切2分35秒
$ ffmpeg -i <input> -ss 00:01:45 -t 00:02:35 -vcodec copy -acodec copy <output>
# 从1分45秒开始剪切到第4分20秒与上一行等效
$ ffmpeg -i <input> -ss 00:01:45 -to 00:04:20 -codec copy <output>
$ ffmpeg -ss 00:00:30 -i orginalfile.mpg -t 00:00:05 -vcodec copy -acodec copy newfile.mpg
# 从 4.5 秒开始的 5 秒长的视频
$ ffmpeg -i in.mp4 -ss 4.5 -t 5 out.mp4
```
<!--rehype:className=wrap-text -->
### 视频帧速率
```bash
$ ffmpeg -i input.avi -r 24 output.avi
```
将输出文件的帧速率强制为 24 fps
```bash
$ ffmpeg -r 1 -i input.m2v -r 24 output.avi
```
将输入文件的帧速率(仅对原始格式有效)强制为 1 fps将输出文件的帧速率强制为 24 fps
### H265 2-pass 编码
<!--rehype:wrap-class=row-span-2-->
```bash
$ ffmpeg -y -i <input> -c:v libx265 -b:v 2600k \
-x265-params pass=1 \
-an -f mp4 /dev/null && \
ffmpeg -i <input> \
-c:v libx265 -b:v 2600k \
-x265-params pass=2 \
-c:a aac -b:a 128k output.mp4
```
<!--rehype:className=wrap-text -->
对于 `H265 2-pass` 编码,您需要组合 `2``ffmpeg` 调用
### 视频比特率设置
```bash
$ ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
```
将输出文件的视频比特率设置为 64 kbit/s
### 固定旋转
```bash
$ ffmpeg -i <input> -c copy -metadata:s:v:0 rotate=90 <output>
```
<!--rehype:className=wrap-text -->
不要为旋转重新编码,而是简单地为旋转角度添加一个视频元数据字段
### 缩放到特定宽度
```bash
$ ffmpeg -i in.mp4 -filter:v scale="538:trunc(ow/a/2)*2" -c:a copy out.mp4
```
给定所需的视频宽度,例如 538 像素,您可以使用以下方法将视频调整为该宽度,同时保持宽高比
重新包装
---
### 提取音频流
```bash
$ ffmpeg -i file.mp4 -vn -c copy output.aac
```
<!--rehype:className=wrap-text -->
`-vn` (过滤视频),使用 `-c copy`,不会重新解码和编码,加快速度。
### 提取视频流
```bash
$ ffmpeg -i file.mp4 -an -c copy output.mp4
```
### 处理 id3 标签
<!--rehype:wrap-class=row-span-2-->
提取
```bash
$ ffmpeg -i file.mp3 -f ffmetadata metadata.txt
```
<!--rehype:className=wrap-text -->
设置
```bash
$ ffmpeg -i file.mp3 -acodec copy -metadata title="<title>" -metadata artist="<artist>" -metadata album="<album>" out.mp3
```
<!--rehype:className=wrap-text -->
更多[请查看](https://gist.github.com/eyecatchup/0757b3d8b989fe433979db2ea7d95a01)
### 重新采样/转换音频
```bash
$ ffmpeg -i file.aac -acodec mp3 -ar 44100 -ab 128000 output.mp3
```
<!--rehype:className=wrap-text -->
### 将输入文件转码为 DVD PAL 格式
```bash
$ ffmpeg -y -threads 8 -i inFile -target pal-dvd -ac 2 -aspect 16:9 -acodec mp2 -ab 224000 -vf pad=0:­0:0:0 outFile
```
<!--rehype:className=wrap-text -->
### -map 命令
<!--rehype:wrap-class=col-span-2 row-span-2-->
`-map` 命令用于指定索引文件,以及索引文件中流类型和它的索引
----
```bash
-map index:stram_type:stream_index
```
----
:- | -
:- | -
`input_file_index` | 输入的文件索引(从 0 开始)
`stream_type` | 指定文件流的类型(a -> 音频v -> 视频s -> 字幕)
`stream_index` | 指定流类型的索引(从 0 开始)
将第一个输入文件的第二个音频拷贝到 out.mp3
```bash
$ ffmpeg -i input.mp4 -map 0:a:1 -c copy out.mp3
```
将第一个输入文件的视频流和第二个输入文件的音频流拷贝到 out.mp4
```bash
$ ffmpeg -i i1.mp4 -i i2.mp4 -map 0:v -map 0:a -c copy out.mp4
```
#### 反向 -map 命令
<!--rehype:wrap-class=col-span-2-->
反向的 map 命令(在 map 命令的参数前加负号)。例如,`-map -0:a:0`,忽略第一个文件中的第一个音频流。
<!--rehype:className=wrap-text -->
### 切换容器(转换类型)
将容器从 `MKV` 更改为 `MP4`
```bash
$ ffmpeg -i file.mkv -acodec copy -vcodec copy file.mp4
```
<!--rehype:className=wrap-text -->
要将视频从 `.mov` 更改为 `.mp4`
```bash
$ ffmpeg -i in.mov out.mp4
```
### 音视频同步
<!--rehype:wrap-class=row-span-2-->
将音频延迟 3 秒
```bash
$ ffmpeg -i input.mov -itsoffset 3 -i input.mov -map 0:v -map 1:a -codec:a copy -codec:v copy output.mov
```
<!--rehype:className=wrap-text -->
将视频延迟 3 秒(即将音频提前 3 秒)
```bash
$ ffmpeg -i input.mov -itsoffset 3 -i input.mov -map 1:v -map 0:a -codec:a copy -codec:v copy output.mov
```
<!--rehype:className=wrap-text -->
### 图片中的视频
```bash
$ ffmpeg -f image2 -i image%d.jpg video.mp4
```
<!--rehype:className=wrap-text -->
多个编号的图像 image1.jpg、image2.jpg... 像这样从它们创建一个视频
### 将视频拆分为图像
```bash
$ ffmpeg -i video.mp4 image%d.jpg
```
### 录屏
<!--rehype:wrap-class=col-span-2 row-span-2-->
#### 查找所有可用设备
```bash
$ ffmpeg -f avfoundation -list_devices true -i ""
```
<!--rehype:className=wrap-text -->
<span style="color:red">一定要选择好设备,根据设备进行配置。</sapn>
#### windows 下录屏
```bash
$ ffmpeg -hide_banner -loglevel error -stats -f gdigrab -framerate 60 \
-offset_x 0 -offset_y 0 -video_size 1920x1080 -draw_mouse 1 -i deskop \
-c:v libx264 -r 60 -preset ultrafast -pix_fmt yuv420p -y screen_record.mp4
```
#### mac 下录屏
```bash
$ ffmpeg -f avfoundation -i 1:0 -preset ultrafast out.mkv
```
### 合并音频与图片
合并多个音频,自定义背景图片,生成视频音乐
```bash
# mylist.txt >>>
file '1.mp3'
file '2.mp3'
file '3.mp3'
# OBS: 46500 = 25:50 minutes * 60 * 30fps
# echo "00:25:50" | awk -F: '{ print (($1 * 3600) + ($2 * 60) + $3) * 30 }'
$ ffmpeg -y -loop 1 -i cover.jpg -f concat -i mylist.txt -c:v libx264 -r 30 -pix_fmt yuv420p -vframes 46500 -c:a aac -b:a 192k -strict experimental -shortest output.mp4
```
<!--rehype:className=wrap-text -->
### 转换为 Gif
<!--rehype:wrap-class=col-span-2 row-span-3-->
```bash
$ ffmpeg -ss 2 -t 28 -i input.mp4 -vf "fps=10,scale=1080:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif
```
<!--rehype:className=wrap-text -->
上面有关更多信息,请参阅 [StackOverflow 问题](https://superuser.com/a/556031)
```bash
# 转换为 GIF
$ ffmpeg -i input.mov output.gif
# 从 GIF 转换
$ ffmpeg -i input.gif output.mov
# 在非 GIF 格式之间转换
$ ffmpeg -i input.mov -codec:v copy -codec:a copy output.mp4
```
### 转换为灰度
```bash
$ ffmpeg -y -i inFile -flags gray outFile
```
### 字幕格式转换
```bash
# srt -> ass
$ ffmpeg -i subtitle.srt subtitle.ass
# ass -> vtt
$ ffmpeg -i subtitle.ass subtitle.vtt
```
srt、ass、vtt 等格式之间可以相互转换
<!--rehype:className=wrap-text -->
### 字幕
<!--rehype:wrap-class=col-span-2 row-span-2-->
将字幕写入视频
```bash
$ ffmpeg -i input.mov -filter:v 'subtitles=subtitles.srt' -codec:a copy output.mov
```
将字幕写入视频,具有自定义字幕样式
```bash
$ ffmpeg -i input.mov -filter:v "subtitles=subtitles.srt:force_style='FontName=Menlo Bold,Fontsize=18'" -codec:a copy output.mov
```
<!--rehype:className=wrap-text -->
### 制造 1 分钟的音频噪音
```bash
$ ffmpeg -ar 48000 -t 60 -f s16le -acodec pcm_s16le -i /dev/u­random -ab 64K -f mp2 -acodec mp2 -y noise.mp2
```
<!--rehype:className=wrap-text -->
### 从视频中提取图像
```bash
$ ffmpeg -i foo.avi -r 1 -s WxH -f image2 outFil­e%0­3d.png
```
<!--rehype:className=wrap-text -->
### 音量
<!--rehype:wrap-class=col-span-2 row-span-2-->
将音量减半
```bash
$ ffmpeg -i input.mov -codec:v copy -filter:a 'volume=0.5' output.mov
```
音量加倍
```bash
$ ffmpeg -i input.mov -codec:v copy -filter:a 'volume=2' output.mov
```
### 将图像文件转换为其他格式
```bash
$ ffmpeg -i foo012­2.png foo.tiff
```
pgm, ppm, pam, pgmyuv, jpeg, gif, png, tiff, sgi
### 将图像转换为 AVI 文件
```bash
$ ffmpeg -f image2 -i foo-%0­3d.jpeg -r 12 -s WxH foo.avi
```
<!--rehype:className=wrap-text -->
### 将 WAV 文件转换为 MP3
```bash
$ ffmpeg -i source­_so­ng.wav -vn -ar 44100 -ac 2 -ab 192 -f mp3 final_­son­g.mp3
```
<!--rehype:className=wrap-text -->
### 从视频中提取音频,将其转码为 MP3
```bash
$ ffmpeg -i source.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 sound.mp3
```
<!--rehype:className=wrap-text -->
### 将 .avi 转换为 .flv
```bash
$ ffmpeg -i source.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv
```
<!--rehype:className=wrap-text -->
### 将图片附加到 mp3
```bash
$ ffmpeg -i input.mp3 -i cover.png -c copy -metad­ata:s:v title=­"­Album cover" -metad­ata:s:v commen­t="Cover (Front­)" out.mp3
```
<!--rehype:className=wrap-text -->
### 将视频与声音文件混合
```bash
$ ffmpeg -i song.wav -i source­_vi­deo.avi outvid­eo.mpg
```
<!--rehype:className=wrap-text -->
### 编写带有 ID3v2.3 页眉和 ID3v1 页脚的 mp3
```bash
$ ffmpeg -i inFile -id3v2­_ve­rsion 3 -write­_id3v1 1 outFil­e.mp3
```
<!--rehype:className=wrap-text -->
### 连接输入文件
```bash
$ cat inFile1 inFile2 | ffmpeg -f mpeg -i - -vcodec copy -acodec copy outFil­e.mpg
```
<!--rehype:className=wrap-text -->
### 使用比特率和 mp3 音频的编解码器对剪辑进行编码
```bash
$ ffmpeg -i clip.avi -vcodec libxvid -b 800000 -acodec libmp3lame -ab 128 new-cl­ip.avi
```
<!--rehype:className=wrap-text -->
### 将音频流与来自不同文件的视频流合并
```bash
$ ffmpeg -i audioS.mp4 -i videoS.mp4 -c copy -map 0:a -map 1:v outFil­e.mp4
```
<!--rehype:className=wrap-text -->
### 合并视频
<!--rehype:wrap-class=col-span-3 row-span-3-->
合并相同规格(解码/分辨率/帧率)视频
```bash
# mylist.txt >>>
file '1.mp4'
file '2.mp4'
file '3.mp4'
# 这些文件是相对路径,如使用绝对路径需要添加 `-safe 0` 参数
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
```
<!--rehype:className=wrap-text -->
合并当前目录下所有视频
```bash
$ ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
```
<!--rehype:className=wrap-text -->
合并不同规格视频,保证视频不变形
```bash
$ ffmpeg -i 1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts tmp1.ts
$ ffmpeg -i 2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts tmp2.ts
$ ffmpeg -i 3.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts tmp3.ts
$ ffmpeg -threads 2 -i "concat:tmp1.ts|tmp2.ts|tmp3.ts" -vf "scale=720:1080:force_original_aspect_ratio=decrease,pad=720:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuvj420p -shortest -y output.mp4
```
<!--rehype:className=wrap-text -->
合并不同解码视频
```bash
$ ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mkv
```
<!--rehype:className=wrap-text -->
合并视频并重新编码音频
```bash
$ ffmpeg -f concat -i mylist.txt -c:v copy -c:a flac -strict -2 output.mp4
```
<!--rehype:className=wrap-text -->
视频过滤器
---
### 格式
如果一个 fliter 有多个参数,需要使用 `,` 分隔
```bash
$ ffmpeg -i test.avi -c:v libx264 -vf "scale=1024:-1,transpose=1,crop=iw/3:ih/3" output.mp4
```
### 缩放
<!--rehype:wrap-class=row-span-2-->
```bash
$ ffmpeg -i input.mp4 -vf "scale=640:480" out.mp4
# -1 → 指根据另一个参数帮我们推断
$ ffmpeg -i input.mp4 -vf "scale=720:-1" out.mp4
# 宽度和高度
ffmpeg -i input.mp4 -vf "scale=w=800:h=600" output.mp4
# in_w\in_h 输入尺寸
ffmpeg -i input.mkv -vf "scale=w=1/2*in_w:h=1/2*in_h" output.mkv
```
<!--rehype:className=wrap-text -->
### 裁剪
<!--rehype:wrap-class=row-span-2-->
从左上角开始,复制 `x=0px` `y=0px` 的相应窗口来创建 `1280x720` 大小的输出视频
```bash
ffmpeg -i input.mp4 -vf "crop=w=1280:h=720:x=0:y=0" output.mp4
```
裁剪到宽度 360高度 640从坐标 (10, 20) 开始
```bash
$ ffmpeg -i input.mov -vf 'crop=360:640:10:20' output.mov
```
<!--rehype:className=wrap-text -->
### 去除水印
设置一个矩形覆盖区域 x=10:y=10:w=120:h=45
```bash
# show=1 为可选参数,设置显示边框,方便调试用的
ffmpeg -i 1.mp4 -b:v 548k -vf delogo=x=10:y=10:w=120:h=45:show=1 output.mp4
```
<!--rehype:className=wrap-text -->
### 创建缩略图
<!--rehype:wrap-class=row-span-2-->
在 10 秒时创建一个缩略图
```bash
$ ffmpeg -ss 10 -i <input file> -vframes 1 -vcodec png -an thumb.png
```
<!--rehype:className=wrap-text -->
例如,要每 `n` 秒创建一次缩略图,请使用 `-vf fps=1/n`
```bash
$ ffmpeg -i <input file> -vf fps=1/60 thumbnails/thumb%03d.png
```
<!--rehype:className=wrap-text -->
### 添加水印
在视频左上方 20,20 的位置插入 logo.png 图片
```bash
# -b:v 548k 可选参数,设置视频比特率,默认 200k 最好设置与原视频一致
ffmpeg -i 1.mp4 -acodec copy -b:v 548k -vf "movie=logo.png[watermark];[in][watermark]overlay=20:20" output.mp4
```
<!--rehype:className=wrap-text -->
### 视频旋转
```bash
# 顺时针旋转 90
$ ffmpeg -i input.avi -vf "rotate=90*PI/180" out.mp4
# 顺时针旋转 180翻转 90
$ ffmpeg -i input.mp4 -vf "rotate=PI" out.mp4
```
### 更改视频播放速度
```bash
# 加速 2 倍
$ ffmpeg -i input.mkv -vf "setpts=0.5*PTS" output.mkv
# 减速 2 倍
$ ffmpeg -i input.mp4 -vf "setpts=2*PTS" output.mp4
```
### 添加背景音乐
```bash
# -t 10 文件时长,单位为秒,建议取值原始视频总时长
$ ffmpeg -i 1.mp4 -i test.mp3 \
-filter_complex "[1:a]aloop=loop=-1:size=2e+09[out];[out][0:a]amix" \
-t 10 out.mp4
```
音频过滤器
---
### 调节音量
```bash
# 增大音量
$ ffmpeg -i test.mp4 -af "volumn=1.5" out.mp4
```
### 更改音频速度
<!--rehype:wrap-class=row-span-2-->
```bash
$ ffmpeg -i input.wav -af "atempo=0.75" output.wav
# 加速 4 倍
$ ffmpeg -i input.mp3 -af "atempo=2.0,atempo=2.0" ouutput.mp3
```
`atempo` 它只接受 `0.5`(半速) 到 `2` (倍速)之间的值。为了越过这个限制,你可以链式使用这个过滤器
### 统一视频的音量
```bash
$ ffmpeg -i test.mp4 -af "loudnorm=I=-5:LRA=1" out.mp4
```
### 重新映射通道数
```bash
# 使左右耳的声音同时出现
$ ffmpeg -i input.mp3 -af "channelmap=1-0|1-1" output.mp3
```
另见
---
- [FFmpeg 官网地址](https://ffmpeg.org/) _(ffmpeg.org)_
- [FFmpeg Cheat Sheet](https://lzone.de/cheat-sheet/ffmpeg) _(lzone.de)_
- [FFmpeg Cheat Sheet](https://devhints.io/ffmpeg) _(devhints.io)_
- [FFmpeg Cheat Sheet](https://github.com/yuanqing/ffmpeg-cheatsheet) _(github.com)_
- [FFmpeg Cheat Sheet](https://cheatography.com/thetartankilt/cheat-sheets/ffmpeg/) _(cheatography.com)_

View File

@ -1,7 +1,7 @@
Find 备忘清单
===
这是 Linux find 命令备忘单的快速参考列表,包含常用选项和示例。
这是 Linux find 命令备忘单的快速参考列表,包含常用选项和示例。
入门
----
@ -39,7 +39,6 @@ $ find . -name "json_*"
| `-mindepth` | find / -mindepth 3 -maxdepth 5 -name pass | 在子目录级别 2 和 4 之间 |
<!--rehype:className=show-header-->
### 类型
| | |
@ -224,7 +223,6 @@ $ find . -type d -empty
$ find . -type f -empty -delete
```
查找日期和时间
-------------

View File

@ -1,7 +1,7 @@
Git 备忘清单
===
本备忘单总结了常用的 Git 命令行指令,以供快速参考。
本备忘单总结了常用的 [Git](https://git-scm.com/) 命令行指令,以供快速参考。
入门
----
@ -11,23 +11,29 @@ Git 备忘清单
创建一个新的本地存储库
```shell
$ git init [project name]
$ git init [项目名称]
```
克隆存储库
克隆存储库(代码仓库)
```shell
$ git clone git_url
$ git clone <git_url>
```
将存储库克隆到指定目录
```shell
$ git clone git_url 指定目录
$ git clone <git_url> 指定目录
```
将存储库克隆到指定目录,并指定分支
```shell
$ git clone <git_url> -b <分支名称> 指定目录
```
### 做出改变
<!--rehype:wrap-class=row-span-2-->
<!--rehype:wrap-class=row-span-3-->
在工作目录中**显示**修改后的文件,为您的下一次提交暂存
@ -89,8 +95,8 @@ $ git diff --staged
$ git rebase [branch]
```
### 配置
<!--rehype:wrap-class=row-span-2-->
设置将附加到您的提交和标签的名称
@ -116,7 +122,20 @@ $ git config --global color.ui auto
$ git config --global --edit
```
显示本地 `repo` 配置设置
```shell
$ git config --list
```
删除全局设置
```bash
$ git config --global --unset <entry-name>
```
### 使用分支
<!--rehype:wrap-class=row-span-3-->
列出所有本地分支
@ -130,25 +149,25 @@ $ git branch
$ git branch -av
```
切换到 my_branch并更新工作目录
切换到 `my_branch`,并更新工作目录
```shell
$ git checkout my_branch
```
创建一个名为 new_branch 的新分支
创建一个名为 `new_branch` 的新分支
```shell
$ git checkout -b new_branch
```
删除名为 my_branch 的分支
删除名为 `my_branch` 的分支
```shell
$ git branch -d my_branch
```
将分支 A 合并到分支 B
将分支 `A` 合并到分支 `B`
```shell
$ git checkout branchB
@ -161,7 +180,31 @@ $ git merge branchA
$ git tag my_tag
```
从远程分支中创建并切换到本地分支
```shell
$ git checkout -b <branch-name> origin/<branch-name>
```
### 临时提交
```shell
# 保存已修改和分阶段的更改
$ git stash
# 列出隐藏文件更改的堆栈顺序
$ git stash list
# 从存储堆栈顶部编写工作
$ git stash pop
# 丢弃存储堆栈顶部的更改
$ git stash drop
# 回到某个 stash 的状态
$ git stash apply <stash@{n}>
# 删除所有的 stash
$ git stash clear
```
### 观察你的存储库
<!--rehype:wrap-class=row-span-2-->
显示当前活动分支的提交历史
@ -193,7 +236,21 @@ $ git diff branchB...branchA
$ git show [SHA]
```
### 重构文件名
```bash
# 从工作目录中删除文件并暂存删除
git rm <filename>
# 从版本控制中删除文件但在本地保留文件
git rm --cached <filename>
# 更改文件名并准备提交
git mv <filename-orig> <filename-renamed>
```
### 同步
<!--rehype:wrap-class=row-span-2-->
从该 Git 远程获取所有分支
@ -230,6 +287,7 @@ $ git cherry-pick [commit_id]
```
### 远程
<!--rehype:wrap-class=row-span-2-->
添加一个 git URL 作为别名
@ -261,32 +319,6 @@ $ git remote rm [remote repo name]
$ git remote set-url origin [git_url]
```
### 临时提交
保存已修改和分阶段的更改
```shell
$ git stash
```
列出隐藏文件更改的堆栈顺序
```shell
$ git stash list
```
从存储堆栈顶部编写工作
```shell
$ git stash pop
```
丢弃存储堆栈顶部的更改
```shell
$ git stash drop
```
### 跟踪路径更改
从项目中删除文件并暂存删除以进行提交
@ -309,7 +341,7 @@ $ git log --stat -M
### 忽略文件
```gitignore
```gitignore showLineNumbers
/logs/*
# “!” 意思是不要忽视
!logs/.gitkeep
@ -323,30 +355,44 @@ node_modules
`.gitignore` 文件指定了 Git 应该忽略的未跟踪的文件
### git 配置 ssh 代理
```bash
$ cat ~/.ssh/config
Host gitlab.com
# 直接使用 shadowsocks 提供的 socks5 代理端口
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
Host github.com
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
```
<!--rehype:className=wrap-text-->
Git 技巧
------
### 重命名分支
#### **重命名**为`new`
- **重命名**为`new`
```shell
$ git branch -m <new>
$ git branch -m <old> <new> # 重命名分支
```
```shell
$ git branch -m <new>
$ git branch -m <old> <new> #重命名分支
```
#### **推送**并重置
- **推送**并重置
```shell
$ git push origin -u <new>
```
```shell
$ git push origin -u <new>
```
#### **删除**远程分支
- **删除**远程分支
```shell
$ git push origin --delete <old> # 方法1
$ git push origin :oldBranchName # 方法2
```
```shell
$ git push origin --delete <old> #方法1
$ git push origin :oldBranchName #方法2
```
<!--rehype:className=style-timeline-->
### Log
@ -384,7 +430,7 @@ $ git branch -vv
$ git checkout -
```
只获取远程分支
只获取所有远程分支
```shell
$ git branch -r
@ -427,7 +473,7 @@ $ git config --global alias.ci commit
$ git config --global alias.st status
```
也可以看看:[More Aliases](https://gist.github.com/johnpolacek/69604a1f6861129ef088)
也可以看看:[更多别名](https://gist.github.com/johnpolacek/69604a1f6861129ef088)
### 设置大小写敏感
@ -519,12 +565,6 @@ $ git branch --merged master | grep -v '^\*\| master' | xargs -n 1 git branch -
```
<!--rehype:className=wrap-text-->
### 中文乱码的解决方案
```shell
$ git config --global core.quotepath false
```
### 把 A 分支的某一个 commit放到 B 分支上
```shell
@ -532,4 +572,326 @@ $ git config --global core.quotepath false
$ git checkout <B>
# 将 A 分支 <hash-id> 的内容 pick 到 B 分支
$ git cherry-pick <hash-id>
```
```
### 回到远程仓库的状态
```bash
$ git fetch --all && git reset --hard origin/master
```
<!--rehype:className=wrap-text-->
抛弃本地所有的修改,回到远程仓库的状态
### 重设第一个 commit
```bash
$ git update-ref -d HEAD
```
把所有的改动都重新放回工作区,并**清空所有的 commit**,这样就可以重新提交第一个 `commit` 了
### 查看冲突文件列表
```bash
$ git diff --name-only --diff-filter=U
```
### 展示工作区的冲突文件列表
<!--rehype:wrap-class=row-span-2-->
输出工作区和暂存区的 different (不同)。
```bash
$ git diff
```
还可以展示本地仓库中任意两个 commit 之间的文件变动:
```bash
$ git diff <commit-id> <commit-id>
```
### 展示暂存区和最近版本的不同
```bash
git diff --cached
```
### 中文乱码的解决方案
```shell
$ git config --global core.quotepath false
```
### 展示暂存区、工作区和最近版本的不同
```bash
$ git diff HEAD
```
输出工作区、暂存区 和本地最近的版本(commit)的different(不同)。
### 删除已经合并到 master 的分支
```bash
$ git branch --merged master | grep -v '^\*\| master' | xargs -n 1 git branch -d
```
<!--rehype:className=wrap-text-->
### 关联远程分支
<!--rehype:wrap-class=row-span-2-->
```bash
$ git branch -u origin/mybranch
```
或者在 `push` 时加上 `-u` 参数
```bash
git push origin/mybranch -u
```
关联之后,`git branch -vv` 就可以展示关联的远程分支名了, 同时推送到远程仓库直接:`git push`,不需要指定远程仓库
### 查看远程分支和本地分支的对应关系
```bash
$ git remote show origin
```
### 展示当前分支的最近的 tag
```bash
$ git describe --tags --abbrev=0
```
### 查看某段代码是谁写的
```bash
$ git blame <file-name>
```
`blame` 的意思为`责怪`,你懂的。
### 修改作者名
```bash
$ git commit --amend --author='Author Name <email@address.com>'
```
### 修改远程仓库的 url
```bash
$ git remote set-url origin <URL>
```
### 增加远程仓库
```bash
$ git remote add origin <remote-url>
```
<!--rehype:className=wrap-text-->
### 列出所有远程仓库
```bash
$ git remote -v
```
### 查看两个星期内的改动
```bash
$ git whatchanged --since='2 weeks ago'
```
### 从 stash 中拿出某个文件的修改
```bash
$ git checkout <stash@{n}> -- <file-path>
```
<!--rehype:className=wrap-text-->
### 展示所有 tracked 的文件
```bash
$ git ls-files -t
```
### 展示所有 untracked 的文件
```bash
$ git ls-files --others
```
### 展示所有忽略的文件
```bash
$ git ls-files --others -i --exclude-standard
```
<!--rehype:className=wrap-text-->
### 把某一个分支导出成一个文件
```bash
$ git bundle create <file> <branch-name>
```
### 从包中导入分支
<!--rehype:wrap-class=row-span-2-->
```bash
$ git clone repo.bundle <repo-dir> -b <branch-name>
```
<!--rehype:className=wrap-text-->
新建一个分支,分支内容就是上面 `git bundle create` 命令导出的内容
### 执行 rebase 之前自动 stash
```bash
$ git rebase --autostash
```
### 从远程仓库根据 ID拉下某一状态到本地分支
```bash
$ git fetch origin pull/<id>/head:<branch-name>
```
### 详细展示一行中的修改
```bash
$ git diff --word-diff
```
### 清除 gitignore 文件中记录的文件
```bash
$ git clean -X -f
```
### 展示忽略的文件
```bash
$ git status --ignored
```
### commit 历史中显示 Branch1 有的但是 Branch2 没有 commit
```bash
$ git log Branch1 ^Branch2
```
### 在 commit log 中显示 GPG 签名
```bash
$ git log --show-signature
```
### 新建并切换到新分支上,同时这个分支没有任何 commit
```bash
$ git checkout --orphan <branch-name>
```
相当于保存修改,但是重写 commit 历史
### 展示任意分支某一文件的内容
```bash
$ git show <branch-name>:<file-name>
```
### 配置 http 和 socks 代理
<!--rehype:wrap-class=row-span-4-->
```bash
# 查看代理
$ git config --global http.proxy
$ git config --global https.proxy
$ git config --global socks.proxy
# 设置代理
# 适用于 privoxy 将 socks 协议转为 http 协议的 http 端口
$ git config --global http.proxy http://127.0.0.1:1080
$ git config --global https.proxy http://127.0.0.1:1080
$ git config --global socks.proxy 127.0.0.1:1080
# 取消代理
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy
$ git config --global --unset socks.proxy
# 只对 github.com 设置代理
$ git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
$ git config --global https.https://github.com.proxy socks5://127.0.0.1:1080
# 取消 github.com 代理
$ git config --global --unset http.https://github.com.proxy
$ git config --global --unset https.https://github.com.proxy
```
### clone 最新一次提交
```bash
$ git clone --depth=1 https://github.com/user/repo.git
```
只会 `clone` 最近一次提交,将减少 `clone` 时间
### 忽略某个文件的改动
<!--rehype:wrap-class=row-span-2-->
关闭 track 指定文件的改动,也就是 Git 将不会在记录这个文件的改动
```bash
git update-index --assume-unchanged path/to/file
```
<!--rehype:className=wrap-text-->
恢复 track 指定文件的改动
```bash
git update-index --no-assume-unchanged path/to/file
```
<!--rehype:className=wrap-text-->
### 以最后提交的顺序列出所有 Git 分支
```bash
git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads
```
最新的放在最上面
### 在 commit log 中查找相关内容
```bash
git log --all --grep='<given-text>'
```
通过 grep 查找given-text: 所需要查找的字段
### 把暂存区的指定 file 放到工作区中
```bash
git reset <file-name>
```
不添加参数,默认是 `-mixed`
### 配置 SSH 协议代理
```shell
# 对于使用 git@ 协议的,可以配置 socks5 代理
# macOS 系统编辑 ~/.ssh/config 文件,添加这几行,设置 github 代理
Host github.com
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
```
<!--rehype:className=wrap-text-->
另见
---
- [最常用的 git 提示和技巧](https://github.com/git-tips/tips)

841
docs/github-actions.md Normal file
View File

@ -0,0 +1,841 @@
Github Actions 备忘清单
====
本备忘单总结了 [Github Actions](https://github.com/actions) 常用的配置说明,以供快速参考。
入门
---
### 介绍
GitHub [Actions](https://github.com/actions) 的仓库中自动化、自定义和执行软件开发工作流程,有四个基本的概念,如下:
:- | :-
:- | :-
`workflow` _(工作流程)_ | 持续集成一次运行的过程,就是一个 `workflow`
`job` _(任务)_ | 一个 `workflow` 由一个或多个 `jobs` 构成,含义是一次持续集成的运行,可以完成多个任务
`step` _(步骤)_ | 每个 `job` 由多个 `step` 构成,一步步完成
`action` _(动作)_ | 每个 `step` 可以依次执行一个或多个命令(`action`)
<!--rehype:className=style-list-arrow-->
---
- 采用 [YAML](./yaml.md) 格式定义配置文件
- 存放在代码仓库的 `.github/workflows` 目录中
- 后缀名统一为 `.yml`,比如 `ci.yml`
- 一个库可以有多个 `workflow` 文件
- 根据配置事件自动运行配置文件
<!--rehype:className=style-round-->
### 配置文件
```yaml {3,5,10}
name: GitHub Actions Demo
on:
push:
branches:
- main
# 任务
jobs:
build:
runs-on: ubuntu-latest
# 步骤 根据步骤执行任务
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install
- run: npm run build
```
存放到 `.github/workflows` 目录中,命名为 `ci.yml`,当 `push` 代码到仓库 `main` 分支中,该配置自动运行配置。
### 指定触发
<!--rehype:wrap-class=row-span-2-->
`push` 事件触发 `workflow`
```yaml
on: push
```
`push` 事件或 `pull_request` 事件都可以触发 `workflow`
```yaml
on: [push, pull_request]
```
只有在 `main` 分支 `push` 事件触发 `workflow`
```yaml {2}
on:
push:
branches:
- main
```
`push` 事件触发 `workflow``docs` 目录下的更改 `push` 事件不触发 `workflow`
```yaml {2,4}
on:
push:
paths-ignore:
- 'docs/**'
```
push 事件触发 workflow包括 sub-project 目录或其子目录中的文件触发 workflow除非该文件在 sub-project/docs 目录中,不触发 workflow
```yaml
on:
push:
paths:
- 'sub-project/**'
- '!sub-project/docs/**'
```
版本发布为 `published` 时运行工作流程。
```yml
on:
release:
types: [published]
```
### 多项任务
```yml
jobs:
my_first_job: # 第一个任务
name: My first job
my_second_job: # 第二个任务
name: My second job
```
通过 jobs `(jobs.<job_id>.name)`字段,配置一项或多项需要执行的任务
### 多项任务依赖关系
通过 needs `(jobs.<job_id>.needs)`字段,指定当前任务的依赖关系
```yml
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]
```
上面配置中,`job1` 必须先于 `job2` 完成,而 `job3` 等待 `job1` 和 `job2` 的完成才能运行。因此,这个 `workflow` 的运行顺序依次为:`job1`、`job2`、`job3`
### 多项任务传递参数
<!--rehype:wrap-class=col-span-2-->
```yml {2,5,9,11,15}
jobs:
job1:
runs-on: ubuntu-latest
# 将步骤输出映射到作业输出
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "::set-output name=test::hello"
- id: step2
run: echo "::set-output name=test::world"
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
```
### 指定每项任务的虚拟机环境
```yml
runs-on: ubuntu-latest
```
指定运行所需要的虚拟机环境,⚠️ 它是必填字段
```yml {3}
jobs:
build: # 任务名称
runs-on: ubuntu-latest # 虚拟机环境配置
```
---
- `Windows Server 2022` _(windows-latest)_ 或 _(windows-2022)_
- `Ubuntu 20.04` _(ubuntu-latest)_ 或 _(ubuntu-20.04)_
- `macOS Monterey 12` _(macos-12)_
- `macOS Big Sur 11` _(macos-latest)_,_(macos-11)_
<!--rehype:className=style-arrow-->
另见: [选择 GitHub 托管的运行器](https://docs.github.com/cn/actions/using-workflows/workflow-syntax-for-github-actions#选择-github-托管的运行器)
### 指定每项任务的步骤
每个步骤都可以指定以下三个字段
```shell
jobs.<job_id>.steps.name # 步骤名称
# 该步骤运行的命令或者 action
jobs.<job_id>.steps.run
# 该步骤所需的环境变量
jobs.<job_id>.steps.env
```
`steps` 字段指定每个 `Job` 的运行步骤,可以包含一个或多个步骤(`steps`)
```yml {4}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install
- run: npm run build
```
### 环境变量
```shell
jobs.<job_id>.environment
```
使用单一环境名称的示例
```yml
environment: staging_environment
```
使用环境名称和 URL 的示例
```yml
environment:
name: production_environment
url: https://github.com
```
#### 自定义环境变量
`GitHub` 会保留 `GITHUB_` 环境变量前缀供 `GitHub` 内部使用。设置有 `GITHUB_` 前缀的环境变量或密码将导致错误。
```yml
- name: 测试 nodejs 获取环境变量
env:
API_TOKEN: ${{ secrets.API_TOKEN }}
```
在 `https://github.com/<用户名>/<项目名称>/settings/secrets` 中添加 `secrets` `API_TOKEN`,在工作流中设置环境变量 [`API_TOKEN`](https://github.com/jaywcjlove/github-actions/blob/799b232fca3d9df0272eaa12610f9ebfca51b288/.github/workflows/ci.yml#L46)
### 表达式
在 `if` 条件下使用表达式时,可以省略表达式语法 (`${{ }}`),因为 GitHub 会自动将 `if` 条件作为表达式求值
```yml {3}
steps:
- uses: actions/hello-world-action@v1.1
if: github.repository == 'uiw/uiw-repo'
# if: ${{ <expression> }}
```
设置环境变量的示例
```yml
env:
MY_ENV_VAR: ${{ <expression> }}
```
#### 操作符
- `( )` _(逻辑分组)_
- `[ ]` _(指数)_
- `.` _(属性取消引用)_
- `!` _(不是)_
- `<` _(少于)_
- `<=` _(小于或等于)_
- `>` _(比...更棒)_
- `>=` _(大于或等于)_
- `==` _(平等的)_
- `!=` _(不相等)_
- `&&` _(和)_
- `||` _(或者)_
<!--rehype:className=cols-2 style-none-->
### Github 上下文
<!--rehype:wrap-class=col-span-2-->
属性名称 | 类型 | 描述
---- | ---- | ----
`github` _(object)_ | 工作流程中任何作业或步骤期间可用的顶层上下文。
`github.event` _(object)_ | 完整事件 web 挂钩有效负载。 更多信息请参阅“触发工作流程的事件”。
`github.event_path` _(string)_ | 运行器上完整事件 web 挂钩有效负载的路径。
`github.workflow` _(string)_ | 工作流程的名称。 如果工作流程文件未指定 name此属性的值将是仓库中工作流程文件的完整路径。
`github.job` _(string)_ | 当前作业的 job_id。
`github.run_id` _(string)_ | 仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。
`github.run_number` _(string)_ | 仓库中特定工作流程每个运行的唯一编号。 此编号从 1对应于工作流程的第一个运行开始然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。
`github.actor` _(string)_ | 发起工作流程运行的用户的登录名。
`github.repository` _(string)_ | 所有者和仓库名称。 例如 Codertocat/Hello-World。
`github.repository_owner` _(string)_ | 仓库所有者的名称。 例如 Codertocat。
`github.event_name` _(string)_ | 触发工作流程运行的事件的名称。
`github.sha` _(string)_ | 触发工作流程的提交 SHA。
`github.ref` _(string)_ | 触发工作流程的分支或标记参考。
`github.head_ref` _(string)_ | 工作流程运行中拉取请求的 head_ref 或来源分支。 此属性仅在触发工作流程运行的事件为 pull_request 时才可用。
`github.base_ref` _(string)_ | 工作流程运行中拉取请求的 base_ref 或目标分支。 此属性仅在触发工作流程运行的事件为 pull_request 时才可用。
`github.token` _(string)_ | 代表仓库上安装的 GitHub 应用程序进行身份验证的令牌。 这在功能上等同于 GITHUB_TOKEN 密码。 更多信息请参阅“使用 GITHUB_TOKEN 验证身份”。
`github.workspace` _(string)_ | 使用 checkout 操作时步骤的默认工作目录和仓库的默认位置。
`github.action` _(string)_ | 正在运行的操作的名称。 在当前步骤运行脚本时GitHub 删除特殊字符或使用名称 run。 如果在同一作业中多次使用相同的操作,则名称将包括带有序列号的后缀。 例如,运行的第一个脚本名称为 run1则第二个脚本将命名为 run2。 同样actions/checkout 第二次调用时将变成 actionscheckout2。
<!--rehype:className=style-list-arrow-->
[Github 上下文](https://help.github.com/cn/actions/reference/context-and-expression-syntax-for-github-actions)是访问有关工作流运行、运行器环境、作业和步骤的信息的一种方式
### 默认环境变量
环境变量 | 描述
---- | ----
`CI` | 始终设置为 `true`
`HOME` | 用于存储用户数据的 GitHub 主目录路径。 例如 `/github/home`
`GITHUB_WORKFLOW` | 工作流程的名称。
`GITHUB_RUN_ID` | 仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。
`GITHUB_RUN_NUMBER` | 仓库中特定工作流程每个运行的唯一编号。 此编号从 1对应于工作流程的第一个运行开始然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。
`GITHUB_ACTION` | 操作唯一的标识符 (id)。
`GITHUB_ACTIONS` | 当 GitHub 操作 运行工作流程时,始终设置为 true。 您可以使用此变量来区分测试是在本地运行还是通过 GitHub 操作 运行。
`GITHUB_ACTION_PATH` | GitHub 操作所在的路径
`GITHUB_ACTOR` | 发起工作流程的个人或应用程序的名称。 例如 octocat
`GITHUB_API_URL` | 返回 `API URL`。例如:`https://api.github.com`
`GITHUB_REPOSITORY` | 所有者和仓库名称。 例如 octocat/Hello-World
`GITHUB_EVENT_NAME` | 触发工作流程的 web 挂钩事件的名称
`GITHUB_EVENT_PATH` | 具有完整 web 挂钩事件有效负载的文件路径。 例如 /github/workflow/event.json
`GITHUB_WORKSPACE` | GitHub 工作空间目录路径。 如果您的工作流程使用 [actions/checkout](https://github.com/actions/checkout) 操作,工作空间目录将包含存储仓库副本的子目录。 如果不使用 [actions/checkout](https://github.com/actions/checkout) 操作,该目录将为空。 例如 /home |/runner/work/my-repo-name/my-repo-name
`GITHUB_SHA` | 触发工作流程的提交 SHA。 例如 ffac537e6cbbf9
`GITHUB_REF` | 触发工作流程的分支或标记参考。 例如 refs/heads/feature-branch-1。 如果分支或标记都不适用于事件类型,则变量不会存在
`GITHUB_HEAD_REF` | 仅为复刻的仓库设置。头部仓库的分支
`GITHUB_BASE_REF` | 仅为复刻的仓库设置。基础仓库的分支
<!--rehype:className=style-list-arrow-->
另见: [默认环境变量](https://docs.github.com/cn/actions/learn-github-actions/environment-variables#default-environment-variables)
### 直接常量
<!--rehype:wrap-class=row-span-2-->
作为表达式的一部分,可以使用 `boolean`, `null`, `number` 或 `string`数据类型
```yml
env:
myNull: ${{ null }}
myBoolean: ${{ false }}
myIntegerNumber: ${{ 711 }}
myFloatNumber: ${{ -9.2 }}
myHexNumber: ${{ 0xff }}
myExponentialNumber: ${{ -2.99e-2 }}
myString: Mona the Octocat
myStringInBraces: ${{ 'It''s source!' }}
```
### 函数 contains
<!--rehype:wrap-class=row-span-2-->
使用字符串的示例
```js
contains('Hello world', 'llo') // 返回 true
```
使用对象过滤器的示例返回 true
```js
contains(github.event.issue.labels.*.name, 'bug')
```
<!--rehype:className=wrap-text -->
另见: [函数 contains](https://docs.github.com/cn/actions/learn-github-actions/expressions#contains)
### 函数 startsWith
```js
startsWith('Hello world', 'He') // 返回 true
```
另见: [函数 startsWith](https://docs.github.com/cn/actions/learn-github-actions/expressions#startswith),此函数不区分大小写
### 函数 format
```js
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)
### 函数 join
```js
join(github.event.issue.labels.*.name, ', ')
// 也许返回 'bug, help wanted'.
```
另见: [函数 join](https://docs.github.com/cn/actions/learn-github-actions/expressions#join)
### 函数 toJSON
```js
toJSON(job)
// 也许返回 { "status": "Success" }.
```
另见: [函数 toJSON](https://docs.github.com/cn/actions/learn-github-actions/expressions#tojson)
### 函数
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`fromJSON` | 返回 JSON 对象或 JSON 数据类型的值 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#fromjson)
`hashFiles` | 返回与路径模式匹配的文件集的单个哈希 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#hashfiles)
`success` | 当前面的步骤都没失败或被取消时返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#success)
`always` | 使步骤始终执行,返回 `true` 即使取消也是如此 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#always)
`cancelled` | 如果工作流被取消,则返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#cancelled)
`failure` | 当作业的任何先前步骤失败时返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#failure)
### 函数 success()
```yml
steps:
...
- name: The job has succeeded
if: ${{ success() }}
```
### 函数 failure()
```yml
steps:
...
- name: The job has failed
if: ${{ failure() }}
```
常用实例
----
### 获取版本信息
<!--rehype:wrap-class=col-span-2-->
```yml
- name: Test
run: |
# Strip git ref prefix from version
echo "${{ github.ref }}"
# VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# # Strip "v" prefix from tag name
# [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
echo "$VERSION"
```
<!--rehype:className=wrap-text -->
### 提交到 gh-pages 分支
```yml
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{secrets.GITHUB_TOKEN}}
publish_dir: ./build
```
### 修改 package.json
```yml
- name: Modify Version
shell: bash
run: |
node -e 'var pkg = require("./package.json"); pkg.version= (new Date().getFullYear().toString().substr(2)) + "." + (new Date().getMonth() + 1) + "." + (new Date().getDate()); require("fs").writeFileSync("./package.json", JSON.stringify(pkg, null, 2))'
```
<!--rehype:className=wrap-text -->
使用 [github-action-package](https://github.com/jaywcjlove/github-action-package) 修改 `name` 字段
```yml
- name: package.json info
uses: jaywcjlove/github-action-package@main
with:
rename: '@wcj/github-package-test'
```
### 克隆带有 Submodule 的仓库
```yml
- name: Checkout
uses: actions/checkout@v3
with:
path: main
submodules: true
```
`submodules``true` 检出子模块或 `recursive` 递归检出子模块
```yml
- name: Clone sub repository
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
# git submodule sync --recursive
# git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --remote --force --recursive --checkout ant.design
```
### 步骤依赖作业
<!--rehype:wrap-class=row-span-2-->
使用 `jobs.<job_id>.needs` 识别在此作业运行之前必须成功完成的任何作业。它可以是一个字符串,也可以是字符串数组。 如果某个作业失败,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。
```yml
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]
```
在此示例中,`job1` 必须在 `job2` 开始之前成功完成,而 `job3` 要等待 `job1` 和 `job2` 完成。此示例中的作业按顺序运行:
```
❶ job1
❷ job2
❸ job3
```
配置如下
```yml
jobs:
job1:
job2:
needs: job1
job3:
if: ${{ always() }}
needs: [job1, job2]
```
在此示例中,`job3` 使用 `always()` 条件表达式,因此它始终在 `job1` 和 `job2` 完成后运行,不管它们是否成功。
### 同步 Gitee
<!--rehype:wrap-class=col-span-2-->
```yml
- name: Sync to Gitee
run: |
mirror() {
git clone "https://github.com/$1/$2"
cd "$2"
git remote add gitee "https://jaywcjlove:${{ secrets.GITEE_TOKEN }}@gitee.com/uiw/$2"
git remote set-head origin -d
git push gitee --prune +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*
cd ..
}
mirror uiwjs uiw
```
<!--rehype:className=wrap-text -->
### 提交 NPM 包
```yml
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
```
获取 `NPM_TOKEN`,可以通过 [npm](https://www.npmjs.com/settings/wcjiang/tokens) 账号创建 `token`
```shell
npm token list [--json|--parseable] # 查看
npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16] # 创建
npm token revoke <id|token> # 撤销
```
<!--rehype:className=wrap-text -->
可以使用 [JS-DevTools/npm-publish](https://github.com/JS-DevTools/npm-publish) 提交
```yml
- name: 📦 @province-city-china/data
uses: JS-DevTools/npm-publish@v1
with:
token: ${{ secrets.NPM_TOKEN }}
package: packages/data/package.json
```
它有个好处,检测 `package.json` 中版本号是否发生变更,来决定是否提交版本,不会引发流程错误。
### 步骤作业文件共享
Artifacts 是 GitHub Actions 为您提供持久文件并在运行完成后使用它们或在作业(文档)之间共享的一种方式。
要创建工件并使用它,您将需要不同的操作:上传和下载。
要上传文件或目录,您只需像这样使用它:
```yml
steps:
- uses: actions/checkout@v2
- run: mkdir -p path/to/artifact
- run: echo hello > path/to/artifact/a.txt
- uses: actions/upload-artifact@v2
with:
name: my-artifact
path: path/to/artifact/a.txt
```
然后下载 `artifact` 以使用它:
```yml
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: my-artifact
```
### Node.js
```yml
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: 14
```
使用[矩阵策略](https://docs.github.com/cn/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategy) 在 nodejs 不同版本中运行
```yml
strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
steps:
- uses: actions/checkout@v2
- name: 使用 Node ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npm test
```
### 提交 docker 镜像
<!--rehype:wrap-class=col-span-2 row-span-2-->
```yml
# https://www.basefactor.com/github-actions-docker
- name: Docker login
run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
- name: Build ant.design image
run: |
cd ./ant\.design
docker build -t ant.design .
- name: Tags & Push docs
run: |
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
docker tag ant.design ${{ secrets.DOCKER_USER }}/ant.design:$VERSION
docker tag ant.design ${{ secrets.DOCKER_USER }}/ant.design:latest
docker push ${{ secrets.DOCKER_USER }}/ant.design:$VERSION
docker push ${{ secrets.DOCKER_USER }}/ant.design:latest
```
### 创建一个 tag
```yml
- name: Create Tag
id: create_tag
uses: jaywcjlove/create-tag-action@main
with:
package-path: ./package.json
```
根据 `package-path` 指定的 `package.json` 检测 `version` 是否发生变化来创建 `tag`
### 生成 git 提交日志
```yml
- name: Generate Changelog
id: changelog
uses: jaywcjlove/changelog-generator@main
with:
filter-author: (小弟调调™)
- name: Get the changelog
run: echo "${{ steps.changelog.outputs.changelog }}"
```
<!--rehype:className=wrap-text -->
### 提交到 GitHub docker 镜像仓库
<!--rehype:wrap-class=col-span-3-->
```yml
- name: '登录到 GitHub 注册表'
run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: '编译 docker image'
run: docker build -t ghcr.io/jaywcjlove/reference:latest .
- name: '推送到 GitHub 注册表中'
run: docker push ghcr.io/jaywcjlove/reference:latest
- name: '标记 docker 镜像并发布到 GitHub 注册表'
if: steps.create_tag.outputs.successful
run: |
echo "version: v${{ steps.changelog.outputs.version }}"
docker tag ghcr.io/jaywcjlove/reference:latest ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
docker push ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
```
### 提交 commit 到 master 分支
<!--rehype:wrap-class=col-span-2-->
```yml
- name: 生成一个文件,并将它提交到 master 分支
run: |
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
COMMIT=released-${VERSION}
# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
echo "输出版本号:$VERSION"
# 将版本输出到当前 VERSION 文件中
echo "$VERSION" > VERSION
echo "1. 输出Commit$commit"
echo "2. Released $VERSION"
git fetch
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -am $COMMIT
git branch -av
git pull origin master
- name: 将上面的提交 push 到 master 分支
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
```
### 作业之间共享数据
创建一个文件,然后将其作为构件上传
```yml {11}
jobs:
example-job:
name: Save output
steps:
- shell: bash
run: |
expr 1 + 1 > output.log
- name: Upload output file
uses: actions/upload-artifact@v3
with:
name: output-log-file
path: output.log
```
可以下载名为 `output-log-file` 的工件
```yml {7}
jobs:
example-job:
steps:
- name: Download a single artifact
uses: actions/download-artifact@v3
with:
name: output-log-file
```
### 指定运行命令的工作目录
```yml {3}
- name: Clean temp directory
run: rm -rf *
working-directory: ./temp
```
使用 `working-directory` 关键字,您可以指定运行命令的工作目录(`./temp`)
#### defaults.run
```yml {4,5,7}
jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: scripts
```
作业中的所有 `run` 步骤提供默认的 `shell` 和 `working-directory`
### jobs.<job_id>.steps[*].shell
使用 `bash` 运行脚本
```yml {4}
steps:
- name: Display the path
run: echo $PATH
shell: bash
```
运行 `python` 脚本
```yml {6}
steps:
- name: Display the path
run: |
import os
print(os.environ['PATH'])
shell: python
```
您可以使用 `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-->
另见
---
- [Github Actions 学习笔记](https://jaywcjlove.github.io/github-actions) _(jaywcjlove.github.io)_
- [了解 GitHub Actions](https://docs.github.com/cn/actions/learn-github-actions) _(docs.github.com)_

128
docs/gmail.md Normal file
View File

@ -0,0 +1,128 @@
Gmail 备忘清单
===
本备忘单总结了常用的 [Gmail](https://gmail.com/) 快捷键,以供快速参考。
Gmail 快捷键
---
### Gmail 导航
:- | :-
:- | :-
`u` | 返回话题列表(或刷新话题列表)
`k` / `j` | 较新/较旧的对话
`o` or `Enter` | 打开对话; 折叠/展开
`p` / `n` | 阅读上一条/下一条消息
<code>\`</code> | 转到下一个收件箱部分
`~` | 转到上一个收件箱部分
<!--rehype:className=shortcuts-->
### Gmail 应用程序
:- | :-
:- | :-
`c` | 撰写
`d` | 添加 cc 撰写
`b` | 添加 cc 和 bcc 撰写
`/` | 搜索
`q` | 焦点聊天联系人搜索
`?` | 打开快捷方式帮助
<!--rehype:className=shortcuts-->
### Gmail 操作
<!--rehype:wrap-class=row-span-3-->
:- | :-
:- | :-
`,` | 将焦点移至工具栏
`x` | 选择对话
`s` | 旋转超级巨星
`y` | 删除标签
`e` | 档案
`m` | 忽略对话
`!` | 报告为垃圾邮件
`v` | 打开移动到菜单
`#` | 移到废纸篓
`r` | 回复
`Shift+r` | 在新窗口中回复
`a` | 全部回复
`Shift+a` | 在新窗口中回复所有
`f` | 向前
`Shift+f` | 在新窗口中转发
`Shift+n` | 更新对话
`Tab` 然后 `Enter` | 发邮件
`Esc` | 焦点最后聊天痣
`]` / `[` | 删除并转到上一个/下一个
`}` / `{` | 存档并转到上一个/下一个
`z` | 撤消上一个操作
`.` | 打开更多操作菜单
`l` | 打开标签菜单
`Shift+i` | 标记为已读
`Shift+u` | 标记为未读
`_` | 将所选邮件标记为未读
`Ctrl+s` | 保存草稿
`+``=` | 标记为重要
`-` | 标记为不重要
`Shift+l` | 喜欢/不喜欢嗡嗡声
`h` | 抢先看
`g` 然后 `p` | 打个电话
`&` | 启动老蛇
`Shift+t` | 将对话添加到任务
<!--rehype:className=shortcuts-->
### Gmail 跳转
:- | :-
:- | :-
`g` 然后 `i` | 打开收件箱
`g` 然后 `s` | 打开已加星标的对话
`g` 然后 `t` | 打开已发送消息
`g` 然后 `d` | 打开草稿
`g` 然后 `a` | 打开所有消息
`g` 然后 `c` | 打开联系人
`g` 然后 `b` | 去嗡嗡声
`g` 然后 `l` | 转到标签
`g` 然后 `k` | 前往任务
<!--rehype:className=shortcuts-->
### Gmail 主题列表选择
:- | :-
:- | :-
`*` 然后 `a` | 选择所有对话
`*` 然后 `n` | 取消选择所有对话
`*` 然后 `r` | 选择阅读对话
`*` 然后 `u` | 选择未读对话
`*` 然后 `s` | 选择加星标的对话
`*` 然后 `t` | 选择未加星标的对话
<!--rehype:className=shortcuts-->
### Gmail 搜索语法
:- | :-
:- | :-
`from:[arg]` | 从
`to:[arg]` | 至
`label:­[arg]` | 标签
`subjec­t:[arg]` | 主题
`-[arg]` | 不包含
`has:at­tac­hment` | 有附件
`filena­me:­[fi­lename]` | 附件文件名
`before­:20­11/­11/20` | 之前(日期)
`after:­201­1/11/20` | 之后(日期)
`from:annie``from:david` | 或运算符
`list:[arg]` | 邮件列表
`subjec­t:(­word1 word2)` | 组词
`in:any­where` | 在所有框中搜索(垃圾邮件和垃圾邮件除外)
`in:trash in:inbox in:spam` | 在特定框中搜索
`is:starred is:read is:unread` | 搜索特定消息
`is:chat` | 在聊天中搜索
`cc:[arg] bcc:[arg]` | 搜索副本收件人
<!--rehype:className=shortcuts-->
### Gmail 提示和技巧
-`u` 刷新话题列表
- 对于多选,选择一个对话,然后 `shift+单击`另一个对话以选择其间的所有对话
- 在主题中添加 `EOM`(消息结尾)以避免 `no-text-in-body` 警告

968
docs/golang.md Normal file
View File

@ -0,0 +1,968 @@
Golang 备忘清单
===
该备忘单提供了帮助您使用 [Golang](https://golang.org) 的基本语法和方法。
入门
--------
### hello.go
```go
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
```
直接运行
```shell
$ go run hello.go
Hello, world!
```
或者在 [Go repl](https://repl.it/languages/go) 中尝试一下
### 变量
```go
var s1 string
s1 = "Learn Go!"
// 一次声明多个变量
var b, c int = 1, 2
var d = true
```
简短声明
```go
s1 := "Learn Go!" // string
b, c := 1, 2 // int
d := true // bool
```
参见:[基本类型](#golang-基本类型)
### 函数
```go
package main
import "fmt"
// 程序的入口点
func main() {
fmt.Println("Hello world!")
say("Hello Go!")
}
func say(message string) {
fmt.Println("You said: ", message)
}
```
参见:[函数(Functions)](#golang-函数)
### 注释
```go
// 单行注释
/* 这是
多行注释 */
```
### 如果语句
```go
if true {
fmt.Println("Yes!")
}
```
参见:[条件控制](#golang-条件控制)
Golang 基本类型
--------
### 字符串 Strings
```go
s1 := "Hello" + "World"
s2 := `A "raw" string literal
can include line breaks.`
// 输出10
fmt.Println(len(s1))
// 输出Hello
fmt.Println(string(s1[0:5]))
```
字符串的类型为 `字符串`
### 数字 Numbers
```go
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias: uint8)
var u uint = 7 // uint (unsigned)
var p float32 = 22.7 // 32-bit float
```
#### 操作符 Operators
```go
x := 5
x++
fmt.Println("x + 4 =", x + 4)
fmt.Println("x * 4 =", x * 4)
```
参见:[更多操作符](#运算符和标点符号)
### 布尔值 Booleans
```go
isTrue := true
isFalse := false
```
#### 操作符
```go
fmt.Println(true && true) // true
fmt.Println(true && false) // false
fmt.Println(true || true) // true
fmt.Println(true || false) // true
fmt.Println(!true) // false
```
参见:[更多操作符](#运算符和标点符号)
### 数组 Arrays
<!--rehype:wrap-class=row-span-2-->
```go
┌────┬────┬────┬────┬─────┬─────┐
| 2 | 3 | 5 | 7 | 11 | 13 |
└────┴────┴────┴────┴─────┴─────┘
0 1 2 3 4 5
```
---
```go
primes := [...]int{2, 3, 5, 7, 11, 13}
fmt.Println(len(primes)) // => 6
// 输出:[2 3 5 7 11 13]
fmt.Println(primes)
// 与 [:3] 相同,输出:[2 3 5]
fmt.Println(primes[0:3])
```
---
```go
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1]) //=> Hello World
fmt.Println(a) // => [Hello World]
```
#### 2d array
```go
var twoDimension [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoDimension[i][j] = i + j
}
}
// => 2d: [[0 1 2] [1 2 3]]
fmt.Println("2d: ", twoDimension)
```
### 指针(Pointers)
```go
func main () {
b := *getPointer()
fmt.Println("Value is", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}
a := new(int)
*a = 234
```
参见:[指针(Pointers)](https://tour.golang.org/moretypes/1)
### 切片(Slices)
```go
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s)
fmt.Println(s[1])
fmt.Println(len(s))
fmt.Println(s[1:3])
slice := []int{2, 3, 4}
```
另见:[切片示例](https://gobyexample.com/slices)
### 常量(Constants)
```go
const s string = "constant"
const Phi = 1.618
const n = 500000000
const d = 3e20 / n
fmt.Println(d)
```
### 类型转换
```go
i := 90
f := float64(i)
u := uint(i)
// 将等于字符Z
s := string(i)
```
#### 如何获取int字符串
```go
i := 90
// 需要导入“strconv”
s := strconv.Itoa(i)
fmt.Println(s) // Outputs: 90
```
Golang 字符串
--------
### 字符串函数
```go
package main
import (
"fmt"
s "strings"
)
func main() {
/* 需要将字符串导入为 s */
fmt.Println(s.Contains("test", "e"))
/* 内置 */
fmt.Println(len("hello")) // => 5
// 输出: 101
fmt.Println("hello"[1])
// 输出: e
fmt.Println(string("hello"[1]))
}
```
### fmt.Printf
<!--rehype:wrap-class=row-span-2 col-span-2-->
```go
package main
import (
"fmt"
"os"
)
type point struct {
x, y int
}
func main() {
p := point{1, 2}
fmt.Printf("%v\n", p) // => {1 2}
fmt.Printf("%+v\n", p) // => {x:1 y:2}
fmt.Printf("%#v\n", p) // => main.point{x:1, y:2}
fmt.Printf("%T\n", p) // => main.point
fmt.Printf("%t\n", true) // => TRUE
fmt.Printf("%d\n", 123) // => 123
fmt.Printf("%b\n", 14) // => 1110
fmt.Printf("%c\n", 33) // => !
fmt.Printf("%x\n", 456) // => 1c8
fmt.Printf("%f\n", 78.9) // => 78.9
fmt.Printf("%e\n", 123400000.0) // => 1.23E+08
fmt.Printf("%E\n", 123400000.0) // => 1.23E+08
fmt.Printf("%s\n", "\"string\"") // => "string"
fmt.Printf("%q\n", "\"string\"") // => "\"string\""
fmt.Printf("%x\n", "hex this") // => 6.86578E+15
fmt.Printf("%p\n", &p) // => 0xc00002c040
fmt.Printf("|%6d|%6d|\n", 12, 345) // => | 12| 345|
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45) // => | 1.20| 3.45|
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45) // => |1.20 |3.45 |
fmt.Printf("|%6s|%6s|\n", "foo", "b") // => | foo| b|
fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // => |foo |b |
s := fmt.Sprintf("a %s", "string")
fmt.Println(s)
fmt.Fprintf(os.Stderr, "an %s\n", "error")
}
```
另见:[fmt](https://golang.org/pkg/fmt/)
### 函数实例
| 实例 | Result |
| ----------------------------- | ----------- |
| Contains("test", "es") | true |
| Count("test", "t") | 2 |
| HasPrefix("test", "te") | true |
| HasSuffix("test", "st") | true |
| Index("test", "e") | 1 |
| Join([]string{"a", "b"}, "-") | a-b |
| Repeat("a", 5) | aaaaa |
| Replace("foo", "o", "0", -1) | f00 |
| Replace("foo", "o", "0", 1) | f0o |
| Split("a-b-c-d-e", "-") | [a b c d e] |
| ToLower("TEST") | test |
| ToUpper("test") | TEST |
Golang 条件控制
--------
### 有条件的
```go
a := 10
if a > 20 {
fmt.Println(">")
} else if a < 20 {
fmt.Println("<")
} else {
fmt.Println("=")
}
```
### if 中的语句
```go
x := "hello go!"
if count := len(x); count > 0 {
fmt.Println("Yes")
}
```
---
```go
if _, err := doThing(); err != nil {
fmt.Println("Uh oh")
}
```
### Switch
```go
x := 42.0
switch x {
case 0:
case 1, 2:
fmt.Println("Multiple matches")
case 42: // Don't "fall through".
fmt.Println("reached")
case 43:
fmt.Println("Unreached")
default:
fmt.Println("Optional")
}
```
参见:[Switch](https://github.com/golang/go/wiki/Switch)
### For loop
```go
for i := 0; i <= 10; i++ {
fmt.Println("i: ", i)
}
```
### 对于 Range 循环
```go
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
```
### While 循环
```go
i := 1
for i <= 3 {
fmt.Println(i)
i++
}
```
### Continue 关键字
```go
for i := 0; i <= 5; i++ {
if i % 2 == 0 {
continue
}
fmt.Println(i)
}
```
### Break 关键字
```go
for {
fmt.Println("loop")
break
}
```
Golang 结构和映射
--------
### 定义
<!--rehype:wrap-class=row-span-2-->
```go
package main
import (
"fmt"
)
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y) // => 4 2
}
```
参见:[结构(Structs)](https://tour.golang.org/moretypes/2)
### 字面量
```go
v := Vertex{X: 1, Y: 2}
// Field names can be omitted
v := Vertex{1, 2}
// Y is implicit
v := Vertex{X: 1}
```
您还可以输入字段名
### 映射
<!--rehype:wrap-class=row-span-2-->
```go
m := make(map[string]int)
m["k1"] = 7
m["k2"] = 13
fmt.Println(m) // => map[k1:7 k2:13]
v1 := m["k1"]
fmt.Println(v1) // => 7
fmt.Println(len(m)) // => 2
delete(m, "k2")
fmt.Println(m) // => map[k1:7]
_, prs := m["k2"]
fmt.Println(prs) // => false
n := map[string]int{"foo": 1, "bar": 2}
fmt.Println(n) // => map[bar:2 foo:1]
```
### 指向结构的指针
```go
v := &Vertex{1, 2}
v.X = 2
```
Doing `v.X` is the same as doing `(*v).X`, when `v` is a pointer.
Golang 函数
--------
### 多个参数
```go
func plus(a int, b int) int {
return a + b
}
func plusPlus(a, b, c int) int {
return a + b + c
}
fmt.Println(plus(1, 2))
fmt.Println(plusPlus(1, 2, 3))
```
### 多次返回
```go
func vals() (int, int) {
return 3, 7
}
a, b := vals()
fmt.Println(a) // => 3
fmt.Println(b) // => 7
```
### 匿名函数
```go
r1, r2 := func() (string, string) {
x := []string{"hello", "world"}
return x[0], x[1]
}()
// => hello world
fmt.Println(r1, r2)
```
### 命名返回
```go
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
x, y := split(17)
fmt.Println(x) // => 7
fmt.Println(y) // => 10
```
### 变量函数
```go
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
sum(1, 2) //=> [1 2] 3
sum(1, 2, 3) // => [1 2 3] 6
nums := []int{1, 2, 3, 4}
sum(nums...) // => [1 2 3 4] 10
```
### 初始化函数
```go
import --> const --> var --> init()
```
---
```go
var num = setNumber()
func setNumber() int {
return 42
}
func init() {
num = 0
}
func main() {
fmt.Println(num) // => 0
}
```
### 作为值的函数
```go
func main() {
// 将函数赋给名称
add := func(a, b int) int {
return a + b
}
// 使用名称调用函数
fmt.Println(add(3, 4)) // => 7
}
```
### 关闭 1
```go
func scope() func() int{
outer_var := 2
foo := func() int {return outer_var}
return foo
}
// Outpus: 2
fmt.Println(scope()())
```
### 关闭 2
```go
func outer() (func() int, int) {
outer_var := 2
inner := func() int {
outer_var += 99
return outer_var
}
inner()
return inner, outer_var
}
inner, val := outer()
fmt.Println(inner()) // => 200
fmt.Println(val) // => 101
```
Golang 包(Packages)
--------
### 导入
<!--rehype:wrap-class=row-span-2-->
```go
import "fmt"
import "math/rand"
```
#### 等同于
```go
import (
"fmt" // 给 fmt.Println
"math/rand" // 给 rand.Intn
)
```
另见:[导入](https://tour.golang.org/basics/1)
### 别名
<!--rehype:wrap-class=row-span-2-->
```go
import r "math/rand"
```
---
```go
import (
"fmt"
r "math/rand"
)
```
---
```go
r.Intn()
```
### Packages
```go
package main
// 一个内部包只能被另一个包导入
// 那是在以内部目录的父级为根的树内
package internal
```
另见:[内部包](https://go.dev/doc/go1.4#internalpackages)
### 导出名称
```go
// 以大写字母开头
func Hello () {
···
}
```
另见:[导出的名称](https://tour.golang.org/basics/3)
Golang 并发
--------
### 协程
<!--rehype:wrap-class=row-span-2-->
```go
package main
import (
"fmt"
"time"
)
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}
func main() {
f("direct")
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
}("going")
time.Sleep(time.Second)
fmt.Println("done")
}
```
参见:[Goroutines](https://tour.golang.org/concurrency/1), [Channels](https://tour.golang.org/concurrency/2)
### WaitGroup
<!--rehype:wrap-class=row-span-2-->
```go
package main
import (
"fmt"
"sync"
"time"
)
func w(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("%d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("%d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go w(i, &wg)
}
wg.Wait()
}
```
参见:[WaitGroup](https://golang.org/pkg/sync/#WaitGroup)
### Closing channels
```go
ch <- 1
ch <- 2
ch <- 3
close(ch) // 关闭频道
```
---
```go
// 迭代通道直到关闭
for i := range ch {
···
}
```
---
```go
// Closed if `ok == false`
v, ok := <- ch
```
参见:[范围和关闭](https://tour.golang.org/concurrency/4)
### 缓冲通道
```go
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// 致命错误:
// 所有 goroutine 都处于休眠状态 - 死锁
```
参见:[缓冲通道](https://tour.golang.org/concurrency/3)
Golang 错误控制
--------
### 延迟函数
```go
func main() {
defer func() {
fmt.Println("Done")
}()
fmt.Println("Working...")
}
```
### Lambda defer
```go
func main() {
var d = int64(0)
defer func(d *int64) {
fmt.Printf("& %v Unix Sec\n", *d)
}(&d)
fmt.Print("Done ")
d = time.Now().Unix()
}
```
`defer` 函数使用当前值`d`,除非我们使用指针在 `main` 末尾获取最终值
### Defer
```go
func main() {
defer fmt.Println("Done")
fmt.Println("Working...")
}
```
参见:[Defer, panic and recover](https://blog.golang.org/defer-panic-and-recover)
Golang 方法(Methods)
--------
<!--rehype:body-class=cols-2-->
### 接收器
```go
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v := Vertex{1, 2}
v.Abs()
```
参见:[Methods](https://tour.golang.org/methods/1)
### Mutation
```go
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// `v` 已更新
```
参见:[指针接收器](https://tour.golang.org/methods/4)
Golang 接口(Interfaces)
--------
<!--rehype:body-class=cols-2-->
### 基本接口(Interfaces)
```go
type Shape interface {
Area() float64
Perimeter() float64
}
```
### 结构(Struct)
```go
type Rectangle struct {
Length, Width float64
}
```
结构 `Rectangle` 通过实现其所有方法隐式实现接口 `Shape`
### 方法(Methods)
```go
func (r Rectangle) Area() float64 {
return r.Length * r.Width
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Length + r.Width)
}
```
`Shape` 中定义的方法在`Rectangle`中实现
### 接口实例
```go
func main() {
var r Shape = Rectangle{Length: 3, Width: 4}
fmt.Printf("Type of r: %T, Area: %v, Perimeter: %v.", r, r.Area(), r.Perimeter())
}
```
<!--rehype:className=wrap-text -->
杂项
-------------
### 关键字(Keywords)
- break
- default
- func
- interface
- select
- case
- defer
- go
- map
- struct
- chan
- else
- goto
- package
- switch
- const
- fallthrough
- if
- range
- type
- continue
- for
- import
- return
- var
<!--rehype:className=cols-3 style-none-->
### 运算符和标点符号
| | | | | | | | | |
| --- | ---- | ----- | ----- | ------ | ---- | ----- | --- | --- |
| `+` | `&` | `+=` | `&=` | `&&` | `==` | `!=` | `(` | `)` |
| `-` | `\|` | `-=` | `\|=` | `\|\|` | `<` | `<=` | `[` | `]` |
| `*` | `^` | `*=` | `^=` | `<-` | `>` | `>=` | `{` | `}` |
| `/` | `<<` | `/=` | `<<=` | `++` | `=` | `:=` | `,` | `;` |
| `%` | `>>` | `%=` | `>>=` | `--` | `!` | `...` | `.` | `:` |
| | `&^` | `&^=` | | | | | | |
另见
--------
- [Devhints](https://devhints.io/go) _(devhints.io)_
- [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_
- [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_
- [Effective Go](https://golang.org/doc/effective_go.html) _(golang.org)_
- [Go by Example](https://gobyexample.com/) _(gobyexample.com)_
- [Awesome Go](https://awesome-go.com/) _(awesome-go.com)_
- [JustForFunc Youtube](https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw) _(youtube.com)_
- [Style Guide](https://github.com/golang/go/wiki/CodeReviewComments) _(github.com)_

653
docs/graphql.md Normal file
View File

@ -0,0 +1,653 @@
GraphQL 备忘清单
===
这份快速参考备忘单提供了 [GraphQL](https://graphql.org/) 的简要概述
入门
---
### 概述
- RESTful API 的另一种方法
- GraphQL 是一种 API 查询语言
- 使用清晰的共享术语轻松描述 GraphQL API 的形状。
- 客户端发出查询/突变以读取和更新数据
- GraphQL 语法可以表达复杂的实体关系
- 用 [不同语言](https://graphql.org/code/) 实现 GraphQL 的库
[GraphQL](https://graphql.org/)
### Schema
:-|-
:-|-
`schema` | GraphQL 架构定义
`query` | 读取和遍历数据
`mutation` | 修改数据或触发动作
`subscription` | 发生事件时运行查询
### 内置标量类型
:-|-
:-|-
`Int` | 有符号 32 位整数
`Float` | 有符号双精度浮点值
`String` | UTF-8 字符序列
`Boolean` | 对或错布尔值类型
`ID` | 唯一标识符
### 类型定义
:-|-
:-|-
`scalar` | 标量类型
`type` | 对象类型
`interface` | 接口类型
`union` | 联合类型
`enum` | 枚举类型
`input` | 输入对象类型
### 类型修饰符
:-|-
:-|-
`String` | 可空字符串
`String!` | 非空字符串
`[String]` | 可空字符串列表
`[String]!` | 可空字符串的非空列表
`[String!]!` | 非空字符串的非空列表
### 输入参数
<!--rehype:wrap-class=row-span-2-->
#### 基本输入
```graphql
type Query {
users(limit: Int): [User]
}
```
#### 输入默认值
```graphql
type Query {
users(limit: Int = 10): [User]
}
```
#### 具有多个参数的输入
```graphql
type Query {
users(limit: Int, sort: String): [User]
}
```
#### 具有多个参数和默认值的输入
```graphql
type Query {
users(limit: Int = 10, sort: String): [User]
}
type Query {
users(limit: Int, sort: String = "asc"): [User]
}
type Query {
users(limit: Int = 10, sort: String = "asc"): [User]
}
```
<!--rehype:className=wrap-text -->
### 输入类型
```graphql
input ListUsersInput {
limit: Int
since_id: ID
}
```
```graphql
type Mutation {
users(params: ListUsersInput): [User]!
}
```
### 自定义标量
```graphql
scalar Url
type User {
name: String
homepage: Url
}
```
### 接口
```graphql
interface Foo {
is_foo: Boolean
}
interface Goo {
is_goo: Boolean
}
type Bar implements Foo {
is_foo: Boolean
is_bar: Boolean
}
type Baz implements Foo, Goo {
is_foo: Boolean
is_goo: Boolean
is_baz: Boolean
}
```
实现一个或多个接口的对象
### 联合
```graphql
type Foo {
name: String
}
type Bar {
is_bar: String
}
union SingleUnion = Foo
union MultipleUnion = Foo | Bar
type Root {
single: SingleUnion
multiple: MultipleUnion
}
```
一个或多个对象的联合
### 枚举
```graphql
enum USER_STATE {
NOT_FOUND
ACTIVE
INACTIVE
SUSPENDED
}
type Root {
stateForUser(userID: ID!): USER_STATE!
users(state: USER_STATE, limit: Int = 10): [User]
}
```
<!--rehype:className=wrap-text -->
查询和变更(Mutations)
---
### 字段
```graphql
{
hero {
name
}
}
```
结果:
```json
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
```
### 查询可以有注释
```graphql
{
hero {
name
# 查询可以有注释!
friends {
name
}
}
}
```
结果:
```json
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Han Solo" }
]
}
}
}
```
### 参数 Arguments
```graphql
{
human(id: "1000") {
name
height
}
}
```
结果:
```json
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 1.72
}
}
}
```
### 不同类型的参数
```graphql
{
human(id: "1000") {
name
height(unit: FOOT)
}
}
```
结果:
```json
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 5.6430448
}
}
}
```
### 别名(Aliases)
```graphql
{
empireHero: hero(episode: EMPIRE) {
name
}
jediHero: hero(episode: JEDI) {
name
}
}
```
结果:
```json
{
"data": {
"empireHero": {
"name": "Luke Skywalker"
},
"jediHero": {
"name": "R2-D2"
}
}
}
```
### 片段(Fragments)
<!--rehype:wrap-class=row-span-2-->
```graphql
{
leftComparison: hero(episode: EMPIRE) {
...comparisonFields
}
rightComparison: hero(episode: JEDI) {
...comparisonFields
}
}
fragment comparisonFields on Character {
name
appearsIn
friends {
name
}
}
```
结果:
```json
{
"data": {
"leftComparison": {
"name": "Luke Skywalker",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{ "name": "Han Solo" },
{ "name": "Leia Organa" },
{ "name": "C-3PO" },
{ "name": "R2-D2" }
]
},
"rightComparison": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Han Solo" },
{ "name": "Leia Organa" }
]
}
}
}
```
### 在片段内使用变量
<!--rehype:wrap-class=row-span-3-->
```graphql
query HeroComparison($first: Int = 3) {
leftComparison: hero(episode: EMPIRE) {
...comparisonFields
}
rightComparison: hero(episode: JEDI) {
...comparisonFields
}
}
fragment comparisonFields on Character {
name
friendsConnection(first: $first) {
totalCount
edges {
node {
name
}
}
}
}
```
结果:
```json
{
"data": {
"leftComparison": {
"name": "Luke Skywalker",
"friendsConnection": {
"totalCount": 4,
"edges": [
{
"node": {
"name": "Han Solo"
}
},
{
"node": {
"name": "Leia Organa"
}
}
]
}
},
"rightComparison": {
"name": "R2-D2",
"friendsConnection": {
"totalCount": 3,
"edges": [
{
"node": {
"name": "Luke Skywalker"
}
},
{
"node": {
"name": "Han Solo"
}
}
]
}
}
}
}
```
### 操作名称(Operation name)
```graphql
query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}
```
结果:
```json
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Han Solo" },
{ "name": "Leia Organa" }
]
}
}
}
```
### 变量(Variables)
```graphql
# { "graphiql": true, "variables": { "episode": JEDI } }
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
```
<!--rehype:className=wrap-text -->
变量前缀必须为 `$`,后跟其类型
### 默认变量(Default variables)
```graphql
query HeroNameAndFriends($episode: Episode = "JEDI") {
hero(episode: $episode) {
name
friends {
name
}
}
}
```
<!--rehype:className=wrap-text -->
### 指令(Directives)
```graphql
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends @include(if: $withFriends) {
name
}
}
}
```
<!--rehype:className=wrap-text -->
----
```graphql
{ "episode": "JEDI", "withFriends": false }
```
结果:
```json
{
"data": { "hero": { "name": "R2-D2" } }
}
```
- `@include(if: Boolean)` 仅在参数为 `true` 时,包含此字段
- `@skip(if: Boolean)` 如果参数为 `true`,跳过此字段
### 变更(Mutations)
```graphql
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
```
<!--rehype:className=wrap-text -->
----
```
{
"ep": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
```
结果:
```json
{
"data": {
"createReview": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
}
```
### 内联片段(Inline Fragments)
```graphql
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
... on Human {
height
}
}
}
```
----
```graphql
{ "ep": "JEDI" }
```
结果:
```json
{
"data": {
"hero": {
"name": "R2-D2",
"primaryFunction": "Astromech"
}
}
}
```
### 元字段(Meta fields)
```graphql
{
search(text: "an") {
__typename
... on Human {
name
}
... on Droid {
name
}
... on Starship {
name
}
}
}
```
结果:
```json
{
"data": {
"search": [
{
"__typename": "Human",
"name": "Han Solo"
},
{
"__typename": "Human",
"name": "Leia Organa"
},
{
"__typename": "Starship",
"name": "TIE Advanced x1"
}
]
}
}
```
另见
-------
- [GraphQL Schema Language Cheat Sheet](https://github.com/sogko/graphql-schema-language-cheat-sheet) _(github.com)_

175
docs/grep.md Normal file
View File

@ -0,0 +1,175 @@
Grep 备忘清单
===
本备忘单旨在快速提醒使用命令行程序 grep 所涉及的主要概念,并假设您已经了解其用法。
入门
------
<!--rehype:body-class=cols-5-->
### 使用
<!--rehype:wrap-class=col-span-2-->
搜索标准输出(即文本流)
```shell
$ grep [options] search_string
```
在文件中搜索确切的字符串:
```shell
$ grep [options] search_string path/to/file
```
打印 myfile.txt 中包含字符串“mellon”的行
```shell
$ grep 'mellon' myfile.txt
```
文件名中接受通配符。
### 选项示例
<!--rehype:wrap-class=col-span-3-->
选项 | 示例 | 说明
:-|:-|:-
| `-i` | grep -i ^DA demo.txt | 忘记区分大小写
| `-w` | grep -w "of" demo.txt | 仅搜索完整的单词
| `-A` | grep -A 3 'Exception' error.log | 匹配字符串后显示 3 行
| `-B` | grep -B 4 'Exception' error.log | 在匹配字符串前显示 4 行
| `-C` | grep -C 5 'Exception' error.log | 在匹配字符串周围显示 5 行
| `-r` | grep -r 'github.io' /var/log/nginx/ | 递归搜索 _(在子目录内)_
| `-v` | grep -v 'warning' /var/log/syslog | 返回所有与模式不匹配的行
| `-e` | grep -e '^al' filename | 使用正则表达式 _(以'al'开头的行)_
| `-E` | grep -E 'ja(s\|cks)on' filename | 扩展正则表达式 _(包含 jason 或 jackson 的行)_
| `-c` | grep -c 'error' /var/log/syslog | 计算匹配数
| `-l` | grep -l 'robot' /var/log/* | 打印匹配文件的名称
| `-o` | grep -o search_string filename | 只显示字符串的匹配部分
| `-n` | grep -n "go" demo.txt | 显示匹配的行号
Grep 正则表达式
-------
### 参考
- [Regex syntax](./regex.md) _(jaywcjlove.github.io)_
- [Regex examples](./regex.md#正则表达式示例) _(jaywcjlove.github.io)_
有关更复杂的要求,请参阅完整版的正则表达式备忘单。
### 通配符(Wildcards)
:- | :-
:- | :-
`.` | 任何字符
`?` | 可选且只能出现一次
`*` | 可选的,可以多次出现
`+` | 必需并且可以多次出现
### 量词(Quantifiers)
:- | :-
:- | :-
`{n}` | 前一项恰好出现 n 次
`{n,}` | 上一个项目出现 n 次或更多
`{,m}` | 上一个项目最多出现 n 次
`{n,m}` | 上一项出现在 n 到 m 次之间
### POSIX
:- | :-
:- | :-
`[:alpha:]` | 任何大小写字母
`[:digit:]` | 任何数字
`[:alnum:]` | 任何大小写字母或数字
`[:space:]` | 任何空格
### 字符串
:- | :-
:- | :-
`[A-Z­a-z]` | 任何大小写字母
`[0-9]` | 任何数字
`[0-9­A-Z­a-z]` | 任何大小写字母或数字
### 位置
:- | :-
:- | :-
`^` | 行的开头
`$` | 行结束
`^$` | 空行
`\<` | 词的开头
`\>` | 词尾
更多示例
----
### 搜索命令行历史记录
```bash
history | grep git
```
输入过 `git` 命令的记录
### 搜索多个文件并查找匹配文本在哪些文件中
```bash
grep -l "text" file1 file2 file3...
```
### 多级目录中对文本进行递归搜索
```bash
grep "text" . -r -n
```
`.` 表示当前目录。
### 搜索结果中包括或者排除指定文件
<!--rehype:wrap-class=row-span-2-->
```bash
# 目录中所有的 .php 和 .html 文件中
# 递归搜索字符 "main()"
grep "main()" . -r --include *.{php,html}
# 在搜索结果中排除所有 README 文件
grep "main()" . -r --exclude "README"
# 在搜索结果中排除 filelist 文件列表里的文件
grep "main()" . -r --exclude-from filelist
```
### 输出包含匹配字符串的行数 -n 选项
<!--rehype:wrap-class=row-span-2-->
```bash
grep "text" -n file_name
# 或
cat file_name | grep "text" -n
#多个文件
grep "text" -n file_1 file_2
```
### 忽略匹配样式中的字符大小写
```bash
echo "hello world" | grep -i "HELLO"
# hello
```
### 统计文件或文本中包含匹配字符串的行数 -c 选项
```
grep -c "text" file_name
```
另见
----
- [grep 中文文档](https://wangchujiang.com/linux-command/c/grep.html) _(jaywcjlove.github.io)_

132
docs/homebrew.md Normal file
View File

@ -0,0 +1,132 @@
Homebrew 备忘清单
===
Homebrew 是 macOS(或Linux)缺少的包管理器,备忘清单包含 [brew](https://github.com/Homebrew/brew) 命令的使用与安装
Homebrew
---
### 安装
<!--rehype:wrap-class=row-span-3-->
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
<!--rehype:className=wrap-text -->
加速安装和更新,将仓库源码通过 [gitee](https://gitee.com/) 同步到国内,这样速度杠杠的
```bash
# 把 Homebrew/brew 的 Git 镜像放在这里
export HOMEBREW_BREW_GIT_REMOTE="..."
# 将 Homebrew/homebrew-core 的 Git 镜像放在这里
export HOMEBREW_CORE_GIT_REMOTE="..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
<!--rehype:className=wrap-text -->
在安装期间跳过克隆 (beta)
```bash
export HOMEBREW_INSTALL_FROM_API=1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
<!--rehype:className=wrap-text -->
### 命令
命令 | 说明
:--- :---
`brew install git` | `安装`一个包
`brew reinstall git` | 重新`安装`一个包
`brew uninstall git` | `删除`/`卸载`软件包
`brew upgrade git` | 升级包
:--- :---
`brew unlink git` | `取消`链接
`brew link git` | 关联
`brew switch git 2.5.0` | 更改版本
:--- :---
`brew list --versions git` | 看看你有什么版本
### 更多包命令
命令 | 说明
:--- :---
`brew info git` | 列出版本、注意事项等
`brew cleanup git` | 删除旧版本
`brew edit git` | 编辑此软件包
`brew cat git` | 打印这个软件包
`brew home git` | 打开主页
`brew search git` | 搜索公式
### Brew Cask 命令
命令 | 说明
:--- :---
`brew install --cask firefox` | 安装火狐浏览器
`brew list --cask` | 列出已安装应用
Cask 命令用于与图形应用程序交互
### 全局命令
<!--rehype:wrap-class=row-span-2-->
命令 | 说明
:--- :---
`brew update` | 更新 `brew``cask`
`brew upgrade` | 升级所有软件包
`brew list` | 已安装列表
`brew outdated` | 升级需要什么?
`brew doctor` | 诊断冲泡问题
`brew pin <formula>` | 防止指定软件包升级
`brew unpin <formula>` | 允许升级指定的软件包
### Brew 清理
```bash
$ brew cleanup # 删除旧版本的已安装软件包
$ brew cleanup <formula> # 删除旧版本指定软件包
# 显示所有将被删除的软件包(试运行)
$ brew cleanup -n
```
### brew 源码仓库
```bash
# 列出所有当前点击的源码仓库(点击)
$ brew tap
# 使用 https 从 Github 中点击软件包源码仓库以点击
# https://github.com/user/homebrew-repo
$ brew tap <user/repo>
# 点击指定 URL 中的软件源码仓库
$ brew tap <user/repo> <URL>
# 从存储库中删除给定的源码仓库
$ brew untap <user/repo>
```
### 搜索查看
```bash
# 列出所有已安装的软件包
$ brew list
# 显示所有本地可用的 brew 配方
$ brew search
# 对用于 brew 的软件包名称执行子字符串搜索
$ brew search <text>
# 显示有关软件包的信息
$ brew info <formula>
```
### 帮助命令
命令 | 说明
:--- :---
`brew help` | 打印帮助信息
`brew help <sub-command>` | 打印子命令的帮助信息
另见
---
- [Homebrew 官网](https://brew.sh/index_zh-cn) _(brew.sh)_
- [Homebrew brew 源码](https://github.com/Homebrew/brew) _(github.com)_
- [Homebrew core 源码](https://github.com/Homebrew/homebrew-core) _(github.com)_

View File

@ -3,7 +3,6 @@ HTML 字符实体备忘清单
此备忘清单是 HTML 实体及其编号和名称的完整列表。还包括可以用 HTML 表示的 ASCII 字符的完整列表。
HTML 字符实体引用
------
<!--rehype:body-class=cols-1-->
@ -360,4 +359,4 @@ HTML 字符实体引用
另见
---
- [HTML 字符集实体](https://jaywcjlove.github.io/html-tutorial/reference/charactersets_entities.html)
- [HTML 字符集实体](https://jaywcjlove.github.io/html-tutorial/reference/charactersets_entities.html)

895
docs/html.md Normal file
View File

@ -0,0 +1,895 @@
HTML 备忘清单
===
此 HTML 快速参考备忘单以可读布局列出了常见的 `HTML``HTML5` 标记。
入门
------------
### hello.html
<!--rehype:wrap-class=col-span-2 row-span-2-->
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 Boilerplate</title>
</head>
<body>
<h1>Hello world, hello 备忘清单!</h1>
</body>
</html>
```
或者在 [jsfiddle](https://jsfiddle.net/Randy8080/1e4wz20b/)
### 注释 Comment
```html
<!-- 这是代码注释 -->
<!--
或者你可以注释掉一个
大量的行。
-->
```
### 段落 Paragraph
```html
<p>我来自快速参考</p>
<p>分享快速参考备忘单。</p>
```
请参阅:[段落元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/p)
### HTML 链接
```html
<a href="https://github.com/jaywcjlove/reference">
Github
</a>
<a href="mailto:jack@abc.com">邮箱</a>
<a href="tel:+123456789">电话</a>
<a href="sms:+123456789&body=ha%20ha">
短信
</a>
```
---
:-|:-
:-|:-
`href` | 超链接指向的 URL |
`rel` | 链接 URL 的关系 |
`target` | 链接目标位置:`_self`/`_blank`/`_top`/`_parent` |
请参阅:[\<a> 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a#attributes)
### Image 标签
```html
<img loading="lazy"
src="https://xxx.png"
alt="在此处描述图像"
width="400" height="400">
```
<!--rehype:className=wrap-text -->
---
| | | |
|---|-----------|------------------------------------------|
| | `src` _(URL/路径)_ | 必填,图片位置 |
| | `alt` | 描述图像 |
| | `width` | 图像宽度 |
| | `height` | 图像高度 |
| | `loading` | 浏览器应该如何加载 |
请参阅:[图像嵌入元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img)
### 文本格式标签
```html
<b>粗体文字</b>
<strong>这段文字很重要</strong>
<i>斜体文本</i>
<em>这段文字被强调</em>
<u>下划线文本</u>
<pre>预格式化文本</pre>
<code>源代码</code>
<del>删除的文字</del>
<mark>突出显示的文本 (HTML5)</mark>
<ins>插入的文本</ins>
<sup>使文本上标</sup>
<sub>使文本下标</sub>
<small>使文本变小</small>
<pre>预格式化文本</pre>
<kbd>Ctrl</kbd>
<blockquote>文本块引用</blockquote>
```
### 标题
```html
<h1> 这是标题 1 </h1>
<h2> 这是标题 2 </h2>
<h3> 这是标题 3 </h3>
<h4> 这是标题 4 </h4>
<h5> 这是标题 5 </h5>
<h6> 这是标题 6 </h6>
```
您的页面上应该只有一个 `h1`
### Section Divisions
:-|:-
:-|:-
`<div></div>` | 页面内容的划分或部分
`<span></span>` | 其他内容中的文本部分
`<p></p>` | 文本段落
`<br>` | 换行
`<hr>` | 水平分割线
这些标签用于将页面划分为多个部分
### 内部框架
<!--rehype:wrap-class=row-span-2-->
```html
<iframe
id="inlineFrameExample"
title="Inline Frame Example"
width="100%"
height="200"
frameborder="0"
src="https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik">
</iframe>
```
<!--rehype:className=wrap-text -->
#### ↓ 预览
<iframe id="inlineFrameExample"
title="Inline Frame Example"
width="100%"
height="200"
frameborder="0"
src="https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik">
</iframe>
请参阅:[内联框架元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe)
### HTML 中的 JavaScript
```html
<script type="text/javascript">
let text = "Hello 快速参考";
alert(text);
</script>
```
#### 外部 JavaScript
```html
<body>
...
<script src="app.js"></script>
</body>
```
### HTML 中的 CSS
```html
<style type="text/css">
h1 {
color: purple;
}
</style>
```
#### 外部样式表
```html
<head>
...
<link rel="stylesheet" href="style.css"/>
</head>
```
HTML5 标签
-------------
### 页面
```html
<body>
<header>
<nav>...</nav>
</header>
<main>
<h1>快速参考</h1>
</main>
<footer>
<p>©2023 快速参考</p>
</footer>
</body>
```
### 标题导航
```html
<header>
<nav>
<ul>
<li><a href="#">编辑页面</a></li>
<li><a href="#">Twitter</a></li>
<li><a href="#">Facebook</a></li>
</ul>
</nav>
</header>
```
### HTML5 Tags
<!--rehype:wrap-class=row-span-4-->
:-|:-
:-|:-
[article](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/article) | 独立的内容
[aside](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/aside) | 次要内容
[audio](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/audio) | 嵌入声音或音频流
[bdi](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/bdi) | 双向隔离元件
[canvas](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/canvas) | 通过JavaScript绘制图形
[data](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/data) | 机器可读内容
[datalist](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/datalist) | 一组预定义选项
[details](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/details) | 其他信息
[dialog](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/dialog) | 对话框或子窗口
[embed](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/embed) | 嵌入外部应用程序
[figcaption](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/figcaption) | 图形的标题或图例
[figure](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/figure) | 插图
[footer](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/footer) | 页脚或最不重要的
[header](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/header) | 刊头或重要信息
[main](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/main) | 文件的主要内容
[mark](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/mark) | 突出显示的文本
[meter](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/meter) | 已知范围内的标量值
[nav](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/nav) | 导航链接的一部分
[output](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/output) | 计算的结果
[picture](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/picture) | 用于多个图像源的容器
[progress](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/progress) | 任务的完成进度
[rp](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/rp) | 提供回退括号
[rt](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/rt) | 定义字符的发音
[ruby](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/ruby) | 表示ruby注释
[section](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/section) | 一系列相关内容中的组
[source](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/source) | 媒体元素的资源
[summary](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/summary) | 元素的摘要
[template](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/template) | 定义HTML片段
[time](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/time) | 时间或日期
[track](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/track) | 媒体元素的字幕信息
[video](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video) | 嵌入视频
[wbr](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/wbr) | 换行机会
### HTML5 Video
```html
<video controls="" width="100%">
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
很抱歉,您的浏览器不支持嵌入式视频。
</video>
```
<!--rehype:className=wrap-text -->
#### ↓ 预览
<video controls="" width="100%">
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
很抱歉,您的浏览器不支持嵌入式视频。
</video>
### HTML5 Audio
```html
<audio
controls
src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3">
您的浏览器不支持音频元素。
</audio>
```
<!--rehype:className=wrap-text -->
#### ↓ 预览
<audio controls
src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3">
您的浏览器不支持音频元素。
</audio>
### HTML5 Ruby
```html
<ruby>
<rp>(</rp><rt>hàn</rt><rp>)</rp>
<rp>(</rp><rt></rt><rp>)</rp>
<rp>(</rp><rt>pīn</rt><rp>)</rp>
<rp>(</rp><rt>yīn</rt><rp>)</rp>
</ruby>
```
<!--rehype:className=wrap-text -->
#### ↓ 预览
<!--rehype:wrap-style=text-align: center;-->
<ruby style="font-size: 4rem;">
<rp>(</rp><rt>hàn</rt><rp>)</rp>
<rp>(</rp><rt></rt><rp>)</rp>
<rp>(</rp><rt>pīn</rt><rp>)</rp>
<rp>(</rp><rt>yīn</rt><rp>)</rp>
</ruby>
### HTML5 kdi
```html
<ul>
<li>User <bdi>hrefs</bdi>: 60 points</li>
<li>User <bdi>jdoe</bdi>: 80 points</li>
<li>User <bdi>إيان</bdi>: 90 points</li>
</ul>
```
#### ↓ 预览
<ul>
<li>User <bdi>hrefs</bdi>: 60 points</li>
<li>User <bdi>jdoe</bdi>: 80 points</li>
<li>User <bdi>إيان</bdi>: 90 points</li>
</ul>
### HTML5 progress
```html
<progress value="50" max="100"></progress>
```
<progress value="50" max="100" style="width: 100%"></progress>
### HTML5 mark
```html
<p>我爱<mark>备忘清单</mark></p>
```
<p>我爱<mark>备忘清单</mark></p>
HTML 表格
--------------
### Table 示例
<!--rehype:wrap-class=row-span-2-->
```html
<table>
<thead>
<tr>
<td>name</td>
<td>age</td>
</tr>
</thead>
<tbody>
<tr>
<td>Roberta</td>
<td>39</td>
</tr>
<tr>
<td>Oliver</td>
<td>25</td>
</tr>
</tbody>
</table>
```
### HTML表格标签
<!--rehype:wrap-class=row-span-2-->
标签|说明
:-|:-
[\<table>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/table) | 定义表格
[\<th>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/th) | 定义表格中的标题单元格
[\<tr>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/tr) | 定义表中的行
[\<td>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/td) | 定义表格中的单元格
[\<caption>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/caption) | 定义表格标题
[\<colgroup>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/colgroup) | 定义一组列
[\<col>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/col) | 定义表中的列
[\<thead>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/thead) | 对标题内容进行分组
[\<tbody>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/tbody) | 将正文内容分组
[\<tfoot>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/tfoot) | 对页脚内容进行分组
### \<td> 属性
属性|说明
:-|:-
`colspan` | 单元格应跨越的列数
`headers` | 单元格与一个或多个标题单元格相关
`rowspan` | 单元格应跨越的行数
请参阅:[td\#属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/td#attributes)
### \<th> 属性
属性|说明
:-|:-
`colspan` | 单元格应跨越的列数
`headers` | 单元格与一个或多个标题单元格相关
`rowspan` | 单元格应跨越的行数
`abbr` | 单元格内容的描述
[scope](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/th#attr-scope) | 表头元素(在\<th>中定义)关联的单元格
请参阅:[th\#属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/th#attributes)
HTML 列表
----
### 无序列表
```html
<ul>
<li>I'm an item</li>
<li>I'm another item</li>
<li>I'm another item</li>
</ul>
```
请参阅:[无序列表元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/ul)
### 有序列表
```html
<ol>
<li>I'm the first item</li>
<li>I'm the second item</li>
<li>I'm the third item</li>
</ol>
```
请参阅:[有序列表元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/ol)
### 定义列表
```html
<dl>
<dt>A Term</dt>
<dd>Definition of a term</dd>
<dt>Another Term</dt>
<dd>Definition of another term</dd>
</dl>
```
请参阅:[描述列表元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/dl)
HTML 表单
-----------
### Form 标签
<!--rehype:wrap-class=row-span-2-->
```html
<form method="POST" action="api/login">
<label for="mail">邮箱: </label>
<input type="email" id="mail" name="mail">
<br/>
<label for="pw">密码:</label>
<input type="password" id="pw" name="pw">
<br/>
<input type="submit" value="登录">
<br/>
<input type="checkbox" id="ck" name="ck">
<label for="ck">记住我</label>
</form>
```
#### ↓ 预览
<form method="POST" action="api/login" style="padding: 20px;">
<label for="email">邮箱: </label>
<input type="email" id="email" name="email" class="border border-slate-400 mt-2">
<br/>
<label for="pwd">密码:</label>
<input type="password" id="pwd" name="pwd" class="border border-slate-400 mt-2">
<br/>
<input type="submit" value="登录" class="mt-2">
<br/>
<input type="checkbox" id="ck" name="ck" class="mt-2">
<label for="ck">记住我</label>
</form>
HTML `<form>` 元素用于收集信息并将其发送到外部源。
### Form 属性
属性|说明
:-|:-
`name` | 脚本形式的名称
`action` | 表单脚本的URL
`method` | HTTP方法`POST`/`GET` _(默认)_
`enctype` | 介质类型,请参见[enctype](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLFormElement/enctype)
`onsubmit` | 提交表单时运行
`onreset` | 在窗体重置时运行
### Label 标签
```html
<!-- 嵌套标签 -->
<label>Click me
<input type="text" id="user" name="name"/>
</label>
```
---
```html
<!-- 'for' 属性 -->
<label for="user">Click me</label>
<input id="user" type="text" name="name"/>
```
`for`在标签中引用输入的`id`属性
### Input 标签
```html
<label for="Name">Name:</label>
<input type="text" name="Name" id="">
```
#### ↓ 预览
<form style="padding: 20px;">
<label for="username">Username:</label>
<input type="text" name="username" id="username" class="border border-slate-400">
</form>
请参阅:[HTML输入标记](/html#html-input-tags)
### Textarea 标签
```html
<textarea rows="2" cols="30" name="address" id="address"></textarea>
```
<!--rehype:className=wrap-text -->
#### ↓ 预览
<form style="padding: 20px;">
<textarea rows="2" cols="30" name="address" id="address" class="border border-slate-400"style="width: 100%"></textarea>
</form>
Textarea 是一个多行文本输入控件
### Radio Buttons
```html
<input type="radio" name="gender" id="m">
<label for="m">Male</label>
<input type="radio" name="gender" id="f">
<label for="f">Female</label>
```
#### ↓ 预览
<form style="padding: 20px;">
<input type="radio" name="gender" id="m">
<label for="m">Male</label>
<input type="radio" name="gender" id="f">
<label for="f">Female</label>
</form>
单选按钮用于让用户只选择一个
### Checkboxes
```html
<input type="checkbox" name="s" id="soc">
<label for="soc">Soccer</label>
<input type="checkbox" name="s" id="bas">
<label for="bas">Baseball</label>
```
#### ↓ 预览
<form style="padding: 20px;">
<input type="checkbox" name="sports" id="soccer">
<label for="soccer">Soccer</label>
<input type="checkbox" name="sports" id="baseball">
<label for="baseball">Baseball</label>
</form>
复选框允许用户选择一个或多个
### Select 标签
```html
<label for="city">City:</label>
<select name="city" id="city">
<option value="1">Sydney</option>
<option value="2">Melbourne</option>
<option value="3">Cromwell</option>
</select>
```
#### ↓ 预览
<form style="padding: 20px">
<label for="city">City:</label>
<select name="city" id="city" class="border border-slate-400">
<option value="1">Sydney</option>
<option value="2">Melbourne</option>
<option value="3">Cromwell</option>
</select>
</form>
选择框是选项的下拉列表
### Fieldset 标签
```html
<fieldset>
<legend>Your favorite monster</legend>
<input type="radio" id="kra" name="m">
<label for="kraken">Kraken</label><br/>
<input type="radio" id="sas" name="m">
<label for="sas">Sasquatch</label>
</fieldset>
```
#### ↓ 预览
<form style="padding: 20px">
<fieldset class="border border-slate-400" style="padding: 20px">
<legend>Your favorite monster</legend>
<input type="radio" id="kra" name="monster">
<label for="kra">Kraken</label><br/>
<input type="radio" id="sas" name="monster">
<label for="sas">Sasquatch</label>
</fieldset>
</form>
### 数据列表标签HTML5
```html
<label for="b">Choose a browser: </label>
<input list="list" id="b" name="browser"/>
<datalist id="list">
<option value="Chrome">
<option value="Firefox">
<option value="Internet Explorer">
<option value="Opera">
<option value="Safari">
<option value="Microsoft Edge">
</datalist>
```
#### ↓ 预览
<form style="padding: 20px">
<label for="myBrowser">Choose a browser:</label>
<input list="browsers" id="myBrowser" name="myBrowser"/>
<datalist id="browsers">
<option value="Chrome">
<option value="Firefox">
<option value="Internet Explorer">
<option value="Opera">
<option value="Safari">
<option value="Microsoft Edge">
</datalist>
</form>
### 提交和重置按钮
```html
<form action="register.php" method="post">
<label for="foo">Name:</label>
<input type="text" name="name" id="foo">
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
```
#### ↓ 预览
<form action="register.php" method="post" style="padding: 20px">
<label for="name">Name:</label>
<input type="text" name="name" id="name"">
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
`将数据提交到服务器` 重置为默认值
HTML input 标签
-----------
<!--rehype:body-class=cols-2-->
### Input 属性
<!--rehype:wrap-class=row-span-2-->
输入标记是一个空元素,用于标识要从用户处获取的特定类型的字段信息。
```html
<input type="text" name="?" value="?" minlength="6" required />
```
---
:-|:-
:-|:-
`type="…"` | 正在输入的数据类型
`value="…"` | 默认值
`name="…"` | 用于在 HTTP 请求中描述此数据
`id="…"` | 其他 HTML 元素的唯一标识符
`readonly` | 停止用户修改
`disabled` | 停止任何交互
`checked` | 单选或复选框是否选中
`required` | 是强制性的,参阅[必填](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/required#example)
`placeholder="…"` | 添加临时,请参阅[::placeholder](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::placeholder#examples)
`autocomplete="off"` | 禁用自动完成
`autocapitalize="none"` | 禁用自动大写
`inputmode="…"` | 显示特定键盘,请参阅[inputmode](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/inputmode)
`list="…"` | 关联的[datalist](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/datalist)的id
`maxlength="…"` | 最大字符数
`minlength="…"` | 最小字符数
`min="…"` | 范围和编号上的最小数值
`max="…"` | 范围和编号上的最大数值
`step="…"` | 数字如何在范围和数字中递增
`pattern="…"` | 指定一个[正则表达式](./regex.md),请参阅[pattern](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/pattern)
`autofocus` | 集中精力
`spellcheck` | 执行拼写检查
`multiple` | 是否允许[多个](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/multiple)值
`accept=""` | [file](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file) 中需要文件类型上载控件
请参阅:[\<input>元素 的属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input#attributes)
### Input 类型
| | |
|---------------|------------------|
`type="checkbox"` | <input type="checkbox">
`type="radio"` | <input type="radio">
`type="file"` | <input type="file">
`type="hidden"` | <input type="hidden">
`type="text"` | <input type="text">
`type="password"` | <input type="password">
`type="image"` | <input type="image" src="https://raw.githubusercontent.com/mdn/learning-area/master/html/forms/image-type-example/login.png" width="70">
`type="reset"` | <input type="reset">
`type="button"` | <input type="button">
`type="submit"` | <input type="submit">
#### HTML5 中的新输入类型
| | |
|---------------|------------------|
| `type="color"` | <input type="color" value="#0FB881"> |
| `type="date"` | <input type="date"> |
| `type="time"` | <input type="time"> |
| `type="month"` | <input type="month"> |
| `type="datetime-local"` | <input type="datetime-local"> |
| `type="week"` | <input type="week"> |
| `type="email"` | <input type="email"> |
| `type="tel"` | <input type="tel"> |
| `type="url"` | <input type="url"> |
| `type="number"` | <input type="number"> |
| `type="search"` | <input type="search"> |
| `type="range"` | <input type="range"> |
### Input CSS 选择器
| | |
|---------------|------------------|
| `input:focus` | 当键盘聚焦时 |
HTML meta 标签
-----------
<!--rehype:body-class=cols-2-->
### Meta 标签
<!--rehype:wrap-class=row-span-3-->
meta 标记描述 HTML 文档中的元数据。它解释了关于 HTML 的其他材料。
```html
<meta charset="utf-8">
```
```html
<!-- 标题 -->
<title>···</title>
<meta property="og:title" content="···">
<meta name="twitter:title" content="···">
```
---
```html
<!-- url -->
<link rel="canonical" href="https://···">
<meta property="og:url" content="https://···">
<meta name="twitter:url" content="https://···">
```
---
```html
<!-- 描述 -->
<meta name="description" content="···">
<meta property="og:description" content="···">
<meta name="twitter:description" content="···">
```
---
```html
<!-- image -->
<meta property="og:image" content="https://···">
<meta name="twitter:image" content="https://···">
```
---
```html
<!-- ua -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
```
---
```html
<!-- viewport -->
<meta name="viewport" content="width=device-width">
<meta name="viewport" content="width=1024">
```
### Open Graph
```html
<meta property="og:type" content="website">
<meta property="og:locale" content="en_CA">
<meta property="og:title" content="HTML cheatsheet">
<meta property="og:url" content="https://quickref.me/html">
<meta property="og:image" content="https://xxx.com/image.jpg">
<meta property="og:site_name" content="Name of your website">
<meta property="og:description" content="Description of this page">
```
Facebook、Instagram、Pinterest、LinkedIn 等使用。
### Twitter 卡片
```html
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@QuickRef_ME">
<meta name="twitter:title" content="HTML cheatsheet">
<meta name="twitter:url" content="https://quickref.me/html">
<meta name="twitter:description" content="Description of this page">
<meta name="twitter:image" content="https://xxx.com/image.jpg">
```
请参阅:[Twitter 卡片文档](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary)
### Geotagging
```html
<meta name="ICBM" content="45.416667,-75.7">
<meta name="geo.position" content="45.416667;-75.7">
<meta name="geo.region" content="ca-on">
<meta name="geo.placename" content="Ottawa">
```
请参阅:[Geotagging](https://en.wikipedia.org/wiki/Geotagging#HTML_pages)
另见
--------
- [HTML 4.01 Specification](https://www.w3.org/TR/REC-html40/cover.html#minitoc) _(w3.org)_
- [HTML Tutorial](https://wangchujiang.com/html-tutorial/) _(jaywcjlove.github.io)_
- [Emmet 备忘清单,提升 HTML 和 CSS 代码编写的工具包](./emmet.md) _(jaywcjlove.github.io)_

111
docs/htop.md Normal file
View File

@ -0,0 +1,111 @@
htop 备忘清单
===
htop 是一个交互式流程查看器,此 htop 备忘清单包含 htop 命令
入门
----
### htop 用法
htop 是一个互动的进程查看器,动态观察系统进程状况
- [命令 htop 的官网](https://htop.sourceforge.net/)
```bash
$ htop [-dChustv]
```
#### 安装
```bash
$ apt install htop # Debian
$ dnf install htop # Fedora
$ emerge sys-process/htop # Gentoo
$ pacman -S htop # Arch Linux
$ Compile htop # GoboLinux
```
htop 的软件包在大多数发行版中都[可用下载](https://htop.dev/downloads.html)
### 选项示例
<!--rehype:wrap-class=col-span-2-->
长选项的强制参数对于短选项也是强制的
:- | :-
:- | :-
`-d --delay=DELAY` | 更新之间的延迟,以十分之一秒为单位
`-C --no-color --no-colour` | 以单色模式启动 `htop`
`-h --help` | 显示帮助消息并退出
`-p --pid=PID,PID...` | 仅显示给定的PID
`-s --sort-key COLUMN` | 按此列排序(对列列表使用`--sort-key`帮助)
`-u --user=USERNAME` | 仅显示给定用户的进程
`-v --version` | 输出版本信息并退出
`-t --tree` | 在树状视图中显示流程
### 状态
:- | :-
:- | :-
`R` | 运行中
`S` | 休眠
`T` | 追踪/停止
`Z` | 僵尸
`D` | 磁盘睡眠
<!--rehype:className=shortcuts-->
### 交互式命令
<!--rehype:wrap-class=col-span-2 row-span-3-->
:- | :-
:- | :-
`F1`, `h`, `?` | 转到帮助屏幕
`F10`, `q` | 退出
`Space` | 标记或取消标记进程
`U` | 取消标记所有进程(删除所有使用 Space 键添加的标记)
`s` | 跟踪进程系统调用:如果安装了 `strace(1)`,按下此键会将其附加到当前选定的进程,呈现进程发出的系统调用的实时更新
`l` | 显示进程打开的文件:如果安装了 `lsof(1)`,按下该键将显示进程打开的文件描述符列表
`F2`, `S` | 转到设置屏幕,您可以在其中配置屏幕顶部显示的仪表,设置各种显示选项,在配色方案中进行选择,并选择显示的列,以何种顺序显示
`F3`, `/` | 逐步搜索所有显示进程的命令行。当前选定(突出显示)的命令将在您键入时更新。在搜索模式下,按 `F3` 将循环匹配出现的事件
`F4`, `\` | 增量进程过滤:输入部分进程命令行,仅显示名称匹配的进程。要取消过滤,请再次输入过滤选项并按 `Esc`
`F5`, `t` | 树视图:按父级组织进程,并将它们之间的关系布局为树。切换键将在树和您之前选择的排序视图之间切换。选择排序视图将退出树视图
`F6` | 在排序视图上,选择一个字段进行排序,也可以通过 < > 访问。当前排序字段由标题中的突出显示。在树视图中,展开或折叠当前子树。树节点中的“+”指示符表示它已折叠
`F7`, `]` | 增加所选进程的优先级(从“nice”值中减去)。这只能由超级用户完成
`F8`, `[` | 降低选定进程的优先级(添加到“nice”值)
`F9`, `k` | “杀死”进程:向一个或一组进程发送一个在菜单中选择的信号。如果进程被标记,则将信号发送到所有标记的进程。如果没有标记,则发送到当前选定的进程
`+`, `-` | 在树视图模式下,展开或折叠子树。
`a` | (在多 CPU 机器上)设置 CPU 亲和性:标记允许进程使用的 CPU
`u` | 仅显示指定用户拥有的进程
`F` | “跟随”进程:如果排序顺序导致当前选定的进程在列表中移动,则使选择栏跟随它。这对于监控进程很有用:这样,您可以使进程始终在屏幕上可见。使用移动键时,“跟随”失效。
`p` | 在适用的情况下显示运行程序的完整路径(这是一个切换键)
`Ctrl-L` | 刷新:重绘屏幕并重新计算数值
`Numbers` | PID搜索输入进程ID选择突出显示将移至它
<!--rehype:className=shortcuts-->
### 排序/线程
:- | :-
:- | :-
`M` | 按`内存`使用情况排序 _(最高兼容性键)_
`P` | 按`CPU`使用情况排序 _(最高兼容性键)_
`T` | 按`时间`排序 _(最高兼容性键)_
`I` | `反转`排序顺序
`K` | 隐藏`内核`线程
`H` | 隐藏`用户`线程
<!--rehype:className=shortcuts-->
### 滚动
:- | :-
:- | :-
`Up`, `Alt-k` | 在流程列表中选择(突出)`上`一个流程
`Down`, `Alt-j` | 在流程列表中选择(突出)`下`一个流程
`Left`, `Alt-h` | 向`左`滚动流程列表
`Right`, `Alt-l` | 向`右`滚动进程列表
`PgUp`, `PgDn` | 将流程列表`向上``向下`滚动一个窗口
`Home` | 滚动到流程列表的`顶部` <br /> _选择第一个流程_
`End` | 滚动到流程列表的`底部` <br /> _选择最后一个流程_
`Ctrl-A`, `^` | 向`左`滚动到流程条目`开头` _(即行开头)_
`Ctrl-E`, `$` | 向`右`滚动到流程条目`末尾` _(即行尾)_
<!--rehype:className=shortcuts-->

View File

@ -6,114 +6,114 @@ HTTP 状态码备忘清单。 每个 HTTP 状态代码的快速参考。
HTTP 状态码
---
### Means
### 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-->
* [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题_<!--rehype:tooltips-->
* [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成并创建了一个新资源_<!--rehype:tooltips-->
* [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理但处理未完成_<!--rehype:tooltips-->
* [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本而不是来自原始服务器_<!--rehype:tooltips-->
* [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头但响应中没有实体主体_<!--rehype:tooltips-->
* [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入_<!--rehype:tooltips-->
* [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围_<!--rehype:tooltips-->
- [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题_<!--rehype:tooltips-->
- [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成并创建了一个新资源_<!--rehype:tooltips-->
- [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理但处理未完成_<!--rehype:tooltips-->
- [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本而不是来自原始服务器_<!--rehype:tooltips-->
- [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头但响应中没有实体主体_<!--rehype:tooltips-->
- [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入_<!--rehype:tooltips-->
- [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围_<!--rehype:tooltips-->
### 4xx. 客户端错误
<!--rehype:wrap-class=row-span-3-->
* [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求_<!--rehype:tooltips-->
* [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码_<!--rehype:tooltips-->
* [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码_<!--rehype:tooltips-->
* [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面_<!--rehype:tooltips-->
* [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面_<!--rehype:tooltips-->
* [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的_<!--rehype:tooltips-->
* [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应_<!--rehype:tooltips-->
* [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证然后才能提供此请求_<!--rehype:tooltips-->
* [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长_<!--rehype:tooltips-->
* [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突请求无法完成_<!--rehype:tooltips-->
* [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用_<!--rehype:tooltips-->
* [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它,服务器将不会接受请求_<!--rehype:tooltips-->
* [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false_<!--rehype:tooltips-->
* [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求因为请求实体太大_<!--rehype:tooltips-->
* [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生_<!--rehype:tooltips-->
* [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求因为不支持媒体类型_<!--rehype:tooltips-->
* [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围_<!--rehype:tooltips-->
* [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望_<!--rehype:tooltips-->
* [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求但在客户端升级到不同协议后可能愿意这样做_<!--rehype:tooltips-->
* [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果_<!--rehype:tooltips-->
- [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求_<!--rehype:tooltips-->
- [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码_<!--rehype:tooltips-->
- [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码_<!--rehype:tooltips-->
- [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面_<!--rehype:tooltips-->
- [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面_<!--rehype:tooltips-->
- [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的_<!--rehype:tooltips-->
- [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应_<!--rehype:tooltips-->
- [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证然后才能提供此请求_<!--rehype:tooltips-->
- [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长_<!--rehype:tooltips-->
- [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突请求无法完成_<!--rehype:tooltips-->
- [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用_<!--rehype:tooltips-->
- [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它服务器将不会接受请求_<!--rehype:tooltips-->
- [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false_<!--rehype:tooltips-->
- [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求因为请求实体太大_<!--rehype:tooltips-->
- [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生_<!--rehype:tooltips-->
- [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求因为不支持媒体类型_<!--rehype:tooltips-->
- [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围_<!--rehype:tooltips-->
- [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望_<!--rehype:tooltips-->
- [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求但在客户端升级到不同协议后可能愿意这样做_<!--rehype:tooltips-->
- [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果_<!--rehype:tooltips-->
### 1xx. 信息
* [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分但只要没有被拒绝客户端就应该继续请求_<!--rehype:tooltips-->
* [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议_<!--rehype:tooltips-->
* [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应_<!--rehype:tooltips-->
- [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分但只要没有被拒绝客户端就应该继续请求_<!--rehype:tooltips-->
- [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议_<!--rehype:tooltips-->
- [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应_<!--rehype:tooltips-->
### 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-->
* [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-->
* [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用,但代码被保留_<!--rehype:tooltips-->
* [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
- [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-->
- [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-->
- [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用但代码被保留_<!--rehype:tooltips-->
- [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
### 5xx. 服务器错误
* [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。 服务器遇到了意外情况_<!--rehype:tooltips-->
* [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。 服务器不支持所需的功能_<!--rehype:tooltips-->
* [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。 服务器收到来自上游服务器的无效响应_<!--rehype:tooltips-->
* [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。 服务器暂时超载或停机_<!--rehype:tooltips-->
* [504: Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5) _网关已超时_<!--rehype:tooltips-->
* [505: HTTP Version Not Supported](https://tools.ietf.org/html/rfc7231#section-6.6.6) _服务器不支持“http 协议”版本_<!--rehype:tooltips-->
- [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。服务器遇到了意外情况_<!--rehype:tooltips-->
- [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。服务器不支持所需的功能_<!--rehype:tooltips-->
- [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。服务器收到来自上游服务器的无效响应_<!--rehype:tooltips-->
- [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。服务器暂时超载或停机_<!--rehype:tooltips-->
- [504: Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5) _网关已超时_<!--rehype:tooltips-->
- [505: HTTP Version Not Supported](https://tools.ietf.org/html/rfc7231#section-6.6.6) _服务器不支持“http 协议”版本_<!--rehype:tooltips-->
### RESTful API
:- | -
---- | ----
`200` | 返回成功GETDELETE 请求成功
`204` | 无内容POST 请求成功
`301` | 永久重定向
`302/307` | 临时重定向
`304` | 未修改,自上次请求以来
`331` | 用户名正确,需要密码
`332` | 需要登录帐户
`400` | 错误请求,缺少 API 请求的必需属性
`401` | 未授权,无效凭据进行身份验证将
`403` | 禁地,该请求不被允许
`404` | 未找到,无法访问资
`405` | 方法不允许,不支持该请求
`409` | 冲突,冲突资源已存在
`412` | 该请求被拒绝
`422` | 无法处理,无法处理该实体
`429` | 请求过多,用户超出了应用速率限制
`500` | 服务器错误,在处理请求时,服务器出现问题
`530` | 未登录
`200` | 返回成功GETDELETE 请求成功
`204` | 无内容POST 请求成功
`301` | 永久重定向
`302/307` | 临时重定向
`304` | 未修改,自上次请求以来
`331` | 用户名正确,需要密码
`332` | 需要登录帐户
`400` | 错误请求,缺少 API 请求的必需属性
`401` | 未授权,无效凭据进行身份验证将
`403` | 禁地,该请求不被允许
`404` | 未找到,无法访问资
`405` | 方法不允许,不支持该请求
`409` | 冲突,冲突资源已存在
`412` | 该请求被拒绝
`422` | 无法处理,无法处理该实体
`429` | 请求过多,用户超出了应用速率限制
`500` | 服务器错误,在处理请求时,服务器出现问题
`530` | 未登录
### 5xx 永久性否定
<!--rehype:wrap-class=col-span-2-->
:- | -
---- | ----
`500` | 语法错误,命令无法识别。这可能包括诸如命令行太长之类的错误
`501` | 在参数中有语法错误
`502` | 未执行命令
`503` | 错误的命令序列
`504` | 未执行该参数的命令
`530` | 未登录
`532` | 存储文件需要帐户
`550` | 未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)
`551` | 请求的操作异常终止:未知的页面类型
`552` | 请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)
`553` | 未执行请求的操作。不允许的文件名
`500` | 语法错误,命令无法识别。这可能包括诸如命令行太长之类的错误
`501` | 在参数中有语法错误
`502` | 未执行命令
`503` | 错误的命令序列
`504` | 未执行该参数的命令
`530` | 未登录
`532` | 存储文件需要帐户
`550` | 未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)
`551` | 请求的操作异常终止:未知的页面类型
`552` | 请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)
`553` | 未执行请求的操作。不允许的文件名
永久性否定的完成答复,该命令不成功,错误是永久性的。如果客户端重试命令,将再次出现同样的错误。
@ -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)_

185
docs/ini.md Normal file
View File

@ -0,0 +1,185 @@
INI 备忘清单
====
这是理解和编写 INI 格式配置文件的快速参考备忘单,此清单包含配置的内容,结构和语法等内容。
入门
------
### 介绍
INI 是一种固定标准格式的配置文件INI配置方法来自 MS-DOS 操作系统
```ini
; 这里是注释
[owner]
name=John Doe
organization=Acme Products
[database]
; 这里是注释
server=192.0.2.42
port=143
file="acme payroll.dat"
```
现在已成为许多配置的非正式标准,其它操作系统可能使用 `.conf``.cfg` 作为后缀
### 稳定的特性
- 基本元素是键或属性
- 每个键由`名称``值`构成,等号 (=) 分隔
- `键名称`显示在等号的`左侧`
- `等号``分号``保留`字符
<!--rehype:className=style-round-->
```ini
name = value
```
与下面👇 JSON 大致相同
```js
{
"name": "value"
}
```
### 注释
注释 (`;`)
```ini
; 这里是注释文本,将被忽略
```
注释 (`#`)
```ini
# 这里是注释文本,⚠️ 部分编译器支持
```
一行之后的注释 (`;`,`#`) _(不标准)_
```ini
var = a ; 这是一个内联注释
foo = bar # 这是另一个内联注释
```
在某些情况下注释必须单独出现在行上
### 部分(Sections)
- 名称单独出现在一行中
- 名称在方括号 `[``]`
- 没有明确的 `section 结束` 分隔符
- 在下一个 `section` 声明处或文件末尾处结束
- 部分和属性名称不区分大小写
<!--rehype:className=style-round-->
```ini
[section]
key1 = a
key2 = b
```
与下面👇 `JSON` 大致相同
```json
{
"section": {
"key1": "a",
"key2": "b"
}
}
```
### 嵌套(部分解析器支持)
```ini
[section]
domain = jaywcjlove.github.io
[section.subsection]
foo = bar
```
与下面👇 `JSON` 大致相同
```js
{
"section": {
"domain": "jaywcjlove.github.io"
"subsection": {
"foo": "bar"
}
}
}
```
嵌套到上一节(简写)
```ini
[section]
domain = jaywcjlove.github.io
[.subsection]
foo = bar
```
### 转义字符
序列 | 意思
:- | :-
`\\` | \ (单个反斜杠,转义转义字符)
`\'` | 撇号
`\"` | 双引号
`\0` | 空字符
`\a` | 铃声/警报/声音
`\b` | 退格键,某些应用程序的[贝尔字符](https://en.wikipedia.org/wiki/Bell_character)
`\t` | 制表符
`\r` | 回车
`\n` | 换行
`\;` | 分号
`\#` | 数字符号
`\=` | 等号
`\:` | 冒号
`\x????` | 十六进制代码点的 Unicode 字符对应于 ????
### 数组
```ini
[section]
domain = jaywcjlove.github.io
array[]=first value
array[]=second value
```
与下面👇 `JSON` 大致相同
```js
{
"section": {
"domain": "jaywcjlove.github.io",
"array": [
"first value", "second value"
]
}
}
```
### 解释器
- [@go-ini/ini](https://github.com/go-ini/ini) _(golang)_
- [@npm/ini](https://www.npmjs.com/package/ini) _(nodejs)_
- [@zonyitoo/rust-ini](https://github.com/zonyitoo/rust-inii) _(rust)_
- [@rxi/ini](https://www.npmjs.com/package/ini) _(c)_
- [@pulzed/mINI](https://github.com/pulzed/mINI) _(c++)_
- [@rickyah/ini-parser](https://github.com/rickyah/ini-parser) _(c#)_
- [@Enichan/Ini](https://github.com/Enichan/Ini) _(c#)_
另见
---
- [INI 文件配置](https://en.wikipedia.org/wiki/INI_file) _(wikipedia.org)_
- [YAML 格式配置文件备忘清单](./yaml.md) _(jaywcjlove.github.io)_
- [TOML 格式配置文件备忘清单](./toml.md) _(jaywcjlove.github.io)_

236
docs/iso-639-1.md Normal file
View File

@ -0,0 +1,236 @@
ISO 639-1 Language Code 备忘清单
===
这是一个符合 ISO 639-1 标准的 ISO 语言代码列表,它为多语言网站提供参考。
入门
----
### 介绍
<!--rehype:style=display:none;&wrap-style=padding-top:0;&wrap-class=col-span-3-->
- [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) 是用于对语言进行分类的标准化命名法
- [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) 代码涵盖世界主要语言
- 这些代码是用于指示语言的有用的国际和正式速记
- 两个字母的代码
- 用于多语言网站,即国际化 (`i18n`)
- [i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization) 语言代码
<!--rehype:className=style-round-->
ISO 639-1 代码列表
----
### 完整代码
<!--rehype:wrap-class=col-span-3-->
639-1 代码 | ISO 语言(中文)名称 | ISO 语言名称 | 本地名称 (地名)
:-|:-|:-|:-
`aa` | 阿法尔语 | Afar | Afaraf
`ab` | 阿布哈兹语 | Abkhaz | аҧсуа бызшәа
`ae` | 阿维斯陀语 | Avestan | avesta
`af` | 南非語 | Afrikaans | Afrikaans
`ak` | 阿坎语 | Akan | Akan
`am` | 阿姆哈拉语 | Amharic | አማርኛ
`an` | 阿拉贡语 | Aragonese | aragonés
`ar` | 阿拉伯语 | Arabic | اللغة العربية
`as` | 阿萨姆语 | Assamese | অসমীয়া
`av` | 阿瓦尔语 | Avaric | авар мацӀ
`ay` | 艾马拉语 | Aymara | aymar aru
`az` | 阿塞拜疆语 | Azerbaijani | azərbaycan dili
`ba` | 巴什基尔语 | Bashkir | башҡорт теле
`be` | 白俄罗斯语 | Belarusian | беларуская мова
`bg` | 保加利亚语 | Bulgarian | български език
`bh` | 比哈尔语 | Bihari | भोजपुरी
`bi` | 比斯拉马语 | Bislama | Bislama
`bm` | 班巴拉语 | Bambara | bamanankan
`bn` | 孟加拉语 | Bengali | বাংলা
`bo` | 藏语 | Tibetan | བོད་ཡིག
`br` | 布列塔尼语 | Breton | brezhoneg
`bs` | 波斯尼亚语 | Bosnian | bosanski jezik
`ca` | 加泰隆语 | Catalan | Català
`ce` | 车臣语 | Chechen | нохчийн мотт
`ch` | 查莫罗语 | Chamorro | Chamoru
`co` | 科西嘉语 | Corsican | corsu
`cr` | 克里语 | Cree | ᓀᐦᐃᔭᐍᐏᐣ
`cs` | 捷克语 | Czech | čeština
`cu` | 古教会斯拉夫语 | Old Church Slavonic | ѩзыкъ словѣньскъ
`cv` | 楚瓦什语 | Chuvash | чӑваш чӗлхи
`cy` | 威尔士语 | Welsh | Cymraeg
`da` | 丹麦语 | Danish | dansk
`de` | 德语 | German | Deutsch
`dv` | 迪维西语 | Divehi | Dhivehi
`dz` | 不丹语 | Dzongkha | རྫོང་ཁ
`ee` | 埃维语 | Ewe | Eʋegbe
`el` | 现代希腊语 | Greek | Ελληνικά
`en` | 英语 | English | English
`eo` | 世界语 | Esperanto | Esperanto
`es` | 西班牙语 | Spanish | Español
`et` | 爱沙尼亚语 | Estonian | eesti
`eu` | 巴斯克语 | Basque | euskara
`fa` | 波斯语 | Persian | فارسی
`ff` | 富拉语 | Fula | Fulfulde
`fi` | 芬兰语 | Finnish | suomi
`fj` | 斐济语 | Fijian | Vakaviti
`fo` | 法罗语 | Faroese | føroyskt
`fr` | 法语 | French | Français
`fy` | 弗里西亚语 | Western Frisian | Frysk
`ga` | 爱尔兰语 | Irish | Gaeilge
`gd` | 苏格兰盖尔语 | Scottish Gaelic | Gàidhlig
`gl` | 加利西亚语 | Galician | galego
`gn` | 瓜拉尼语 | Guarani | avañe'ẽ
`gu` | 古吉拉特语 | Gujarati | ગુજરાતી
`gv` | 马恩岛语 | Manx | Gaelg
`ha` | 豪萨语 | Hausa | هَوُسَ
`he` | 希伯来语 | Hebrew | עברית
`hi` | 印地语 | Hindi | हिन्दी
`ho` | 希里莫图语 | Hiri Motu | Hiri Motu
`hr` | 克罗地亚语 | Croatian | Hrvatski
`ht` | 海地克里奥尔语 | Haitian | Kreyòl ayisyen
`hu` | 匈牙利语 | Hungarian | magyar
`hy` | 亚美尼亚语 | Armenian | Հայերեն
`hz` | 赫雷罗语 | Herero | Otjiherero
`ia` | 因特语 | Interlingua | Interlingua
`id` | 印尼语 | Indonesian | Bahasa Indonesia
`ie` | 西方国际语 | Interlingue | Interlingue
`ig` | 伊博语 | Igbo | Asụsụ Igbo
`ii` | 四川彝语(诺苏语) | Nuosu | ꆈꌠ꒿ Nuosuhxop
`ik` | 伊努皮克语 | Inupiaq | Iñupiaq
`io` | 伊多语 | Ido | Ido
`is` | 冰岛语 | Icelandic | Íslenska
`it` | 意大利语 | Italian | Italiano
`iu` | 因纽特语 | Inuktitut | ᐃᓄᒃᑎᑐᑦ
`ja` | 日语 | Japanese | 日本語
`jv` | 爪哇语 | Javanese | basa Jawa
`ka` | 格鲁吉亚语 | Georgian | ქართული
`kg` | 刚果语 | Kongo | Kikongo
`ki` | 基库尤语 | Kikuyu | Gĩkũyũ
`kj` | 宽亚玛语 | Kwanyama | Kuanyama
`kk` | 哈萨克语 | Kazakh | қазақ тілі
`kl` | 格陵兰语 | Kalaallisut | kalaallisut
`km` | 高棉语 | Khmer | ខេមរភាសា
`kn` | 卡纳达语 | Kannada | ಕನ್ನಡ
`ko` | 朝鲜语、韩语 | Korean | 한국어
`kr` | 卡努里语 | Kanuri | Kanuri
`ks` | 克什米尔语 | Kashmiri | कश्मीरी
`ku` | 库尔德语 | Kurdish | Kurdî
`kv` | 科米语 | Komi | коми кыв
`kw` | 康沃尔语 | Cornish | Kernewek
`ky` | 吉尔吉斯语 | Kyrgyz | Кыргызча
`la` | 拉丁语 | Latin | latine
`lb` | 卢森堡语 | Luxembourgish | Lëtzebuergesch
`lg` | 卢干达语 | Ganda | Luganda
`li` | 林堡语 | Limburgish | Limburgs
`ln` | 林加拉语 | Lingala | Lingála
`lo` | 老挝语 | Lao | ພາສາ
`lt` | 立陶宛语 | Lithuanian | lietuvių kalba
`lu` | 卢巴语 | Luba-Katanga | Tshiluba
`lv` | 拉脱维亚语 | Latvian | latviešu valoda
`mg` | 马达加斯加语 | Malagasy | fiteny malagasy
`mh` | 马绍尔语 | Marshallese | Kajin M̧ajeļ
`mi` | 毛利语 | Māori | te reo Māori
`mk` | 马其顿语 | Macedonian | македонски јазик
`ml` | 马拉雅拉姆语 | Malayalam | മലയാളം
`mn` | 蒙古语 | Mongolian | Монгол хэл
`mo` | 摩尔达维亚语 | Moldovan | Лимба молдовеняскэ
`mr` | 马拉地语 | Marathi | मराठी
`ms` | 马来语 | Malay | Bahasa Malaysia
`mt` | 马耳他语 | Maltese | Malti
`my` | 缅甸语 | Burmese | ဗမာစာ
`na` | 瑙鲁语 | Nauru | Ekakairũ Naoero
`nb` | 书面挪威语 | Norwegian Bokmål | Norsk bokmål
`nd` | 北恩德贝莱语 | Northern Ndebele | isiNdebele
`ne` | 尼泊尔语 | Nepali | नेपाली
`ng` | 恩敦加语 | Ndonga | Owambo
`nl` | 荷兰语 | Dutch | Nederlands
`nn` | 新挪威语 | Norwegian Nynorsk | Norsk nynorsk
`no` | 挪威语 | Norwegian | Norsk
`nr` | 南恩德贝莱语 | Southern Ndebele | isiNdebele
`nv` | 纳瓦霍语 | Navajo | Diné bizaad
`ny` | 尼扬贾语 | Chichewa | chiCheŵa
`oc` | 奥克语 | Occitan | occitan
`oj` | 奥杰布瓦语 | Ojibwe | ᐊᓂᔑᓈᐯᒧᐎᓐ
`om` | 奥罗莫语 | Oromo | Afaan Oromoo
`or` | 奥里亚语 | Oriya | ଓଡ଼ିଆ
`os` | 奥塞梯语 | Ossetian | ирон æвзаг
`pa` | 旁遮普语 | Panjabi | ਪੰਜਾਬੀ
`pi` | 巴利语 | Pāli | पाऴि
`pl` | 波兰语 | Polish | Polski
`ps` | 普什图语 | Pashto | پښتو
`pt` | 葡萄牙语 | Portuguese | Português
`qu` | 克丘亚语 | Quechua | Runa Simi
`rm` | 罗曼什语 | Romansh | rumantsch grischun
`rn` | 基隆迪语 | Kirundi | Ikirundi
`ro` | 罗马尼亚语 | Romanian | Română
`ru` | 俄语 | Russian | Русский
`rw` | 卢旺达语 | Kinyarwanda | Ikinyarwanda
`sa` | 梵语 | Sanskrit | संस्कृतम्
`sc` | 撒丁语 | Sardinian | sardu
`sd` | 信德语 | Sindhi | सिन्धी
`se` | 北萨米语 | Northern Sami | Davvisámegiella
`sg` | 桑戈语 | Sango | yângâ tî sängö
`sh` | 塞尔维亚-克罗地亚语 | Serbo-Croatian | Српскохрватски језик
`si` | 僧伽罗语 | Sinhala | සිංහල
`sk` | 斯洛伐克语 | Slovak | slovenčina
`sl` | 斯洛文尼亚语 | Slovenian | slovenščina
`sm` | 萨摩亚语 | - | -
`sn` | 修纳语 | Shona | chiShona
`so` | 索马里语 | Somali | Soomaaliga
`sq` | 阿尔巴尼亚语 | Albanian | Shqip
`sr` | 塞尔维亚语 | Serbian | српски језик
`ss` | 斯威士语 | Swati | SiSwati
`st` | 塞索托语 | Southern Sotho | Sesotho
`su` | 巽他语 | Sundanese | Basa Sunda
`sv` | 瑞典语 | Swedish | Svenska
`sw` | 斯瓦希里语 | Swahili | Kiswahili
`ta` | 泰米尔语 | Tamil | தமிழ்
`te` | 泰卢固语 | Telugu | తెలుగు
`tg` | 塔吉克语 | Tajik | тоҷикӣ
`th` | 泰语 | Thai | ไทย
`ti` | 提格雷尼亚语 | Tigrinya | ትግርኛ
`tk` | 土库曼语 | Turkmen | Türkmen
`tl` | 他加禄语 | Tagalog | Wikang Tagalog
`tn` | 茨瓦纳语 | Tswana | Setswana
`to` | 汤加语 | Tonga | faka Tonga
`tr` | 土耳其语 | Turkish | Türkçe
`ts` | 宗加语 | Tsonga | Xitsonga
`tt` | 塔塔尔语 | Tatar | татар теле
`tw` | 特威语 | Twi | Twi
`ty` | 塔希提语 | Tahitian | Reo Tahiti
`ug` | 维吾尔语 | Uyghur | ئۇيغۇرچە‎
`uk` | 乌克兰语 | Ukrainian | Українська
`ur` | 乌尔都语 | Urdu | اردو
`uz` | 乌兹别克语 | Uzbek | Ўзбек
`ve` | 文达语 | Venda | Tshivenḓa
`vi` | 越南语 | Vietnamese | Tiếng Việt
`vo` | 沃拉普克语 | Volapük | Volapük
`wa` | 瓦隆语 | Walloon | walon
`wo` | 沃洛夫语 | Wolof | Wollof
`xh` | 科萨语 | Xhosa | isiXhosa
`yi` | 依地语 | Yiddish | ייִדיש
`yo` | 约鲁巴语 | Yoruba | Yorùbá
`za` | 壮语 | Zhuang | Saɯ cueŋƅ
`zh` | 汉语(中文) | Chinese | 中文
`zu` | 祖鲁语 | Zulu | isiZulu
<!--rehype:className=show-header-->
### SO 639-1 新增了以下语言
<!--rehype:wrap-class=col-span-3-->
ISO 639-1 | ISO 639-2 | 名称 | 更改日期 | 更改类型 | 曾用代码
:-|:-|:-|:-|:-|:-
io | ido | 伊多语 | 2002年1月15日 | 新增 | art
wa | wln | 瓦隆语 | 2002年1月29日 | 新增 | roa
li | lim | 林堡语 | 2002年8月2日 | 新增 | gem
ii | iii | 四川省彝语(诺苏语) | 2002年10月14日 | 新增 | -
an | arg | 阿拉贡语 | 2002年12月23日 | 新增 | roa
ht | hat | 海地克里奥尔语 | 2003年2月26日 | 新增 | cpf
<!--rehype:className=show-header-->
自 [RFC 3066](https://tools.ietf.org/html/rfc3066) 出版后ISO 639-1 新增了以上语言
另见
---
<!--rehype:wrap-class=col-span-3-->
- [国际化与本地化](https://zh.wikipedia.org/wiki/国际化与本地化) _(wikipedia.org)_
- [ISO_639-1](https://zh.wikipedia.org/wiki/ISO_639-1) _(wikipedia.org)_

789
docs/java.md Normal file
View File

@ -0,0 +1,789 @@
Java 备忘清单
===
该备忘单是针对 Java 初学者的速成课程,有助于复习 Java 语言的基本语法。
入门
--------
### Hello.java
<!--rehype:wrap-class=row-span-2-->
```java
public class Hello {
// 主要方法
public static void main(String[] args)
{
// 输出: Hello, world!
System.out.println("Hello, world!");
}
}
```
编译和运行
```shell
$ javac Hello.java
$ java Hello
Hello, world!
```
### 变量 Variables
```java
int num = 5;
float floatNum = 5.99f;
char letter = 'D';
boolean bool = true;
String site = "quickref.me";
```
### 原始数据类型
<!--rehype:wrap-class=row-span-2-->
| 数据类型 | 大小 | 默认 | 范围 |
|-----------|--------|---------|---------------------|
| `byte` | 1 byte | 0 | -128 ^to^ 127 |
| `short` | 2 byte | 0 | -2^15^ ^to^ 2^15^-1 |
| `int` | 4 byte | 0 | -2^31^ ^to^ 2^31^-1 |
| `long` | 8 byte | 0 | -2^63^ ^to^ 2^63^-1 |
| `float` | 4 byte | 0.0f | _N/A_ |
| `double` | 8 byte | 0.0d | _N/A_ |
| `char` | 2 byte | \\u0000 | 0 ^to^ 65535 |
| `boolean` | _N/A_ | false | true / false |
<!--rehype:className=show-header-->
### 字符串 Strings
```java
String first = "John";
String last = "Doe";
String name = first + " " + last;
System.out.println(name);
```
查看: [Strings](#java-字符串)
### 循环 Loops
```java
String word = "QuickRef";
for (char c: word.toCharArray()) {
System.out.print(c + "-");
}
// 输出: Q-u-i-c-k-R-e-f-
```
查看: [Loops](#java-循环)
### 数组 Arrays
```java
char[] chars = new char[10];
chars[0] = 'a'
chars[1] = 'b'
String[] letters = {"A", "B", "C"};
int[] mylist = {100, 200};
boolean[] answers = {true, false};
```
查看: [Arrays](#java-数组)
### Swap
```java
int a = 1;
int b = 2;
System.out.println(a + " " + b); // 1 2
int temp = a;
a = b;
b = temp;
System.out.println(a + " " + b); // 2 1
```
### Type Casting
```java
// Widening
// byte<short<int<long<float<double
int i = 10;
long l = i; // 10
// Narrowing
double d = 10.02;
long l = (long)d; // 10
String.valueOf(10); // "10"
Integer.parseInt("10"); // 10
Double.parseDouble("10"); // 10.0
```
### 条件语句 Conditionals
```java
int j = 10;
if (j == 10) {
System.out.println("I get printed");
} else if (j > 10) {
System.out.println("I don't");
} else {
System.out.println("I also don't");
}
```
查看: [Conditionals](#条件语句 Conditionals)
### 用户输入
```java
Scanner in = new Scanner(System.in);
String str = in.nextLine();
System.out.println(str);
int num = in.nextInt();
System.out.println(num);
```
Java 字符串
-------
### 基本的
```java
String str1 = "value";
String str2 = new String("value");
String str3 = String.valueOf(123);
```
### 字符串连接
```java
String s = 3 + "str" + 3; // 3str3
String s = 3 + 3 + "str"; // 6str
String s = "3" + 3 + "str"; // 33str
String s = "3" + "3" + "23"; // 3323
String s = "" + 3 + 3 + "23"; // 3323
String s = 3 + 3 + 23; // 29
```
### 字符串生成器
<!--rehype:wrap-class=row-span-3-->
```java
StringBuilder sb = new StringBuilder(10);
```
---
```java
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| | | | | | | | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5 6 7 8 9
```
---
```java
sb.append("Reference");
```
---
```java
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| R | e | f | e | r | e | n | c | e |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5 6 7 8 9
```
---
```java
sb.delete(3, 9);
```
---
```java
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| R | e | f | | | | | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5 6 7 8 9
```
---
```java
sb.insert(0, "My ");
```
---
```java
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| M | y | | R | e | f | | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5 6 7 8 9
```
---
```java
sb.append("!");
```
---
```java
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| M | y | | R | e | f | ! | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5 6 7 8 9
```
### 比较
```java
String s1 = new String("QuickRef");
String s2 = new String("QuickRef");
s1 == s2 // false
s1.equals(s2) // true
"AB".equalsIgnoreCase("ab") // true
```
### 操纵
```java
String str = "Abcd";
str.toUpperCase(); // ABCD
str.toLowerCase(); // abcd
str.concat("#"); // Abcd#
str.replace("b", "-"); // A-cd
" abc ".trim(); // abc
"ab".toCharArray(); // {'a', 'b'}
```
### 信息
```java
String str = "abcd";
str.charAt(2); // c
str.indexOf("a") // 0
str.indexOf("z") // -1
str.length(); // 4
str.toString(); // abcd
str.substring(2); // cd
str.substring(2,3); // c
str.contains("c"); // true
str.endsWith("d"); // true
str.startsWith("a"); // true
str.isEmpty(); // false
```
### 不可变
```java
String str = "hello";
str.concat("world");
// 输出: hello
System.out.println(str);
```
---
```java
String str = "hello";
String concat = str.concat("world");
// 输出: helloworld
System.out.println(concat);
```
一旦创建就不能修改任何修改都会创建一个新的String
Java 数组
-------
### 申明 Declare
```java
int[] a1;
int[] a2 = {1, 2, 3};
int[] a3 = new int[]{1, 2, 3};
int[] a4 = new int[3];
a4[0] = 1;
a4[2] = 2;
a4[3] = 3;
```
### 修改 Modify
```java
int[] a = {1, 2, 3};
System.out.println(a[0]); // 1
a[0] = 9;
System.out.println(a[0]); // 9
System.out.println(a.length); // 3
```
### 循环 (读 & 写)
```java
int[] arr = {1, 2, 3};
for (int i=0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
System.out.print(arr[i] + " ");
}
// 输出: 2 4 6
```
### Loop (Read)
```java
String[] arr = {"a", "b", "c"};
for (int a: arr) {
System.out.print(a + " ");
}
// 输出: a b c
```
### Multidimensional Arrays
```java
int[][] matrix = { {1, 2, 3}, {4, 5} };
int x = matrix[1][0]; // 4
// [[1, 2, 3], [4, 5]]
Arrays.deepToString(matrix)
for (int i = 0; i < a.length; ++i) {
for(int j = 0; j < a[i].length; ++j) {
System.out.println(a[i][j]);
}
}
// 输出: 1 2 3 4 5 6 7
```
### Sort
```java
char[] chars = {'b', 'a', 'c'};
Arrays.sort(chars);
// [a, b, c]
Arrays.toString(chars);
```
Java 条件语句
-----------
### 运算符
<!--rehype:wrap-class=row-span-3-->
- `+` _(加法运算符(也用于字符串连接))_
- `-` _(减法运算符)_
- `*` _(乘法运算符)_
- `/` _(分区运算符)_
- `%` _(余数运算符)_
- `=` _(简单赋值运算符)_
- `++` _(增量运算符;将值增加 1)_
- `--` _(递减运算符;将值减 1)_
- `!` _(逻辑补码运算符;反转布尔值)_
<!--rehype:className=style-round-->
---
- `==` _(等于)_
- `!=` _(不等于)_
- `>` _(比...更棒)_
- `>=` _(大于或等于)_
- `<` _(少于)_
- `<=` _(小于或等于)_
<!--rehype:className=cols-2 style-round-->
---
- `&&` _条件与_
- `||` _条件或_
- [?:](#三元运算符) _三元(if-then-else 语句的简写)_
<!--rehype:className=style-round-->
---
- `instanceof` _(将对象与指定类型进行比较)_
<!--rehype:className=style-round-->
---
- `~` _(一元按位补码)_
- `<<` _(签名左移)_
- `>>` _(有符号右移)_
- `>>>` _(无符号右移)_
- `&` _(按位与)_
- `^` _(按位异或)_
- `|` _(按位包含 OR)_
<!--rehype:className=cols-2 style-round-->
### If else
```java
int k = 15;
if (k > 20) {
System.out.println(1);
} else if (k > 10) {
System.out.println(2);
} else {
System.out.println(3);
}
```
### Switch
<!--rehype:wrap-class=row-span-2-->
```java
int month = 3;
String str;
switch (month) {
case 1:
str = "January";
break;
case 2:
str = "February";
break;
case 3:
str = "March";
break;
default:
str = "Some other month";
break;
}
// 输出: Result March
System.out.println("Result " + str);
```
### 三元运算符
```java
int a = 10;
int b = 20;
int max = (a > b) ? a : b;
// 输出: 20
System.out.println(max);
```
Java 循环
----
### For 循环
```java
for (int i = 0; i < 10; i++) {
System.out.print(i);
}
// 输出: 0123456789
```
---
```java
for (int i = 0,j = 0; i < 3; i++,j--) {
System.out.print(j + "|" + i + " ");
}
// 输出: 0|0 -1|1 -2|2
```
### 增强的 For 循环
```java
int[] numbers = {1,2,3,4,5};
for (int number: numbers) {
System.out.print(number);
}
// 输出: 12345
```
用于循环数组或列表
### While 循环
```java
int count = 0;
while (count < 5) {
System.out.print(count);
count++;
}
// 输出: 01234
```
### Do While 循环
```java
int count = 0;
do {
System.out.print(count);
count++;
} while (count < 5);
// 输出: 01234
```
### 继续声明
```java
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue;
}
System.out.print(i);
}
// 输出: 01245
```
### 中断语句
```java
for (int i = 0; i < 5; i++) {
System.out.print(i);
if (i == 3) {
break;
}
}
// 输出: 0123
```
Java 框架搜集
--------------------
### Java 搜集
<!--rehype:wrap-class=col-span-2 row-span-2-->
搜集 | Interface | 有序 | 已排序 | 线程安全 | 复制 | Nullable
:-|:-|:-|:-|:-|:-|:-
[ArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) | List | Y | _N_ | _N_ | Y | Y
[Vector](https://docs.oracle.com/javase/8/docs/api/java/util/Vector.html) | List | Y | _N_ | Y | Y | Y
[LinkedList](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html) | List, Deque | Y | _N_ | _N_ | Y | Y
[CopyOnWriteArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html) | List | Y | _N_ | Y | Y | Y
[HashSet](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html) | Set | _N_ | _N_ | _N_ | _N_ | One `null`
[LinkedHashSet](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashSet.html) | Set | Y | _N_ | _N_ | _N_ | One `null`
[TreeSet](https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html) | Set | Y | Y | _N_ | _N_ | _N_
[CopyOnWriteArraySet](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html) | Set | Y | _N_ | Y | _N_ | One `null`
[ConcurrentSkipListSet](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentSkipListSet.html) | Set | Y | Y | Y | _N_ | _N_
[HashMap](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html) | Map | _N_ | _N_ | _N_ | _N (key)_ | One `null` _(key)_
[HashTable](https://docs.oracle.com/javase/8/docs/api/java/util/Hashtable.html) | Map | _N_ | _N_ | Y | _N (key)_ | _N (key)_
[LinkedHashMap](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html) | Map | Y | _N_ | _N_ | _N (key)_ | One `null` _(key)_
[TreeMap](https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html) | Map | Y | Y | _N_ | _N (key)_ | _N (key)_
[ConcurrentHashMap](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html) | Map | _N_ | _N_ | Y | _N (key)_ | _N_
[ConcurrentSkipListMap](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentSkipListMap.html) | Map | Y | Y | Y | _N (key)_ | _N_
[ArrayDeque](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html) | Deque | Y | _N_ | _N_ | Y | _N_
[PriorityQueue](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html) | Queue | Y | _N_ | _N_ | Y | _N_
[ConcurrentLinkedQueue](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html) | Queue | Y | _N_ | Y | Y | _N_
[ConcurrentLinkedDeque](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentLinkedDeque.html) | Deque | Y | _N_ | Y | Y | _N_
[ArrayBlockingQueue](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ArrayBlockingQueue.html) | Queue | Y | _N_ | Y | Y | _N_
[LinkedBlockingDeque](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/LinkedBlockingDeque.html) | Deque | Y | _N_ | Y | Y | _N_
[PriorityBlockingQueue](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/PriorityBlockingQueue.html) | Queue | Y | _N_ | Y | Y | _N_
<!--rehype:className=show-header-->
### ArrayList
```java
List<Integer> nums = new ArrayList<>();
// 添加
nums.add(2);
nums.add(5);
nums.add(8);
// 检索
System.out.println(nums.get(0));
// 为循环迭代编制索引
for (int i = 0; i < nums.size(); i++) {
System.out.println(nums.get(i));
}
nums.remove(nums.size() - 1);
nums.remove(0); // 非常慢
for (Integer value : nums) {
System.out.println(value);
}
```
### HashMap
```java
Map<Integer, String> m = new HashMap<>();
m.put(5, "Five");
m.put(8, "Eight");
m.put(6, "Six");
m.put(4, "Four");
m.put(2, "Two");
// 检索
System.out.println(m.get(6));
// Lambda forEach
m.forEach((key, value) -> {
String msg = key + ": " + value;
System.out.println(msg);
});
```
### HashSet
```java
Set<String> set = new HashSet<>();
if (set.isEmpty()) {
System.out.println("Empty!");
}
set.add("dog");
set.add("cat");
set.add("mouse");
set.add("snake");
set.add("bear");
if (set.contains("cat")) {
System.out.println("Contains cat");
}
set.remove("cat");
for (String element : set) {
System.out.println(element);
}
```
### ArrayDeque
```java
Deque<String> a = new ArrayDeque<>();
// 使用 add()
a.add("Dog");
// 使用 addFirst()
a.addFirst("Cat");
// 使用 addLast()
a.addLast("Horse");
// [Cat, Dog, Horse]
System.out.println(a);
// 访问元素
System.out.println(a.peek());
// 移除元素
System.out.println(a.pop());
```
杂项 Misc
----
### 访问修饰符
<!--rehype:wrap-class=col-span-2-->
| 修饰符 | Class | Package | Subclass | World |
|-------------|-------|---------|----------|-------|
| public | Y | Y | Y | Y |
| protected | Y | Y | Y | _N_ |
| no modifier | Y | Y | _N_ | _N_ |
| private | Y | _N_ | _N_ | _N_ |
<!--rehype:className=show-header-->
### 常用表达
```java
String text = "I am learning Java";
// 删除所有空格
text.replaceAll("\\s+", "");
// 拆分字符串
text.split("\\|");
text.split(Pattern.quote("|"));
```
查看: [Regex in java](./regex.md#java-中的正则表达式)
### 注释 Comment
```java
// 我是单行注释!
/*
而我是一个
多行注释!
*/
/**
* 这个
* 是
* 文档
* 注释
*/
```
### 关键字
<!--rehype:wrap-class=col-span-2-->
- abstract
- continue
- for
- new
- switch
- assert
- default
- goto
- package
- synchronized
- boolean
- do
- if
- private
- this
- break
- double
- implements
- protected
- throw
- byte
- else
- import
- public
- throws
- case
- enum
- instanceof
- return
- transient
- catch
- extends
- int
- short
- try
- char
- final
- interface
- static
- void
- class
- finally
- long
- strictfp
- volatile
- const
- float
- native
- super
- while
<!--rehype:className=cols-7 style-none-->
### 数学方法
方法 | 说明
:-|:-
`Math.max(a,b)` | `a``b` 的最大值
`Math.min(a,b)` | `a``b` 的最小值
`Math.abs(a)` | 绝对值
`Math.sqrt(a)` | `a` 的平方根
`Math.pow(a,b)` | `b` 的幂
`Math.round(a)` | 最接近的整数
`Math.sin(ang)` | 正弦
`Math.cos(ang)` | `ang` 的余弦
`Math.tan(ang)` | `ang` 的切线
`Math.asin(ang)` | `ang` 的反正弦
`Math.log(a)` | `a` 的自然对数
`Math.toDegrees(rad)` | 以度为单位的角度弧度
`Math.toRadians(deg)` | 以弧度为单位的角度度
### Try/Catch/Finally
```java
try {
// something
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("always printed");
}
```
另见
---
- [Java 官网](https://www.java.com/zh-CN/) _(java.com)_

View File

@ -54,7 +54,6 @@ count = 10;
console.log(count); // => 10
```
### const 关键字
```javascript
@ -238,11 +237,9 @@ parseFloat();
parseInt();
```
JavaScript 条件
----
### 操作符
<!--rehype:wrap-class=row-span-3-->
@ -273,7 +270,7 @@ true && false; // false
1 === '1' // false
```
#### 逻辑运算符 !
#### 逻辑运算符
```javascript
let lateToWork = true;
@ -386,18 +383,18 @@ sum(3, 6); // 9
### 匿名函数
```javascript
// Named function
// 命名函数
function rocketToMars() {
return 'BOOM!';
}
// Anonymous function
// 匿名函数
const rocketToMars = function() {
return 'BOOM!';
}
```
### 箭头函数 (ES6)
<!--rehype:wrap-class=row-span-2-->
<!--rehype:wrap-class=row-span-3-->
#### 有两个参数
@ -590,6 +587,48 @@ for (let j = 0; j < 3; j++) {
JavaScript Arrays
----
### 方法
<!--rehype:wrap-class=row-span-6-->
:- | :-
:- | :-
`Array.from()` | 类似数组对象创建一个新的 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from)
`Array.isArray()` | 值是否是一个 Array [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)
`Array.of()` | 创建一个新数组示例 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/of)
`.at()` | 返回值索引对应的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/at)
`.concat()` | 合并两个或多个数组 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat)
`.copyWithin()` | 浅复制替换某个位置 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin)
`.entries()` | 新的 Array Iterator 对象 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/entries)
`.every()` | 是否能通过回调函数的测试 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/every)
`.fill()` | 固定值填充一个数组中 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/fill)
`.filter()` | 返回过滤后的数组 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
`.find()` | 第一个元素的值 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
`.findIndex()` | 第一个元素的索引 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)
`.findLast()` | 最后一个元素的值 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/findLast)
`.findLastIndex()` | 最后一个元素的索引 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex)
`.flat()` | 扁平化嵌套数组 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)
`.flatMap()` | 与 flat 相同 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)
`.forEach()` | 升序循环执行 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
`.includes()` | 是否包含一个指定的值 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)
`.indexOf()` | 找到给定元素的第一个索引 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
`.join()` | 数组链接成一个字符串 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/join)
`.keys()` | 每个索引键 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/keys)
`.lastIndexOf()` | 给定元素的最后一个索引 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
`.map()` | 循环返回一个新数组 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
`.pop()` | `删除`最后一个元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop)
`.push()` | 元素`添加`到数组的末尾 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/push)
`.reduce()` | 循环函数传递当前和上一个值 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)
`.reduceRight()` | 类似 `reduce` 从右往左循环 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight)
`.reverse()` | 数组元素的位置颠倒 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)
`.shift()` | `删除`第一个元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift)
`.slice()` | `提取`元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
`.some()` | 至少有一个通过测试函数 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
`.sort()` | 元素进行排序 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
`.splice()` | `删除``替换``添加`元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
`.toLocaleString()` | 字符串表示数组中的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString)
`.toString()` | 返回字符串 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toString)
`.unshift()` | 元素`添加`到数组的`开头` [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift)
`.values()` | 返回新的 ArrayIterator 对象 [#](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/values)
### 数组
@ -652,24 +691,24 @@ console.log(fruits); // ["apple", "dew"]
### 方法 .shift()
```javascript
let cats = ['Bob', 'Willy', 'Mini'];
cats.shift(); // ['Willy', 'Mini']
const array1 = [1, 2, 3];
const firstElement = array1.shift();
console.log(array1); // 输出: Array [2, 3]
console.log(firstElement); // 输出: 1
```
**从头删除**一个项目并返回已删除的项目。
### 方法 .unshift()
### 方法 .some()
```javascript
let cats = ['Bob'];
// => ['Willy', 'Bob']
cats.unshift('Willy');
// => ['Puff', 'George', 'Willy', 'Bob']
cats.unshift('Puff', 'George');
```js
const array = [1, 2, 3, 4, 5];
// 检查元素是否为偶数
const even = (element) => element % 2 === 0;
console.log(array.some(even));
// 预期输出: true
```
将项目**添加到开头**并返回新的数组长度。
### 方法 .concat()
```javascript
@ -685,6 +724,44 @@ numbers.concat(newFirstNumber)
如果你想避免改变你的原始数组,你可以使用 concat。
### 方法 .splice()
```javascript
const months = ['Jan', 'March'];
months.splice(1, 0, 'Feb');
// 在索引 1 处插入
console.log(months);
// 预期输出: Array ["Jan", "Feb", "March"]
months.splice(2, 1, 'May');
// 替换索引 2 处的 1 个元素
console.log(months);
// 预期输出: Array ["Jan", "Feb", "May"]
```
### 方法 .unshift()
```javascript
let cats = ['Bob'];
// => ['Willy', 'Bob']
cats.unshift('Willy');
// => ['Puff', 'George', 'Willy', 'Bob']
cats.unshift('Puff', 'George');
```
将项目**添加到开头**并返回新的数组长度。
### 方法 .filter()
```javascript
const words = ['js', 'java', 'golang'];
const result = words.filter(word => {
return word.length > 3
});
console.log(result);
// 预期输出: Array ["java", "golang"]
```
JavaScript 循环
----
@ -998,19 +1075,16 @@ console.log(age); // '22'
```javascript
const person = {
firstName: "Matilda",
age: 27,
hobby: "knitting",
goal: "learning JavaScript"
};
delete person.hobby; // or delete person[hobby];
delete person.hobby; // delete person['hobby'];
console.log(person);
/*
{
firstName: "Matilda"
age: 27
goal: "learning JavaScript"
}
*/
} */
```
### 对象作为参数
@ -1217,7 +1291,6 @@ class Song {
}
```
JavaScript Modules
----
<!--rehype:body-class=cols-2-->
@ -1561,7 +1634,7 @@ msg(); // Message: Hello World! <-- 2 秒后
JavaScript 请求
----
### JSON
### JSON
```JS
const jsonObj = {
@ -1693,4 +1766,4 @@ const getSuggestions = async () => {
console.log(error)
}
}
```
```

View File

@ -1,14 +1,16 @@
Jest 备忘清单
===
Jest 是一款优雅、简洁的 JavaScript 测试框架。
Jest 是一款优雅、简洁的 JavaScript 测试框架,这里介绍了它的入门和 一些 API 的索引
入门
----
<!--rehype:body-class=cols-6-->
### 介绍
<!--rehype:wrap-class=col-span-2 row-span-2-->
[Jest](https://jestjs.io/) 是一款优雅、简洁的 JavaScript 测试框架。
[Jest v29](https://jestjs.io/) 是一款优雅、简洁的 JavaScript 测试框架。
- `无需配置` 大多数 JS 项目中即装即用,无需配置
- `优秀接口``it``expect` - Jest 将工具包整合在一处。文档齐全、不断维护,非常不错。
@ -16,9 +18,54 @@ Jest 是一款优雅、简洁的 JavaScript 测试框架。
- `快照` 轻松编写持续追踪大型对象的测试,并在测试旁或代码内显示实时快照。
- `代码覆盖` 无需其他操作,您仅需添加 `--coverage` 参数来生成代码覆盖率报告。
### 测试结构
### 快速开始
<!--rehype:wrap-class=col-span-2 row-span-2-->
```bash
npm install --save-dev jest
```
Add to `package.json`
```js
"scripts": {
"test": "jest"
}
```
运行你的测试
```bash
npm test -- --watch
```
查看: [Getting started](https://jestjs.io/docs/getting-started)
### 编写测试
<!--rehype:wrap-class=col-span-2-->
```js
describe('My work', () => {
test('works', () => {
expect(2).toEqual(2)
})
})
```
### BDD 语法
<!--rehype:wrap-class=col-span-2-->
```js {2}
describe('My work', () => {
it('works', () => { // `it`是`test`的别名
···
})
})
```
### 测试结构
<!--rehype:wrap-class=col-span-3 row-span-2-->
```js
describe('makePoniesPink', () => {
beforeAll(() => {
@ -40,6 +87,143 @@ describe('makePoniesPink', () => {
})
```
### 聚焦测试
```js
describe.only(···)
it.only(···)
// 别名: fit()
```
查看: [test.only](https://jestjs.io/docs/api#testonlyname-fn-timeout)
### 可选参数
<!--rehype:wrap-class=col-span-2-->
| Flag | Description |
| --------------------- | ---------------------------------------- |
| `--coverage` | 查看测试覆盖率摘要 |
| `--detectOpenHandles` | 查看未关闭端口的摘要 |
| `--runInBand` | 一个接一个地运行所有测试 |
| `--bail,-b` | 失败跳出测试 |
更多参数查看 [Jest CLI Options](https://jestjs.io/docs/next/cli#--bailn)
### 跳过测试
```js
describe.skip(···)
it.skip(···)
// 别名: xit()
```
查看: [test.skip](https://jestjs.io/docs/next/api#testskipname-fn)
### 基本测试用例
<!--rehype:wrap-class=col-span-2-->
```js
expect(value).not.toBe(value)
.toEqual(value)
.toBeTruthy()
// Errors 测试
expect(value).toThrow(error)
.toThrowErrorMatchingSnapshot()
```
### 快照
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toMatchSnapshot()
.toMatchInlineSnapshot()
```
### Errors
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toThrow(error)
.toThrowErrorMatchingSnapshot()
```
### Objects
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toBeInstanceOf(Class)
.toMatchObject(object)
.toHaveProperty(keyPath, value)
```
### Objects
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toContain(item)
.toContainEqual(item)
.toHaveLength(number)
```
### Numbers
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toBeCloseTo(number, numDigits)
.toBeGreaterThan(number)
.toBeGreaterThanOrEqual(number)
.toBeLessThan(number)
.toBeLessThanOrEqual(number)
```
### Booleans
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toBeFalsy()
.toBeNull()
.toBeTruthy()
.toBeUndefined()
.toBeDefined()
```
### Strings
<!--rehype:wrap-class=col-span-2-->
```js
expect(value)
.toMatch(regexpOrString)
```
### NaN
<!--rehype:wrap-class=col-span-2-->
```js
test('当值为 NaN 时通过', () => {
expect(NaN).toBeNaN();
expect(1).not.toBeNaN();
});
```
### Others
<!--rehype:wrap-class=col-span-2-->
```js
expect.extend(matchers)
expect.any(constructor)
expect.addSnapshotSerializer(serializer)
expect.assertions(1)
```
匹配器
----
@ -293,8 +477,6 @@ expect(fn).toThrowErrorMatchingSnapshot()
### 实例
<!--rehype:wrap-class=row-span-2-->
请参阅 Jest 文档中的 [更多示例](https://jestjs.io/docs/en/tutorial-async)。
在异步测试中指定一些预期的断言是一个很好的做法,所以如果你的断言根本没有被调用,测试将会失败。
```js
@ -314,6 +496,7 @@ beforeEach(expect.hasAssertions)
```
这将验证每个测试用例至少存在一个断言。 它还可以与更具体的 `expect.assertions(3)` 声明配合使用。
请参阅 Jest 文档中的 [更多示例](https://jestjs.io/docs/en/tutorial-async)
### async/await
@ -337,8 +520,8 @@ test('async test', (done) => {
setTimeout(() => {
try {
const result = getAsyncOperationResult()
expect(result).toBe(true)
const res = getAsyncOperatResult()
expect(res).toBe(true)
done()
} catch (err) {
done.fail(err)
@ -363,7 +546,6 @@ test('async test', () => {
从你的测试中 _返回_ 一个 `Promise`
## 模拟
### 模拟函数
@ -374,18 +556,28 @@ test('call the callback', () => {
const callback = jest.fn()
fn(callback)
expect(callback).toBeCalled()
expect(callback.mock.calls[0][1].baz).toBe('pizza') // 第一次调用的第二个参数
expect(callback.mock.calls[0][1].baz)
.toBe('pizza') // 第一次调用的第二个参数
// 匹配第一个和最后一个参数,但忽略第二个参数
expect(callback).toHaveBeenLastCalledWith('meal', expect.anything(), 'margarita')
expect(callback)
.toHaveBeenLastCalledWith(
'meal',
expect.anything(),
'margarita'
)
})
```
<!--rehype:className=wrap-text -->
您还可以使用快照:
```js
test('call the callback', () => {
// mockName 在 Jest 22+ 中可用
const callback = jest.fn().mockName('Unicorn')
const callback = jest.fn()
.mockName('Unicorn')
fn(callback)
expect(callback).toMatchSnapshot()
// ->
@ -411,6 +603,7 @@ const callback = jest.fn(() => true)
```js
const callback
= jest.fn().mockReturnValue(true)
const callbackOnce
= jest.fn().mockReturnValueOnce(true)
```
@ -418,26 +611,29 @@ const callbackOnce
或解析值:
```js
const promise
const promise
= jest.fn().mockResolvedValue(true)
const promiseOnce
const promiseOnce
= jest.fn().mockResolvedValueOnce(true)
```
他们甚至可以拒绝值:
```js
const failedPromise
= jest.fn().mockRejectedValue('Error')
const failedPromiseOnce
= jest.fn().mockRejectedValueOnce('Error')
const failedPromise =
jest.fn().mockRejectedValue('Error')
const failedPromiseOnce =
jest.fn().mockRejectedValueOnce('Error')
```
你甚至可以结合这些:
```js
const callback
= jest.fn().mockReturnValueOnce(false).mockReturnValue(true)
const callback = jest.fn()
.mockReturnValueOnce(false)
.mockReturnValue(true)
// ->
// call 1: false
// call 2+: true
@ -446,13 +642,20 @@ const callback
### 使用 `jest.mock` 方法模拟模块
```js
jest.mock('lodash/memoize', () => (a) => a) // The original lodash/memoize should exist
jest.mock('lodash/memoize', () => (a) => a, { virtual: true }) // The original lodash/memoize isnt required
// 原来的 lodash/memoize 应该存在
jest.mock(
'lodash/memoize',
() => (a) => a
)
// 不需要原始的 lodash/memoize
jest.mock(
'lodash/memoize',
() => (a) => a,
{ virtual: true }
)
```
[jest.mock docs](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options)
> 注意:当使用 `babel-jest` 时,对 `jest.mock` 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。
注意:当使用 `babel-jest` 时,对 [`jest.mock`](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options) 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。
### 使用模拟文件模拟模块
@ -468,22 +671,18 @@ module.exports = (a) => a
jest.mock('lodash/memoize')
```
注意:当使用 `babel-jest` 时,对 `jest.mock` 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`
注意:当使用 `babel-jest` 时,对 `jest.mock` 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。[手动模拟文档](https://jestjs.io/docs/en/manual-mocks)
[手动模拟文档](https://jestjs.io/docs/en/manual-mocks)
### 模拟对象方法
### 模拟 getters 和 setters
```js
const spy = jest.spyOn(console, 'log').mockImplementation(() => {})
expect(console.log.mock.calls).toEqual([['dope'], ['nope']])
spy.mockRestore()
```
```js
const spy = jest.spyOn(ajax, 'request').mockImplementation(() => Promise.resolve({ success: true }))
expect(spy).toHaveBeenCalled()
spy.mockRestore()
const getTitle = jest.fn(() => 'pizza')
const setTitle = jest.fn()
const location = {}
Object.defineProperty(location, 'title', {
get: getTitle,
set: setTitle,
})
```
### 模拟 getter 和 setter (Jest 22.1.0+)
@ -508,8 +707,9 @@ const setTitle = jest
jest.useFakeTimers()
test('kill the time', () => {
const callback = jest.fn()
// 运行一些使用 setTimeoutsetInterval 的代码
const actual = someFunctionThatUseTimers(callback)
// 运行使用 setTimeoutsetInterval 的代码
const actual
= someFunctionThatUseTimers(callback)
// 快进直到所有定时器都执行完毕
jest.runAllTimers()
// 同步检查结果
@ -524,8 +724,9 @@ test('kill the time', () => {
jest.useFakeTimers()
test('kill the time', () => {
const callback = jest.fn()
// 运行一些使用 setTimeoutsetInterval 的代码
const actual = someFunctionThatUseTimers(callback)
// 运行使用 setTimeoutsetInterval 的代码
const actual
= someFunctionThatUseTimers(callback)
// 快进 250 毫秒
jest.advanceTimersByTime(250)
// 同步检查结果
@ -533,20 +734,29 @@ test('kill the time', () => {
})
```
对于特殊情况,请使用 [jest.runOnlyPendingTimers()](https://jestjs.io/docs/en/timer-mocks#run-pending-timers)。
> 对于特殊情况,请使用 [jest.runOnlyPendingTimers()](https://jestjs.io/docs/en/timer-mocks#run-pending-timers)。
**注意:** 您应该在测试用例中调用 `jest.useFakeTimers()` 以使用其他假计时器方法。
### 模拟 getters 和 setters
### 模拟对象方法
```js
const getTitle = jest.fn(() => 'pizza')
const setTitle = jest.fn()
const location = {}
Object.defineProperty(location, 'title', {
get: getTitle,
set: setTitle,
})
const spy = jest.spyOn(console, 'log')
.mockImplementation(() => {})
expect(console.log.mock.calls)
.toEqual([['dope'], ['nope']])
spy.mockRestore()
```
```js
const spy = jest.spyOn(ajax, 'request')
.mockImplementation(
() => Promise.resolve({success: true})
)
expect(spy).toHaveBeenCalled()
spy.mockRestore()
```
### 清除和恢复模拟
@ -558,8 +768,10 @@ Object.defineProperty(location, 'title', {
// 清除模拟使用日期
// fn.mock.calls、fn.mock.instances
fn.mockClear()
// 清除并删除任何模拟的返回值或实现
fn.mockReset()
// 重置并恢复初始实现
fn.mockRestore()
```
@ -587,7 +799,6 @@ const fs = require('fs')
const fs = require.requireActual('fs')
```
数据驱动测试Jest 23+
----
@ -673,7 +884,6 @@ test('第二个文本', () => {
`Node.js` 和 `Jest` 会缓存你需要的模块。 要测试具有副作用的模块,您需要在测试之间重置模块注册表
另见
----

236
docs/jq.md Normal file
View File

@ -0,0 +1,236 @@
jq 备忘清单
===
这个快速参考备忘单提供了使用 [jq](https://stedolan.github.io/jq/) 命令的各种方法。
入门
----
### 介绍
jq 就像用于 JSON 数据的 [sed](./sed.md) - 您可以使用它来切片、过滤、映射和转换结构化数据
- [jq 官网](https://stedolan.github.io/jq/) _(stedolan.github.io)_
- [jq 命令使用](https://jaywcjlove.github.io/linux-command/c/jq.html) _(jaywcjlove.github.io)_
安装
```bash
$ sudo apt-get install jq # Debian& Ubuntu
$ sudo dnf install jq # Fedora
$ sudo zypper install jq # openSUSE
$ sudo pacman -S jq # Arch
$ brew install jq # macOS & Homebrew
$ port install jq # macOS & MacPorts
```
语法
```bash
$ jq [options] <jq filter> [file...]
$ jq [options] --args <jq filter> [strings...]
$ jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
```
<!--rehype:className=wrap-text -->
### 选项
<!--rehype:wrap-class=col-span-2-->
:- | -
:- | -
`-c` | 紧凑而不是漂亮的输出
`-n` | 使用`null`作为单个输入值
`-e` | 根据输出设置退出状态代码
`-s` | 将所有输入读取(吸取)到数组中;应用过滤器
`-r` | 输出原始字符串而不是JSON文本
`-R` | 读取原始字符串而不是JSON文本
`-C` | 为 JSON 着色
`-M` | 单色不要为JSON着色
`-S` | 在输出上排序对象的键
`--tab` | 使用制表符进行缩进
`--arg a v` | 将变量 `$a` 设置为 value `<v>`
`--argjson a v` | 将变量 `$a` 设置为 JSON value `<v>`
`--slurpfile a f` | 将变量 `$a` 设置为从`<f>`读取的JSON文本数组
`--rawfile a f` | 将变量 `$a` 设置为包含`<f>`内容的字符串
`--args` | 其余参数是字符串参数,而不是文件
`--jsonargs` | 其余的参数是JSON参数而不是文件
`--` | 终止参数处理
学习示例
---
### 获取一个键的值
```bash
$ echo '{"foo": 42, "bar": "less interesting data"}' | jq '.foo'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
42
```
### 数组运算
```bash
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[1]'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
{
"name": "XML",
"good": false
}
```
### 构造一个数组/对象
```bash
$ echo '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}' | jq '{user, title: .titles[]}'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
{
"user": "stedolan",
"title": "JQ Primer"
}
{
"user": "stedolan",
"title": "More JQ"
}
```
### 计算一个值的长度
```bash
$ echo '[[1,2], "string", {"a":2}, null]' | jq '.[] | length'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
2
6
1
0
```
### 取出数组中的键
```bash
$ echo '{"abc": 1, "abcd": 2, "Foo": 3}' | jq 'keys'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
[
"Foo",
"abc",
"abcd"
]
```
### 使用多个过滤器
```bash
$ echo '{ "foo": 42, "bar": "something else", "baz": true}' | jq '.foo, .bar'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
42
"something else"
```
### 管道传递给下一个过滤器
```bash
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[] | .name'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
"JSON"
"XML"
```
### 条件语句判断
```bash
$ echo '[1,5,3,0,7]' | jq 'map(select(. >= 2))'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
[
5,
3,
7
]
```
### 每个输入调用过滤器
```bash
$ echo '[1,2,3]' | jq 'map(.+1)'
```
输出结果
```bash
[
2,
3,
4
]
```
### 条件判断
```bash
$ echo '2' | jq 'if . == 0 then "zero" elif . == 1 then "one" else "many" end'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
"many"
```
### 字符串插入值并进行运算
```bash
$ echo '42' | jq '"The input was \(.), which is one less than \(.+1)"'
```
<!--rehype:className=wrap-text -->
输出结果
```bash
"The input was 42, which is one less than 43"
```
<!--rehype:className=wrap-text -->
另见
----
- [jq 官网](https://stedolan.github.io/jq/) _(stedolan.github.io)_
- [jq 命令使用](https://jaywcjlove.github.io/linux-command/c/jq.html) _(jaywcjlove.github.io)_

View File

@ -75,13 +75,13 @@ JSON 备忘清单
```json
{ "foo": 'bar' }
```
Have to be delimited by double quotes
Have to be delimited by double quotes
### 数字
<!--rehype:wrap-class=row-span-2-->
类型 | 说明
类型 | 说明
-----|------
`Integer` | 数字 1-9、0 和正数或负数
`Fraction` | 0.3、3.9 等分数
@ -297,6 +297,7 @@ let myArray = [
}
];
```
----
| | |
@ -320,7 +321,7 @@ let myArray = [
];
```
-----
----
| | |
|--------------|-----------|
@ -328,10 +329,9 @@ let myArray = [
| `myArray[5]` | true |
| `myArray[6]` | undefined |
另见
----
- [JSON](https://www.json.org/json-en.html) _(json.org)_
- [JSON Editor Online](http://jsoneditoronline.org/) _(jsoneditoronline.org)_
- [Convert JSON Array to Markdown Table, CSV and more](https://tableconvert.com/json-to-markdown) _(tableconvert.com)_
- [Convert JSON Array to Markdown Table, CSV and more](https://tableconvert.com/json-to-markdown) _(tableconvert.com)_

428
docs/koajs.md Normal file
View File

@ -0,0 +1,428 @@
Koajs 备忘清单
===
基于 Node.js 平台的下一代 web 开发框架,包含 [Koa](https://koajs.com/) 的 API 参考列表和一些示例。
入门
---
### Hello World
<!--rehype:wrap-class=row-span-2-->
[Koa](https://koajs.com/) 需要 [node v7.6.0](https://nodejs.org) 或更高版本来支持ES2015、异步方法你可以安装自己支持的 `node` 版本
- 安装依赖
```bash
$ mkdir myapp # 创建目录
$ cd myapp # 进入目录
$ nvm install 7
$ npm init -y # 初始化一个配置
$ npm install koa # 安装依赖
```
- 入口文件 `index.js` 添加代码:
```js
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
```
- 使用以下命令运行应用程序
```bash
$ node index.js
```
<!--rehype:className=style-timeline-->
### 级联
<!--rehype:wrap-class=row-span-2-->
```js
const Koa = require('koa');
const app = new Koa();
// X-Response-Time x 响应时间
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// 记录器 logger
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(
`${ctx.method} ${ctx.url} - ${ms}`
);
});
// 响应 response
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
```
### 配置
:- | :-
:- | :-
`app.env` | 默认为 `NODE_ENV` 或 `development`
`app.keys` | 签名 `cookie` 密钥数组
`app.proxy` | 何时信任真正的代理头字段
`app.subdomainOffset` | 要忽略的 `.subdomains` 的偏移量,默认为 `2`
`app.proxyIpHeader` | 代理 `ip` 头,默认为 `X-Forwarded-For`
`app.maxIpsCount` | 从代理 `ip` 头读取的最大 `ips` 数,默认为 `0`(表示无穷大)
<!--rehype:className=style-list style-list-arrow-->
### app.callback()
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`app.listen(...)` [#](https://koajs.com/#app-listen-) | 为一个绑定 `3000` 端口的简单 `Koa` 应用
`app.callback()` [#](https://koajs.com/#app-callback-) | 返回一个适合 `http.createServer()` 方法的回调函数用来处理请求
`app.use(function)` [#](https://koajs.com/#app-use-function-) | 添加指定的中间件,详情请看 [Middleware](https://github.com/koajs/koa/wiki#middleware)
`app.keys` [#](https://koajs.com/#app-keys-) | 设置签名 `cookie` 密钥
`app.context` [#](https://koajs.com/#app-context) | 从中创建 `ctx` 的原型
<!--rehype:className=style-list style-list-arrow-->
### 错误处理
```js
app.on('error', (err, ctx) => {
log.error('server error', err, ctx)
});
```
默认情况下 `Koa` 会将所有错误信息输出到 `stderr` 除非 `app.silent` 是 `true`。当 `err.status` 是 `404` 或者 `err.expose` 时,默认错误处理程序也不会输出错误
### Context 示例
```js
app.use(async ctx => {
ctx; // 这是上下文 Context
ctx.request; // 这是 koa Request
ctx.response; // 这是 koa Response
});
```
### app.listen(...)
<!--rehype:wrap-class=col-span-2 row-span-2-->
```js
const Koa = require('koa');
const app = new Koa();
app.listen(3000);
```
`app.listen(...)` 实际上是以下代码的语法糖:
```js
const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
```
这意味着您可以同时支持 `HTTPS` 和 `HTTPS`,或者在 `多个端口` 监听同一个应用
```js
const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);
```
### ctx.throw 示例
```js
ctx.throw(400);
ctx.throw(400, 'name required');
ctx.throw(400, 'name required', { user: user });
```
`this.throw('name required', 400)` 等价于
```js
const err = new Error('name required');
err.status = 400;
err.expose = true;
throw err;
```
### ctx.assert 示例
```js
ctx.assert(
ctx.state.user,
401,
'User not found. Please login!'
);
```
### Context(上下文) API
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`ctx.req` | Node 的 request 对象
`ctx.res` | Node 的 response 对象
`ctx.request` | Koa 的 Request 对象
`ctx.response` | Koa 的 Response 对象
`ctx.state` | 推荐的命名空间,用于通过中间件传递信息到前端视图
`ctx.app` | 应用实例引用
`ctx.app.emit` | 发出由第一个参数定义的类型的事件
`ctx.cookies.get(name, [options])` | 获得 `cookie` 中名为 `name` 的值
`ctx.cookies.set(name, value, [options])` | 设置 `cookie` 中名为 `name` 的值
`ctx.throw([status], [msg], [properties])` | 抛出包含 `.status` 属性的错误,默认为 `500`
`ctx.assert(value, [status], [msg], [properties])` | 当 `!value` 时, `Helper` 方法抛出一个类似 `.throw()` 的错误
`ctx.respond` | 避免使用 `Koa` 的内置响应处理功能,您可以直接赋值 `this.repond = false`
<!--rehype:className=style-list style-list-arrow-->
### ctx.cookies.set 参数
:- | :-
:- | :-
`maxAge` | 表示从Date开始的毫秒数 `now()` 到期。
`expires` | 一个 `Date` 对象,指示 `cookie` 的到期日期(默认情况下在会话结束时到期)
`path` | 表示 `cookie` 路径的字符串(默认为`/`
`domain` | 表示 `cookie` 的域的字符串(无默认值)
`secure` | 一个布尔值,指示 `cookie` 是否只通过HTTPS发送HTTP默认为falseHTTPS默认为true。阅读有关此选项的更多信息
`httpOnly` | 一个布尔值指示cookie是否只通过HTTPS发送而不可用于客户端 JavaScript默认为true
`sameSite` | 一个布尔值或字符串指示cookie是否为“同一站点”cookie默认为false。这可以设置为“strict”、“lax”、“none”或true映射为“strect”
`signed` | 一个布尔值指示是否对cookie进行签名默认为false。如果这是真的还将发送另一个附加了.sig后缀的同名cookie其中一个27字节的url安全base64 SHA1值表示cookie name=cookie值相对于第一个Keygrip键的哈希值。此签名密钥用于在下次收到cookie时检测篡改
`overwrite` | 一个布尔值,指示是否覆盖以前设置的同名 `cookie`默认为false。如果为true则在设置此Cookie时将从set-Cookie标头中筛选出在同一请求期间设置的具有相同名称的所有Cookie无论路径或域如何
<!--rehype:className=style-list style-list-arrow-->
### 请求(Request)
<!--rehype:wrap-class=row-span-5-->
:- | :-
:- | :-
`request.header` | 请求头对象
`request.header=` | 设置请求头对象
`request.headers` | 请求头对象。等价于 request.header.
`request.headers=` | 设置请求头对象。 等价于request.header=.
`request.method` | 请求方法
`request.method=` | 设置请求方法, 在实现中间件时非常有用,比如 methodOverride()
`request.length` | 以数字的形式返回 request 的内容长度(Content-Length),或者返回 undefined。
`request.url` | 获得请求url地址.
`request.url=` | 设置请求地址用于重写url地址时
`request.originalUrl` | 获取请求原始地址
`request.origin` | 获取URL原始地址, 包含 protocol 和 host
`request.href` | 获取完整的请求URL, 包含 protocol, host 和 url
`request.path` | 获取请求路径名
`request.path=` | 设置请求路径名并保留当前查询字符串
`request.querystring` | 获取查询参数字符串(url中?后面的部分),不包含?
`request.querystring=` | 设置原始查询字符串
`request.search` | 获取查询参数字符串,包含?
`request.search=` | 设置原始查询字符串
`request.host` | 获取 host (hostname:port)。 当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
`request.hostname` | 获取 hostname。当 app.proxy 设置为 true 时,支持 X-Forwarded-Host。
`request.URL` | 获取 WHATWG 解析的对象.
`request.type` | 获取请求 Content-Type不包含像 "charset" 这样的参数。
`request.charset` | 获取请求 charset没有则返回 `undefined`
`request.query` | 将查询参数字符串进行解析并以对象的形式返回,如果没有查询参数字字符串则返回一个空对象
`request.query=` | 根据给定的对象设置查询参数字符串
`request.fresh` | 检查请求缓存是否 "fresh"(内容没有发生变化)
`request.stale` | 与 req.fresh 相反
`request.protocol` | 返回请求协议,"https" 或者 "http"
`request.secure` | 简化版 this.protocol == "https",用来检查请求是否通过 TLS 发送
`request.ip` | 请求远程地址,当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
`request.ips` | 当 X-Forwarded-For 存在并且 app.proxy 有效,将会返回一个有序(从 upstream 到 downstreamip 数组
`request.subdomains` | 以数组形式返回子域名
`request.is(types...)` | 检查请求所包含的 "Content-Type" 是否为给定的 type 值
`request.accepts(types)` | 检查给定的类型 types(s) 是否可被接受,当为 true 时返回最佳匹配,否则返回 false
`request.acceptsEncodings(encodings)` | 检查 `encodings` 是否可以被接受,当为 `true` 时返回最佳匹配,否则返回 `false`
`request.acceptsCharsets(charsets)` | 检查 `charsets` 是否可以被接受,如果为 `true` 则返回最佳匹配,否则返回 `false`
`request.acceptsLanguages(langs)` | 检查 `langs` 是否可以被接受,如果为 `true` 则返回最佳匹配,否则返回 `false`
`request.idempotent` | 检查请求是否为幂等(idempotent)
`request.socket` | 返回请求的socket
`request.get(field)` | 返回请求头
<!--rehype:className=style-list style-list-arrow-->
### 响应(Response)
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`response.header` | Response header 对象
`response.headers` | Response header 对象。等价于 response.header.
`response.socket` | Request socket.
`response.status` | 获取响应状态。 默认情况下response.status设置为404而不像node's res.statusCode默认为200。
`response.status=` | 通过数字设置响应状态
`response.message` | 获取响应状态消息。默认情况下, response.message关联response.status。
`response.message=` | 将响应状态消息设置为给定值。
`response.length=` | 将响应Content-Length设置为给定值。
`response.length` | 如果 Content-Length 作为数值存在,或者可以通过 ctx.body 来进行计算,则返回相应数值,否则返回 undefined。
`response.body` | 获取响应体。
`response.body=` | 设置响应体为如 `string`,`Buffer`,`Stream`,`Object\|Array`,`null`
`response.get(field)` | 获取 response header 中字段值field 不区分大小写
`response.set(field, value)` | 设置 response header 字段 field 的值为 value
`response.append(field, value)`| 添加额外的字段field 的值为 val
`response.set(fields)` | 使用对象同时设置 response header 中多个字段的值
`response.remove(field)` | 移除 response header 中字段 filed
`response.type` | 获取 response Content-Type不包含像"charset"这样的参数
`response.type=` | 通过 mime 类型的字符串或者文件扩展名设置 response Content-Type
`response.is(types...)` | 跟 `ctx.request.is()` 非常类似。用来检查响应类型是否是所提供的类型之一
`response.redirect(url, [alt])` | 执行 [302] 重定向到对应 url
`response.attachment([filename])` | 设置 "attachment" 的 Content-Disposition用于给客户端发送信号来提示下载
`response.headerSent` | 检查 response header 是否已经发送,用于在发生错误时检查客户端是否被通知。
`response.lastModified` | 如果存在 Last-Modified则以 Date 的形式返回。
`response.lastModified=` | 以 UTC 格式设置 Last-Modified。您可以使用 Date 或 date 字符串来进行设置。
`response.etag=` | 设置 包含 "s 的 ETag
`response.vary(field)` | 不同于field.
`response.flushHeaders()` | 刷新任何设置的响应头,并开始响应体
<!--rehype:className=style-list style-list-arrow-->
### 请求(Request)别名
以下访问器和别名与 [Request](#请求request) 等价:
- `ctx.header`
- `ctx.headers`
- `ctx.method`
- `ctx.method=`
- `ctx.url`
- `ctx.url=`
- `ctx.originalUrl`
- `ctx.origin`
- `ctx.href`
- `ctx.path`
- `ctx.path=`
- `ctx.query`
- `ctx.query=`
- `ctx.querystring`
- `ctx.querystring=`
- `ctx.host`
- `ctx.hostname`
- `ctx.fresh`
- `ctx.stale`
- `ctx.socket`
- `ctx.protocol`
- `ctx.secure`
- `ctx.ip`
- `ctx.ips`
- `ctx.subdomains`
- `ctx.is()`
- `ctx.accepts()`
- `ctx.acceptsEncodings()`
- `ctx.acceptsCharsets()`
- `ctx.acceptsLanguages()`
- `ctx.get()`
### 响应(Response)别名
以下访问器和别名与 [Response](#响应response) 等价:
- `ctx.body`
- `ctx.body=`
- `ctx.status`
- `ctx.status=`
- `ctx.message`
- `ctx.message=`
- `ctx.length=`
- `ctx.length`
- `ctx.type=`
- `ctx.type`
- `ctx.headerSent`
- `ctx.redirect()`
- `ctx.attachment()`
- `ctx.set()`
- `ctx.append()`
- `ctx.remove()`
- `ctx.lastModified=`
- `ctx.etag=`
### request.fresh 示例
```js
// freshness 检查需要状态 20x 或 304
ctx.status = 200;
ctx.set('ETag', '123');
// 缓存正常
if (ctx.fresh) {
ctx.status = 304;
return;
}
// 缓存已过时
// 获取新数据
ctx.body = await db.find('something');
```
### ctx.is 示例
```js
// Content-Type: text/html; charset=utf-8
ctx.is('html'); // => 'html'
ctx.is('text/html'); // => 'text/html'
ctx.is('text/*', 'text/html');
// => 'text/html'
// 当 Content-Type 为 application/json 时
ctx.is('json', 'urlencoded'); // => 'json'
ctx.is('application/json');
// => 'application/json'
ctx.is('html', 'application/*');
// => 'application/json'
ctx.is('html'); // => false
```
### ctx.accepts 示例
```js
// 接受: text/*, application/json
ctx.accepts('html');
// => "html"
ctx.accepts('text/html');
// => "text/html"
ctx.accepts('json', 'text');
// => "json"
ctx.accepts('application/json');
// => "application/json"
```
### request.acceptsCharsets 示例
```js
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets('utf-8', 'utf-7');
// => "utf-8"
ctx.acceptsCharsets(['utf-7', 'utf-8']);
// => "utf-8"
```
检查 `charsets` 是否可以被接受,如果为 `true` 则返回最佳匹配, 否则返回 `false`
### response.set 示例
```js
ctx.set({
'Etag': '1234',
'Last-Modified': date
});
```
使用对象同时设置 response header 中多个字段的值
### response.type 示例
```js
const ct = ctx.type;
// => "image/png"
```
获取 response Content-Type不包含像"charset"这样的参数

421
docs/latex.md Normal file
View File

@ -0,0 +1,421 @@
LaTeX 备忘清单
===
本备忘单总结了 [LaTeX](https://www.latex-project.org/) 常用显示数学符号的参考列表和一些 [KaTeX](https://katex.org/) 的应用示例。
入门
---
### 介绍
[LaTeX](https://www.latex-project.org/) 基于 TEX 的排版系统,适用于生成高印刷质量的科技和数学、物理文档。
- [LaTeX 官网](https://www.latex-project.org/) _(latex-project.org)_
- [KaTeX 官网](https://katex.org/) _(katex.org)_
而 [KaTeX](https://katex.org/) 只处理 LaTeX 的数学符号的一个更小的子集,用于 web 上展示
### 示例
```KaTeX
% \f is defined as #1f(#2) using the macro
f\relax(x) = \int_{-\infty}^\infty
f\hat\xi\,e^{2 \pi i \xi x}
\,d\xi
```
---
```LaTeX
% \f is defined as #1f(#2) using the macro
f\relax(x) = \int_{-\infty}^\infty
f\hat\xi\,e^{2 \pi i \xi x}
\,d\xi
```
### 行内展示
```markdown
基于 KaTeX 在一行
展示示例: `KaTeX:\int_0^\infty x^2 dx`
```
基于 KaTeX 在一行展示示例: `KaTeX:\int_0^\infty x^2 dx`
Supported Functions
---
### Accents
<!--rehype:wrap-class=col-span-2 row-span-2-->
:- | :- | :-
:- | :- | :-
`KaTeX:a'` <pur>`a'`</pur> | `KaTeX:\tilde{a}` <pur>`\tilde{a}`</pur> | `KaTeX:\mathring{g}` <pur>`\mathring{g}`</pur>
`KaTeX:a''` <pur>`a''`</pur> | `KaTeX:\widetilde{ac}` <pur>`\widetilde{ac}`</pur> | `KaTeX:\overgroup{AB}` <pur>`\overgroup{AB}`</pur>
`KaTeX:a^{\prime}` <pur>`a^{\prime}`</pur> | `KaTeX:\utilde{AB}` <pur>`\utilde{AB}`</pur> | `KaTeX:\undergroup{AB}` <pur>`\undergroup{AB}`</pur>
`KaTeX:\acute{a}` <pur>`\acute{a}`</pur> | `KaTeX:\vec{F}` <pur>`\vec{F}`</pur> | `KaTeX:\Overrightarrow{AB}` <pur>`\Overrightarrow{AB}`</pur>
`KaTeX:\bar{y}` <pur>`\bar{y}`</pur> | `KaTeX:\overleftarrow{AB}` <pur>`\overleftarrow{AB}`</pur> | `KaTeX:\overrightarrow{AB}` <pur>`\overrightarrow{AB}`</pur>
`KaTeX:\breve{a}` <pur>`\breve{a}`</pur> | `KaTeX:\underleftarrow{AB}` <pur>`\underleftarrow{AB}`</pur> | `KaTeX:\underrightarrow{AB}` <pur>`\underrightarrow{AB}`</pur>
`KaTeX:\check{a}` <pur>`\check{a}`</pur> | `KaTeX:\overleftharpoon{ac}` <pur>`\overleftharpoon{ac}`</pur> | `KaTeX:\overrightharpoon{ac}` <pur>`\overrightharpoon{ac}`</pur>
`KaTeX:\dot{a}` <pur>`\dot{a}`</pur> | `KaTeX:\overleftrightarrow{AB}` <pur>`\overleftrightarrow{AB}`</pur> | `KaTeX:\overbrace{AB}` <pur>`\overbrace{AB}`</pur>
`KaTeX:\ddot{a}` <pur>`\ddot{a}`</pur> | `KaTeX:\underleftrightarrow{AB}` <pur>`\underleftrightarrow{AB}`</pur> | `KaTeX:\underbrace{AB}` <pur>`\underbrace{AB}`</pur>
`KaTeX:\grave{a}` <pur>`\grave{a}`</pur> | `KaTeX:\overline{AB}` <pur>`\overline{AB}`</pur> | `KaTeX:\overlinesegment{AB}` <pur>`\overlinesegment{AB}`</pur>
`KaTeX:\hat{\theta}` <pur>`\hat{\theta}`</pur> | `KaTeX:\underline{AB}` <pur>`\underline{AB}`</pur> | `KaTeX:\underlinesegment{AB}` <pur>`\underlinesegment{AB}`</pur>
`KaTeX:\widehat{ac}` <pur>`\widehat{ac}`</pur> | `KaTeX:\widecheck{ac}` <pur>`\widecheck{ac}`</pur> | `KaTeX:\underbar{X}` <pur>`\underbar{X}`</pur>
### \text中的强调功能
:- | :- | :-
:- | :- | :-
`KaTeX:\'{a}` <pur>`\'{a}`</pur> | `KaTeX:\~{a}` <pur>`\~{a}`</pur> |
`KaTeX:\.{a}` <pur>`\.{a}`</pur> | `KaTeX:\H{a}` <pur>`\H{a}`</pur> |
``KaTeX:\\\`{a}`` <pur><code>\\&#96;{a}</code></pur> | `KaTeX:\={a}` <pur>`\={a}`</pur> |
`KaTeX:\"{a}` <pur>`\"{a}`</pur> | `KaTeX:\v{a}` <pur>`\v{a}`</pur> |
`KaTeX:\^{a}` <pur>`\^{a}`</pur> | `KaTeX:\u{a}` <pur>`\u{a}`</pur> |
`KaTeX:\r{a}` <pur>`\r{a}`</pur> |
### Delimiter Sizing
:- | :-
:- | :-
`KaTeX:\left(\LARGE{AB}\right)` | <pur>`\left(\LARGE{AB}\right)`</pur>
`KaTeX:( \big( \Big( \bigg( \Bigg(`| <pur>`( \big( \Big( \bigg( \Bigg(`</pur>
---
:- | :- | :- | :- | :-
:- | :- | :- | :- | :-
`\left` | `\big` | `\bigl` | `\bigm` | `\bigr`
`\middle` | `\Big` | `\Bigl` | `\Bigm` | `\Bigr`
`\right` | `\bigg` | `\biggl` | `\biggm` | `\biggr`
`` | `\Bigg` | `\Biggl` | `\Biggm` | `\Biggr`
### 分隔符 Delimiters
<!--rehype:wrap-class=col-span-3-->
预览 | 方法 | 预览 | 方法 | 预览 | 方法 | 预览| 方法 | 预览 | 方法
:- | :- | :- | :- | :- | :- | :- | :- | :- | :-
| `KaTeX:()` | <pur>`()`</pur> | `KaTeX:\lparen \rparen` | <pur>`\lparen` `\rparen`</pur> | `KaTex:⌈ ⌉` | <pur>`⌈ ⌉`</pur> | `KaTex:\lceil \rceil` | <pur>`\lceil` `\rceil`</pur> | `KaTex:\uparrow` | <pur>`\uparrow`</pur> |
| `KaTeX:[]` | <pur>`[]`</pur> | `KaTeX:\lbrack \rbrack` | <pur>`\lbrack` `\rbrack`</pur> | `KaTex:⌊ ⌋` | <pur>`⌊ ⌋`</pur> | `KaTex:\lfloor \rfloor` | <pur>`\lfloor` `\rfloor`</pur> | `KaTex:\downarrow` | <pur>`\downarrow`</pur> |
| `KaTeX:\{ \}` | <pur>`{}`</pur> | `KaTex:\lbrace \rbrace` | <pur>`\lbrace` `\rbrace`</pur> | `KaTex:⎰⎱` | <pur>`⎰⎱`</pur> | `KaTex:\lmoustache \rmoustache` | <pur>`\lmoustache` `\rmoustache`</pur> | `KaTex:\updownarrow` | <pur>`\updownarrow`</pur> |
| `KaTeX:⟨ ⟩` | <pur>`⟨⟩`</pur> | `KaTex:\langle \rangle` | <pur>`\langle` `\rangle`</pur> | `KaTex:⟮ ⟯` | <pur>`⟮ ⟯`</pur> | `KaTex:\lgroup \rgroup` | <pur>`\lgroup` `\rgroup`</pur> | `KaTex:\Uparrow` | <pur>`\Uparrow`</pur> |
| `KaTeX:` | <pur>`\|`</pur> | `KaTex:\vert` | <pur>`\vert`</pur> | `KaTex:┌ ┐` | <pur>`┌ ┐`</pur> | `KaTex:\ulcorner \urcorner` | <pur>`\ulcorner` `\urcorner`</pur> | `KaTex:\Downarrow` | <pur>`\Downarrow`</pur> |
| `KaTeX:\|` _(<red>MD语法冲突</red>)_ | <pur><code>\\&#124;</code></pur> | `KaTex:\Vert` | <pur>`\Vert`</pur> | `KaTex:└ ┘` | <pur>`└ ┘`</pur> | `KaTex:\llcorner \lrcorner` | <pur>`\llcorner` `\lrcorner`</pur> | `KaTex:\Updownarrow` | <pur>`\Updownarrow`</pur> |
| `KaTeX: ` | <pur>`\lvert` `\rvert`</pur> | `KaTex:\lVert \rVert` | <pur>`\lVert` `\rVert`</pur> | | <pur>`\left.`</pur> | | <pur>`\right.`</pur> | `KaTex:\backslash` | <pur>`\backslash`</pur> |
| `KaTeX:\lang` `KaTeX:\rang` | <pur>`\lang` `\rang`<pur> | `KaTeX:\lt \gt` | <pur>`\lt \gt`</pur> | `KaTex:⟦ ⟧` | <pur>`⟦ ⟧`</pur> | `KaTex:\llbracket \rrbracket` | <pur>`\llbracket` `\rrbracket`</pur> | `KaTex:\lBrace \rBrace` | <pur>`\lBrace \rBrace`</pur> |
<!--rehype:className=show-header left-align-->
Environments
---
### Environments 1
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{matrix}
a & b \\
c & d
\end{matrix}
```
```LaTeX
\begin{matrix}
a & b \\
c & d
\end{matrix}
```
### Environments 2
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{array}{cc}
a & b \\
c & d
\end{array}
```
```LaTeX
\begin{array}{cc}
a & b \\
c & d
\end{array}
```
### Environments 3
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}
```
```LaTeX
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}
```
### Environments 4
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
```
```LaTeX
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
```
### Environments 5
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{vmatrix}
a & b \\
c & d
\end{vmatrix}
```
```LaTeX
\begin{vmatrix}
a & b \\
c & d
\end{vmatrix}
```
### Environments 6
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{Vmatrix}
a & b \\
c & d
\end{Vmatrix}
```
```LaTeX
\begin{Vmatrix}
a & b \\
c & d
\end{Vmatrix}
```
### Environments 7
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{Bmatrix}
a & b \\
c & d
\end{Bmatrix}
```
```LaTeX
\begin{Bmatrix}
a & b \\
c & d
\end{Bmatrix}
```
### Environments 8
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\def\arraystretch{1.5}
\begin{array}{c:c:c}
a & b & c \\ \hline
d & e & f \\
\hdashline
g & h & i
\end{array}
```
```LaTeX
\def\arraystretch{1.5}
\begin{array}{c:c:c}
a & b & c \\ \hline
d & e & f \\
\hdashline
g & h & i
\end{array}
```
### Environments 9
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
x = \begin{cases}
a &\text{if } b \\
c &\text{if } d
\end{cases}
```
```LaTeX
x = \begin{cases}
a &\text{if } b \\
c &\text{if } d
\end{cases}
```
### Environments 10
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{rcases}
a &\text{if } b \\
c &\text{if } d
\end{rcases}⇒…
```
```LaTeX
\begin{rcases}
a &\text{if } b \\
c &\text{if } d
\end{rcases}⇒…
```
### Environments 11
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{smallmatrix}
a & b \\
c & d
\end{smallmatrix}
```
```LaTeX
\begin{smallmatrix}
a & b \\
c & d
\end{smallmatrix}
```
### Environments 12
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\sum_{
\begin{subarray}{l}
i\in\Lambda\\
0<j<n
\end{subarray}}
```
```LaTeX
\sum_{
\begin{subarray}{l}
i\in\Lambda\\
0<j<n
\end{subarray}}
```
### Environments 12
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{equation}
\begin{split} a &=b+c\\
&=e+f
\end{split}
\end{equation}
```
<!--rehype:style=flex:1;-->
```LaTeX
\begin{equation}
\begin{split} a &=b+c\\
&=e+f
\end{split}
\end{equation}
```
### Environments 12
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{align}
a&=b+c \\
d+e&=f
\end{align}
```
<!--rehype:style=flex:1;-->
```LaTeX
\begin{align}
a&=b+c \\
d+e&=f
\end{align}
```
### Environments 12
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{gather}
a=b \\
e=b+c
\end{gather}
```
<!--rehype:style=flex:1;-->
```LaTeX
\begin{gather}
a=b \\
e=b+c
\end{gather}
```
### Environments 12
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{alignat}{2}
10&x+&3&y=2\\
3&x+&13&y=4
\end{alignat}
```
<!--rehype:style=flex:1;-->
```LaTeX
\begin{alignat}{2}
10&x+&3&y=2\\
3&x+&13&y=4
\end{alignat}
```
### Environments 12
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
```KaTeX
\begin{CD}
A @>a>> B \\
@VbVV @AAcA \\
C @= D
\end{CD}
```
<!--rehype:style=flex:1;-->
```LaTeX
\begin{CD}
A @>a>> B \\
@VbVV @AAcA \\
C @= D
\end{CD}
```
另见
----
- [LaTeX 官网](https://www.latex-project.org/) _(latex-project.org)_
- [KaTeX 官网](https://katex.org/) _(katex.org)_

566
docs/lerna.md Normal file
View File

@ -0,0 +1,566 @@
Lerna 备忘清单
===
本备忘单旨在快速理解 [Lerna v6](https://github.com/lerna/lerna) 所涉及的主要概念,显示了它的常用命令使用清单。
入门
----
### 介绍
<!--rehype:wrap-class=row-span-2-->
现代构建系统,用于管理和发布来自同一存储库的多个 JavaScript/TypeScript 包。
```bash
$ npx lerna@latest init
```
下面是示例目录结构
```shell {15}
├── README.md
├── remixapp # web 应用 (remixapp)
│   ├── src
│   └── package.json
├── packages
│   ├── footer # 组件(@remixapp/footer)
│ │   ├── src
│ │   └── package.json
│ │
│   └── header # 组件(@remixapp/header)
   ├── src
   └── package.json
├── lerna.json
└── package.json
```
### 引导程序 (Bootstrap)
<!--rehype:wrap-class=row-span-2-->
它在 `package.json` 中依赖于它们,如下所示:
```json {3,4}
"dependencies": {
// ....
"@remixapp/header": "*",
"@remixapp/footer": "*"
}
```
`remixapp` 应用程序导入`页眉`和`页脚`库,如下所示:
```jsx
import { Header } from "header";
import { Footer } from "footer";
export default function Home() {
return (
<>
<Header />
<div>Content!</div>
<Footer />
</>
);
}
```
### useWorkspaces
```json {3}
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true,
"version": "0.0.0"
}
```
<!--rehype:className=wrap-text -->
在 `lerna.json` 中配置 `useWorkspaces` 告诉 `Lerna` 将包链接过程委托给你的包管理器 (此功能由 npm、yarn 和 pnpm 支持)。
### 任务运行
```bash
npx lerna run test --scope=header # 单个
```
多个任务运行
```bash
npx lerna run test --scope=header,footer
```
忽略 `header`,`footer` 其它包中运行任务运行
```bash
npx lerna run build --ignore=header,footer
```
命令索引
---
### run/exec 运行命令
```bash
# 在所有包含它的包中运行 npm run my-script
$ lerna run <script> -- [..args]
$ lerna run test
$ lerna run build
# 观看所有包并在更改时转换,流式前缀输出
$ lerna run --parallel watch
# 在所有包中运行命令
$ lerna exec -- <command> [..args]
$ lerna exec -- rm -rf ./node_modules
$ lerna exec -- protractor conf.js
```
---
:- | :-
:- | :-
`--npm-client <client>` [#](https://github.com/lerna/lerna/tree/main/commands/run#--npm-client-client) | 必须是知道如何运行 npm 生命周期脚本的可执行文件,默认值是 `npm`
`--stream` [#](https://github.com/lerna/lerna/tree/main/commands/run#--stream) | 立即从子进程流式输出,以原始包名称为前缀
`--parallel` [#](https://github.com/lerna/lerna/tree/main/commands/run#--parallel) | 类似于 `--stream` 但完全忽略并发和拓扑排序,立即在所有匹配的包中运行给定的命令或脚本,并带有前缀流输出
`--no-bail` [#](https://github.com/lerna/lerna/tree/main/commands/run#--no-bail) | 默认情况下,如果任何脚本运行返回非零退出代码,`lerna run` 将退出并出现错误。传递 `--no-bail` 以禁用此行为
`--no-prefix` [#](https://github.com/lerna/lerna/tree/main/commands/run#--no-prefix) | 当输出为流式传输(`--stream` 或 `--parallel`)时禁用包名称前缀。当将结果传送到其他进程(例如编辑器插件)时,此选项很有用
`--profile` [#](https://github.com/lerna/lerna/tree/main/commands/run#--profile) | 分析脚本执行并生成性能配置文件
`--profile-location <location>` [#](https://github.com/lerna/lerna/tree/main/commands/run#--profile-location-location) | 您可以为性能配置文件输出提供自定义位置。提供的路径将相对于当前工作目录进行解析。
`useNx=false` [#](https://github.com/lerna/lerna/tree/main/commands/run#usenxfalse) | 通过将 `useNx` 设置为 `false`,您可以使用 `lerna` 中的遗留任务运行实现 (`p-map` 和 `p-queue`),而不是使用由 [Nx](https://nx.dev) 提供支持的默认现代任务运行器实现。
<!--rehype:className=style-list-arrow-->
### publish 发布包
<!--rehype:wrap-class=row-span-3-->
```bash
# 发布自上次发布以来已更改的软件包
$ lerna publish
# 显式发布在当前提交中标记的包
$ lerna publish from-git
# 显式发布注册表中不存在最新版本的软件包
$ lerna publish from-package
# 使用下一个语义预发布版本,例如
$ lerna publish --canary
# 1.0.0 => 1.0.1-alpha.0+${SHA}
# 自上次提交以来更改的包
# 随后的金丝雀发布将产生1.0.1-alpha.1+${SHA}等
$ lerna publish --canary --preid beta
# 1.0.0 => 1.0.1-beta.0+${SHA}
# 以下是等价的:
$ lerna publish --canary minor
$ lerna publish --canary preminor
# 1.0.0 => 1.1.0-alpha.0+${SHA}
```
---
:- | :-
:- | :-
`--canary` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--canary) | 使用此标志运行时,以更精细的方式(每次提交)发布包
`--contents <dir>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--contents-dir) | 要发布的子目录。 必须适用于所有包,并且必须包含 `package.json` 文件
`--dist-tag <tag>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--dist-tag-tag) | 使用此标志运行时,将使用给定的 `npm dist-tag`(默认为 `latest`)发布到 `npm`
`--git-head <sha>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--git-head-sha) | 打包 `tarball` 时将显式 `SHA` 设置为清单上的 `gitHead`,仅允许使用 `from-package` 位置
`--graph-type <all\|dependencies>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--graph-type-alldependencies) | 设置在构建包图时使用哪种依赖项。默认值是依赖项,即仅包含包的 `package.json` 的依赖项部分中列出的包
`--ignore-scripts` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--ignore-scripts) | 传递时,此标志将在 `lerna` 发布期间禁用运行[生命周期脚本](https://github.com/lerna/lerna/tree/main/commands/publish#lifecycle-scripts)
`--ignore-prepublish` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--ignore-prepublish) | 传递时,此标志将禁用在 `lerna` 发布期间运行[已弃用](https://docs.npmjs.com/cli/v8/using-npm/scripts#prepare-and-prepublish)的[预发布脚本](https://github.com/lerna/lerna/tree/main/commands/publish#lifecycle-scripts)
`--legacy-auth` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--legacy-auth) | 发布需要身份验证的包时,您正在使用仅使用旧版 `Base64` `用户名:密码` 的内部托管 NPM 注册表。这与 NPM 发布 `_auth` 标志相同
`--no-git-reset` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--no-git-reset) | 默认情况下,`lerna publish` 确保对工作树的任何更改都已重置
`--no-granular-pathspec` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--no-granular-pathspec) | 默认情况下,`lerna publish` 将尝试(如果启用)`git checkout` 仅在发布过程中临时修改的叶包清单
`--verify-access` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--verify-access) | 从历史上看,`lerna` 试图通过使用给定令牌执行一些抢占式 `npm API` 请求来快速解决授权/身份验证问题
`--otp` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--otp) | 发布需要双重身份验证的包时,您可以使用 `--otp` 指定一次性密码
`--preid` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--preid) | 与同名的 `lerna` 版本选项不同,该选项只适用于 `--canary` 版本计算
`--pre-dist-tag <tag>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--pre-dist-tag-tag) | 与 `--dist-tag` 的工作方式相同,但仅适用于使用预发布版本发布的软件包
`--registry <url>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--registry-url) | 使用此标志运行时,转发的 `npm` 命令将为您的包使用指定的注册表
`--tag-version-prefix` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--tag-version-prefix) | 此选项允许提供自定义前缀而不是默认前缀:`v`
`--temp-tag` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--temp-tag) | 传递时,此标志将更改默认发布过程,首先将所有更改的包发布到临时 `dist-tag(lerna-temp)`,然后将新版本移动到 `--dist-tag` 配置的 `dist-tag` (默认`latest`)
`--yes` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--yes) | 使用此标志运行时,`lerna publish` 将跳过所有确认提示
<!--rehype:className=style-list-arrow-->
#### 不推荐使用的选项
:- | :-
:- | :-
`--no-verify-access` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--no-verify-access) | 旧的抢先访问验证现在默认关闭,因此不需要 `--no-verify-access`
`--skip-npm` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--skip-npm) | 直接调用 [lerna version](#version-修改版本号)
<!--rehype:className=style-list-arrow-->
#### 每个包中的配置
```json
"publishConfig": {
"access": "public",
"registry": "http://my-registry.com",
"tag": "flippin-sweet",
"directory": "dist"
}
```
---
:- | :-
:- | :-
`access` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigaccess) | 要发布具有范围的包(例如,`@mycompany/rocks`)
`registry` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigregistry) | 通过设置注册表来自定义每个包的注册表
`tag` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigtag) | 您可以通过设置标签来自定义每个包的 `dist-tag`
`directory` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigtag) | 这个 _非标准_ 字段允许您像 `--contents` 一样自定义发布的子目录,但基于每个包
<!--rehype:className=style-list-arrow-->
### version 修改版本号
<!--rehype:wrap-class=row-span-3-->
```bash
$ lerna version 1.0.1 # 明确的
$ lerna version patch # semver 关键字
$ lerna version # 从提示中选择
$ lerna version [major | minor | ...]
# 使用下一个语义版本值
# 这会跳过“为...选择新版本”提示
# 强制所有包版本化
$ lerna version --force-publish
$ lerna version -m "chore(doc): publish %s"
# 提交消息 = "chore(doc): publish v1.0.0"
$ lerna version -m "chore(doc): publish %v"
# 提交消息 = "chore(doc): publish 1.0.0"
```
---
- `major` 重大的
- `minor` 次要的
- `patch` 修补
- `premajor` 主要的
- `preminor` 初级
- `prepatch` 预补丁
- `prerelease` 预发行
<!--rehype:className=cols-2-->
---
:- | :-
:- | :-
`--allow-branch <glob>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--allow-branch-glob) | 与启用 `lerna version` 的 `git` 分支匹配的 `glob` 白名单
`--amend` [#](https://github.com/lerna/lerna/tree/main/commands/version#--amend) | 使用此标志运行时,`lerna version` 将在当前提交上执行所有更改,而不是添加新的
`--changelog-preset` [#](https://github.com/lerna/lerna/tree/main/commands/version#--changelog-preset) | 默认情况下,更改日志预设设置为 [angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular#angular-convention)
`--conventional-commits` [#](https://github.com/lerna/lerna/tree/main/commands/version#--conventional-commits) | 使用常规提交规范来确定[版本 bump](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-recommended-bump) 并生成 CHANGELOG.md 文件
`--conventional-graduate` [#](https://github.com/lerna/lerna/tree/main/commands/version#--conventional-graduate) | 将使用 `*` 对指定的包(逗号分隔)或所有包进行分级
`--conventional-prerelease` [#](https://github.com/lerna/lerna/tree/main/commands/version#--conventional-prerelease) | 预发布版本发布指定的包
`--create-release <type>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--create-release-type) | 根据更改的包创建正式的 `GitHub` 或 `GitLab` 版本
`--exact` [#](https://github.com/lerna/lerna/tree/main/commands/version#--exact) | 在更新的包中精确指定更新的依赖项(没有标点符号),而不是与 [semver](./semver.md) 兼容(使用`^`
`--force-publish` [#](https://github.com/lerna/lerna/tree/main/commands/version#--force-publish) | 强制发布指定的包
`--git-remote <name>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--git-remote-name) | 把 `git` 更改推送到指定的远程位置,而不是`origin`
`--ignore-changes` [#](https://github.com/lerna/lerna/tree/main/commands/version#--ignore-changes) | 检测更改的包时忽略与 `glob` 匹配的文件中的更改
`--ignore-scripts` [#](https://github.com/lerna/lerna/tree/main/commands/version#--ignore-scripts) | 禁用在 `lerna version` 期间运行的生命周期脚本
`--include-merged-tags` [#](https://github.com/lerna/lerna/tree/main/commands/version#--include-merged-tags) | 在检测到更改的包时包括来自合并分支的标签
`--message <msg>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--message-msg) | 此选项别名为 `-m` 以与 `git commit` 进行奇偶校验
`--no-changelog` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-changelog) | 使用常规提交时,不要生成任何 CHANGELOG.md 文件
`--no-commit-hooks` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-commit-hooks) | 允许 `git commit hooks` 在提交版本更改时运行。通过 `--no-commit-hooks` 禁用此行为
`--no-git-tag-version` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-git-tag-version) | 将提交对 `package.json` 文件的更改并标记发布。通过 `--no-git-tag-version` 禁用该行为
`--no-granular-pathspec` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-granular-pathspec) | 仅添加在版本控制过程中更改的叶包清单(可能还有变更日志)。这产生了 `git add --packages/*/package.json` 的等价物,但针对更改的内容量身定制
`--no-private` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-private) | 在选择版本、提交和标记版本时包含私有包。通过 `--no-private` 禁用此行为
`--no-push` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-push) | 将已提交和标记的更改推送到配置的 `git remote`。通过 `--no-push` 禁用此行为
`--preid` [#](https://github.com/lerna/lerna/tree/main/commands/version#--preid) | 使用此标志运行时lerna 版本将使用指定的[预发布标识符](https://semver.org/#spec-item-9)增加 `premajor`、`preminor`、`prepatch` 或 `prerelease` [semver](./semver.md) bumps
`--sign-git-commit` [#](https://github.com/lerna/lerna/tree/main/commands/version#--sign-git-commit) | 此选项类似于同名的 npm 版本选项
`--sign-git-tag` [#](https://github.com/lerna/lerna/tree/main/commands/version#--sign-git-tag) | 此选项类似于同名的 `npm` 版本选项
`--force-git-tag` [#](https://github.com/lerna/lerna/tree/main/commands/version#--force-git-tag) | 此选项替换任何现有标记而不是失败
`--tag-version-prefix` [#](https://github.com/lerna/lerna/tree/main/commands/version#--tag-version-prefix) | 此选项允许提供自定义前缀而不是默认前缀:`v`
`--yes` [#](https://github.com/lerna/lerna/tree/main/commands/version#--yes) | 使用此标志运行时,`lerna` 版本将跳过所有确认提示
<!--rehype:className=style-list-arrow-->
#### 不推荐使用的选项
:- | :-
:- | :-
`--cd-version` [#](https://github.com/lerna/lerna/tree/main/commands/version#--cd-version) | 将 `semver` 关键字传递给 [bump](https://github.com/lerna/lerna/tree/main/commands/version#semver-bump) 位置
`--repo-version` [#](https://github.com/lerna/lerna/tree/main/commands/version#--repo-version) | 将明确的版本号传递给 [bump](https://github.com/lerna/lerna/tree/main/commands/version#semver-bump) 位置
`--skip-git` [#](https://github.com/lerna/lerna/tree/main/commands/version#--skip-git) | 请改用 `--no-git-tag-version` 和 `--no-push`
<!--rehype:className=style-list-arrow-->
### bootstrap
将本地包`链接`在一起,并`安装`其余的包依赖项
```bash
$ lerna bootstrap -- --production \
--no-optional
$ lerna bootstrap --hoist
```
:- | :-
:- | :-
`--hoist [glob]` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--strict) | 在 `repo` 根目录安装与 `glob` 匹配的外部依赖项,以便它们可用于所有包
`--strict` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--nohoist-glob) | 与提升 _(hoist)_ 一起使用时,会在发出版本警告后抛出错误并停止引导
`--nohoist [glob]` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--nohoist-glob) | 不要在 `repo` 根目录安装与 `glob` 匹配的外部依赖项。这可用于选择不提升某些依赖项
`--ignore` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--ignore) | 当与 `bootstrap` 命令一起使用时,还可以在 `lerna` 中设置 `--ignore` 标志
<!--rehype:className=style-list-arrow-->
#### 选项
:- | :-
:- | :-
`--ignore-prepublish` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--ignore-prepublish) | 跳过默认在引导程序包中运行的预发布生命周期脚本
`--ignore-scripts` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--ignore-scripts) | 跳过通常在引导程序包中运行(准备等)的任何生命周期脚本
`--registry <url>` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--registry-url) | 指定 npm 包的仓库地址
`--npm-client <client>` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--npm-client-client) | 必须是知道如何安装 `npm` 包依赖项的可执行文件
`--use-workspaces` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--use-workspaces) | 启用与 `Yarn Workspaces` 的集成(从 `yarn@0.27+` 开始可用)
`--no-ci` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--no-ci) | 在 `CI` 环境中调用 `npm ci` 而不是 `npm install`
`--force-local` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--force-local) | 此标志会导致引导命令始终对本地依赖项进行符号链接,而不管匹配的版本范围如何
<!--rehype:className=style-list-arrow-->
### info 本地环境信息
```bash
$ lerna info
lerna notice cli v6.0.0
Environment info:
System(系统):
OS: macOS 12.2
CPU: (8) x64 Apple M1
Binaries(二进制文件):
Node: 16.17.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.5.0 - /usr/local/bin/npm
Utilities(实用程序):
Git: 2.33.0 - /opt/homebrew/bin/git
npmPackages:
lerna: ^6.0.0 => 6.0.0
```
### 过滤选项
<!--rehype:wrap-class=col-span-2 row-span-2-->
```bash
$ lerna exec --scope my-component -- ls -la
$ lerna run --scope toolbar-* test
$ lerna run --scope package-1 --scope *-2 lint
$ lerna exec --ignore package-{1,2,5} -- ls -la
$ lerna run --ignore package-1 test
$ lerna run --ignore package-@(1|2) --ignore package-3 lint
# 列出自最新标签以来已更改的包的内容
$ lerna exec --since -- ls -la
# 对自 main 以来发生更改的所有包运行测试
$ lerna run test --since main
# 列出自 some-branch 以来发生变化的所有包
$ lerna ls --since some-branch
# my-component 及其所有依赖项将被引导
$ lerna bootstrap --scope my-component --include-dependencies
$ lerna bootstrap --scope "package-*" --ignore "package-util-*" --include-dependencies
# 所有匹配 “package-util-*” 的包都将被忽略,除非它们是
# 依赖于名称与 “package-*” 匹配的包
```
#### 选项
:- | :-
:- | :-
`--scope <glob>` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--scope-glob) | 仅包括名称与给定 `glob` 匹配的包
`--ignore <glob>` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--ignore-glob) | 排除名称与给定 `glob` 匹配的包
`--no-private` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--no-private) | 排除私有包
`--since [ref]` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--since-ref) | 仅包括自指定 `ref` 以来已更改的包
`--exclude-dependents` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--exclude-dependents) | 使用 `--since` 运行命令时排除所有传递依赖项覆盖默认的“changed”算法
`--include-dependents` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--include-dependents) | 无论 `--scope`、`--ignore` 或 `--since` 是什么,在运行命令时都包括所有传递依赖项
`--include-dependencies` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--include-dependencies) | 无论 `--scope`、`--ignore` 或 `--since` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--since-ref) 是什么,在运行命令时都包括所有传递依赖项
`--include-merged-tags` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--include-merged-tags) | 使用 `--since` 运行命令时包括来自合并分支的标签
### list
列出本地程序包,也尊重所有可用的[过滤选项](#过滤选项)
```bash
# 与 lerna list 相同,它本身类似于 ls 命令
lerna ls
# 相当于 lerna ls -l显示长输出
lerna ll
# 相当于 lerna ls -la显示所有包(包括私有包)
lerna la
```
#### 选项
:- | :-
:- | :-
`--json` | 显示为 JSON [#](https://github.com/lerna/lerna/tree/main/commands/publish#--json)
`--ndjson` | 换行符分隔 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--ndjson)
`-a,--all` | 所有包 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--all)
`-l,--long` | 显示扩展信息 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--long)
`-p,--parseable` | 显示可解析的输出 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--parseable)
`--toposort` | 按拓扑排序 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--toposort)
`--graph` | JSON 格式邻接依赖关系图 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--graph)
### changed
列出自上次标记版本以来已更改的本地软件包
- `lerna changed` 支持 `lerna ls` 支持的所有[选项](#选项-1)
- 与 `lerna ls` 不同的是不支持过滤器选项
<!--rehype:className=style-round-->
`lerna changed` 支持 `lerna version` 的以下选项
:- | :-
:- | :-
`--conventional-graduate` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--conventional-graduate)
`--force-publish` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--force-publish)
`--ignore-changes` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--ignore-changes)
`--include-merged-tags` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--include-merged-tags)
### init
创建新的 Lerna 仓库或将现有仓库升级到当前版本 Lerna
- 如果 `lerna` 不存在,请将其添加到 `package.json` 中的 `devDependency`
- 创建一个 `lerna.json` 配置文件来存储版本号
- 如果不存在 `.gitignore`,则生成一个忽略文件
<!--rehype:className=style-timeline-->
---
```shell
$ lerna init --independent
```
---
:- | :-
:- | :-
`--independent` [#](https://github.com/lerna/lerna/tree/main/commands/init#--independent) | 使用独立版本控制模式 [#](https://github.com/lerna/lerna/tree/main/commands/init#--independent)
`--exact` [#](https://github.com/lerna/lerna/tree/main/commands/init#--exact) | 添加或更新 `lerna` 的本地版本时将使用插入符范围 [#](https://github.com/lerna/lerna/tree/main/commands/init#--exact)
它将配置 `lerna.json` 以强制所有后续执行完全匹配
```js
{
"command": {
"init": {
"exact": true
}
},
"version": "0.0.0"
}
```
### import
将一个包导入到带有提交历史的 `monorepo`
```bash
# 开始使用 Lerna
$ git init lerna-repo && cd lerna-repo
$ npx lerna init
$ npm install
# 添加提交
$ git add .
# 如果没有提交,导入命令将失败
$ git commit -m "Initial lerna commit"
# 导入其他存储库
$ npx lerna import <外部存储库的路径>
$ npx lerna import ~/Product --flatten
```
选项
:- | :-
:- | :-
`--flatten` [#](https://github.com/lerna/lerna/tree/main/commands/import#--flatten) | 当导入具有冲突的合并提交的存储库时,导入命令将无法尝试应用所有提交
`--dest` [#](https://github.com/lerna/lerna/tree/main/commands/import#--dest) | 导入仓库时,可以通过 `lerna.json` 中列出的目录来指定目标目录
`--preserve-commit` [#](https://github.com/lerna/lerna/tree/main/commands/import#--preserve-commit) | 每个 git 提交都有一个作者和一个提交者
<!--rehype:className=style-list-arrow-->
### add
<!--rehype:wrap-class=row-span-2-->
将依赖项添加到匹配的包
```shell
$ lerna add <package>[@version] \
[--dev] [--exact] [--peer]
```
选项
:- | :-
:- | :-
`--dev` [#](https://github.com/lerna/lerna/tree/main/commands/add#--dev) | 将新包添加到 `devDependencies`
`--exact` [#](https://github.com/lerna/lerna/tree/main/commands/add#--exact) | 添加具有精确版本(例如 `1.0.1`)而不是默认 `^` semver 范围(例如 `^1.0.1`)的新包
`--peer` [#](https://github.com/lerna/lerna/tree/main/commands/add#--peer) | 将新包添加到 `peerDependencies`
`--registry <url>` [#](https://github.com/lerna/lerna/tree/main/commands/add#--registry-url) | 使用自定义注册表安装目标包
`--no-bootstrap` [#](https://github.com/lerna/lerna/tree/main/commands/add#--no-bootstrap) | 跳过链式 `lerna bootstrap`
<!--rehype:className=style-list-arrow-->
实例
```bash
# 将 mod-1 包添加到“prefix-”前缀文件夹中的包中
$ lerna add mod-1 packages/prefix-*
# 将 mod-1 安装到mod-2
$ lerna add mod-1 --scope=mod-2
# 在 devDependencies 中安装 mod-1 到 mod-2
$ lerna add mod-1 --scope=mod-2 --dev
# 在 peerDependencies 中安装 mod-1 到 mod-2
$ lerna add mod-1 --scope=mod-2 --peer
# 在除 mod-1 之外的所有模块中安装 mod-1
$ lerna add mod-1
# 在所有模块中安装 babel-core
$ lerna add babel-core
```
### diff
比较自上次发布以来的所有包或单个包
```bash
$ lerna diff [package]
$ lerna diff
$ lerna diff package-name # 区分一个特定的包
```
类似于 `lerna changed`,此命令运行 `git diff`
### clean
从所有包中删除 `node_modules` 目录
```bash
$ lerna clean
```
接受所有[过滤选项](#过滤选项)。`lerna clean` 不会从根 `node_modules` 目录中删除模块,即使您启用了 `--hoist` 选项
### add-caching
运行设置基本缓存选项的向导
```bash
$ lerna add-caching
```
### link
将所有相互依赖的包符号链接在一起
```bash
$ lerna link
```
[`--force-local`](https://github.com/lerna/lerna/tree/main/commands/link#--force-local) 设置会导致链接命令始终对本地依赖项进行符号链接
### repair
更新配置文件以匹配当前安装的 lerna 版本
```bash
$ npm i lerna@latest
$ lerna repair
```
[`lerna repair`](https://github.com/lerna/lerna/tree/main/core/lerna/commands/repair#usage) 在升级后最有用,可确保应用新版本 lerna 的任何配置文件更改

718
docs/lessjs.md Normal file
View File

@ -0,0 +1,718 @@
Less 备忘清单
===
本备忘单旨在快速理解 [Less](https://github.com/less/less.js) 所涉及的主要概念,显示了它的常用方法使用清单。
入门
---
### 介绍
Less(Leaner Style Sheets 的缩写)是一门向后兼容的 [`CSS`](./css.md) 扩展语言
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
- [在线编译预览](http://lesscss.org/less-preview/#eyJjb2RlIjoiI2xpYigpIHtcbiAgICAuY29sb3JzKCkge1xuICAgICAgQHByaW1hcnk6IGJsdWU7XG4gICAgICBAc2Vjb25kYXJ5OiBncmVlbjtcbiAgICB9XG4gICAgLnJ1bGVzKEBzaXplKSB7XG4gICAgICBib3JkZXI6IEBzaXplIHNvbGlkIHdoaXRlO1xuICAgIH1cbiAgfVxuICBcbiAgLmJveCB3aGVuICgjbGliLmNvbG9yc1tAcHJpbWFyeV0gPSBibHVlKSB7XG4gICAgd2lkdGg6IDEwMHB4O1xuICAgIGhlaWdodDogKCR3aWR0aCAvIDIpO1xuICB9XG4gIFxuICAuYmFyOmV4dGVuZCguYm94KSB7XG4gICAgQG1lZGlhIChtaW4td2lkdGg6IDYwMHB4KSB7XG4gICAgICB3aWR0aDogMjAwcHg7XG4gICAgICAjbGliLnJ1bGVzKDFweCk7XG4gICAgfVxuICB9IiwiYWN0aXZlVmVyc2lvbiI6IjQueCJ9) _(lesscss.org)_
在 Node.js 环境中使用 `Less`
```bash
$ npm install -g less
$ lessc styles.less styles.css
```
在浏览器环境中使用 `Less`
```html
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="https://cdn.jsdelivr.net/npm/less@4" ></script>
```
<!--rehype:className=wrap-text -->
### 变量(Variables)
```less
@width: 10px;
@height: @width + 10px;
#header {
width: @width;
height: @height;
}
```
编译 css 为:
```css
#header {
width: 10px;
height: 20px;
}
```
另见: [变量的更多信息](https://lesscss.org/features/#variables-feature)
### 混合(Mixins)
```less {1,8,13}
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu a {
color: #111;
.bordered();
}
.post a {
color: red;
.bordered();
}
```
另见: [混合(Mixin)的更多信息](https://lesscss.org/features/#mixins-feature)
### 嵌套(Nesting)
```css
#header {
color: black;
}
#header .navigation {
font-size: 12px;
}
#header .logo {
width: 300px;
}
```
👇👇 更改为 less 的写法 ✅ 👇👇
```less
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
```
### 父选择器 &
```less
.button {
color: blue;
&-ok {
background-image: url("ok.png");
}
&:hover {
color: green;
}
}
```
编译 css 为:
```css
.button {
color: blue;
}
.button-ok {
background-image: url("ok.png");
}
.button:hover {
color: green;
}
```
### @规则嵌套和冒泡
<!--rehype:wrap-class=row-span-2-->
```less
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-image: url(/img/icon2x.png);
}
}
@media (min-width: 1280px) {
width: 800px;
}
}
```
编译 css 为:
```css
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/icon2x.png);
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}
```
<!--rehype:className=wrap-text -->
### 运算(Operations)
<!--rehype:wrap-class=row-span-2-->
算术运算符 `+`、`-`、`*`、`/` 对任何数字、颜色或变量进行运算
```less
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果 -1.5cm
@incompatible-units: 2 + 5px - 3cm;
// 结果是 4px
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%
@base: 2cm * 3mm; // 结果是 6cm
@color: (#224488 / 2); // 结果是 #112244
background-color: #112244 + #111;
// 结果是 #223355
@color: #222 / 2;
// 结果是 `#222 / 2`, not #111
background-color: (#FFFFFF / 16);
// 结果是 #101010
```
#### calc() 特例
为了与 `CSS` 保持兼容,`calc()` 并不对数学表达式进行计算,但是在嵌套函数中会计算变量和数学公式的值
```less
@var: 50vh/2;
width: calc(50% + (@var - 20px));
// 结果是 calc(50% + (25vh - 20px))
```
### 转义(Escaping)
<!--rehype:wrap-class=row-span-2-->
```less
@min768: ~"(min-width: 768px)";
.element {
@media @min768 {
font-size: 1.2rem;
}
}
```
编译 css 为:
```css
@media (min-width: 768px) {
.element {
font-size: 1.2rem;
}
}
```
从 Less 3.5 开始,可以简写为
```less
@min768: (min-width: 768px);
.element {
@media @min768 {
font-size: 1.2rem;
}
}
```
在 Less 3.5+ 版本中,许多以前需要“引号转义”的情况就不再需要了
### 函数(Functions)
```less
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width); // 返回 `50%`
color: saturate(@base, 5%);
background-color:
spin(lighten(@base, 25%), 8);
}
```
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等
### 命名空间和访问符
```less
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white;
}
}
.tab { ... }
.citation { ... }
}
```
把 `.button` 类混合到 `#header a` 中,我们可以这样做
```less
#header a {
color: orange;
#bundle.button();
// 还可以书写为 #bundle > .button 形式
}
```
### 映射(Maps)
```less
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}
```
输出符合预期(css)
```css
.button {
color: blue;
border: 1px solid green;
}
```
另见:[映射(Maps)](https://lesscss.org/features/#maps-feature)
### 作用域Scope
```less
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}
```
和上面实例代码相同
```less
@var: red;
#page {
#header {
color: @var; // white
}
@var: white;
}
```
另见:[懒加载](https://lesscss.org/features/#variables-feature-lazy-loading)
### 注释Comments
```less
/* 一个块注释
* style comment! */
@var: red;
// 这一行被注释掉了!
@var: white;
```
块注释和行注释都可以使用
### 导入Importing
```less
@import "library"; // library.less
@import "typo.css";
```
另见:[导入(Importing)的知识](https://lesscss.org/features/#imports-feature)
### Extend
<!--rehype:wrap-class=row-span-2-->
```less
nav ul {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
```
编译 css 为:
```css
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
```
函数
---
### 逻辑函数 if & boolean
```less
@bg: black;
@bg-light: boolean(luma(@bg) > 50%);
div {
background: @bg;
color: if(@bg-light, black, white);
}
```
编译 css 为:
```css
div {
background: black;
color: white;
}
```
### 字符串函数
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`escape` | 将 [URL 编码](http://en.wikipedia.org/wiki/Percent-encoding)应用于输入字符串中的特殊字符
`e` | 字符串转义
`%` | 第一个参数是带有占位符的字符串
```less
escape('a=1') // 输出 a%3D1
@mscode: "ms:alwaysHasItsOwnSyntax.For.Stuff()"
filter: e(@mscode);
// 输出 filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
format-a-d: %("repetitions: %a file: %d", 1 + 2, "directory/file.less");
// 输出 format-a-d: "repetitions: 3 file: "directory/file.less"";
```
### 替换字符串 replace
<!--rehype:wrap-class=col-span-2-->
```less
replace("Hello, Mars?", "Mars\?", "Earth!");
replace("One + one = 4", "one", "2", "gi");
replace('This is a string.', "(string)\.$", "new $1.");
replace(~"bar-1", '1', '2');
```
预期输出
```
"Hello, Earth!";
"2 + 2 = 4";
'This is a new string.';
bar-2;
```
### length
```less
@list: "banana", "tomato", "potato", "peach";
n: length(@list);
```
预期输出
```css
n: 4;
```
返回值列表中的元素数
### extract
```less
@list: apple, pear, coconut, orange;
value: extract(@list, 3);
```
预期输出
```css
value: coconut;
```
返回列表中指定位置的值
### range
```less
value: range(4);
// 输出 value: 1 2 3 4;
value: range(10px, 30px, 10);
// 输出 value: 10px 20px 30px;
```
生成跨越一系列值的列表
### each
<!--rehype:wrap-class=row-span-3-->
```less
@selectors: blue, green, red;
each(@selectors, {
.sel-@{value} {
a: b;
}
});
```
预期输出
```css
.sel-blue {
a: b;
}
.sel-green {
a: b;
}
.sel-red {
a: b;
}
```
每个列表成员的每个规则集都绑定到 `@value`、`@key` 和 `@index` 变量
```less
@set: {
one: blue;
two: green;
three: red;
}
.set {
each(@set, {
@{key}-@{index}: @value;
});
}
```
预期输出
```css
.set {
one-1: blue;
two-2: green;
three-3: red;
}
```
将规则集的评估绑定到列表的每个成员
### each()
```less
set-2() {
one: blue;
two: green;
three: red;
}
.set-2 {
// 调用 mixin 并迭代每个规则
each(.set-2(), .(@v, @k, @i) {
@{k}-@{i}: @v;
});
}
```
预期输出
```css
.set-2 {
one-1: blue;
two-2: green;
three-3: red;
}
```
### 使用 `range` 和 `each` 创建一个 `for` 循环
```less
each(range(4), {
.col-@{value} {
height: (@value * 50px);
}
});
```
预期输出
```css
.col-1 {
height: 50px;
}
.col-2 {
height: 100px;
}
.col-3 {
height: 150px;
}
.col-4 {
height: 200px;
}
```
### 数学函数
<!--rehype:wrap-class=row-span-3-->
:- | :-
:- | :-
`ceil(2.4)` _(输出 3)_ | 向上舍入到下一个最大整数 [#](https://lesscss.org/functions/#math-functions-ceil)
`floor(2.6)` _(输出 2)_ | 向下舍入到下一个最小整数 [#](https://lesscss.org/functions/#math-functions-floor)
`percentage(0.5)` _(输出 50%)_ | 将浮点数转换为百分比字符串 [#](https://lesscss.org/functions/#math-functions-floor)
`round(1.67)` _(输出 2)_ | 应用舍入 [#](https://lesscss.org/functions/#math-functions-round)
`sqrt(25cm)` _(输出 5cm)_ | 计算数字的平方根。保持单位不变 [#](https://lesscss.org/functions/#math-functions-sqrt)
`abs(25cm)` _(输出 25cm)_ | 计算数字的绝对值。 保持单位不变 [#](https://lesscss.org/functions/#math-functions-abs)
`sin(1deg)` _(输出 0.01745240643728351)_ | 计算正弦函数 [#](https://lesscss.org/functions/#math-functions-sin)
`asin(-0.8414709848078965)` _(输出 -1rad)_ | 计算反正弦(正弦的倒数)函数 [#](https://lesscss.org/functions/#math-functions-asin)
`cos(1deg)` _(输出 0.9998476951563913)_ | 计算余弦函数 [#](https://lesscss.org/functions/#math-functions-cos)
`acos(0.5403023058681398)` _(输出 1rad)_ | 计算反余弦(余弦的倒数)函数 [#](https://lesscss.org/functions/#math-functions-acos)
`tan(1deg)` _(输出 0.017455064928217585)_ | 计算正切函数 [#](https://lesscss.org/functions/#math-functions-tan)
`atan(-1.5574077246549023)` _(输出 -1rad)_ | 计算反正切(正切的倒数)函数 [#](https://lesscss.org/functions/#math-functions-atan)
`pi()` _(输出 3.141592653589793)_ | π (pi) [#](https://lesscss.org/functions/#math-functions-pi)
`pow(0cm, 0px)` _(输出 1cm)_ | 返回第一个参数的第二个参数次幂的值 [#](https://lesscss.org/functions/#math-functions-pow)
`mod(11cm, 6px)` _(输出 5cm)_ | 返回第一个参数模数第二个参数的值 [#](https://lesscss.org/functions/#math-functions-mod)
`min(5, 10)` _(输出 5)_ | 返回一个或多个值中的最小值 [#](https://lesscss.org/functions/#math-functions-min)
`max(5, 10)` _(输出 10)_ | 返回一个或多个值中的最大值 [#](https://lesscss.org/functions/#math-functions-min)
<!--rehype:className=style-list-arrow-->
### 颜色定义函数
:- | :-
:- | :-
`rgb`| [#](https://lesscss.org/functions/#color-definition-rgb)
`rgba`| [#](https://lesscss.org/functions/#color-definition-rgba)
`argb`| [#](https://lesscss.org/functions/#color-definition-argb)
`hsl`| [#](https://lesscss.org/functions/#color-definition-hsl)
`hsla`| [#](https://lesscss.org/functions/#color-definition-hsla)
`hsv`| [#](https://lesscss.org/functions/#color-definition-hsv)
`hsva`| [#](https://lesscss.org/functions/#color-definition-hsva)
### 类型函数
:- | :-
:- | :-
`isnumber`| 值是否为数字 [#](https://lesscss.org/functions/#type-functions-isnumber)
`isstring`| 值是否为字符串 [#](https://lesscss.org/functions/#type-functions-isstring)
`iscolor`| 值是否为颜色值 [#](https://lesscss.org/functions/#type-functions-iscolor)
`iskeyword`| 值是否为 keyword [#](https://lesscss.org/functions/#type-functions-iskeyword)
`isurl`| 值是否为 url 值 [#](https://lesscss.org/functions/#type-functions-isurl)
`ispixel`| 值是否为像素值 [#](https://lesscss.org/functions/#type-functions-ispixel)
`isem`| 值是否为 em 值 [#](https://lesscss.org/functions/#type-functions-isem)
`ispercentage`| 值是否为 百分百 值 [#](https://lesscss.org/functions/#type-functions-ispercentage)
`isunit`| 值是是否为指定单位的数字 [#](https://lesscss.org/functions/#type-functions-isunit)
`isruleset`| 值是否为规则集 [#](https://lesscss.org/functions/#type-functions-isruleset)
`isdefined`| 值是否为 defined [#](https://lesscss.org/functions/#type-functions-isdefined)
### 杂项函数
:- | :-
:- | :-
`color`| [#](https://lesscss.org/functions/#misc-functions-color)
`image-size`| [#](https://lesscss.org/functions/#misc-functions-image-size)
`image-width`| [#](https://lesscss.org/functions/#misc-functions-image-width)
`image-height`| [#](https://lesscss.org/functions/#misc-functions-image-height)
`convert`| [#](https://lesscss.org/functions/#misc-functions-convert)
`data-uri`| [#](https://lesscss.org/functions/#misc-functions-data-uri)
`default`| [#](https://lesscss.org/functions/#misc-functions-default)
`unit`| [#](https://lesscss.org/functions/#misc-functions-unit)
`get-unit`| [#](https://lesscss.org/functions/#misc-functions-get-unit)
`svg-gradient`| [#](https://lesscss.org/functions/#misc-functions-svg-gradient)
### 颜色通道函数
:- | :-
:- | :-
`hue`| [#](https://lesscss.org/functions/#color-channel-hue)
`saturation`| [#](https://lesscss.org/functions/#color-channel-saturation)
`lightness`| [#](https://lesscss.org/functions/#color-channel-lightness)
`hsvhue`| [#](https://lesscss.org/functions/#color-channel-hsvhue)
`hsvsaturation`| [#](https://lesscss.org/functions/#color-channel-hsvsaturation)
`hsvvalue`| [#](https://lesscss.org/functions/#color-channel-hsvvalue)
`red`| [#](https://lesscss.org/functions/#color-channel-red)
`green`| [#](https://lesscss.org/functions/#color-channel-green)
`blue`| [#](https://lesscss.org/functions/#color-channel-blue)
`alpha`| [#](https://lesscss.org/functions/#color-channel-alpha)
`luma`| [#](https://lesscss.org/functions/#color-channel-luma)
`luminance`| [#](https://lesscss.org/functions/#color-channel-luminance)
### 色彩运算函数
:- | :-
:- | :-
`saturate`| [#](https://lesscss.org/functions/#color-operations-saturate)
`desaturate`| [#](https://lesscss.org/functions/#color-operations-desaturate)
`lighten`| [#](https://lesscss.org/functions/#color-operations-lighten)
`darken`| [#](https://lesscss.org/functions/#color-operations-darken)
`fadein`| [#](https://lesscss.org/functions/#color-operations-fadein)
`fadeout`| [#](https://lesscss.org/functions/#color-operations-fadeout)
`fade`| [#](https://lesscss.org/functions/#color-operations-fade)
`spin`| [#](https://lesscss.org/functions/#color-operations-spin)
`mix`| [#](https://lesscss.org/functions/#color-operations-mix)
`tint`| [#](https://lesscss.org/functions/#color-operations-tint)
`shade`| [#](https://lesscss.org/functions/#color-operations-shade)
`greyscale`| [#](https://lesscss.org/functions/#color-operations-greyscale)
`contrast`| [#](https://lesscss.org/functions/#color-operations-contrast)
### 颜色混合功能
:- | :-
:- | :-
`multiply`| [#](https://lesscss.org/functions/#color-blending-multiply)
`screen`| [#](https://lesscss.org/functions/#color-blending-screen)
`overlay`| [#](https://lesscss.org/functions/#color-blending-overlay)
`softlight`| [#](https://lesscss.org/functions/#color-blending-softlight)
`hardlight`| [#](https://lesscss.org/functions/#color-blending-hardlight)
`difference`| [#](https://lesscss.org/functions/#color-blending-difference)
`exclusion`| [#](https://lesscss.org/functions/#color-blending-exclusion)
`average`| [#](https://lesscss.org/functions/#color-blending-average)
`negation`| [#](https://lesscss.org/functions/#color-blending-negation)
另见
---
- [Less.js 官网](http://lesscss.org) _(lesscss.org)_
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
- [Stylus 备忘清单](./stylus.md) _(jaywcjlove.github.io)_
- [在线编译预览](http://lesscss.org/less-preview/#eyJjb2RlIjoiI2xpYigpIHtcbiAgICAuY29sb3JzKCkge1xuICAgICAgQHByaW1hcnk6IGJsdWU7XG4gICAgICBAc2Vjb25kYXJ5OiBncmVlbjtcbiAgICB9XG4gICAgLnJ1bGVzKEBzaXplKSB7XG4gICAgICBib3JkZXI6IEBzaXplIHNvbGlkIHdoaXRlO1xuICAgIH1cbiAgfVxuICBcbiAgLmJveCB3aGVuICgjbGliLmNvbG9yc1tAcHJpbWFyeV0gPSBibHVlKSB7XG4gICAgd2lkdGg6IDEwMHB4O1xuICAgIGhlaWdodDogKCR3aWR0aCAvIDIpO1xuICB9XG4gIFxuICAuYmFyOmV4dGVuZCguYm94KSB7XG4gICAgQG1lZGlhIChtaW4td2lkdGg6IDYwMHB4KSB7XG4gICAgICB3aWR0aDogMjAwcHg7XG4gICAgICAjbGliLnJ1bGVzKDFweCk7XG4gICAgfVxuICB9IiwiYWN0aXZlVmVyc2lvbiI6IjQueCJ9) _(lesscss.org)_

223
docs/lsof.md Normal file
View File

@ -0,0 +1,223 @@
Lsof 备忘清单
===
这个快速参考备忘单提供了使用 lsof 命令的各种方法。
入门
----
### 介绍
**lsof** 表示 `L`i`s`t `O`pen `F`iles 用于查找哪个进程打开了哪些文件
```shell
$ lsof
$ sudo lsof -u root
```
### 特定于端口
```shell
$ lsof -i :8080
$ lsof -i :80 -i :22
$ lsof -i TCP:22
$ lsof -i TCP:1-1024
$ lsof -i UDP
$ lsof -i @192.168.1.5
```
### 特定于进程
```shell
$ lsof -c mysql
$ lsof -c java
$ lsof -c ssh
$ lsof -c nginx
$ lsof -c ssh -c httpd
```
### 特定于用户
```shell
$ lsof -u www-data
$ lsof -u www-data -u ubuntu
$ lsof -i -u ^root # 特定用户除外
```
### 特定于网络
```shell
$ lsof -i 4 # 仅 IPv4
$ lsof -i 6 # 仅 IPv6
```
### 特定的PID
```shell
$ lsof -p 1753
$ lsof -p ^3 # 除了某些pid
```
### 特定文件名
```shell
$ lsof /var/log/messages
$ lsof /etc/passwd
```
### 特定目录
```shell
$ lsof +D /var/log # 在目录内
```
### Kill
```shell
$ kill -9 `lsof -t -u apache`
$ kill -9 $(lsof -t -i :8080)
```
### 参数
<!--rehype:wrap-class=row-span-2-->
```bash
-a # 列出打开文件存在的进程;
-c<进程名> # 列出指定进程所打开的文件;
-g # 列出GID号进程详情
-d<文件号> # 列出占用该文件号的进程;
+d<目录> # 列出目录下被打开的文件;
+D<目录> # 递归列出目录下被打开的文件;
-n<目录> # 列出使用NFS的文件
-i<条件> # 列出符合条件的进程(协议,:端口,@ip)
-p<进程号> # 列出指定进程号所打开的文件;
-u # 列出UID号进程详情
-h # 显示帮助信息;
-v # 显示版本信息
```
### 列出指定进程号所打开的文件
```bash
lsof -p $pid
```
### 获取端口对应的进程 ID=>pid
```bash
lsof -i:9981 -P -t -sTCP:LISTEN
```
### 列出打开文件的进程
```bash
lsof $filename
```
示例
---
### 示例
<!--rehype:wrap-class=col-span-2-->
```bash
$ lsof
command PID USER FD type DEVICE SIZE NODE NAME
init 1 root cwd DIR 8,2 4096 2 /
init 1 root rtd DIR 8,2 4096 2 /
init 1 root txt REG 8,2 43496 6121706 /sbin/init
init 1 root mem REG 8,2 143600 7823908 /lib64/ld-2.5.so
init 1 root mem REG 8,2 1722304 7823915 /lib64/libc-2.5.so
init 1 root mem REG 8,2 23360 7823919 /lib64/libdl-2.5.so
init 1 root mem REG 8,2 95464 7824116 /lib64/libselinux.so.1
init 1 root mem REG 8,2 247496 7823947 /lib64/libsepol.so.1
init 1 root 10u FIFO 0,17 1233 /dev/initctl
migration 2 root cwd DIR 8,2 4096 2 /
migration 2 root rtd DIR 8,2 4096 2 /
migration 2 root txt unknown /proc/2/exe
```
### 文件描述符列表(FD)
<!--rehype:wrap-class=row-span-3-->
:- | :-
:- | :-
`cwd` | 表示当前工作目录,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
`txt` | 该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
`lnn` | 库引用 (AIX);
`er` | FD 信息错误(参见名称栏)
`jld` | jail 目录 (FreeBSD);
`ltx` | 共享库文本(代码和数据)
`mxx` | 十六进制内存映射类型编号xx
`m86` | DOS合并映射文件
`mem` | 内存映射文件
`mmap` | 内存映射设备
`pd` | 父目录
`rtd` | 根目录
`tr` | 内核跟踪文件 (OpenBSD)
`v86` | VP/ix 映射文件
`0` | 表示标准输出
`1` | 表示标准输入
`2` | 表示标准错误
<!--rehype:className=style-list-arrow-->
### 示例列信息
:- | :-
:- | :-
`COMMAND` | 进程的名称
`PID` | 进程标识符
`PPID` | 父进程标识符(需要指定-R参数
`USER` | 进程所有者
`PGID` | 进程所属组
`FD` | 文件描述符,应用程序通过它识别该文件
### 标准输出/输入/错误文件状态模式(FD)
:- | :-
:- | :-
`u` | 表示该文件被打开并处于读取/写入模式
`r` | 表示该文件被打开并处于只读模式
`w` | 表示该文件被打开并处于写入模式
`空格` | 表示该文件的状态模式为 unknow且没有锁定
`-` | 表示该文件的状态模式为 unknow且被锁定
一般在[标准输出/输入/错误](#文件描述符列表fd)后还跟着文件状态模式
### 文件状态模锁 (FD)
:- | :-
:- | :-
`N` | 对于未知类型的Solaris NFS锁
`r` | 用于部分文件的读取锁定
`R` | 对整个文件进行读取锁定
`w` | 对文件的一部分进行写锁定(文件的部分写锁)
`W` | 对整个文件进行写锁定(整个文件的写锁)
`u` | 用于任何长度的读写锁
`U` | 对于未知类型的锁
`x` | 对于文件部分的SCO OpenServer Xenix锁
`X` | 对于整个文件的SCO OpenServer Xenix锁
`space` | 如果没有锁
在[文件状态模式](#标准输出输入错误文件状态模式fd)后面,还跟着相关的锁
### 文件类型
标识 | 说明
:- | :-
`DIR` | 表示目录
`CHR` | 表示字符类型
`BLK` | 块设备类型
`UNIX` | UNIX 域套接字
`FIFO` | 先进先出 (FIFO) 队列
`IPv4` | 网际协议 (IP) 套接字
`DEVICE` | 指定磁盘的名称
`SIZE` | 文件的大小
`NODE` | 索引节点(文件在磁盘上的标识)
`NAME` | 打开文件的确切名称
`REG` | 常规文件
另见
---
- [lsof 命令帮助文档](https://jaywcjlove.github.io/linux-command/c/lsof.html) _(jaywcjlove.github.io)_

View File

@ -3,7 +3,6 @@ Markdown 备忘清单
这是 Markdown 语法的快速参考备忘单。
Markdown 快速参考
----
@ -30,7 +29,6 @@ Header 2
--------
```
### 块引用
```markdown
@ -64,6 +62,7 @@ Header 2
+ Item 1
+ Item 2
```
或者**任务**列表
```markdown
@ -132,11 +131,13 @@ ___
### 代码
~~~markdown
```markdown
```javascript
console.log("This is a block code")
```
~~~
```
```markdown
~~~css
@ -144,12 +145,10 @@ console.log("This is a block code")
~~~
```
```markdown
4 空格缩进做一个代码块
```
#### 内联代码
```markdown
@ -246,4 +245,4 @@ Markdown 表格生成器:[tableconvert.com](https://tableconvert.com/)
另见
----
- [GitHub 风格的 Markdown 规范](https://github.github.com/gfm/) _(github.com)_
- [GitHub 风格的 Markdown 规范](https://github.github.com/gfm/) _(github.com)_

1417
docs/matlab.md Normal file

File diff suppressed because it is too large Load Diff

105
docs/mime.md Normal file
View File

@ -0,0 +1,105 @@
MIME 类型 备忘清单
===
此备忘单列出了一些常见的 Web MIME 类型。 您可以查看包含所有已注册 MIME 类型的 [IANA/MIME 媒体类型注册表](https://www.iana.org/assignments/media-types/media-types.xhtml)。
入门
----
### 介绍
<!--rehype:style=display:none;&wrap-style=padding-top:0;&wrap-class=col-span-3-->
- MIME 类型注册表关联特定的文件扩展名和文件名模式
- MIME多用途 Internet 邮件扩展)类型又名媒体类型
- MIME 类型在 IETF 的 RFC 6838 中定义和标准化
- 表示文档、文件或字节分类的性质和格式。
- 对于 Internet 上的文件格式或格式内容
<!--rehype:className=style-round-->
MIME 类型列表
--------
### 常见的 MIME媒体类型
<!--rehype:wrap-class=col-span-3-->
扩展名 | MIME 类型(内容类型) | 文件种类
:-|:-|:-
\.aac | audio/aac | AAC 音频
\.abw | application/x\-abiword | AbiWord 文档
\.arc | application/x\-freearc | 存档文档(嵌入多个文件)
\.avi | video/x\-msvideo | AVI: 音频视频交错
\.azw | application/vnd\.amazon\.ebook | 亚马逊 Kindle 电子书格式
\.bin | application/octet\-stream | 任何类型的二进制数据
\.bmp | image/bmp | Windows OS/2 位图图形
\.bz | application/x\-bzip | BZip 存档
\.bz2 | application/x\-bzip2 | BZip2 存档
\.csh | application/x\-csh | C\-Shell 脚本
\.css | text/css | 级联样式表 (CSS)
\.csv | text/csv | 逗号分隔值 (CSV)
\.doc | application/msword | 微软 Word
\.docx | application/vnd\.openxmlformats\-officedocument\.wordprocessingml\.document | 微软 Word (OpenXML)
\.eot | application/vnd\.ms\-fontobject | MS 嵌入式 OpenType 字体
\.epub | application/epub\+zip | 电子出版物 (EPUB)
\.gz | application/gzip | GZip 压缩存档
\.gif | image/gif | 图形交换格式 (GIF)
\.htm \.html | text/html | 超文本标记语言 (HTML)
\.ico | image/vnd\.microsoft\.icon | 图标格式
\.ics | text/calendar | iCalendar 格式
\.jar | application/java\-archive | Java 存档 (JAR)
\.jpeg \.jpg | image/jpeg | JPEG 图像
\.js | text/javascript | JavaScript
\.json | application/json | JSON格式
\.jsonld | application/ld\+json | JSON\-LD 格式
\.mid \.midi | audio/midi audio/x\-midi | 乐器数字接口 (MIDI)
\.mjs | text/javascript | JavaScript 模块
\.mp3 | audio/mpeg | MP3 音频
\.mpeg | video/mpeg | MPEG 视频
\.mpkg | application/vnd\.apple\.installer\+xml | Apple 安装程序包
\.odp | application/vnd\.oasis\.opendocument\.presentation | OpenDocument 演示文档
\.ods | application/vnd\.oasis\.opendocument\.spreadsheet | OpenDocument 电子表格文档
\.odt | application/vnd\.oasis\.opendocument\.text | OpenDocument 文本文档
\.oga | audio/ogg | OGG 音频
\.ogv | video/ogg | OGG 视频
\.ogx | application/ogg | OGG
\.opus | audio/opus | Opus 音频
\.otf | font/otf | OpenType 字体
\.png | image/png | 便携式网络图形
\.pdf | application/pdf | Adobe 便携式文档格式 (PDF)
\.php | application/php | 超文本预处理器(个人主页)
\.ppt | application/vnd\.ms\-powerpoint | 微软PowerPoint
\.pptx | application/vnd\.openxmlformats\-officedocument\.presentationml\.presentation | 微软 PowerPoint (OpenXML)
\.rar | application/vnd\.rar | RAR 存档
\.rtf | application/rtf | 富文本格式 (RTF)
\.sh | application/x\-sh | Bourne shell 脚本
\.svg | image/svg\+xml | 可缩放矢量图形 (SVG)
\.swf | application/x\-shockwave\-flash | 小型 Web 格式 (SWF) 或 Adobe Flash 文档
\.tar | application/x\-tar | Tape 存档 (TAR)
\.tif \.tiff | image/tiff | 标记图像文件格式 (TIFF)
\.ts | video/mp2t | MPEG 传输流
\.ttf | font/ttf | TrueType 字体
\.txt | text/plain | 文本,(通常为 ASCII 或 ISO 8859\-n
\.vsd | application/vnd\.visio | 微软 Visio
\.wav | audio/wav | Waveform 音频格式
\.weba | audio/webm | WEBM 音频
\.webm | video/webm | WEBM视频
\.webp | image/webp | WEBP图像
\.woff | font/woff | Web 开放字体格式 (WOFF)
\.woff2 | font/woff2 | Web 开放字体格式 (WOFF)
\.xhtml | application/xhtml\+xml | XHTML
\.xls | application/vnd\.ms\-excel | Microsoft Excel
\.xlsx | application/vnd\.openxmlformats\-officedocument\.spreadsheetml\.sheet | Microsoft Excel (OpenXML)
\.xml | application/xml 如果临时用户不可读(RFC 3023第 3 节) text/xml如果临时用户可读(RFC 3023第 3 节) | XML
\.xul | application/vnd\.mozilla\.xul\+xml | XUL
\.zip | application/zip | ZIP 档案
\.3gp | video/3gpp audio/3gpp 如果它不包含视频 | 3GPP 音视频容器
\.3g2 | video/3gpp2 audio/3gpp2 如果它不包含视频 | 3GPP2 音视频容器
\.7z | application/x\-7z\-compressed | 7-zip 存档
\.markdown \.md | text/markdown | Markdown 文件
<!--rehype:className=show-header-->
另见
---
- [iana mime.types](http://www.iana.org/assignments/media-types/media-types.xhtml) _(iana.org)_
- [apache mime.types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types) _(svn.apache.org)_
- [nginx mime.types](http://hg.nginx.org/nginx/raw-file/default/conf/mime.types) _(hg.nginx.org)_

603
docs/mysql.md Normal file
View File

@ -0,0 +1,603 @@
MySQL 备忘清单
===
本备忘单旨在快速理解 [MySQL](https://mysql.com) 所涉及的主要概念提供了最常用的SQL语句供您参考。
入门
---
### 介绍
<!--rehype:wrap-class=row-span-3-->
MySQL 为关系型数据库(Relational Database Management System),一个关系型数据库由一个或数个表格组成,如下所示的一个表格
----
```bash
name ▼ 键 ▼ 列(col)
┌┈┈┈┈┬┈┈┈┈┈┈┈┈┬┈┈┈┈┈┈┬┈┈┈┈┈┈┈┐
┆ id ┆ name ┆ uid ┆ level ┆ ◀ 表头header
├┈┈┈┈┼┈┈┈┈┈┈┈┈┤┈┈┈┈┈┈┤┈┈┈┈┈┈┈┤
1 ┆ mysql ┆ 03
├┈┈┈┈┼┈┈┈┈┈┈┈┈┤┈┈┈┈┈┈┤┈┈┈┈┈┈┈┤
2 ┆ redis ┆ 121 ┆ ◀ 行 row
└┈┈┈┈┴┈┈┈┈┈┈┈┈┴┈┈┈┈┈┈┴┈┈┈┈┈┈┈┘
redis ▲ 值
```
----
- `表头(header)` 每一列的名称
- `列(col)` 具有相同数据类型的数据的集合
- `行(row)` 每一行用来描述某个人/物的具体信息
- `值(value)` 行的具体信息,每个值与该列数据类型相同
- `键(key)` 用来识别某个特定的人/物的方法,有唯一性
### 登录MySQL
```shell
# 默认用户名<root>-p 是密码,
# ⚠️参数后面不需要空格
mysql -h 127.0.0.1 -u <用户名> -p<密码>
mysql -D 数据库名 -h 主机名 -u 用户名 -p
mysql -h <host> -P <端口号> -u <user> -p [db_name]
mysql -h <host> -u <user> -p [db_name]
```
### 常用的
<!--rehype:wrap-class=row-span-3-->
#### 数据库 Database
:-|:-
:-|:-
`CREATE DATABASE` db `;` | `创建`数据库
`SHOW DATABASES;` | `列出`数据库
`USE` db`;` | `切换`到数据库
`CONNECT` db `;` | `切换`到数据库
`DROP DATABASE` db`;` | `删除`数据库
#### 表 Table
:-|:-
:-|:-
`SHOW TABLES;` | 列出当前数据库的表
`SHOW FIELDS FROM` t`;` | 表的列表字段
`DESC` t`;` | 显示表格结构
`SHOW CREATE TABLE`t`;` | 显示创建表sql
`TRUNCATE TABLE`t`;` | 删除表中的所有数据
`DROP TABLE`t`;` | 删除表格
#### Proccess
:-|:-
:-|:-
`show processlist;` | 列出进程
`kill` pid`;` | 杀死进程
### 查看 MySQL 信息
```shell
# 显示当前mysql的version的各种信息
mysql> status;
# 显示当前mysql的version信息
mysql> select version();
# 查看 MySQL 端口号
mysql> show global variables like 'port';
```
### 退出MySQL会话
```bash
mysql> exit
```
退出 `quit;``\q;` 一样的效果
### 备份
创建备份
```sql
mysqldump -u user -p db_name > db.sql
```
导出不带架构的数据库
```shell
mysqldump -u user -p db_name --no-data=true --add-drop-table=false > db.sql
```
<!--rehype:className=wrap-text -->
恢复备份
```shell
mysql -u user -p db_name < db.sql
```
MySQL 示例
------
### 管理表格
创建一个包含三列的新表
```sql
CREATE TABLE t (
id INT,
name VARCHAR DEFAULT NOT NULL,
price INT DEFAULT 0
PRIMARY KEY(id)
);
```
从数据库中删除表
```sql
DROP TABLE t ;
```
向表中添加新列
```sql
ALTER TABLE t ADD column;
```
从表中删除列c
```sql
ALTER TABLE t DROP COLUMN c ;
```
添加约束
```sql
ALTER TABLE t ADD constraint;
```
删除约束
```sql
ALTER TABLE t DROP constraint;
```
将表从t1重命名为t2
```sql
ALTER TABLE t1 RENAME TO t2;
```
将列c1重命名为c2
```sql
ALTER TABLE t1 RENAME c1 TO c2 ;
```
删除表中的所有数据
```sql
TRUNCATE TABLE t;
```
### 从表中查询数据
从表中查询列c1、c2中的数据
```sql
SELECT c1, c2 FROM t
```
查询表中的所有行和列
```sql
SELECT * FROM t
```
查询数据并使用条件筛选行
```sql
SELECT c1, c2 FROM t
WHERE condition
```
查询表中的不同行
```sql
SELECT DISTINCT c1 FROM t
WHERE condition
```
按升序或降序对结果集排序
```sql
SELECT c1, c2 FROM t
ORDER BY c1 ASC [DESC]
```
跳过行的偏移并返回下n行
```sql
SELECT c1, c2 FROM t
ORDER BY c1
LIMIT n OFFSET offset
```
使用聚合函数对行进行分组
```sql
SELECT c1, aggregate(c2)
FROM t
GROUP BY c1
```
使用HAVING子句筛选组
```sql
SELECT c1, aggregate(c2)
FROM t
GROUP BY c1
HAVING condition
```
### 从多个表查询
<!--rehype:wrap-class=row-span-2-->
内部连接 t1 和 t2
```sql
SELECT c1, c2
FROM t1
INNER JOIN t2 ON condition
```
左连接t1和t1
```sql
SELECT c1, c2
FROM t1
LEFT JOIN t2 ON condition
```
右连接t1和t2
```sql
SELECT c1, c2
FROM t1
RIGHT JOIN t2 ON condition
```
执行完全外部连接
```sql
SELECT c1, c2
FROM t1
FULL OUTER JOIN t2 ON condition
```
生成表中行的笛卡尔积
```sql
SELECT c1, c2
FROM t1
CROSS JOIN t2
```
执行交叉连接的另一种方法
```sql
SELECT c1, c2
FROM t1, t2
```
使用INNER Join子句将t1连接到自身
```sql
SELECT c1, c2
FROM t1 A
INNER JOIN t1 B ON condition
```
使用SQL运算符合并两个查询中的行
```sql
SELECT c1, c2 FROM t1
UNION [ALL]
SELECT c1, c2 FROM t2
```
返回两个查询的交集
```sql
SELECT c1, c2 FROM t1
INTERSECT
SELECT c1, c2 FROM t2
```
从另一个结果集中减去一个结果集
```sql
SELECT c1, c2 FROM t1
MINUS
SELECT c1, c2 FROM t2
```
使用模式匹配%查询行_
```sql
SELECT c1, c2 FROM t1
WHERE c1 [NOT] LIKE pattern
```
查询列表中的行
```sql
SELECT c1, c2 FROM t
WHERE c1 [NOT] IN value_list
```
查询两个值之间的行
```sql
SELECT c1, c2 FROM t
WHERE c1 BETWEEN low AND high
```
检查表中的值是否为NULL
```sql
SELECT c1, c2 FROM t
WHERE c1 IS [NOT] NULL
```
### 使用 SQL 约束
将c1和c2设置为主键
```sql
CREATE TABLE t(
c1 INT, c2 INT, c3 VARCHAR,
PRIMARY KEY (c1,c2)
);
```
将c2列设置为外键
```sql
CREATE TABLE t1(
c1 INT PRIMARY KEY,
c2 INT,
FOREIGN KEY (c2) REFERENCES t2(c2)
);
```
使c1和c2中的值唯一
```sql
CREATE TABLE t(
c1 INT, c1 INT,
UNIQUE(c2,c3)
);
```
确保c1>0和c1>=c2中的值
```sql
CREATE TABLE t(
c1 INT, c2 INT,
CHECK(c1> 0 AND c1 >= c2)
);
```
c2列中的设置值不为NULL
```sql
CREATE TABLE t(
c1 INT PRIMARY KEY,
c2 VARCHAR NOT NULL
);
```
### 修改数据
在表格中插入一行
```sql
INSERT INTO t(column_list)
VALUES(value_list);
```
在表格中插入多行
```sql
INSERT INTO t(column_list)
VALUES (value_list),
(value_list), ;
```
将行从t2插入t1
```sql
INSERT INTO t1(column_list)
SELECT column_list
FROM t2;
```
更新列c1中所有行的新值
```sql
UPDATE t
SET c1 = new_value;
```
更新列c1、c2中与条件匹配的值
```sql
UPDATE t
SET c1 = new_value,
c2 = new_value
WHERE condition;
```
删除表中的所有数据
```sql
DELETE FROM t;
```
删除表中的行子集
```sql
DELETE FROM t
WHERE condition;
```
### 管理视图
<!--rehype:wrap-class=row-span-2-->
创建由c1和c2组成的新视图
```sql
CREATE VIEW v(c1,c2)
AS
SELECT c1, c2
FROM t;
```
使用选中选项创建新视图
```sql
CREATE VIEW v(c1,c2)
AS
SELECT c1, c2
FROM t;
WITH [CASCADED | LOCAL] CHECK OPTION;
```
创建递归视图
```sql
CREATE RECURSIVE VIEW v
AS
select-statement -- anchor part
UNION [ALL]
select-statement; -- recursive part
```
创建临时视图
```sql
CREATE TEMPORARY VIEW v
AS
SELECT c1, c2
FROM t;
```
删除视图
```sql
DROP VIEW view_name;
```
### 管理触发器
创建或修改触发器
```sql
CREATE OR MODIFY TRIGGER trigger_name
WHEN EVENT
ON table_name TRIGGER_TYPE
EXECUTE stored_procedure;
```
#### WHEN
:-|:-
:-|:-
`BEFORE` | 在事件发生前调用
`AFTER` | 事件发生后调用
#### EVENT
:-|:-
:-|:-
`INSERT` | 为INSERT调用
`UPDATE` | 调用UPDATE
`DELETE` | 调用DELETE
#### TRIGGER_TYPE
:-|:-
:-|:-
`FOR EACH ROW` | -
`FOR EACH STATEMENT` | -
### 管理索引
在t表的c1和c2上创建索引
```sql
CREATE INDEX idx_name
ON t(c1,c2);
```
在t表的c3、c4上创建唯一索引
```sql
CREATE UNIQUE INDEX idx_name
ON t(c3,c4)
```
删除索引
```sql
DROP INDEX idx_name;
```
MySQL 数据类型
---------
### Strings
| - | - |
|--------------|-----------------------------|
| `CHAR` | String (0 - 255) |
| `VARCHAR` | String (0 - 255) |
| `TINYTEXT` | String (0 - 255) |
| `TEXT` | String (0 - 65535) |
| `BLOB` | String (0 - 65535) |
| `MEDIUMTEXT` | String (0 - 16777215) |
| `MEDIUMBLOB` | String (0 - 16777215) |
| `LONGTEXT` | String (0 - 429496­7295) |
| `LONGBLOB` | String (0 - 429496­7295) |
| `ENUM` | One of preset options |
| `SET` | Selection of preset options |
### Date & time
| Data Type | Format |
|-------------|---------------------|
| `DATE` | yyyy-MM-dd |
| `TIME` | hh:mm:ss |
| `DATETIME` | yyyy-MM-dd hh:mm:ss |
| `TIMESTAMP` | yyyy-MM-dd hh:mm:ss |
| `YEAR` | yyyy |
### Numeric
| - | - |
|---------------|---------------------------------------------------------------|
| `TINYINT x` | Integer (-128 to 127) |
| `SMALLINT x` | Integer (-32768 to 32767) |
| `MEDIUMINT x` | Integer (-8388608 to 8388607) |
| `INT x` | Integer (-2147­483648 to 214748­3647) |
| `BIGINT x` | Integer (-9223­372­036­854­775808 to 922337­203­685­477­5807) |
| `FLOAT` | Decimal (precise to 23 digits) |
| `DOUBLE` | Decimal (24 to 53 digits) |
| `DECIMAL` | "­DOU­BLE­" stored as string |
另见
---
- [SQL 基础教程](http://www.w3school.com.cn/sql/index.asp) _(w3school.com.cn)_
- [SQL 语句教程](http://www.1keydata.com/cn/sql/sql-count.php) _(1keydata.com)_
- [21分钟 MySQL 基础入门](https://jaywcjlove.github.io/mysql-tutorial/21-minutes-MySQL-basic-entry.html) _(jaywcjlove.github.io)_

229
docs/netcat.md Normal file
View File

@ -0,0 +1,229 @@
Netcat 备忘清单
===
该备忘单提供了在 Linux 和 Unix 上使用 Netcat 的各种方法。
入门
------
<!--rehype:body-class=cols-5-->
### 用法
<!--rehype:wrap-class=col-span-2-->
连接到位于任何地方的主机
```shell
$ nc [options] [host] [port]
```
监听传入连接
```shell
$ nc -lp port [host] [port]
```
### 选项示例
<!--rehype:wrap-class=col-span-3 row-span-2-->
选项 | 示例 | 说明
:- | :- | :-
`-h` | nc -h | 帮助
`-z` | nc -z 192.168.1.9 1-100 | 端口扫描主机或 `IP` 地址
`-v` | nc -zv 192.168.1.9 1-100 | 提供详细输出
`-n` | nc -zn 192.168.1.9 1-100 | 通过禁用 `DNS` 解析进行快速扫描
`-l` | nc -lp 8000 | `TCP` 侦听模式 _(用于入站连接)_
`-w` | nc -w 180 192.168.1.9 8000 | 定义超时值
`-k` | nc -kl 8000 | 断线后继续收听
`-u` | nc -u 192.168.1.9 8000 | 使用 `UDP` 而不是 `TCP`
`-q` | nc -q 1 192.168.1.9 8000 | 客户在 `EOF` 后熬夜
`-4` | nc -4 -l 8000 | 仅限 `IPv4`
`-6` | nc -6 -l 8000 | 仅限 `IPv6`
### 聊天客户端-服务器
<!--rehype:wrap-class=col-span-2-->
服务器 Server (192.168.1.9)
```shell
$ nc -lv 8000
```
客户端 Client
```shell
$ nc 192.168.1.9 8000
```
Netcat 示例
--------
### Banner 抓取
```shell
$ nc website.com 80
GET index.html HTTP/1.1
HEAD / HTTP/1.1
```
或者
```shell
echo "" | nc -zv -wl 192.168.1.1 801-805
```
### 端口扫描
扫描 `21``25` 之间的端口
```shell
$ nc -zvn 192.168.1.1 21-25
```
扫描端口 `22``3306``8080`
```shell
$ nc -zvn 192.168.1.1 22 3306 8080
```
### 代理和端口转发
```shell
$ nc -lp 8001 -c "nc 127.0.0.1 8000"
```
或者
```shell
$ nc -l 8001 | nc 127.0.0.1 8000
```
创建从一个本地端口到另一个本地端口的隧道
### 下载文件
服务器 Server (192.168.1.9)
```shell
$ nc -lv 8000 < file.txt
```
客户端 Client
```shell
$ nc -nv 192.168.1.9 8000 > file.txt
```
假设您想将文件 `file.txt` 从服务器 A 传输到客户端 B。
### 上传文件
服务器 Server (192.168.1.9)
```shell
$ nc -lv 8000 > file.txt
```
客户端 Client
```shell
$ nc 192.168.1.9 8000 < file.txt
```
假设您想将文件 `file.txt` 从客户端 `B` 传输到服务器 `A`
### 目录传输
服务器 Server (192.168.1.9)
```shell
$ tar -cvf dir_name | nc -l 8000
```
客户端 Client
```shell
$ nc -n 192.168.1.9 8000 | tar -xvf -
```
假设您想通过网络将目录从 `A` 传输到 `B`
### 加密传输
<!--rehype:wrap-class=col-span-2-->
服务器 Server (192.168.1.9)
```shell
$ nc -l 8000 | openssl enc -d -des3 -pass pass:password > file.txt
```
客户端 Client
```shell
$ openssl enc -des3 -pass pass:password | nc 192.168.1.9 8000
```
在通过网络传输之前加密数据
### 克隆
服务器 Server (192.168.1.9)
```shell
$ dd if=/dev/sda | nc -l 8000
```
客户端 Client
```shell
$ nc -n 192.168.1.9 8000 | dd of=/dev/sda
```
克隆 linux PC 非常简单。假设你的系统盘是 /dev/sda
### 视频流
服务器 Server (192.168.1.9)
```shell
$ cat video.avi | nc -l 8000
```
客户端 Client
```shell
$ nc 192.168.1.9 8000 | mplayer -vo x11 -cache 3000 -
```
使用 netcat 流式传输视频
### 远程 shell
服务器 Server (192.168.1.9)
```shell
$ nc -lv 8000 -e /bin/bash
```
客户端 Client
```shell
$ nc 192.168.1.9 8000
```
我们已经使用 `telnet``ssh` 使用远程 `Shell`,但是如果它们没有安装并且我们没有安装它们的权限,那么我们也可以使用 `netcat` 创建远程 `shell`
### 逆转 shell
服务器 Server (192.168.1.9)
```shell
$ nc -lv 8000
```
客户端 Client
```shell
$ nc 192.168.1.9 8000 -v -e /bin/bash
```
反向 `shell` 通常用于绕过防火墙限制,例如阻止入站连接

206
docs/netstat.md Normal file
View File

@ -0,0 +1,206 @@
Netstat 备忘清单
===
此快速参考备忘单提供了各种使用 netstat 命令的方法
入门
-----
### 入门实例
端口 80 上的所有连接
```shell
$ netstat -anp | grep :80
```
网络统计帮助
```shell
$ netstat -h
```
### 监听
选项 | 说明
:- | :-
`netstat -ltunp` | 所有监听端口
`netstat -ltn` | 监听 TCP 端口
`netstat -lun` | 监听 UDP 端口
`netstat -lx` | 监听 Unix 端口
`netstat -lt` | 仅列出侦听 TCP 端口
`netstat -lu` | 仅列出侦听 UDP 端口
`netstat -l` | 列出所有监听条件
### 连接
<!--rehype:wrap-class=row-span-2-->
选项 | 说明
:- | :-
`netstat -a` | 所有连接
`netstat -at` | 所有 TCP 连接
`netstat -au` | 所有 UDP 连接
`netstat -ant` | 显示没有反向 DNS 查找的 IP 地址
选项 | 说明
:- | :-
`netstat` | 活动连接
`netstat -a` | 所有连接
`netstat -at` | 所有 TCP 连接
`netstat -au` | 所有 UDP 连接
`netstat -ant` | 显示没有反向 DNS 查找的 IP 地址
`netstat -tnl` | 监听 TCP 端口
`netstat -unl` | 监听 UDP 端口
### 网络
选项 | 说明
:- | :-
`netstat -i` | 显示网络接口
`netstat -ie` | 显示网络接口扩展信息
`netstat -n` | 仅显示 IP 地址
`netstat -F` | 尽可能显示 IP 地址的域名
### 路由
选项 | 说明
:- | :-
`netstat -r` | 显示路由表
`netstat -rn` | 显示路由表,不解析主机
### 统计数据
<!--rehype:wrap-class=row-span-3-->
选项 | 说明
:- | :-
`netstat -s` | 显示统计信息
`netstat -st` | 显示 TCP 统计信息
`netstat -su` | 显示 UDP 统计信息
`netstat -ltpe` | 使用进程信息和扩展信息显示 TCP 的侦听连接
`netstat -tp` | 显示带有 PID 编号的服务名称
`sudo netstat -nlpt` | 列出进程名称/PID 和用户 ID
`netstat -nlptue` | 所有带有 PID 和扩展信息的侦听端口
`netstat -M` | 显示伪装的连接
### 显示没有域名的 TCP 连接
```bash
$ netstat --tcp --numeric
```
### 显示活动/已建立的连接
```bash
$ netstat -atnp | grep ESTA
```
### 获取活动连接的连续列表
```bash
$ watch -d -n0 "netstat -atnp | grep ESTA"
```
### 显示到特定端口的所有打开连接
```bash
$ netstat -anp | grep":"
```
插入`端口`号(上图)代替冒号 `:`
### 检查服务是否正在运行
```bash
$ sudo netstat -aple | grep ntp
```
你可以用`http``smtp`代替`ntp`
Netstat 安全命令
---
### 显示具有大量连接的 IP
<!--rehype:wrap-class=col-span-3-->
```bash
$ netstat -tn 2>/dev/null | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
```
<!--rehype:className=wrap-text -->
### 连接到端口 80 的 IP 地址
<!--rehype:wrap-class=col-span-3-->
```bash
$ netstat -tn 2>/dev/null | grep ':80 ' | awk '{print $5}' |sed -e 's/::ffff://' | cut -f1 -d: | sort | uniq -c | sort -rn | head
```
<!--rehype:className=wrap-text -->
### 显示端口 80 上的活动连接数
```bash
$ netstat -an |grep :80 |wc -l
```
### 仅显示外部 IP 地址
<!--rehype:wrap-class=col-span-2-->
```bash
$ netstat -antu | grep :80 | grep -v LISTEN | awk '{print $5}'
```
### 显示活动 SYNC_REC
<!--rehype:wrap-class=row-span-2-->
以下命令将输出服务器上正在发生和正在发生的活动 `SYNC_REC` 数量。数量应该很低(小于 `5`)。如果该数字为两位数,则您可能正在遭受 `DoS` 攻击或被邮件轰炸。
```bash
$ netstat -n -p|grep SYN_REC | wc -l
```
#### 列出发送 SYN_REC 连接的唯一 IP 地址
```bash
$ netstat -n -p | grep SYN_REC | awk '{print $5}' | awk -F: '{print $1}'
```
<!--rehype:className=wrap-text -->
与上面的命令一样,该命令也列出了发送 `SYN_REC` 连接状态的节点的所有唯一 `IP` 地址
### 每个远程 IP 的连接数
<!--rehype:wrap-class=col-span-2-->
```bash
$ netstat -antu | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -n
```
<!--rehype:className=wrap-text -->
或者
```bash
$ netstat -antu | awk '$5 ~ /[0-9]:/{split($5, a, ":"); ips[a[1]]++} END {for (ip in ips) print ips[ip], ip | "sort -k1 -nr"}'
```
<!--rehype:className=wrap-text -->
### 检查开放端口ipv4 和 ipv6
```bash
$ netstat -plntu
```
### 检查开放端口ipv4 和 ipv6
```bash
$ netstat -plnt
```
### 每个 IP 的打开连接数
```bash
$ netstat -an | grep 80 | wc -l
```
### 活跃的互联网连接
```bash
$ netstat -pnut -w | column -t -s $'\t'
```

869
docs/nginx.md Normal file
View File

@ -0,0 +1,869 @@
NGINX 备忘清单
===
这个 [nginx](https://nginx.org/en/) 快速参考备忘单显示了它的常用命和配置使用清单。
入门
----
### 服务管理
<!--rehype:wrap-class=row-span-2-->
```bash
sudo systemctl status nginx # nginx当前状态
sudo systemctl reload nginx # 重新加载 nginx
sudo systemctl restart nginx # 重启nginx
sudo nginx -t # 检查语法
nginx # 启动
nginx -s reload # 重启
nginx -s stop # 关闭进程
nginx -s quit # 平滑关闭nginx
nginx -V # 查看nginx的安装状态
```
### Docker 安装
<!--rehype:wrap-class=col-span-2-->
```bash
docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx
```
### 简单代理
<!--rehype:wrap-class=col-span-2-->
```nginx
location / {
proxy_pass http://127.0.0.1:3000;
proxy_redirect off;
proxy_set_header Host $host;
}
```
### 全局变量
<!--rehype:wrap-class=col-span-2 row-span-4-->
| 变量 | 说明
:- | :-
`$args` | 这个变量等于请求行中的参数,同 `$query_string`
`$remote_port` | 客户端的端口
`$content_length` | 请求头中的 `Content-length` 字段
`$remote_user` | 已经经过 `Auth Basic Module` 验证的用户名
`$content_type` | 请求头中的 `Content-Type` 字段
`$request_filename` | 当前请求的文件路径,由 `root` 或alias指令与URI请求生成
`$document_root` | 当前请求在 `root` 指令中指定的值
`$scheme` | HTTP方法如httphttps
`$host` | 请求主机头字段,否则为服务器名称
`$hostname` | 主机名
`$http_user_agent` | 客户端`agent`信息
`$http_cookie` | 客户端`cookie`信息
`$server_protocol` | 请求使用的协议,通常是`HTTP/1.0``HTTP/1.1`
`$server_addr` | 服务器地址,在完成一次系统调用后可以确定这个值
`$server_name` | 服务器名称
`$server_port` | 请求到达服务器的端口号
`$limit_rate` | 这个变量可以限制连接速率
`$request_method` | 客户端请求的动作,如 GET/POST
`$request_uri` | 包含请求参数的原始URI不包含主机名`/foo/bar.php?arg=baz`
`$remote_addr` | 客户端的IP地址
`$uri` | 不带请求参数的当前URI`$uri`不包含主机名,如 `/foo/bar.html`
`$document_uri` | 与 `$uri` 相同
`$nginx_version` | `nginx` 版本
更多全局变量[查看官方文档](https://nginx.org/en/docs/varindex.html)
### 监听端口
```nginx
server {
listen 80; # 标准 HTTP 协议
listen 443 ssl; # 标准 HTTPS 协议
listen 443 ssl http2; # 对于 http2
listen [::]:80; # 使用 IPv6 在 80 上收听
# 仅收听使用 IPv6
listen [::]:80 ipv6only=on;
}
```
### 域名 (server_name)
```nginx
server {
# 监听 example.com
server_name example.com;
# 监听多个域
server_name example.com www.example.com;
# 监听所有子域
server_name *.example.com;
# 监听所有顶级域
server_name example.*;
# 监听未指定的主机名(监听 IP 地址本身)
server_name "";
}
```
### 负载均衡(简单实例)
```nginx
upstream node_js {
server 0.0.0.0:3000;
server 0.0.0.0:4000;
server 127.155.142.421;
}
```
### 负载均衡(权重)
```nginx
upstream test {
server localhost:8080 weight=9;
server localhost:8081 weight=1;
}
```
### upstream ip_hash
```nginx {2}
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
```
解决负载均衡 `session` 的问题
### upstream fair
```nginx {2}
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
```
响应时间短的优先分配
### server 可选参数
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`weight` | 访问权重数值越高,收到请求越多
`fail_timeout` | 指定的时间内必须提供响应
`max_fails` | 尝试失败服务器连接的最大次数
`down` | 标记一个服务器不再接受任何请求
`backup` | 有服务器宕机,标记的机器接收请求
配置示例
```nginx
upstream test {
server 127.0.0.1:83 weight=9; # 权重
server 127.0.0.1:83 weight=1; # 权重
# 失败超时时间
server 127.0.0.1:83 max_fails=3;
server 127.0.0.1:83 weight=3 down;
}
```
### upstream url_hash
```nginx {2,3}
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
```
按访问url的hash结果来分配请求
### upstream keepalive
```nginx {4}
upstream memcached_backend {
server 127.0.0.1:11211;
server 10.0.0.2:11211;
keepalive 32;
}
```
激活缓存以连接到上游服务器
### 子文件夹中的代理
<!--rehype:wrap-class=col-span-2-->
```nginx {1,2}
location /folder/ { # / 很重要!
proxy_pass http://127.0.0.1:3000/; # / 很重要!
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
```
### 反向代理
<!--rehype:wrap-class=row-span-3-->
#### 基础
```nginx
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://0.0.0.0:3000;
# 其中 0.0.0.0:3000 是绑定在
# 0.0.0.0端口3000 列表上的 Node.js 服务器
}
}
```
#### 基础 + (upstream)
```nginx
upstream node_js {
server 0.0.0.0:3000;
# 其中 0.0.0.0:3000 是绑定在
# 0.0.0.0端口3000 列表上的 Node.js 服务器
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://node_js;
}
}
```
#### 升级连接(适用于支持 WebSockets 的应用程序)
```nginx
upstream node_js {
server 0.0.0.0:3000;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://node_js;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
```
适用于 Node.js、Streamlit、Jupyter 等
### 静态资源(传统 Web 服务器)
<!--rehype:wrap-class=col-span-2-->
```nginx
server {
listen 80;
server_name example.com;
root /path/to/website;
# root /www/data/ 示例,如果里面没有'root',它将寻找 /www/data/index.html
location / {
}
location /images/ { # 如果里面没有“root”它将寻找 /www/data/images/index.html
}
location /videos/ { # 由于里面有“root”它会寻找 /www/media/videos/index.html
root /www/media;
}
}
```
### HTTPS 协议
<!--rehype:wrap-class=col-span-2-->
大多数 SSL 选项取决于您的应用程序做什么或需要什么
```nginx
server {
listen 443 ssl http2;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/fullchain.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
add_header Strict-Transport-Security max-age=15768000;
}
```
您可以使用 Let's Encrypt 轻松保护您的网站/应用程序。去 [lets-encrypt](https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx.html) 获取更多信息
### 重定向(301永久)
<!--rehype:wrap-class=row-span-2-->
将 www.example.com 重定向到 example.com
```nginx
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
```
将 http 重定向到 https
```nginx
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
```
### 重定向(302临时)
```nginx
server {
listen 80;
server_name yourdomain.com;
return 302 http://otherdomain.com;
}
```
### 永久重定向到 HTTPS 安全域
```nginx
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
```
### 重定向参数
:- | :-
:- | :-
`permanent` | 永久性重定向。日志中的状态码为 `301`
`redirect` | 临时重定向。日志中的状态码为 `302`
### HTTP 请求端真实的IP
```nginx
location / {
proxy_set_header X-Forwarded-For $remote_addr;
}
```
<!--rehype:className=wrap-text -->
示例
----
<!--rehype:body-class=cols-6-->
### websocket 的代理 keepalive
<!--rehype:wrap-class=col-span-3-->
```nginx
# Upstreams
upstream backend {
server 127.0.0.1:3000;
keepalive 5;
}
# HTTP Server
server {
server_name your_hostname.com;
error_log /var/log/nginx/rocketchat.access.log;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
```
<!--rehype:className=wrap-text -->
### Apache 的反向代理
<!--rehype:wrap-class=col-span-3-->
```nginx
server {
server_name domain.tld;
access_log /log/domain.tld.access.log;
error_log /log/domain.tld.error.log;
root /var/www/domain.tld/htdocs;
# 将请求传递给 Apache 后端
location / {
proxy_pass http://backend;
}
# 使用后备处理静态文件
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?g|gif|cur|heic|png|tiff|ico|zip|webm|mp3|aac|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|webp)$ {
add_header "Access-Control-Allow-Origin" "*";
access_log off;
log_not_found off;
expires max;
try_files $uri @fallback;
}
# 如果找不到文件,则回退以将请求传递给 Apache
location @fallback {
proxy_pass http://backend;
}
}
```
<!--rehype:className=wrap-text -->
### Gitlab 的反向代理
<!--rehype:wrap-class=col-span-4 row-span-3-->
```nginx
server {
#侦听的80端口
listen 80;
server_name git.example.cn;
location / {
proxy_pass http://localhost:3000;
# 以下是一些反向代理的配置可删除
proxy_redirect off;
# 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header Host $host;
client_max_body_size 10m; # 允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; # 缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 300; # nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 300; # 后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 300; # 连接成功后,后端服务器响应时间(代理接收超时)
# 设置代理服务器nginx保存用户头信息的缓冲区大小
proxy_buffer_size 4k;
# proxy_buffers缓冲区网页平均在32k以下的话这样设置
proxy_buffers 4 32k;
# 高负荷下缓冲大小proxy_buffers*2
proxy_busy_buffers_size 64k;
}
}
```
### 重定向整个网站
<!--rehype:wrap-class=col-span-2-->
```nginx
server {
server_name old-site.com;
return 301 $scheme://new-site.com$request_uri;
}
```
<!--rehype:className=wrap-text -->
### 重定向单页
<!--rehype:wrap-class=col-span-2-->
```nginx
server {
location = /oldpage.html {
return 301 http://example.org/newpage.html;
}
}
```
<!--rehype:className=wrap-text -->
### 重定向整个子路径
<!--rehype:wrap-class=col-span-2-->
```nginx
location /old-site {
rewrite ^/old-site/(.*) http://example.org/new-site/$1 permanent;
}
```
<!--rehype:className=wrap-text -->
### 负载均衡
<!--rehype:wrap-class=col-span-3-->
```nginx
upstream example {
ip_hash;
# upstream的负载均衡weight是权重可以根据机器配置定义权重。
# weigth参数表示权值权值越高被分配到的几率越大。
server 192.168.122.11:8081 ;
server 127.0.0.1:82 weight=3;
server 127.0.0.1:83 weight=3 down;
server 127.0.0.1:84 weight=3; max_fails=3 fail_timeout=20s;
server 127.0.0.1:85 weight=4;;
keepalive 32;
}
server {
#侦听的80端口
listen 80;
server_name git.example.cn;
location / {
# 在这里设置一个代理,和 upstream 的名字一样
proxy_pass http://example;
}
}
```
### 内容缓存
<!--rehype:wrap-class=col-span-3-->
允许浏览器基本上永久地缓存静态内容。 Nginx 将为您设置 Expires 和 Cache-Control 头信息
```nginx {3}
location /static {
root /data;
expires max;
}
```
如果要求浏览器永远不会缓存响应(例如用于跟踪请求),请使用 `-1`
```nginx {3}
location = /empty.gif {
empty_gif;
expires -1;
}
```
### 跨域问题
<!--rehype:wrap-class=col-span-3-->
```nginx
server {
listen 80;
server_name api.xxx.com;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,HEAD';
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
```
### 重定向 URI 来解决跨域问题
<!--rehype:wrap-class=col-span-3 row-span-2-->
```nginx
upstream test {
server 127.0.0.1:8080;
server localhost:8081;
}
server {
listen 80;
server_name api.xxx.com;
location / {
root html; # 去请求../html文件夹里的文件
index index.html index.htm; # 首页响应地址
}
# 用于拦截请求,匹配任何以 /api/开头的地址,
# 匹配符合以后,停止往下搜索正则。
location ^~/api/{
# 代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用
# 例如www.a.com/api/msg?meth=1&par=2重写只对/api/msg重写。
# rewrite后面的参数是一个简单的正则 ^/api/(.*)$
# $1代表正则中的第一个()$2代表第二个()的值,以此类推。
rewrite ^/api/(.*)$ /$1 break;
# 把请求代理到其他主机
# 其中 http://www.b.com/ 写法和 http://www.b.com写法的区别如下
# 如果你的请求地址是他 http://server/html/test.jsp
# 配置一: http://www.b.com/ 后面有“/”
# 将反向代理成 http://www.b.com/html/test.jsp 访问
# 配置一: http://www.b.com 后面没有有“/”
# 将反向代理成 http://www.b.com/test.jsp 访问
proxy_pass http://test;
# 如果 proxy_pass URL 是 http://a.xx.com/platform/ 这种情况
# proxy_cookie_path应该设置成 /platform/ / (注意两个斜杠之间有空格)。
proxy_cookie_path /platfrom/ /;
# 设置 Cookie 头通过
proxy_pass_header Set-Cookie;
}
}
```
### 跳转到带 www 的域上面
<!--rehype:wrap-class=col-span-3-->
```nginx
server {
listen 80;
# 配置正常的带www的域名
server_name www.wangchujiang.com;
root /home/www/wabg/download;
location / {
try_files $uri $uri/ /index.html =404;
}
}
server {
# 将不带 www 的 wangchujiang.com
# 永久性重定向到 https://www.wangchujiang.com
server_name wangchujiang.com;
rewrite ^(.*) https://www.wangchujiang.com$1 permanent;
}
```
### 代理转发
<!--rehype:wrap-class=col-span-2 row-span-2-->
```nginx
upstream server-api {
# api 代理服务地址
server 127.0.0.1:3110;
}
upstream server-resource {
# 静态资源 代理服务地址
server 127.0.0.1:3120;
}
server {
listen 3111;
server_name localhost; # 这里指定域名
root /home/www/server-statics;
# 匹配 api 路由的反向代理到API服务
location ^~/api/ {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://server-api;
}
# 假设这里验证码也在API服务中
location ^~/captcha {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://server-api;
}
# 假设你的图片资源全部在另外一个服务上面
location ^~/img/ {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://server-resource;
}
# 路由在前端,后端没有真实路由,
# 路由不存在的 404 状态的页面返回 /index.html
# 使用场景,用在 React/Vue项目没有真实路由
location / {
try_files $uri $uri/ /index.html =404;
# 空格很重要 ^
}
}
```
### 屏蔽 IP
<!--rehype:wrap-class=col-span-4-->
可以放到 `http`, `server`, `location`, `limit_except` 语句块
```nginx
include blockip.conf;
```
在 `blockip.conf` 里面输入内容,如:
```nginx
deny 165.91.122.67;
deny IP; # 屏蔽单个 ip 访问
allow IP; # 允许单个 ip 访问
deny all; # 屏蔽所有 ip 访问
allow all; # 允许所有 ip 访问
deny 123.0.0.0/8; # 屏蔽整个段即从 123.0.0.1 到 123.255.255.254 访问的命令
deny 124.45.0.0/16; # 屏蔽IP段即从 123.45.0.1 到 123.45.255.254 访问的命令
deny 123.45.6.0/24; # 屏蔽IP段即从 123.45.6.1 到 123.45.6.254 访问的命令
# 如果你想实现这样的应用除了几个IP外其他全部拒绝
allow 1.1.1.1;
allow 1.1.1.2;
deny all;
```
### 强制将 http 重定向到 https
<!--rehype:wrap-class=col-span-4-->
```nginx
server {
listen 80;
server_name example.com;
rewrite ^ https://$http_host$request_uri? permanent; # 强制将 http 重定向到 https
# 在错误页面和“服务器”响应头字段中启用或禁用发射nginx版本。 防止黑客利用版本漏洞攻击
server_tokens off;
}
```
### 代理转发连接替换
<!--rehype:wrap-class=col-span-2-->
```nginx
location ^~/api/upload {
rewrite ^/(.*)$ /wfs/v1/upload break;
proxy_pass http://wfs-api;
}
```
将地址 `/api/upload` 替换为 `/wfs/v1/upload`
### 爬虫 User-Agent 过滤
<!--rehype:wrap-class=col-span-4-->
```nginx
location / {
if ($http_user_agent ~* "python|curl|java|wget|httpclient|okhttp") {
return 503;
}
# 正常处理
# ...
}
```
### 图片防盗链
<!--rehype:wrap-class=col-span-2-->
```nginx
location ~* \.(gif|jpg|png|swf|flv)$ {
root html;
valid_referers none blocked *.nginx.com;
if ($invalid_referer) {
rewrite ^/ www.nginx.cn;
# return 404;
}
}
```
### 虚拟目录配置
<!--rehype:wrap-class=col-span-2-->
```nginx
location /img/ {
alias /var/www/image/;
}
# 访问 /img/ 目录里面的文件时,
# 会自动去 /var/www/image/ 目录找文件
location /img/ {
root /var/www/image;
}
# 访问 /img/ 目录下的文件时,
# 会去 /var/www/image/img/ 目录下找文件
```
### 屏蔽文件目录
<!--rehype:wrap-class=col-span-2 row-span-2-->
通用备份和归档文件
```nginx
location ~* "\.(old|orig|original|php#|php~|php_bak|save|swo|aspx?|tpl|sh|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" {
deny all;
}
```
<!--rehype:className=wrap-text -->
拒绝访问 `.git` 和 `.svn` 目录
```nginx
location ~ (.git|.svn) {
deny all;
}
```
<!--rehype:className=wrap-text -->
拒绝访问隐藏文件和目录
```nginx
location ~ /\.(?!well-known\/) {
deny all;
}
```
### 防盗图配置
<!--rehype:wrap-class=col-span-4-->
```nginx
location ~ \/public\/(css|js|img)\/.*\.(js|css|gif|jpg|jpeg|png|bmp|swf) {
valid_referers none blocked *.jslite.io;
if ($invalid_referer) {
rewrite ^/ http://wangchujiang.com/piratesp.png;
}
}
```
### 阻止常见攻击
<!--rehype:wrap-class=col-span-2-->
#### base64编码的网址
```nginx
location ~* "(base64_encode)(.*)(\()" {
deny all;
}
```
#### javascript eval() url
```nginx
location ~* "(eval\()" {
deny all;
}
```
### Gzip 配置
<!--rehype:wrap-class=col-span-4 row-span-2-->
```nginx
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "msie6";
```
### 使网站不可索引
<!--rehype:wrap-class=col-span-2-->
```nginx
add_header X-Robots-Tag "noindex";
location = /robots.txt {
return 200 "User-agent: *\nDisallow: /\n";
}
```
另见
---
- [Nginx 安装维护入门学习笔记](https://jaywcjlove.github.io/nginx-tutorial) _(jaywcjlove.github.io)_
- [](https://virtubox.github.io/advanced-nginx-cheatsheet/) _(virtubox.github.io)_

View File

@ -1,7 +1,7 @@
npm 备忘清单
===
这个 npm 快速参考备忘单显示了它的常用命令使用清单
这个 [npm](https://www.npmjs.com/) 快速参考备忘单显示了它的常用命令使用清单
常用命令
----
@ -9,134 +9,150 @@ npm 备忘清单
### 包管理
| 命令 | 描述 |
| --- | --- |
| `npm i` | `npm install`的别名 |
| `npm install` | 安装 package.json 中的所有内容 |
| `npm install --production` | 安装 package.json 中的所有内容除了 devDependecies |
| `npm install lodash` | 安装一个包 |
| `npm install --save-dev lodash` | 安装为 devDependency |
| `npm install --save-exact lodash` | 准确安装 |
| `npm install @scope/package-name` | 安装一个作用域的公共包 |
| `npm install <package_name>@<tag>` | 使用 dist-tags 安装包 |
| `npm install -g <package_name>` | 全局安装包 |
| `npm uninstall <package_name>` | 卸载包 |
命令 | 描述
:- |:-
`npm init -y` | 创建 `package.json` 文件
`npm install` `npm i` | 安装 `package.json` 中的所有内容
`npm install --production` | 安装 `package.json` 中的所有内容 <br /> _(除了 `devDependecies`)_
`npm install lodash` | 安装一个包
`npm install --save-dev lodash` | 安装为 `devDependency`
`npm install --save-exact lodash` | 准确安装
`npm install @scope/package-name` | 安装一个作用域的公共包
`npm install <package_name>@<tag>` | 使用 `dist-tags` 安装包
`npm install -g <package_name>` | 全局安装包
`npm uninstall <package_name>` | 卸载包
<!--rehype:class=auto-wrap-->
`--save` 是 npm@5 的默认值。 以前,使用不带 `--save``npm install` 不会更新 package.json。
### 安装
<!--rehype:wrap-class=row-span-3-->
### 安装名称
命令 | 描述
:- |:-
`npm i sax` | `NPM`
`npm i sax@latest` | 指定标签 `最新`
`npm i sax@3.0.0` | 指定版本 `3.0.0`
`npm i sax@">=1 <2.0"` | 指定版本范围
`npm i @org/sax` | 范围内的 `NPM`
`npm i user/repo` | GitHub
`npm i user/repo#master` | GitHub
`npm i github:user/repo` | GitHub
`npm i gitlab:user/repo` | GitLab
`npm i /path/to/repo` | 绝对路径
`npm i ./archive.tgz` | 压缩包
`npm i https://site.com/archive.tgz` | 通过 `HTTP` 压缩包
<!--rehype:class=auto-wrap-->
| 命令 | 描述 |
| --- | --- |
| `npm i sax` | NPM 包 |
| `npm i sax@latest` | 指定标签“最新” |
| `npm i sax@3.0.0` | 指定版本 `3.0.0` |
| `npm i sax@">=1 <2.0"` | 指定版本范围 |
| `npm i @org/sax` | 范围内的 NPM 包 |
| `npm i user/repo` | GitHub |
| `npm i user/repo#master` | GitHub |
| `npm i github:user/repo` | GitHub |
| `npm i gitlab:user/repo` | GitLab |
| `npm i /path/to/repo` | 绝对路径 |
| `npm i ./archive.tgz` | 压缩包 |
| `npm i https://site.com/archive.tgz` | 通过 HTTP 压缩包 |
安装依赖的可用参数
- `-P`, `--save-prod` 包将出现在您的依赖项中,这是默认值(npm v8),除非存在 `-D``-O`
- `-D`, `--save-dev` 包会出现在你的 `devDependencies`
- `-O`, `--save-optional` 包将出现在您的 `optionalDependencies`
- `--no-save` 防止保存到依赖项
- `-E`, `--save-exact` 依赖项将使用精确的版本进行配置,而不是使用 `npm` 的默认 [`semver`](./semver.md) 范围运算符
- `-B`, `--save-bundle` 依赖项也将添加到您的 [`bundleDependencies`](./package.json.md#bundleddependencies) 列表中
<!--rehype:className=style-arrow-->
命令 `npm i``npm install` 的别名
### 清单
| 命令 | 描述 |
| --- | --- |
| `npm list` | 列出此软件中所有依赖项的已安装版本 |
| `npm list -g --depth 0` | 列出所有全局安装包的安装版本 |
| `npm view` | 列出此软件中所有依赖项的最新版本 |
| `npm outdated` | 仅列出此软件中已过时的依赖项 |
命令 | 描述
:- |:-
`npm list` | 列出此软件中所有依赖项的已安装版本
`npm list -g --depth 0` | 列出所有全局安装包的安装版本
`npm view` | 列出此软件中所有依赖项的最新版本
`npm outdated` | 仅列出此软件中已过时的依赖项
<!--rehype:class=auto-wrap-->
### 缓存 cache
```bash
$ npm cache add <package-spec> # 将指定的包添加到本地缓存
$ npm cache clean [<key>] # 删除缓存文件夹中的所有数据
$ npm cache ls [<name>@<version>]
$ npm cache verify # 验证缓存文件夹的内容,垃圾收集任何不需要的数据,
# 并验证缓存索引和所有缓存数据的完整性
```
用于添加、列出或清理 [npm](https://www.npmjs.com/) 缓存文件夹
### 更新
| 命令 | 描述 |
| --- | --- |
| `npm version <version>` | 要更改 `package.json` 中的版本号 |
| `npm update` | 更新生产包 |
| `npm update --dev` | 更新开发包 |
| `npm update -g` | 更新全局包 |
| `npm update lodash` | 更新 lodash 包 |
命令 | 描述
:- | -
`npm version <version>` | 要更改 `package.json` 中的版本号
`npm update` | 更新生产包
`npm update --dev` | 更新开发包
`npm update -g` | 更新全局包
`npm update lodash` | 更新 `lodash`
### 杂项功能
<!--rehype:wrap-class=row-span-2-->
将某人添加为所有者
```bash
npm owner add USERNAME PACKAGENAME
```
列出包
```bash
npm ls
```
向安装旧版本软件包的用户添加警告(弃用)
```bash
npm deprecate PACKAGE@"< 0.2.0" "critical bug fixed in v0.2.0"
```
更新所有包或选定的包
```bash
npm update [-g] PACKAGE
```
检查过时的包
```bash
npm outdated [PACKAGE]
```
### 更改包裹可见性
将公共包设为私有
```bash
npm access restricted <package-name>
```
公开私有包
```bash
npm access restricted <package-name>
```
授予私有包访问权限
```bash
npm owner add <user> <your-package-name>
```
### 要将包转移到 npm 用户帐户
```bash
npm owner add <their-username> <package-name>
# 新维护者接受邀请
npm owner rm <your-username> <package-name>
```
写入启用了双因素身份验证
```bash
npm owner add <their-username> <package-name> --otp=123456
# 将某人添加为所有者
$ npm owner add USERNAME PACKAGENAME
# 列出包
$ npm ls
# 向安装旧版本软件包的用户添加警告(弃用)
$ npm deprecate PACKAGE@"< 0.2.0" "critical bug fixed in v0.2.0"
# 更新所有包或选定的包
$ npm update [-g] PACKAGE
# 检查过时的包
$ npm outdated [PACKAGE]
```
### 取消发布包
```bash
npm unpublish <package-name> -f
$ npm unpublish <package-name> -f
# 取消指定版本
npm unpublish <package-name>@<version>
$ npm unpublish <package-name>@<version>
```
注意:如果您取消发布整个包,则必须在 24 小时后才能发布该包的任何新版本
注意:如果您取消发布整个包,则必须在 24 小时后才能发布该包的任何新版本
### 更改包裹可见性
```bash
# 将公共包设为私有
$ npm access restricted <package-name>
# 公开私有包
$ npm access public <package-name>
# 授予私有包访问权限
$ npm owner add <user> <your-package-name>
```
### 要将包转移到 npm 用户帐户
```bash
# 新维护者接受邀请
$ npm owner add <their-username> <package-name>
# 删除维护者
$ npm owner rm <your-username> <package-name>
# 写入启用了双因素身份验证
$ npm owner add <their-username> <package-name> --otp=123456
```
### 发布包 npmjs.org
```bash
$ npm publish
# 第一次需要指定公开参数
$ npm publish --access public
```
发布公开包,到 [npmjs.org](https://docs.npmjs.com)
### 使用 nrm 切换 registry
```bash
$ npm install -g nrm # 安装 nrm 包
# 查看 registry 列表
$ nrm ls
# 将注册表切换到 cnpm
$ nrm use cnpm
```
配置
---
@ -150,17 +166,27 @@ npm unpublish <package-name>@<version>
`$PREFIX/etc/npmrc` | 全局配置文件
`/path/to/npm/npmrc` | npm 内置配置文件
### 配置内容
<!--rehype:wrap-class=col-span-2-->
```ini
# last modified: 01 Jan 2016
; Set a new registry for a scoped package
@myscope:registry=https://mycustomregistry.example.org
@myscope:registry=https://registry.npmmirror.com
```
<!--rehype:className=wrap-text -->
注释使用 `#`, `;` 放置到一行的开头`.npmrc` 文件由指定此注释语法的 [`npm/ini`](https://github.com/npm/ini) 解析
注释使用 `#`, `;` 放置到一行的开头 [`.npmrc`](https://docs.npmjs.com/cli/v8/configuring-npm/npmrc) 文件由指定此注释语法的 [`npm/ini`](https://github.com/npm/ini) 解析
### registry
:- | :-
:- | :-
`npm` | <https://registry.npmjs.org/>
`yarn` | <https://registry.yarnpkg.com/>
`tencent` | <https://mirrors.cloud.tencent.com/npm/>
`cnpm` | <https://r.cnpmjs.org/>
`taobao` | <https://registry.npmmirror.com/>
`npmMirror` | <https://skimdb.npmjs.com/registry/>
### `.npmignore`
@ -180,19 +206,21 @@ npm unpublish <package-name>@<version>
`.npmignore` 文件就像 [`.gitignore`](./git.md#忽略文件) 一样工作。它不能覆盖 `package.json#files` 字段。
### 中国镜像站安装
<!--rehype:wrap-class=col-span-2-->
<!--rehype:wrap-class=col-span-2 row-span-2-->
```bash
# 临时使用
$ npm install -g <package-name> --registry=https://registry.npmmirror.com
```
将配置放置在 `.npmrc` 配置文件中。
将配置放置在 [`.npmrc`](https://docs.npmjs.com/cli/v8/configuring-npm/npmrc) 全局配置文件中,或者在项目的根目录中。
```ini
; registry=https://registry.npmjs.org/
registry=https://registry.npmmirror.com
```
或者配置到 `package.json#publishConfig` 字段上
或者配置到 [`package.json#publishConfig`](./package.json.md#publishconfig) 字段上
```json
"publishConfig":{
@ -200,4 +228,67 @@ registry=https://registry.npmmirror.com
}
```
请参阅:[npmmirror 中国镜像站](https://npmmirror.com/)
替换 npm 仓库地址为 npmmirror(淘宝) 镜像地址
```bash
$ npm config set registry https://registry.npmmirror.com
```
请参阅:[npmmirror 中国镜像站](https://npmmirror.com/)
#### electronjs 镜像和缓存
```ini
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
; ELECTRON_CUSTOM_DIR="{{ version }}"
```
<!--rehype:className=wrap-text -->
### 身份验证相关配置
```ini
//registry.npmjs.org/:_authToken=MYTOKEN
; 将适用于 @myorg 和 @another
//somewhere.com/:_authToken=MYTOKEN
; 将适用于 @myorg
//somewhere.com/myorg/:_authToken=MYTOKEN1
; 将适用于 @another
//somewhere.com/another/:_authToken=MYTOKEN2
```
纯 ESM 包
----
### CommonJS 项目移动到 ESM
<!--rehype:wrap-class=col-span-3-->
-`"type": "module"` 添加到您的 [package.json](./package.json.md)
- 将 [package.json](./package.json.md) 中的 `"main": "index.js"` 替换为 `"exports": "./index.js"`
- 将 [package.json](./package.json.md) 中的 `"engines"` 字段更新为 Node.js 14: `"node": ">=14.16"`。(不包括 <red>~~Node.js 12~~</red>,因为它不再受支持)
- 删除 `"use strict"`;来自所有 JavaScript 文件
- 将所有 `require()` / `module.export` 替换为 `import` / `export`
- 仅使用完整的相对文件路径进行导入:`import x from '.';``import x from './index.js';`
- 如果您有 `TypeScript` 类型定义(例如 `index.d.ts`),请将其更新为使用 ESM 导入/导出
- 可选但推荐使用 `node:` 导入[协议](https://nodejs.org/api/esm.html#esm_node_imports)
### TypeScript 项目输出 ESM
<!--rehype:wrap-class=col-span-3-->
- 确保您使用的是 TypeScript 4.7 或更高版本
-`"type": "module"` 添加到您的 [package.json](./package.json.md)
- 将 [package.json](./package.json.md) 中的 `"main": "index.js"` 替换为 `"exports": "./index.js"`
- 将 [package.json](./package.json.md) 中的 `"engines"` 字段更新为 Node.js 14: `"node": ">=14.16"`。 (不包括 <red>~~Node.js 12~~</red>,因为它不再受支持)
-`"module": "node16"`, `"moduleResolution": "node16"` 添加到您的 [tsconfig.json](./typescript.md) ([列子](https://github.com/sindresorhus/tsconfig/blob/main/tsconfig.json))
- 仅使用完整的相对文件路径进行导入:`import x from '.';``import x from './index.js';`
- 删除 `namespace` 使用并改用 `export`
- 可选但推荐使用 `node:` 导入[协议](https://nodejs.org/api/esm.html#esm_node_imports)
- **即使您正在导入 `.ts` 文件,也必须在相对导入中使用 `.js` 扩展名**
阅读[官方 ESM 指南](https://www.typescriptlang.org/docs/handbook/esm-node.html)
另见
----
- [npm 仓库、网站和命令行界面的文档](https://docs.npmjs.com/) _(npmjs.com)_
- [npmmirror 中国镜像站](https://npmmirror.com/) _(npmmirror.com)_

View File

@ -12,6 +12,8 @@ package.json 备忘清单
- [npm 文档](https://docs.npmjs.com/files/package.json) _(npmjs.com)_
- [yarnpkg 文档](https://classic.yarnpkg.com/en/docs/package-json) _(yarnpkg.com)_
- [packages 文档](https://nodejs.org/api/packages.html) _(nodejs.org)_
- [npm 备忘清单(速查表)](./npm.md) _(jaywcjlove.github.io)_
### `name`
@ -21,7 +23,7 @@ package.json 备忘清单
}
```
**规则**
#### 规则
- 必须小于或等于214个字符(包括 `@scope/` 范围包)
- 不能以点(`.`)或下划线(`_`)开头
@ -101,7 +103,7 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
鼓励使用开源 [(OSI-approved)](https://opensource.org/licenses/alphabetical) 许可证,除非你有特别的原因不用它。 如果你开发的包是你工作的一部分,最好和公司讨论后再做决定。
**license字段必须是以下之一:**
#### **license字段必须是以下之一**
- 如果你使用标准的许可证,需要一个有效地 [SPDX 许可证标识](https://spdx.org/licenses/)。
- 如果你用多种标准许可证,需要有效的 [SPDX 许可证表达式2.0语法表达式](https://www.npmjs.com/package/spdx)。
@ -328,12 +330,100 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
字段由模块作者提供,作为 `JavaScript` 包或组件工具的提示,用于打包模块以供客户端使用。 提案就[在这里](https://github.com/defunctzombie/package-browser-field-spec)。
### `exports`
```json
{
"name": "mod",
"exports":{
".": "./lib/index.js",
"./lib/*": "./lib/*.js"
}
}
```
使用最新的 `exports` 字段导出,可规避 `main` 字段局限性 [具体参考](https://nodejs.org/api/packages.html)
### exports 导出子路径中的模块
```json
{
"name": "mod",
"exports": {
".": "./index.js",
"./sub": "./src/sub.js"
}
}
```
导入
```js
import sub from "mod/sub"
```
### exports 简写 (`.` 唯一的导出)
```json
{
"exports": {
".": "./dist/index.js"
}
}
```
简写
```json
{
"exports": "./dist/index.js"
}
```
### 条件导出(exports)
<!--rehype:wrap-class=col-span-2 row-span-2-->
:- | -
:- | -
`export` | 通过 `import``import()``es` 模块加载的任何顶层导入或解析操作加载时,匹配。
`require` | 当包通过 `require()` 加载时匹配。预期的格式包括 CommonJS、JSON 和本地插件。
`node` | 匹配任何 `Node.js` 环境。可以是 `cjs``es` 模块文件。必须在 `import``require` 之后。
`default` | 默认的降级条件。可以是一个 `cjs``es` 模块文件。这个条件应该总是排在最后。
```js
{
"exports": {
".": {
"import":"./dist/index.mjs",
"require":"./dist/index.cjs", // 当包通过 `require()` 加载时匹配
"node": "./dist/ployfill.js", // 匹配任何 `Node.js` 环境
"default": "./dist/default.js" // 默认的降级条件
}
}
}
```
<red>注意:</red>由于 `require``import` 互斥,所以 `require` 不能加载 `es` 的模块,`export` 不能加载 `cjs` 模块
### `main` Vs `exports`
```json
{
"main": "./index.js",
"exports": "./index.js"
}
```
如果同时出现 <red>~~`main`~~</red>`exports` 字段,只会读取 `exports` 字段
## 任务类字段
包里还可以包含一些可执行脚本或者其他配置信息。
### `scripts`
脚本是定义自动化开发相关任务的好方法,比如使用一些简单的构建过程或开发工具。 在 `scripts` 字段里定义的脚本,可以通过 `yarn run <script>` 命令来执行。 例如,下面 `build-project` 脚本可以通过 `yarn run build-project` 调用,并执行 `node build-project.js`
```json
{
"scripts": {
@ -342,12 +432,14 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
}
```
脚本是定义自动化开发相关任务的好方法,比如使用一些简单的构建过程或开发工具。 在 `scripts` 字段里定义的脚本,可以通过 `yarn run <script>` 命令来执行。 例如,上述 `build-project` 脚本可以通过 `yarn run build-project` 调用,并执行 `node build-project.js`
有一些特殊的脚本名称。 如果定义了 `preinstall` 脚本,它会在包安装前被调用。 出于兼容性考虑,`install``postinstall``prepublish` 脚本会在包完成安装后被调用。
----
`start` 脚本的默认值为 `node server.js`
----
参考文档:[npm docs](https://docs.npmjs.com/files/package.json#default-values)
### 特定的 `scripts`
@ -355,24 +447,24 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
对于以下脚本,`npm` 支持 `package.json` 文件的 `scripts` 默认命令字段:
- `prepublish`: 在打包并发布包之前运行,以及在没有任何参数的本地 `npm` 安装之前运行。 (见下文)
- `prepare`: 在打包和发布包之前运行,在没有任何参数的本地 `npm install` 上运行,以及安装 git 依赖项时(见下文)。 这是在 `preublish` 之后运行,但是在 `preublishOnly` 之前运行
- `prepublishOnly`: 在包准备和打包之前运行仅限于npm发布。 (见下文。)
- `prepublish`: 在打包并发布包之前运行,以及在没有任何参数的本地 `npm` 安装之前运行
- `prepare`: 在打包和发布包之前运行,在没有任何参数的本地 `npm install` 上运行,以及安装 git 依赖项时。 这是在 `preublish` 之后运行,但是在 `preublishOnly` 之前运行
- `prepublishOnly`: 在包准备和打包之前运行仅限于npm发布
- `prepack`: 在打包 `tarball` 之前运行(在 `npm pack``npm publish`,以及安装 git 依赖项时)
- `postpack`: 在生成 `tarball` 之后运行并移动到其最终目标
- `publish`, `postpublish`: 在包发布后运行
- `preinstall`: 在安装软件包之前运行
- `install`, `postinstall`: 安装包后运行
- `preuninstall`, `uninstall`: 在卸载软件包之前运行
- `postuninstall`: 在卸载软件包之后运行
- `preversion`: 在改变包版本之前运行
- `version`: 改变包版本后运行,但提交之前
- `postversion`: 改变包版本后运行,然后提交
- `pretest`, `test`, `posttest`: 由 `npm test` 命令运行
- `prestop`, `stop`, `poststop`: 由 `npm stop` 命令运行
- `prestart`, `start`, `poststart`: 由 `npm start` 命令运行
- `prerestart`, `restart`, `postrestart`: 由 `npm restart` 命令运行。 注意:如果没有提供重启脚本,`npm restart` 将运行 `stop``start` 脚本
- `preshrinkwrap`, `shrinkwrap`, `postshrinkwrap`: 由 `npm shrinkwrap` 命令运行
- `postpack`: 在生成 `tarball` 之后运行并移动到其最终目标
- `publish`, `postpublish`: 在包发布后运行
- `preinstall`: 在安装软件包之前运行
- `install`, `postinstall`: 安装包后运行
- `preuninstall`, `uninstall`: 在卸载软件包之前运行
- `postuninstall`: 在卸载软件包之后运行
- `preversion`: 在改变包版本之前运行
- `version`: 改变包版本后运行,但提交之前
- `postversion`: 改变包版本后运行,然后提交
- `pretest`, `test`, `posttest`: 由 `npm test` 命令运行
- `prestop`, `stop`, `poststop`: 由 `npm stop` 命令运行
- `prestart`, `start`, `poststart`: 由 `npm start` 命令运行
- `prerestart`, `restart`, `postrestart`: 由 `npm restart` 命令运行。 注意:如果没有提供重启脚本,`npm restart` 将运行 `stop``start` 脚本
- `preshrinkwrap`, `shrinkwrap`, `postshrinkwrap`: 由 `npm shrinkwrap` 命令运行
参考文档:[npm docs](https://docs.npmjs.com/misc/scripts).
@ -475,8 +567,19 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
这些是只在你的包开发期间需要,但是生产环境不会被安装的包。
### `overrides`
```json
{
"overrides": {
"foo": "1.0.0"
}
}
```
对依赖项的依赖项进行特定更改,例如用已知的安全问题替换依赖项的版本
### `peerDependencies`
<!--rehype:wrap-class=col-span-2-->
```json
{
@ -530,6 +633,8 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
}
```
它允许对等依赖项标记为可选
系统
----
@ -564,7 +669,6 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
此选项指定你的包的操作系统兼容性,它会检查 `process.platform`
### `cpu`
```json
@ -611,6 +715,8 @@ Yarn
### `flat`
<!-- markdownlint-disable MD042 -->
如果你的包只允许给定依赖的一个版本,你想强制和命令行上 [yarn install --flat](#) 相同的行为,把这个值设为 `true`
```json
@ -638,8 +744,11 @@ Yarn
注意,`yarn install --flat` 命令将会自动在 `package.json` 文件里加入 `resolutions` 字段。
另见
----
- [PACKAGE.JSON 中文说明](https://jaywcjlove.github.io/package.json) _(github.io)_
- [PACKAGE.JSON 中文说明](https://jaywcjlove.github.io/package.json) _(github.io)_
- [npm 文档](https://docs.npmjs.com/files/package.json) _(npmjs.com)_
- [yarnpkg 文档](https://classic.yarnpkg.com/en/docs/package-json) _(yarnpkg.com)_
- [packages 文档](https://nodejs.org/api/packages.html) _(nodejs.org)_
- [npm 备忘清单(速查表)](./npm.md) _(jaywcjlove.github.io)_

972
docs/php.md Normal file
View File

@ -0,0 +1,972 @@
PHP 备忘清单
===
这份 [PHP](https://www.php.net/manual/zh/index.php) 备忘单为快速查找最常用代码的正确语法提供了参考
入门
------
### hello.php
```php
<?php // 以 PHP 开放标签开头
echo "Hello World\n";
print("Hello quickref.me");
?>
```
PHP 运行命令
```shell
$ php hello.php
```
### 变量 Variables
```php
$boolean1 = true;
$boolean2 = True;
$int = 12;
$float = 3.1415926;
unset($float); // 删除变量
$str1 = "How are you?";
$str2 = 'Fine, thanks';
```
查看: [Types](#php-类型)
### 字符串 Strings
```php
$url = "quickref.me";
echo "I'm learning PHP at $url";
// 连接字符串
echo "I'm learning PHP at " . $url;
$hello = "Hello, ";
$hello .= "World!";
echo $hello; # => Hello, World!
```
查看: [Strings](#php-字符串)
### 数组 Arrays
```php
$num = [1, 3, 5, 7, 9];
$num[5] = 11;
unset($num[2]); // 删除变量
print_r($num); # => 1 3 7 9 11
echo count($num); # => 5
```
查看: [Arrays](#php-数组)
### 运算符 Operators
```php
$x = 1;
$y = 2;
$sum = $x + $y;
echo $sum; # => 3
```
查看: [Operators](#php-运算符)
### Include
<!--rehype:wrap-class=row-span-3-->
#### vars.php
```php
<?php // 以 PHP 开放标签开头。
$fruit = 'apple';
echo "I was imported";
return 'Anything you like.';
?>
```
#### test.php
```php
<?php
include 'vars.php';
echo $fruit . "\n"; # => apple
/* 与 include 相同,
如果不能包含则导致错误*/
require 'vars.php';
// 也有效
include('vars.php');
require('vars.php');
// 通过 HTTP 包含
include 'http://x.com/file.php';
// 包含和返回语句
$result = include 'vars.php';
echo $result; # => Anything you like.
?>
```
### 功能 Functions
```php
function add($num1, $num2 = 1) {
return $num1 + $num2;
}
echo add(10); # => 11
echo add(10, 5); # => 15
```
查看: [Functions](#php-函数)
### 注释 Comments
```php
# 这是一个单行 shell 样式的注释
// 这是一行 c++ 风格的注释
/* 这是一个多行注释
另一行注释 */
```
### 常数 Constants
```php
const MY_CONST = "hello";
echo MY_CONST; # => hello
# => MY_CONST is: hello
echo 'MY_CONST is: ' . MY_CONST;
```
### 类 Classes
```php
class Student {
public function __construct($name) {
$this->name = $name;
}
}
$alex = new Student("Alex");
```
查看: [Classes](#php-类)
PHP 类型
------
### 布尔值 Boolean
<!--rehype:wrap-class=row-span-2-->
```php
$boolean1 = true;
$boolean2 = TRUE;
$boolean3 = false;
$boolean4 = FALSE;
$boolean5 = (boolean) 1; # => true
$boolean6 = (boolean) 0; # => false
```
布尔值不区分大小写
### 整数 Integer
<!--rehype:wrap-class=row-span-2-->
```php
$int1 = 28; # => 28
$int2 = -32; # => -32
$int3 = 012; # => 10 (octal)
$int4 = 0x0F; # => 15 (hex)
$int5 = 0b101; # => 5 (binary)
# => 2000100000 (decimal, PHP 7.4.0)
$int6 = 2_000_100_000;
```
另见: [Integers](https://www.php.net/manual/en/language.types.integer.php)
### 字符串 Strings
```php
echo 'this is a simple string';
```
查看: [Strings](#php-字符串)
### 数组 Arrays
```php
$arr = array("hello", "world", "!");
```
查看: [Arrays](#php-数组)
### 浮点数 Float (Double)
```php
$float1 = 1.234;
$float2 = 1.2e7;
$float3 = 7E-10;
$float4 = 1_234.567; // as of PHP 7.4.0
var_dump($float4); // float(1234.567)
$float5 = 1 + "10.5"; # => 11.5
$float6 = 1 + "-1.3e3"; # => -1299
```
### Null
```php
$a = null;
$b = 'Hello php!';
echo $a ?? 'a is unset'; # => a is unset
echo $b ?? 'b is unset'; # => Hello php
$a = array();
$a == null # => true
$a === null # => false
is_null($a) # => false
```
### 可迭代对象 Iterables
```php
function bar(): iterable {
return [1, 2, 3];
}
function gen(): iterable {
yield 1;
yield 2;
yield 3;
}
foreach (bar() as $value) {
echo $value; # => 123
}
```
PHP 字符串
------
### 字符串 String
```php
# => '$String'
$sgl_quotes = '$String';
# => 'This is a $String.'
$dbl_quotes = "This is a $sgl_quotes.";
# => a tab character.
$escaped = "a \t tab character.";
# => a slash and a t: \t
$unescaped = 'a slash and a t: \t';
```
### 多行 Multi-line
```php
$str = "foo";
// 未插值的多行
$nowdoc = <<<'END'
Multi line string
$str
END;
// 将执行字符串插值
$heredoc = <<<END
Multi line
$str
END;
```
### 操作 Manipulation
```php
$s = "Hello Phper";
echo strlen($s); # => 11
echo substr($s, 0, 3); # => Hel
echo substr($s, 1); # => ello Phper
echo substr($s, -4, 3);# => hpe
echo strtoupper($s); # => HELLO PHPER
echo strtolower($s); # => hello phper
echo strpos($s, "l"); # => 2
var_dump(strpos($s, "L")); # => false
```
另见: [字符串函数](https://www.php.net/manual/en/ref.strings.php)
PHP 数组
------
### 定义
<!--rehype:wrap-class=row-span-2-->
```php
$a1 = ["hello", "world", "!"]
$a2 = array("hello", "world", "!");
$a3 = explode(",", "apple,pear,peach");
```
#### 混合 int 和 string 键
```php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
```
#### 短数组语法
```php
$array = [
"foo" => "bar",
"bar" => "foo",
];
```
### 多阵列
```php
$multiArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
print_r($multiArray[0][0]) # => 1
print_r($multiArray[0][1]) # => 2
print_r($multiArray[0][2]) # => 3
```
### 多类型
<!--rehype:wrap-class=row-span-2-->
```php
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dim" => array(
"a" => "foo"
)
)
);
# => string(3) "bar"
var_dump($array["foo"]);
# => int(24)
var_dump($array[42]);
# => string(3) "foo"
var_dump($array["multi"]["dim"]["a"]);
```
### 操作
```php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // 附加
$arr["x"] = 42; // 用键添加
sort($arr); // 排序
unset($arr[5]); // 消除
unset($arr); // 移除所有
```
查看: [数组函数](https://www.php.net/manual/en/ref.array.php)
### 索引迭代
```php
$array = array('a', 'b', 'c');
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "i:{$i}, v:{$array[$i]}\n";
}
```
### 价值迭代
```php
$colors = array('red', 'blue', 'green');
foreach ($colors as $color) {
echo "Do you like $color?\n";
}
```
### 关键迭代
```php
$arr = ["foo" => "bar", "bar" => "foo"];
foreach ( $arr as $key => $value )
{
echo "key: " . $key . "\n";
echo "val: {$arr[$key]}\n";
}
```
### 串联阵列
```php
$a = [1, 2];
$b = [3, 4];
// PHP 7.4 以后
# => [1, 2, 3, 4]
$result = [...$a, ...$b];
```
### Into 函数
```php
$array = [1, 2];
function foo(int $a, int $b) {
echo $a; # => 1
echo $b; # => 2
}
foo(...$array);
```
### Splat运算符
```php
function foo($first, ...$other) {
var_dump($first); # => a
var_dump($other); # => ['b', 'c']
}
foo('a', 'b', 'c' /*, ...*/ );
// 或
function foo($first, string ...$other){}
```
PHP 运算符
-------
### 算术
:- | -
:- | -
`+` | 添加
`-` | 减法
`*` | 乘法
`/` | 分配
`%` | 取模
`**` | 求幂
### 分配
:- | -
:- | -
`a += b` | 如同 `a = a + b`
`a -= b` | 如同 `a = a b`
`a *= b` | 如同 `a = a * b`
`a /= b` | 如同 `a = a / b`
`a %= b` | 如同 `a = a % b`
### 比较
:- | -
:- | -
`==` | 平等的
`===` | 完全相同的
`!=` | 不相等
`<>` | 不相等
`!==` | 不相同
`<` | 少于
`>` | 比...更棒
`<=` | 小于或等于
`>=` | 大于或等于
`<=>` | 小于/等于/大于
### 逻辑的
:- | -
:- | -
`and` | 和
`or` | 或者
`xor` | 独家或
`!` | 不是
`&&` | 和
`\|\|` | 或者
### 算术
```php
// 算术
$sum = 1 + 1; // 2
$difference = 2 - 1; // 1
$product = 2 * 2; // 4
$quotient = 2 / 1; // 2
// 速记算术
$num = 0;
$num += 1; // 将 $num 增加 1
echo $num++; // 打印 1评估后的增量
echo ++$num; // 打印 3评估前的增量
$num /= $float; // 将商除并分配给 $num
```
### 按位
:- | -
:- | -
`&` | 和
`|` | 或(包括或)
`^` | 异或(异或)
`~` | 不是
`<<` | 左移
`>>` | 右移
PHP 条件
------
### If elseif else
```php
$a = 10;
$b = 20;
if ($a > $b) {
echo "a is bigger than b";
} elseif ($a == $b) {
echo "a is equal to b";
} else {
echo "a is smaller than b";
}
```
### Switch
```php
$x = 0;
switch ($x) {
case '0':
print "it's zero";
break;
case 'two':
case 'three':
// do something
break;
default:
// do something
}
```
### 三元运算符
```php
# => Does
print (false ? 'Not' : 'Does');
$x = false;
# => Does
print($x ?: 'Does');
$a = null;
$b = 'Does print';
# => a is unsert
echo $a ?? 'a is unset';
# => print
echo $b ?? 'b is unset';
```
### 匹配
```php
$statusCode = 500;
$message = match($statusCode) {
200, 300 => null,
400 => '未找到',
500 => '服务器错误',
default => '已知状态码',
};
echo $message; # => 服务器错误
```
查看: [Match](https://www.php.net/manual/en/control-structures.match.php)
### 匹配表达式
```php
$age = 23;
$result = match (true) {
$age >= 65 => 'senior',
$age >= 25 => 'adult',
$age >= 18 => 'young adult',
default => 'kid',
};
echo $result; # => young adult
```
PHP 循环
------
### while 循环
```php
$i = 1;
# => 12345
while ($i <= 5) {
echo $i++;
}
```
### do while 循环
```php
$i = 1;
# => 12345
do {
echo $i++;
} while ($i <= 5);
```
### for i 循环
```php
# => 12345
for ($i = 1; $i <= 5; $i++) {
echo $i;
}
```
### break 跳出循环
```php
# => 123
for ($i = 1; $i <= 5; $i++) {
if ($i === 4) {
break;
}
echo $i;
}
```
### continue 继续
```php
# => 1235
for ($i = 1; $i <= 5; $i++) {
if ($i === 4) {
continue;
}
echo $i;
}
```
### foreach 循环
```php
$a = ['foo' => 1, 'bar' => 2];
# => 12
foreach ($a as $k) {
echo $k;
}
```
查看: [Array iteration](#关键迭代)
PHP 函数
------
### 返回值
```php
function square($x)
{
return $x * $x;
}
echo square(4); # => 16
```
### 返回类型
```php
// 基本返回类型声明
function sum($a, $b): float {/*...*/}
function get_item(): string {/*...*/}
class C {}
// 返回一个对象
function getC(): C { return new C; }
```
### 可空返回类型
```php
// 在 PHP 7.1 中可用
function nullOrString(int $v) : ?string
{
return $v % 2 ? "odd" : null;
}
echo nullOrString(3); # => odd
var_dump(nullOrString(4)); # => NULL
```
查看: [Nullable types](https://www.php.net/manual/en/migration71.new-features.php)
### 无效函数
```php
// 在 PHP 7.1 中可用
function voidFunction(): void
{
echo 'Hello';
return;
}
voidFunction(); # => Hello
```
### 变量函数
```php
function bar($arg = '')
{
echo "In bar(); arg: '$arg'.\n";
}
$func = 'bar';
$func('test'); # => In bar(); arg: test
```
### 匿名函数
```php
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World'); # => Hello World
$greet('PHP'); # => Hello PHP
```
### 递归函数
```php
function recursion($x)
{
if ($x < 5) {
echo "$x";
recursion($x + 1);
}
}
recursion(1); # => 1234
```
### 默认参数
```php
function coffee($type = "cappuccino")
{
return "Making a cup of $type.\n";
}
# => 制作一杯卡布奇诺
echo coffee();
# => 制作一杯
echo coffee(null);
# => 制作一杯浓缩咖啡
echo coffee("espresso");
```
### 箭头函数
```php
$y = 1;
$fn1 = fn($x) => $x + $y;
// 相当于按值使用 $y
$fn2 = function ($x) use ($y) {
return $x + $y;
};
echo $fn1(5); # => 6
echo $fn2(5); # => 6
```
PHP 类
------
### 构造函数 Constructor
```php
class Student {
public function __construct($name) {
$this->name = $name;
}
public function print() {
echo "Name: " . $this->name;
}
}
$alex = new Student("Alex");
$alex->print(); # => Name: Alex
```
### 继承 Inheritance
```php
class ExtendClass extends SimpleClass
{
// 重新定义父方法
function displayVar()
{
echo "Extending class\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
```
### 类变量 Classes variables
<!--rehype:wrap-class=row-span-2-->
```php
class MyClass
{
const MY_CONST = 'value';
static $staticVar = 'static';
// 可见度
public static $var1 = 'pubs';
// 仅限类
private static $var2 = 'pris';
// 类和子类
protected static $var3 = 'pros';
// 类和子类
protected $var6 = 'pro';
// 仅限类
private $var7 = 'pri';
}
```
静态访问
```php
echo MyClass::MY_CONST; # => value
echo MyClass::$staticVar; # => static
```
### 魔术方法
```php
class MyClass
{
// 对象被视为字符串
public function __toString()
{
return $property;
}
// 与 __construct() 相反
public function __destruct()
{
print "Destroying";
}
}
```
### 接口
```php
interface Foo
{
public function doSomething();
}
interface Bar
{
public function doSomethingElse();
}
class Cls implements Foo, Bar
{
public function doSomething() {}
public function doSomethingElse() {}
}
```
各种各样的
------
### 基本错误处理
```php
try {
// 做一点事
} catch (Exception $e) {
// 处理异常
} finally {
echo "Always print!";
}
```
### PHP 8.0 中的异常
<!--rehype:wrap-class=col-span-2-->
```php {.wrap}
$nullableValue = null;
try {
$value = $nullableValue ?? throw new InvalidArgumentException();
} catch (InvalidArgumentException) { // 变量是可选的
// 处理我的异常
echo "print me!";
}
```
### 自定义异常
<!--rehype:wrap-class=row-span-2-->
```php
class MyException extends Exception {
// 做一点事
}
```
用法
```php
try {
$condition = true;
if ($condition) {
throw new MyException('bala');
}
} catch (MyException $e) {
// 处理我的异常
}
```
### Nullsafe 运算符
<!--rehype:wrap-class=row-span-2-->
```php
// 从 PHP 8.0.0 开始,这一行:
$result = $repo?->getUser(5)?->name;
// 相当于下面的代码:
if (is_null($repo)) {
$result = null;
} else {
$user = $repository->getUser(5);
if (is_null($user)) {
$result = null;
} else {
$result = $user->name;
}
}
```
另见: [Nullsafe 运算符](https://wiki.php.net/rfc/nullsafe_operator)
### 常用表达
```php
$str = "Visit Quickref.me";
echo preg_match("/qu/i", $str); # => 1
```
查看: [PHP中的正则表达式](./regex.md#php中的正则表达式)
### fopen() 模式
:- | -
:- | -
`r` | 读
`r+` | 读写,前置
`w` | 写入,截断
`w+` | 读写,截断
`a` | 写,追加
`a+` | 读写,追加
### 运行时定义的常量
```php
define("CURRENT_DATE", date('Y-m-d'));
// 一种可能的表示
echo CURRENT_DATE; # => 2021-01-05
# => CURRENT_DATE is: 2021-01-05
echo 'CURRENT_DATE is: ' . CURRENT_DATE;
```
另见
----
- [PHP 官方中文文档](https://www.php.net/manual/zh/index.php) _(php.net)_
- [Learn X in Y minutes](https://learnxinyminutes.com/docs/php/) _(learnxinyminutes.com)_

629
docs/postgres.md Normal file
View File

@ -0,0 +1,629 @@
PostgreSQL 备忘清单
===
[PostgreSQL](https://www.postgresql.org/docs/current/) 备忘清单为您提供了常用的 PostgreSQL 命令和语句。
入门
---------------
### 入门
切换和连接
```shell
$ sudo -u postgres psql
```
列出所有数据库
```shell
postgres=# \l
```
连接到名为 postgres 的数据库
```shell
postgres=# \c postgres
```
断开
```shell
postgres=# \q
postgres=# \!
```
### psql 命令
<!--rehype:wrap-class=col-span-2-->
参数 | 示例 | 说明
:- |- | -
`[-d] <database>` | psql -d mydb | 连接到数据库
`-U` | psql -U john mydb | 以特定用户身份连接
`-h` `-p` | psql -h localhost -p 5432 mydb | 连接到主机/端口
`-U` `-h` `-p` `-d` | psql -U admin -h 192.168.1.5 -p 2506 -d mydb | 连接远程 PostgreSQL
`-W` | psql -W mydb | 强制密码
`-c` | psql -c '\c postgres' -c '\dt' | 执行 SQL 查询或命令
`-H` | psql -c "\l+" -H postgres > database.html | 生成 HTML 报告
`-l` | psql -l | 列出所有数据库
`-f` | psql mydb -f file.sql | 从文件执行命令
`-V` | psql -V | 打印 psql 版本
<!--rehype:className=show-header-->
### 获得帮助
:- | -
:- | -
`\h` | SQL 命令语法帮助
`\h` DELETE | DELETE SQL 语句语法
`\?` | PostgreSQL 命令列表
在 PostgreSQL 控制台中运行
PostgreSQL 工作
-------
### Recon 观察
显示版本
```sql
SHOW SERVER_VERSION;
```
显示系统状态
```sql
\conninfo
```
显示环境变量
```sql
SHOW ALL;
```
列出用户
```sql
SELECT rolname FROM pg_roles;
```
显示当前用户
```sql
SELECT current_user;
```
显示当前用户的权限
```sql
\du
```
显示当前数据库
```sql
SELECT current_database();
```
显示数据库中的所有表
```sql
\dt
```
列出函数
```sql
\df <schema>
```
### Databases 数据库
列出数据库
```sql
\l
```
连接到数据库
```sql
\c <database_name>
```
显示当前数据库
```sql
SELECT current_database();
```
[创建数据库](http://www.postgresql.org/docs/current/static/sql-createdatabase.html)
```sql
CREATE DATABASE <database_name> WITH OWNER <username>;
```
<!--rehype:className=wrap-text-->
[删除数据库](http://www.postgresql.org/docs/current/static/sql-dropdatabase.html)
```sql
DROP DATABASE IF EXISTS <database_name>;
```
<!--rehype:className=wrap-text-->
[重命名数据库](http://www.postgresql.org/docs/current/static/sql-alterdatabase.html)
```sql
ALTER DATABASE <old_name> RENAME TO <new_name>;
```
<!--rehype:className=wrap-text-->
### Tables 表
列出当前数据库中的表
```sql
\dt
SELECT table_schema,table_name FROM information_schema.tables ORDER BY table_schema,table_name;
```
<!--rehype:className=wrap-text-->
全局列表
```sql
\dt *.*.
SELECT * FROM pg_catalog.pg_tables
```
列表表架构
```sql
\d <table_name>
\d+ <table_name>
SELECT column_name, data_type, character_maximum_length
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = '<table_name>';
```
<!--rehype:className=wrap-text-->
[创建表](http://www.postgresql.org/docs/current/static/sql-createtable.html)
```sql
CREATE TABLE <table_name>(
<column_name> <column_type>,
<column_name> <column_type>
);
```
创建表,主键自增
```sql
CREATE TABLE <table_name> (
<column_name> SERIAL PRIMARY KEY
);
```
[删除表](http://www.postgresql.org/docs/current/static/sql-droptable.html)
```sql
DROP TABLE IF EXISTS <table_name> CASCADE;
```
### Permissions 权限
成为 postgres 用户,如果您有权限错误
```shell
sudo su - postgres
psql
```
[授予](http://www.postgresql.org/docs/current/static/sql-grant.html) 对数据库的所有权限
```sql
GRANT ALL PRIVILEGES ON DATABASE <db_name> TO <user_name>;
```
<!--rehype:className=wrap-text-->
授予数据库连接权限
```sql
GRANT CONNECT ON DATABASE <db_name> TO <user_name>;
```
<!--rehype:className=wrap-text-->
授予架构权限
```sql
GRANT USAGE ON SCHEMA public TO <user_name>;
```
授予函数权限
```sql
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO <user_name>;
```
<!--rehype:className=wrap-text-->
授予在所有表上选择、更新、插入、删除的权限
```sql
GRANT SELECT, UPDATE, INSERT ON ALL TABLES IN SCHEMA public TO <user_name>;
```
<!--rehype:className=wrap-text-->
在表上授予权限
```sql
GRANT SELECT, UPDATE, INSERT ON <table_name> TO <user_name>;
```
<!--rehype:className=wrap-text-->
授予对表的选择权限
```sql
GRANT SELECT ON ALL TABLES IN SCHEMA public TO <user_name>;
```
<!--rehype:className=wrap-text-->
### Columns 列
[添加栏目](http://www.postgresql.org/docs/current/static/sql-altertable.html)
```sql
ALTER TABLE <table_name> IF EXISTS
ADD <column_name> <data_type> [<constraints>];
```
<!--rehype:className=wrap-text-->
更新栏
```sql
ALTER TABLE <table_name> IF EXISTS
ALTER <column_name> TYPE <data_type> [<constraints>];
```
<!--rehype:className=wrap-text-->
删除列
```sql
ALTER TABLE <table_name> IF EXISTS
DROP <column_name>;
```
将列更新为自增主键
```sql
ALTER TABLE <table_name>
ADD COLUMN <column_name> SERIAL PRIMARY KEY;
```
<!--rehype:className=wrap-text-->
使用自动递增的主键插入表中
```sql
INSERT INTO <table_name>
VALUES (DEFAULT, <value1>);
INSERT INTO <table_name> (<column1_name>,<column2_name>)
VALUES ( <value1>,<value2> );
```
<!--rehype:className=wrap-text-->
### Data 数据
[选择](http://www.postgresql.org/docs/current/static/sql-select.html) 所有数据
```sql
SELECT * FROM <table_name>;
```
读取一行数据
```sql
SELECT * FROM <table_name> LIMIT 1;
```
搜索数据
```sql
SELECT * FROM <table_name> WHERE <column_name> = <value>;
```
<!--rehype:className=wrap-text-->
[插入](http://www.postgresql.org/docs/current/static/sql-insert.html) 数据
```sql
INSERT INTO <table_name> VALUES( <value_1>, <value_2> );
```
<!--rehype:className=wrap-text-->
[更新](http://www.postgresql.org/docs/current/static/sql-update.html) 数据
```sql
UPDATE <table_name>
SET <column_1> = <value_1>, <column_2> = <value_2>
WHERE <column_1> = <value>;
```
<!--rehype:className=wrap-text-->
[删除](http://www.postgresql.org/docs/current/static/sql-delete.html) 所有数据
```sql
DELETE FROM <table_name>;
```
删除特定数据
```sql
DELETE FROM <table_name>
WHERE <column_name> = <value>;
```
### Users 用户
<!--rehype:wrap-class=col-span-2-->
列出角色
```sql
SELECT rolname FROM pg_roles;
```
[创建用户](http://www.postgresql.org/docs/current/static/sql-createuser.html)
```sql
CREATE USER <user_name> WITH PASSWORD '<password>';
```
[删除用户](http://www.postgresql.org/docs/current/static/sql-dropuser.html)
```sql
DROP USER IF EXISTS <user_name>;
```
[更改](http://www.postgresql.org/docs/current/static/sql-alterrole.html) 用户密码
```sql
ALTER ROLE <user_name> WITH PASSWORD '<password>';
```
### Schema
列出 Schemas
```sql
\dn
SELECT schema_name FROM information_schema.schemata;
SELECT nspname FROM pg_catalog.pg_namespace;
```
[创建架构](http://www.postgresql.org/docs/current/static/sql-createschema.html)
```sql
CREATE SCHEMA IF NOT EXISTS <schema_name>;
```
[删除模式](http://www.postgresql.org/docs/current/static/sql-dropschema.html)
```sql
DROP SCHEMA IF EXISTS <schema_name> CASCADE;
```
PostgreSQL 命令
-----------
### 表
:- | -
:- | -
`\d <table>` | 描述表
`\d+ <table>` | 详细描述表格
`\dt` | 列出当前模式中的表
`\dt *.*` | 列出所有模式中的表
`\dt <schema>.*` | 列出架构的表
`\dp` | 列出表访问权限
`\det[+]` | 列出外部表
### 查询缓冲区
:- | -
:- | -
`\e [FILE]` | 编辑查询缓冲区(或文件)
`\ef [FUNC]` | 编辑函数定义
`\p` | 显示内容
`\r` | 重置(清除)查询缓冲区
`\s [FILE]` | 显示历史记录或保存到文件
`\w FILE` | 将查询缓冲区写入文件
### 信息
<!--rehype:wrap-class=row-span-4-->
:- | -
:- | -
`\l[+]` | 列出所有数据库
`\dn[S+]` | 列出架构
`\di[S+]` | 列出索引
`\du[+]` | 列出角色
`\ds[S+]` | 列出序列
`\df[antw][S+]` | 列出函数
`\deu[+]` | 列出用户映射
`\dv[S+]` | 列表视图
`\dl` | 列出大对象
`\dT[S+]` | 列出数据类型
`\da[S]` | 列出聚合
`\db[+]` | 列出表空间
`\dc[S+]` | 列出转化
`\dC[+]` | 列出演员表
`\ddp` | 列出默认权限
`\dd[S]` | 显示对象描述
`\dD[S+]` | 列出域
`\des[+]` | 列出国外服务器
`\dew[+]` | 列出外部数据包装器
`\dF[+]` | 列出文本搜索配置
`\dFd[+]` | 列出文本搜索词典
`\dFp[+]` | 列出文本搜索解析器
`\dFt[+]` | 列出文本搜索模板
`\dL[S+]` | 列出程序语言
`\do[S]` | 列出运算符
`\dO[S+]` | 列出排序规则
`\drds` | 列出每个数据库的角色设置
`\dx[+]` | 列出扩展
`S`:显示系统对象,`+`:附加细节
### 连接
:- | -
:- | -
`\c [DBNAME]` | 连接到新数据库
`\encoding [ENCODING]` | 显示或设置客户端编码
`\password [USER]` | 更改密码
`\conninfo` | 显示信息
### 格式化
:- | -
:- | -
`\a` | 在未对齐和对齐之间切换
`\C [STRING]` | 设置表格标题,如果没有则取消设置
`\f [STRING]` | 显示或设置未对齐的字段分隔符
`\H` | 切换 HTML 输出模式
`\t [on\|off]` | 仅显示行
`\T [STRING]` | 设置或取消设置 HTML \<table\> 标签属性
`\x [on\|off]` | 切换扩展输出
### 输入输出
:- | -
:- | -
`\copy ...` | 导入/导出表 _另见_ [复制](#导入导出-csv)
`\echo [STRING]` | 打印字符串
`\i FILE` | 执行文件
`\o [FILE]` | 将所有结果导出到文件
`\qecho [STRING]` | 输出流的字符串
### 变量
:- | -
:- | -
`\prompt [TEXT] NAME` | 设置变量
`\set [NAME [VALUE]]` | 设置变量 _(如果没有参数,则列出所有变量)_
`\unset NAME` | 删除变量
### 杂项
:- | -
:- | -
`\cd [DIR]` | 更改目录
`\timing [on\|off]` | 切换时间
`\! [COMMAND]` | 在shell中执行
`\! ls -l` | 在shell中列出所有
### 大对象
- `\lo_export LOBOID FILE`
- `\lo_import FILE [COMMENT]`
- `\lo_list`
- `\lo_unlink LOBOID`
各种各样的
-------------
### 备份
使用 pg_dumpall 备份所有数据库
```shell
$ pg_dumpall -U postgres > all.sql
```
使用 pg_dump 备份数据库
```shell
$ pg_dump -d mydb -f mydb_backup.sql
```
- &nbsp; `-a` &nbsp; 只转储数据,而不是模式(schema)
- &nbsp; `-s` &nbsp; 只转储模式,不转储数据
- &nbsp; `-c` &nbsp; 在重新创建之前删除数据库
- &nbsp; `-C` &nbsp; 还原前创建数据库
- &nbsp; `-t` &nbsp; 仅转储命名表
- &nbsp; `-F` &nbsp; 格式(`c`:自定义,`d`:目录,`t`tar)
<!--rehype:className=style-none-->
使用 `pg_dump -?` 获取完整的选项列表
### 恢复
使用 psql 恢复数据库
```shell
$ psql -U user mydb < mydb_backup.sql
```
使用 pg_restore 恢复数据库
```shell
$ pg_restore -d mydb mydb_backup.sql -c
```
- &nbsp; `-U` &nbsp; 指定数据库用户
- &nbsp; `-c` &nbsp; 在重新创建之前删除数据库
- &nbsp; `-C` &nbsp; 还原前创建数据库
- &nbsp; `-e` &nbsp; 如果遇到错误退出
- &nbsp; `-F` &nbsp; 格式(`c`:自定义,`d`:目录,`t`:tar`p`:纯文本sql(默认))
<!--rehype:className=style-none-->
使用 `pg_restore -?` 获取完整的选项列表
### 远程访问
获取 postgresql.conf 的位置
```shell
$ psql -U postgres -c 'SHOW config_file'
```
附加到 postgresql.conf
```shell
listen_addresses = '*'
```
附加到 pg_hba.conf(与 postgresql.conf 相同的位置)
```shell
host all all 0.0.0.0/0 md5
host all all ::/0 md5
```
重启 PostgreSQL 服务器
```shell
$ sudo systemctl restart postgresql
```
### 导入/导出 CSV
将表格导出为 CSV 文件
```sql
\copy table TO '<path>' CSV
\copy table(col1,col1) TO '<path>' CSV
\copy (SELECT...) TO '<path>' CSV
```
将 CSV 文件导入表格
```sql
\copy table FROM '<path>' CSV
\copy table(col1,col1) FROM '<path>' CSV
```
另见:[复制](https://www.postgresql.org/docs/current/sql-copy.html)
另见
----
- [Posgres-cheatsheet](https://gist.github.com/apolloclark/ea5466d5929e63043dcf#posgres-cheatsheet) _(gist.github.com)_

1241
docs/python.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
Quick Reference 备忘清单
===
这是您可以在 Quick Reference 备忘单上使用的样式参考,快速参与贡献
这是您可以在 Quick Reference 备忘单上使用的样式参考,快速参与[贡献](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)
入门
---
### 本地编译预览
简单的将仓库克隆下来本地调试页面展示
将仓库克隆本地调试页面。请参阅[贡献指南](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)了解如何开始
#### 克隆仓库
@ -22,14 +22,103 @@ git clone git@github.com:jaywcjlove/reference.git
```shell
npm i # 安装依赖
npm run build # 编译输出 HTML
npm run start # 监听 md 文件编译输出 HTML
```
HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静态页面在浏览器中打开预览。
### 介绍
```shell
npm run start # 监听 md 文件编译输出 HTML
```
在备忘清单采用 `HTML 注释语法`,标识网站布局和一些样式,目的是为了在 `GitHub` 中也是正常毫无瑕疵的预览 `Markdown`
### 目录结构
```bash
.
├── CONTRIBUTING.md # 贡献说明
├── Dockerfile
├── LICENSE
├── README.md # Home(首页) 内容
├── dist # 编译后的静态资源目录
├── docs # Markdown 文档(速查表)
│   ├── bash.md
│   ├── ....
│   └── yaml.md
├── package.json
└── scripts # MD 转 HTML 的编译脚本
├── assets # LOGO 图标文件资源
├── ....
└── watch.mjs
```
### 添加一个备忘清单
一个简单的备忘清单包含 `页面大标题<h1>`,放在大标题下面的 `介绍` 文本,`<h2>` 分类标题,`<h3>` 内容为 `卡片`
```markdown
备忘清单 (页面大标题)
===
这是您可以在当前清单上使用的样式参考!备忘清单介绍
入门 (分类标题)
---
### 介绍 (卡片)
卡片内容
```
上面 markdown 内容存放到 `docs` 目录中,命名为 `xxx.md`
### 首页导航
<!--rehype:wrap-class=col-span-2-->
首页(`README.md`)存放在仓库的根目录,通过这个 `README.md` 自动生成首页导航,下面是导航实例:
```markdown
## Linux 命令
[Cron](./docs/cron.md)<!--rehype:style=background: rgb(239 68 68/var(\-\-bg\-opacity));-->
<!--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"`
- 使用 `<!--rehype:class=home-card-->` 标识卡片样式
### 首页提示配置
```markdown
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing-->
```
<!--rehype:className=wrap-text-->
添加 `contributing` 类名,会在卡片下方默认添加 `👆待完善需要您的参与`
```markdown
class=tag&data-info=👆看看还缺点儿什么?
```
上面示例将默认提示更改为: `👆看看还缺点儿什么?`
```markdown
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=tag&data-lang=Python-->
```
<!--rehype:className=wrap-text-->
添加 `class=tag&data-lang=Python` 类名和参数,会在卡片右上角标记 _`Python`_
Markdown 语法注释
---
### 介绍
<!--rehype:wrap-class=row-span-2-->
在备忘清单采用 `HTML 注释语法`,标识网站布局和一些样式,目的是为了在 `GitHub` 中也是正常毫无瑕疵的预览 [`Markdown`](./markdown.md)。
```markdown
### 卡片标题
@ -38,26 +127,26 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
卡片 Markdown 内容展示,下面注释语法为文字内容改变样式
<!--rehype:style=color: red;-->
```
<!--rehype:className=wrap-text -->
<!--rehype:className=wrap-text-->
使用 `col-span-2` 类标识,卡片占 `2` 列位置
上面基础示例,使用 `col-span-2` 类标识,卡片占 `2` 列位置,参考现有备忘清单的源代码是一个好习惯!
### 注释语法介绍
<!--rehype:wrap-class=row-span-3&style=color:black;background-color: #d7a100;-->
<!--rehype:wrap-class=row-span-4&style=color:black;background-color: #d7a100;-->
- 在某个 Markdown 语法下方或者后面,添加 HTML注释
- 在某个 [`Markdown`](./markdown.md) 语法下方或者后面,添加 HTML注释
-`<!--rehype:` 开始,`-->` 结束,包裹参数内容
- 内容采用 URL 参数的字符拼接方式
#### 语法
`<!--rehype:` + `key=value` + `&` + `key=value` + `-->`
`标识开始` + `参数` + `分隔符` + `参数` + `标识结束`
`<!--rehype:` _+_ `key=value` _+_ **`&`** _+_ `key=value` _+_ `-->`
`标识开始` + `参数` + `分隔符(&)` + `参数` + `标识结束`
#### 示例
```markdown
### H2 部分
## H2 部分
<!--rehype:body-class=cols-2-->
### H3 部分
@ -70,8 +159,7 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
### 标题
<!--rehype:wrap-class=row-span-3&style=color:red;-->
```
<!--rehype:className=wrap-text -->
<!--rehype:className=wrap-text-->
#### 参数说明
@ -79,7 +167,7 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
---- | ----
`body-style` | 包裹所有卡片`外壳`的样式
`body-class` | 用于卡片栏布局,添加`类`
`wrap-style` | 卡片栏添加 CSS 样式
`wrap-style` | 卡片栏添加 [CSS](./css.md) 样式
`wrap-class` | 用于卡片占位,添加`类`
### 文字颜色
@ -97,7 +185,7 @@ _我是红色_<!--rehype:style=color: red;-->
**加粗变大红色**
<!--rehype:style=color: red;font-size: 18px-->
```
<!--rehype:className=wrap-text -->
<!--rehype:className=wrap-text-->
上面添加注释样式,文字 _加粗变大红色_<!--rehype:style=color: red;font-size: 18px-->`红`并且`大`
@ -107,11 +195,10 @@ _我是红色_<!--rehype:style=color: red;-->
\```js
function () {}
\```
<!--rehype:className=wrap-text -->
<!--rehype:className=wrap-text-->
```
如果代码块内容太长,使用强制换行类解决
如果代码块内容太长,使用强制换行类(`wrap-text`)解决
### 展示表格表头
@ -136,7 +223,7 @@ export const Student = (
);
```
上面 `{1,4-5}` 行代码高亮,下面是 `Markdown` 代码示例
上面 `{1,4-5}` 行代码高亮,下面是 [`Markdown`](./markdown.md) 代码示例
```markdown
```jsx {1,4-5}
@ -151,11 +238,11 @@ export const Student = (
添加注释配置 `<!--rehype:tooltips-->` 添加一个 Tooltips 提示。
### H3 部分(卡片)背景颜色
<!--rehype:wrap-style=background: #00c69357;-->
<!--rehype:wrap-style=background: #8dffd42e;-->
```markdown
### H3 部分(卡片)背景颜色
<!--rehype:wrap-style=background: #00c69357;-->
<!--rehype:wrap-style=background: #8dffd42e;-->
```
<!--rehype:className=wrap-text -->
@ -171,7 +258,7 @@ export const Student = (
### 快捷键样式
| Key | value |
| Key | value |
| ---- | ---- |
| `快捷键` | 说明 |
| `快捷键` | 说明 |
@ -192,6 +279,8 @@ const school = <div>学校</div>;
```jsx showLineNumbers
```
标记语言后面添加 `showLineNumbers` 标识
### 内置类样式
:- | -
@ -200,6 +289,7 @@ const school = <div>学校</div>;
`wrap-text` | 超出换行
`show-header` | 展示表头
`style-none` | 隐藏 `<ul>` 列表样式
`style-list` | `<table>` 单元格行展示
<!--rehype:className=shortcuts-->
### 颜色标签
@ -207,10 +297,73 @@ const school = <div>学校</div>;
:- | -
:- | -
`<yel>` | <yel>黄色</yel>
`<red>` | <yel>红色</yel>
`<pur>` | <pur>紫色</pur>
`<code>` 或 <code>\`\`</code> | <code>绿</code>`色`
`<del>``~~删除~~` | <del>~~红色~~</del>
<!--rehype:className=shortcuts-->
### HTML 代码预览
```
```html preview
<b>这里是你的 HTML 代码</b>
\```
```
---
```html preview
<b>这里是你的 HTML 代码</b>
```
上面的 [`markdown`](./markdown.md) 代码在 `meta` 位置添加 `preview` 标识,[HTML](./html.md) 代码将被执行预览
### 隐藏卡片标题
<!--rehype:style=display:none;&wrap-style=padding-top: 0;-->
```
隐藏卡片标题,在 H3 标题下面添加注释样式
```
```markdown {2}
### 隐藏卡片标题
<!--rehype:style=display:none;&wrap-style=padding-top: 0;-->
```
<!--rehype:className=wrap-text -->
### 注释类配置
<!--rehype:wrap-class=col-span-2-->
类 | 说明
---- | ----
`<!--rehype:className=wrap-text-->` | 强制换行
`<!--rehype:className=show-header-->` | 展示表格表头
`<!--rehype:className=shortcuts-->` | 快捷键样式
`<!--rehype:className=auto-wrap-->` | 隐藏表头强制小尺寸自动换行
`<!--rehype:className=style-list-arrow-->` | 列表箭头样式展示表格
`<!--rehype:className=style-list-->` | 列表样式展示表格
`<!--rehype:className=left-align-->` | 表格末尾列左对齐
`<!--rehype:className=style-none-->` | \<li> 没有标记
`<!--rehype:className=style-timeline-->` | 时间轴样式
`<!--rehype:className=style-arrow-->` | 箭头标记
### KaTeX 数学渲染
```KaTeX
c = \pm\sqrt{a^2 + b^2}
L = \frac{1}{2} \rho v^2 S C_L
```
上面示例 [`Markdown`](./markdown.md) 代码源码
```markdown {1}
```KaTeX
c = \pm\sqrt{a^2 + b^2}
L = \frac{1}{2} \rho v^2 S C_L
```
还可以单行展示 `KaTeX:c = \pm\sqrt{a^2 + b^2}`,需要标记 <code>\`KaTeX:数学公式\`</code> 将被显示成数学公式,这是基于 [KaTeX](https://katex.org/) 生成
布局
---
@ -229,7 +382,7 @@ H2 部分
上面实例 `H2 部分` 标题下面有三个`卡片`,默认 `3` 栏布局。
```markdown
```markdown {3}
H2 部分
---
<!--rehype:body-class=cols-2-->
@ -247,11 +400,12 @@ H2 部分
`cols-3` | `3` 栏卡片布局
`cols-4` | `4` 栏卡片布局
`cols-5` | `5` 栏卡片布局
`cols-{1~6}` | `1~6` 栏卡片布局
<!--rehype:className=show-header -->
### 占位布局 style 写法
```markdown
```markdown {2}
### H3 部分
<!--rehype:wrap-style=grid-row: span 2/span 2;-->
```
@ -261,7 +415,7 @@ H2 部分
### 卡片栏布局 style 写法
```markdown
```markdown {2}
## H2 部分
<!--rehype:body-style=grid-template-columns: repeat(2,minmax(0,1fr));-->
```
@ -269,10 +423,9 @@ H2 部分
放在 `## H2 部分` 下面的注释配置,与 `<!--rehype:body-class=cols-2-->` 相同,设置 2 栏布局。
### H3 部分
```markdown
```markdown {2,4}
### 卡片 1 (H3 部分)
<!--rehype:wrap-class=row-span-2-->
### 卡片 2 (H3 部分)
@ -285,9 +438,11 @@ H2 部分
`col-span-2` | `2` 列占位
`col-span-3` | `3` 列占位
`col-span-4` | `4` 列占位
`col-span-5` | `5` 列占位
`row-span-2` | `2` 行占位
`row-span-3` | `3` 行占位
`row-span-4` | `4` 行占位
`row-span-5` | `5` 行占位
<!--rehype:className=show-header -->
### 卡片合并行布局 1
@ -301,7 +456,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### H3 Title 1
@ -326,7 +481,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### Title 1
@ -374,7 +529,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### Title 1
@ -398,7 +553,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈┈┈┈┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### Title 1
@ -422,7 +577,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### Title 1
@ -446,7 +601,7 @@ H2 部分
╰┈┈┈┈┈┈┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### Title 1
@ -470,7 +625,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
H2 部分
@ -501,7 +656,7 @@ H2 部分
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
```
上面布局效果 Markdown 源码:
上面布局效果 [Markdown](./markdown.md) 源码:
```markdown
### Title 1
@ -515,7 +670,6 @@ H2 部分
在 `Title 1` 标题添加 `col-span-2` 和 `row-span-2` 占位类,使用 `空格` 间隔。
表格
---
@ -523,16 +677,16 @@ H2 部分
#### Date
| | |
| ---- | ---- |
:- | :-
:- | :-
`%m/%d/%Y` | 06/05/2013
`%A, %B %e, %Y` | Sunday, June 5, 2013
`%b %e %a` | Jun 5 Sun
#### Time
| | |
| ---- | ---- |
:- | :-
:- | :-
`%H:%M` | 23:05
`%I:%M %p` | 11:05 PM
@ -540,8 +694,8 @@ H2 部分
### 快捷键
| | |
| ---- | ---- |
:- | :-
:- | :-
`V` | Vector
`P` | Pencil
`T` | Text
@ -561,6 +715,50 @@ H2 部分
`<!--rehype:className=show-header-->`
### 列表样式展示表格
:- | :-
:- | :-
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
<!--rehype:className=style-list-->
`<!--rehype:className=style-list-->`
### 列表箭头样式展示表格
:- | :-
:- | :-
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
<!--rehype:className=style-list-arrow-->
`<!--rehype:className=style-list-arrow-->`
### 隐藏表头强制小尺寸自动换行
:- | :-
:- | :-
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
<!--rehype:className=auto-wrap-->
`<!--rehype:className=auto-wrap-->`
### 表格末尾列左对齐
<!--rehype:wrap-class=col-span-2-->
| Prefix | What |
| ---- | ---- |
`//` | Anywhere
`./` | Relative
<!--rehype:className=show-header left-align-->
默认表格末尾列`右对齐`,添加 `<!--rehype:className=left-align-->` 类让其`左对齐`
列表
---
@ -584,6 +782,30 @@ H2 部分
`<!--rehype:className=cols-4-->`
### 列表步骤
<!--rehype:wrap-class=row-span-2-->
- **重命名为 new_name**
```bash
$ git branch -m <new_name>
```
- 推送和**重置**
```bash
$ git push origin -u <new_name>
```
- 删除远程分支
```bash
$ git push origin --delete <old>
```
<!--rehype:className=style-timeline-->
`<!--rehype:className=style-timeline-->`
### 没有标记
- Item 1
@ -592,10 +814,31 @@ H2 部分
- Item 4
- Item 5
- Item 6
- Item 7
- Item 8
- Item 9
<!--rehype:className=cols-3 style-none-->
`<!--rehype:className=cols-3 style-none-->`
### 圆圈标记
- Item 1
- Item 2
- Item 3
<!--rehype:className=style-round-->
`<!--rehype:className=style-round-->`
### 箭头标记
- Item 1
- Item 2
- Item 3
<!--rehype:className=style-arrow-->
`<!--rehype:className=style-arrow-->`
H2 部分 - 5列效果展示
---
<!--rehype:body-class=cols-5-->

View File

@ -3,7 +3,6 @@ React 备忘清单
适合初学者的综合 React 备忘清单。
入门
----
@ -12,9 +11,9 @@ React 备忘清单
React 是一个用于构建用户界面的 JavaScript 库。
- [React 官方文档](https://reactjs.org/) _(reactjs.org)_
- [Styled Components 备忘清单](./styled-components.md) _(jaywcjlove.github.io)_
```js
import React from 'react'
import {createRoot} from 'react-dom/client'
import App from './App'
```
@ -46,19 +45,19 @@ import ReactDOM from 'react-dom'
export class Hello extends Component {
...
}
export default function World() {
/* ... */
}
```
使用 `export` 或者 `export default` 导出 `Hello` 组件
使用 `export` 导出 **`Hello`**`export default` 导出 **`World`** 组件
```jsx
import { Hello } from './hello.js';
const Example = <Hello />;
import World, { Hello } from './hello.js';
```
使用 `import` 导入 `Hello` 组件,在示例中使用。
### React 组件中的 CSS
```jsx {2,5}
@ -81,7 +80,6 @@ export const Student = (
);
```
### 属性
```jsx
@ -111,7 +109,6 @@ class Student extends React.Component {
`class` 组件使用 `this.props` 访问传递给组件的属性。
### Children
<!--rehype:wrap-class=row-span-2-->
@ -137,7 +134,7 @@ function AlertBox(props) {
}
```
----
-----
```jsx
{props.children}
@ -157,7 +154,7 @@ class AlertBox extends React.Component {
}
```
----
-----
```jsx
{this.props.children}
@ -296,7 +293,7 @@ function Student() {
### Portals
React 并*没有*创建一个新的 `div`。它只是把子元素渲染到 `domNode` 中。`domNode` 是一个可以在任何位置的有效 DOM 节点。
React 并_没有_创建一个新的 `div`。它只是把子元素渲染到 `domNode` 中。`domNode` 是一个可以在任何位置的有效 DOM 节点。
```jsx
render() {
@ -437,7 +434,7 @@ function CustomTextInput(props) {
</div>
```
----
-----
- [识别不安全的生命周期](https://zh-hans.reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles)
- [关于使用过时字符串 ref API 的警告](https://zh-hans.reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)
@ -753,7 +750,7 @@ export default function Weather(props) {
}
```
----
-----
```js
{isShow && <div>内容</div>}
@ -859,7 +856,6 @@ class Welcome extends React.Component {
`this.props` | 组件接受参数
`this.state` | 组件内状态
### Pure 组件
```jsx
@ -1002,7 +998,7 @@ Menu.Item = ({ children }) => (
);
```
----
-----
```jsx
<Menu>
@ -1329,7 +1325,7 @@ PropTypes 属性类型检查
import PropTypes from 'prop-types'
```
----
-----
:- | -
:- | -
@ -1353,7 +1349,6 @@ import PropTypes from 'prop-types'
`oneOf(any)` | 枚举类型
`oneOfType([type])` | 几种类型中的任意一个类型
#### _数组 Array_
:- | -
@ -1536,4 +1531,4 @@ MyComponent.propTypes = {
- [React 官方中文文档](https://zh-hans.reactjs.org/) _(zh-hans.reactjs.org)_
- [反应生命周期方法图](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) _(projects.wojtekmaj.pl)_
- [React 16 Cheat Sheet](https://reactcheatsheet.com)
- [Awesome React](https://github.com/enaqx/awesome-react) _(github.com)_
- [Awesome React](https://github.com/enaqx/awesome-react) _(github.com)_

View File

@ -33,7 +33,6 @@ RegEX 备忘清单
`[a-zA-Z]` | 范围内的字符:<br>`a-z``A-Z`
`[a-zA-Z0-9]` | 范围内的字符:<br>`a-z``A-Z``0-9`
### 量词
范例 | 说明
@ -115,7 +114,6 @@ RegEX 备忘清单
`[\b]` | 退格字符
`\` | 使任何字符文字
### 锚点
范例 | 说明
@ -129,7 +127,6 @@ RegEX 备忘清单
`\b` | 一个词的边界
`\B` | 非单词边界
### 替代
范例 | 说明
@ -210,8 +207,8 @@ RegEX 备忘清单
`(?!...)` | 负先行断言
`(?<=...)` | 正后发断言
`(?<!...)` | 负后发断言
`?= `|正先行断言-存在
`?! `|负先行断言-排除
`?=`|正先行断言-存在
`?!`|负先行断言-排除
`?<=`|正后发断言-存在
`?<!`|负后发断言-排除
@ -244,30 +241,30 @@ RegEX 备忘清单
:-|-
:-|-
`(*ACCEPT)` | 控制动词
`(*FAIL)` | 控制动词
`(*MARK:NAME)` | 控制动词
`(*COMMIT)` | 控制动词
`(*PRUNE)` | 控制动词
`(*SKIP)` | 控制动词
`(*THEN)` | 控制动词
`(*UTF)` | 图案修饰符
`(*UTF8)` | 图案修饰符
`(*UTF16)` | 图案修饰符
`(*UTF32)` | 图案修饰符
`(*UCP)` | 图案修饰符
`(*CR)` | 换行修饰符
`(*LF)` | 换行修饰符
`(*CRLF)` | 换行修饰符
`(*ANYCRLF)` | 换行修饰符
`(*ANY)` | 换行修饰符
`\R` | 换行修饰符
`(*BSR_ANYCRLF)` | 换行修饰符
`(*BSR_UNICODE)` | 换行修饰符
`(*LIMIT_MATCH=x)` | 正则表达式引擎修饰符
`(*LIMIT_RECURSION=d)` | 正则表达式引擎修饰符
`(*NO_AUTO_POSSESS)` | 正则表达式引擎修饰符
`(*NO_START_OPT)` | 正则表达式引擎修饰符
`(*ACCEPT)` | 控制动词
`(*FAIL)` | 控制动词
`(*MARK:NAME)` | 控制动词
`(*COMMIT)` | 控制动词
`(*PRUNE)` | 控制动词
`(*SKIP)` | 控制动词
`(*THEN)` | 控制动词
`(*UTF)` | 图案修饰符
`(*UTF8)` | 图案修饰符
`(*UTF16)` | 图案修饰符
`(*UTF32)` | 图案修饰符
`(*UCP)` | 图案修饰符
`(*CR)` | 换行修饰符
`(*LF)` | 换行修饰符
`(*CRLF)` | 换行修饰符
`(*ANYCRLF)` | 换行修饰符
`(*ANY)` | 换行修饰符
`\R` | 换行修饰符
`(*BSR_ANYCRLF)` | 换行修饰符
`(*BSR_UNICODE)` | 换行修饰符
`(*LIMIT_MATCH=x)` | 正则表达式引擎修饰符
`(*LIMIT_RECURSION=d)` | 正则表达式引擎修饰符
`(*NO_AUTO_POSSESS)` | 正则表达式引擎修饰符
`(*NO_START_OPT)` | 正则表达式引擎修饰符
正则表达式示例
--------------
@ -276,26 +273,25 @@ RegEX 备忘清单
范例 | 说明
:-|-
`ring ` | 匹配 <yel>ring</yel> sp<yel>ring</yel>board 等。
`. ` | 匹配 <yel>a</yel><yel>9</yel><yel>+</yel> 等。
`h.o ` | 匹配 <yel>hoo</yel><yel>h2o</yel><yel>h/o</yel> 等。
`ring\? ` | 匹配 <yel>ring?</yel>
`\(quiet\) ` | 匹配<yel>(安静)</yel>
`c:\\windows ` | 匹配 <yel>c:\windows</yel>
`ring` | 匹配 <yel>ring</yel> sp<yel>ring</yel>board 等。
`.` | 匹配 <yel>a</yel><yel>9</yel><yel>+</yel> 等。
`h.o` | 匹配 <yel>hoo</yel><yel>h2o</yel><yel>h/o</yel> 等。
`ring\?` | 匹配 <yel>ring?</yel>
`\(quiet\)` | 匹配<yel>(安静)</yel>
`c:\\windows` | 匹配 <yel>c:\windows</yel>
使用 `\` 搜索这些特殊字符:<br> `[ \ ^ $ . | ? * + ( ) { }`
### 速记类
范例 | 说明
:-|-
`\w ` | “单词”字符 <br> _(字母、数字或下划线)_
`\d ` | 数字
`\s ` | 空格 <br> _(空格、制表符、vtab、换行符)_
`\W, \D, or \S ` | 不是单词、数字或空格
`[\D\S] ` | 表示不是数字或空格,两者都匹配
`[^\d\s] ` | 禁止数字和空格
`\w` | “单词”字符 <br> _(字母、数字或下划线)_
`\d` | 数字
`\s` | 空格 <br> _(空格、制表符、vtab、换行符)_
`\W, \D, or \S` | 不是单词、数字或空格
`[\D\S]` | 表示不是数字或空格,两者都匹配
`[^\d\s]` | 禁止数字和空格
### 出现次数
@ -311,9 +307,9 @@ RegEX 备忘清单
范例 | 说明
:-|-
`cat\|dog ` | 匹配 <yel>cat</yel><yel>dog</yel>
`id\|identity ` | 匹配 <yel>id</yel><yel>id</yel>entity
`identity\|id ` | 匹配 <yel>id</yel><yel>identity</yel>
`cat\|dog` | 匹配 <yel>cat</yel><yel>dog</yel>
`id\|identity` | 匹配 <yel>id</yel><yel>id</yel>entity
`identity\|id` | 匹配 <yel>id</yel><yel>identity</yel>
当替代品重叠时,命令从长到短
@ -334,7 +330,7 @@ RegEX 备忘清单
范例 | 说明
:-|-
`* + {n,}`<br>_greedy_ | 尽可能匹配
`<.+> ` | 在 <yel>\<b>bold\<\/b></yel> 中找到 1 个大匹配项
`<.+>` | 在 <yel>\<b>bold\<\/b></yel> 中找到 1 个大匹配项
`*? +? {n,}?`<br>_lazy_ | 尽可能少匹配
`<.+?>` | 在 \<<yel>b</yel>>bold\<<yel>\/b</yel>> 中找到 2 个匹配项
@ -343,20 +339,19 @@ RegEX 备忘清单
范例 | 说明
:-|-
`\b ` | “单词”边缘(非“单词”字符旁边)
`\bring ` | 单词以“ring”开头例如 <yel>ringtone</yel>
`ring\b ` | 单词以“ring”结尾例如 <yel>spring</yel>
`\b9\b ` | 匹配单个数字 <yel>9</yel>,而不是 19、91、99 等。
`\b[a-zA-Z]{6}\b ` | 匹配 6 个字母的单词
`\B ` | 不是字边
`\Bring\B ` | 匹配 <yel>springs</yel><yel>wringer</yel>
`^\d*$ ` | 整个字符串必须是数字
`\b` | “单词”边缘(非“单词”字符旁边)
`\bring` | 单词以“ring”开头例如 <yel>ringtone</yel>
`ring\b` | 单词以“ring”结尾例如 <yel>spring</yel>
`\b9\b` | 匹配单个数字 <yel>9</yel>,而不是 19、91、99 等。
`\b[a-zA-Z]{6}\b` | 匹配 6 个字母的单词
`\B` | 不是字边
`\Bring\B` | 匹配 <yel>springs</yel><yel>wringer</yel>
`^\d*$` | 整个字符串必须是数字
`^[a-zA-Z]{4,20}$` | 字符串必须有 4-20 个字母
`^[A-Z] ` | 字符串必须以大写字母开头
`[\.!?"')]$ ` | 字符串必须以终端标点结尾
`^[A-Z]` | 字符串必须以大写字母开头
`[\.!?"')]$` | 字符串必须以终端标点结尾
### 修饰
### 修饰
范例 | 说明
:-|-
@ -371,8 +366,8 @@ RegEX 备忘清单
范例 | 说明
:-|-
`(in\|out)put ` | 匹配 <yel>input</yel><yel>output</yel>
`\d{5}(-\d{4})?` | 美国邮政编码 _(“+ 4”可选)_
`(in\|out)put` | 匹配 <yel>input</yel><yel>output</yel>
`\d{5}(-\d{4})?` | 美国邮政编码 _(“+ 4”可选)_
如果组后匹配失败,解析器会尝试每个替代方案。
<br>
@ -417,11 +412,10 @@ RegEX 备忘清单
`(?<! )` | 向后看,如果你找不到后面
`\b\w+?(?=ing\b)` | 匹配 <yel>warbl</yel>ing, <yel>str</yel>ing, <yel>fish</yel>ing, ...
`\b(?!\w+ing\b)\w+\b` | 不以“ing”结尾的单词
`(?<=\bpre).*?\b ` | 匹配 pre<yel>tend</yel>、pre<yel>sent</yel>、pre<yel>fix</yel>、...
`(?<=\bpre).*?\b` | 匹配 pre<yel>tend</yel>、pre<yel>sent</yel>、pre<yel>fix</yel>、...
`\b\w{3}(?<!pre)\w*?\b` | 不以“pre”开头的词
`\b\w+(?<!ing)\b` | 匹配不以“ing”结尾的单词
### If-then-else
匹配 `Mr.``Ms.` 如果单词 `her` 稍后在字符串中
@ -458,7 +452,7 @@ M(?(?=.*?\bher\b)s|r)\.
表达式 | 匹配示例
:- | -
`.ar` | The `car` `par`ked in the `gar`age.
`.ar` | The `car` <pur>`par`</pur>ked in the `gar`age.
`ar[.]` | A garage is a good place to park a c`ar`.
<!--rehype:className=show-header-->
@ -480,7 +474,7 @@ M(?(?=.*?\bher\b)s|r)\.
表达式 | 匹配示例
:- | -
`[a-z]*` | T`he` `car` `parked` `in` `the` `garage` #21.
`[a-z]*` | T`he` <pur>`car`</pur> `parked` <pur>`in`</pur> `the` <pur>`garage`</pur> #21.
`\s*cat\s*` | The fat `cat` sat on the con`cat`enation.
表达式 `[a-z]*` 匹配一个行中所有以小写字母开头的字符串。
@ -509,7 +503,7 @@ M(?(?=.*?\bher\b)s|r)\.
`[0-9]{2,3}` | The number was 9.`999`7 but we rounded it off to `10`.0.
`[0-9]{2,}` | The number was 9.`9997` but we rounded it off to `10`.0.
`[0-9]{3}` | The number was 9.`999`7 but we rounded it off to 10.0.
<!--rehype:className=show-header-->
<!--rehype:className=style-list-arrow-->
### `(...)` 特征标群
@ -622,7 +616,7 @@ M(?(?=.*?\bher\b)s|r)\.
表达式 | 匹配示例
:- | -
`The` | The `fat` cat sat on the mat.
`/The/gi` | The `fat` `cat` `sat` on the `mat`.
`/The/gi` | `The` fat cat sat on `the` mat.
<!--rehype:className=show-header-->
修饰语 `i` 用于忽略大小写,`g` 表示全局搜索。
@ -649,8 +643,8 @@ M(?(?=.*?\bher\b)s|r)\.
表达式 | 匹配示例
:- | -
`/(.*at)/` | `The fat cat sat on the mat`.
`/(.*?at)/` | `The fat` cat sat on the mat.
`/(.*at)/` | `The fat cat sat on the mat`.
`/(.*?at)/` | `The fat` cat sat on the mat.
<!--rehype:className=show-header-->
Python 中的正则表达式
@ -664,7 +658,6 @@ Python 中的正则表达式
import re
```
### 实例
<!--rehype:wrap-class=col-span-2 row-span-3-->
@ -729,18 +722,15 @@ False
函数 | 说明
:-|-
`re.findall` | 返回包含所有匹配项的列表
`re.finditer` | 返回一个可迭代的匹配对象每个匹配一个
`re.finditer` | 返回一个可迭代的匹配对象<br/> _(每个匹配一个)_
`re.search` | 如果字符串中的任何位置存在匹配项,则返回 Match 对象
`re.split` | 返回一个列表,其中字符串在每次匹配时被拆分
`re.sub` | 用字符串替换一个或多个匹配项
`re.compile` | 编译正则表达式模式供以后使用
`re.escape` | 返回所有非字母数字反斜杠的字符串
### Flags 标志
:- | - | -
:- | - | -
`re.I` | `re.IGNORECASE` | 忽略大小写
@ -750,8 +740,6 @@ False
`re.U` | `re.UNICODE` | 使 `\w``\b``\d``\s` _unicode 依赖_
`re.X` | `re.VERBOSE` | 可读风格
JavaScript 中的正则表达式
---------------
@ -830,7 +818,7 @@ let regex = /apples/gi;
console.log(text.match(regex));
```
### split()
### split()
<!--rehype:wrap-class=col-span-2-->
```javascript
@ -855,7 +843,7 @@ console.log(array[1]);
### replace()
```javascript {.wrap}
```javascript
let text = 'Do you like aPPles?';
let regex = /apples/i
@ -894,14 +882,12 @@ text.replaceAll(regex, "mangoes");
```
<!--rehype:className=wrap-text-->
PHP中的正则表达式
------------
### 函数
<!--rehype:wrap-class=col-span-2-->
:- | -
:- | -
`preg_match()` | 执行正则表达式匹配
@ -911,7 +897,6 @@ PHP中的正则表达式
`preg_split()` | 按正则表达式模式拆分字符串
`preg_grep()` | 返回与模式匹配的数组条目
### preg_replace
```php
@ -923,7 +908,6 @@ echo preg_replace($regex, "QuickRef", $str);
```
<!--rehype:className=wrap-text-->
### preg_match
```php
@ -933,7 +917,6 @@ $regex = "#quickref#i";
echo preg_match($regex, $str);
```
### preg_matchall
<!--rehype:wrap-class=col-span-2 row-span-2-->
@ -952,17 +935,15 @@ if (preg_match_all($regex, $input_str, $matches_out)) {
}
```
### preg_grep
```php
```php
$arr = ["Jane", "jane", "Joan", "JANE"];
$regex = "/Jane/";
// Output: Jane
echo preg_grep($regex, $arr);
```
### preg_split
<!--rehype:wrap-class=col-span-2-->
@ -973,7 +954,6 @@ $regex = "@\s@";
print_r(preg_split($regex, $str));
```
Java 中的正则表达式
-------------
@ -1003,10 +983,8 @@ boolean s3 = Pattern.matches(".s", "XXXX");
System.out.println(s3); // Outputs: false
```
### 模式字段
:- | -
:- | -
`CANON_EQ` | 规范等价
@ -1017,7 +995,6 @@ System.out.println(s3); // Outputs: false
`UNICODE_CASE` | Unicode 感知大小写折叠
`UNIX_LINES` | Unix 行模式
### 方法
#### Pattern
@ -1029,10 +1006,10 @@ System.out.println(s3); // Outputs: false
#### 匹配器
- int start([int group | 字符串名称])
- int end([int group | 字符串名称])
- int start([int group | 字符串名称])
- int end([int group | 字符串名称])
- 布尔 find([int start])
- 字符 group([int 组 | 字符串名称])
- 字符 group([int 组 | 字符串名称])
- 匹配器重置 reset()
#### String
@ -1043,7 +1020,6 @@ System.out.println(s3); // Outputs: false
还有更多方法...
### 例子
<!--rehype:wrap-class=col-span-2-->
@ -1073,7 +1049,6 @@ while (m.find()) {
System.out.println(matches);
```
MySQL中的正则表达式
-------------
<!--rehype:body-class=cols-2-->
@ -1082,16 +1057,15 @@ MySQL中的正则表达式
函数名称 | 说明
:- | -
`REGEXP ` | 字符串是否匹配正则表达式
`REGEXP_INSTR() ` | 匹配正则表达式的子字符串的起始索引 <br>_注意仅限 MySQL 8.0+_
`REGEXP_LIKE() ` | 字符串是否匹配正则表达式 <br>_(注意:仅 MySQL 8.0+)_
`REGEXP` | 字符串是否匹配正则表达式
`REGEXP_INSTR()` | 匹配正则表达式的子字符串的起始索引 <br>_注意仅限 MySQL 8.0+_
`REGEXP_LIKE()` | 字符串是否匹配正则表达式 <br>_(注意:仅 MySQL 8.0+)_
`REGEXP_REPLACE()` | 替换匹配正则表达式的子字符串 <br>_注意仅限 MySQL 8.0+_
`REGEXP_SUBSTR() ` | 返回匹配正则表达式的子字符串 <br>_(注意:仅 MySQL 8.0+)_
`REGEXP_SUBSTR()` | 返回匹配正则表达式的子字符串 <br>_(注意:仅 MySQL 8.0+)_
### REGEXP
```sql {.wrap}
```sql
expr REGEXP pat
```
@ -1107,7 +1081,6 @@ mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
1 0
```
### REGEXP_REPLACE
```
@ -1123,7 +1096,6 @@ mysql> SELECT REGEXP_REPLACE('abc ghi', '[a-z]+', 'X', 1, 2);
abc X
```
### REGEXP_SUBSTR
```
@ -1139,8 +1111,7 @@ mysql> SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3);
ghi
```
### REGEXP_LIKE
### REGEXP_LIKE
```
REGEXP_LIKE(expr, pat[, match_type])
@ -1161,10 +1132,9 @@ mysql> SELECT regexp_like('a\nb\nc', '^b$', 'm');
1
```
### REGEXP_INSTR
``` {.wrap}
```
REGEXP_INSTR(expr, pat[, pos[, occurrence[, return_option[, match_type]]]])
```

276
docs/resolutions.md Normal file
View File

@ -0,0 +1,276 @@
Resolutions 备忘清单
===
此备忘清单列出了流行手机、平板电脑、笔记本电脑和手表的屏幕尺寸、可视窗口尺寸和 CSS 媒体查询
入门
------
### 介绍
<!--rehype:style=display:none;&wrap-style=padding-top:0;&wrap-class=col-span-3-->
- 分辨率是像素数(单个颜色点)
- 可视窗口由屏幕上网页填充的矩形大小定义
- 屏幕分辨率是指屏幕上显示的文本和图像的清晰度
- 用于设计
<!--rehype:className=style-round-->
解析度清单列表
------
### 手机
<!--rehype:wrap-class=col-span-3-->
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
| Apple iPhone 11 (2019) | 6.1 <sub>inch</sub> | 828 x 1792 <sub>px</sub> | 414 x 896 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iOS 13.0 |
| Apple iPhone 11 Pro (2019) | 5.8 <sub>inch</sub> | 1125 x 2436 <sub>px</sub> | 375 x 812 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 13.0 |
| Apple iPhone 11 Pro Max (2019) | 6.5 <sub>inch</sub> | 1242 x 2688 <sub>px</sub> | 414 x 896 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 13.0 |
| Apple iPhone 12 (2020) | 6.1 <sub>inch</sub> | 1170 x 2532 <sub>px</sub> | 390 x 844 <sub>px</sub> | 460 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
| Apple iPhone 12 Pro (2020) | 6.1 <sub>inch</sub> | 1170 x 2532 <sub>px</sub> | 390 x 844 <sub>px</sub> | 460 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
| Apple iPhone 12 Pro Max (2020) | 6.7 <sub>inch</sub> | 1284 x 2778 <sub>px</sub> | 428 x 926 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
| Apple iPhone 12 mini (2020) | 5.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 476 <sub>ppi</sub> | 159 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
| Apple iPhone 5 | 4 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 6 |
| Apple iPhone 5c | 4 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 7 |
| Apple iPhone 5s | 4 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 7 |
| Apple iPhone 6 | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 8 |
| Apple iPhone 6s | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9 |
| Apple iPhone 6s Plus | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 414 x 736 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 9 |
| Apple iPhone 7 | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 10.0.1 |
| Apple iPhone 7 Plus | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 414 x 736 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 10.0.1 |
| Apple iPhone 8 | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 11 |
| Apple iPhone 8 Plus | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 414 x 736 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 11 |
| Apple iPhone SE | 4.0 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iOS 9.3.2 |
| Apple iPhone SE (2020) | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iOS 13.0 |
| Apple iPhone X | 5.8 <sub>inch</sub> | 1125 x 2436 <sub>px</sub> | 375 x 812 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 11.1.1 |
| Apple iPhone XR | 6.1 <sub>inch</sub> | 828 x 1792 <sub>px</sub> | 414 x 896 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 12 |
| Apple iPhone XS | 5.8 <sub>inch</sub> | 1125 x 2436 <sub>px</sub> | 375 x 812 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 12 |
| Apple iPhone XS Max | 6.5 <sub>inch</sub> | 1242 x 2688 <sub>px</sub> | 414 x 896 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 12 |
| Google Pixel | 5.0 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 412 x 732 <sub>px</sub> | 441 <sub>ppi</sub> | 168 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 7.1 |
| Google Pixel | 5.0 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 411 x 731 <sub>px</sub> | 441 <sub>ppi</sub> | 168 <sub>ppi</sub> | 2.6 <sub>xxhdpi</sub> | Android 7.1 |
| Google Pixel 2 | 5.0 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 412 x 732 <sub>px</sub> | 441 <sub>ppi</sub> | 168 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 8.0 |
| Google Pixel 2 XL | 6.0 <sub>inch</sub> | 1440 x 2880 <sub>px</sub> | | 538 <sub>ppi</sub> | 154 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 8.0 |
| Google Pixel 3 (2018) | 5.5 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 393 x 786 <sub>px</sub> | 443 <sub>ppi</sub> | 161 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
| Google Pixel 3 XL (2018) | 6.3 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | 412 x 846 <sub>px</sub> | 523 <sub>ppi</sub> | 149 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
| Google Pixel 3a (2019) | 5.6 <sub>inch</sub> | 1080 x 2220 <sub>px</sub> | 393 x 808 <sub>px</sub> | 441 <sub>ppi</sub> | 160 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
| Google Pixel 3a XL (2019) | 6 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 412 x 823 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| Google Pixel 4 (2019) | 5.7 <sub>inch</sub> | 1080 x 2280 <sub>px</sub> | 393 x 830 <sub>px</sub> | 444 <sub>ppi</sub> | 161 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 10.0 |
| Google Pixel 4 XL (2019) | 6.3 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 412 x 869 <sub>px</sub> | 537 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10 |
| Google Pixel 4a (2020) | 5.81 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 443 <sub>ppi</sub> | 161 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 10.0 |
| Google Pixel 5 (2020) | 6 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 432 <sub>ppi</sub> | 157 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 11.0 |
| Google Pixel XL | 5.5 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | | 534 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 7.1 |
| HTC Desire 10 Lifestyle | 5.5 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | 360 x 640 <sub>px</sub> | 267 <sub>ppi</sub> | 134 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 6.0 |
| HTC Desire 628 | 5.0 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | 360 x 640 <sub>px</sub> | 294 <sub>ppi</sub> | 147 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 5.1 |
| Honor 6X (2016) | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 403 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 6.0 |
| Honor 7X (2017) | 5.93 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 360 x 720 <sub>px</sub> | 407 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 7.0 |
| Honor 8X (2018) | 6.5 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 397 <sub>ppi</sub> | 132 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 8.1 |
| Honor 9X (2019) | 6.59 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 391 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 9.0 |
| Huawei Mate 10 Lite (2017) | 5.9 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 360 x 720 <sub>px</sub> | 409 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 7.0 |
| Huawei Mate 20 Lite (2018) | 6.3 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 409 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 8.1 |
| Huawei Mate 20 Pro (2018) | 6.39 <sub>inch</sub> | 1440 x 3120 <sub>px</sub> | 360 x 780 <sub>px</sub> | 538 <sub>ppi</sub> | 135 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 9.0 |
| Huawei Mate 30 (2019) | 6.62 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 389 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 10.0 |
| Huawei Mate 30 Pro (2019) | 6.53 <sub>inch</sub> | 1176 x 2400 <sub>px</sub> | 392 x 800 <sub>px</sub> | 409 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 10.0 |
| Huawei Nova 7i (2020) | 6.4 <sub>inch</sub> | 1080 x 2310 <sub>px</sub> | 360 x 770 <sub>px</sub> | 398 <sub>ppi</sub> | 133 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 10.0 |
| Huawei Y9 Prime (2019) | 6.59 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 391 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 9.0 |
| Huawei Y9s (2019) | 6.59 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 391 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 9.0 |
| LG G5 | 5.3 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 554 <sub>ppi</sub> | 139 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 6.0.1 |
| Motorola Moto E5 Plus | 6.0 <sub>inch</sub> | 720 x 1440 <sub>px</sub> | | 268 <sub>ppi</sub> | 134 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 8.0 |
| OnePlus 6 | 6.28 <sub>inch</sub> | 1080 x 2280 <sub>px</sub> | 412 x 869 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 8.1 |
| OnePlus 6T | 6.41 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| OnePlus 7 | 6.41 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| OnePlus 7 Pro | 6.67 <sub>inch</sub> | 1440 x 3120 <sub>px</sub> | 412 x 892 <sub>px</sub> | 516 <sub>ppi</sub> | 147 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
| OnePlus 7T (2019) | 6.55 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| OnePlus 8 (2020) | 6.55 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 915 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| OnePlus 8 Pro (2020) | 6.78 <sub>inch</sub> | 1440 x 3168 <sub>px</sub> | 412 x 906 <sub>px</sub> | 513 <sub>ppi</sub> | 147 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10.0 |
| OnePlus 8T (2020) | 6.55 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 11.0 |
| OnePlus Nord (2020) | 6.44 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 915 <sub>px</sub> | 408 <sub>ppi</sub> | 155 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Redmi Note 9 Pro (2020) | 6.67 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 393 x 873 <sub>px</sub> | 395 <sub>ppi</sub> | 144 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung A50 (2019) | 6.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 403 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| Samsung Galaxy A30 (2019) | 6.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 403 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| Samsung Galaxy A50s (2019) | 6.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 403 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| Samsung Galaxy A51 (2019) | 6.5 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 405 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung Galaxy A6s | 6.0 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 360 x 720 <sub>px</sub> | 402 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 8.0 |
| Samsung Galaxy A70s (2019) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 393 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| Samsung Galaxy A71 (2020) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 393 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung Galaxy Fold (2019) | 7.3 <sub>inch</sub> | 1536 x 2152 <sub>px</sub> | 768 x 1076 <sub>px</sub> | 362 <sub>ppi</sub> | 181 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 9.0 |
| Samsung Galaxy J4 | 5.5 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | | | 134 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 8.0 |
| Samsung Galaxy J5 | 5.0 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | | 294 <sub>ppi</sub> | | 2 <sub>xhdpi</sub> | Android 5.1 |
| Samsung Galaxy J5 Prime | 5.0 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | | 294 <sub>ppi</sub> | 147 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 6.0.1 |
| Samsung Galaxy J6 | 5.6 <sub>inch</sub> | 720 x 1480 <sub>px</sub> | | 293 <sub>ppi</sub> | 147 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 8.0 |
| Samsung Galaxy J7 | 5.5 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | 360 x 640 <sub>px</sub> | 267 <sub>ppi</sub> | 134 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 6.0.1 |
| Samsung Galaxy J7 Prime | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
| Samsung Galaxy J7 Prime2 (2018) | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 412 x 732 <sub>px</sub> | 401 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 7.0 |
| Samsung Galaxy J7 Pro | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 7.0 |
| Samsung Galaxy J8 | 6.0 <sub>inch</sub> | 720 x 1480 <sub>px</sub> | | 274 <sub>ppi</sub> | 137 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 8.0 |
| Samsung Galaxy Note20 (2020) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 915 <sub>px</sub> | 393 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung Galaxy Note20 Ultra (2020) | 6.9 <sub>inch</sub> | 1440 x 3088 <sub>px</sub> | 412 x 883 <sub>px</sub> | 496 <sub>ppi</sub> | 142 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10.0 |
| Samsung Galaxy Note8 | 6.3 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | | 521 <sub>ppi</sub> | 149 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 7.1.1 |
| Samsung Galaxy On8 | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
| Samsung Galaxy S10 | 6.1 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 360 x 760 <sub>px</sub> | 550 <sub>ppi</sub> | 138 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 9.0 |
| Samsung Galaxy S10 Lite (2020) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 394 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung Galaxy S10+ | 6.4 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 412 x 869 <sub>px</sub> | 522 <sub>ppi</sub> | 149 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
| Samsung Galaxy S20 (2020) | 6.4 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 360 x 800 <sub>px</sub> | 563 <sub>ppi</sub> | 141 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 10.0 |
| Samsung Galaxy S20 FE (2020) | 6.5 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 407 <sub>ppi</sub> | 155 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung Galaxy S20 Ultra (2020) | 6.9 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 412 x 915 <sub>px</sub> | 511 <sub>ppi</sub> | 146 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10.0 |
| Samsung Galaxy S20+ (2020) | 6.7 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 384 x 854 <sub>px</sub> | 525 <sub>ppi</sub> | 140 <sub>ppi</sub> | 3.75 <sub>xxxhdpi</sub> | Android 10.0 |
| Samsung Galaxy S21 Ultra (2021) | 6.8 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 384 x 854 <sub>px</sub> | 515 <sub>ppi</sub> | 137 <sub>ppi</sub> | 3.75 <sub>xxxhdpi</sub> | Android 11.0 |
| Samsung Galaxy S8 | 5.8 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | 360 x 740 <sub>px</sub> | 570 <sub>ppi</sub> | 142 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 7.0 |
| Samsung Galaxy S8+ | 6.2 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | | 529 <sub>ppi</sub> | 132 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 7.0 |
| Samsung Galaxy S9 | 5.8 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | 360 x 740 <sub>px</sub> | 570 <sub>ppi</sub> | 142 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 8.0 |
| Samsung Galaxy S9+ | 6.2 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | | 529 <sub>ppi</sub> | 151 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 8.0 |
| Samsung Galaxy Z Flip (2020) | 6.7 <sub>inch</sub> | 1080 x 2636 <sub>px</sub> | 412 x 1004 <sub>px</sub> | 425 <sub>ppi</sub> | 162 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
| Samsung Galaxy Z Fold2 (2020) | 7.6 <sub>inch</sub> | 1768 x 2208 <sub>px</sub> | 884 x 1104 <sub>px</sub> | 373 <sub>ppi</sub> | 187 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 10.0 |
| Samsung Note10 (2019) | 6.3 <sub>inch</sub> | 1080 x 2280 <sub>px</sub> | 412 x 869 <sub>px</sub> | 401 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
| Samsung Note10+ (2019) | 6.8 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 412 x 869 <sub>px</sub> | 498 <sub>ppi</sub> | 142 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
| Samsung S6 | 5.1 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 577 <sub>ppi</sub> | 144 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 5.0.2 |
| Samsung S6 edge | 5.1 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 577 <sub>ppi</sub> | 144 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 5.0.2 |
| Samsung S7 | 5.1 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 577 <sub>ppi</sub> | 144 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 6.0 |
| Samsung S7 edge | 5.5 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 534 <sub>ppi</sub> | 153 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 6.0 |
| Sony Xperia X | 5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 441 <sub>ppi</sub> | 147 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
| Sony Xperia XZ | 5.2 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 424 <sub>ppi</sub> | 141 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
| Xiaomi Redmi Note 7 (2019) | 6.3 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 409 <sub>ppi</sub> | 149 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
| Xiaomi Redmi Note 8 (2019) | 6.3 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 409 <sub>ppi</sub> | 149 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
| Xiaomi Redmi Note 8 Pro (2019) | 6.53 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 395 <sub>ppi</sub> | 144 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
<!--rehype:className=show-header-->
### 平板
<!--rehype:wrap-class=col-span-3-->
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
| Apple iPad 10.2" (2019) | 10.2 <sub>inch</sub> | 1620 x 2160 <sub>px</sub> | 810 x 1080 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
| Apple iPad 10.2" (2020) | 10.2 <sub>inch</sub> | 1620 x 2160 <sub>px</sub> | 810 x 1080 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 14 |
| Apple iPad Air | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 7 |
| Apple iPad Air 10.5" (2019) | 10.5 <sub>inch</sub> | 1668 x 2224 <sub>px</sub> | 834 x 1112 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
| Apple iPad Air 10.9" (2020) | 10.9 <sub>inch</sub> | 1640 x 2360 <sub>px</sub> | 820 x 1180 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 14 |
| Apple iPad Air 2 | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 8.1 |
| Apple iPad Mini 7.9" (2019) | 7.9 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 324 <sub>ppi</sub> | 162 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
| Apple iPad Pro | 12.9 <sub>inch</sub> | 2048 x 2732 <sub>px</sub> | 1024 x 1366 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9 |
| Apple iPad Pro 10.5 (2017) | 10.5 <sub>inch</sub> | 1668 x 2224 <sub>px</sub> | 834 x 1112 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 11 |
| Apple iPad Pro 11" (2018) | 11 <sub>inch</sub> | 1668 x 2388 <sub>px</sub> | 834 x 1194 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
| Apple iPad Pro 11" (2020) | 11 <sub>inch</sub> | 1668 x 2388 <sub>px</sub> | 834 x 1194 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.4 |
| Apple iPad Pro 12.9" (2018) | 12.9 <sub>inch</sub> | 2048 x 2732 <sub>px</sub> | 1024 x 1366 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
| Apple iPad Pro 12.9" (2020) | 12.9 <sub>inch</sub> | 2048 x 2732 <sub>px</sub> | 1024 x 1366 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.4 |
| Apple iPad Pro 9.7 | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9.3.2 |
| Apple iPad Pro 9.7 (2017) | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 10.3 |
| Apple iPad mini 3 | 7.9 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 324 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9 |
| Apple iPad mini 4 | 7.9 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 324 <sub>ppi</sub> | 162 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 8.1 |
| Google Pixel C (2015) | 10.2 <sub>inch</sub> | 2560x1800 <sub>px</sub> | 1280 x 900 <sub>px</sub> | 308 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 6.0.1 |
<!--rehype:className=show-header-->
### 笔记本电脑
<!--rehype:wrap-class=col-span-3-->
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
| MacBook 2015 12" | 12 <sub>inch</sub> | 2304 x 1440 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook 2016 12" | 12 <sub>inch</sub> | 2304 x 1440 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook 2017 12" | 12 <sub>inch</sub> | 2304 x 1440 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Air 2014 11" | 11.6 <sub>inch</sub> | 1366 x 768 <sub>px</sub> | 1366 x 768 <sub>px</sub> | 135 <sub>ppi</sub> | 135 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | OS X Mavericks |
| MacBook Air 2014 13" | 13.3 <sub>inch</sub> | 1440 x 900 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 128 <sub>ppi</sub> | 128 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | OS X Mavericks |
| MacBook Air 2015 11" | 11.6 <sub>inch</sub> | 1366 x 768 <sub>px</sub> | 1366 x 768 <sub>px</sub> | 135 <sub>ppi</sub> | 135 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | OS X El Capitan |
| MacBook Air 2015 13" | 13.3 <sub>inch</sub> | 1440 x 900 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 128 <sub>ppi</sub> | 128 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | macOS Sierra |
| MacBook Air 2017 13" | 13.3 <sub>inch</sub> | 1440 x 900 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 128 <sub>ppi</sub> | 128 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | macOS Mojave |
| MacBook Air 2018 13" | 13.3 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Mojave |
| MacBook Air 2020 13" | 13.3 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 114 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | macOS Catalina |
| MacBook Pro 13" 2018 | 13.3 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Mojave |
| MacBook Pro 15" 2018 | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Mojave |
| MacBook Pro 16" 2019 | 16 <sub>inch</sub> | 3072 x 1920 <sub>px</sub> | 1536 x 960 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Catalina |
| MacBook Pro 2014 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2014 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2015 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2015 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2016 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2016 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2017 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
| MacBook Pro 2017 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
<!--rehype:className=show-header-->
### 智能手表
<!--rehype:wrap-class=col-span-3-->
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
| Apple Watch SE (40mm) (2020) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
| Apple Watch SE (44mm) (2020) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
| Apple Watch Series 3 (38mm) | 1.5 <sub>inch</sub> | 340 x 272 <sub>px</sub> | 170 x 136 <sub>px</sub> | 290 <sub>ppi</sub> | 145 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 4.0 |
| Apple Watch Series 3 (42mm) | 1.65 <sub>inch</sub> | 390 x 312 <sub>px</sub> | 195 x 156 <sub>px</sub> | 303 <sub>ppi</sub> | 152 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 4.0 |
| Apple Watch Series 4 (40mm) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 5.0 |
| Apple Watch Series 4 (44mm) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 5.0 |
| Apple Watch Series 5 (40mm) (2019) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 6.0 |
| Apple Watch Series 5 (44mm) (2019) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 6.0 |
| Apple Watch Series 6 (40mm) (2020) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
| Apple Watch Series 6 (44mm) (2020) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
| Asus Zenwatch 2 (2015) | 1.63 <sub>inch</sub> | 320 x 320 <sub>px</sub> | 213 x 213 <sub>px</sub> | 278 <sub>ppi</sub> | 185 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | |
| Asus Zenwatch 3 (2016) | 1.39 <sub>inch</sub> | 400 x 400 <sub>px</sub> | 267 x 267 <sub>px</sub> | 287 <sub>ppi</sub> | 191 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 2.1 |
| Asus Zenwatch 3 (2016) | 1.39 <sub>inch</sub> | 400 x 400 <sub>px</sub> | 267 x 267 <sub>px</sub> | 287 <sub>ppi</sub> | 191 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 2.1 |
| Huawei Watch GT (2018) | 1.39 <sub>inch</sub> | 454 x 454 <sub>px</sub> | 227 x 227 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | |
| Huawei Watch Magic (2018) | 1.2 <sub>inch</sub> | 390 x 390 <sub>px</sub> | 195 x 195 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | |
| LG G Watch R (2015) | 1.3 <sub>inch</sub> | 320 x 320 <sub>px</sub> | 213 x 213 <sub>px</sub> | 245 <sub>ppi</sub> | 163 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 1.0 |
| LG Watch Sport (2017) | 1.38 <sub>inch</sub> | 480 x 480 <sub>px</sub> | 240 x 240 <sub>px</sub> | 348 <sub>ppi</sub> | 174 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android Wear 2.0 |
| LG Watch Urbane 2nd Edition (2016) | 1.38 <sub>inch</sub> | 480 x 480 <sub>px</sub> | 240 x 240 <sub>px</sub> | 348 <sub>ppi</sub> | 174 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android Wear 2.0 |
| LG Watch W7 (2018) | 1.2 <sub>inch</sub> | 360 x 360 <sub>px</sub> | 240 x 240 <sub>px</sub> | 300 <sub>ppi</sub> | 200 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 2.0 |
| Samsung Galaxy Watch (2018) | 1.3 <sub>inch</sub> | 360 x 360 <sub>px</sub> | 240 x 240 <sub>px</sub> | 278 <sub>ppi</sub> | 185 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Tizen-based <br/>wearable OS 4.0 |
<!--rehype:className=show-header-->
### 常见的显示分辨率N/A = 不适用)
<!--rehype:wrap-class=col-span-2 row-span-2-->
标准 | 纵横比 | 可视窗口 | 百万像素 | Steam(%) | Stat Counter(%)
:- |:- |:- |:- |:- |:- |
`nHD` | 16:9 | 640 x 360 <sub>px</sub> | 0.230 | N/A | 0.47
`SVGA` | 4:3 | 800 x 600 <sub>px</sub> | 0.480 | N/A | 0.76
`XGA` | 4:3 | 1024 x 768 <sub>px</sub> | 0.786 | 0.38 | 2.78
`WXGA` | 16:9 | 1280 x 720 <sub>px</sub> | 0.922 | 0.36 | 4.82
`WXGA` | 16:10 | 1280 x 800 <sub>px</sub> | 1.024 | 0.61 | 3.08
`SXGA` | 5:4 | 1280 x 1024 <sub>px</sub> | 1.311 | 1.24 | 2.47
`HD` | ≈16:9 | 1360 x 768 <sub>px</sub> | 1.044 | 1.55 | 1.38
`HD` | ≈16:9 | 1366 x 768 <sub>px</sub> | 1.049 | 10.22 | 23.26
`WXGA+` | 16:10 | 1440 x 900 <sub>px</sub> | 1.296 | 3.12 | 6.98
N/A | 16:9 | 1536 x 864 <sub>px</sub> | 1.327 | N/A | 8.5
`HD+` | 16:9 | 1600 x 900 <sub>px</sub> | 1.440 | 2.59 | 4.14
`WSXGA+` | 16:10 | 1680 x 1050 <sub>px</sub> | 1.764 | 1.97 | 2.23
`FHD` | 16:9 | 1920 x 1080 <sub>px</sub> | 2.074 | 64.81 | 20.41
`WUXGA` | 16:10 | 1920 x 1200 <sub>px</sub> | 2.304 | 0.81 | 0.93
`QWXGA` | 16:9 | 2048 x 1152 <sub>px</sub> | 2.359 | N/A | 0.51
`QXGA` | 4:3 | 2048 x 1536 <sub>px</sub> | 3.145 | - | -
`UWFHD` | ≈21:9 | 2560 x 1080 <sub>px</sub> | 2.765 | 1.13 | N/A
`QHD` | 16:9 | 2560 x 1440 <sub>px</sub> | 3.686 | 6.23 | 2.15
`WQXGA` | 16:10 | 2560 x 1600 <sub>px</sub> | 4.096 | &lt;0.58 | &lt;2.4
`UWQHD` | ≈21:9 | 3440 x 1440 <sub>px</sub> | 4.954 | 0.87 | N/A
`4K UHD`| 16:9 | 3840 x 2160 <sub>px</sub> | 8.294 | 2.12 | N/A
`Other` | - | - | - | 2.00 | 15.09
<!--rehype:className=show-header-->
### 屏幕分辨率
解析度 | 像素
:- |:-
`540p / qHD` | 960×540<sub>px</sub>
`720p / HD` | 1280×720<sub>px</sub>
`1080p / Full HD / FHD` | 19201080<sub>px</sub>
`2K` | 2048×1080<sub>px</sub>
`1440p / QHD / QuadHD / WQHD` | 2560×1440<sub>px</sub>
`2160p / UHD` | 3840×2160<sub>px</sub>
`4K` | 4096×2160<sub>px</sub>
`5K` | 5120×2880<sub>px</sub>
`8K / 8K UHD` | 7680×4320<sub>px</sub>
### 显示分辨率和用例
解析度名称 | 设备
:- |:-
`8K` _(8K UHD)_ | `TVs`
`“Cinema” 4K` _(4K)_ | 投影仪
`UHD` _(4K, Ultra HD, Ultra-High Definition)_ | `TVs`, 监视器, 智能手机
`2K` _(none)_ | 投影仪
`WUXGA` _(Widescreen Ultra Extended Graphics Array)_ | 监视器, 投影仪
`1080p` _(Full HD, FHD, HD, High Definition)_ | `TVs`, 监视器, 智能手机
`720p` _(HD, High Definition)_ `TVs`, 智能手机
<!--rehype:className=style-list-arrow-->
另见
---
- [通用解析度列表](https://en.wikipedia.org/wiki/List_of_common_resolutions) _(en.wikipedia.org)_
- [显示屏分辨率](https://en.wikipedia.org/wiki/Display_resolution) _(en.wikipedia.org)_

2452
docs/ruby.md Normal file

File diff suppressed because it is too large Load Diff

1060
docs/rust.md Normal file

File diff suppressed because it is too large Load Diff

619
docs/sass.md Normal file
View File

@ -0,0 +1,619 @@
Sass
===
这是一份快速参考备忘单,列出了 [SASS](https://sass-lang.com) 最有用的功能。
Sass 基础
--------
### 介绍
<!--rehype:wrap-class=row-span-2-->
- [Sass 官方文档](https://sass-lang.com/documentation) _(sass-lang.com)_
- [Sass 中文文档](https://www.sass.hk/docs/) _(sass.hk)_
Sass 是一种 CSS 的预编译语言
```bash
$ npm install -g sass
```
在 Node.js 环境中使用 Sass
```bash
$ sass source/index.scss build/index.css
$ sass --watch input.scss output.css
$ sass --watch app/sass:public/css
```
### 变量
```scss
$defaultLinkColor: #46EAC2;
a {
color: $defaultLinkColor;
}
```
### 字符串插值
```scss
$wk: -webkit-;
.rounded-box {
#{$wk}border-radius: 4px;
}
```
### 注释
```scss
/*
这是多行注释
块注释
块注释
*/
// 这是一条单行注释
```
### Extend
```scss
.button {
···
}
.push-button {
@extend .button;
}
```
### 嵌套(Nesting)
<!--rehype:wrap-class=row-span-2-->
```scss
nav {
ul {
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
}
}
```
编译 css 为:
```scss
nav ul {
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
}
```
### 模块(片段)
<!--rehype:wrap-class=row-span-2-->
```scss
// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
```
注意以下划线开头的 Sass 文件
```scss
// styles.scss
@use 'base';
.inverse {
background-color: base.$primary-color;
color: white;
}
```
编译 css 为:
```css
.inverse {
background-color: #333;
color: white;
}
```
### 混合(Mixins)
```scss
@mixin heading-font {
font-family: sans-serif;
font-weight: bold;
}
h1 {
@include heading-font;
}
```
查看: [混合(Mixins)](#sass-混合mixins)
### @import
```scss
@import './other_sass_file';
@import '/code', 'lists';
// 纯 CSS @imports
@import "theme.css";
@import url(theme);
```
`.sass``.sass` 扩展名是可选的。
Sass 混合(Mixins)
------
### 参数
```scss
@mixin font-size($n) {
font-size: $n * 1.2em;
}
```
----
```scss
body {
@include font-size(2);
}
```
### 默认值
```scss
@mixin pad($n: 10px) {
padding: $n;
}
```
----
```scss
body {
@include pad(15px);
}
```
### 默认变量
```scss
$default-padding: 10px;
@mixin pad($n: $default-padding) {
padding: $n;
}
body {
@include pad(15px);
}
```
Sass 颜色函数
--------
<!--rehype:body-class=cols-2-->
### rgba
```scss
rgb(100, 120, 140)
rgba(100, 120, 140, .5)
rgba($color, .5)
```
### Mixing
```scss
mix($a, $b, 10%) // 10% a, 90% b
```
### 修改 HSLA
```scss
darken($color, 5%)
lighten($color, 5%)
```
```scss
saturate($color, 5%)
desaturate($color, 5%)
grayscale($color)
```
```scss
adjust-hue($color, 15deg)
complement($color) // like adjust-hue(_, 180deg)
invert($color)
```
```scss
fade-in($color, .5) // aka opacify()
fade-out($color, .5) // aka transparentize()
rgba($color, .5) // sets alpha to .5
```
### 获取值
<!--rehype:wrap-class=row-span-2-->
#### HSLA
```scss
hue($color) // 0deg..360deg
saturation($color) // 0%..100%
lightness($color) // 0%..100%
alpha($color) // 0..1 (aka opacity())
```
#### RGB
```scss
red($color) // 0..255
green($color)
blue($color)
```
----
:- | :-
:- | :-
`color.red()` | 用于获取颜色的红色通道
`color.green()` | 用于获得颜色的绿色通道
`color.blue()` | 用于获取颜色的蓝色通道
`color.hue()` | 以获得颜色的色调
`color.saturation()` | 用于获得颜色的饱和度
`color.lightness()` | 以获得颜色的亮度
另见: [hue()](http://sass-lang.com/documentation/Sass/Script/Functions.html#hue-instance_method), [red()](http://sass-lang.com/documentation/Sass/Script/Functions.html#red-instance_method)
### Sass 内置了对颜色值的支持
```scss
@debug rgb(204, 102, 153); // #c69
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
@debug hsl(228, 7%, 86%); // #dadbdf
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)
```
### 调整
```scss
// 固定金额变动
adjust-color($color, $blue: 5)
adjust-color($color, $lightness: -30%) // darken(_, 30%)
adjust-color($color, $alpha: -0.4) // fade-out(_, .4)
adjust-color($color, $hue: 30deg) // adjust-hue(_, 15deg)
// 通过百分比变化
scale-color($color, $lightness: 50%)
// 完全改变一个属性
change-color($color, $hue: 180deg)
change-color($color, $blue: 250)
```
支持的: `$red`, `$green`, `$blue`, `$hue`, `$saturation`, `$lightness`, `$alpha`
Sass 其他函数
--------
### 字符串
<!--rehype:wrap-class=row-span-2-->
```scss
unquote('hello')
quote(bold); // "bold"
```
```scss
to-upper-case(hello)
to-lower-case(hello)
```
----
```scss
str-length(hello world)
// "ello" - 它是从 1 开始的而不是从 0 开始的
str-slice(hello, 2, 5)
str-insert("abcd", "X", 1) // "Xabcd"
```
### Numbers
<!--rehype:wrap-class=row-span-2-->
```scss
floor(4.2) // 4
ceil(4.2) // 5
round(4.2) // 4
abs(-10px) // 10px
```
----
```scss
min(1px, 4px) // 1px
$widths: 50px, 30px, 100px
@debug math.min($widths...) // 30px
```
----
```scss
percentage(.5) // 50%
random(3) // 0..3
```
### Units
```scss
unit(3em) // 'em'
unitless(100px) // false
```
### Units
```scss
unit(3em) // 'em'
unitless(100px) // false
```
### Misc
```scss
// 检查 $red
variable-exists(red)
// 检查@mixin red-text
mixin-exists(red-text)
function-exists(redify)
```
----
```scss
global-variable-exists(red)
```
----
```scss
// .menu li a
selector-append('.menu', 'li', 'a')
// .menu:hover li
selector-nest('.menu', '&:hover li')
selector-extend(...)
selector-parse(...)
selector-replace(...)
selector-unify(...)
```
Sass 功能检查
--------
<!--rehype:body-class=cols-2-->
### 功能检查
```scss
meta.feature-exists($feature)
feature-exists($feature) //=> boolean
```
----
```scss
@mixin debug-content-exists {
@debug meta.content-exists();
@content;
}
@include debug-content-exists; // false
@include debug-content-exists { // true
// Content!
}
```
### 功能
:- | :-
:- | :-
`global-variable-shadowing` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着局部变量将隐藏全局变量,除非它具有 `!global` 标志
`extend-selector-pseudoclass` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着 `@extend` 规则将影响嵌套在伪类中的选择器,如 `:not()`
`units-level-3` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着单位算术支持在 CSS 值和单位级别 3 中定义的单位
`at-error` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着支持 `@error` 规则
`custom-property` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着自定义属性声明值不支持除插值之外的任何表达式
<!--rehype:className=style-list-arrow-->
Sass 循环
--------
### For 循环
```scss
$base-color: #036;
@for $i from 1 through 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
```
编译 css 为:
```css
ul:nth-child(3n + 1) {
background-color: #004080;
}
ul:nth-child(3n + 2) {
background-color: #004d99;
}
ul:nth-child(3n + 3) {
background-color: #0059b3;
}
```
### Each 循环(简单)
```scss
$sizes: 40px, 50px;
@each $size in $sizes {
.icon-#{$size} {
font-size: $size;
height: $size;
}
}
```
编译 css 为:
```css
.icon-40px {
font-size: 40px;
height: 40px;
}
.icon-50px {
font-size: 50px;
height: 50px;
}
```
### Each 循环(嵌套)
```scss
$icons: ("eye": "\f112", "start": "\f12e");
@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
}
}
```
编译 css 为:
```css
.icon-eye:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}
.icon-start:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}
```
### While 循环
<!--rehype:wrap-class=col-span-2-->
```scss
@use "sass:math";
/// 将 `$value` 除以 `$ratio` 直到它低于 `$base`
@function scale-below($value, $base, $ratio: 1.618) {
@while $value > $base {
$value: math.div($value, $ratio);
}
@return $value;
}
$normal-font-size: 16px;
sup {
font-size: scale-below(20px, 16px);
}
```
编译 css 为:
```css
sup {
font-size: 12.36094px;
}
```
Sass 其它功能
--------
### 条件句
<!--rehype:wrap-class=row-span-2-->
```scss
@mixin avatar($size, $circle: false) {
width: $size;
height: $size;
@if $circle {
border-radius: $size / 2;
}
}
.square-av {
@include avatar(100px, $circle: false);
}
.circle-av {
@include avatar(100px, $circle: true);
}
```
编译 css 为:
```css
.square-av {
width: 100px;
height: 100px;
}
.circle-av {
width: 100px;
height: 100px;
border-radius: 50px;
}
```
### 插值
```scss
.#{$klass} { ... } // Class
call($function-name) // Functions
@media #{$tablet}
font: #{$size}/#{$line-height}
url("#{$background}.jpg")
```
### 列表
```scss
$list: (a b c);
nth($list, 1) // starts with 1
length($list)
@each $item in $list { ... }
```
### Maps
<!--rehype:wrap-class=col-span-2-->
```scss
$map: (key1: value1, key2: value2, key3: value3);
map-get($map, key1)
```
另见
----
- [Sass 官方文档](https://sass-lang.com/documentation) _(sass-lang.com)_
- [Sass 中文文档](https://www.sass.hk/docs/) _(sass.hk)_

137
docs/screen.md Normal file
View File

@ -0,0 +1,137 @@
Screen 备忘清单
====
这是 screen 命令的快速参考指南备忘单。
入门
----
### 快速开始
```shell
$ screen
```
---
1\. 按 <kbd>Ctrl-A</kbd> <kbd>D</kbd> 分离会话
---
2\. 列出所有屏幕会话
```shell
$ screen -ls
```
3\. 重新附加屏幕会话
```shell
$ screen -r <name/pid>
```
### 选项
<!--rehype:wrap-class=col-span-2-->
选项 | 示例 | 说明
:-|:-|:-
`-S` | screen -S debug | 使用会话名称启动新会话
`-ls` | screen -ls | 列出正在运行的会话/屏幕
`-x` | screen -x | 附加到正在运行的会话
`-r` | screen -r debug | 使用名称附加到正在运行的会话
`-R` | screen -R debug | 附加到会话 _(如果它不存在将创建)_
`-d` | screen -d -m wget xxxx.com/large.file | 分离模式下的开始屏幕
`-X` | screen -X -S debug kill | 终止正在运行的会话
<!--rehype:className=show-header-->
### 进入
Command | Description
:-|:-
`screen -S <name>` | 使用会话名称开始新的屏幕会话
`screen -ls` | 列出正在运行的会话/屏幕
`screen -x` | 附加到正在运行的会话
`screen -r <name>` | 使用名称附加到正在运行的会话
`screen -dRR` | “终极附加”
### 窗口管理
<!--rehype:wrap-class=col-span-2 row-span-2-->
Command | Description
:-|:-
`Ctrl-A` `C` | 创建新窗口
`Ctrl-A` `Ctrl-A` | 更改为上次访问的活动窗口
`Ctrl-A` `0...9` | 按编号切换到窗口
`Ctrl-A` `'` `<0...9 or title>` | 按编号或名称更改为窗口
`Ctrl-A` `N` or `Ctrl-A` `<space>` | 切换到列表中的下一个窗口
`Ctrl-A` `P` or `Ctrl-A` `<backspace>` | 切换到列表中的上一个窗口
`Ctrl-A` `"` | 查看窗口列表
`Ctrl-A` `W` | 显示窗口栏
`Ctrl-A` `K` | 杀死当前窗口 _(不推荐)_
`Ctrl-A` `\` | 杀死所有窗口 _(不推荐)_
`Ctrl-A` `A` | 重命名当前窗口
<!--rehype:className=shortcuts-->
### 出去
Command | Description
:-|:-
`Ctrl-A` `D` | 分离
`Ctrl-A` `D` `D` | 分离和注销 <br> _(快速退出)_
`Ctrl-A` `:` | 退出所有会话
`Ctrl-A` `C-\` | 强制退出屏幕<br> _(不推荐)_
<!--rehype:className=shortcuts-->
### 帮助
| Command | Description |
|--------------|--------------------------------|
| `Ctrl-A` `?` | 查看帮助 _(列出键绑定)_ |
<!--rehype:className=shortcuts-->
### 杂项
<!--rehype:wrap-class=col-span-2 row-span-2-->
Command | Description
:-|:-
`Ctrl-A` `C-l` | 重绘窗口
`Ctrl-A` `[` | 复制模式
`Ctrl-A` `ESC` | 复制模式
`Ctrl-A` `]` | 粘贴
`Ctrl-A` `M` | 活动监控窗口
`Ctrl-A` `_` | 静音监控窗口
`Ctrl-A` `Ctrl-V` | 输入二合字母 _(非 ASCII 字符)_
`Ctrl-A` `X` | 锁定(密码保护)显示
`Ctrl-A` `:` | 输入屏幕命令
`Ctrl-A` `H` | 在屏幕会话中启用日志记录
<!--rehype:className=shortcuts-->
### 分屏
Command | Description
:-|:-
`Ctrl-A` `S` | 水平分割显示
`Ctrl-A` `V` | 垂直分割显示
`Ctrl-A` `\|` | 垂直拆分显示
`Ctrl-A` `TAB` | 跳转到下一个显示区域
`Ctrl-A` `X` | 删除当前区域
`Ctrl-A` `Q` | 删除除当前区域之外的所有区域
<!--rehype:className=shortcuts-->
### 滚动
Command | Description
:-|:-
`Ctrl-a esc` | 进入滚动模式
`Ctrl-u` | 向上滑动
`Ctrl-d` | 向下滚动
`esc esc` | 退出滚动模式
<!--rehype:className=shortcuts-->
### 屏幕技巧
[SSH](./ssh.md) 并附加在一行中
```shell
$ ssh -t user@host screen -x <name/pid>
```

View File

@ -1,6 +1,8 @@
Sed 备忘清单
====
Sed 是一个流编辑器,此 Sed 备忘清单包含 Sed 命令和一些常见的 Sed 技巧。
入门
----
@ -69,26 +71,26 @@ Sed 命令
### 命令
<!--rehype:wrap-class=col-span-2-->
| Command | Example | Description |
|---------|----------------------------------------|-----------------------------|
| `p` | sed -n '1,4 p' input.txt | Print lines 1-4 |
| `p` | sed -n -e '1,4 p' -e '6,7 p' input.txt | Print lines 1-4 and 6-7 |
| `d` | sed '1,4 d' input.txt | Print lines except 1-4 |
| `w` | sed -n '1,4 w output.txt' input.txt | Write pattern space to file |
| `a` | sed '2 a new-line' input.txt | Append line after |
| `i` | sed '2 i new-line' input.txt | Insert line before |
命令 | 示例 | 描述
:- | :- |:-
`p` | sed -n '1,4 p' input.txt | 打印第 1-4 行
`p` | sed -n -e '1,4 p' -e '6,7 p' input.txt | 打印第 1-4 行和第 6-7
`d` | sed '1,4 d' input.txt | 打印除 1-4 之外的行
`w` | sed -n '1,4 w output.txt' input.txt | 将模式空间写入文件
`a` | sed '2 a new-line' input.txt | 在后面追加一行
`i` | sed '2 i new-line' input.txt | 在前面插入行
<!--rehype:className=show-header-->
### 空间命令
| Command | Description |
|---------|--------------------------------------------------------------|
| `n` | 打印模式空间,空模式空间,读取下一行 |
| `x` | 用保持空间交换模式空间 |
| `h` | 复制模式空间以保持空间 |
| `H` | 追加模式空间以保持空间 |
| `g` | 将保持空间复制到模式空间 |
| `G` | 将保持空间附加到模式空间 |
命令 | 描述
:- | :-
`n` | 打印模式空间,空模式空间,读取下一行
`x` | 用保持空间交换模式空间
`h` | 复制模式空间以保持空间
`H` | 追加模式空间以保持空间
`g` | 将保持空间复制到模式空间
`G` | 将保持空间附加到模式空间
### Flags
@ -97,7 +99,7 @@ $ sed 's/old/new/[flags]' [input-file]
```
---
| Flag | Description |
|----------|--------------------------------------------|
| `g` | 全球替代 |
@ -107,7 +109,6 @@ $ sed 's/old/new/[flags]' [input-file]
| `I` | 搜索时忽略大小写 |
| `e` | 在命令行中替换并执行 |
### 循环命令
| Command | Description |

View File

@ -54,7 +54,6 @@ Semver 备忘清单
<!--rehype:className=shortcuts-->
### 连字符范围
<!--rehype:wrap-class=row-span-3-->
| 范围 | 描述 |
| --- | --- |
@ -76,9 +75,46 @@ Semver 备忘清单
| `1.2 - 2.3.0` | 是 `1.2.0 - 2.3.0` |
<!--rehype:className=shortcuts-->
当右侧为部分(例如,`2.3`)时,假定缺失的部分为`x`(例如,` 2.3.x`)。
当右侧为部分(例如,`2.3`)时,假定缺失的部分为`x`(例如,`2.3.x`)。
如果左边是部分的(例如,`1.2`),则假定缺少的部分为`0`(例如,` 1.2.0`)。
如果左边是部分的(例如,`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,9 +135,15 @@ Semver 备忘清单
| `1.x.x` | 表示定义了公共 API |
<!--rehype:className=shortcuts-->
### 预发布
```
1.2.3-prerelease+build
1.1.2-prerelease+meta
```
另见
----
- [语义化版本号验证正则表达式,支持按编号提取的语言](https://regex101.com/r/vkijKf/1/)
- [语义化版本号验证正则表达式,支持按组名称提取的语言](https://regex101.com/r/Ly7O1x/3/)
- [语义化版本号验证正则表达式,支持按组名称提取的语言](https://regex101.com/r/Ly7O1x/3/)

View File

@ -22,7 +22,6 @@ Sketch 备忘清单
| `t` | (Text) 文本 |
<!--rehype:className=shortcuts-->
### 类型
<!--rehype:wrap-class=row-span-2-->
@ -131,8 +130,7 @@ Sketch 备忘清单
| `Fn + ↓` | 选择下面的页面 |
<!--rehype:className=shortcuts-->
另见
----
- [Sketch 官网](https://www.sketch.com/) _(sketch.com)_
- [Sketch 官网](https://www.sketch.com/) _(sketch.com)_

View File

@ -99,7 +99,6 @@ $ scp user@server:/dir/* .
`~/.ssh/known_hosts` | 登录主机
`~/.ssh/authorized_keys` | 授权登录密钥
### SCP 选项
选项 | 说明
@ -111,7 +110,6 @@ scp `-P` 8080 | 使用特定端口
scp `-B` | 批处理模式_防止密码_
scp `-p` | 保留时间和模式
### 配置示例
```toml
@ -148,7 +146,6 @@ $ ssh -J user@proxy_host1:port1,user@proxy_host2:port2 user@remote_host3
```
<!--rehype:className=wrap-text -->
### ssh-copy-id
```shell
@ -229,7 +226,6 @@ $ ssh-keygen -p -f ~/.ssh/id_rsa
- dsa
- ecdsa
### known_hosts
<!--rehype:wrap-class=col-span-2-->
@ -247,11 +243,11 @@ $ ssh-keygen -R <ip/hostname>
### 密钥格式
- PEM
- PEM
- PKCS8
另见
--------
- [OpenSSH 配置文件示例](https://www.cyberciti.biz/faq/create-ssh-config-file-on-linux-unix/) _(cyberciti.biz)_
- [ssh_config](https://linux.die.net/man/5/ssh_config) _(linux.die.net)_
- [ssh_config](https://linux.die.net/man/5/ssh_config) _(linux.die.net)_

1109
docs/styled-components.md Normal file

File diff suppressed because it is too large Load Diff

559
docs/stylus.md Normal file
View File

@ -0,0 +1,559 @@
Stylus 备忘清单
===
本备忘单旨在快速理解 [stylus](https://github.com/stylus/stylus) 所涉及的主要概念,显示了它的常用方法使用清单。
入门
---
### 介绍
<!--rehype:wrap-class=row-span-2-->
为 Node.js 构建的富有表现力、健壮、功能丰富的 [CSS](./css.md) 语言
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
- [在线编译预览](https://stylus-lang.com/try.html) _(stylus-lang.com)_
```bash
# npm
$ npm install stylus -g
# pnpm
$ pnpm add -g stylus
```
在 Node.js 环境中使用 `stylus`
```bash
$ stylus one.styl two.styl
# stylus 从标准输入读取并输出到标准输出
$ stylus --compress < some.styl > some.css
# 将 css 目录中的文件编译输出到 `public/css`
$ stylus css --out public/css
```
转换 CSS输出 `*.styl` 文件
```
$ stylus --css < test.css > test.styl
$ stylus --css test.css /tmp/out.styl
```
### 支持 CSS 嵌套语法
```stylus
.box {
color: blue;
.button {
color: red;
}
}
```
Stylus 是一个 CSS 预处理器。另见: [stylus-lang.com](http://stylus-lang.com/)
### 支持类 python 缩进语法
```stylus
.box
color: blue
.button
color: red
```
也有效!冒号也是可选的。这通常用于 Stylus 文档的语法
### 混合 Mixins
```stylus
caps-type()
letter-spacing: 0.05em
```
----
```stylus {2}
h5
caps-type()
```
编译 css 为:
```css
h5 {
letter-spacing: 0.05em;
}
```
<!-- markdownlint-disable MD051 -->
另见:下面[Mixins](#混合-Mixins)
### 变量 Variables
```stylus
royal-blue = #36a
```
----
```stylus
div
color: royal-blue
```
标识符(变量名、函数等)也可以包括 `$` 字符
```stylus
$font-size = 14px
body {
font: $font-size sans-serif;
}
```
另见:[变量 Variables](https://stylus-lang.com/docs/variables.html)
混合 Mixins
------
### 没有参数
```stylus {1}
red-border()
border: solid 2px red
```
----
```stylus {2}
div
red-border()
```
另见: [Mixins](http://stylus-lang.com/docs/mixins.html)
### 有参数
```stylus {1}
border-radius(n)
-webkit-border-radius: n
border-radius: n
```
----
```stylus {2,3}
div
border-radius: 2px
border-radius(2px)
```
Mixins can be applied in two different ways.
### 参数默认值
```stylus {1}
border-radius(n = 2px)
-webkit-border-radius: n
```
### 块混合
```stylus {3}
mobile()
@media (max-width: 480px)
{block}
```
----
```stylus {1}
+mobile()
width: 10px
```
另见: [块混合](http://stylus-lang.com/docs/mixins.html#block-mixins)
### Rest 参数
```stylus {1}
shadow(offset-x, args...)
box-shadow: offset-x args
margin-top: offset-x
```
----
```stylus
#login
shadow: 1px 2px 5px #eee
```
另见: [Rest 参数](http://stylus-lang.com/docs/vargs.html)
函数 Functions
---------
### 函数 Functions
```stylus {1}
add(a, b)
a + b
```
----
```stylus {2}
body
padding: add(10px, 5)
```
另见: [Functions](http://stylus-lang.com/docs/functions.html)
### 参数默认值
```stylus {1}
add(a, b = 2)
a + b
```
另见: [参数默认值](http://stylus-lang.com/docs/functions.html#argument-defaults)
### 命名参数
```stylus
shadow(x, y)
x y (y * 1.5) #000
```
----
```stylus {2}
.button
box-shadow: shadow(x: 2, y: 4)
```
另见: [命名参数](http://stylus-lang.com/docs/functions.html#named-parameters)
### 多个返回值
```stylus {2}
sizes()
8px 16px
```
----
```stylus
sizes()[0] // → 8px
sizes()[1] // → 16px
```
另见: [多个返回值](http://stylus-lang.com/docs/functions.html#multiple-return-values)
### arguments
```stylus
sum()
n = 0
for num in arguments
n = n + num
```
----
```stylus
sum(1,2,3,4,5) // => 15
```
参数 local 可用于所有函数体,并包含所有传递的参数
### hash 示例
```stylus
get(hash, key)
return pair[1] if pair[0] == key for pair in hash
hash = (one 1) (two 2) (three 3)
get(hash, two)
// => 2
```
<!--rehype:className=wrap-text -->
值 Values
------
### 条件赋值
```stylus {2}
royal-blue = #36a
royal-blue ?= #89f
```
----
```stylus
div
color: royal-blue // #36a
```
`?=` 只会在之前未设置的情况下设置变量
另见: [条件赋值](https://stylus-lang.com/docs/operators.html#conditional-assignment--)
### 属性查找
```stylus {2,3}
.logo
width: w = 150
margin-left: -(w / 2)
// or
height: 80px
margin-top: -(@height / 2)
```
另见: [属性查找](https://stylus-lang.com/docs/variables.html#property-lookup)
### 插值
```stylus
-{prefix}-border-radius: 2px
```
另见: [Interpolation](https://stylus-lang.com/docs/interpolation.html)
### Color operators
```stylus
#888 + 50% // → #c3c3c3 (lighten)
#888 - 50% // → #444 (darken)
#f00 + 50deg // → #ffd500 (hue)
```
### Casting
```stylus
n = 5px
```
----
```stylus {1,2}
foo: (n)em
foo: (n * 5)%
```
### Lookup
```stylus {3}
light-blue = #3bd
name = 'blue'
lookup('light-' + name)
```
另见: [lookup](https://stylus-lang.com/docs/bifs.html#lookupname)
高级功能
-----------------
### 有条件的
<!--rehype:wrap-class=row-span-2-->
```stylus
if color == blue
display: block
else if true and true
display: inline
else if 'hey' is not 'bye'
display: flex
else
display: none
```
别名:
:- | :-
:- | :-
| `==` | `is` |
| `!=` | `is not` |
| `!=` | `isnt` |
另见: [Conditionals](https://stylus-lang.com/docs/functions.html#conditionals)
### 对于循环
```stylus {5}
font-size-1 = 10px
font-size-2 = 20px
font-size-3 = 30px
for i in 1..3
.text-{i}
font-size: lookup('font-size-' + i)
```
### 定义检查
```stylus {1}
if ohnoes is defined
color: blue
```
另见: [is defined](https://stylus-lang.com/docs/operators.html#variable-definition-is-defined)
### False 值
```stylus
0
null
false
''
```
### 类型检查
```stylus
if val is a 'string'
if val is a 'ident'
if #fff is a 'rgba' // → true
```
另见: [Instance check](https://stylus-lang.com/docs/operators.html#instance-check-is-a)
内置函数
------------------
### 颜色函数
<!--rehype:wrap-class=row-span-4-->
```stylus
alpha(#fff) //→ 1
alpha(rgba(0, 0, 0, 0.2)) //→ 0.2
```
----
```stylus
dark(black) //→ true
light(black) //→ false
```
----
```stylus
hue(#0a0) //→ 50deg
saturation(#f00) //→ 100%
lightness(#f00) //→ 50%
luminosity(#f00) //→ 0.2126
```
----
```stylus
hue(#0a0, 0deg)
saturation(#f00, 50%)
lightness(#f00)
```
----
```stylus
lighten(color, 10%)
darken(color, 10%)
saturate(color, 10%)
desaturate(color, 10%)
invert(color)
```
----
```stylus
tint(color, 50%) // mix with white
shade(color, 50%) // mix with black
```
----
```stylus
unquote(string)
```
另见: [Built-in functions](http://stylus-lang.com/docs/bifs.html)
### 图片尺寸
返回给定图像的宽度和高度
```stylus
width: image-size('tux.png')[0]
height: image-size('tux.png')[1]
```
另见: [image-size](http://stylus-lang.com/docs/bifs.html#image-sizepath)
### 缓存 Caching
<!--rehype:wrap-class=row-span-2-->
```stylus
size($width)
+cache('w' + $width)
width: $width
.a { size: 10px }
.b { size: 10px }
```
----
```stylus
// 输出: .a, b { width: 10px }
```
在第一次调用时将其内容应用于给定的选择器,但会在第二次调用时使用相同的参数 `@extend` 第一次调用的选择器。另见: [cache](http://stylus-lang.com/docs/bifs.html#cachekeys)
### Embed URL
```
background: embedurl('logo.png')
// → background: url("data:image/png;base64,…")
```
<!--rehype:className=wrap-text -->
另见: [embedurl](http://stylus-lang.com/docs/bifs.html#embedurlpath-encoding)
### 添加属性
```stylus
gradient(color)
add-property('background-image', linear-gradient(top, color, darken(color, 20%)))
color
```
----
```stylus
body
background: gradient(red)
```
另见: [add-property](http://stylus-lang.com/docs/bifs.html#add-propertyname-expr)
### sprintf
```stylus
'-webkit-gradient(%s, %s, %s)' % (linear (0 0) (0 100%))
// → -webkit-gradient(linear, 0 0, 0 100%)
```
<!--rehype:className=wrap-text -->
----
```stylus
s("rgba(0, 0, 0, %s)", 0.3)
```
另见: [s](http://stylus-lang.com/docs/bifs.html#sfmt-)
另见
---
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
- [在线编译预览](https://stylus-lang.com/try.html) _(stylus-lang.com)_
- [Less.js 备忘清单](./lessjs.md) _(jaywcjlove.github.io)_

150
docs/sublime-text.md Normal file
View File

@ -0,0 +1,150 @@
Sublime Text 备忘清单
===
这个 [Sublime Text](https://www.sublimetext.com/) 快速参考备忘单显示了它的键盘快捷键和命令。
## 快捷键
### 文本编辑初学者
<!--rehype:wrap-class=row-span-3-->
[Sublime Text](https://www.sublimetext.com/) 是一个用于代码、标记的复杂文本编辑器。
快捷键 | 说明
:- | -
`⌘ D` | 选择单词(重复包括单词的下一个实例)
`⌘ L` | 选择行(重复以包括下一行)
`⌘ ⇧ L` | 将选择拆分为多行(多行编辑)
`⌘ ⇧ A` | 选择标签内的文本(重复以展开)
`⌃ ⇧ M` | 选择大括号或尖括号(重复展开)
`⌘ X` | 剪切一行
`⌃ M` | 转到匹配的括号
`⌃ ↩︎` or `↩︎` | 在后面插入行
`⌘ ↵` | 在后面插入行
`⇧ ⌘ ↵` | 在前面插入行
`⇧ ⌥ ▲` | 选择当前行光标之前
`⇧ ⌥ ▼` | 选择当前行光标之后
`⇧ ⌃ M` | 选择当前括号的所有内容
`⌥ ⇠/⇢` | 进行逐词移动,相应的
`⌥ ⇧ ⇠/⇢` | 进行逐词选择
`⌘ U` | 返回到历史光标位置(撤销)
`⌃ M` | 快速的在起始括号和结尾括号间切换
`⌃ ⇧ M` | 则可以快速选择括号间的内容
`⌃ ⇧ J` | 对于缩进型语言(例如Python)可以使用
`⌃ ⌘ D` | 复制整行
<!--rehype:className=shortcuts-->
查看:[Sublime Text](https://www.sublimetext.com/) 官网
### 代码折叠
快捷键 | 说明
:- | -
`⌘ Alt [` | 折叠最近的块
`⌘ Alt ]` | 展开最近的块
`⌘ K ⌘ 1` | 折叠所有第一级代码块
`⌘ K ⌘ 2` | 折叠所有二级代码块
`⌘ K ⌘ 3` | 折叠所有第三级代码块(等)
`⌘ K ⌘ T` | 折叠所有 HTML 属性
`⌘ K ⌘ 0` | 展开一切
`⌘ K 0` | 代码展开
<!--rehype:className=shortcuts-->
### macOS 键盘符号
快捷键 | 说明
:- | -
`⌘` | Command()
`⌃` | Control
`⌥` | Option(alt)
`⇧` | Shift
`⇪` | Caps Lock(大写)
`fn` | 功能键就是fn
`↩︎` | return/Enter
<!--rehype:className=shortcuts-->
### 编辑
快捷键 | 说明
:- | -
`⌘ ⇧ D` | 复制当前行/选择
`⌘ ⇧ K` | 删除当前行/选择
`⇧ del` | 删除当前行/选择
`⌘ ⇧ ▲` | 移动队列
`⌘ ⇧ ▼` | 下移一行
`⌘ ▼/▲`| 移动到首行/尾行
<!--rehype:className=shortcuts-->
### 转到
快捷键 | 说明
:- | -
`⌘ P` | 去任何地方
`⌘ G` | 转到行号
`⌘ R` | 转到符号
`⌘ P, :` | 转到行号(`:`之后输入数字)
`⌘ P, #` | 转到并列出字符串模糊匹配(`#`之后输入字符)
`⌘ P, @` | 转到并列出符号(`@`之后开始输入符号名称)
<!--rehype:className=shortcuts-->
### 选择(Selecting)
- `⌘ + D`
选择光标所在的单词,并高亮该词出现的所有位置
- `⌘ + D`
择该词出现的下一个位置
- `⌘ + U` 进行回退使用Esc退
<!--rehype:className=style-timeline shortcuts-->
----
快捷键 | 说明
:- | -
`⌃ K` / `⌘ K K` | 从光标处删除到行末尾
<!--rehype:className=shortcuts-->
### 拆分窗口
快捷键 | 说明
:- | -
`⇧ ⌥ 2` | 将视图拆分为两列
`⇧ ⌥ 1` | 将视图还原为单列
`⇧ ⌥ 5` | 将视图设置为网格4 组)
`⌃ 2` | 跳到第 2 组
`⇧ ⌃ 2` | 将文件移动到组 2
<!--rehype:className=shortcuts-->
### 文本操作
快捷键 | 说明
:- | -
`⌃ K ⌃ L` | 转换为小写
`⌃ K ⌃ U` | 转换为大写
`⇧ ⌃ K` | 删除行
`⌃BACKSPACE` | 向后删除单词
`⌃DEL` | 删除单词转发
<!--rehype:className=shortcuts-->
### 命令行中启动编辑器
<!--rehype:wrap-class=col-span-2-->
```bash
sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl\
/usr/local/bin/subl
```
<!--rehype:className=wrap-text -->
#### 在命令行中使用 **subl** 命令
```bash
$ subl .
$ subl README.md
```
软链放到这个目录 `/usr/local/bin/subl`,这是因为 `Rootless` 机制,不能存放到 ~~`/usr/bin/subl`~~ 位置。
另见
----
- [Sublime Text 官网](https://www.sublimetext.com/) _(sublimetext.com)_
- [Sublime 编辑器快捷键](https://jaywcjlove.github.io/handbook/Shortcuts/sublime.html) _(jaywcjlove.github.io)_

1538
docs/swift.md Normal file

File diff suppressed because it is too large Load Diff

1207
docs/swiftui.md Normal file

File diff suppressed because it is too large Load Diff

110
docs/systemd.md Normal file
View File

@ -0,0 +1,110 @@
Systemd
===
最常用的 [Systemd](https://systemd.io/) 命令备忘单快速参考
命令
----
### 查看系统信息
:- | -
:- | -
`systemctl list-dependencies` | 显示单元的依赖关系
`systemctl list-sockets` | 列出套接字和激活的内容
`systemctl list-jobs` | 查看活动的 systemd 作业
`systemctl list-unit-files` | 查看单元文件及其状态
`systemctl list-units` | 显示单位是否已加载/活动
`systemctl get-default` | 列出默认目标(如运行级别)
<!--rehype:className=style-list-->
### 改变系统状态
:- | -
:- | -
`systemctl reboot` | 重启系统(reboot.target)
`systemctl poweroff` | 关闭系统(poweroff.target)
`systemctl emergency` | 进入紧急模式(emergency.target)
`systemctl default` | 返回默认目标(multi-user.target)
<!--rehype:className=style-list-->
### 使用服务
<!--rehype:wrap-class=row-span-2-->
:- | -
:- | -
`systemctl stop service` | <red>停止</red>正在运行的服务
`systemctl start service` | 启动服务
`systemctl restart service` | 重新启动正在运行的服务
`systemctl reload service` | 重新加载服务中的所有配置文件
`systemctl daemon-reload` | 必须运行以重新加载更改的单元文件
`systemctl status` | service 查看服务是否正在运行/启用
`systemctl --failed` | 显示未能运行的服务
`systemctl reset-failed` | 将任何单位从失败状态重置
`systemctl enable service` | 使服务在启动时启动
`systemctl disable service` | 禁用服务 - 不会在启动时启动
`systemctl show service` | 显示服务(或其他单元)的属性
`systemctl edit service` | 创建片段以放入单元文件
`systemctl edit --full service` | 编辑整个单元文件以进行服务
`systemctl -H host status network` | 远程运行任何 systemctl 命令
<!--rehype:className=style-list-->
### 查看日志消息
<!--rehype:wrap-class=col-span-2-->
:- | -
:- | -
`journalctl` | 显示所有收集的日志消息
`journalctl -u network.service` | 查看网络服务消息
`journalctl -f` | 关注出现的消息
`journalctl -k` | 仅显示内核消息
### SysVinit 到 Systemd
<!--rehype:wrap-class=col-span-3-->
SysVinit | Systemd | 说明
:- | - | -
`service SERVICE_NAME start` | `systemctl start SERVICE_NAME` | 用于启动服务(不重启持久)
`service SERVICE_NAME stop` | `systemctl stop SERVICE_NAME` | 用于停止服务(不永久重启)
`service SERVICE_NAME restart` | `systemctl restart SERVICE_NAME` | 用于停止然后启动服务
`service SERVICE_NAME reload` | `systemctl reload SERVICE_NAME` | 重新加载配置文件而不中断挂起的操作
`service SERVICE_NAME condrestart` | `systemctl condrestart SERVICE_NAME` | 如果服务已在运行,则重新启动
`service SERVICE_NAME status` | `systemctl status SERVICE_NAME` | 判断服务当前是否正在运行
`chkconfig SERVICE_NAME on` | `systemctl enable SERVICE_NAME` | 打开服务,以便在下次启动时启动,或其他触发器
`chkconfig SERVICE_NAME off` | `systemctl disable SERVICE_NAME` | 为下次重新启动或任何其他触发器关闭服务
`chkconfig SERVICE_NAME` | `systemctl is-enabled SERVICE_NAME` | 用于检查服务是否配置为在当前环境中启动
`chkconfig list` | `systemctl list-unit-files type=service` (or) <br/>`ls /etc/systemd/system/*.wants/` | 打印一个服务表,列出每个配置的运行级别打开或关闭
`chkconfig list \| grep 5:on` | `systemctl list-dependencies graphical.target` | 打印启动到图形模式时将启动的服务表
`chkconfig SERVICE_NAME list` | `ls /etc/systemd/system/*.wants/SERVICE_NAME.service` | 用于列出此服务配置为打开或关闭的级别
`chkconfig SERVICE_NAME add` | `systemctl daemon-reload` | 在创建新服务文件或修改任何配置时使用
<!--rehype:className=show-header-->
### 目标运行级别
<!--rehype:wrap-class=col-span-3-->
SysVinit | Systemd | 说明
:- | - | -
`0` | `runlevel0.target`, `poweroff.target` | 停止系统
`1`, `s`, `single` | `runlevel1.target`, `rescue.target` | 单用户模式
`2`, `4` | `runlevel2.target`, `runlevel4.target`, `multi-user.target` | 用户定义/站点特定的运行级别。 默认情况下,与 3 相同
`3` | `runlevel3.target`, `multi-user.target` | 多用户,非图形。 用户通常可以通过多个控制台或通过网络登录
`5` | `runlevel5.target`, `graphical.target` | 多用户,图形。 通常具有运行级别 3 的所有服务以及图形登录
`6` | `runlevel6.target`, `reboot.target` | 重启
`emergency` | `emergency.target` | 应急外壳
<!--rehype:className=show-header-->
### 更改运行级别
<!--rehype:wrap-class=col-span-3-->
SysVinit | Systemd | 说明
:- | - | -
`telinit 3` | `systemctl isolate multi-user.target` <br/>OR `systemctl isolate runlevel3.target`<br/>OR `telinit 3` | 更改为多用户运行级别
`sed s/^id:.*:initdefault:/id:3:initdefault:/` | `ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target` | 设置为在下次重新启动时使用多用户运行级别
<!--rehype:className=show-header-->
另见
---
- [Systemd 官网](https://systemd.io/) _(systemd.io)_
- [Systemd Cheat Sheet](https://access.redhat.com/sites/default/files/attachments/12052018_systemd_6.pdf) _(access.redhat.com)_
- [Systemd Cheat Sheet](https://www.linuxtrainingacademy.com/systemd-cheat-sheet/) _(linuxtrainingacademy.com)_

243
docs/tmux.md Normal file
View File

@ -0,0 +1,243 @@
Tmux 备忘清单
===
最常用的快捷键和命令的 tmux 备忘单快速参考
Tmux CLI
-------
### 新会话
<!--rehype:wrap-class=row-span-2-->
开始一个新的会话
```bash
$ tmux
$ tmux new
$ tmux new-session
:new
```
开始一个名为 myname 的新会话
```bash
$ tmux new -s myname
:new -s myname
```
显示所有会话,或者 <kbd>Ctrl</kbd> + <kbd>b</kbd> + <kbd>s</kbd> 快捷键
```bash
$ tmux ls
$ tmux list-sessions
```
### 附加会话
<!--rehype:wrap-class=row-span-2-->
附加到上一个会话
```bash
$ tmux a
$ tmux at
$ tmux attach
$ tmux attach-session
```
附加到命名
```bash
$ tmux a -t myname
```
附加到名为 myname 的会话
```bash
$ tmux a -t myname
$ tmux at -t myname
$ tmux attach -t myname
$ tmux attach-session -t myname
```
### 终止会话
按名称终止会话
```bash
$ tmux kill-ses -t myname # 杀死/删除会话
$ tmux kill-session -t myname
```
杀死/删除除当前会话之外的所有会话
```bash
$ tmux kill-ses -a
```
杀死/删除除 myname 之外的所有会话
```bash
$ tmux kill-ses -a -t myname
```
### Tmux 帮助
```bash
$ tmux info
```
### 配置
重新加载配置
```bash
$ tmux source-file ~/.tmu­x.conf
```
显示配置
```bash
$ tmux show-options -g
```
### 复制模式
命令 | 描述
:- | -
`Ctrl+b` `[` | 进入复制模式
`<Space>` | 开始选择
`Enter` | 复制选择
`q` | 退出复制模式
`Ctrl+b` `]` | 粘贴 buffer_0 的内容
<!--rehype:className=shortcuts-->
主要作用类似于在 [Vim](./vim.md#动作) 中选择文本
Tmux 快捷键
----------
### 入门
<!--rehype:style=background:rgb(245 158 11/1);-->
快捷键/命令 | 描述
:- | -
| `Ctrl+b` `?` | List all shortcuts |
<!--rehype:className=shortcuts show-header-->
----
显示每个会话、窗口、窗格等
```bash
$ tmux info
```
### 窗格(拆分)
<!--rehype:wrap-class=row-span-2-->
快捷键/命令 | 描述
:- | -
`Ctrl+b` `"` _/_ `%` | 水平分割/垂直
`Ctrl+b` `!` | 窗格 -> 窗口
`Ctrl+b` `x` | 杀死窗格
`Ctrl+b` \<Arrow> | 导航窗格
`Ctrl+b` \<Space> | 切换布局
`Ctrl+b` `{` _/_ `}` | 向左/向右移动
`Ctrl+b` `o` | 转到下一个窗格
`Ctrl+b` `z` | 切换全屏
`Ctrl+b` `;` | 切换最后一个窗格
`Ctrl+b` `q` | 显示号码
`Ctrl+b` `q` `0`...`9` | 转到 # 窗格
<!--rehype:className=shortcuts-->
### Window (Tabs)
<!--rehype:wrap-class=row-span-2-->
快捷键/命令 | 描述
:- | -
`Ctrl+b` `c` | 创建窗口
`Ctrl+b` `p` _/_ `n` | 上一个/下一个窗口
`Ctrl+b` `"` _/_ `%` | 水平分割/垂直
`Ctrl+b` `w` | 列表窗口
`Ctrl+b` `,` | 重命名窗口
`Ctrl+b` `f` | 查找窗口
`Ctrl+b` `l` | 最后一个窗口
`Ctrl+b` `.` | 移动窗口
`Ctrl+b` `&` | 关闭窗口
`Ctrl+b` `0`...`9` | 转到#窗口
<!--rehype:className=shortcuts-->
### 会话Windows 组)
快捷键/命令 | 描述
:- | -
`Ctrl+b` `d` | <red>从会话中分离</red>
`Ctrl+b` `s` | 显示所有会话
`Ctrl+b` `$` | 重命名会话
`Ctrl+b` `(` _/_ `)` | 上一届/下一届
<!--rehype:className=shortcuts-->
Tmux 命令模式
-----------
### 用法
<!--rehype:style=background:rgb(245 158 11/1);-->
快捷键/命令 | 描述
:- | -
`Ctrl+b` `:` | 进入命令模式
<!--rehype:className=shortcuts-->
### 调整大小
快捷键/命令 | 描述
:- | -
`resize-pane -D 20` | 缩小尺寸
`resize-pane -U 20` | 调整大小
`resize-pane -L 20` | 向左调整大小
`resize-pane -R 20` | 向右调整大小
### 清单
快捷键/命令 | 描述
:- | -
`list-keys` | 所有命令
`list-panes` | 所有窗格
`list-windows` | 所有窗口
### 复印
快捷键/命令 | 描述
:- | -
`list-buffers` | 列出所有缓冲区
`show-buffer` | 显示 #0 内容
`capture-pane` | 窗格的副本
`choose-buffer` | 显示和粘贴
`save-buffer a.txt` | 保存到文件
`delete-buffer -b 1` | 删除缓冲区 1
### 环境
快捷键/命令 | 描述
:- | -
`set -g OPTION` | 为所有会话设置
`setw -g OPTION` | 为所有窗口设置
`setw -g mode-keys vi` | 启用 vi 模式
`set -g prefix C-a` | 设置前缀
### 杂项
快捷键/命令 | 描述
:- | -
`swap-pane -s 3 -t 1` | 交换窗格
`swap-window -t -1` | 向左移动
`setw synchronize-panes` | 同步窗格
`join-pane -t :#` | 加入窗格
另见
---
- [Tmux 开源仓库](https://github.com/tmux/tmux) _(github.com)_
- [Tmux Cheat Sheet & Quick Reference](https://tmuxcheatsheet.com/) _(tmuxcheatsheet.com)_

View File

@ -12,6 +12,7 @@ TOML 备忘清单
- [Document](https://toml.io/en/latest) _(toml.io)_
- [Learn X in Y minutes](https://learnxinyminutes.com/docs/toml/) _(learnxinyminutes.com)_
- [Better TOML VSCode 插件](https://marketplace.visualstudio.com/items?itemName=bungcip.better-toml) _(visualstudio.com)_
### 示例
@ -43,7 +44,6 @@ int3 = -21
integerRange = 64
```
### 浮点数
```toml
@ -79,7 +79,7 @@ str2 = "You can \"quote\" me."
str3 = "Name\tJos\u00E9\nLoc\tSF."
```
See: [Strings](#toml-strings)
See: [Strings](#字符串)
### Table
@ -164,9 +164,9 @@ bar = 2
```toml
[table1]
foo = "bar"
foo = "bar"
[table1.nested_table]
baz = "bat"
baz = "bat"
```
### 类数组
@ -185,16 +185,16 @@ text = "Love it!"
```json
{
"comments" : [
{
"author" : "Nate",
"text" : "Great Article!"
},
{
"author" : "Anonymous",
"text" : "Love It!"
}
]
"comments" : [
{
"author" : "Nate",
"text" : "Great Article!"
},
{
"author" : "Anonymous",
"text" : "Love It!"
}
]
}
```
@ -223,17 +223,18 @@ type = "pug"
[foo.bar.baz]
bat = "hi"
```
#### ↓ 等效的 JSON
```json
{
"foo" : {
"bar" : {
"baz" : {
"bat" : "hi"
}
}
}
"foo" : {
"bar" : {
"baz" : {
"bat" : "hi"
}
}
}
}
```
@ -246,11 +247,21 @@ bat = "hi"
[ j . "ʞ" .'l' ] # same as [j."ʞ".'l']
```
### Inline Table
### 内联表
<!--rehype:wrap-class=col-span-2-->
```toml
```toml
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
animal = { type.name = "pug" }
```
```
另见
---
- [Document](https://toml.io/en/latest) _(toml.io)_
- [Learn X in Y minutes](https://learnxinyminutes.com/docs/toml/) _(learnxinyminutes.com)_
- [Better TOML VSCode 插件](https://marketplace.visualstudio.com/items?itemName=bungcip.better-toml) _(visualstudio.com)_
- [INI 格式配置文件备忘清单](./ini.md) _(jaywcjlove.github.io)_
- [YAML 格式配置文件备忘清单](./yaml.md) _(jaywcjlove.github.io)_

View File

@ -10,8 +10,8 @@ TypeScript 备忘清单
TypeScript 是具有类型语法的 JavaScript。Interface 是为了匹配它们的运行时行为而构建的。
- [JavaScript 备忘清单](./javascript.md)
- [TypeScript 官网](https://www.typescriptlang.org/)
- [JavaScript 备忘清单](./javascript.md) _(jaywcjlove.github.io)_
- [TypeScript 官网](https://www.typescriptlang.org/) _(typescriptlang.org)_
### 内置类型基元
@ -240,7 +240,6 @@ type Data = typeof data
通过 typeof 运算符重用来自现有 JavaScript 运行时值的类型。
### 从函数返回类型
```ts
@ -1077,11 +1076,9 @@ console.log(fiveToHex());
从 Type 中移除 this 参数。 如果 Type 没有显式声明此参数,则结果只是 Type。 否则,从 Type 创建一个不带此参数的新函数类型。 泛型被删除,只有最后一个重载签名被传播到新的函数类型中。
JSX
----
### JSX 介绍
JSX 规范是对 ECMAScript 的类似 XML 的语法扩展。
@ -1233,7 +1230,6 @@ function NotAValidFactoryFunction() {
默认情况下,`JSX.ElementClass` 是 {},但可以对其进行扩展,以将 `JSX` 的使用限制为仅限于符合适当接口的类型。
### 类组件
<!--rehype:wrap-class=col-span-2-->
@ -1258,6 +1254,7 @@ class MyComponent extends React.Component<Props, {}> {
```
### 泛型组件
<!--rehype:wrap-class=col-span-2-->
```tsx
// 一个泛型组件
@ -1266,4 +1263,53 @@ class Select<T> extends React.Component<SelectProps<T>, any> {}
// 使用
const Form = () => <Select<string> items={['a', 'b']} />;
```
```
各种各样的技巧
---
### keyof 取 interface 的键
<!--rehype:wrap-class=row-span-2-->
```ts
interface Point {
x: number;
y: number;
}
// type keys = "x" | "y"
type keys = keyof Point;
```
### 索引签名
```ts
interface NumberOrString {
[index: string]: string | number;
length: number;
name: string;
}
```
### 从数组中提取类型
```ts
type Point = { x: number; y: number; }
type Data = Point[];
// Data 是个数组,提取里面的元素类型
type PointDetail = Data[number];
// type PointDetail = { x: number; y: number; }
```
### 只读元组类型
```ts
const point = [3, 4] as const
// type 'readonly [3, 4]'
```
另见
----
- [JavaScript 备忘清单](./javascript.md)
- [TypeScript 官网](https://www.typescriptlang.org/) _(typescriptlang.org)_

View File

@ -46,7 +46,7 @@ G gg H M L k j ▶ print("to")
┆ ╰┈┈┈┈┈▷
┆ - SCREEN 1 END
╰┈┈┈┈┈┈┈┈┈┈┈┈┈┈▷ print("SCREEN 2")
```
```
### 动作
<!--rehype:wrap-class=row-span-2-->
@ -163,7 +163,7 @@ G gg H M L k j ▶ print("to")
快捷方式 | 说明
:- | -
| `d` _\|_ `x` | 删除选择 _(剪切)_
| `s` | 替换选择
| `s` | 替换选择
| `y` | Yank 选择 _(复制)_
<!--rehype:className=shortcuts-->
@ -210,7 +210,7 @@ Vim 运算符
快捷方式 | 说明
:- | -
`d` | <yel>w</yel>
`d` | <yel>w</yel>
运算符 | 动作
<!--rehype:className=shortcuts-->
@ -276,7 +276,6 @@ Vim 文本对象
### 用法
<!--rehype:style=background:#d7a100;-->
快捷方式 | 说明
:- | -
`v` | &nbsp; &nbsp; &nbsp; &nbsp; <pur>i</pur> _/_ <pur>a</pur> | <yel>p</yel>
@ -409,7 +408,7 @@ Vim 搜索和替换
`?foo` | 向后搜索
`/\v\d+` | 使用 [regex](./regex.md) 搜索
`n` | 下一个匹配的搜索模式
`N` | 上一场比赛
`N` | 上一个匹配的搜索
`*` | 向前搜索当前单词
`#` | 向后搜索当前单词
@ -435,6 +434,7 @@ Vim 搜索和替换
```vim
:%s/{pattern}/{str}/[flags]
```
---
:- | -
@ -460,7 +460,7 @@ Vim 搜索和替换
`,3` | 接下来的 `3`
`-3,` | 转发 `3`
### 全局命令
### 全局命令
<!--rehype:wrap-class=row-span-2-->
```vim
@ -516,7 +516,6 @@ Vim 搜索和替换
### 例子
<!--rehype:wrap-class=col-span-2-->
```shell
:s/a\|b/xxx\0xxx/g # 将 "a b" 修改为 "xxxaxxx xxxbxxx"
:s/test/\U& file/ # 将 "test" 修改为 "TEST FILE"
@ -855,4 +854,4 @@ dfx # 删除文本直到字符“x”(包括字符“x”): delete forward x
- [Devhints](https://devhints.io/vim) _(devhints.io)_
- [Vim cheatsheet](https://vim.rtorr.com/lang/zh_cn/) _(vim.rotrr.com)_
- [Vim documentation](http://vimdoc.sourceforge.net/htmldoc/) _(vimdoc.sourceforge.net)_
- [Interactive Vim tutorial](http://openvim.com/) _(openvim.com)_
- [Interactive Vim tutorial](http://openvim.com/) _(openvim.com)_

View File

@ -61,11 +61,10 @@ VSCode 备忘清单
| `F8` | 转到下一个错误 |
| `Shift` `F8` | 转到上一个错误 |
| `Ctrl` `Shift` `Tab` | 浏览编辑组历史 |
| `Alt` ` ←` _/_ `→` | 后退/前进 |
| `Alt` `←` _/_ `→` | 后退/前进 |
| `Ctrl` `M` | 切换 Tab 移动焦点 |
<!--rehype:className=shortcuts-->
### 搜索和替换
| - | - |
@ -115,7 +114,6 @@ VSCode 备忘清单
| `Ctrl` `K` `M` | 更改文件语言 |
<!--rehype:className=shortcuts-->
### 编辑管理
| - | - |
@ -123,7 +121,7 @@ VSCode 备忘清单
| `Ctrl` `F4` `Ctrl` `W` | 关闭编辑器 |
| `Ctrl` `K` `F` | 关闭文件夹 |
| `Ctrl` `\` | 拆分编辑器 |
| `Ctrl` ` 1` _/_ `2` _/_ `3` | 专注于第一、第二或第三编辑组 |
| `Ctrl` `1` _/_ `2` _/_ `3` | 专注于第一、第二或第三编辑组 |
| `Ctrl` `K` `Ctrl` `←` _/_ `→` | 专注于上一个/下一个编辑组 |
| `Ctrl` `Shift` `PgUp` _/_ `PgDn` | 向左/向右移动编辑器 |
| `Ctrl` `K` `←` _/_ `→` | 移动活动编辑器组 |
@ -170,7 +168,6 @@ VSCode 备忘清单
| `Ctrl` `K` `Z` | Zen 模式Esc Esc 退出) |
<!--rehype:className=shortcuts-->
### 调试
| - | - |

642
docs/vue.md Normal file
View File

@ -0,0 +1,642 @@
Vue 3 备忘清单
===
渐进式 JavaScript 框架 [Vue 3](https://cn.vuejs.org/) 备忘清单的快速参考列表,包含常用 API 和示例。
入门
---
### 介绍
Vue 是一套用于构建用户界面的渐进式框架
- [Vue 3.x 官方文档](https://cn.vuejs.org/) _(cn.vuejs.org)_
- [Vue Router 4.x 官方文档](https://router.vuejs.org/zh/) _(router.vuejs.org)_
- [Vue 2 备忘清单](./vue2.md)
<!--rehype:className=style-round-->
注意Vue 3.x 版本对应 Vue Router 4.x 路由版本
### 创建应用
<!--rehype:wrap-class=row-span-3-->
已安装 `16.0` 或更高版本的 Node.js
```bash
$ npm init vue@latest
```
指令将会安装并执行 [create-vue](https://www.npmjs.com/package/create-vue),它是 Vue 官方的项目脚手架工具
```bash
✔ Project name: … <your-project-name>
✔ Add TypeScript? … No/Yes
✔ Add JSX Support? … No/Yes
✔ Add Vue Router for Single Page Application development? … No/Yes
✔ Add Pinia for state management? … No/Yes
✔ Add Vitest for Unit testing? … No/Yes
✔ Add Cypress for both Unit and End-to-End testing? … No/Yes
✔ Add ESLint for code quality? … No/Yes
✔ Add Prettier for code formatting? … No/Yes
Scaffolding project in ./<your-project-name>...
Done.
```
<!--rehype:className=wrap-text -->
安装依赖并启动开发服务器
```bash
$ cd <your-project-name>
$ npm install
$ npm run dev
```
当你准备将应用发布到生产环境时,请运行:
```bash
$ npm run build
```
此命令会在 `./dist` 文件夹中为你的应用创建一个生产环境的构建版本
### 应用实例
<!--rehype:wrap-class=row-span-2-->
```js
import { createApp } from 'vue'
const app = createApp({
data() {
return { count: 0 }
}
})
app.mount('#app')
```
挂载应用
```html
<div id="app">
<button @click="count++">
{{ count }}
</button>
</div>
```
### 通过 CDN 使用 Vue
```html
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">{{ message }}</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
```
<!--rehype:className=wrap-text -->
### 使用 ES 模块构建版本
```html
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
```
<!--rehype:className=wrap-text -->
模板语法
---
### 文本插值
```html
<span>Message: {{ msg }}</span>
```
使用的是 `Mustache` 语法 (即双大括号),每次 `msg` 属性更改时它也会同步更新
### 原始 HTML
<!--rehype:wrap-class=col-span-2-->
```html
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
```
双大括号`{{}}`会将数据解释为纯文本,使用 `v-html` 指令,将插入 HTML
### Attribute 绑定
```html
<div v-bind:id="dynamicId"></div>
```
简写
```html
<div :id="dynamicId"></div>
```
### 布尔型 Attribute
```html
<button :disabled="isButtonDisabled">
Button
</button>
```
<!--rehype:className=wrap-text -->
### 动态绑定多个值
<!--rehype:wrap-class=row-span-2-->
```js
data() {
return {
objectOfAttrs: {
id: 'container',
class: 'wrapper'
}
}
}
```
通过不带参数的 `v-bind`,你可以将它们绑定到单个元素上
```html
<div v-bind="objectOfAttrs"></div>
```
### 使用 JavaScript 表达式
```html
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
```
### 仅支持表达式(例子都是无效)
```html
<!-- 这是一个语句,而非表达式 -->
{{ var a = 1 }}
<!-- 条件控制也不支持,请使用三元表达式 -->
{{ if (ok) { return message } }}
```
### 调用函数
```html
<span :title="toTitleDate(date)">
{{ formatDate(date) }}
</span>
```
### 指令 Directives
```html
<p v-if="seen">Now you see me</p>
```
### 参数 Arguments
```html
<a v-bind:href="url"> ... </a>
<!-- 简写 -->
<a :href="url"> ... </a>
```
### 绑定事件
```html
<a v-on:click="doSomething"> ... </a>
<!-- 简写 -->
<a @click="doSomething"> ... </a>
```
### 动态参数
```html
<a v-bind:[attributeName]="url"> ... </a>
<!-- 简写 -->
<a :[attributeName]="url"> ... </a>
```
这里的 `attributeName` 会作为一个 JS 表达式被动态执行
### 动态的事件名称
```html
<a v-on:[eventName]="doSomething"> ... </a>
<!-- 简写 -->
<a @[eventName]="doSomething">
```
### 修饰符 Modifiers
```html
<form @submit.prevent="onSubmit">
...
</form>
```
`.prevent` 修饰符会告知 `v-on` 指令对触发的事件调用 `event.preventDefault()`
### 指令语法
```bash
v-on:submit.prevent="onSubmit"
──┬─ ─┬──── ─┬───── ─┬──────
┆ ┆ ┆ ╰─ Value 解释为JS表达式
┆ ┆ ╰─ Modifiers 由前导点表示
┆ ╰─ Argument 跟随冒号或速记符号
╰─ Name 以 v- 开头使用速记时可以省略
```
响应式基础
---
### 声明状态
```html
<div>{{ count }}</div>
```
---
```js {2,4}
export default {
data() {
return {
count: 0
}
},
}
```
### 声明方法
```html
<button @click="increment">
{{ count }}
</button>
```
---
```js {8-10}
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
```
### 有状态方法
```js
import { debounce } from 'lodash-es'
export default {
created() {
// 每个实例都有了自己的预置防抖的处理函数
this.debouncedClick = debounce(this.click, 500)
},
unmounted() {
// 最好是在组件卸载时
// 清除掉防抖计时器
this.debouncedClick.cancel()
},
methods: {
click() {
// ... 对点击的响应 ...
}
}
}
```
<!--rehype:className=wrap-text -->
API 参考
---
### 全局 API - 应用实例
<!--rehype:wrap-class=row-span-3-->
:- | :-
:- | :-
`createApp()` | [#](https://cn.vuejs.org/api/application.html#create-app)
`createSSRApp()` | [#](https://cn.vuejs.org/api/application.html#create-ssr-app)
`app.mount()` | [#](https://cn.vuejs.org/api/application.html#app-mount)
`app.unmount()` | [#](https://cn.vuejs.org/api/application.html#app-unmount)
`app.provide()` | [#](https://cn.vuejs.org/api/application.html#app-provide)
`app.component()` | [#](https://cn.vuejs.org/api/application.html#app-component)
`app.directive()` | [#](https://cn.vuejs.org/api/application.html#app-directive)
`app.use()` | [#](https://cn.vuejs.org/api/application.html#app-use)
`app.mixin()` | [#](https://cn.vuejs.org/api/application.html#app-mixin)
`app.version` | [#](https://cn.vuejs.org/api/application.html#app-version)
`app.config` | [#](https://cn.vuejs.org/api/application.html#app-config)
`app.config.errorHandler` | [#](https://cn.vuejs.org/api/application.html#app-config-errorhandler)
`app.config.warnHandler` | [#](https://cn.vuejs.org/api/application.html#app-config-warnhandler)
`app.config.performance` | [#](https://cn.vuejs.org/api/application.html#app-config-performance)
`app.config.compilerOptions` | [#](https://cn.vuejs.org/api/application.html#app-config-compileroptions)
`app.config.globalProperties` | [#](https://cn.vuejs.org/api/application.html#app-config-globalproperties)
`app.config.optionMergeStrategies` | [#](https://cn.vuejs.org/api/application.html#app-config-optionmergestrategies)
### 全局 API - 通用
:- | :-
:- | :-
`version` | [#](https://cn.vuejs.org/api/general.html#version)
`nextTick()` | [#](https://cn.vuejs.org/api/general.html#nexttick)
`defineComponent()` | [#](https://cn.vuejs.org/api/general.html#definecomponent)
`defineAsyncComponent()` | [#](https://cn.vuejs.org/api/general.html#defineasynccomponent)
`defineCustomElement()` | [#](https://cn.vuejs.org/api/general.html#definecustomelement)
### 组合式 API - setup()
:- | :-
:- | :-
`基本使用` | [#](https://cn.vuejs.org/api/composition-api-setup.html#basic-usage)
`访问 Props` | [#](https://cn.vuejs.org/api/composition-api-setup.html#accessing-props)
`Setup 上下文` | [#](https://cn.vuejs.org/api/composition-api-setup.html#setup-context)
`与渲染函数一起使用` | [#](https://cn.vuejs.org/api/composition-api-setup.html#usage-with-render-functions)
### 组合式 API - 响应式: 工具
:- | :-
:- | :-
`isRef()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#isref)
`unref()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#unref)
`toRef()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#toref)
`toRefs()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#torefs)
`isProxy()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#isproxy)
`isReactive()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#isreactive)
`isReadonly()` | [#](https://cn.vuejs.org/api/reactivity-utilities.html#isreadonly)
### 组合式 API - 生命周期钩子
<!--rehype:wrap-class=row-span-3-->
:- | :-
:- | :-
`onMounted()` | 组件挂载完成后执行 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onmounted)
`onUpdated()` | 状态变更而更新其 DOM 树之后调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onupdated)
`onUnmounted()` | 组件实例被卸载之后调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onunmounted)
`onBeforeMount()` | 组件被挂载之前被调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onbeforemount)
`onBeforeUpdate()` | 状态变更而更新其 DOM 树之前调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onbeforeupdate)
`onBeforeUnmount()` | 组件实例被卸载之前调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onbeforeunmount)
`onErrorCaptured()` | 捕获了后代组件传递的错误时调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured)
`onRenderTracked()` | 组件渲染过程中追踪到响应式依赖时调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onrendertracked)
`onRenderTriggered()` | 响应式依赖的变更触发了组件渲染时调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onrendertriggered)
`onActivated()` | 若组件实例是 \<KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onactivated)
`onDeactivated()` | 若组件实例是 \<KeepAlive> 缓存树的一部分,当组件从 DOM 中被移除时调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#ondeactivated)
`onServerPrefetch()` | 组件实例在服务器上被渲染之前调用 [#](https://cn.vuejs.org/api/composition-api-lifecycle.html#onserverprefetch)
<!--rehype:className=style-list-->
### 组合式 API - 依赖注入
:- | :-
:- | :-
`provide()` | [#](https://cn.vuejs.org/api/composition-api-dependency-injection.html#provide)
`inject()` | [#](https://cn.vuejs.org/api/composition-api-dependency-injection.html#inject)
### 组合式 API - 响应式: 核心
:- | :-
:- | :-
`ref()` | [#](https://cn.vuejs.org/api/reactivity-core.html#ref)
`computed ()` | [#](https://cn.vuejs.org/api/reactivity-core.html#computed)
`reactive()` | [#](https://cn.vuejs.org/api/reactivity-core.html#reactive)
`readonly()` | [#](https://cn.vuejs.org/api/reactivity-core.html#readonly)
`watchEffect()` | [#](https://cn.vuejs.org/api/reactivity-core.html#watcheffect)
`watchPostEffect()` | [#](https://cn.vuejs.org/api/reactivity-core.html#watchposteffect)
`watchSyncEffect()` | [#](https://cn.vuejs.org/api/reactivity-core.html#watchsynceffect)
`watch()` | [#](https://cn.vuejs.org/api/reactivity-core.html#watch)
### 选项式 API - 状态选项
:- | :-
:- | :-
`data` | [#](https://cn.vuejs.org/api/options-state.html#data)
`props` | [#](https://cn.vuejs.org/api/options-state.html#props)
`computed` | [#](https://cn.vuejs.org/api/options-state.html#computed)
`methods` | [#](https://cn.vuejs.org/api/options-state.html#methods)
`watch` | [#](https://cn.vuejs.org/api/options-state.html#watch)
`emits` | [#](https://cn.vuejs.org/api/options-state.html#emits)
`expose` | [#](https://cn.vuejs.org/api/options-state.html#expose)
### 选项式 API - 生命周期选项
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`beforeCreate` | [#](https://cn.vuejs.org/api/options-lifecycle.html#beforecreate)
`created` | [#](https://cn.vuejs.org/api/options-lifecycle.html#created)
`beforeMount` | [#](https://cn.vuejs.org/api/options-lifecycle.html#beforemount)
`mounted` | [#](https://cn.vuejs.org/api/options-lifecycle.html#mounted)
`beforeUpdate` | [#](https://cn.vuejs.org/api/options-lifecycle.html#beforeupdate)
`updated` | [#](https://cn.vuejs.org/api/options-lifecycle.html#updated)
`beforeUnmount` | [#](https://cn.vuejs.org/api/options-lifecycle.html#beforeunmount)
`unmounted` | [#](https://cn.vuejs.org/api/options-lifecycle.html#unmounted)
`errorCaptured` | [#](https://cn.vuejs.org/api/options-lifecycle.html#errorcaptured)
`renderTracked` | [#](https://cn.vuejs.org/api/options-lifecycle.html#rendertracked)
`renderTriggered` | [#](https://cn.vuejs.org/api/options-lifecycle.html#rendertriggered-sup-classvt-badge-dev-only)
`activated` | [#](https://cn.vuejs.org/api/options-lifecycle.html#activated)
`deactivated` | [#](https://cn.vuejs.org/api/options-lifecycle.html#deactivated)
`serverPrefetch` | [#](https://cn.vuejs.org/api/options-lifecycle.html#serverprefetch)
### 选项式 API - 其他杂项
:- | :-
:- | :-
`name` | 显式声明组件展示时的名称 [#](https://cn.vuejs.org/api/options-misc.html#name)
`inheritAttrs` | 默认的组件 `attribute` 透传行为 [#](https://cn.vuejs.org/api/options-misc.html#inheritattrs)
`components` | [#](https://cn.vuejs.org/api/options-misc.html#components)
`directives` | [#](https://cn.vuejs.org/api/options-misc.html#directives)
### 选项式 API - 渲染选项
:- | :-
:- | :-
`template` | [#](https://cn.vuejs.org/api/options-rendering.html#template)
`render` | [#](https://cn.vuejs.org/api/options-rendering.html#render)
`compilerOptions` | [#](https://cn.vuejs.org/api/options-rendering.html#compileroptions)
### 选项式 API - 组件实例
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`$data` | [#](https://cn.vuejs.org/api/component-instance.html#data)
`$props` | [#](https://cn.vuejs.org/api/component-instance.html#props)
`$el` | [#](https://cn.vuejs.org/api/component-instance.html#el)
`$options` | [#](https://cn.vuejs.org/api/component-instance.html#options)
`$parent` | [#](https://cn.vuejs.org/api/component-instance.html#parent)
`$root` | [#](https://cn.vuejs.org/api/component-instance.html#root)
`$slots` | [#](https://cn.vuejs.org/api/component-instance.html#slots)
`$refs` | [#](https://cn.vuejs.org/api/component-instance.html#refs)
`$attrs` | [#](https://cn.vuejs.org/api/component-instance.html#attrs)
`$watch()` | [#](https://cn.vuejs.org/api/component-instance.html#watch)
`$emit()` | [#](https://cn.vuejs.org/api/component-instance.html#emit)
`$forceUpdate()` | [#](https://cn.vuejs.org/api/component-instance.html#forceupdate)
`$nextTick()` | [#](https://cn.vuejs.org/api/component-instance.html#nexttick)
### 选项式 API - 组合选项
:- | :-
:- | :-
`provide` | [#](https://cn.vuejs.org/api/options-composition.html#provide)
`inject` | [#](https://cn.vuejs.org/api/options-composition.html#inject)
`mixins` | [#](https://cn.vuejs.org/api/options-composition.html#mixins)
`extends` | [#](https://cn.vuejs.org/api/options-composition.html#extends)
### 内置内容 - 指令
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`v-text` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-text)
`v-html` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-html)
`v-show` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-show)
`v-if` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-if)
`v-else` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-else)
`v-else-if` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-else-if)
`v-for` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-for)
`v-on` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-on)
`v-bind` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-bind)
`v-model` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-model)
`v-slot` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-slot)
`v-pre` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-pre)
`v-once` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-once)
`v-memo` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-memo)
`v-cloak` | [#](https://cn.vuejs.org/api/built-in-directives.html#v-cloak)
### 内置内容 - 组件
:- | :-
:- | :-
`<Transition>` | [#](https://cn.vuejs.org/api/built-in-components.html#transition)
`<TransitionGroup>` | [#](https://cn.vuejs.org/api/built-in-components.html#transitiongroup)
`<KeepAlive>` | [#](https://cn.vuejs.org/api/built-in-components.html#keepalive)
`<Teleport>` | [#](https://cn.vuejs.org/api/built-in-components.html#teleport)
`<Suspense>` | [#](https://cn.vuejs.org/api/built-in-components.html#suspense)
### 内置内容 - 特殊 Attributes
:- | :-
:- | :-
`key` | [#](https://cn.vuejs.org/api/built-in-special-attributes.html#key)
`ref` | [#](https://cn.vuejs.org/api/built-in-special-attributes.html#ref)
`is` | [#](https://cn.vuejs.org/api/built-in-special-attributes.html#is)
### 内置内容 - 特殊元素
:- | :-
:- | :-
`<component>` | [#](https://cn.vuejs.org/api/built-in-special-elements.html#component)
`<slot>` | [#](https://cn.vuejs.org/api/built-in-special-elements.html#slot)
### 单文件组件 - 语法定义
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`总览` | [#](https://cn.vuejs.org/api/sfc-spec.html#overview)
`相应语言块` | [#](https://cn.vuejs.org/api/sfc-spec.html#language-blocks)
`自动名称推导` | [#](https://cn.vuejs.org/api/sfc-spec.html#automatic-name-inference)
`预处理器` | [#](https://cn.vuejs.org/api/sfc-spec.html#pre-processors)
`Src 导入` | [#](https://cn.vuejs.org/api/sfc-spec.html#src-imports)
`注释` | [#](https://cn.vuejs.org/api/sfc-spec.html#comments)
### 单文件组件 - \<script setup>
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`基本语法` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#basic-syntax)
`响应式` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#reactivity)
`使用组件` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#using-components)
`使用自定义指令` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#using-custom-directives)
`defineProps() 和 defineEmits()` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#defineprops-defineemits)
`defineExpose` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#defineexpose)
`useSlots() 和 useAttrs()` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#useslots-useattrs)
`与普通的 &lt;script&gt; 一起使用` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#usage-alongside-normal-script)
`顶层 await` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#top-level-await)
`针对 TypeScript 的功能` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#typescript-only-features)
`限制` | [#](https://cn.vuejs.org/api/sfc-script-setup.html#restrictions)
### 单文件组件 - CSS 功能
:- | :-
:- | :-
`组件作用域 CSS` | [#](https://cn.vuejs.org/api/sfc-css-features.html#scoped-css)
`CSS Modules` | [#](https://cn.vuejs.org/api/sfc-css-features.html#css-modules)
`CSS 中的 v-bind()` | [#](https://cn.vuejs.org/api/sfc-css-features.html#v-bind-in-css)
### 进阶 API - 渲染函数
:- | :-
:- | :-
`h()` | [#](https://cn.vuejs.org/api/render-function.html#h)
`mergeProps()` | [#](https://cn.vuejs.org/api/render-function.html#mergeprops)
`cloneVNode()` | [#](https://cn.vuejs.org/api/render-function.html#clonevnode)
`isVNode()` | [#](https://cn.vuejs.org/api/render-function.html#isvnode)
`resolveComponent()` | [#](https://cn.vuejs.org/api/render-function.html#resolvecomponent)
`resolveDirective()` | [#](https://cn.vuejs.org/api/render-function.html#resolvedirective)
`withDirectives()` | [#](https://cn.vuejs.org/api/render-function.html#withdirectives)
`withModifiers()` | [#](https://cn.vuejs.org/api/render-function.html#withmodifiers)
### 进阶 API - 服务端渲染
:- | :-
:- | :-
`renderToString()` | [#](https://cn.vuejs.org/api/ssr.html#rendertostring)
`renderToNodeStream()` | [#](https://cn.vuejs.org/api/ssr.html#rendertonodestream)
`pipeToNodeWritable()` | [#](https://cn.vuejs.org/api/ssr.html#pipetonodewritable)
`renderToWebStream()` | [#](https://cn.vuejs.org/api/ssr.html#rendertowebstream)
`pipeToWebWritable()` | [#](https://cn.vuejs.org/api/ssr.html#pipetowebwritable)
`renderToSimpleStream()` | [#](https://cn.vuejs.org/api/ssr.html#rendertosimplestream)
`useSSRContext()` | [#](https://cn.vuejs.org/api/ssr.html#usessrcontext)
### 进阶 API - TypeScript 工具类型
:- | :-
:- | :-
`PropType<T>` | [#](https://cn.vuejs.org/api/utility-types.html#proptypet)
`ComponentCustomProperties` | [#](https://cn.vuejs.org/api/utility-types.html#componentcustomproperties)
`ComponentCustomOptions` | [#](https://cn.vuejs.org/api/utility-types.html#componentcustomoptions)
`ComponentCustomProps` | [#](https://cn.vuejs.org/api/utility-types.html#componentcustomprops)
`CSSProperties` | [#](https://cn.vuejs.org/api/utility-types.html#cssproperties)
### 进阶 API - 自定义渲染
:- | :-
:- | :-
`createRenderer()` | [#](https://cn.vuejs.org/api/custom-renderer.html#create-renderer)
另见
---
- [Vue 3.x 官方文档](https://cn.vuejs.org/)
- [Vue Router 4.x 官方文档](https://router.vuejs.org/zh/)

2078
docs/vue2.md Normal file

File diff suppressed because it is too large Load Diff

191
docs/webstorm.md Normal file
View File

@ -0,0 +1,191 @@
WebStorm 备忘清单
===
此快速参考备忘单列出了在 Windows/Linux 或 Mac 上运行的 [WebStorm](https://www.jetbrains.com/webstorm/) 的默认键盘快捷键
Webstorm Windows & Linux 键盘映射
--------
### 编辑
<!--rehype:wrap-class=row-span-5-->
快捷键 | 说明
:-|:-
`Ctrl` `Space`| 基本代码完成
`Alt` `Enter`| 显示意图操作,快速修复
`Ctrl` `P`| 参数信息
`Ctrl` `Q`| 快速文档查找
`Ctrl` `mouse over`| 简要信息
`Ctrl` `F1`| 插入符号处的错误或警告
`Alt` `Insert`| 生成代码...
`Ctrl` `Alt` `T`| 环绕...
`Ctrl` `J`| 插入实时模板
`Ctrl` `/`| 用行注释/取消注释
`Ctrl` `Shift` `/`| 用块评论/取消评论
`Ctrl` `W`| 选择连续增加的代码块
`Ctrl` `Shift` `W`| 将当前选择减少到以前的状态
`Alt+Q`| 上下文信息
`Ctrl` `Alt` `L`| 重新格式化代码
`Ctrl` `Alt` `I`| 自动缩进行
`Tab`| 缩进选定的行
`Shift` `Tab`| 取消缩进选定的行
`Ctrl` `Shift` `V`| 从最近的缓冲区粘贴...
`Ctrl` `D`| 复制当前行或选定块
`Ctrl` `Y`| 删除插入符号处的行
`Alt` `Shift` `Up`| 向上移动队列
`Alt` `Shift` `Down`| 下移线
`Ctrl` `Shift` `J`| 连接线
`Ctrl` `Enter`| 分割线
`Shift` `Enter`| 开始新行
`Ctrl` `Shift` `U`| 在插入符号或选定块中切换单词的大小写
`Ctrl` `Shift` `]`| 选择直到代码块结束
`Ctrl` `Shift` `[`| 选择直到代码块开始
`Ctrl` `Delete`| 删除到词尾
`Ctrl` `Backspace`| 删除到单词开头
`Ctrl` `+`| 展开代码块
`Ctrl` `-`| 折叠代码块
`Ctrl` `Shift` `+`| 展开全部
`Ctrl` `Shift` `-`| 全部收缩
`Ctrl` `F4`| 关闭活动编辑器选项卡
<!--rehype:className=shortcuts-->
### 一般的
快捷键 | 说明
:-|:-
`Double Shift`| 到处搜索
`Ctrl` `Shift` `A`| 寻找行动
`Alt` `0...9`| 打开相应的工具窗口
`Ctrl` `Shift` `F12`| 切换最大化编辑器
`Alt` `Shift` `F`| 添加到收藏夹
`Alt` `Shift` `I`| 检查当前文件
`Ctrl` <kbd>\`</kbd>| 快速切换电流方案
`Ctrl` `Alt` `S`| 打开设置对话框
`Ctrl` `Tab`| 在工具和选项卡之间切换
<!--rehype:className=shortcuts-->
### 导航
<!--rehype:wrap-class=row-span-4-->
快捷键 | 说明
:-|:-
`Ctrl` `B` _\|_ `Ctrl + Click` | 前往 declaration
`Ctrl` `N` | 前往 class
`Ctrl` `Shift` `N` | 转到文件
`Ctrl` `Alt` `Shift` `N` | 转到符号
`Alt` `Right` | 转到下一个编辑器选项卡
`Alt` `Left` | 转到上一个编辑器选项卡
`F12` | 返回上一个工具窗口
`Esc` | 转到编辑器
`Ctrl` `G` | 去行
`Ctrl` `E` | 最近的文件弹出
`Ctrl` `Alt` `Right` | 向前导航
`Ctrl` `Alt` `Left` | 向后导航
`Ctrl` `Shift` `Backspace` | 导航到最后一个编辑位置
`Alt` `F1` | 在任何视图中选择当前文件或符号
`Ctrl` `Alt` `B` | 转到实施
`Ctrl` `Shift` `I` | 打开快速定义查找
`Ctrl` `Shift` `B` | 转到类型声明
`Ctrl` `U` | 转到超方法/超类
`Alt` `Up` | 转到上一个方法
`Alt` `Down` | 转到下一个方法
`Ctrl` `]` _/_ `[` | 移动到代码块结束/开始
`Cltrl` `Shift` `M` | 将插入符号移动到匹配的大括号
`Ctrl` `F12` | 文件结构弹出
`Ctrl` `H` | 类型层次结构
`Ctrl` `Alt` `H` | 调用层次结构
`F2` _/_ `Shift` `F2` | 下/上一个突出显示的错误
`F4` _/_ `Ctrl` `Enter` | 跳转到源
`Alt` `Home` | 跳转到导航栏
`F11` | 切换书签
`Ctrl` `Shift` `F11` | 使用助记符切换书签
`Ctrl` `0...9` | 转到编号的书签
`Shift` `F11` | 显示书签
<!--rehype:className=shortcuts-->
### 多个插入符号和选择
快捷键 | 说明
:-|:-
`Alt` `Click`| 添加或删除插入符号
`Shift` `Ctrl + Alt-J`| 选择所有出现
`Alt` `J`| 选择下一个出现
`Alt` `Shift` `J`| 取消选择事件
`Esc`| 取消选择所有出现或插入符号
<!--rehype:className=shortcuts-->
### 调试
快捷键 | 说明
:-|:-
`F8`| 跨过去
`F7`| 踏入
`Shift` `F7`| 智能步入
`Shift` `F8`| 走出去
`Alt` `F9`| 运行到光标
`Alt` `F8`| 评估表达式
`F9`| 简历计划
`Ctrl` `F8`| 切换断点
`Ctrl` `Shift` `F8`| 查看断点
<!--rehype:className=shortcuts-->
### 运行
快捷键 | 说明
:-|:-
`Alt` `Shift` `F10`| 选择配置并运行
`Alt` `Shift` `F9`| 选择配置和调试
`Shift` `F10`| 运行
`Shift` `F9`| 调试
`Ctrl` `Shift` `F10`| 从编辑器运行上下文配置
`Alt` `Shift` `R`| 重新运行测试
`Alt` `F11`| 运行 Gulp/Grunt/npm 任务
<!--rehype:className=shortcuts-->
### 使用搜索
快捷键 | 说明
:-|:-
`Alt` `F7`| 查找用法
`Ctrl` `F7`| 在文件中查找用法
`Ctrl` `Shift` `F7`| 突出显示文件中的用法
`Ctrl` `Alt` `F7`| 显示用法
<!--rehype:className=shortcuts-->
### VCS/本地历史
快捷键 | 说明
:-|:-
`Alt` <kbd>\`</kbd>| VCS 快速弹出窗口
`Ctrl` `K`| 将项目提交到 VCS
`Ctrl` `T`| 从 VCS 更新项目
`Alt` `Shift` `C`| 查看最近的更改
<!--rehype:className=shortcuts-->
### 搜索/替换
快捷键 | 说明
:-|:-
`Ctrl` `F`| 寻找
`F3`| 找下一个
`Shift` `F3`| 查找上一个
`Ctrl` `Shift` `F`| 在路径中查找
`Ctrl` `R`| 代替
`Ctrl` `Shift` `R`| 在路径中替换
<!--rehype:className=shortcuts-->
### 重构
快捷键 | 说明
:-|:-
`Ctrl` `Alt` `Shift +T`| 重构这个
`F5` _/_ `F6`| 复制/移动
`Alt` `Delete`| 安全删除
`Shift` `F6`| 改名
`Ctrl` `F6`| 更改函数签名
`Ctrl` `Alt` `N`| 内联变量
`Ctrl` `Alt` `M`| 提取方法
`Ctrl` `Alt` `V`| 提取变量
`Ctrl` `Alt` `C`| 提取常数
`Ctrl` `Alt` `P`| 提取参数
<!--rehype:className=shortcuts-->

101
docs/xcode.md Normal file
View File

@ -0,0 +1,101 @@
Xcode 备忘清单
====
这个 Xcode 快速参考备忘单显示了它的键盘快捷键和命令。
Xcode
---
### 搜索
快捷键 | 描述
:---- | ----
`Cmd + F` | 在文件中查找
`Cmd + Option + F` | 在文件中查找和替换
`Cmd + Shift + F` | 在项目中查找
`Cmd + Option + Shift + F` | 在项目中查找和替换
<!--rehype:className=shortcuts-->
### 选项卡
快捷键 | 描述
:---- | ----
`Cmd + T` | 新选项卡
`Cmd + }` | 上一个选项卡
`Cmd + {` | 下一个选项卡
<!--rehype:className=shortcuts-->
### 导航
<!--rehype:wrap-class=row-span-2-->
快捷键 | 描述
:---- | ----
`Cmd + Shift + O` | 快速打开
`Cmd + J` | 专注于编辑
`Cmd + Ctrl + UP` | 下一个对手
`Cmd + Ctrl + DOWN` | 上一个对手
`Cmd + Ctrl + RIGHT` | 下一个最近的文件
`Cmd + Ctrl + LEFT` | 上一个 最近的文件
`Cmd + click` | 符号的定义
`Cmd + L` | 去线
`Cmd + Option + LEFT` | 折叠部分
`Cmd + Option + RIGHT` | 展开部分
<!--rehype:className=shortcuts-->
### 调试
快捷键 | 描述
:---- | ----
`Cmd + Shift + Y` | 切换调试区域
`Cmd + '` | 下一期
`Cmd + "` | 上一期
`Cmd + \` | 添加/删除断点
`Cmd + Y` | 活动/非活动断点
`Cmd + K` | 清除控制台
<!--rehype:className=shortcuts-->
### 导航器(左侧面板)
快捷键 | 描述
:---- | ----
`Cmd + 0` | 显示隐藏
`Cmd + 1-8` | 切换标签
`Option + click` | 打开助理编辑器
`Shift + Option + click` | 决定在哪里打开
`double click` | 在新窗口中打开
<!--rehype:className=shortcuts-->
### 编辑
快捷键 | 描述
:---- | ----
`Cmd + Option + ENTER` | 显示助理编辑器
`Cmd + ENTER` | 隐藏助理编辑器
`Ctrl + SPACE or ESC` | 切换完成
`Cmd + ]` | 缩进部分
`Cmd + [` | 突出部分
`Ctrl + i` | 修复缩进
`Cmd + /` | 评论/取消评论
`Cmd + Option + [` | 向上移动队列
`Cmd + Option + ]` | 下移线
<!--rehype:className=shortcuts-->
### 实用程序(右面板)
快捷键 | 描述
:---- | ----
`Cmd + Option + 0` | 显示隐藏
`Cmd + Option + 1-9` | 转到选项卡
<!--rehype:className=shortcuts-->
### 调试和运行
快捷键 | 描述
:---- | ----
`Cmd + B` | 建造
`Cmd + R` | 运行
`Cmd + .` | 停止
`Cmd + Shift + B` | 分析
`Cmd + U` | 测试
`Cmd + Shift + K` | 清理
<!--rehype:className=shortcuts-->

View File

@ -118,10 +118,9 @@ $x('//a[text()="XPath"]')[0].click()
### 运算符
<!--rehype:wrap-class=col-span-2-->
运算符 | 说明 | 示例
运算符 | 说明 | 示例
:- | - | -
`\|` | 计算两个节点集 | `//book \| //cd`
`\|` | 计算两个节点集 | `//book \| //cd`
`+` | 添加 | `6 + 4`
`-` | 减法 | `6 - 4`
`*` | 乘法 | `6 * 4`
@ -137,8 +136,6 @@ $x('//a[text()="XPath"]')[0].click()
`mod` | 模数(除法余数) | `5` mod `2`
<!--rehype:className=show-header-->
XPath 表达式
-----------
@ -149,7 +146,6 @@ XPath 表达式
| `//` | `ul` | `/` | `a[@id='link']` |
| Axis | Step | Axis | Step |
### 前缀
| 前缀 | 例子 | 意思是 |
@ -202,6 +198,7 @@ XPath Predicates(谓词)
//ul[count(li) > 2]
//ul[count(li[@class='hide']) > 0]
```
```bash
# 返回具有 `<li>` 子级的 `<ul>`
//ul[li]
@ -251,6 +248,7 @@ text() # //button[text()="Submit"]
lang(str)
namespace-uri()
```
```bash
count() # //table[count(tr)=1]
position() # //ol/li[position()=2]
@ -357,12 +355,12 @@ XPath Axes
|--------------------|--------|-------|
`ancestor` | | 选择当前节点的所有祖先(父母、祖父母等)
`ancestor-or-self` | | 选择当前节点所有祖先(父、祖父等)和当前节点本身
`attribute` | `@` | `@href``attribute::href` 的缩写
`child` | | `div``child::div` 的缩写
`descendant` | | 选择当前节点的所有后代(子、孙等)
`attribute` | `@` | `@href``attribute::href` 的缩写
`child` | | `div``child::div` 的缩写
`descendant` | | 选择当前节点的所有后代(子、孙等)
`descendant-or-self` | `//` | `//``/descendant-or-self::node()/`的缩写 选择当前节点和当前节点本身的所有后代(子、孙等)
`namespace` | | 选择当前节点的所有命名空间节点
`self` | `.` | `.``self::node()` 的缩写,选择当前节点
`namespace` | | 选择当前节点的所有命名空间节点
`self` | `.` | `.``self::node()` 的缩写,选择当前节点
`parent` | `..` | `..``parent::node()` 的缩写,选择当前节点的父节点
`following` | | 选择文档中当前节点结束标记之后的所有内容
`following-sibling` | | 选择当前节点之后的所有兄弟节点
@ -429,5 +427,5 @@ count(//*) # 计算所有元素
另见
--------
* [Devhints](https://devhints.io/xpath) _(devhints.io)_
* [Xpath test bed](http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm) _(whitebeam.org)_
- [Devhints](https://devhints.io/xpath) _(devhints.io)_
- [Xpath test bed](http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm) _(whitebeam.org)_

526
docs/yaml.md Normal file
View File

@ -0,0 +1,526 @@
YAML 备忘清单
====
这是理解和编写 YAML 格式配置文件的快速参考备忘单。
入门
-----------
### 介绍
[YAML](https://yaml.org/) 是一种数据序列化语言,旨在供人类直接读写
- YAML 不允许使用制表符
- 元素部分之间必须有空间
- YAML 区分大小写
-`.yaml``.yml` 扩展名结束您的 YAML 文件
- YAML 是 JSON 的超集
- Ansible playbook 是 YAML 文件
<!--rehype:className=style-round-->
### 标量类型
<!--rehype:wrap-class=row-span-2-->
```yaml
n1: 1 # 整数
n2: 1.234 # 浮点
s1: 'abc' # 字符串
s2: "abc" # 字符串
s3: abc # 字符串
b: false # 布尔类型
d: 2015-04-05 # 日期类型
```
#### ↓ 等效的 JSON
```json
{
"n1": 1,
"n2": 1.234,
"s1": "abc",
"s2": "abc",
"s3": "abc",
"b": false,
"d": "2015-04-05"
}
```
使用空格缩进。 元素部分之间必须有空间。
### 变量
```yaml
some_thing: &VAR_NAME foobar
other_thing: *VAR_NAME
```
#### ↓ 等效的 JSON
```json
{
"some_thing": "foobar",
"other_thing": "foobar"
}
```
### 注释
```yaml
# A single line comment example
# block level comment example
# comment line 1
# comment line 2
# comment line 3
```
### 多行字符串
```yaml
description: |
hello
world
```
#### ↓ 等效的 JSON
```json
{"description": "hello\nworld\n"}
```
### 继承
<!--rehype:wrap-class=row-span-2-->
```yaml
parent: &defaults
a: 2
b: 3
child:
<<: *defaults
b: 4
```
#### ↓ 等效的 JSON
```json
{
"parent": {
"a": 2,
"b": 3
},
"child": {
"a": 2,
"b": 4
}
}
```
### 参考
<!--rehype:wrap-class=row-span-2-->
```yaml
values: &ref
- Will be
- reused below
other_values:
i_am_ref: *ref
```
#### ↓ 等效的 JSON
```json
{
"values": [
"Will be",
"reused below"
],
"other_values": {
"i_am_ref": [
"Will be",
"reused below"
]
}
}
```
### 折叠的字符串
```yaml
description: >
hello
world
```
#### ↓ 等效的 JSON
```json
{"description": "hello world\n"}
```
### 两份文件
```yaml
---
document: this is doc 1
---
document: this is doc 2
```
YAML使用`---`将指令与文档内容分开。
YAML Collections
-----------
### 序列
```yaml
- Mark McGwire
- Sammy Sosa
- Ken Griffey
```
#### ↓ 等效的 JSON
```json
[
"Mark McGwire",
"Sammy Sosa",
"Ken Griffey"
]
```
### 映射
```yaml
hr: 65 # Home runs
avg: 0.278 # Batting average
rbi: 147 # Runs Batted In
```
#### ↓ 等效的 JSON
```json
{
"hr": 65,
"avg": 0.278,
"rbi": 147
}
```
### 映射到序列
```yaml
attributes:
- a1
- a2
methods: [getter, setter]
```
#### ↓ 等效的 JSON
```json
{
"attributes": ["a1", "a2"],
"methods": ["getter", "setter"]
}
```
### 映射序列
```yaml
children:
- name: Jimmy Smith
age: 15
- name: Jimmy Smith
age: 15
-
name: Sammy Sosa
age: 12
```
#### ↓ 等效的 JSON
```json
{
"children": [
{"name": "Jimmy Smith", "age": 15},
{"name": "Jimmy Smith", "age": 15},
{"name": "Sammy Sosa", "age": 12}
]
}
```
### 序列的序列
```yaml
my_sequences:
- [1, 2, 3]
- [4, 5, 6]
-
- 7
- 8
- 9
- 0
```
#### ↓ 等效的 JSON
```json
{
"my_sequences": [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9, 0]
]
}
```
### 映射的映射
```yaml
Mark McGwire: {hr: 65, avg: 0.278}
Sammy Sosa: {
hr: 63,
avg: 0.288
}
```
#### ↓ 等效的 JSON
```json
{
"Mark McGwire": {
"hr": 65,
"avg": 0.278
},
"Sammy Sosa": {
"hr": 63,
"avg": 0.288
}
}
```
### 嵌套集合
```yaml
Jack:
id: 1
name: Franc
salary: 25000
hobby:
- a
- b
location: {country: "A", city: "A-A"}
```
#### ↓ 等效的 JSON
```json
{
"Jack": {
"id": 1,
"name": "Franc",
"salary": 25000,
"hobby": ["a", "b"],
"location": {
"country": "A", "city": "A-A"
}
}
}
```
### 无序集
```yaml
set1: !!set
? one
? two
set2: !!set {'one', "two"}
```
#### ↓ 等效的 JSON
```json
{
"set1": {"one": null, "two": null},
"set2": {"one": null, "two": null}
}
```
集合表示为一个映射,其中每个键都与一个空值相关联
### 有序映射
```yaml
ordered: !!omap
- Mark McGwire: 65
- Sammy Sosa: 63
- Ken Griffy: 58
```
#### ↓ 等效的 JSON
```json
{
"ordered": [
{"Mark McGwire": 65},
{"Sammy Sosa": 63},
{"Ken Griffy": 58}
]
}
```
YAML 参考
--------------
### 条款
- 序列又名数组或列表
- 标量又名字符串或数字
- 映射又名哈希或字典
<!--rehype:className=style-round-->
基于 YAML.org [refcard](https://yaml.org/refcard.html)。
### 文档指标
:- | :-
:- | :-
`%` | 指令指标
`---` | 文档标题
`...` | 文档终结者
### 收集指标
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`?` | 关键指标
`:` | 价值指标
`-` | 嵌套系列条目指示器
`,` | 单独的内联分支条目
`[]` | 环绕串联系列分支
`{}` | 环绕在线键控分支
### 别名指标
:- | :-
:- | :-
`&` | 锚属性
`*` | 别名指示符
### 特殊键
:- | :-
:- | :-
`=` | 默认“值”映射键
`<<` | 合并来自另一个映射的键
### 标量指标
:- | :-
:- | :-
`''` | 环绕内联未转义标量
`"` | 环绕内嵌转义标量
`|` | 块标量指示器
`>` | 折叠标量指示器
`-` | 剥离 chomp 修饰符(`\|-``>-`
`+` | 保留 chomp 修饰符(`\|+``>+`
`1-9` | 显式缩进修饰符(`\|1``>2`)。 <br/> 修饰符可以组合(`\|2-`, `>+1`
### 标签属性(通常未指定)
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`none` | 未指定的标签(由应用程序自动解析)
`!` | 非特定标签(默认情况下,`!!map`/`!!seq`/`!!str`
`!foo` | 主要(按照惯例,表示本地 `!foo` 标记)
`!!foo` | 次要的(按照惯例,表示 `tag:yaml.org,2002:foo`
`!h!foo` | 需要 `%TAG !h! <prefix>`(然后表示 `<prefix>foo`
`!<foo>` | 逐字标记始终表示“foo”
<!--rehype:class=auto-wrap-->
### 杂项指标
| | |
|-----|-----------------------------|
| `#` | 一次性评论指示器 |
| <code>\`@</code> | 两者都保留供将来使用 |
### 核心类型(默认自动标签)
<!--rehype:wrap-class=row-span-2-->
| | |
|---------|------------------------------------------|
| `!!map` | `{Hash table, dictionary, mapping}` |
| `!!seq` | `{List, array, tuple, vector, sequence}` |
| `!!str` | Unicode 字符串 |
### 转义码
<!--rehype:wrap-class=row-span-3-->
#### Numeric
- `\x12` (8-bit)
- `\u1234` (16-bit)
- `\U00102030` (32-bit)
<!--rehype:className=cols-2 style-none-->
#### Protective
- `\\` (\\)
- `\"` (")
- `\` ( )
- `\<TAB>` (TAB)
<!--rehype:className=cols-3 style-none-->
#### C
- `\0` (NUL)
- `\a` (BEL)
- `\b` (BS)
- `\f` (FF)
- `\n` (LF)
- `\r` (CR)
- `\t` (TAB)
- `\v` (VTAB)
<!--rehype:className=cols-3 style-none-->
#### 额外的
- `\e` (ESC)
- `\_` (NBSP)
- `\N` (NEL)
- `\L` (LS)
- `\P` (PS)
<!--rehype:className=cols-3 style-none-->
### 更多类型
| | |
|----------|-----------------------------|
| `!!set` | `{cherries, plums, apples}` |
| `!!omap` | `[one: 1, two: 2]` |
### 与语言无关的标量类型
<!--rehype:wrap-class=col-span-2-->
| | |
|---------------------------|--------------------------------------------|
| `{~, null}` | 空(无值)。 |
| `[1234, 0x4D2, 02333]` | [十进制整数、十六进制整数、八进制整数] |
| `[1_230.15, 12.3015e+02]` | [固定浮点数,指数浮点数] |
| `[.inf, -.Inf, .NAN]` | [无穷大(浮点数),负数,不是数字] |
| `{Y, true, Yes, ON}` | 布尔真 |
| `{n, FALSE, No, off}` | 布尔假 |
<!--rehype:class=auto-wrap-->
另见
---
- [YAML Reference Card](https://yaml.org/refcard.html) _(yaml.org)_
- [Learn X in Y minutes](https://learnxinyminutes.com/docs/yaml/) _(learnxinyminutes.com)_
- [YAML lint online](http://www.yamllint.com/) _(yamllint.com)_
- [INI 格式配置文件备忘清单](./ini.md) _(jaywcjlove.github.io)_
- [TOML 格式配置文件备忘清单](./toml.md) _(jaywcjlove.github.io)_

193
docs/yarn.md Normal file
View File

@ -0,0 +1,193 @@
Yarn 备忘清单
===
这是一份 [`Yarn`](https://yarnpkg.com/) 软件包管理器备忘单,其中列出了 `Yarn` 常用命令使用清单
入门
---
### Yarn 与 npm 命令比较
<!--rehype:wrap-class=col-span-2-->
npm(v5) | yarn | 说明
:- | :- | :-
`npm install` | `yarn add`, `yarn`| 安装依赖
`npm init` | `yarn init` | 创建 `package.json` 文件
`npm install gulp --save` | `yarn add gulp` | 安装 `gulp`
`npm install gulp --save-dev --save-exact` | `yarn add gulp --dev --exact`
`npm install -g gulp` | `yarn global add gulp`
`npm update` | `yarn upgrade`
`npm cache clean` | `yarn cache clean` | 清理缓存目录
`./node_modules/.bin/gulp` | `yarn run gulp`
<!--rehype:className=show-header left-align-->
npm _([备忘清单](./npm.md))_ 和 Yarn 有很多相似之处
### yarn install
```shell
--no-lockfile # 不要读取或生成 yarn.lock 锁定文件
--pure-lockfile
--frozen-lockfile
--silent
--offline
--update-checksums
--check-files
--flat
--force
--ignore-scripts
--modules-folder <path>
--production[=true|false]
```
这些选项可用于 `yarn install`
### yarn add
<!--rehype:wrap-class=row-span-2-->
在 [devDependencies](./package.json.md#devdependencies) 中安装一个或多个包
```shell
--dev, -D
```
在 [peerDependencies](./package.json.md#peerdependencies) 中安装一个或多个包
```shell
--peer, -P
```
在 [optionalDependencies](./package.json.md#optionaldependencies) 中安装一个或多个包
```shell
--optional, -O
```
更改包版本
```shell
--exact, -E # 将包安装为精确版本
--tilde, -T # 安装有相同次要版本的包的最新版本
```
这些选项可用于 `yarn add`.
### Workspaces
<!--rehype:wrap-class=row-span-2-->
`package.json` 中 [workspaces](./package.json.md#workspaces) 配置:
```json
"workspaces": [
"packages/*"
]
```
----
```bash
jest/
├─ package.json
└─ packages/
├─ jest-matcher-utils/
│ └─ package.json
└─ jest-diff/
└─ package.json
```
(1.0 新增)允许 monoreso 相互共享包。另见:[介绍工作空间](https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/)
### 选择性版本解析
`package.json` 中 [`resolutions`](./package.json.md#resolutions) 配置:
```json
"resolutions": {
"**/sass-brunch/node-sass": "4.5.2"
}
```
另见:[选择性版本解析](https://github.com/yarnpkg/yarn/pull/4105)。(1.0 新增)允许您指定子依赖项的版本
### Create
```bash
yarn create react-app hello
```
安装 `create react app` 并运行它 See: [yarn create](https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-yarn-create.md)
示例
---
### 安装包
<!--rehype:wrap-class=row-span-2-->
```bash
# 将包添加到“dependencies”
$ yarn add <package>
# 将包添加到“devDependencies”
$ yarn add -D <package>
# 将软件包添加为确切版本
$ yarn add -E <package>
# 在您的操作系统上全局安装软件包
$ yarn global add <package>
```
### 移除包
```bash
$ yarn remove <package>
```
从所有类型的依赖项中删除包
### 查看包
<!--rehype:wrap-class=row-span-2-->
```bash
# 列出已安装的软件包
$ yarn list
# 列出顶级安装包
$ yarn list --depth=0
# 列出已安装的顶级全局包
$ yarn global list --depth=0
# 列出带有过滤字符串和深度级别的包
$ yarn list --pattern "gulp|grunt" --depth=1
```
### 清除
```bash
# 从包依赖项中清理并删除不必要的文件
$ yarn autoclean
# 检查过时的包依赖项
$ yarn outdated
```
### 信息
```bash
$ yarn why <query>
$ yarn why jest
```
显示有关安装软件包的原因的信息
### 清理缓存
运行此命令将清除全局缓存。 下次运行 `yarn``yarn install` 时,它将再次填充
```bash
$ yarn cache clean
```
此外,您可以指定一个或多个要清理的包
另见
---
- [npm 备忘清单](./npm.md)
- [Yarn 官方文档网站](https://yarnpkg.com/)
- [Yarn 2 中文文档网站](https://www.yarnpkg.cn/)
- [Yarn 1 中文文档网站](https://yarn.bootcss.com/) _(bootcss.com)_

Some files were not shown because too many files have changed in this diff Show More