mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-19 06:06:54 +00:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5594525e7 | ||
|
|
e15eaaffe0 | ||
|
|
74cf57aaac | ||
|
|
cfe44f204b | ||
|
|
0a6c1fb251 | ||
|
|
75a3d7399b | ||
|
|
795ff3f4c3 | ||
|
|
c41672b2e0 | ||
|
|
9cc62e703f | ||
|
|
19d6bafbe1 | ||
|
|
388c1511d6 | ||
|
|
8849afe5cf | ||
|
|
89b962557a | ||
|
|
5de0153df4 | ||
|
|
ed4d304cd2 | ||
|
|
48564bda8d | ||
|
|
b9d053b3cd | ||
|
|
cd258c92c3 | ||
|
|
6230d1d750 | ||
|
|
365abc6b3b | ||
|
|
79c65b3e44 | ||
|
|
6b34901d94 | ||
|
|
90693ff95e | ||
|
|
1a01c35e52 | ||
|
|
c335bc6ce7 | ||
|
|
f3ea7e9887 | ||
|
|
c13ec31163 | ||
|
|
bbbb66b489 | ||
|
|
74f16623c9 | ||
|
|
1127c43823 | ||
|
|
ea3a22e13c | ||
|
|
c0018b66f3 | ||
|
|
02e296ed75 | ||
|
|
4facf5b390 | ||
|
|
c5d11441bc | ||
|
|
96bdd7c1dd | ||
|
|
ba764c1380 | ||
|
|
c7cfde0930 | ||
|
|
13177979bb | ||
|
|
6a17a7d46c | ||
|
|
8c30b41e20 | ||
|
|
b2d1cb68db | ||
|
|
3589a6ee53 | ||
|
|
7efbed6a24 | ||
|
|
21d74f1183 | ||
|
|
d6d0098379 | ||
|
|
241bb4df78 | ||
|
|
82d8f2db98 | ||
|
|
9882244bd9 | ||
|
|
f243cbd858 | ||
|
|
d420b38329 | ||
|
|
ea2d238bd8 | ||
|
|
5234511a2f | ||
|
|
746a31e125 | ||
|
|
c45e031155 | ||
|
|
4a2b89d0b6 | ||
|
|
2a4fbf6a79 | ||
|
|
84ea68cab0 | ||
|
|
3ed5eb1ee0 | ||
|
|
60836af606 | ||
|
|
739345ac24 | ||
|
|
1a977a87a0 | ||
|
|
d1a5b57e4d | ||
|
|
2b9d379d70 | ||
|
|
bdee5d6b6d | ||
|
|
348f6bff8b | ||
|
|
7a3d624364 | ||
|
|
06f1c6f256 | ||
|
|
4a7f33f7bb | ||
|
|
e077d2911d | ||
|
|
5f2edb0914 | ||
|
|
911206be80 | ||
|
|
18808851a9 | ||
|
|
2bf87e0de7 | ||
|
|
f6d96ab2b8 | ||
|
|
59c55121c7 | ||
|
|
9f174d9088 | ||
|
|
5810bcd1d7 | ||
|
|
897b57bfb4 |
@@ -1,5 +0,0 @@
|
||||
# https://github.com/browserslist/browserslist#browserslistrc
|
||||
|
||||
last 2 versions
|
||||
> 0.2%
|
||||
not dead
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"body-max-line-length": [
|
||||
0,
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
2
.github/codeql/codeql-config.yml
vendored
Normal file
2
.github/codeql/codeql-config.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
paths-ignore:
|
||||
- "assets/js"
|
||||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
ruby: [2.7, 3]
|
||||
ruby: ["3.0", "3.1", "3.2"]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
bundler-cache: true
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
|
||||
- name: Build Assets
|
||||
run: npm i && npm run build
|
||||
|
||||
13
.github/workflows/codeql.yml
vendored
13
.github/workflows/codeql.yml
vendored
@@ -2,11 +2,9 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: ["**.js"]
|
||||
paths: ["_javascript/**/*.js"]
|
||||
pull_request:
|
||||
paths: ["**.js"]
|
||||
schedule:
|
||||
- cron: "0 0 * * 5"
|
||||
paths: ["_javascript/**/*.js"]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
@@ -29,16 +27,17 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: "${{ matrix.language }}"
|
||||
config-file: .github/codeql/codeql-config.yml
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
||||
8
.github/workflows/pages-deploy.yml.hook
vendored
8
.github/workflows/pages-deploy.yml.hook
vendored
@@ -37,12 +37,12 @@ jobs:
|
||||
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v3
|
||||
uses: actions/configure-pages@v4
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3
|
||||
ruby-version: 3.2
|
||||
bundler-cache: true
|
||||
|
||||
- name: Build site
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
|
||||
|
||||
- name: Upload site artifact
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: "_site${{ steps.pages.outputs.base_path }}"
|
||||
|
||||
@@ -70,4 +70,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
32
.github/workflows/stale.yml
vendored
32
.github/workflows/stale.yml
vendored
@@ -8,23 +8,25 @@ permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
STALE_LABEL: stale
|
||||
EXEMPT_LABELS: "pending,planning,in progress"
|
||||
MESSAGE: >
|
||||
This conversation has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs.
|
||||
Thank you for your contributions.
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
days-before-stale: 30
|
||||
days-before-close: 1
|
||||
stale-issue-label: stale
|
||||
exempt-issue-labels: pending
|
||||
stale-issue-message: >
|
||||
This issue has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs.
|
||||
Thank you for your contributions.
|
||||
stale-pr-label: stale
|
||||
exempt-pr-labels: pending
|
||||
stale-pr-message: >
|
||||
This PR has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs.
|
||||
Thank you for your contributions.
|
||||
# 60 days before marking issues/PRs stale
|
||||
days-before-close: -1 # does not close automatically
|
||||
stale-issue-label: ${{ env.STALE_LABEL }}
|
||||
exempt-issue-labels: ${{ env.EXEMPT_LABELS }}
|
||||
stale-issue-message: ${{ env.MESSAGE }}
|
||||
stale-pr-label: ${{ env.STALE_LABEL }}
|
||||
exempt-pr-labels: ${{ env.EXEMPT_LABELS }}
|
||||
stale-pr-message: ${{ env.MESSAGE }}
|
||||
|
||||
2
.github/workflows/style-lint.yml
vendored
2
.github/workflows/style-lint.yml
vendored
@@ -20,6 +20,6 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
- run: npm i
|
||||
- run: npm test
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,7 +16,6 @@ package-lock.json
|
||||
|
||||
# IDE configurations
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Misc
|
||||
assets/js/dist
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no -- commitlint -x $(npm root -g)/@commitlint/config-conventional --edit
|
||||
npx --no -- commitlint --edit ${1}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"trailingComma": "none"
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"extends": "stylelint-config-standard-scss",
|
||||
"rules": {
|
||||
"no-descending-specificity": null,
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"at-rule-no-vendor-prefix": null,
|
||||
"property-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"value-no-vendor-prefix": null,
|
||||
"color-function-notation": "legacy",
|
||||
"alpha-value-notation": "number",
|
||||
"selector-not-notation": "simple",
|
||||
"color-hex-length": "long",
|
||||
"declaration-block-single-line-max-declarations": 3,
|
||||
"scss/operator-no-newline-after": null,
|
||||
"rule-empty-line-before": [
|
||||
"always",
|
||||
{ "ignore": ["after-comment", "first-nested"] }
|
||||
],
|
||||
"value-keyword-case": ["lower", { "ignoreProperties": ["/^\\$/"] }],
|
||||
"media-feature-range-notation": "prefix"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"skip": {
|
||||
"commit": true,
|
||||
"tag": true
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"type": "feat",
|
||||
"section": "Features"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"section": "Bug Fixes"
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"section": "Improvements"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
.vscode/extensions.json
vendored
Normal file
12
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"recommendations": [
|
||||
// Liquid tags auto-complete
|
||||
"killalau.vscode-liquid-snippets",
|
||||
// Liquid syntax highlighting and formatting
|
||||
"Shopify.theme-check-vscode",
|
||||
// Common formatter
|
||||
"esbenp.prettier-vscode",
|
||||
"foxundermoon.shell-format",
|
||||
"stylelint.vscode-stylelint"
|
||||
]
|
||||
}
|
||||
24
.vscode/settings.json
vendored
Normal file
24
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
// Prettier
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"prettier.trailingComma": "none",
|
||||
// Shopify Liquid
|
||||
"files.associations": {
|
||||
"*.html": "liquid"
|
||||
},
|
||||
// Formatter
|
||||
"[html][liquid]": {
|
||||
"editor.defaultFormatter": "Shopify.theme-check-vscode"
|
||||
},
|
||||
"[shellscript]": {
|
||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||
},
|
||||
// Disable vscode built-in stylelint
|
||||
"css.validate": false,
|
||||
"scss.validate": false,
|
||||
"less.validate": false,
|
||||
// Stylint extension settings
|
||||
"stylelint.snippet": ["css", "less", "postcss", "scss"],
|
||||
"stylelint.validate": ["css", "less", "postcss", "scss"]
|
||||
}
|
||||
37
README.md
37
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
# Chirpy Jekyll Theme
|
||||
|
||||
A minimal, responsive and feature-rich Jekyll theme for technical writing.
|
||||
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
|
||||
|
||||
[][gem]
|
||||
[][ci]
|
||||
@@ -10,7 +10,7 @@
|
||||
[][license]
|
||||
[](https://996.icu)
|
||||
|
||||
[**Live Demo →**][demo]
|
||||
[**Live Demo** →][demo]
|
||||
|
||||
[][demo]
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
## Features
|
||||
|
||||
<details>
|
||||
<summary>Click to expand/close details</summary>
|
||||
|
||||
|
||||
- Dark / Light Theme Mode
|
||||
- Localized UI language
|
||||
- Pinned Posts on Home Page
|
||||
@@ -38,11 +34,9 @@
|
||||
- Built-in Search
|
||||
- Atom Feeds
|
||||
- PWA
|
||||
- Google Analytics
|
||||
- Google Analytics / GoatCounter
|
||||
- SEO & Performance Optimization
|
||||
|
||||
</details>
|
||||
|
||||
## Documentation
|
||||
|
||||
To learn how to use, develop, and upgrade the project, please refer to the [Wiki][wiki].
|
||||
@@ -55,22 +49,18 @@ For details, see the "[Contributing Guidelines][contribute-guide]".
|
||||
|
||||
## Credits
|
||||
|
||||
This project is mainly built with [Jekyll][jekyllrb] ecosystem,
|
||||
[Bootstrap][bootstrap], [Font Awesome][icons], and some other [wonderful tools][lib].
|
||||
The avatar and favicon design come from [Clipart Max][image].
|
||||
### Contributors
|
||||
|
||||
Many thanks to the [contributors][contributors] who participated in the development
|
||||
and to the folks who reported bugs or shared ideas.
|
||||
Thanks to [all the contributors][contributors] involved in the development of the project!
|
||||
|
||||
Last but not least, thanks to [JetBrains][jetbrains] for providing the _Open Source License_.
|
||||
[][contributors]
|
||||
<sub> —— Made with [contrib.rocks](https://contrib.rocks)</sub>
|
||||
|
||||
## Sponsoring
|
||||
### Third-Party Assets
|
||||
|
||||
If you like this project or have built something through it, please consider sponsoring it, and your support would be greatly appreciated.
|
||||
This project is built on the [Jekyll][jekyllrb] ecosystem and some [great libraries][lib], and is developed using [VS Code][vscode] as well as tools provided by [JetBrains][jetbrains] under a non-commercial open-source software license.
|
||||
|
||||
[][ko-fi]
|
||||
[][donation]
|
||||
[][donation]
|
||||
The avatar and favicon for the project's website are from [ClipartMAX][clipartmax].
|
||||
|
||||
## License
|
||||
|
||||
@@ -81,14 +71,11 @@ This project is published under [MIT License][license].
|
||||
[codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
|
||||
[license]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE
|
||||
[jekyllrb]: https://jekyllrb.com/
|
||||
[bootstrap]: https://getbootstrap.com/
|
||||
[icons]: https://fontawesome.com/
|
||||
[image]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
|
||||
[clipartmax]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
|
||||
[demo]: https://cotes2020.github.io/chirpy-demo/
|
||||
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
|
||||
[contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md
|
||||
[contributors]: https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors
|
||||
[lib]: https://github.com/cotes2020/chirpy-static-assets
|
||||
[vscode]: https://code.visualstudio.com/
|
||||
[jetbrains]: https://www.jetbrains.com/?from=jekyll-theme-chirpy
|
||||
[ko-fi]: https://ko-fi.com/coteschung/
|
||||
[donation]: https://sponsor.cotes.page/
|
||||
|
||||
24
_config.yml
24
_config.yml
@@ -52,6 +52,9 @@ google_site_verification: # fill in to your verification string
|
||||
google_analytics:
|
||||
id: # fill in your Google Analytics ID
|
||||
|
||||
goatcounter:
|
||||
id: # fill in your Goatcounter ID
|
||||
|
||||
# Prefer color scheme setting.
|
||||
#
|
||||
# Note: Keep empty will follow the system prefer color by default,
|
||||
@@ -63,7 +66,7 @@ google_analytics:
|
||||
# light - Use the light color scheme
|
||||
# dark - Use the dark color scheme
|
||||
#
|
||||
theme_mode: # [light|dark]
|
||||
theme_mode: # [light | dark]
|
||||
|
||||
# The CDN endpoint for images.
|
||||
# Notice that once it is assigned, the CDN url
|
||||
@@ -75,6 +78,10 @@ img_cdn: "https://chirpy-img.netlify.app"
|
||||
# the avatar on sidebar, support local or CORS resources
|
||||
avatar: "/commons/avatar.jpg"
|
||||
|
||||
# The URL of the site-wide social preview image used in SEO `og:image` meta tag.
|
||||
# It can be overridden by a customized `page.image` in front matter.
|
||||
social_preview_image: # string, local or CORS resources
|
||||
|
||||
# boolean type, the global switch for TOC in posts.
|
||||
toc: true
|
||||
|
||||
@@ -104,10 +111,17 @@ assets:
|
||||
enabled: # boolean, keep empty means false
|
||||
# specify the Jekyll environment, empty means both
|
||||
# only works if `assets.self_host.enabled` is 'true'
|
||||
env: # [development|production]
|
||||
env: # [development | production]
|
||||
|
||||
pwa:
|
||||
enabled: true # the option for PWA feature
|
||||
enabled: true # the option for PWA feature (installable)
|
||||
cache:
|
||||
enabled: true # the option for PWA offline cache
|
||||
# Paths defined here will be excluded from the PWA cache.
|
||||
# Usually its value is the `baseurl` of another website that
|
||||
# shares the same domain name as the current website.
|
||||
deny_paths:
|
||||
# - "/example" # URLs match `<SITE_URL>/example/*` will not be cached by the PWA
|
||||
|
||||
paginate: 10
|
||||
|
||||
@@ -153,10 +167,6 @@ defaults:
|
||||
values:
|
||||
layout: page
|
||||
permalink: /:title/
|
||||
- scope:
|
||||
path: assets/img/favicons
|
||||
values:
|
||||
swcache: true
|
||||
- scope:
|
||||
path: assets/js/dist
|
||||
values:
|
||||
|
||||
@@ -40,7 +40,7 @@ copyright:
|
||||
Except where otherwise noted, the blog posts on this site are licensed
|
||||
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.
|
||||
|
||||
meta: Using the :THEME theme for :PLATFORM
|
||||
meta: Using the :THEME theme for :PLATFORM.
|
||||
|
||||
not_found:
|
||||
statment: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
||||
|
||||
@@ -8,6 +8,8 @@ cdns:
|
||||
- url: https://fonts.googleapis.com
|
||||
# jsDelivr CDN
|
||||
- url: https://cdn.jsdelivr.net
|
||||
# polyfill.io for math (cdnjs.cloudflare.com/polyfill)
|
||||
- url: https://cdnjs.cloudflare.com
|
||||
|
||||
# fonts
|
||||
|
||||
@@ -23,17 +25,17 @@ bootstrap:
|
||||
js: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js
|
||||
|
||||
toc:
|
||||
css: https://cdn.jsdelivr.net/npm/tocbot@4.21.2/dist/tocbot.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/tocbot@4.21.2/dist/tocbot.min.js
|
||||
css: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.js
|
||||
|
||||
fontawesome:
|
||||
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.2/css/all.min.css
|
||||
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.1/css/all.min.css
|
||||
|
||||
search:
|
||||
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
|
||||
|
||||
mermaid:
|
||||
js: https://cdn.jsdelivr.net/npm/mermaid@10.5.0/dist/mermaid.min.js
|
||||
js: https://cdn.jsdelivr.net/npm/mermaid@10.8.0/dist/mermaid.min.js
|
||||
|
||||
dayjs:
|
||||
js:
|
||||
|
||||
@@ -23,3 +23,16 @@ platforms:
|
||||
# - type: Weibo
|
||||
# icon: "fab fa-weibo"
|
||||
# link: "http://service.weibo.com/share/share.php?title=TITLE&url=URL"
|
||||
#
|
||||
# - type: Mastodon
|
||||
# icon: "fa-brands fa-mastodon"
|
||||
# # See: https://github.com/justinribeiro/share-to-mastodon#properties
|
||||
# instances:
|
||||
# - label: mastodon.social
|
||||
# link: "https://mastodon.social/"
|
||||
# - label: mastodon.online
|
||||
# link: "https://mastodon.online/"
|
||||
# - label: fosstodon.org
|
||||
# link: "https://fosstodon.org/"
|
||||
# - label: photog.social
|
||||
# link: "https://photog.social/"
|
||||
|
||||
10
_includes/embed/bilibili.html
Normal file
10
_includes/embed/bilibili.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<iframe
|
||||
class="embed-video bilibili"
|
||||
loading="lazy"
|
||||
src="https://player.bilibili.com/player.html?bvid={{ include.id }}"
|
||||
scrolling="no"
|
||||
border="0"
|
||||
frameborder="no"
|
||||
framespacing="0"
|
||||
allowfullscreen="true"
|
||||
></iframe>
|
||||
@@ -1,5 +1,6 @@
|
||||
<iframe
|
||||
class="embed-video twitch"
|
||||
loading="lazy"
|
||||
src="https://player.twitch.tv/?video={{ include.id }}&parent={{ site.url | split: '://' | last | remove: '/' }}"
|
||||
frameborder="0"
|
||||
allowfullscreen="true"
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ favicon_path }}/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ favicon_path }}/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ favicon_path }}/favicon-16x16.png">
|
||||
<link rel="manifest" href="{{ favicon_path }}/site.webmanifest">
|
||||
{% if site.pwa.enabled %}
|
||||
<link rel="manifest" href="{{ favicon_path }}/site.webmanifest">
|
||||
{% endif %}
|
||||
<link rel="shortcut icon" href="{{ favicon_path }}/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="{{ site.title }}">
|
||||
<meta name="application-name" content="{{ site.title }}">
|
||||
|
||||
@@ -8,9 +8,15 @@
|
||||
"
|
||||
>
|
||||
<p>
|
||||
{{ '©' }}
|
||||
{{- '©' }}
|
||||
<time>{{ 'now' | date: '%Y' }}</time>
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
|
||||
{% if site.social.links %}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
{% else %}
|
||||
<em class="fst-normal">{{ site.social.name }}</em>.
|
||||
{% endif %}
|
||||
|
||||
{% if site.data.locales[include.lang].copyright.brief %}
|
||||
<span
|
||||
data-bs-toggle="tooltip"
|
||||
|
||||
8
_includes/goatcounter.html
Normal file
8
_includes/goatcounter.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<!-- GoatCounter -->
|
||||
|
||||
<script
|
||||
data-goatcounter="https://{{ site.goatcounter.id }}.goatcounter.com/count"
|
||||
async
|
||||
src="https://gc.zgo.at/count.js"
|
||||
></script>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
<!-- The Head -->
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
|
||||
@@ -11,29 +9,43 @@
|
||||
content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
|
||||
>
|
||||
|
||||
{% capture seo_tags %}
|
||||
{%- capture seo_tags -%}
|
||||
{% seo title=false %}
|
||||
{% endcapture %}
|
||||
{%- endcapture -%}
|
||||
|
||||
<!-- Setup Open Graph image -->
|
||||
|
||||
{% if page.image %}
|
||||
{% assign img = page.image.path | default: page.image %}
|
||||
{% assign src = page.image.path | default: page.image %}
|
||||
|
||||
{% unless img contains '://' %}
|
||||
{% assign img_path = page.img_path | append: '/' | append: img | replace: '//', '/' %}
|
||||
{% capture target %}"{{ img | absolute_url }}"{% endcapture %}
|
||||
{% unless src contains '://' %}
|
||||
{%- capture img_url -%}
|
||||
{% include img-url.html src=src img_path=page.img_path absolute=true %}
|
||||
{%- endcapture -%}
|
||||
|
||||
{% if site.img_cdn contains '//' %}
|
||||
<!-- it's a cross-origin URL -->
|
||||
{% capture replacement %}"{{ site.img_cdn }}{{ img_path }}"{% endcapture %}
|
||||
{% else %}
|
||||
<!-- it's a local file path -->
|
||||
{%- capture replacement -%}
|
||||
"{{ site.img_cdn | append: '/' | append: img_path | replace: '//', '/' | absolute_url }}"
|
||||
{%- endcapture -%}
|
||||
{% endif %}
|
||||
{%- capture old_url -%}{{ src | absolute_url }}{%- endcapture -%}
|
||||
{%- capture new_url -%}{{ img_url }}{%- endcapture -%}
|
||||
|
||||
{% assign seo_tags = seo_tags | replace: target, replacement %}
|
||||
{% assign seo_tags = seo_tags | replace: old_url, new_url %}
|
||||
{% endunless %}
|
||||
|
||||
{% elsif site.social_preview_image %}
|
||||
{%- capture img_url -%}
|
||||
{% include img-url.html src=site.social_preview_image absolute=true %}
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- capture og_image -%}
|
||||
<meta property="og:image" content="{{ img_url }}" />
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- capture twitter_image -%}
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:image" content="{{ img_url }}" />
|
||||
{%- endcapture -%}
|
||||
|
||||
{% assign old_meta_clip = '<meta name="twitter:card" content="summary" />' %}
|
||||
{% assign new_meta_clip = og_image | append: twitter_image %}
|
||||
{% assign seo_tags = seo_tags | replace: old_meta_clip, new_meta_clip %}
|
||||
{% endif %}
|
||||
|
||||
{{ seo_tags }}
|
||||
@@ -69,7 +81,7 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].bootstrap.css | relative_url}}">
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].bootstrap.css | relative_url }}">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].fontawesome.css | relative_url }}">
|
||||
|
||||
41
_includes/img-url.html
Normal file
41
_includes/img-url.html
Normal file
@@ -0,0 +1,41 @@
|
||||
{%- comment -%}
|
||||
Generate image final URL based on `site.img_cdn`, `page.img_path`
|
||||
|
||||
Arguments:
|
||||
src - required, basic image path
|
||||
img_path - optional, relative path of image
|
||||
absolute - optional, boolean, if true, generate absolute URL
|
||||
|
||||
Return:
|
||||
image URL
|
||||
{%- endcomment -%}
|
||||
|
||||
{% assign url = include.src %}
|
||||
|
||||
{%- if url -%}
|
||||
{% unless url contains ':' %}
|
||||
{%- comment -%} Add page image path prefix {%- endcomment -%}
|
||||
{% assign url = include.img_path | default: '' | append: '/' | append: url %}
|
||||
|
||||
{%- comment -%} CND URL {%- endcomment -%}
|
||||
{% if site.img_cdn %}
|
||||
{% assign url = site.img_cdn
|
||||
| append: '/'
|
||||
| append: url
|
||||
| replace: '///', '/'
|
||||
| replace: '//', '/'
|
||||
| replace: ':/', '://'
|
||||
%}
|
||||
|
||||
{% unless site.img_cdn contains ':' %}
|
||||
{% if include.absolute %}
|
||||
{% assign url = site.url | append: site.baseurl | append: url %}
|
||||
{% else %}
|
||||
{% assign url = site.baseurl | append: url %}
|
||||
{% endif %}
|
||||
{% endunless %}
|
||||
{% endif %}
|
||||
{% endunless %}
|
||||
{%- endif -%}
|
||||
|
||||
{{- url -}}
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
<!-- layout specified -->
|
||||
|
||||
{% assign js_dist = '/assets/js/dist/' %}
|
||||
|
||||
{% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %}
|
||||
{% assign urls = urls | append: ',' | append: site.data.origin[type]['lazy-polyfill'].js %}
|
||||
|
||||
@@ -65,7 +67,7 @@
|
||||
{% assign js = 'commons' %}
|
||||
{% endcase %}
|
||||
|
||||
{% capture script %}/assets/js/dist/{{ js }}.min.js{% endcapture %}
|
||||
{% capture script %}{{ js_dist }}{{ js }}.min.js{% endcapture %}
|
||||
<script defer src="{{ script | relative_url }}"></script>
|
||||
|
||||
{% if page.math %}
|
||||
@@ -83,24 +85,29 @@
|
||||
displayMath: [
|
||||
['$$', '$$'],
|
||||
['\\[', '\\]']
|
||||
]
|
||||
],
|
||||
/* equation numbering */
|
||||
tags: 'ams'
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
|
||||
<script id="MathJax-script" async src="{{ site.data.origin[type].mathjax.js | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
<!-- PWA -->
|
||||
{% if site.pwa.enabled %}
|
||||
<script defer src="{{ '/app.js' | relative_url }}"></script>
|
||||
{% else %}
|
||||
<script defer src="{{ '/unregister.js' | relative_url }}"></script>
|
||||
<script defer src="{{ 'app.min.js' | prepend: js_dist | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- GA -->
|
||||
{% if site.google_analytics.id != empty and site.google_analytics.id %}
|
||||
{% include google-analytics.html %}
|
||||
{% endif %}
|
||||
|
||||
<!-- GoatCounter -->
|
||||
{% if site.goatcounter.id != empty and site.goatcounter.id %}
|
||||
{% include goatcounter.html %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
<!-- Post sharing snippet -->
|
||||
|
||||
<div class="share-wrapper d-flex align-items-center">
|
||||
<span class="share-label text-muted me-1">{{ site.data.locales[include.lang].post.share }}</span>
|
||||
<span class="share-label text-muted">{{ site.data.locales[include.lang].post.share }}</span>
|
||||
<span class="share-icons">
|
||||
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
|
||||
{% assign title = title | uri_escape %}
|
||||
{% assign url = page.url | absolute_url | url_encode %}
|
||||
|
||||
{% for share in site.data.share.platforms %}
|
||||
{% for share in site.data.share.platforms -%}
|
||||
{%- capture tooltip -%}
|
||||
data-bs-toggle="tooltip" data-bs-placement="top" title="{{ share.type }}" aria-label="{{ share.type }}"
|
||||
{%- endcapture -%}
|
||||
|
||||
{% if share.type == 'Mastodon' %}
|
||||
<script defer type="module" src="https://cdn.jsdelivr.net/npm/@justinribeiro/share-to-mastodon/+esm"></script>
|
||||
<button class="btn text-start" {{ tooltip }}>
|
||||
<share-to-mastodon
|
||||
class="share-mastodon"
|
||||
message="{{ title }}"
|
||||
url="{{ url }}"
|
||||
{%- if share.instances -%}
|
||||
customInstanceList="{{ share.instances | jsonify | xml_escape }}"
|
||||
{%- endif %}
|
||||
>
|
||||
<i class="fa-fw {{ share.icon }}"></i>
|
||||
</share-to-mastodon>
|
||||
</button>
|
||||
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url %}
|
||||
<a
|
||||
href="{{ link }}"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ share.type }}"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label="{{ share.type }}"
|
||||
>
|
||||
|
||||
<a href="{{ link }}" target="_blank" rel="noopener" {{ tooltip }}>
|
||||
<i class="fa-fw {{ share.icon }}"></i>
|
||||
</a>
|
||||
{% endfor %}
|
||||
@@ -31,7 +46,7 @@
|
||||
title="{{ site.data.locales[include.lang].post.button.share_link.title }}"
|
||||
data-title-succeed="{{ site.data.locales[include.lang].post.button.share_link.succeed }}"
|
||||
>
|
||||
<i class="fa-fw fas fa-link pe-none"></i>
|
||||
<i class="fa-fw fas fa-link pe-none fs-6"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -48,23 +48,6 @@
|
||||
{% assign _img_content = null %}
|
||||
{% assign _img_snippets = _content | split: IMG_TAG %}
|
||||
|
||||
<!-- CDN URL -->
|
||||
{% if site.img_cdn %}
|
||||
{% if site.img_cdn contains '//' %}
|
||||
{% assign _path_prefix = site.img_cdn %}
|
||||
{% else %}
|
||||
{% assign _path_prefix = site.img_cdn | relative_url %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% assign _path_prefix = site.baseurl %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Add image path -->
|
||||
{% if page.img_path %}
|
||||
{% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
|
||||
{% assign _path_prefix = _path_prefix | append: _path %}
|
||||
{% endif %}
|
||||
|
||||
{% for _img_snippet in _img_snippets %}
|
||||
{% if forloop.first %}
|
||||
{% assign _img_content = _img_snippet %}
|
||||
@@ -113,6 +96,12 @@
|
||||
{% assign _final_src = null %}
|
||||
{% assign _lazyload = true %}
|
||||
|
||||
{%- capture _img_url -%}
|
||||
{% include img-url.html src=_src img_path=page.img_path %}
|
||||
{%- endcapture -%}
|
||||
|
||||
{% assign _path_prefix = _img_url | remove: _src %}
|
||||
|
||||
{% unless _src contains '//' %}
|
||||
{% assign _final_src = _path_prefix | append: _src %}
|
||||
{% assign _src_alt = 'src="' | append: _path_prefix %}
|
||||
|
||||
@@ -3,18 +3,12 @@
|
||||
<aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end">
|
||||
<header class="profile-wrapper">
|
||||
<a href="{{ '/' | relative_url }}" id="avatar" class="rounded-circle">
|
||||
{% if site.avatar != empty and site.avatar %}
|
||||
{% capture avatar_url %}
|
||||
{% if site.avatar contains '://' %}
|
||||
{{ site.avatar }}
|
||||
{% elsif site.img_cdn != empty and site.img_cdn %}
|
||||
{{ site.avatar | prepend: site.img_cdn }}
|
||||
{% else %}
|
||||
{{ site.avatar | relative_url }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
<img src="{{ avatar_url | strip }}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
||||
{% endif %}
|
||||
{%- if site.avatar != empty and site.avatar -%}
|
||||
{%- capture avatar_url -%}
|
||||
{% include img-url.html src=site.avatar %}
|
||||
{%- endcapture -%}
|
||||
<img src="{{- avatar_url -}}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
||||
{%- endif -%}
|
||||
</a>
|
||||
|
||||
<h1 class="site-title">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{% if forloop.first %}
|
||||
<span>
|
||||
<a href="{{ '/' | relative_url }}">
|
||||
{{ site.data.locales[include.lang].tabs.home | capitalize }}
|
||||
{{- site.data.locales[include.lang].tabs.home | capitalize -}}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
{% elsif page.layout == 'category' or page.layout == 'tag' %}
|
||||
<span>
|
||||
<a href="{{ item | relative_url }}">
|
||||
{{ site.data.locales[include.lang].tabs[item] | default: page.title }}
|
||||
<a href="{{ item | append: '/' | relative_url }}">
|
||||
{{- site.data.locales[include.lang].tabs[item] | default: page.title -}}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<!-- Get the last 5 posts from lastmod list. -->
|
||||
<!-- Get 5 last posted/updated posts -->
|
||||
|
||||
{% assign MAX_SIZE = 5 %}
|
||||
|
||||
{% assign all_list = '' | split: '' %}
|
||||
|
||||
{% for post in site.posts %}
|
||||
{% if post.last_modified_at and post.last_modified_at != post.date %}
|
||||
{% capture elem %}
|
||||
{{- post.last_modified_at | date: "%Y%m%d%H%M%S" -}}::{{- forloop.index0 -}}
|
||||
{% endcapture %}
|
||||
{% assign all_list = all_list | push: elem %}
|
||||
{% endif %}
|
||||
{% assign datetime = post.last_modified_at | default: post.date %}
|
||||
|
||||
{% capture elem %}
|
||||
{{- datetime | date: "%Y%m%d%H%M%S" -}}::{{- forloop.index0 -}}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign all_list = all_list | push: elem %}
|
||||
{% endfor %}
|
||||
|
||||
{% assign all_list = all_list | sort | reverse %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export function toc() {
|
||||
if (document.querySelector('main h2')) {
|
||||
if (document.querySelector('main h2, main h3')) {
|
||||
// see: https://github.com/tscanlin/tocbot#usage
|
||||
tocbot.init({
|
||||
tocSelector: '#toc',
|
||||
|
||||
@@ -61,7 +61,11 @@ tail_includes:
|
||||
<em>
|
||||
{% if authors %}
|
||||
{% for author in authors %}
|
||||
<a href="{{ site.data.authors[author].url }}">{{ site.data.authors[author].name }}</a>
|
||||
{% if site.data.authors[author].url -%}
|
||||
<a href="{{ site.data.authors[author].url }}">{{ site.data.authors[author].name }}</a>
|
||||
{%- else -%}
|
||||
{{ site.data.authors[author].name }}
|
||||
{%- endif %}
|
||||
{% unless forloop.last %}{{ '</em>, <em>' }}{% endunless %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
|
||||
@@ -134,7 +134,14 @@ fi;
|
||||
|
||||
The mathematics powered by [**MathJax**](https://www.mathjax.org/):
|
||||
|
||||
$$ \sum_{n=1}^\infty 1/n^2 = \frac{\pi^2}{6} $$
|
||||
$$
|
||||
\begin{equation}
|
||||
\sum_{n=1}^\infty 1/n^2 = \frac{\pi^2}{6}
|
||||
\label{eq:series}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
We can reference the equation as \eqref{eq:series}.
|
||||
|
||||
When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$ and they are
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ authors: [<author1_id>, <author2_id>] # for multiple entries
|
||||
---
|
||||
```
|
||||
|
||||
|
||||
Having said that, the key `author` can also identify multiple entries.
|
||||
|
||||
> The benefit of reading the author information from the file `_data/authors.yml`{: .filepath } is that the page will have the meta tag `twitter:creator`, which enriches the [Twitter Cards](https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started#card-and-content-attribution) and is good for SEO.
|
||||
@@ -110,6 +109,8 @@ math: true
|
||||
After enabling the mathematical feature, you can add math equations with the following syntax:
|
||||
|
||||
- **Block math** should be added with `$$ math $$` with **mandatory** blank lines before and after `$$`
|
||||
- **Inserting equation numbering** should be added with `$$\begin{equation} math \end{equation}$$`
|
||||
- **Referencing equation numbering** should be done with `\label{eq:label_name}` in the equation block and `\eqref{eq:label_name}` inline with text (see example below)
|
||||
- **Inline math** (in lines) should be added with `$$ math $$` without any blank line before or after `$$`
|
||||
- **Inline math** (in lists) should be added with `\$$ math $$`
|
||||
|
||||
@@ -120,6 +121,17 @@ $$
|
||||
LaTeX_math_expression
|
||||
$$
|
||||
|
||||
<!-- Equation numbering, keep all blank lines -->
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
LaTeX_math_expression
|
||||
\label{eq:label_name}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
Can be referenced as \eqref{eq:label_name}.
|
||||
|
||||
<!-- Inline math in lines, NO blank lines -->
|
||||
|
||||
"Lorem ipsum dolor sit amet, $$ LaTeX_math_expression $$ consectetur adipiscing elit."
|
||||
@@ -243,7 +255,7 @@ For instance, when using images:
|
||||
The parsing result will automatically add the CDN prefix `https://cdn.com` before the image path:
|
||||
|
||||
```html
|
||||
<img src="https://cdn.com/path/to/flower.png" alt="The flower">
|
||||
<img src="https://cdn.com/path/to/flower.png" alt="The flower" />
|
||||
```
|
||||
{: .nolineno }
|
||||
|
||||
@@ -267,7 +279,7 @@ And then, the image source of Markdown can write the file name directly:
|
||||
The output will be:
|
||||
|
||||
```html
|
||||
<img src="/img/path/flower.png" alt="The flower">
|
||||
<img src="/img/path/flower.png" alt="The flower" />
|
||||
```
|
||||
{: .nolineno }
|
||||
|
||||
@@ -285,7 +297,7 @@ image:
|
||||
---
|
||||
```
|
||||
|
||||
Note that the [`img_path`](#image-path) can also be passed to the preview image, that is, when it has been set, the attribute `path` only needs the image file name.
|
||||
Note that the [`img_path`](#image-path) can also be passed to the preview image, that is, when it has been set, the attribute `path` only needs the image file name.
|
||||
|
||||
For simple use, you can also just use `image` to define the path.
|
||||
|
||||
@@ -420,16 +432,16 @@ You can embed a video with the following syntax:
|
||||
```liquid
|
||||
{% include embed/{Platform}.html id='{ID}' %}
|
||||
```
|
||||
|
||||
Where `Platform` is the lowercase of the platform name, and `ID` is the video ID.
|
||||
|
||||
The following table shows how to get the two parameters we need in a given video URL, and you can also know the currently supported video platforms.
|
||||
|
||||
| Video URL | Platform | ID |
|
||||
|----------------------------------------------------------------------------------------------------|-----------|:--------------|
|
||||
| [https://www.**youtube**.com/watch?v=**H-B46URT4mg**](https://www.youtube.com/watch?v=H-B46URT4mg) | `youtube` | `H-B46URT4mg` |
|
||||
| [https://www.**twitch**.tv/videos/**1634779211**](https://www.twitch.tv/videos/1634779211) | `twitch` | `1634779211` |
|
||||
|
||||
|
||||
| Video URL | Platform | ID |
|
||||
| -------------------------------------------------------------------------------------------------- | ---------- | :------------- |
|
||||
| [https://www.**youtube**.com/watch?v=**H-B46URT4mg**](https://www.youtube.com/watch?v=H-B46URT4mg) | `youtube` | `H-B46URT4mg` |
|
||||
| [https://www.**twitch**.tv/videos/**1634779211**](https://www.twitch.tv/videos/1634779211) | `twitch` | `1634779211` |
|
||||
| [https://www.**bilibili**.com/video/**BV1Q44y1B7Wf**](https://www.bilibili.com/video/BV1Q44y1B7Wf) | `bilibili` | `BV1Q44y1B7Wf` |
|
||||
|
||||
## Learn More
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ Now you can choose _ONE_ of the following methods to deploy your Jekyll site.
|
||||
There are a few things to get ready for.
|
||||
|
||||
- If you're on the GitHub Free plan, keep your site repository public.
|
||||
- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, go the the root of your site and update the platform list of the lock-file:
|
||||
- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, go to the root of your site and update the platform list of the lock-file:
|
||||
|
||||
```console
|
||||
$ bundle lock --add-platform x86_64-linux
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
The common styles
|
||||
*/
|
||||
/* The common styles */
|
||||
|
||||
html {
|
||||
@media (prefers-color-scheme: light) {
|
||||
@@ -86,6 +84,10 @@ blockquote {
|
||||
padding-left: 1rem;
|
||||
color: var(--blockquote-text-color);
|
||||
|
||||
> p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&[class^='prompt-'] {
|
||||
border-left: 0;
|
||||
position: relative;
|
||||
@@ -103,10 +105,6 @@ blockquote {
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
> p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include prompt('tip', '\f0eb', 'regular');
|
||||
@@ -146,6 +144,10 @@ footer {
|
||||
}
|
||||
}
|
||||
|
||||
em {
|
||||
@extend %text-highlight;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
@@ -324,6 +326,10 @@ sup {
|
||||
object-fit: cover;
|
||||
|
||||
@extend %rounded;
|
||||
|
||||
@at-root #post-list & {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,7 +553,8 @@ main {
|
||||
|
||||
@extend %rounded;
|
||||
|
||||
&.youtube {
|
||||
&.youtube,
|
||||
&.bilibili {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
@@ -636,12 +643,12 @@ main {
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
margin: 0.75rem 1rem 1rem 0 !important;
|
||||
margin: 0.75rem 1rem 1rem 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
margin: 0.75rem 0 1rem 1rem !important;
|
||||
margin: 0.75rem 0 1rem 1rem;
|
||||
}
|
||||
|
||||
/* --- Overriding --- */
|
||||
|
||||
@@ -63,7 +63,8 @@
|
||||
|
||||
/* Posts */
|
||||
--toc-highlight: #0550ae;
|
||||
--btn-share-hover-color: var(--link-color);
|
||||
--btn-share-color: gray;
|
||||
--btn-share-hover-color: #0d6efd;
|
||||
--card-bg: white;
|
||||
--card-hovor-bg: #e2e2e2;
|
||||
--card-shadow: rgb(104, 104, 104, 0.05) 0 2px 6px 0,
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
Post-specific style
|
||||
*/
|
||||
|
||||
@mixin btn-sharing-color($light-color, $important: false) {
|
||||
@if $important {
|
||||
color: var(--btn-share-color, $light-color) !important;
|
||||
} @else {
|
||||
color: var(--btn-share-color, $light-color);
|
||||
}
|
||||
}
|
||||
|
||||
%btn-post-nav {
|
||||
width: 50%;
|
||||
position: relative;
|
||||
@@ -72,11 +64,23 @@ h1 + .post-meta {
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
%icon-size {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.share-icons {
|
||||
font-size: 1.2rem;
|
||||
display: flex;
|
||||
|
||||
i {
|
||||
color: var(--btn-share-color);
|
||||
|
||||
@extend %icon-size;
|
||||
}
|
||||
|
||||
> * {
|
||||
margin-left: 0.25rem;
|
||||
@extend %icon-size;
|
||||
|
||||
margin-left: 0.5rem;
|
||||
|
||||
&:hover {
|
||||
i {
|
||||
@@ -86,44 +90,29 @@ h1 + .post-meta {
|
||||
}
|
||||
|
||||
button {
|
||||
position: relative;
|
||||
bottom: 2px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
line-height: inherit;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
}
|
||||
|
||||
a :hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fa-square-x-twitter {
|
||||
@include btn-sharing-color(black);
|
||||
}
|
||||
|
||||
.fa-facebook-square {
|
||||
@include btn-sharing-color(rgb(66, 95, 156));
|
||||
}
|
||||
|
||||
.fa-telegram {
|
||||
@include btn-sharing-color(rgb(39, 159, 217));
|
||||
}
|
||||
|
||||
.fa-linkedin {
|
||||
@include btn-sharing-color(rgb(0, 119, 181));
|
||||
}
|
||||
|
||||
.fa-weibo {
|
||||
@include btn-sharing-color(rgb(229, 20, 43));
|
||||
}
|
||||
} /* .share-icons */
|
||||
|
||||
.fas.fa-link {
|
||||
@include btn-sharing-color(rgb(171, 171, 171));
|
||||
}
|
||||
} /* .share-wrapper */
|
||||
}
|
||||
|
||||
.share-mastodon {
|
||||
/* See: https://github.com/justinribeiro/share-to-mastodon#properties */
|
||||
--wc-stm-font-family: $font-family-base;
|
||||
--wc-stm-dialog-background-color: var(--card-bg);
|
||||
--wc-stm-form-button-border: 1px solid var(--btn-border-color);
|
||||
--wc-stm-form-submit-background-color: var(--sidebar-btn-bg);
|
||||
--wc-stm-form-cancel-background-color: var(--sidebar-btn-bg);
|
||||
--wc-stm-form-button-background-color-hover: #007bff;
|
||||
--wc-stm-form-button-color-hover: white;
|
||||
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.post-tags {
|
||||
line-height: 2rem;
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
layout: compress
|
||||
# The list to be cached by PWA
|
||||
---
|
||||
|
||||
const resource = [
|
||||
/* --- CSS --- */
|
||||
'{{ "/assets/css/:THEME.css" | replace: ':THEME', site.theme | relative_url }}',
|
||||
|
||||
/* --- PWA --- */
|
||||
'{{ "/app.js" | relative_url }}',
|
||||
'{{ "/sw.js" | relative_url }}',
|
||||
|
||||
/* --- HTML --- */
|
||||
'{{ "/index.html" | relative_url }}',
|
||||
'{{ "/404.html" | relative_url }}',
|
||||
|
||||
{% for tab in site.tabs %}
|
||||
'{{ tab.url | relative_url }}',
|
||||
{% endfor %}
|
||||
|
||||
/* --- Favicons & compressed JS --- */
|
||||
{% assign cache_list = site.static_files | where: 'swcache', true %}
|
||||
{% for file in cache_list %}
|
||||
'{{ file.path | relative_url }}'{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
];
|
||||
|
||||
/* The request url with below domain will be cached */
|
||||
const allowedDomains = [
|
||||
{% if site.google_analytics.id != empty and site.google_analytics.id %}
|
||||
'www.googletagmanager.com',
|
||||
'www.google-analytics.com',
|
||||
{% endif %}
|
||||
|
||||
'{{ site.url | split: "//" | last }}',
|
||||
|
||||
{% if site.img_cdn contains '//' and site.img_cdn %}
|
||||
'{{ site.img_cdn | split: '//' | last | split: '/' | first }}',
|
||||
{% endif %}
|
||||
|
||||
'fonts.gstatic.com',
|
||||
'fonts.googleapis.com',
|
||||
'cdn.jsdelivr.net',
|
||||
'polyfill.io'
|
||||
];
|
||||
|
||||
/* Requests that include the following path will be banned */
|
||||
const denyUrls = [];
|
||||
51
assets/js/data/swconf.js
Normal file
51
assets/js/data/swconf.js
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
layout: compress
|
||||
permalink: '/:path/swconf.js'
|
||||
# Note that this file will be fetched by the ServiceWorker, so it will not be cached.
|
||||
---
|
||||
|
||||
const swconf = {
|
||||
{% if site.pwa.cache.enabled %}
|
||||
cacheName: 'chirpy-{{ "now" | date: "%s" }}',
|
||||
|
||||
{%- comment -%} Resources added to the cache during PWA installation. {%- endcomment -%}
|
||||
resources: [
|
||||
'{{ "/assets/css/:THEME.css" | replace: ':THEME', site.theme | relative_url }}',
|
||||
'{{ "/" | relative_url }}',
|
||||
{% for tab in site.tabs %}
|
||||
'{{- tab.url | relative_url -}}',
|
||||
{% endfor %}
|
||||
|
||||
{% assign cache_list = site.static_files | where: 'swcache', true %}
|
||||
{% for file in cache_list %}
|
||||
'{{ file.path | relative_url }}'{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
],
|
||||
|
||||
{%- comment -%} The request url with below domain will be cached. {%- endcomment -%}
|
||||
allowHosts: [
|
||||
{% if site.img_cdn and site.img_cdn contains '//' %}
|
||||
'{{ site.img_cdn | split: '//' | last | split: '/' | first }}',
|
||||
{% endif %}
|
||||
|
||||
{%- unless site.assets.self_host.enabled -%}
|
||||
{% for cdn in site.data.origin["cors"].cdns %}
|
||||
'{{ cdn.url | split: "//" | last }}'
|
||||
{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
{% endunless %}
|
||||
],
|
||||
|
||||
{%- comment -%} The request url with below path will not be cached. {%- endcomment -%}
|
||||
denyPaths: [
|
||||
{% for path in site.pwa.cache.deny_paths %}
|
||||
{% unless path == empty %}
|
||||
'{{ path | relative_url }}'{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endunless %}
|
||||
{% endfor %}
|
||||
],
|
||||
purge: false
|
||||
{% else %}
|
||||
purge: true
|
||||
{% endif %}
|
||||
};
|
||||
@@ -1,47 +1,54 @@
|
||||
---
|
||||
layout: compress
|
||||
permalink: '/app.js'
|
||||
permalink: /assets/js/dist/:basename.min.js
|
||||
---
|
||||
|
||||
const $notification = $('#notification');
|
||||
const $btnRefresh = $('#notification .toast-body>button');
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
/* Registering Service Worker */
|
||||
navigator.serviceWorker.register('{{ "/sw.js" | relative_url }}')
|
||||
.then(registration => {
|
||||
const isEnabled = '{{ site.pwa.enabled }}' === 'true';
|
||||
|
||||
/* in case the user ignores the notification */
|
||||
if (registration.waiting) {
|
||||
$notification.toast('show');
|
||||
if (isEnabled) {
|
||||
const swUrl = '{{ '/sw.min.js' | relative_url }}';
|
||||
const $notification = $('#notification');
|
||||
const $btnRefresh = $('#notification .toast-body>button');
|
||||
|
||||
navigator.serviceWorker.register(swUrl).then((registration) => {
|
||||
{% comment %}In case the user ignores the notification{% endcomment %}
|
||||
if (registration.waiting) {
|
||||
$notification.toast('show');
|
||||
}
|
||||
|
||||
registration.addEventListener('updatefound', () => {
|
||||
registration.installing.addEventListener('statechange', () => {
|
||||
if (registration.waiting) {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
$notification.toast('show');
|
||||
}
|
||||
|
||||
registration.addEventListener('updatefound', () => {
|
||||
registration.installing.addEventListener('statechange', () => {
|
||||
if (registration.waiting) {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
$notification.toast('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$btnRefresh.click(() => {
|
||||
if (registration.waiting) {
|
||||
registration.waiting.postMessage('SKIP_WAITING');
|
||||
}
|
||||
$notification.toast('hide');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$btnRefresh.on('click', () => {
|
||||
if (registration.waiting) {
|
||||
registration.waiting.postMessage('SKIP_WAITING');
|
||||
}
|
||||
$notification.toast('hide');
|
||||
});
|
||||
});
|
||||
|
||||
let refreshing = false;
|
||||
|
||||
/* Detect controller change and refresh all the opened tabs */
|
||||
{% comment %}Detect controller change and refresh all the opened tabs{% endcomment %}
|
||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||
if (!refreshing) {
|
||||
window.location.reload();
|
||||
refreshing = true;
|
||||
}
|
||||
if (!refreshing) {
|
||||
window.location.reload();
|
||||
refreshing = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
navigator.serviceWorker.getRegistrations().then(function (registrations) {
|
||||
for (let registration of registrations) {
|
||||
registration.unregister();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,51 @@
|
||||
---
|
||||
layout: compress
|
||||
permalink: '/sw.js'
|
||||
permalink: /:basename.min.js
|
||||
# PWA service worker
|
||||
---
|
||||
|
||||
self.importScripts('{{ "/assets/js/data/swcache.js" | relative_url }}');
|
||||
const swconfUrl = '{{ '/assets/js/data/swconf.js' | relative_url }}';
|
||||
|
||||
const cacheName = 'chirpy-{{ "now" | date: "%s" }}';
|
||||
importScripts(swconfUrl);
|
||||
const purge = swconf.purge;
|
||||
|
||||
function verifyDomain(url) {
|
||||
for (const domain of allowedDomains) {
|
||||
const regex = RegExp(`^http(s)?:\/\/${domain}\/`);
|
||||
function verifyHost(url) {
|
||||
for (const host of swconf.allowHosts) {
|
||||
const regex = RegExp(`^http(s)?://${host}/`);
|
||||
if (regex.test(url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isExcluded(url) {
|
||||
for (const item of denyUrls) {
|
||||
if (url === item) {
|
||||
return true;
|
||||
function verifyUrl(url) {
|
||||
if (!verifyHost(url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const requestPath = new URL(url).pathname;
|
||||
|
||||
for (const path of swconf.denyPaths) {
|
||||
if (requestPath.startsWith(path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!purge) {
|
||||
swconf.allowHosts.push(location.host);
|
||||
}
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
if (purge) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.waitUntil(
|
||||
caches.open(cacheName).then((cache) => {
|
||||
return cache.addAll(resource);
|
||||
caches.open(swconf.cacheName).then((cache) => {
|
||||
return cache.addAll(swconf.resources);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -41,8 +55,12 @@ self.addEventListener('activate', (event) => {
|
||||
caches.keys().then((keyList) => {
|
||||
return Promise.all(
|
||||
keyList.map((key) => {
|
||||
if (key !== cacheName) {
|
||||
if (purge) {
|
||||
return caches.delete(key);
|
||||
} else {
|
||||
if (key !== swconf.cacheName) {
|
||||
return caches.delete(key);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -66,22 +84,16 @@ self.addEventListener('fetch', (event) => {
|
||||
return fetch(event.request).then((response) => {
|
||||
const url = event.request.url;
|
||||
|
||||
if (
|
||||
event.request.method !== 'GET' ||
|
||||
!verifyDomain(url) ||
|
||||
isExcluded(url)
|
||||
) {
|
||||
if (purge || event.request.method !== 'GET' || !verifyUrl(url)) {
|
||||
return response;
|
||||
}
|
||||
|
||||
/* see: <https://developers.google.com/web/fundamentals/primers/service-workers#cache_and_return_requests> */
|
||||
{% comment %}See: <https://developers.google.com/web/fundamentals/primers/service-workers#cache_and_return_requests>{% endcomment %}
|
||||
let responseToCache = response.clone();
|
||||
|
||||
caches.open(cacheName).then((cache) => {
|
||||
/* console.log('[sw] Caching new resource: ' + event.request.url); */
|
||||
caches.open(swconf.cacheName).then((cache) => {
|
||||
cache.put(event.request, responseToCache);
|
||||
});
|
||||
|
||||
return response;
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
layout: compress
|
||||
permalink: '/unregister.js'
|
||||
---
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.getRegistrations().then((registrations) => {
|
||||
for (let reg of registrations) {
|
||||
reg.unregister();
|
||||
}
|
||||
});
|
||||
}
|
||||
Submodule assets/lib updated: 6e3fa73468...7bc0d86b6a
@@ -2,6 +2,90 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [6.5.4](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.5.3...v6.5.4) (2024-03-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* correct the attribute for the Twitter social image ([#1615](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1615)) ([cfe44f2](https://github.com/cotes2020/jekyll-theme-chirpy/commit/cfe44f204bcec8e05f498512ec50878e626a124f))
|
||||
* **seo:** correct social preview image path inside `<meta>` tag ([#1623](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1623)) ([74cf57a](https://github.com/cotes2020/jekyll-theme-chirpy/commit/74cf57aaacf6674057e6f33240a22f4888cfe88f))
|
||||
|
||||
## [6.5.3](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.5.2...v6.5.3) (2024-03-07)
|
||||
|
||||
## [6.5.2](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.5.1...v6.5.2) (2024-02-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* correct the base URL parameter name ([#1576](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1576)) ([19d6baf](https://github.com/cotes2020/jekyll-theme-chirpy/commit/19d6bafbe1a60614e0d63b961bc73c342a9f6f33)), closes [#1553](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1553)
|
||||
|
||||
## [6.5.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.5.0...v6.5.1) (2024-02-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* correct the generation of relative resource paths ([#1553](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1553)) ([89b9625](https://github.com/cotes2020/jekyll-theme-chirpy/commit/89b962557a56ccc13eba3c9c20b4270ee9d30042))
|
||||
|
||||
## [6.5.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.4.2...v6.5.0) (2024-02-14)
|
||||
|
||||
### Features
|
||||
|
||||
* add `pwa.cache.*` option to precisely control caching ([#1501](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1501)) ([1127c43](https://github.com/cotes2020/jekyll-theme-chirpy/commit/1127c43823aac4db7fd80d5bb706ae7b1e129dc6))
|
||||
* add analytics support for GoatCounter ([#1526](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1526)) ([90693ff](https://github.com/cotes2020/jekyll-theme-chirpy/commit/90693ff95e72ca4b5135a7b454a6ab521b995b3e))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* correct the Twitter Card in social share preview ([#1498](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1498)) ([74f1662](https://github.com/cotes2020/jekyll-theme-chirpy/commit/74f16623c9c4877ef36ac52e8b69c19d1d9a82ba))
|
||||
* missing "/" at the end of URLs for categories and tags in breadcrumb ([#1495](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1495)) ([02e296e](https://github.com/cotes2020/jekyll-theme-chirpy/commit/02e296ed75b7906b2d112c67f9054f5d71919de9))
|
||||
|
||||
### Improvements
|
||||
|
||||
* allow no social links to be configured ([#1494](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1494)) ([4facf5b](https://github.com/cotes2020/jekyll-theme-chirpy/commit/4facf5b390eeba612ca439f3354c5d2d881aac56))
|
||||
* allow TOC to start at heading 3 ([#1512](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1512)) ([bbbb66b](https://github.com/cotes2020/jekyll-theme-chirpy/commit/bbbb66b489a3bf2b878947336fe894e8ea2ae3f5))
|
||||
* enable equation numbering in MathJax ([#1520](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1520)) ([c13ec31](https://github.com/cotes2020/jekyll-theme-chirpy/commit/c13ec311636d5e057c6895e353e1c1a4e570f582))
|
||||
|
||||
## [6.4.2](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.4.1...v6.4.2) (2024-01-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* resume the `blockquote` display type ([#1480](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1480)) ([c7cfde0](https://github.com/cotes2020/jekyll-theme-chirpy/commit/c7cfde093020c73ca9a1b83437eb600379e05918)), closes [#1449](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1449)
|
||||
|
||||
## [6.4.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.4.0...v6.4.1) (2024-01-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `og:image` URL is incorrect ([#1468](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1468)) ([b2d1cb6](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b2d1cb68db659270aac537d2aa8d4b806fa6991d)), closes [#1463](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1463)
|
||||
|
||||
## [6.4.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.3.1...v6.4.0) (2024-01-10)
|
||||
|
||||
### Features
|
||||
|
||||
* add bilibili embed video support ([#1406](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1406)) ([4a2b89d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/4a2b89d0b698d672486349131a89025fa47afcb6))
|
||||
* add site-wide social preview image settings ([#1463](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1463)) ([241bb4d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/241bb4df7878cff7f82014df660874a1dcddba76))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* image float breaks quotes and prompts ([#1449](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1449)) ([ea2d238](https://github.com/cotes2020/jekyll-theme-chirpy/commit/ea2d238bd8adc018256862e05a5092311c87a671)), closes [#1441](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1441)
|
||||
* url-less authors should not have empty links ([#1410](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1410)) ([2a4fbf6](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2a4fbf6a7925da610a75c498116da7cf9ba857d7)), closes [#1403](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1403)
|
||||
|
||||
### Improvements
|
||||
|
||||
* include the latest posts in the "Recently Updated" list ([#1456](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1456)) ([82d8f2d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/82d8f2db984711f334f55b6af5098ec16770e824))
|
||||
|
||||
## [6.3.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.3.0...v6.3.1) (2023-11-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **home:** responsive gap at the bottom of preview image ([1a977a8](https://github.com/cotes2020/jekyll-theme-chirpy/commit/1a977a87a0da1cff35d0896cf9265c31034841a6))
|
||||
|
||||
## [6.3.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.2.3...v6.3.0) (2023-11-10)
|
||||
|
||||
### Features
|
||||
|
||||
* add Mastodon sharing link ([#1344](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1344)) ([2bf87e0](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2bf87e0de7928f325811e1bb96cfcaefdf6cf66a)), closes [#1324](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1324)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **home:** crop the preview image that doesn't match 1.91:1 ([#1325](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1325)) ([5810bcd](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5810bcd1d7b83e111017831fa82c368a6b15c7cd))
|
||||
* resume lazy loading for Twitch videos ([#1326](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1326)) ([9f174d9](https://github.com/cotes2020/jekyll-theme-chirpy/commit/9f174d9088e5c83a5e0c4630336cea65e199c553)), closes [#1267](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1267)
|
||||
|
||||
## [6.2.3](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v6.2.2...v6.2.3) (2023-10-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "jekyll-theme-chirpy"
|
||||
spec.version = "6.2.3"
|
||||
spec.version = "6.5.4"
|
||||
spec.authors = ["Cotes Chung"]
|
||||
spec.email = ["cotes.chung@gmail.com"]
|
||||
|
||||
spec.summary = "A minimal, responsive and feature-rich Jekyll theme for technical writing."
|
||||
spec.summary = "A minimal, responsive, and feature-rich Jekyll theme for technical writing."
|
||||
spec.homepage = "https://github.com/cotes2020/jekyll-theme-chirpy"
|
||||
spec.license = "MIT"
|
||||
|
||||
@@ -23,12 +23,12 @@ Gem::Specification.new do |spec|
|
||||
"plugin_type" => "theme"
|
||||
}
|
||||
|
||||
spec.required_ruby_version = ">= 2.6"
|
||||
spec.required_ruby_version = ">= 3.0"
|
||||
|
||||
spec.add_runtime_dependency "jekyll", "~> 4.3"
|
||||
spec.add_runtime_dependency "jekyll-paginate", "~> 1.1"
|
||||
spec.add_runtime_dependency "jekyll-redirect-from", "~> 0.16"
|
||||
spec.add_runtime_dependency "jekyll-seo-tag", "~> 2.7"
|
||||
spec.add_runtime_dependency "jekyll-seo-tag", "~> 2.8"
|
||||
spec.add_runtime_dependency "jekyll-archives", "~> 2.2"
|
||||
spec.add_runtime_dependency "jekyll-sitemap", "~> 1.4"
|
||||
spec.add_runtime_dependency "jekyll-include-cache", "~> 0.2"
|
||||
|
||||
97
package.json
97
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jekyll-theme-chirpy",
|
||||
"version": "6.2.3",
|
||||
"description": "A minimal, responsive and feature-rich Jekyll theme for technical writing.",
|
||||
"version": "6.5.4",
|
||||
"description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/cotes2020/jekyll-theme-chirpy.git"
|
||||
@@ -21,15 +21,92 @@
|
||||
"fixlint": "npm run test -- --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.23.0",
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/preset-env": "^7.22.20",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-terser": "^0.4.3",
|
||||
"@babel/preset-env": "^7.23.9",
|
||||
"@commitlint/cli": "^18.6.1",
|
||||
"@commitlint/config-conventional": "^18.6.2",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"husky": "^9.0.11",
|
||||
"rimraf": "^5.0.5",
|
||||
"rollup": "^3.29.4",
|
||||
"rollup-plugin-license": "^3.1.0",
|
||||
"stylelint": "^15.10.3",
|
||||
"stylelint-config-standard-scss": "^11.0.0"
|
||||
"rollup": "^4.10.0",
|
||||
"rollup-plugin-license": "^3.2.0",
|
||||
"stylelint": "^16.2.1",
|
||||
"stylelint-config-standard-scss": "^13.0.0"
|
||||
},
|
||||
"prettier": {
|
||||
"trailingComma": "none"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 2 versions",
|
||||
"> 0.2%",
|
||||
"not dead"
|
||||
],
|
||||
"commitlint": {
|
||||
"extends": [
|
||||
"@commitlint/config-conventional"
|
||||
],
|
||||
"rules": {
|
||||
"body-max-line-length": [
|
||||
0,
|
||||
"always"
|
||||
]
|
||||
}
|
||||
},
|
||||
"stylelint": {
|
||||
"extends": "stylelint-config-standard-scss",
|
||||
"rules": {
|
||||
"no-descending-specificity": null,
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"at-rule-no-vendor-prefix": null,
|
||||
"property-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"value-no-vendor-prefix": null,
|
||||
"color-function-notation": "legacy",
|
||||
"alpha-value-notation": "number",
|
||||
"selector-not-notation": "simple",
|
||||
"color-hex-length": "long",
|
||||
"declaration-block-single-line-max-declarations": 3,
|
||||
"scss/operator-no-newline-after": null,
|
||||
"rule-empty-line-before": [
|
||||
"always",
|
||||
{
|
||||
"ignore": [
|
||||
"after-comment",
|
||||
"first-nested"
|
||||
]
|
||||
}
|
||||
],
|
||||
"value-keyword-case": [
|
||||
"lower",
|
||||
{
|
||||
"ignoreProperties": [
|
||||
"/^\\$/"
|
||||
]
|
||||
}
|
||||
],
|
||||
"media-feature-range-notation": "prefix"
|
||||
}
|
||||
},
|
||||
"standard-version": {
|
||||
"skip": {
|
||||
"commit": true,
|
||||
"tag": true
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"type": "feat",
|
||||
"section": "Features"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"section": "Bug Fixes"
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"section": "Improvements"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,21 @@ import terser from '@rollup/plugin-terser';
|
||||
import license from 'rollup-plugin-license';
|
||||
import path from 'path';
|
||||
|
||||
const JS_SRC = '_javascript';
|
||||
const JS_DIST = 'assets/js/dist';
|
||||
const SRC_DEFAULT = '_javascript';
|
||||
const DIST_DEFAULT = 'assets/js/dist';
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
|
||||
function build(filename) {
|
||||
return {
|
||||
input: [`${JS_SRC}/${filename}.js`],
|
||||
input: [`${SRC_DEFAULT}/${filename}.js`],
|
||||
output: {
|
||||
file: `${JS_DIST}/${filename}.min.js`,
|
||||
file: `${DIST_DEFAULT}/${filename}.min.js`,
|
||||
format: 'iife',
|
||||
name: 'Chirpy',
|
||||
sourcemap: !isProd
|
||||
},
|
||||
watch: {
|
||||
include: `${JS_SRC}/**`
|
||||
include: `${SRC_DEFAULT}/**`
|
||||
},
|
||||
plugins: [
|
||||
babel({
|
||||
@@ -28,7 +28,7 @@ function build(filename) {
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: 'ignored',
|
||||
content: { file: path.join(__dirname, JS_SRC, '_copyright') }
|
||||
content: { file: path.join(__dirname, SRC_DEFAULT, '_copyright') }
|
||||
}
|
||||
}),
|
||||
isProd && terser()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# and production branch.
|
||||
#
|
||||
#
|
||||
# Usage: run on main branch or the patch branch
|
||||
# Usage: run on the default, release or the patch branch
|
||||
#
|
||||
# Requires: Git, NPM and RubyGems
|
||||
|
||||
@@ -18,8 +18,7 @@ opt_pre=false # preview mode option
|
||||
|
||||
working_branch="$(git branch --show-current)"
|
||||
|
||||
# AKA the default branch, main/master branch
|
||||
STAGING_BRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
|
||||
DEFAULT_BRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
|
||||
|
||||
PROD_BRANCH="production"
|
||||
|
||||
@@ -65,17 +64,20 @@ _check_cli() {
|
||||
}
|
||||
|
||||
_check_git() {
|
||||
# ensure nothing is uncommitted
|
||||
# ensure that changes have been committed
|
||||
if [[ -n $(git status . -s) ]]; then
|
||||
echo "> Abort: Commit the staged files first, and then run this tool again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure the working branch is the default/patch branch
|
||||
if [[ $working_branch != "$STAGING_BRANCH" && $working_branch != hotfix/* ]]; then
|
||||
echo "> Abort: Please run on the $STAGING_BRANCH branch or a patch branche."
|
||||
exit 1
|
||||
fi
|
||||
$opt_pre || (
|
||||
if [[ $working_branch != "$DEFAULT_BRANCH" &&
|
||||
$working_branch != hotfix/* &&
|
||||
$working_branch != "$PROD_BRANCH" ]]; then
|
||||
echo "> Abort: Please run on the default, release or patch branch."
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
}
|
||||
|
||||
_check_src() {
|
||||
@@ -101,14 +103,16 @@ check() {
|
||||
_check_node_packages
|
||||
}
|
||||
|
||||
# auto-generate a new version number to the file 'package.json' and
|
||||
# Auto-generate a new version number to the file 'package.json'
|
||||
bump_node() {
|
||||
bump="standard-version -i $CHANGE_LOG"
|
||||
|
||||
if $opt_pre; then
|
||||
standard-version -i "$CHANGE_LOG" -p rc
|
||||
else
|
||||
standard-version -i "$CHANGE_LOG"
|
||||
bump="$bump -p rc"
|
||||
fi
|
||||
|
||||
eval "$bump"
|
||||
|
||||
# Change heading of Patch version to heading level 2 (a bug from `standard-version`)
|
||||
sed -i "s/^### \[/## \[/g" "$CHANGE_LOG"
|
||||
# Replace multiple empty lines with a single empty line
|
||||
@@ -117,39 +121,46 @@ bump_node() {
|
||||
|
||||
## Bump new version to gem config file
|
||||
bump_gem() {
|
||||
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$1/" "$GEM_SPEC"
|
||||
_ver="$1"
|
||||
|
||||
if $opt_pre; then
|
||||
_ver="${1/-/.}"
|
||||
fi
|
||||
|
||||
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$_ver/" "$GEM_SPEC"
|
||||
}
|
||||
|
||||
# Update the git branches, create a new tag, and then build the gem package.
|
||||
release() {
|
||||
# Creates a new tag on the production branch with the given version number.
|
||||
# Also commits the changes and merges the production branch into the default branch.
|
||||
branch() {
|
||||
_version="$1" # X.Y.Z
|
||||
_latest_commit="$(git rev-parse HEAD)"
|
||||
|
||||
git add .
|
||||
git commit -m "chore(release): $_version"
|
||||
|
||||
# Create a new tag on production branch
|
||||
echo -e "> Create tag v$_version\n"
|
||||
git tag "v$_version"
|
||||
|
||||
git checkout "$STAGING_BRANCH"
|
||||
git checkout "$DEFAULT_BRANCH"
|
||||
git merge --no-ff --no-edit "$PROD_BRANCH"
|
||||
|
||||
if [[ $working_branch == hotfix/* ]]; then
|
||||
git merge --no-ff --no-edit "$working_branch"
|
||||
# delete the patch branch
|
||||
git branch -D "$working_branch"
|
||||
fi
|
||||
|
||||
# cherry-pick the latest commit from production branch to default branch
|
||||
git cherry-pick "$_latest_commit"
|
||||
|
||||
}
|
||||
|
||||
## Build a gem package
|
||||
## Build a Gem package
|
||||
build_gem() {
|
||||
git checkout "$PROD_BRANCH"
|
||||
|
||||
# Remove unnecessary theme settings
|
||||
sed -i "s/^img_cdn:.*/img_cdn:/;s/^avatar:.*/avatar:/" _config.yml
|
||||
rm -f ./*.gem
|
||||
|
||||
npm run build
|
||||
git add "$JS_DIST" -f # add JS dist to gem
|
||||
git add "$JS_DIST" -f # add JS distribution files to gem
|
||||
gem build "$GEM_SPEC"
|
||||
cp "$JS_DIST"/* "$BACKUP_PATH"
|
||||
|
||||
@@ -159,12 +170,15 @@ build_gem() {
|
||||
|
||||
# restore the dist files for future development
|
||||
mkdir -p "$JS_DIST" && cp "$BACKUP_PATH"/* "$JS_DIST"
|
||||
|
||||
# back to the default branch
|
||||
git checkout "$DEFAULT_BRANCH"
|
||||
}
|
||||
|
||||
main() {
|
||||
check
|
||||
|
||||
if [[ $opt_pre = false ]]; then
|
||||
if [[ $opt_pre = false && $working_branch != "$PROD_BRANCH" ]]; then
|
||||
git checkout "$PROD_BRANCH"
|
||||
git merge --no-ff --no-edit "$working_branch"
|
||||
fi
|
||||
@@ -175,16 +189,12 @@ main() {
|
||||
|
||||
bump_gem "$_version"
|
||||
|
||||
echo -e "> Build the gem package for v$_version\n"
|
||||
|
||||
if [[ $opt_pre = false ]]; then
|
||||
echo -e "> Bumped version number to $_version\n"
|
||||
git add .
|
||||
git commit -m "chore(release): $_version"
|
||||
|
||||
release "$_version"
|
||||
branch "$_version"
|
||||
fi
|
||||
|
||||
echo -e "> Build the gem package for v$_version\n"
|
||||
|
||||
build_gem
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user