mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 21:53:26 +00:00
Compare commits
111 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
945e8d1953 | ||
|
|
a400dc9501 | ||
|
|
6a4169fc03 | ||
|
|
95b4b453e6 | ||
|
|
de14c00570 | ||
|
|
f4d4065b1c | ||
|
|
52f854a2da | ||
|
|
38f20e8119 | ||
|
|
1728d697e6 | ||
|
|
d9863d6a02 | ||
|
|
b460d03c3b | ||
|
|
a053c454e4 | ||
|
|
77c2009658 | ||
|
|
9844b964a8 | ||
|
|
063b2a6651 | ||
|
|
e5df04dd59 | ||
|
|
9e9278ce30 | ||
|
|
30dfc6fb7e | ||
|
|
1ce350e33e | ||
|
|
50c88f7205 | ||
|
|
387fc67102 | ||
|
|
414715fc47 | ||
|
|
1bb54096f4 | ||
|
|
abb548fcee | ||
|
|
ed93fbdfde | ||
|
|
4ad0a76789 | ||
|
|
89b76dc2a0 | ||
|
|
395b24736a | ||
|
|
fa0155de6f | ||
|
|
0bffb276fe | ||
|
|
2417db656c | ||
|
|
e5bf234835 | ||
|
|
2dfdb66e0a | ||
|
|
da9881a47f | ||
|
|
c68a937e01 | ||
|
|
4001ef7cba | ||
|
|
1b16b152df | ||
|
|
e607e5fe86 | ||
|
|
d761d340a8 | ||
|
|
f411ba33d8 | ||
|
|
f722757f6f | ||
|
|
beabb36d7f | ||
|
|
42ff0f2282 | ||
|
|
34631a0c30 | ||
|
|
53b0329e5a | ||
|
|
2877896b9e | ||
|
|
7ef88c8b8f | ||
|
|
2acf14ecf0 | ||
|
|
603705f20e | ||
|
|
0267ad8d40 | ||
|
|
c0b8c089c2 | ||
|
|
a603aac8e8 | ||
|
|
91ed3d4649 | ||
|
|
20454e5a57 | ||
|
|
aadda0347c | ||
|
|
5e9a7b319e | ||
|
|
2537283beb | ||
|
|
7dc7a7efc8 | ||
|
|
39b09b97c0 | ||
|
|
8d164c2e6e | ||
|
|
1a94b1889f | ||
|
|
6d07d4738b | ||
|
|
6e0afcf9e8 | ||
|
|
952927762a | ||
|
|
3c3598e8b1 | ||
|
|
9d9bca5e3b | ||
|
|
03248f5bff | ||
|
|
e2c288a925 | ||
|
|
b80d95dcdd | ||
|
|
72ba1f7849 | ||
|
|
46d80cbf9a | ||
|
|
0213331a16 | ||
|
|
780af9ac5f | ||
|
|
b513c0764d | ||
|
|
57e8c6e594 | ||
|
|
49dc866bd8 | ||
|
|
b7a483680e | ||
|
|
7ecb377c9b | ||
|
|
a83e4c1b30 | ||
|
|
0b29c0321f | ||
|
|
2e76300d04 | ||
|
|
20f2ff4b23 | ||
|
|
899609a291 | ||
|
|
f56852a700 | ||
|
|
c969eaa040 | ||
|
|
ab8cef9174 | ||
|
|
b3ff6c79a6 | ||
|
|
7f8c19d480 | ||
|
|
d52fa88337 | ||
|
|
bea170cff0 | ||
|
|
961ebb545b | ||
|
|
797450174d | ||
|
|
f0a2113a9f | ||
|
|
c98a41317f | ||
|
|
5f1e6e9350 | ||
|
|
65dbea9d3b | ||
|
|
fd97067ec3 | ||
|
|
d5413a954f | ||
|
|
9359d6ef11 | ||
|
|
6d1d440c00 | ||
|
|
08ec6cd3b5 | ||
|
|
3ecb59deb1 | ||
|
|
885ed44646 | ||
|
|
d31e677ca0 | ||
|
|
bf3b539d6d | ||
|
|
ab927e9954 | ||
|
|
d5e08b05ab | ||
|
|
eb247b8886 | ||
|
|
4fa7c6af6e | ||
|
|
2cce0be8af | ||
|
|
cf7d8a45ba |
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -36,6 +36,7 @@ Steps to reproduce the behavior:
|
||||
- Gem version: <!-- by running: `gem -v`-->
|
||||
- Bundler version: <!-- by running: `bundle -v`-->
|
||||
- Jekyll version: <!-- by running: `bundle list | grep " jekyll "` -->
|
||||
- Theme version: <!-- by running: `gem list | grep jekyll-theme-chirpy` -->
|
||||
|
||||
### Desktop
|
||||
<!-- If necessary, uncomment and fill in the following list:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/question.md
vendored
2
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -16,4 +16,4 @@ labels: question
|
||||
- [ ] My question is based on the latest code of `master` branch.
|
||||
|
||||
## Description
|
||||
<!-- Please describe your question in detial. -->
|
||||
<!-- Please describe your question in detail. -->
|
||||
|
||||
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,9 +2,9 @@
|
||||
|
||||
<!--
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||
-->
|
||||
|
||||
e.g. Fixes #(issue)
|
||||
-->
|
||||
|
||||
## Type of change
|
||||
|
||||
@@ -22,7 +22,7 @@ Please select the desired item checkbox and change it to "[x]", then delete opti
|
||||
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
-->
|
||||
|
||||
- [ ] I have run `bash ./tools/test.sh --build` (at the root of the project) locally and passed
|
||||
- [ ] I have run `bash ./tools/deploy.sh --dry-run` (at the root of the project) locally and passed
|
||||
- [ ] I have tested this feature in the browser
|
||||
|
||||
### Test Configuration
|
||||
|
||||
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
@@ -36,12 +36,5 @@ jobs:
|
||||
ruby-version: 2.7
|
||||
bundler-cache: true
|
||||
|
||||
- name: Build Site
|
||||
env:
|
||||
JEKYLL_ENV: production
|
||||
run: |
|
||||
bundle exec jekyll b
|
||||
|
||||
- name: Test Site
|
||||
run: |
|
||||
bash tools/test.sh
|
||||
run: bash tools/deploy.sh --dry-run
|
||||
|
||||
18
.github/workflows/issue-interceptor.yml
vendored
Normal file
18
.github/workflows/issue-interceptor.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Intercept bad issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
auto_close_issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Auto close issues that did not follow template
|
||||
uses: lucasbento/auto-close-issues@v1.0.2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template. Please DO NOT open another similar issue, try to edit the current issue according to the template, then it will be reopened automatically."
|
||||
closed-issues-label: "🙁 Not following issue template"
|
||||
20
.github/workflows/issue-pr-interceptor.yml
vendored
20
.github/workflows/issue-pr-interceptor.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: "Intercept bad issue/PRs"
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
autoclose:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Auto close issues/pr that did not follow template
|
||||
uses: roots/issue-closer@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-pattern: "(\\[x\\]|\\[X\\]) I have read"
|
||||
issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template."
|
||||
pr-pattern: "(\\[x\\]|\\[X\\]) (Bug fix|New feature|Breaking change|Documentation update)|@dependabot"
|
||||
pr-close-message: ":wave: Hi @${pull_request.user.login},\n\nThis PR is being automatically closed because it does not follow the PR template."
|
||||
26
.github/workflows/pages-deploy.yml.hook
vendored
26
.github/workflows/pages-deploy.yml.hook
vendored
@@ -25,29 +25,5 @@ jobs:
|
||||
ruby-version: 2.7
|
||||
bundler-cache: true
|
||||
|
||||
- name: Check baseurl
|
||||
run: |
|
||||
baseurl="$(grep '^baseurl:' _config.yml | sed "s/.*: *//;s/['\"]//g;s/#.*//")"
|
||||
if [[ -n $baseurl ]]; then
|
||||
echo "BASE_URL=$baseurl" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build Site
|
||||
env:
|
||||
JEKYLL_ENV: production
|
||||
run: |
|
||||
bundle exec jekyll b -d "_site$BASE_URL"
|
||||
|
||||
- name: Test Site
|
||||
run: |
|
||||
bash tools/test.sh
|
||||
|
||||
- name: Deploy
|
||||
run: |
|
||||
if [[ -n $BASE_URL ]]; then
|
||||
mv _site$BASE_URL _site-rename
|
||||
rm -rf _site
|
||||
mv _site-rename _site
|
||||
fi
|
||||
|
||||
bash tools/deploy.sh
|
||||
run: bash tools/deploy.sh
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,6 +1,9 @@
|
||||
# hidden files
|
||||
.*
|
||||
!.github
|
||||
!.git*
|
||||
!.editorconfig
|
||||
!.nojekyll
|
||||
!.travis.yml
|
||||
|
||||
# bundler cache
|
||||
_site
|
||||
|
||||
17
.travis.yml
17
.travis.yml
@@ -3,48 +3,39 @@ dist: bionic
|
||||
|
||||
language: minimal
|
||||
|
||||
if: tag =~ /^v(\d)+(\.(\d)+){2}$/
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
- name: CD
|
||||
- name: Deploy
|
||||
language: ruby
|
||||
rvm: 2.7.0
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# required to avoid SSL error (for htmlproofer)
|
||||
- libcurl4-openssl-dev
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/vendor/bundle
|
||||
|
||||
before_install:
|
||||
# match the Gemfile.lock, travis' bundler is 2.1.2
|
||||
- gem install bundler:2.2.4
|
||||
- bundle config path 'vendor/bundle'
|
||||
|
||||
install:
|
||||
# overriding to drop the travis `--development` flag
|
||||
- bundle install --jobs=3 --retry=3
|
||||
|
||||
script:
|
||||
- eval "$BUILD_CMD"
|
||||
|
||||
git:
|
||||
depth: false # for posts' lastmod
|
||||
|
||||
- name: Flush Starter
|
||||
script:
|
||||
- eval "$FLUSH_STARTER"
|
||||
script: eval "$FLUSH_STARTER"
|
||||
|
||||
before_script:
|
||||
- git -C "$HOME" clone "$BUILDER_REPO" --depth=1 -q
|
||||
|
||||
branches:
|
||||
only: /.*-stable$/
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
|
||||
3
Gemfile
3
Gemfile
@@ -17,3 +17,6 @@ end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform?
|
||||
|
||||
# Jekyll <= 4.2.0 compatibility with Ruby 3.0
|
||||
gem "webrick", "~> 1.7"
|
||||
|
||||
184
README.md
184
README.md
@@ -1,85 +1,68 @@
|
||||
# Chirpy
|
||||
<div align="right">
|
||||
|
||||
Language: English | [简体中文](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md)
|
||||
EN /
|
||||
[中文(简体)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md)
|
||||
|
||||
[](https://rubygems.org/gems/jekyll-theme-chirpy)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
|
||||
[](https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
|
||||
[](https://996.icu)
|
||||
</div>
|
||||
|
||||
A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation. Designed to help you record and share your knowledge easily. [Live Demo »](https://chirpy.cotes.info)
|
||||
<div align="center">
|
||||
|
||||
[](https://chirpy.cotes.info)
|
||||
# Chirpy Jekyll Theme
|
||||
|
||||
[](https://rubygems.org/gems/jekyll-theme-chirpy)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
|
||||
[](https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
|
||||
[](https://996.icu)
|
||||
|
||||
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
|
||||
|
||||
**[Live Demo →](https://chirpy.cotes.info)**
|
||||
|
||||
[](https://chirpy.cotes.info)
|
||||
|
||||
</div>
|
||||
|
||||
## Features
|
||||
|
||||
- Localized Layout
|
||||
- Configurable Theme Mode
|
||||
- Pinned Posts
|
||||
- Configurable theme mode
|
||||
- Double-level Categories
|
||||
- Last modified date for posts
|
||||
- Hierarchical Categories
|
||||
- Last Modified Date for Posts
|
||||
- Table of Contents
|
||||
- Automatically recommend related posts
|
||||
- Syntax highlighting
|
||||
- Mathematical expressions
|
||||
- Mermaid diagram & flowchart
|
||||
- Automatically Recommend Related Posts
|
||||
- Syntax Highlighting
|
||||
- Mathematical Expressions
|
||||
- Mermaid Diagram & Flowchart
|
||||
- Search
|
||||
- Atom Feeds
|
||||
- Disqus Comments
|
||||
- Google Analytics
|
||||
- GA Pageviews reporting (Advanced)
|
||||
- SEO and Performance Optimization
|
||||
- GA Pageviews Reporting (Advanced)
|
||||
- SEO & Performance Optimization
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
|
||||
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
|
||||
|
||||
## Installation
|
||||
|
||||
There are two ways to get the theme:
|
||||
### Creating a New Site
|
||||
|
||||
- **Install from RubyGems** - Easy to update, isolate irrelevant project files so you can focus on writing.
|
||||
- **Fork on GitHub** - Convenient for custom development, but difficult to update, only suitable for web developers.
|
||||
There are two ways to create a new repository for this theme:
|
||||
|
||||
### Installing the Theme Gem
|
||||
- **[Using the Chirpy Starter](#option-1-using-the-chirpy-starter)** - Easy to upgrade, isolates irrelevant project files so you can focus on writing.
|
||||
|
||||
Add this line to your Jekyll site's `Gemfile`:
|
||||
- **[Forking on GitHub](#option-2-forking-on-github)** - Convenient for custom development, but difficult to upgrade. Unless you are familiar with Jekyll and are determined to tweak or contribute to this project, this approach is not recommended.
|
||||
|
||||
```ruby
|
||||
gem "jekyll-theme-chirpy"
|
||||
```
|
||||
#### Option 1. Using the Chirpy Starter
|
||||
|
||||
And add this line to your Jekyll site's `_config.yml`:
|
||||
Create a new repository from the [**Chirpy Starter**][use-starter] and name it `<GH_USERNAME>.github.io`, where `GH_USERNAME` represents your GitHub username.
|
||||
|
||||
```yaml
|
||||
theme: jekyll-theme-chirpy
|
||||
```
|
||||
#### Option 2. Forking on GitHub
|
||||
|
||||
And then execute:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
Finally, copy the required files from the theme's gem (for detailed files, see [starter project][starter]) to your Jekyll site.
|
||||
|
||||
> **Hint**: To locate the installed theme’s gem, execute:
|
||||
>
|
||||
> ```console
|
||||
> $ bundle info --path jekyll-theme-chirpy
|
||||
> ```
|
||||
|
||||
Or you can [**use the starter template**][use-starter] to create a Jekyll site to save time copying files from the theme's gem. We have prepared everything for you there!
|
||||
|
||||
### Fork on GitHub
|
||||
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and then clone your fork to local. (Please note that the default branch code is in development. If you want the blog to be stable, please switch to the [latest tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) and start writing.)
|
||||
|
||||
Install gem dependencies by:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and rename it to `<GH_USERNAME>.github.io`. Please note that the default branch code is in development. If you want the site to be stable, please switch to the [latest tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) and start writing.
|
||||
|
||||
And then execute:
|
||||
|
||||
@@ -87,18 +70,28 @@ And then execute:
|
||||
$ bash tools/init.sh
|
||||
```
|
||||
|
||||
> **Note**: If you don't plan to deploy your site on GitHub Pages, append parameter option `--no-gh` at the end of the above command.
|
||||
> **Note**: If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
|
||||
|
||||
What it does is:
|
||||
The above command will:
|
||||
|
||||
1. Remove some files or directories from your repository:
|
||||
1. Removes some files or directories from your repository:
|
||||
- `.travis.yml`
|
||||
- files under `_posts`
|
||||
- folder `docs`
|
||||
|
||||
2. If you use the `--no-gh` option, the directory `.github` will be deleted. Otherwise, setup the GitHub Action workflow by removing the extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in the folder `.github`.
|
||||
2. If the option `--no-gh` is provided, the directory `.github` will be deleted. Otherwise, setup the GitHub Action workflow by removing the extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in the folder `.github`.
|
||||
|
||||
3. Automatically create a commit to save the changes.
|
||||
3. Removes item `Gemfile.lock` from `.gitignore`.
|
||||
|
||||
4. Creates a new commit to save the changes automatically.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
Before running for the first time, go the root directory of your site, and install dependencies as follows:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -111,6 +104,12 @@ Update the variables of `_config.yml` as needed. Some of them are typical option
|
||||
- `timezone`
|
||||
- `lang`
|
||||
|
||||
### Customing Stylesheet
|
||||
|
||||
If you need to customize stylesheet, copy the theme's `assets/css/style.scss` to the same path on your Jekyll site, and then add the custom style at the end of the style file.
|
||||
|
||||
Starting from [`v4.1.0`][chirpy-4.1.0], if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`, create a new file `_sass/variables-hook.scss` and assign new values to the target variable in it.
|
||||
|
||||
### Running Local Server
|
||||
|
||||
You may want to preview the site contents before publishing, so just run it by:
|
||||
@@ -121,14 +120,14 @@ $ bundle exec jekyll s
|
||||
|
||||
Or run the site on Docker with the following command:
|
||||
|
||||
```terminal
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
-p 4000:4000 jekyll/jekyll \
|
||||
jekyll serve
|
||||
```
|
||||
|
||||
Open a browser and visit to _<http://localhost:4000>_.
|
||||
After a while, the local service will be published at _<http://127.0.0.1:4000>_.
|
||||
|
||||
### Deployment
|
||||
|
||||
@@ -136,40 +135,47 @@ Before the deployment begins, checkout the file `_config.yml` and make sure the
|
||||
|
||||
Now you can choose ONE of the following methods to deploy your Jekyll site.
|
||||
|
||||
#### Deploy on GitHub Pages
|
||||
#### Deploy by Using Github Actions
|
||||
|
||||
For security reasons, GitHub Pages build runs on `safe` mode, which restricts us from using plugins to generate additional page files. Therefore, we can use **GitHub Actions** to build the site, store the built site files on a new branch, and use that branch as the source of the GH Pages service.
|
||||
For security reasons, GitHub Pages build runs on `safe` mode, which restricts us from using plugins to generate additional page files. Therefore, we can use **GitHub Actions** to build the site, store the built site files on a new branch, and use that branch as the source of the GitHub Pages service.
|
||||
|
||||
Quickly check the files needed for GitHub Actions build:
|
||||
|
||||
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`. Otherwise, create a new one and fill in the contents of the [workflow file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name.
|
||||
- Ensure your Jekyll site has file `tools/test.sh` and `tools/deploy.sh`. Otherwise, copy them from this repo to your Jekyll site.
|
||||
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`. Otherwise, create a new one and fill in the contents of the [sample file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name.
|
||||
|
||||
And then rename your repository to `<GH-USERNAME>.github.io` on GitHub.
|
||||
- Ensure your Jekyll site has file `tools/deploy.sh`. Otherwise, copy it from here to your Jekyll site.
|
||||
|
||||
- Furthermore, if you have committed `Gemfile.lock` to the repo, and your runtime system is not Linux, don't forget to update the platform list in the lockfile:
|
||||
|
||||
```console
|
||||
$ bundle lock --add-platform x86_64-linux
|
||||
```
|
||||
|
||||
After the above steps, rename your repository to `<GH_USERNAME>.github.io` on GitHub.
|
||||
|
||||
Now publish your Jekyll site by:
|
||||
|
||||
1. Push any commit to remote to trigger the GitHub Actions workflow. Once the build is complete and successful, a new remote branch named `gh-pages` will appear to store the built site files.
|
||||
|
||||
2. Browse to your repo's landing page on GitHub and select the branch `gh-pages` as the [publishing source](https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) through _Settings_ → _Options_ → _GitHub Pages_:
|
||||
2. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar, and then in the section **Source** of _GitHub Pages_, select the `/(root)` directory of branch `gh-pages` as the [publishing source][pages-src]. Remember to click <kbd>Save</kbd> before leaving.
|
||||
|
||||

|
||||

|
||||
|
||||
3. Visit your website at the address indicated by GitHub.
|
||||
|
||||
#### Deploy on Other Platforms
|
||||
#### Manually Build and Deploy
|
||||
|
||||
On platforms other than GitHub, we cannot enjoy the convenience of **GitHub Actions**. Therefore, we should build the site locally (or on some other 3rd-party CI platform) and then put the site files on the server.
|
||||
On self-hosted servers, you cannot enjoy the convenience of **GitHub Actions**. Therefore, you should build the site on your local machine and then upload the site files to the server.
|
||||
|
||||
Go to the root of the source project, build your site by:
|
||||
Go to the root of the source project, and build your site as follows:
|
||||
|
||||
```console
|
||||
$ JEKYLL_ENV=production bundle exec jekyll b
|
||||
```
|
||||
|
||||
Or build the site with Docker by:
|
||||
Or build the site on Docker:
|
||||
|
||||
```terminal
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--env JEKYLL_ENV=production \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
@@ -177,11 +183,32 @@ $ docker run -it --rm \
|
||||
jekyll build
|
||||
```
|
||||
|
||||
Unless you specified the output path, the generated site files will be placed in folder `_site` of the project's root directory. Now you should upload those files to your web server.
|
||||
Unless you specified the output path, the generated site files will be placed in folder `_site` of the project's root directory. Now you should upload those files to the target server.
|
||||
|
||||
### Upgrading
|
||||
|
||||
It depends on how you use the theme:
|
||||
|
||||
- If you are using the theme gem (there will be `gem "jekyll-theme-chirpy"` in the `Gemfile`), editing the `Gemfile` and update the version number of the them gem, for example:
|
||||
```diff
|
||||
- gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1"
|
||||
+ gem "jekyll-theme-chirpy", "~> 3.3", ">= 3.3.0"
|
||||
```
|
||||
|
||||
And then execute the following command:
|
||||
|
||||
```console
|
||||
$ bundle update jekyll-theme-chirpy
|
||||
```
|
||||
|
||||
As the version upgrades, the critical files (for details, see the [Startup Template][starter]) and configuration options will change. Please refer to the [Upgrade Guide](https://github.com/cotes2020/jekyll-theme-chirpy/wiki/Upgrade-Guide) to keep your repo's files in sync with the latest version of the theme.
|
||||
|
||||
- If you forked from the source project (there will be `gemspec` in the `Gemfile` of your site), then merge the [latest upstream tags][latest-tag] into your Jekyll site to complete the upgrade.
|
||||
The merge is likely to conflict with your local modifications. Please be patient and careful to resolve these conflicts.
|
||||
|
||||
## Documentation
|
||||
|
||||
For more details and a better reading experience, please check out the [tutorials on the demo site](https://chirpy.cotes.info/categories/tutorial/). In the meanwhile, a copy of the tutorial is also available on the [Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki).
|
||||
For more details and a better reading experience, please check out the [tutorials on the demo site](https://chirpy.cotes.info/categories/tutorial/). In the meanwhile, a copy of the tutorial is also available on the [Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Please note that the tutorials on the demo website or Wiki are based on the latest release, and the features of `master` branch usually ahead of the documentation.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -210,6 +237,9 @@ This work is published under [MIT](https://github.com/cotes2020/jekyll-theme-chi
|
||||
[starter]: https://github.com/cotes2020/chirpy-starter
|
||||
[use-starter]: https://github.com/cotes2020/chirpy-starter/generate
|
||||
[workflow]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/workflows/pages-deploy.yml.hook
|
||||
[chirpy-4.1.0]: https://github.com/cotes2020/jekyll-theme-chirpy/releases/tag/v4.1.0
|
||||
[pages-src]: https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site
|
||||
[latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags
|
||||
|
||||
<!-- ReadMe links -->
|
||||
|
||||
|
||||
21
_config.yml
21
_config.yml
@@ -3,18 +3,21 @@
|
||||
# Import the theme
|
||||
theme: jekyll-theme-chirpy
|
||||
|
||||
# Only if your site type is GitHub Project sites and doesn't have a custom domain,
|
||||
# change below value to '/projectname'.
|
||||
# Change the following value to '/PROJECT_NAME' ONLY IF your site type is GitHub Pages Project sites
|
||||
# and doesn't have a custom domain.
|
||||
baseurl: ''
|
||||
|
||||
# the HTML language tag › https://www.w3.org/International/questions/qa-choosing-language-tags
|
||||
lang: en-US
|
||||
# The language of the webpage › http://www.lingoes.net/en/translator/langcode.htm
|
||||
# If it has the same name as one of the files in folder `_data/locales`, the layout language will also be changed,
|
||||
# otherwise, the layout language will use the default value of 'en'.
|
||||
lang: en
|
||||
|
||||
# Change to your timezone › http://www.timezoneconverter.com/cgi-bin/findzone/findzone
|
||||
timezone: Asia/Shanghai
|
||||
|
||||
# jekyll-seo-tag settings › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
|
||||
# --------------------------
|
||||
# ↓ --------------------------
|
||||
|
||||
title: Chirpy # the main title
|
||||
|
||||
tagline: A text-focused Jekyll theme # it will display as the sub-title
|
||||
@@ -47,7 +50,9 @@ social:
|
||||
# - https://www.linkedin.com/in/username
|
||||
|
||||
google_site_verification: google_meta_tag_verification # change to your verification string
|
||||
# --------------------------
|
||||
|
||||
# ↑ --------------------------
|
||||
|
||||
|
||||
google_analytics:
|
||||
id: '' # fill in your Google Analytics ID
|
||||
@@ -74,10 +79,10 @@ theme_mode: # [light|dark]
|
||||
# will be added to all image (site avatar & posts' images) paths starting with '/'
|
||||
#
|
||||
# e.g. 'https://cdn.com'
|
||||
img_cdn: ''
|
||||
img_cdn: 'https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images@0a003683c0c3ca549d12c309f9b3e03ea20981e5'
|
||||
|
||||
# the avatar on sidebar, support local or CORS resources
|
||||
avatar: https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/avatar.jpg
|
||||
avatar: '/commons/avatar.jpg'
|
||||
|
||||
# boolean type, the global switch for ToC in posts.
|
||||
toc: true
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
-
|
||||
type: github
|
||||
icon: 'fab fa-github-alt'
|
||||
icon: 'fab fa-github'
|
||||
-
|
||||
type: twitter
|
||||
icon: 'fab fa-twitter'
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# The date format
|
||||
|
||||
tooltip: "%a, %b %e, %Y, %l:%M %p %z"
|
||||
|
||||
post:
|
||||
long: "%b %e, %Y"
|
||||
short: "%b %e"
|
||||
@@ -1,19 +0,0 @@
|
||||
# The label text of site.
|
||||
|
||||
panel:
|
||||
lastmod: Recent Update
|
||||
trending_tags: Trending Tags
|
||||
toc: Contents
|
||||
|
||||
post:
|
||||
relate_posts: Further Reading
|
||||
share: Share
|
||||
button:
|
||||
next: Newer
|
||||
previous: Older
|
||||
|
||||
search_hint: Search # text show on search bar
|
||||
|
||||
pin_prompt: Pinned # pinned prompt
|
||||
|
||||
read_time_unit: min # see posts' time to read
|
||||
90
_data/locales/en.yml
Normal file
90
_data/locales/en.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Post
|
||||
category: Category
|
||||
tag: Tag
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Home
|
||||
categories: Categories
|
||||
tags: Tags
|
||||
archives: Archives
|
||||
about: About
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: search
|
||||
cancel: Cancel
|
||||
no_results: Oops! No result founds.
|
||||
|
||||
panel:
|
||||
lastmod: Recent Update
|
||||
trending_tags: Trending Tags
|
||||
toc: Contents
|
||||
|
||||
# The liquid date format › http://strftime.net/
|
||||
date_format:
|
||||
tooltip: '%a, %b %e, %Y, %l:%M %p %z'
|
||||
post:
|
||||
long: '%b %e, %Y'
|
||||
short: '%b %e'
|
||||
archive_month: '%b'
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: This post is licensed under :LICENSE_NAME by the author.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Some rights reserved.
|
||||
verbose: >-
|
||||
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: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
||||
hint_template: :HEAD_BAK to try finding it again, or search for it on the :ARCHIVES_PAGE.
|
||||
head_back: Head back Home
|
||||
archives_page: Archives page
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
published: 'on'
|
||||
updated: Updated
|
||||
timeago:
|
||||
day: days ago
|
||||
hour: hours ago
|
||||
minute: minutes ago
|
||||
just_now: just now
|
||||
words: words
|
||||
pageview_measure: views
|
||||
read_time:
|
||||
unit: min
|
||||
prompt: read
|
||||
relate_posts: Further Reading
|
||||
share: Share
|
||||
button:
|
||||
next: Newer
|
||||
previous: Older
|
||||
copy_code:
|
||||
succeed: Copied!
|
||||
share_link:
|
||||
title: Copy link
|
||||
succeed: Link copied successfully!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Pinned
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: categories
|
||||
post_measure: posts
|
||||
90
_data/locales/id-ID.yml
Normal file
90
_data/locales/id-ID.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Postingan
|
||||
category: Kategori
|
||||
tag: Tagar
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Beranda
|
||||
categories: Kategori
|
||||
tags: Tagar
|
||||
archives: Arsip
|
||||
about: Tentang
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: Cari
|
||||
cancel: Batal
|
||||
no_results: Ups! Tidak ada hasil yang ditemukan.
|
||||
|
||||
panel:
|
||||
lastmod: Postingan Terbaru
|
||||
trending_tags: Tagar Terpopuler
|
||||
toc: Konten
|
||||
|
||||
# The liquid date format › http://strftime.net/
|
||||
date_format:
|
||||
tooltip: "%a, %e %b, %Y, %l:%M %p"
|
||||
post:
|
||||
long: "%e %b, %Y"
|
||||
short: "%e %b"
|
||||
archive_month: "%b"
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Postingan ini dilisensikan di bawah :LICENSE_NAME oleh penulis.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Sebagian konten dilindungi.
|
||||
verbose: >-
|
||||
Kecuali jika dinyatakan, Postingan blog di situs ini dilisensikan
|
||||
di bawah Lisensi Creative Commons Attribution 4.0 International (CC BY 4.0) oleh penulis.
|
||||
|
||||
meta: Didukung oleh :PLATFORM dengan tema :THEME.
|
||||
|
||||
not_found:
|
||||
statment: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada.
|
||||
hint_template: :HEAD_BAK untuk mencoba mencari kembali, atau cari di :ARCHIVES_PAGE.
|
||||
head_back: Kembali ke Beranda
|
||||
archives_page: Halaman Arsip
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
published: "pada"
|
||||
updated: Diperbarui
|
||||
timeago:
|
||||
day: hari yang lalu
|
||||
hour: jam yang lalu
|
||||
minute: menit yang lalu
|
||||
just_now: baru saja
|
||||
words: kata
|
||||
pageview_measure: dilihat
|
||||
read_time:
|
||||
unit: menit
|
||||
prompt: baca
|
||||
relate_posts: Postingan Lainya
|
||||
share: Bagikan
|
||||
button:
|
||||
next: Terbaru
|
||||
previous: Terlama
|
||||
copy_code:
|
||||
succeed: Disalin!
|
||||
share_link:
|
||||
title: Salin tautan
|
||||
succeed: Tautan berhasil disalin!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Disematkan
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: kategori
|
||||
post_measure: Postingan
|
||||
89
_data/locales/zh-CN.yml
Normal file
89
_data/locales/zh-CN.yml
Normal file
@@ -0,0 +1,89 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: 文章
|
||||
category: 分类
|
||||
tag: 标签
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: 首页
|
||||
categories: 分类
|
||||
tags: 标签
|
||||
archives: 归档
|
||||
about: 关于
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: 搜索
|
||||
cancel: 取消
|
||||
no_results: 搜索结果为空
|
||||
|
||||
panel:
|
||||
lastmod: 最近更新
|
||||
trending_tags: 热门标签
|
||||
toc: 文章内容
|
||||
|
||||
# The liquid date format › http://strftime.net/
|
||||
date_format:
|
||||
tooltip: '%F, %R %z'
|
||||
post:
|
||||
long: '%F'
|
||||
short: '%m-%d'
|
||||
archive_month: '%m月'
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: 本文由作者按照 :LICENSE_NAME 进行授权
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: 保留部分权利。
|
||||
verbose: >-
|
||||
除非另有说明,本网站上的博客文章均由作者按照知识共享署名 4.0 国际 (CC BY 4.0) 许可协议进行授权。
|
||||
|
||||
meta: 本站由 :PLATFORM 生成,采用 :THEME 主题。
|
||||
|
||||
not_found:
|
||||
statment: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。
|
||||
hint_template: :HEAD_BAK尝试再次查找它,或在:ARCHIVES_PAGE上搜索它。
|
||||
head_back: 返回主页
|
||||
archives_page: 归档页面
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
published: 发表于
|
||||
updated: 更新于
|
||||
timeago:
|
||||
day: 天前
|
||||
hour: 小时前
|
||||
minute: 分钟前
|
||||
just_now: 刚刚
|
||||
words: 字
|
||||
pageview_measure: 次浏览
|
||||
read_time:
|
||||
unit: 分钟
|
||||
prompt: 阅读
|
||||
relate_posts: 相关文章
|
||||
share: 分享
|
||||
button:
|
||||
next: 下一篇
|
||||
previous: 上一篇
|
||||
copy_code:
|
||||
succeed: 已复制!
|
||||
share_link:
|
||||
title: 分享链接
|
||||
succeed: 链接已复制!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: 顶置
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: 个分类
|
||||
post_measure: 篇文章
|
||||
@@ -1,11 +0,0 @@
|
||||
# License data
|
||||
|
||||
license:
|
||||
name: CC BY 4.0
|
||||
link: "https://creativecommons.org/licenses/by/4.0/"
|
||||
|
||||
brief: Some rights reserved.
|
||||
|
||||
verbose: >-
|
||||
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.
|
||||
@@ -1,25 +1,54 @@
|
||||
<!--
|
||||
The Disqus lazy loading.
|
||||
Powered by: <https://github.com/osvaldasvalutis/disqusLoader.js>
|
||||
-->
|
||||
|
||||
<div id="disqus" class="pt-2 pb-2">
|
||||
<p class="text-center text-muted small pb-5">
|
||||
<div id="disqus_thread" class="pt-2 pb-2">
|
||||
<p class="text-center text-muted small">
|
||||
Comments powered by <a href="https://disqus.com/">Disqus</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script src="{{ '/assets/js/lib/jquery.disqusloader.min.js' | relative_url }}"></script>
|
||||
<script>
|
||||
const options = {
|
||||
scriptUrl: '//{{ site.disqus.shortname }}.disqus.com/embed.js',
|
||||
|
||||
disqusConfig: function() {
|
||||
this.page.title = '{{ page.title }}';
|
||||
this.page.url = '{{ page.url | absolute_url }}';
|
||||
this.page.identifier = '{{ page.url }}';
|
||||
}
|
||||
<script type="text/javascript">
|
||||
var disqus_config = function () {
|
||||
this.page.url = '{{ page.url | absolute_url }}';
|
||||
this.page.identifier = '{{ page.url }}';
|
||||
};
|
||||
|
||||
$.disqusLoader('#disqus', options);
|
||||
/* Lazy loading */
|
||||
|
||||
var disqus_observer = new IntersectionObserver(function (entries) {
|
||||
if(entries[0].isIntersecting) {
|
||||
(function () {
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://{{ site.disqus.shortname }}.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
|
||||
disqus_observer.disconnect();
|
||||
}
|
||||
}, { threshold: [0] });
|
||||
|
||||
disqus_observer.observe(document.querySelector('#disqus_thread'));
|
||||
|
||||
/* Auto switch theme */
|
||||
|
||||
function reloadDisqus() {
|
||||
/* Disqus hasn't been loaded */
|
||||
if (typeof DISQUS === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.readyState == 'complete') {
|
||||
DISQUS.reset({ reload: true, config: disqus_config });
|
||||
}
|
||||
}
|
||||
|
||||
const modeToggle = document.querySelector(".mode-toggle");
|
||||
|
||||
if (modeToggle !== null) {
|
||||
modeToggle.addEventListener('click', reloadDisqus);
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', reloadDisqus);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -8,21 +8,28 @@
|
||||
<p class="mb-0">
|
||||
© {{ 'now' | date: "%Y" }}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
{% if site.data.rights.brief %}
|
||||
{% if site.data.locales[lang].copyright.brief %}
|
||||
<span data-toggle="tooltip" data-placement="top"
|
||||
title="{{ site.data.rights.verbose }}">{{ site.data.rights.brief }}</span>
|
||||
title="{{ site.data.locales[lang].copyright.verbose }}">{{ site.data.locales[lang].copyright.brief }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-right">
|
||||
<p class="mb-0">
|
||||
Powered by
|
||||
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
|
||||
with
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy"
|
||||
target="_blank" rel="noopener">Chirpy</a>
|
||||
theme.
|
||||
{% capture _platform %}
|
||||
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
|
||||
{% endcapture %}
|
||||
|
||||
{% capture _theme %}
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
|
||||
{% endcapture %}
|
||||
|
||||
{{ site.data.locales[lang].meta
|
||||
| default: 'Powered by :PLATFORM with :THEME theme.'
|
||||
| replace: ':PLATFORM', _platform | replace: ':THEME', _theme
|
||||
}}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
{% if page.layout == 'home' or page.layout == 'post' %}
|
||||
|
||||
<!-- i18n for `_javascript/utils/timeago.js` -->
|
||||
<meta name="day-prompt" content="{{ site.data.locales[lang].post.timeago.day }}">
|
||||
<meta name="hour-prompt" content="{{ site.data.locales[lang].post.timeago.hour }}">
|
||||
<meta name="minute-prompt" content="{{ site.data.locales[lang].post.timeago.minute }}">
|
||||
<meta name="justnow-prompt" content="{{ site.data.locales[lang].post.timeago.just_now }}">
|
||||
|
||||
{% if site.google_analytics.pv.proxy_endpoint %}
|
||||
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
|
||||
{% endif %}
|
||||
@@ -62,13 +68,8 @@
|
||||
|
||||
{% include css-selector.html %}
|
||||
|
||||
<!-- JavaScripts -->
|
||||
<!-- JavaScript -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
|
||||
|
||||
<script defer
|
||||
src="https://cdn.jsdelivr.net/combine/npm/popper.js@1.15.0,npm/bootstrap@4/dist/js/bootstrap.min.js"></script>
|
||||
|
||||
{% include js-selector.html %}
|
||||
|
||||
</head>
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
JS selector for site.
|
||||
-->
|
||||
|
||||
<!-- layout specified -->
|
||||
|
||||
{% if page.layout == 'home' or page.layout == 'post' %}
|
||||
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
|
||||
<!-- pv-report needs countup.js -->
|
||||
<script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></script>
|
||||
<script async src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script>
|
||||
<script defer src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'post' or page.layout == 'page' %}
|
||||
<!-- image lazy-loading & popup -->
|
||||
<script async
|
||||
src="https://cdn.jsdelivr.net/combine/npm/lozad/dist/lozad.min.js,npm/magnific-popup@1/dist/jquery.magnific-popup.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/combine/npm/lozad/dist/lozad.min.js,npm/magnific-popup@1/dist/jquery.magnific-popup.min.js,npm/clipboard@2/dist/clipboard.min.js"></script>
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'home'
|
||||
@@ -51,6 +52,10 @@
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<!-- commons -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/combine/npm/popper.js@1.16.1,npm/bootstrap@4/dist/js/bootstrap.min.js"></script>
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
<!-- PWA -->
|
||||
<script defer src="{{ '/app.js' | relative_url }}"></script>
|
||||
|
||||
8
_includes/lang.html
Normal file
8
_includes/lang.html
Normal file
@@ -0,0 +1,8 @@
|
||||
{% comment %}
|
||||
Detect appearance language and return it through variable "lang"
|
||||
{% endcomment %}
|
||||
{% if site.data.locales[site.lang] %}
|
||||
{% assign lang = site.lang %}
|
||||
{% else %}
|
||||
{% assign lang = 'en' %}
|
||||
{% endif %}
|
||||
72
_includes/language-alias.html
Normal file
72
_includes/language-alias.html
Normal file
@@ -0,0 +1,72 @@
|
||||
{% comment %}
|
||||
|
||||
Convert the alias of the syntax language to the official name
|
||||
|
||||
See: <https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers>
|
||||
|
||||
{% endcomment %}
|
||||
|
||||
{% assign _lang = include.language | default: '' %}
|
||||
|
||||
{% case _lang %}
|
||||
{% when 'actionscript', 'as', 'as3' %}
|
||||
{{ 'ActionScript' }}
|
||||
{% when 'applescript' %}
|
||||
{{ 'AppleScript' }}
|
||||
{% when 'brightscript', 'bs', 'brs' %}
|
||||
{{ 'BrightScript' }}
|
||||
{% when 'cfscript', 'cfc' %}
|
||||
{{ 'CFScript' }}
|
||||
{% when 'coffeescript', 'coffee', 'coffee-script' %}
|
||||
{{ 'CoffeeScript' }}
|
||||
{% when 'cs', 'csharp' %}
|
||||
{{ 'C#' }}
|
||||
{% when 'erl' %}
|
||||
{{ 'Erlang' }}
|
||||
{% when 'graphql' %}
|
||||
{{ 'GraphQL' }}
|
||||
{% when 'haskell', 'hs' %}
|
||||
{{ 'Haskell' }}
|
||||
{% when 'javascript', 'js' %}
|
||||
{{ 'JavaScript' }}
|
||||
{% when 'make', 'mf', 'gnumake', 'bsdmake' %}
|
||||
{{ 'Makefile' }}
|
||||
{% when 'md', 'mkd' %}
|
||||
{{ 'Markdown' }}
|
||||
{% when 'm' %}
|
||||
{{ 'Matlab' }}
|
||||
{% when 'objective_c', 'objc', 'obj-c', 'obj_c', 'objectivec' %}
|
||||
{{ 'Objective-C' }}
|
||||
{% when 'perl', 'pl' %}
|
||||
{{ 'Perl' }}
|
||||
{% when 'php','php3','php4','php5' %}
|
||||
{{ 'PHP' }}
|
||||
{% when 'plaintext', 'text' %}
|
||||
{{ 'Text' }}
|
||||
{% when 'py' %}
|
||||
{{ 'Python' }}
|
||||
{% when 'rb' %}
|
||||
{{ 'Ruby' }}
|
||||
{% when 'rs','no_run','ignore','should_panic' %}
|
||||
{{ 'Rust' }}
|
||||
{% when 'bash', 'zsh', 'ksh', 'sh' %}
|
||||
{{ 'Shell' }}
|
||||
{% when 'st', 'squeak' %}
|
||||
{{ 'Smalltalk' }}
|
||||
{% when 'tex'%}
|
||||
{{ 'TeX' }}
|
||||
{% when 'latex' %}
|
||||
{{ 'LaTex' }}
|
||||
{% when 'ts', 'typescript' %}
|
||||
{{ 'TypeScript' }}
|
||||
{% when 'vb', 'visualbasic' %}
|
||||
{{ 'Visual Basic' }}
|
||||
{% when 'vue', 'vuejs' %}
|
||||
{{ 'Vue.js' }}
|
||||
{% when 'yml' %}
|
||||
{{ 'YAML' }}
|
||||
{% when 'css', 'html', 'scss', 'ssh', 'toml', 'xml', 'yaml' %}
|
||||
{{ _lang | upcase }}
|
||||
{% else %}
|
||||
{{ _lang | capitalize }}
|
||||
{% endcase %}
|
||||
13
_includes/no-zero-date.html
Normal file
13
_includes/no-zero-date.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{% comment %}
|
||||
Remove the zero padding from a month/day string
|
||||
{% endcomment %}
|
||||
|
||||
{% assign ret = include.date_str %}
|
||||
{% assign _first_chat = ret | slice: 0 %}
|
||||
|
||||
{% if _first_chat == '0' %}
|
||||
{% assign _last_idx = ret.size | minus: 1 %}
|
||||
{% assign ret = ret | slice: 1, _last_idx %}
|
||||
{% endif %}
|
||||
|
||||
{{ ret | replace: ' 0', ' ' }}
|
||||
@@ -2,6 +2,8 @@
|
||||
The Pannel on right side (Desktop views)
|
||||
-->
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<div id="panel-wrapper" class="col-xl-3 pl-2 text-muted topbar-down">
|
||||
|
||||
<div class="access">
|
||||
@@ -11,7 +13,7 @@
|
||||
{% if update_list.size > 0 %}
|
||||
|
||||
<div id="access-lastmod" class="post">
|
||||
<span>{{- site.data.label.panel.lastmod | default: 'Recent Update' -}}</span>
|
||||
<span>{{- site.data.locales[lang].panel.lastmod -}}</span>
|
||||
<ul class="post-content pl-0 pb-1 ml-1 mt-2">
|
||||
|
||||
{% for item in update_list %}
|
||||
@@ -30,7 +32,7 @@
|
||||
|
||||
{% if trending_tags.size > 0 %}
|
||||
<div id="access-tags">
|
||||
<span>{{- site.data.label.panel.trending_tags | default: 'Trending Tags' -}}</span>
|
||||
<span>{{- site.data.locales[lang].panel.trending_tags -}}</span>
|
||||
<div class="d-flex flex-wrap mt-3 mb-1 mr-3">
|
||||
|
||||
{% for tag_name in trending_tags %}
|
||||
@@ -48,7 +50,7 @@
|
||||
<script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js"></script>
|
||||
<div id="toc-wrapper" class="pl-0 pr-4 mb-5">
|
||||
<span class="pl-3 pt-2 mb-2">
|
||||
{{- site.data.label.panel.toc | default: 'Contents' -}}
|
||||
{{- site.data.locales[lang].panel.toc -}}
|
||||
</span>
|
||||
<nav id="toc" data-toggle="toc"></nav>
|
||||
</div>
|
||||
|
||||
@@ -5,24 +5,24 @@
|
||||
<div class="post-navigation d-flex justify-content-between">
|
||||
{% if page.previous.url %}
|
||||
<a href="{{ site.baseurl }}{{ page.previous.url }}" class="btn btn-outline-primary"
|
||||
prompt="{{ site.data.label.post.button.previous | default: 'previous' }}">
|
||||
prompt="{{ site.data.locales[lang].post.button.previous }}">
|
||||
<p>{{ page.previous.title }}</p>
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.label.post.button.previous | default: 'previous' }}">
|
||||
prompt="{{ site.data.locales[lang].post.button.previous }}">
|
||||
<p>-</p>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% if page.next.url %}
|
||||
<a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary"
|
||||
prompt="{{ site.data.label.post.button.next | default: 'next' }}">
|
||||
prompt="{{ site.data.locales[lang].post.button.next }}">
|
||||
<p>{{ page.next.title }}</p>
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.label.post.button.next | default: 'next' }}">
|
||||
prompt="{{ site.data.locales[lang].post.button.next }}">
|
||||
<p>-</p>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
The paginator for post list on HomgPage.
|
||||
-->
|
||||
|
||||
<ul class="pagination mt-4 mb-0 pl-lg-2">
|
||||
<ul class="pagination align-items-center mt-4 mb-0 pl-lg-2">
|
||||
<!-- left arrow -->
|
||||
{% if paginator.previous_page %}
|
||||
{% assign prev_url = paginator.previous_page_path | relative_url %}
|
||||
{% else %}
|
||||
{% assign prev_url = "#" %}
|
||||
{% endif %}
|
||||
|
||||
<li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
|
||||
<a class="page-link btn-box-shadow" href="{{ prev_url }}" aria-label="previous-page">
|
||||
<i class="fas fa-angle-left"></i>
|
||||
@@ -65,12 +66,19 @@
|
||||
|
||||
{% endfor %}
|
||||
|
||||
<!-- mobile pagination -->
|
||||
<li class="page-index align-middle">
|
||||
<span>{{ paginator.page }}</span>
|
||||
<span class="text-muted">/ {{ paginator.total_pages }}</span>
|
||||
</li>
|
||||
|
||||
<!-- right arrow -->
|
||||
{% if paginator.next_page_path %}
|
||||
{% assign next_url = paginator.next_page_path | relative_url %}
|
||||
{% else %}
|
||||
{% assign next_url = "#" %}
|
||||
{% endif %}
|
||||
|
||||
<li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
|
||||
<a class="page-link btn-box-shadow" href="{{ next_url }}" aria-label="next-page">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
-->
|
||||
|
||||
<div class="share-wrapper">
|
||||
<span class="share-label text-muted mr-1">{{ site.data.label.post.share | default: 'Share' }}</span>
|
||||
<span class="share-label text-muted mr-1">{{ site.data.locales[lang].post.share }}</span>
|
||||
<span class="share-icons">
|
||||
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
|
||||
{% assign url = page.url | absolute_url %}
|
||||
@@ -16,8 +16,11 @@
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
||||
<i class="fa-fw fas fa-link small" onclick="copyLink()"
|
||||
data-toggle="tooltip" data-placement="top" title="Copy link"></i>
|
||||
<i id="copy-link" class="fa-fw fas fa-link small"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="{{ site.data.locales[lang].post.button.share_link.title }}"
|
||||
title-succeed="{{ site.data.locales[lang].post.button.share_link.succeed }}">
|
||||
</i>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<!--
|
||||
Calculate the post's reading time, and display the word count in tooltip
|
||||
-->
|
||||
|
||||
{% assign words = include.content | strip_html | number_of_words: "auto" %}
|
||||
|
||||
<!-- words per minute -->
|
||||
|
||||
{% assign wpm = 180 %}
|
||||
{% assign min_time = 1 %}
|
||||
|
||||
@@ -13,7 +15,16 @@
|
||||
{% assign read_time = min_time %}
|
||||
{% endunless %}
|
||||
|
||||
{% capture read_prompt %}
|
||||
{{- site.data.locales[lang].post.read_time.prompt -}}
|
||||
{% endcapture %}
|
||||
|
||||
<!-- return element -->
|
||||
<span class="readtime" data-toggle="tooltip" data-placement="bottom" title="{{ words }} words">
|
||||
{{- read_time -}}{{" "}}{{- site.data.label.read_time_unit | default: "min" -}}
|
||||
<span class="readtime" data-toggle="tooltip" data-placement="bottom"
|
||||
title="{{ words }} {{ site.data.locales[lang].post.words }}">
|
||||
{{- read_time -}}{{" "}}{{- site.data.locales[lang].post.read_time.unit -}}
|
||||
{%- if include.prompt -%}
|
||||
{% assign _prompt_words = read_prompt | number_of_words: 'auto' %}
|
||||
{% unless _prompt_words > 1 %}{{" "}}{% endunless %}{{ read_prompt }}
|
||||
{%- endif -%}
|
||||
</span>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
In order to allow a wide table to scroll horizontally,
|
||||
we suround the markdown table with `<div class="table-wrapper">` and `</div>`
|
||||
-->
|
||||
|
||||
{% if _content contains '<table>' %}
|
||||
{% assign _content = _content
|
||||
| replace: '<table>', '<div class="table-wrapper"><table>'
|
||||
@@ -21,6 +22,7 @@
|
||||
https://github.com/penibelst/jekyll-compress-html/issues/101
|
||||
https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
|
||||
-->
|
||||
|
||||
{% if _content contains '<pre class="highlight">' %}
|
||||
{% assign _content = _content
|
||||
| replace: '<div class="highlight"><pre class="highlight"><code', '<div class="highlight"><code'
|
||||
@@ -29,14 +31,20 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- Add attribute 'hide-bullet' to the checkbox list -->
|
||||
|
||||
{% if _content contains '<li class="task-list-item"><' %}
|
||||
{% assign _content = _content
|
||||
| replace: '"task-list-item"><', '"task-list-item" hide-bullet><'
|
||||
%}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<!-- images -->
|
||||
|
||||
{% if _content contains '<img src="' %}
|
||||
|
||||
<!-- add CDN prefix if it exists -->
|
||||
|
||||
{% if site.img_cdn != '' %}
|
||||
{% assign img_path_replacement = '<img src="' | append: site.img_cdn | append: '/' %}
|
||||
{% else %}
|
||||
@@ -46,16 +54,100 @@
|
||||
{% assign _content = _content | replace: '<img src="/', img_path_replacement %}
|
||||
|
||||
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
|
||||
{% assign img_placehodler
|
||||
= 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' %}
|
||||
|
||||
{% assign lozad_replacement = '<img src="'
|
||||
| append: img_placehodler
|
||||
| append: '" data-src="' %}
|
||||
{% assign _content = _content | replace: '<img src="', '<img data-proofer-ignore data-src="' %}
|
||||
|
||||
{% assign _content = _content | replace: '<img src="', lozad_replacement %}
|
||||
<!-- add image placehoder to prevent layout reflow -->
|
||||
|
||||
{% assign _img_content = nil %}
|
||||
|
||||
{% assign _images = _content | split: '<img ' %}
|
||||
|
||||
{% for _img in _images %}
|
||||
{% if forloop.first %}
|
||||
{% assign _img_content = _img %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign _width = nil %}
|
||||
{% assign _height = nil %}
|
||||
{% assign _attrs = _img | split: '>' | first | split: ' ' %}
|
||||
|
||||
{% for _attr in _attrs %}
|
||||
{% capture _key %}{{ _attr | split: '=' | first }}{% endcapture %}
|
||||
{% capture _value %}{{ _attr | split: '=' | last | replace: '"', '' }}{% endcapture %}
|
||||
|
||||
{% case _key %}
|
||||
{% when 'width' %}
|
||||
{% assign _width = _value %}
|
||||
{% when 'height' %}
|
||||
{% assign _height = _value %}
|
||||
{% endcase %}
|
||||
|
||||
{% if _width and _height %}
|
||||
{% capture _svg %}data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{_width}} {{_height}}'%3E%3C/svg%3E{% endcapture %}
|
||||
{% assign _img_content = _img_content | append: '<img src="' | append: _svg | append: '" ' | append: _img %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% unless _width and _height %}
|
||||
{% assign _img_content = _img_content | append: '<img ' | append: _img %}
|
||||
{% endunless %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% assign _content = _img_content %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- Add header for code snippets -->
|
||||
|
||||
{% if _content contains '<div class="highlight"><code>' %}
|
||||
{% assign _code_spippets = _content | split: '<div class="highlight"><code>' %}
|
||||
{% assign _new_content = '' %}
|
||||
|
||||
{% for _snippet in _code_spippets %}
|
||||
|
||||
{% if forloop.last %}
|
||||
{% assign _new_content = _new_content | append: _snippet %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% assign _left = _snippet | split: '><' | last%}
|
||||
|
||||
{% if _left contains 'file="' %}
|
||||
{% assign _text = _left | split: 'file="' | last | split: '"' | first %}
|
||||
{% assign _label_icon = 'far fa-file-code' %}
|
||||
{% else %}
|
||||
{% assign _lang = _left | split: 'language-' | last | split: ' ' | first %}
|
||||
{% capture _text %}{% include language-alias.html language=_lang %}{% endcapture %}
|
||||
{% assign _label_icon = 'fas fa-code small' %}
|
||||
{% endif %}
|
||||
|
||||
{% capture _label %}
|
||||
<span text-data="{{ _text }}"><i class="fa-fw {{ _label_icon }}"></i></span>
|
||||
{% endcapture %}
|
||||
|
||||
{% assign _new_content = _new_content | append: _snippet
|
||||
| append: '<div class="code-header">'
|
||||
| append: _label
|
||||
| append: '<button aria-label="copy" title-succeed="'
|
||||
| append: site.data.locales[lang].post.button.copy_code.succeed
|
||||
| append: '"><i class="far fa-clipboard"></i></button></div>'
|
||||
| append: '<div class="highlight"><code>'
|
||||
%}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% assign _content = _new_content %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
<!-- return -->
|
||||
|
||||
{{ _content }}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
{% if index_list.size > 0 %}
|
||||
<div id="related-posts" class="mt-5 mb-2 mb-sm-4">
|
||||
<h3 class="pt-2 mt-1 mb-4 ml-1"
|
||||
data-toc-skip>{{ site.data.label.post.relate_posts | default: 'Further Reading' }}</h3>
|
||||
data-toc-skip>{{ site.data.locales[lang].post.relate_posts }}</h3>
|
||||
<div class="card-deck mb-4">
|
||||
{% for entry in index_list %}
|
||||
{% assign index = entry | plus: 0 %}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
</div>
|
||||
{% endcapture %}
|
||||
|
||||
{% capture not_found %}<p class="mt-5">Oops! No result founds.</p>{% endcapture %}
|
||||
{% capture not_found %}<p class="mt-5">{{ site.data.locales[lang].search.no_results }}</p>{% endcapture %}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.7.3/dest/simple-jekyll-search.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js"></script>
|
||||
|
||||
<script>
|
||||
SimpleJekyllSearch({
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
|
||||
<div class="col-12 col-sm-11 post-content">
|
||||
<div id="search-hints">
|
||||
<h4 class="text-muted mb-4">{{ site.data.label.panel.trending_tags | default: 'Trending Tags' }}</h4>
|
||||
<h4 class="text-muted mb-4">{{ site.data.locales[lang].panel.trending_tags }}</h4>
|
||||
|
||||
{% include trending-tags.html %}
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
The Side Bar
|
||||
-->
|
||||
|
||||
<div id="sidebar" class="d-flex flex-column align-items-end">
|
||||
|
||||
<div id="sidebar" class="d-flex flex-column align-items-end" lang="{{lang}}">
|
||||
<div class="profile-wrapper text-center">
|
||||
<div id="avatar">
|
||||
<a href="{{ '/' | relative_url }}" alt="avatar" class="mx-auto">
|
||||
@@ -21,19 +20,19 @@
|
||||
</div>
|
||||
|
||||
<div class="site-title mt-3">
|
||||
<a href="{{ '/' | relative_url }}">{{- site.title -}}</a>
|
||||
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
||||
</div>
|
||||
|
||||
<div class="site-subtitle font-italic">{{- site.tagline -}}</div>
|
||||
<div class="site-subtitle font-italic">{{ site.tagline }}</div>
|
||||
|
||||
</div><!-- .profile-wrapper -->
|
||||
|
||||
<ul class="w-100">
|
||||
|
||||
<!-- home -->
|
||||
<li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ '/' | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw fas fa-home ml-xl-3 mr-xl-3 unloaded"></i>
|
||||
<span>{{ "HOME" }}</span>
|
||||
<span>{{ site.data.locales[lang].tabs.home | upcase }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- the real tabs -->
|
||||
@@ -41,14 +40,16 @@
|
||||
<li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ tab.url | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw {{ tab.icon }} ml-xl-3 mr-xl-3 unloaded"></i>
|
||||
<span>{{ tab.title | upcase }}</span>
|
||||
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %}
|
||||
|
||||
<span>{{ site.data.locales[lang].tabs.[tab_name] | default: tab.title | upcase }}</span>
|
||||
</a>
|
||||
</li> <!-- .nav-item -->
|
||||
{% endfor %}
|
||||
|
||||
</ul> <!-- ul.nav.flex-column -->
|
||||
|
||||
<div class="sidebar-bottom mt-auto d-flex flex-wrap justify-content-center">
|
||||
<div class="sidebar-bottom mt-auto d-flex flex-wrap justify-content-center align-items-center">
|
||||
|
||||
{% for entry in site.data.contact %}
|
||||
{% capture url %}
|
||||
|
||||
@@ -3,29 +3,25 @@
|
||||
See: /assets/js/_utils/timeage.js
|
||||
-->
|
||||
|
||||
{% assign tooltip_df = site.data.date_format.tooltip | default: '%a, %b %e, %Y, %l:%M %p %z' %}
|
||||
{% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
|
||||
{% assign post_short_df = site.data.date_format.post.short | default: '%b %e' %}
|
||||
{% assign tooltip_df = site.data.locales[lang].date_format.tooltip %}
|
||||
{% assign post_long_df = site.data.locales[lang].date_format.post.long %}
|
||||
{% assign post_short_df = site.data.locales[lang].date_format.post.short %}
|
||||
|
||||
{% if include.preposition %}
|
||||
{{ include.preposition }}
|
||||
{% endif %}
|
||||
<span class="timeago {% if include.class %}{{ include.class }}{% endif %}"
|
||||
{% if include.tooltip %}
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="{{ include.date | date: tooltip_df }}"
|
||||
{% endif %}
|
||||
|
||||
{% if include.prefix %}prefix="{{ include.prefix }} "{% endif%}
|
||||
{% if include.prep %}prep="{{ include.prep }}"{% endif %} >
|
||||
|
||||
{% assign this_year = site.time | date: "%Y" %}
|
||||
{% assign post_year = include.date | date: "%Y" %}
|
||||
|
||||
{% if post_year == this_year %}
|
||||
{% endif %}>
|
||||
{%- assign this_year = site.time | date: "%Y" -%}
|
||||
{%- assign post_year = include.date | date: "%Y" -%}
|
||||
{%- if post_year == this_year -%}
|
||||
{{ include.date | date: post_short_df }}
|
||||
{% else %}
|
||||
{%- else -%}
|
||||
{{ include.date | date: post_long_df }}
|
||||
{% endif %}
|
||||
|
||||
{%- endif -%}
|
||||
<i class="unloaded">{{ include.date | date_to_xmlschema }}</i>
|
||||
|
||||
</span>
|
||||
|
||||
@@ -8,34 +8,35 @@
|
||||
|
||||
{% assign paths = page.url | split: '/' %}
|
||||
|
||||
{% if paths.size == 0 %}
|
||||
{% if paths.size == 0 or page.layout == 'home' %}
|
||||
<!-- index page -->
|
||||
<span>{{ 'Posts' }}</span>
|
||||
<span>{{ site.data.locales[lang].tabs.home | capitalize }}</span>
|
||||
|
||||
{% else %}
|
||||
|
||||
{% for item in paths %}
|
||||
|
||||
{% if forloop.first %}
|
||||
{% unless page.layout == 'post' %}
|
||||
<span>
|
||||
<a href="{{ '/' | relative_url }}">{{ 'Home' }}</a>
|
||||
<a href="{{ '/' | relative_url }}">
|
||||
{{ site.data.locales[lang].tabs.home | capitalize }}
|
||||
</a>
|
||||
</span>
|
||||
{% endunless %}
|
||||
|
||||
{% elsif forloop.last %}
|
||||
<span>{{ page.title }}</span>
|
||||
|
||||
{% else %}
|
||||
<span>
|
||||
{% assign url = item %}
|
||||
{% if item == 'posts' and page.layout == 'post' %}
|
||||
{% assign url = '/' %}
|
||||
{% if page.collection == 'tabs' %}
|
||||
<span>{{ site.data.locales[lang].tabs[item] | default: page.title }}</span>
|
||||
{% else %}
|
||||
<span>{{ page.title }}</span>
|
||||
{% endif %}
|
||||
<a href="{{ url | relative_url }}">
|
||||
{{ item | capitalize }}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
{% elsif page.layout == 'category' or page.layout == 'tag' %}
|
||||
<span>
|
||||
<a href="{{ item | relative_url }}">
|
||||
{{ site.data.locales[lang].tabs[item] | default: page.title }}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
@@ -48,11 +49,12 @@
|
||||
|
||||
<div id="topbar-title">
|
||||
{% if page.layout == 'home' %}
|
||||
{{- site.title -}}
|
||||
{% elsif page.dynamic_title %}
|
||||
{{- page.title -}}
|
||||
{{- site.data.locales[lang].title | default: site.title -}}
|
||||
{% elsif page.collection == 'tabs' %}
|
||||
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
|
||||
{{- site.data.locales[lang].tabs[tab_key] | default: page.title -}}
|
||||
{% else %}
|
||||
{{- page.layout | capitalize -}}
|
||||
{{- site.data.locales[lang].layout[page.layout] | default: page.layout | capitalize -}}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -60,10 +62,10 @@
|
||||
<span id="search-wrapper" class="align-items-center">
|
||||
<i class="fas fa-search fa-fw"></i>
|
||||
<input class="form-control" id="search-input" type="search"
|
||||
aria-label="search" autocomplete="off" placeholder="{{ site.data.label.search_hint | default: 'Search' }}...">
|
||||
aria-label="search" autocomplete="off" placeholder="{{ site.data.locales[lang].search.hint | capitalize }}...">
|
||||
<i class="fa fa-times-circle fa-fw" id="search-cleaner"></i>
|
||||
</span>
|
||||
<span id="search-cancel" >Cancel</span>
|
||||
<span id="search-cancel" >{{ site.data.locales[lang].search.cancel }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* Chirpy v4.3.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
131
_javascript/utils/clipboard.js
Normal file
131
_javascript/utils/clipboard.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Clipboard functions
|
||||
*
|
||||
* Dependencies:
|
||||
* - popper.js (https://github.com/popperjs/popper-core)
|
||||
* - clipboard.js (https://github.com/zenorocha/clipboard.js)
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
const btnSelector = '.code-header>button';
|
||||
const ICON_SUCCESS = 'fas fa-check';
|
||||
const ATTR_TIMEOUT = 'timeout';
|
||||
const TIMEOUT = 2000; // in milliseconds
|
||||
|
||||
function isLocked(node) {
|
||||
if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) {
|
||||
let timeout = $(node).attr(ATTR_TIMEOUT);
|
||||
if (Number(timeout) > Date.now()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function lock(node) {
|
||||
$(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||
}
|
||||
|
||||
function unlock(node) {
|
||||
$(node).removeAttr(ATTR_TIMEOUT);
|
||||
}
|
||||
|
||||
/* --- Copy code block --- */
|
||||
|
||||
// Initial the clipboard.js object
|
||||
const clipboard = new ClipboardJS(btnSelector, {
|
||||
target(trigger) {
|
||||
let codeBlock = trigger.parentNode.nextElementSibling;
|
||||
return codeBlock.querySelector('code .rouge-code');
|
||||
}
|
||||
});
|
||||
|
||||
$(btnSelector).tooltip({
|
||||
trigger: 'hover',
|
||||
placement: 'left'
|
||||
});
|
||||
|
||||
function getIcon(btn) {
|
||||
let iconNode = $(btn).children();
|
||||
return iconNode.attr('class');
|
||||
}
|
||||
|
||||
const ICON_DEFAULT = getIcon(btnSelector);
|
||||
|
||||
function showTooltip(btn) {
|
||||
const succeedTitle = $(btn).attr('title-succeed');
|
||||
$(btn).attr('data-original-title', succeedTitle).tooltip('show');
|
||||
}
|
||||
|
||||
function hideTooltip(btn) {
|
||||
$(btn).tooltip('hide').removeAttr('data-original-title');
|
||||
}
|
||||
|
||||
function setSuccessIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_SUCCESS);
|
||||
}
|
||||
|
||||
function resumeIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_DEFAULT);
|
||||
}
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
e.clearSelection();
|
||||
|
||||
const trigger = e.trigger;
|
||||
if (isLocked(trigger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSuccessIcon(trigger);
|
||||
showTooltip(trigger);
|
||||
lock(trigger);
|
||||
|
||||
setTimeout(() => {
|
||||
hideTooltip(trigger);
|
||||
resumeIcon(trigger);
|
||||
unlock(trigger);
|
||||
}, TIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
/* --- Post link sharing --- */
|
||||
|
||||
$('#copy-link').click((e) => {
|
||||
|
||||
let target = $(e.target);
|
||||
|
||||
if (isLocked(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy URL to clipboard
|
||||
|
||||
const url = window.location.href;
|
||||
const $temp = $("<input>");
|
||||
|
||||
$("body").append($temp);
|
||||
$temp.val(url).select();
|
||||
document.execCommand("copy");
|
||||
$temp.remove();
|
||||
|
||||
// Switch tooltip title
|
||||
|
||||
const defaultTitle = target.attr('data-original-title');
|
||||
const succeedTitle = target.attr('title-succeed');
|
||||
|
||||
target.attr('data-original-title', succeedTitle).tooltip('show');
|
||||
lock(target);
|
||||
|
||||
setTimeout(() => {
|
||||
target.attr('data-original-title', defaultTitle);
|
||||
unlock(target);
|
||||
}, TIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copy current page url to clipboard.
|
||||
*/
|
||||
|
||||
function copyLink(url) {
|
||||
if (!url || 0 === url.length) {
|
||||
url = window.location.href;
|
||||
}
|
||||
|
||||
const $temp = $("<input>");
|
||||
$("body").append($temp);
|
||||
$temp.val(url).select();
|
||||
document.execCommand("copy");
|
||||
$temp.remove();
|
||||
|
||||
alert("Link copied successfully!");
|
||||
|
||||
}
|
||||
@@ -11,10 +11,10 @@ $(function() {
|
||||
return;
|
||||
}
|
||||
|
||||
/* lozy loading */
|
||||
/* lazy loading */
|
||||
|
||||
const imgs = document.querySelectorAll(`${IMG_SCOPE} img[data-src]`);
|
||||
const observer = lozad(imgs);
|
||||
const imgList = document.querySelectorAll(`${IMG_SCOPE} img[data-src]`);
|
||||
const observer = lozad(imgList);
|
||||
observer.observe();
|
||||
|
||||
/* popup */
|
||||
@@ -40,9 +40,8 @@ $(function() {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* markup the image links */
|
||||
$(`${IMG_SCOPE} a`).has("img").addClass('img-link');
|
||||
|
||||
$(`${IMG_SCOPE} a`).has('img').addClass('img-link');
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Add language indicator to code snippets
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
const prefix = "language-";
|
||||
const regex = new RegExp(`^${prefix}([a-z])+$`);
|
||||
|
||||
$(`div[class^=${prefix}`).each(function() {
|
||||
let classes = $(this).attr("class").split(" ");
|
||||
|
||||
classes.forEach((_class) => {
|
||||
if (regex.test(_class)) {
|
||||
let lang = _class.substring(prefix.length);
|
||||
$(this).attr("lang", `${lang}`);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -10,26 +10,18 @@ $(function() {
|
||||
|
||||
let intervalId = void 0;
|
||||
|
||||
function timeago(iso, preposition) {
|
||||
const dPrompt = $("meta[name=day-prompt]").attr("content");
|
||||
const hrPrompt = $("meta[name=hour-prompt]").attr("content");
|
||||
const minPrompt = $("meta[name=minute-prompt]").attr("content");
|
||||
const justnowPrompt = $("meta[name=justnow-prompt]").attr("content");
|
||||
|
||||
function timeago(isoDate, dateStr) {
|
||||
let now = new Date();
|
||||
let past = new Date(iso);
|
||||
let prep = (typeof preposition !== "undefined" ? `${preposition} ` : "");
|
||||
let past = new Date(isoDate);
|
||||
|
||||
if (past.getFullYear() !== now.getFullYear()) {
|
||||
toRefresh -= 1;
|
||||
return prep + past.toLocaleString("en-US", {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
if (past.getMonth() !== now.getMonth()) {
|
||||
toRefresh -= 1;
|
||||
return prep + past.toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric"
|
||||
});
|
||||
if (past.getFullYear() !== now.getFullYear()
|
||||
|| past.getMonth() !== now.getMonth()) {
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
let seconds = Math.floor((now - past) / 1000);
|
||||
@@ -37,28 +29,29 @@ $(function() {
|
||||
let day = Math.floor(seconds / 86400);
|
||||
if (day >= 1) {
|
||||
toRefresh -= 1;
|
||||
return day + " day" + (day > 1 ? "s" : "") + " ago";
|
||||
return ` ${day} ${dPrompt}`;
|
||||
}
|
||||
|
||||
let hour = Math.floor(seconds / 3600);
|
||||
if (hour >= 1) {
|
||||
return hour + " hour" + (hour > 1 ? "s" : "") + " ago";
|
||||
return ` ${hour} ${hrPrompt}`;
|
||||
}
|
||||
|
||||
let minute = Math.floor(seconds / 60);
|
||||
if (minute >= 1) {
|
||||
return minute + " minute" + (minute > 1 ? "s" : "") + " ago";
|
||||
return ` ${minute} ${minPrompt}`;
|
||||
}
|
||||
|
||||
return "just now";
|
||||
return justnowPrompt;
|
||||
}
|
||||
|
||||
function updateTimeago() {
|
||||
$(".timeago").each(function() {
|
||||
if ($(this).children("i").length > 0) {
|
||||
let dateStr = $(this).clone().children().remove().end().text();
|
||||
let node = $(this).children("i");
|
||||
let date = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */
|
||||
$(this).text(timeago(date, $(this).attr("prep")));
|
||||
let iosDate = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */
|
||||
$(this).text(timeago(iosDate, dateStr));
|
||||
$(this).append(node);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,8 +3,10 @@ layout: page
|
||||
# The Archives of posts.
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<div id="archives" class="pl-xl-2">
|
||||
|
||||
{% for post in site.posts %}
|
||||
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
|
||||
{% capture pre_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
|
||||
@@ -17,9 +19,10 @@ layout: page
|
||||
<li>
|
||||
<div>
|
||||
{% capture this_day %}{{ post.date | date: "%d" }}{% endcapture %}
|
||||
{% capture this_month %}{{ post.date | date: "%b" }}{% endcapture %}
|
||||
{% capture _mth_df %}{{ site.data.locales[lang].date_format.post.archive_month }}{% endcapture %}
|
||||
{% capture this_month %}{{ post.date | date: _mth_df }}{% endcapture %}
|
||||
<span class="date day">{{ this_day }}</span>
|
||||
<span class="date month small text-muted">{{ this_month }}</span>
|
||||
<span class="date month small text-muted">{% include no-zero-date.html date_str=this_month %}</span>
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -3,6 +3,7 @@ layout: page
|
||||
# All the Categories of posts
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
{% assign HEAD_PREFIX = "h_" %}
|
||||
{% assign LIST_PREFIX = "l_" %}
|
||||
@@ -33,28 +34,23 @@ layout: page
|
||||
|
||||
<div class="card categories">
|
||||
<!-- top-category -->
|
||||
<div class="card-header d-flex justify-content-between hide-border-bottom"
|
||||
id="{{ HEAD_PREFIX }}{{ group_index }}">
|
||||
<div id="{{ HEAD_PREFIX }}{{ group_index }}"
|
||||
class="card-header d-flex justify-content-between hide-border-bottom">
|
||||
<span>
|
||||
{% if sub_categories_size > 0 %}
|
||||
<i class="far fa-folder-open fa-fw"></i>
|
||||
{% else %}
|
||||
<i class="far fa-folder fa-fw"></i>
|
||||
{% endif %}
|
||||
<a href="{{ site.baseurl }}/categories/{{ category_name | slugify | url_encode }}/"
|
||||
class="ml-1 mr-2">
|
||||
{{ category_name }}
|
||||
</a>
|
||||
<i class="far fa-folder{% if sub_categories_size > 0 %}-open{% endif %} fa-fw"></i>
|
||||
|
||||
{% capture _category_url %}/categories/{{ category_name | slugify | url_encode }}/{% endcapture %}
|
||||
<a href="{{ _category_url | relative_url }}" class="ml-1 mr-2">{{ category_name }}</a>
|
||||
|
||||
<!-- content count -->
|
||||
{% assign top_posts_size = site.categories[category_name] | size %}
|
||||
<span class="text-muted small font-weight-light">
|
||||
{% if sub_categories_size > 0 %}
|
||||
{{ sub_categories_size }}
|
||||
{% if sub_categories_size > 1 %}categories{% else %}category{% endif %},
|
||||
{{ site.data.locales[lang].categories.category_measure }},
|
||||
{% endif %}
|
||||
{{ top_posts_size }}
|
||||
post{% if top_posts_size > 1 %}s{% endif %}
|
||||
{{ site.data.locales[lang].categories.post_measure }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -80,11 +76,14 @@ layout: page
|
||||
{% for sub_category in sub_categories %}
|
||||
<li class="list-group-item">
|
||||
<i class="far fa-folder fa-fw"></i>
|
||||
<a href="{{ site.baseurl }}/categories/{{ sub_category | slugify | url_encode }}/"
|
||||
class="ml-1 mr-2">{{ sub_category }}</a>
|
||||
|
||||
{% capture _sub_ctg_url %}/categories/{{ sub_category | slugify | url_encode }}/{% endcapture %}
|
||||
<a href="{{ _sub_ctg_url | relative_url }}" class="ml-1 mr-2">{{ sub_category }}</a>
|
||||
|
||||
{% assign posts_size = site.categories[sub_category] | size %}
|
||||
<span class="text-muted small font-weight-light">{{ posts_size }}
|
||||
post{% if posts_size > 1 %}s{% endif %}
|
||||
<span class="text-muted small font-weight-light">
|
||||
{{ posts_size }}
|
||||
{{ site.data.locales[lang].categories.post_measure }}
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
@@ -3,6 +3,8 @@ layout: page
|
||||
# The Category layout
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<div id="page-category">
|
||||
<h1 class="pl-lg-2">
|
||||
<i class="far fa-folder-open fa-fw text-muted"></i>
|
||||
@@ -11,13 +13,13 @@ layout: page
|
||||
</h1>
|
||||
|
||||
<ul class="post-content pl-0">
|
||||
{% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
|
||||
{% assign post_df = site.data.locales[lang].date_format.post.long %}
|
||||
|
||||
{% for post in page.posts %}
|
||||
<li class="d-flex justify-content-between pl-md-3 pr-md-3">
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
<span class="text-muted small">{{ post.date | date: post_long_df }}</span>
|
||||
<span class="text-muted small">{{ post.date | date: post_df }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -5,13 +5,15 @@ layout: compress
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
{% capture prefer_mode %}
|
||||
{% if site.theme_mode %}
|
||||
mode="{{ site.theme_mode }}"
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
<html lang="{{ site.lang | default: "en-US" }}" {{ prefer_mode }}>
|
||||
<html lang="{{ site.lang }}" {{ prefer_mode }}>
|
||||
|
||||
{% include head.html %}
|
||||
|
||||
@@ -46,6 +48,8 @@ layout: compress
|
||||
|
||||
{% include search-loader.html %}
|
||||
|
||||
{% include js-selector.html %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -3,9 +3,11 @@ layout: page
|
||||
# The Home page layout
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
{% assign pinned = site.posts | where: "pin", "true" %}
|
||||
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
|
||||
|
||||
{% assign pinned = site.posts | where_exp: "item", "item.pin == true" %}
|
||||
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
|
||||
{% assign posts = "" | split: "" %}
|
||||
|
||||
<!-- Get pinned posts -->
|
||||
@@ -39,7 +41,6 @@ layout: page
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div id="post-list">
|
||||
|
||||
{% for post in posts %}
|
||||
@@ -79,7 +80,7 @@ layout: page
|
||||
{% if post.pin %}
|
||||
<div class="pin">
|
||||
<i class="fas fa-thumbtack fa-fw"></i>
|
||||
<span>{{ site.data.label.pin_prompt | default: 'Pinned' }}</span>
|
||||
<span>{{ site.data.locales[lang].post.pin_prompt }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -7,7 +7,14 @@ layout: default
|
||||
<div class="col-12 col-lg-11 col-xl-8">
|
||||
<div id="page" class="post pb-5 pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 mb-md-4">
|
||||
{% if page.dynamic_title %}
|
||||
<h1 class="dynamic-title">{{ page.title }}</h1>
|
||||
<h1 class="dynamic-title">
|
||||
{% if page.collection == 'tabs' %}
|
||||
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
|
||||
{{- site.data.locales[lang].tabs[tab_key] | default: page.title -}}
|
||||
{% else %}
|
||||
{{- page.title -}}
|
||||
{% endif %}
|
||||
</h1>
|
||||
<div class="post-content">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,8 @@ layout: default
|
||||
# The posts' layout
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div id="post-wrapper" class="col-12 col-lg-11 col-xl-8">
|
||||
@@ -17,24 +19,28 @@ layout: default
|
||||
<span class="semi-bold">
|
||||
{{ page.author | default: site.social.name }}
|
||||
</span>
|
||||
{% include timeago.html date=page.date prep="on" tooltip=true %}
|
||||
{% capture _preposition %}{{ site.data.locales[lang].post.published }}{% endcapture %}
|
||||
{% include timeago.html date=page.date tooltip=true preposition=_preposition %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- lastmod -->
|
||||
{% if page.last_modified_at %}
|
||||
<span>
|
||||
{% include timeago.html date=page.last_modified_at
|
||||
class="lastmod" prefix="Updated" tooltip=true %}
|
||||
{{ site.data.locales[lang].post.updated }}
|
||||
{% include timeago.html date=page.last_modified_at class="lastmod" tooltip=true %}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
<!-- read time -->
|
||||
{% include read-time.html content=content %}
|
||||
{% include read-time.html content=content prompt=true %}
|
||||
|
||||
<!-- page views -->
|
||||
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
|
||||
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span>
|
||||
<span id="pv" class="pageviews">
|
||||
<i class="fas fa-spinner fa-spin fa-fw"></i>
|
||||
</span>
|
||||
{{ site.data.locales[lang].post.pageview_measure }}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
@@ -44,7 +50,11 @@ layout: default
|
||||
<div class="post-content">
|
||||
|
||||
{% if page.image.src %}
|
||||
<img src="{{ page.image.src }}" class="preview-img" alt="{{ page.image.alt | default: "Preview Image" }}">
|
||||
<img src="{{ page.image.src }}"
|
||||
class="preview-img"
|
||||
alt="{{ page.image.alt | default: "Preview Image" }}"
|
||||
{% if page.image.width %}width="{{ page.image.width }}"{% endif %}
|
||||
{% if page.image.height %}height="{{ page.image.height }}"{% endif %}>
|
||||
{% endif %}
|
||||
|
||||
{{ content }}
|
||||
@@ -55,6 +65,7 @@ layout: default
|
||||
|
||||
<!-- categories -->
|
||||
{% if page.categories.size > 0 %}
|
||||
|
||||
<div class="post-meta mb-3">
|
||||
<i class="far fa-folder-open fa-fw mr-1"></i>
|
||||
{% for category in page.categories %}
|
||||
@@ -79,13 +90,16 @@ layout: default
|
||||
|
||||
<div class="post-tail-bottom
|
||||
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
|
||||
{% if site.data.rights.license %}
|
||||
<div class="license-wrapper">
|
||||
This post is licensed under
|
||||
<a href="{{ site.data.rights.license.link }}">{{ site.data.rights.license.name }}</a>
|
||||
by the author.
|
||||
</div>
|
||||
{% if site.data.locales[lang].copyright.license.template %}
|
||||
{% capture _replacement %}
|
||||
<a href="{{ site.data.locales[lang].copyright.license.link }}">
|
||||
{{ site.data.locales[lang].copyright.license.name }}
|
||||
</a>
|
||||
{% endcapture %}
|
||||
{{ site.data.locales[lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% include post-sharing.html %}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ layout: page
|
||||
# The layout for Tag page
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<div id="page-tag">
|
||||
<h1 class="pl-lg-2">
|
||||
@@ -11,13 +12,13 @@ layout: page
|
||||
<span class="lead text-muted pl-2">{{ page.posts | size }}</span>
|
||||
</h1>
|
||||
<ul class="post-content pl-0">
|
||||
{% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
|
||||
{% assign post_df = site.data.locales[lang].date_format.post.long %}
|
||||
|
||||
{% for post in page.posts %}
|
||||
<li class="d-flex justify-content-between pl-md-3 pr-md-3">
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
<span class="text-muted small">{{ post.date | date: post_long_df }}</span>
|
||||
<span class="text-muted small">{{ post.date | date: post_df }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -7,7 +7,9 @@ tags: [typography]
|
||||
math: true
|
||||
mermaid: true
|
||||
image:
|
||||
src: https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png
|
||||
src: /commons/devices-mockup.png
|
||||
width: 850
|
||||
height: 585
|
||||
---
|
||||
|
||||
This post is to show Markdown syntax rendering on [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork), you can also use it as an example of writing. Now, let's start looking at text and typography.
|
||||
@@ -50,7 +52,7 @@ Fluttering and dancing in the breeze.
|
||||
### Unordered list
|
||||
|
||||
- Chapter
|
||||
- Setcion
|
||||
- Section
|
||||
- Paragraph
|
||||
|
||||
### Task list
|
||||
@@ -97,39 +99,34 @@ Click the hook will locate the footnote[^footnote], and here is another footnote
|
||||
|
||||
- Default (with caption)
|
||||
|
||||

|
||||
{: width="972" height="589" }
|
||||
_Full screen width and center alignment_
|
||||
|
||||
<br>
|
||||
|
||||
- Specify width
|
||||
|
||||
{: width="400"}
|
||||
_400px image width_
|
||||
|
||||
- Shadow
|
||||
|
||||
{: .shadow width="90%" }
|
||||
{: .shadow width="1548" height="864" style="max-width: 90%" }
|
||||
_shadow effect (visible in light mode)_
|
||||
|
||||
<br>
|
||||
|
||||
- Left aligned
|
||||
|
||||
{: width="350" .normal}
|
||||
{: width="972" height="589" style="max-width: 70%" .normal}
|
||||
|
||||
<br>
|
||||
|
||||
- Float to left
|
||||
|
||||
{: width="240" .left}
|
||||
{: width="972" height="589" style="max-width: 200px" .left}
|
||||
"A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space."
|
||||
|
||||
<br>
|
||||
|
||||
- Float to right
|
||||
|
||||
{: width="240" .right}
|
||||
{: width="972" height="589" style="max-width: 200px" .right}
|
||||
"A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space."
|
||||
|
||||
<br>
|
||||
@@ -179,44 +176,23 @@ SHELL=/usr/local/bin/bash
|
||||
PYENV_SHELL=bash
|
||||
```
|
||||
|
||||
#### Ruby
|
||||
|
||||
```ruby
|
||||
def sum_eq_n?(arr, n)
|
||||
return true if arr.empty? && n == 0
|
||||
arr.product(arr).reject { |a,b| a == b }.any? { |a,b| a + b == n }
|
||||
end
|
||||
```
|
||||
|
||||
#### Shell
|
||||
|
||||
```shell
|
||||
```bash
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "The command was not successful.";
|
||||
#do the needful / exit
|
||||
fi;
|
||||
```
|
||||
|
||||
#### Liquid
|
||||
### Specific filename
|
||||
|
||||
{% raw %}
|
||||
```liquid
|
||||
{% if product.title contains 'Pack' %}
|
||||
This product's title contains the word Pack.
|
||||
{% endif %}
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
#### Java
|
||||
|
||||
```java
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
// Write out any hidden serialization magic
|
||||
s.defaultWriteObject();
|
||||
for (E e: map.keySet()) s.writeObject(e);
|
||||
}
|
||||
```sass
|
||||
@import
|
||||
"colors/light-typography",
|
||||
"colors/dark-typography"
|
||||
```
|
||||
{: file='_sass/jekyll-theme-chirpy.scss'}
|
||||
|
||||
## Reverse Footnote
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ author: Cotes Chung
|
||||
date: 2019-08-08 14:10:00 +0800
|
||||
categories: [Blogging, Tutorial]
|
||||
tags: [writing]
|
||||
render_with_liquid: false
|
||||
---
|
||||
|
||||
## Naming and Path
|
||||
@@ -72,7 +73,7 @@ math: true
|
||||
|
||||
[**Mermaid**](https://github.com/mermaid-js/mermaid) is a great diagrams generation tool. To enable it on your post, add the following to the YAML block:
|
||||
|
||||
```yml
|
||||
```yaml
|
||||
---
|
||||
mermaid: true
|
||||
---
|
||||
@@ -84,16 +85,21 @@ Then you can use it like other markdown language: surround the graph code with `
|
||||
|
||||
### Preview image
|
||||
|
||||
If you want to add an image to the top of the post contents, specify the url and alt attribute for the image:
|
||||
If you want to add an image to the top of the post contents, specify the attribute `src`, `width`, `height` and `alt` for the image:
|
||||
|
||||
```yaml
|
||||
---
|
||||
image:
|
||||
src: /path/to/image/file
|
||||
width: 1000 # in pixels
|
||||
height: 400 # in pixels
|
||||
alt: image alternative text
|
||||
---
|
||||
```
|
||||
|
||||
Except for `alt`, all other options are necessary, especially the `width` and `height`, which are related to user experience and web page loading performance. Later section ["Image size"](#image-size) will also mention this.
|
||||
|
||||
|
||||
### Image caption
|
||||
|
||||
Add italics to the next line of an image,then it will become the caption and appear at the bottom of the image:
|
||||
@@ -102,14 +108,16 @@ Add italics to the next line of an image,then it will become the caption and a
|
||||

|
||||
_Image Caption_
|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
### Image size
|
||||
|
||||
You can specify the width (and height) of a image with `width`:
|
||||
In order to prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image:
|
||||
|
||||
```markdown
|
||||
{: width="400"}
|
||||
{: width="700" height="400" }
|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
### Image position
|
||||
|
||||
@@ -120,31 +128,34 @@ By default, the image is centered, but you can specify the position by using one
|
||||
Image will be left aligned in below sample:
|
||||
|
||||
```markdown
|
||||
{: .normal}
|
||||
{: .normal }
|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
- **Float to the left**
|
||||
|
||||
```markdown
|
||||
{: .left}
|
||||
{: .left }
|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
- **Float to the right**
|
||||
|
||||
```markdown
|
||||
{: .right}
|
||||
{: .right }
|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
> **Limitation**: Once you specify the position of an image, it is forbidden to add the image caption.
|
||||
> **Limitation**: Once the position of the image is specified, the image caption should not be added.
|
||||
|
||||
### Image shadow
|
||||
|
||||
The screenshots of the program window can be considered to show the shadow effect, and the shadow will be visible in the `light` mode:
|
||||
|
||||
```markdown
|
||||
{: .shadow}
|
||||
{: .shadow }
|
||||
```
|
||||
|
||||
{: .nolineno}
|
||||
|
||||
### CDN URL
|
||||
|
||||
@@ -153,6 +164,7 @@ If you host the images on the CDN, you can save the time of repeatedly writing t
|
||||
```yaml
|
||||
img_cdn: https://cdn.com
|
||||
```
|
||||
{: file='_config.yml' .nolineno}
|
||||
|
||||
Once `img_cdn` is assigned, the CDN url will be added to the path of all images (images of site avatar and posts) starting with `/`.
|
||||
|
||||
@@ -161,12 +173,14 @@ For instance, when using images:
|
||||
```markdown
|
||||

|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
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">
|
||||
```
|
||||
{: .nolineno}
|
||||
|
||||
## Pinned Posts
|
||||
|
||||
@@ -180,31 +194,51 @@ pin: true
|
||||
|
||||
## Code Block
|
||||
|
||||
Markdown symbols ```` ``` ```` can easily create a code block as following examples.
|
||||
Markdown symbols ```` ``` ```` can easily create a code block as follows:
|
||||
|
||||
```
|
||||
This is a common code snippet, without syntax highlight and line number.
|
||||
This is a plaintext code snippet.
|
||||
```
|
||||
|
||||
## Specific Language
|
||||
### Specifying Language
|
||||
|
||||
Using ```` ```language ```` you will get code snippets with line numbers and syntax highlight.
|
||||
|
||||
> **Note**: The Jekyll style `{% raw %}{%{% endraw %} highlight LANGUAGE {% raw %}%}{% endraw %}` or `{% raw %}{%{% endraw %} highlight LANGUAGE linenos {% raw %}%}{% endraw %}` are not allowed to be used in this theme !
|
||||
Using ```` ```{language} ```` you will get a code block with syntax highlight:
|
||||
|
||||
````markdown
|
||||
```yaml
|
||||
# Yaml code snippet
|
||||
items:
|
||||
- part_no: A4786
|
||||
descrip: Water Bucket (Filled)
|
||||
price: 1.47
|
||||
quantity: 4
|
||||
key: value
|
||||
```
|
||||
````
|
||||
|
||||
> **Limination**: The Jekyll style `highlight` tag ais not compatible with this theme.
|
||||
|
||||
### Line Number
|
||||
|
||||
By default, all languages except `plaintext`, `console` and `terminal` will display line numbers. When you want to hide the line number of the code block, you can append `{: .nolineno}` at the next line:
|
||||
|
||||
````markdown
|
||||
```shell
|
||||
echo 'No more line numbers!'
|
||||
```
|
||||
{: .nolineno}
|
||||
````
|
||||
|
||||
### Specifying the Filename
|
||||
|
||||
You may have noticed that the code language will be displayed on the left side of the header of the code block. If you want to replace it with the file name, you can add the attribute `file` to achieve this:
|
||||
|
||||
````markdown
|
||||
```shell
|
||||
# content
|
||||
```
|
||||
{: file="path/to/file" }
|
||||
````
|
||||
|
||||
### Liquid Codes
|
||||
|
||||
If you want to display the **Liquid** snippet, surround the liquid code with `{% raw %}{%{% endraw %} raw {%raw%}%}{%endraw%}` and `{% raw %}{%{% endraw %} endraw {%raw%}%}{%endraw%}` .
|
||||
If you want to display the **Liquid** snippet, surround the liquid code with `{% raw %}` and `{% endraw %}`:
|
||||
|
||||
````markdown
|
||||
{% raw %}
|
||||
```liquid
|
||||
{% if product.title contains 'Pack' %}
|
||||
@@ -212,6 +246,9 @@ If you want to display the **Liquid** snippet, surround the liquid code with `{%
|
||||
{% endif %}
|
||||
```
|
||||
{% endraw %}
|
||||
````
|
||||
|
||||
Or adding `render_with_liquid: false` (Requires Jekyll 4.0 or higher) to the post's YAML block.
|
||||
|
||||
## Learn More
|
||||
|
||||
|
||||
@@ -9,54 +9,25 @@ pin: true
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
|
||||
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
|
||||
|
||||
## Installation
|
||||
|
||||
There are two ways to get the theme:
|
||||
### Creating a New Site
|
||||
|
||||
- **Install from RubyGems** - Easy to update, isolate irrelevant project files so you can focus on writing.
|
||||
- **Fork on GitHub** - Convenient for custom development, but difficult to update, only suitable for web developers.
|
||||
There are two ways to create a new repository for this theme:
|
||||
|
||||
### Installing the Theme Gem
|
||||
- **[Using the Chirpy Starter](#option-1-using-the-chirpy-starter)** - Easy to upgrade, isolates irrelevant project files so you can focus on writing.
|
||||
|
||||
Add this line to your Jekyll site's `Gemfile`:
|
||||
- **[Forking on GitHub](#option-2-forking-on-github)** - Convenient for custom development, but difficult to upgrade. Unless you are familiar with Jekyll and are determined to tweak or contribute to this project, this approach is not recommended.
|
||||
|
||||
```ruby
|
||||
gem "jekyll-theme-chirpy"
|
||||
```
|
||||
#### Option 1. Using the Chirpy Starter
|
||||
|
||||
And add this line to your Jekyll site's `_config.yml`:
|
||||
Create a new repository from the [**Chirpy Starter**][use-starter] and name it `<GH_USERNAME>.github.io`, where `GH_USERNAME` represents your GitHub username.
|
||||
|
||||
```yaml
|
||||
theme: jekyll-theme-chirpy
|
||||
```
|
||||
#### Option 2. Forking on GitHub
|
||||
|
||||
And then execute:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
Finally, copy the required files from the theme's gem (for detailed files, see [starter project][starter]) to your Jekyll site.
|
||||
|
||||
> **Hint**: To locate the installed theme’s gem, execute:
|
||||
>
|
||||
> ```console
|
||||
> $ bundle info --path jekyll-theme-chirpy
|
||||
> ```
|
||||
|
||||
Or you can [**use the starter template**][use-starter] to create a Jekyll site to save time copying files from the theme's gem. We have prepared everything for you there!
|
||||
|
||||
### Fork on GitHub
|
||||
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and then clone your fork to local. (Please note that the default branch code is in development. If you want the blog to be stable, please switch to the [latest tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) and start writing.)
|
||||
|
||||
Install gem dependencies by:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and rename it to `<GH_USERNAME>.github.io`. Please note that the default branch code is in development. If you want the site to be stable, please switch to the [latest tag][latest-tag] and start writing.
|
||||
|
||||
And then execute:
|
||||
|
||||
@@ -64,18 +35,28 @@ And then execute:
|
||||
$ bash tools/init.sh
|
||||
```
|
||||
|
||||
> **Note**: If you don't plan to deploy your site on GitHub Pages, append parameter option `--no-gh` at the end of the above command.
|
||||
> **Note**: If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
|
||||
|
||||
What it does is:
|
||||
The above command will:
|
||||
|
||||
1. Remove some files or directories from your repository:
|
||||
1. Removes some files or directories from your repository:
|
||||
- `.travis.yml`
|
||||
- files under `_posts`
|
||||
- folder `docs`
|
||||
|
||||
2. If you use the `--no-gh` option, the directory `.github` will be deleted. Otherwise, setup the GitHub Action workflow by removing the extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in the folder `.github`.
|
||||
2. If the option `--no-gh` is provided, the directory `.github` will be deleted. Otherwise, setup the GitHub Action workflow by removing the extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in the folder `.github`.
|
||||
|
||||
3. Automatically create a commit to save the changes.
|
||||
3. Removes item `Gemfile.lock` from `.gitignore`.
|
||||
|
||||
4. Creates a new commit to save the changes automatically.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
Before running for the first time, go the root directory of your site, and install dependencies as follows:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -88,6 +69,12 @@ Update the variables of `_config.yml` as needed. Some of them are typical option
|
||||
- `timezone`
|
||||
- `lang`
|
||||
|
||||
### Customing Stylesheet
|
||||
|
||||
If you need to customize stylesheet, copy the theme's `assets/css/style.scss` to the same path on your Jekyll site, and then add the custom style at the end of the style file.
|
||||
|
||||
Starting from [`v4.1.0`][chirpy-4.1.0], if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`, create a new file `_sass/variables-hook.scss` and assign new values to the target variable in it.
|
||||
|
||||
### Running Local Server
|
||||
|
||||
You may want to preview the site contents before publishing, so just run it by:
|
||||
@@ -98,14 +85,14 @@ $ bundle exec jekyll s
|
||||
|
||||
Or run the site on Docker with the following command:
|
||||
|
||||
```terminal
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
-p 4000:4000 jekyll/jekyll \
|
||||
jekyll serve
|
||||
```
|
||||
|
||||
Open a browser and visit to _<http://localhost:4000>_.
|
||||
After a while, the local service will be published at _<http://127.0.0.1:4000>_.
|
||||
|
||||
### Deployment
|
||||
|
||||
@@ -113,40 +100,47 @@ Before the deployment begins, checkout the file `_config.yml` and make sure the
|
||||
|
||||
Now you can choose ONE of the following methods to deploy your Jekyll site.
|
||||
|
||||
#### Deploy on GitHub Pages
|
||||
#### Deploy by Using Github Actions
|
||||
|
||||
For security reasons, GitHub Pages build runs on `safe` mode, which restricts us from using plugins to generate additional page files. Therefore, we can use **GitHub Actions** to build the site, store the built site files on a new branch, and use that branch as the source of the GH Pages service.
|
||||
For security reasons, GitHub Pages build runs on `safe` mode, which restricts us from using plugins to generate additional page files. Therefore, we can use **GitHub Actions** to build the site, store the built site files on a new branch, and use that branch as the source of the GitHub Pages service.
|
||||
|
||||
Quickly check the files needed for GitHub Actions build:
|
||||
|
||||
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`. Otherwise, create a new one and fill in the contents of the [workflow file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name.
|
||||
- Ensure your Jekyll site has file `tools/test.sh` and `tools/deploy.sh`. Otherwise, copy them from this repo to your Jekyll site.
|
||||
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`. Otherwise, create a new one and fill in the contents of the [sample file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name.
|
||||
|
||||
And then rename your repository to `<GH-USERNAME>.github.io` on GitHub.
|
||||
- Ensure your Jekyll site has file `tools/deploy.sh`. Otherwise, copy it from here to your Jekyll site.
|
||||
|
||||
- Furthermore, if you have committed `Gemfile.lock` to the repo, and your runtime system is not Linux, don't forget to update the platform list in the lockfile:
|
||||
|
||||
```console
|
||||
$ bundle lock --add-platform x86_64-linux
|
||||
```
|
||||
|
||||
After the above steps, rename your repository to `<GH_USERNAME>.github.io` on GitHub.
|
||||
|
||||
Now publish your Jekyll site by:
|
||||
|
||||
1. Push any commit to remote to trigger the GitHub Actions workflow. Once the build is complete and successful, a new remote branch named `gh-pages` will appear to store the built site files.
|
||||
|
||||
2. Browse to your repo's landing page on GitHub and select the branch `gh-pages` as the [publishing source](https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) through _Settings_ → _Options_ → _GitHub Pages_:
|
||||
2. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar, and then in the section **Source** of _GitHub Pages_, select the `/(root)` directory of branch `gh-pages` as the [publishing source][pages-src]. Remember to click <kbd>Save</kbd> before leaving.
|
||||
|
||||

|
||||
{: width="850" height="153" }
|
||||
|
||||
3. Visit your website at the address indicated by GitHub.
|
||||
|
||||
#### Deploy on Other Platforms
|
||||
#### Manually Build and Deploy
|
||||
|
||||
On platforms other than GitHub, we cannot enjoy the convenience of **GitHub Actions**. Therefore, we should build the site locally (or on some other 3rd-party CI platform) and then put the site files on the server.
|
||||
On self-hosted servers, you cannot enjoy the convenience of **GitHub Actions**. Therefore, you should build the site on your local machine and then upload the site files to the server.
|
||||
|
||||
Go to the root of the source project, build your site by:
|
||||
Go to the root of the source project, and build your site as follows:
|
||||
|
||||
```console
|
||||
$ JEKYLL_ENV=production bundle exec jekyll b
|
||||
```
|
||||
|
||||
Or build the site with Docker by:
|
||||
Or build the site on Docker:
|
||||
|
||||
```terminal
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--env JEKYLL_ENV=production \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
@@ -154,8 +148,34 @@ $ docker run -it --rm \
|
||||
jekyll build
|
||||
```
|
||||
|
||||
Unless you specified the output path, the generated site files will be placed in folder `_site` of the project's root directory. Now you should upload those files to your web server.
|
||||
Unless you specified the output path, the generated site files will be placed in folder `_site` of the project's root directory. Now you should upload those files to the target server.
|
||||
|
||||
### Upgrading
|
||||
|
||||
It depends on how you use the theme:
|
||||
|
||||
- If you are using the theme gem (there will be `gem "jekyll-theme-chirpy"` in the `Gemfile`), editing the `Gemfile` and update the version number of the them gem, for example:
|
||||
|
||||
```diff
|
||||
- gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1"
|
||||
+ gem "jekyll-theme-chirpy", "~> 3.3", ">= 3.3.0"
|
||||
```
|
||||
{: .nolineno file="Gemfile" }
|
||||
|
||||
And then execute the following command:
|
||||
|
||||
```console
|
||||
$ bundle update jekyll-theme-chirpy
|
||||
```
|
||||
|
||||
As the version upgrades, the critical files (for details, see the [Startup Template][starter]) and configuration options will change. Please refer to the [Upgrade Guide](https://github.com/cotes2020/jekyll-theme-chirpy/wiki/Upgrade-Guide) to keep your repo's files in sync with the latest version of the theme.
|
||||
|
||||
- If you forked from the source project (there will be `gemspec` in the `Gemfile` of your site), then merge the [latest upstream tags][latest-tag] into your Jekyll site to complete the upgrade.
|
||||
The merge is likely to conflict with your local modifications. Please be patient and careful to resolve these conflicts.
|
||||
|
||||
[starter]: https://github.com/cotes2020/chirpy-starter
|
||||
[use-starter]: https://github.com/cotes2020/chirpy-starter/generate
|
||||
[workflow]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/workflows/pages-deploy.yml.hook
|
||||
[chirpy-4.1.0]: https://github.com/cotes2020/jekyll-theme-chirpy/releases/tag/v4.1.0
|
||||
[pages-src]: https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site
|
||||
[latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags
|
||||
|
||||
@@ -6,7 +6,7 @@ categories: [Blogging, Tutorial]
|
||||
tags: [favicon]
|
||||
---
|
||||
|
||||
The [favicons](https://www.favicon-generator.org/about/) of [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/) are placed in the directory `assets/img/favicons/`. You may need to replace them with your own. The following sections will guide you how to create and replace the default favicons.
|
||||
The [favicons](https://www.favicon-generator.org/about/) of [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/) are placed in the directory `assets/img/favicons/`. You may want to replace them with your own. The following sections will guide you how to create and replace the default favicons.
|
||||
|
||||
## Generate the favicon
|
||||
|
||||
@@ -21,7 +21,7 @@ Download the generated package, unzip and delete the following two from the extr
|
||||
- `browserconfig.xml`
|
||||
- `site.webmanifest`
|
||||
|
||||
Now, copy the remaining image files (`PNG` and `ICO`) to cover the original files in the folder `assets/img/favicons/` of your Jekyll site.
|
||||
Now, copy the remaining image files (`PNG` and `ICO`) to cover the original files in the folder `assets/img/favicons/` of your Jekyll site. If your Jekyll site doesn't have this directory yet, just create one.
|
||||
|
||||
The following table will helps you understand the changes to the favicon files:
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ With your property created, you now need to set up Data Stream to track your blo
|
||||
|
||||
It should look like this:
|
||||
|
||||

|
||||
{: width="1086" height="542"}
|
||||
|
||||
Now, click on the new data stream and grab the **Measurement ID**. It should look something like `G-V6XXXXXXXX`. Copy this to your `_config.yml` file
|
||||
|
||||
@@ -45,10 +45,11 @@ google_analytics:
|
||||
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
|
||||
cache_path: # the local PV cache data, friendly to visitors from GFW region
|
||||
```
|
||||
{: file="_config.yml"}
|
||||
|
||||
When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pickup your changes. You should now be able to monitor your traffic in realtime.
|
||||
|
||||

|
||||
{: width="616" height="557"}
|
||||
|
||||
## Setup Page Views
|
||||
|
||||
@@ -140,6 +141,7 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
|
||||
# XSRF Settings
|
||||
XSRF_KEY = 'OnceUponATimeThereLivedALegend'
|
||||
```
|
||||
{: file="src/config.py"}
|
||||
|
||||
**Tip:** You can configure a custom domain instead of `https://PROJECT_ID.REGION_ID.r.appspot.com`. But, for the sake of keeping it simple, we will be using the Google provided default URL.
|
||||
|
||||
@@ -183,7 +185,7 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
|
||||
|
||||
If everything went good, you'll get this screen:
|
||||
|
||||

|
||||
{: width="1366" height="354"}
|
||||
|
||||
### Create Google Analytics Query
|
||||
|
||||
@@ -208,14 +210,14 @@ After <kbd>Run Query</kbd>, copy the generated contents of **API Query URI** at
|
||||
|
||||
After the query is saved on GAE, a **Public Endpoint** (public access address) will be generated, and we will get the query result in JSON format when accessing it. Finally, click <kbd>Enable Endpoint</kbd> in **Public Request Endpoint** to make the query effective, and click <kbd>Start Scheduling</kbd> in **Scheduling** to start the scheduled task.
|
||||
|
||||

|
||||
{: width="1100" height="126"}
|
||||
|
||||
|
||||
## Configure Chirpy to Display Page View
|
||||
|
||||
Once all the hard part is done, it is very easy to enable the Page View on Chirpy theme. Your superProxy dashboard should look something like below and you can grab the required values.
|
||||
|
||||

|
||||
{: width="1210" height="694"}
|
||||
|
||||
Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:
|
||||
|
||||
@@ -226,6 +228,7 @@ google_analytics:
|
||||
proxy_endpoint: 'https://PROJECT_ID.REGION_ID.r.appspot.com/query?id=<ID FROM SUPER PROXY>'
|
||||
cache_path: # the local PV cache data, friendly to visitors from GFW region
|
||||
```
|
||||
{: file="_config.yml"}
|
||||
|
||||
Now, you should see the Page View enabled on your blog.
|
||||
|
||||
|
||||
@@ -7,16 +7,9 @@
|
||||
@if $dark-mode {
|
||||
@include dark-scheme;
|
||||
|
||||
.mode-toggle {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
} @else {
|
||||
@include light-scheme;
|
||||
|
||||
.mode-toggle {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,6 +46,45 @@ body {
|
||||
font-family: 'Source Sans Pro', 'Microsoft Yahei', sans-serif;
|
||||
}
|
||||
|
||||
/* --- Scrollbar --- */
|
||||
|
||||
$scrollbar-size: 7px;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: $scrollbar-size;
|
||||
height: $scrollbar-size;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
@at-root body#{&} {
|
||||
-webkit-box-shadow: inset 0 0 6px var(--scrollbar-track-bg);
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--scrollbar-thumb-bg);
|
||||
border-radius: calc(#{$scrollbar-size} / 2);
|
||||
}
|
||||
|
||||
.highlight {
|
||||
border-color: transparent;
|
||||
transition: border-color 0.5s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--scrollbar-thumb-bg);
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
/* add border to act as background-color */
|
||||
border-right-style: inset;
|
||||
border-right-width: calc(100vw + 100vh);
|
||||
border-color: inherit;
|
||||
background-color: var(--highlight-bg-color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* --- Typography --- */
|
||||
|
||||
h1 {
|
||||
@@ -107,6 +139,7 @@ a {
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
@@ -363,9 +396,29 @@ footer {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
|
||||
@mixin caption {
|
||||
+ em {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
font-size: 80%;
|
||||
padding: 0;
|
||||
color: #6d6c6c;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
img[data-src] {
|
||||
margin: 0.5rem 0;
|
||||
|
||||
&[data-loaded=true] {
|
||||
animation: fade-in linear .5s;
|
||||
}
|
||||
|
||||
&.left {
|
||||
float: left;
|
||||
margin: 0.75rem 1rem 1rem 0;
|
||||
@@ -380,6 +433,8 @@ footer {
|
||||
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
|
||||
}
|
||||
|
||||
@include caption;
|
||||
|
||||
}
|
||||
|
||||
a {
|
||||
@@ -404,14 +459,7 @@ footer {
|
||||
}
|
||||
|
||||
&.img-link {
|
||||
+ em {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
font-size: 80%;
|
||||
padding: 0;
|
||||
color: #6d6c6c;
|
||||
}
|
||||
@include caption;
|
||||
}
|
||||
|
||||
} // a
|
||||
@@ -444,10 +492,6 @@ footer {
|
||||
padding-left: 2rem;
|
||||
|
||||
li {
|
||||
+ li {
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul { // sub list
|
||||
padding-left: 2rem;
|
||||
@@ -589,8 +633,6 @@ figure .mfp-title {
|
||||
|
||||
/* --- sidebar layout --- */
|
||||
|
||||
$tab-count: 5 !default;
|
||||
|
||||
$sidebar-display: "sidebar-display";
|
||||
|
||||
#sidebar {
|
||||
@@ -601,7 +643,7 @@ $sidebar-display: "sidebar-display";
|
||||
left: 0;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
width: $sidebar-width-medium;
|
||||
width: $sidebar-width;
|
||||
z-index: 99;
|
||||
background: var(--sidebar-bg);
|
||||
|
||||
@@ -615,31 +657,31 @@ $sidebar-display: "sidebar-display";
|
||||
scrollbar-width: none; /* Firefox */
|
||||
|
||||
a {
|
||||
@include sidebar-links;
|
||||
@extend %sidebar-links;
|
||||
|
||||
&:hover {
|
||||
@include no-text-decoration;
|
||||
|
||||
color: #fff;
|
||||
color: var(--sidebar-active-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
#avatar {
|
||||
&:hover > a {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
> a {
|
||||
display: block;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #b6b6b6;
|
||||
border: 2px solid rgba(222, 222, 222, 0.7);
|
||||
overflow: hidden;
|
||||
transform: translateZ(0); // fixed the zoom in Safari
|
||||
-webkit-transition: border-color 0.35s ease-in-out;
|
||||
-moz-transition: border-color 0.35s ease-in-out;
|
||||
transition: border-color 0.35s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
border-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
@@ -660,15 +702,18 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
.site-title {
|
||||
a {
|
||||
@extend %clickable-transition;
|
||||
|
||||
font-weight: 900;
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: 0.5px;
|
||||
color: rgba(134, 133, 133, 99%);
|
||||
}
|
||||
}
|
||||
|
||||
.site-subtitle {
|
||||
font-size: 95%;
|
||||
color: #828282;
|
||||
color: var(--sidebar-muted-color);
|
||||
line-height: 1.2rem;
|
||||
word-spacing: 1px;
|
||||
margin: 0.5rem 1.5rem 0.5rem 1.5rem;
|
||||
@@ -689,16 +734,16 @@ $sidebar-display: "sidebar-display";
|
||||
text-align: center;
|
||||
display: table;
|
||||
height: $tab-height;
|
||||
&:hover {
|
||||
.nav-link {
|
||||
color: #f8f9facf;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
.nav-link {
|
||||
color: #fcfcfc;
|
||||
color: var(--sidebar-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.active) > a {
|
||||
@extend %clickable-transition;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
@@ -710,7 +755,6 @@ $sidebar-display: "sidebar-display";
|
||||
width: 100%;
|
||||
|
||||
&:last-child {
|
||||
$cursor-width: 3px;
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
@@ -740,12 +784,12 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
@for $i from 1 through $tab-count {
|
||||
$offset: $tab-count - $i;
|
||||
$top: -$offset * $tab-height + $tab-cursor-height / 2;
|
||||
$top: -$offset * $tab-height + ($tab-height - $tab-cursor-height) / 2;
|
||||
|
||||
@if $i < $tab-count {
|
||||
> li.active:nth-child(#{$i}),
|
||||
> li.nav-item:nth-child(#{$i}):hover {
|
||||
~li:last-child::after {
|
||||
~ li:last-child::after {
|
||||
@include fix-cursor($top);
|
||||
}
|
||||
}
|
||||
@@ -774,36 +818,35 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
a {
|
||||
@extend %icon;
|
||||
@extend %clickable-transition;
|
||||
}
|
||||
|
||||
i {
|
||||
line-height: 1.75rem; // default line-height in body
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#mode-toggle-wrapper {
|
||||
@extend %icon;
|
||||
|
||||
i {
|
||||
@include sidebar-links;
|
||||
|
||||
margin: 0;
|
||||
font-size: 1.05rem;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
@extend %sidebar-links;
|
||||
@extend %cursor-pointer;
|
||||
@extend %clickable-transition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.icon-border {
|
||||
background-color: #525354;
|
||||
background-color: var(--sidebar-muted-color);
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
#mode-toggle-wrapper i:hover {
|
||||
color: #fff;
|
||||
#mode-toggle-wrapper:hover > i {
|
||||
color: var(--sidebar-active-color);
|
||||
}
|
||||
|
||||
} // .sidebar-bottom
|
||||
@@ -839,12 +882,11 @@ $sidebar-display: "sidebar-display";
|
||||
height: $topbar-height;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 260px; /* same as sidebar width */
|
||||
left: $sidebar-width; /* same as sidebar width */
|
||||
right: 0;
|
||||
transition: top 0.2s ease-in-out;
|
||||
z-index: 50;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
||||
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.05);
|
||||
background-color: var(--topbar-wrapper-bg);
|
||||
}
|
||||
|
||||
@@ -880,17 +922,21 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
#search-wrapper {
|
||||
display: flex;
|
||||
width: 95%;
|
||||
width: 85%;
|
||||
border-radius: 1rem;
|
||||
border: 1px solid var(--search-wrapper-bg);
|
||||
border: 1px solid var(--search-wrapper-border-color);
|
||||
background: var(--search-wrapper-bg);
|
||||
padding: 0 0.5rem;
|
||||
|
||||
i {
|
||||
z-index: 2;
|
||||
font-size: 0.9rem;
|
||||
color: var(--search-icon-color);
|
||||
}
|
||||
|
||||
.fa-times-circle { /* button 'clean up' */
|
||||
@extend %cursor-pointer;
|
||||
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
@@ -899,6 +945,8 @@ $sidebar-display: "sidebar-display";
|
||||
color: var(--link-color);
|
||||
margin-left: 1rem;
|
||||
display: none;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
@@ -1053,18 +1101,27 @@ $sidebar-display: "sidebar-display";
|
||||
/* --- button back-to-top --- */
|
||||
|
||||
#back-to-top {
|
||||
$size: 2.7em;
|
||||
|
||||
display: none;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
background: var(--button-bg);
|
||||
color: var(--btn-backtotop-color);
|
||||
height: 2.6em;
|
||||
width: 2.7em;
|
||||
padding: 0;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--btn-backtotop-border-color);
|
||||
transition: 0.2s ease-out;
|
||||
-webkit-transition: 0.2s ease-out;
|
||||
transition: transform 0.2s ease-out;
|
||||
-webkit-transition: transform 0.2s ease-out;
|
||||
|
||||
i {
|
||||
line-height: $size;
|
||||
position: relative;
|
||||
bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
#back-to-top:hover {
|
||||
@@ -1083,7 +1140,7 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
@media all and (max-width: 576px) {
|
||||
|
||||
$footer-height: 6rem; // overwrite
|
||||
$footer-height: $footer-height-mobile; // overwrite
|
||||
|
||||
#main > div.row:first-child > div:first-child {
|
||||
min-height: calc(100vh - #{$topbar-height} - #{$footer-height});
|
||||
@@ -1157,7 +1214,7 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
#topbar-wrapper,
|
||||
#main-wrapper {
|
||||
transform: translateX(#{$sidebar-width-medium});
|
||||
transform: translateX(#{$sidebar-width});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1165,8 +1222,8 @@ $sidebar-display: "sidebar-display";
|
||||
#sidebar {
|
||||
@extend %slide;
|
||||
|
||||
transform: translateX(-#{$sidebar-width-medium}); // hide
|
||||
-webkit-transform: translateX(-#{$sidebar-width-medium});
|
||||
transform: translateX(-#{$sidebar-width}); // hide
|
||||
-webkit-transform: translateX(-#{$sidebar-width});
|
||||
|
||||
.cursor {
|
||||
-webkit-transition: none;
|
||||
@@ -1264,7 +1321,7 @@ $sidebar-display: "sidebar-display";
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
margin-left: $sidebar-width-medium;
|
||||
margin-left: $sidebar-width;
|
||||
}
|
||||
|
||||
.profile-wrapper {
|
||||
@@ -1562,19 +1619,10 @@ $sidebar-display: "sidebar-display";
|
||||
|
||||
.nav-link {
|
||||
> span {
|
||||
letter-spacing: 3px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
> i {
|
||||
@include icon-round(1.65rem);
|
||||
|
||||
line-height: 1.5rem;
|
||||
font-size: 0.6rem;
|
||||
padding-top: 1px;
|
||||
padding-left: 1px;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
|
||||
&.unloaded {
|
||||
display: inline-block !important;
|
||||
}
|
||||
@@ -1588,35 +1636,40 @@ $sidebar-display: "sidebar-display";
|
||||
padding-left: 3.5rem;
|
||||
width: 100%;
|
||||
|
||||
$icon-block-size: 2rem;
|
||||
|
||||
&.justify-content-center {
|
||||
-webkit-box-pack: start !important;
|
||||
-ms-flex-pack: start !important;
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: 1rem;
|
||||
width: 3rem;
|
||||
> span,
|
||||
> a {
|
||||
@include ml-mr(0.15rem);
|
||||
|
||||
height: $icon-block-size;
|
||||
margin-bottom: 0.5rem; // wrap line
|
||||
}
|
||||
|
||||
i {
|
||||
@include icon-round(2rem);
|
||||
background-color: var(--sidebar-btn-bg);
|
||||
font-size: 1rem;
|
||||
width: $icon-block-size;
|
||||
height: $icon-block-size;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
|
||||
padding-top: 0.44rem;
|
||||
margin-top: .7rem; // multi line space
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#mode-toggle-wrapper {
|
||||
width: 3rem;
|
||||
|
||||
i {
|
||||
top: 11px;
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-border {
|
||||
top: 26px;
|
||||
top: 0.9rem;
|
||||
}
|
||||
|
||||
} // .sidebar-bottom
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
border-bottom: 1px solid var(--link-underline-color);
|
||||
}
|
||||
|
||||
%clickable-transition {
|
||||
transition: color 0.35s ease-in-out;
|
||||
}
|
||||
|
||||
%no-bottom-border {
|
||||
border-bottom: none;
|
||||
}
|
||||
@@ -51,25 +55,21 @@
|
||||
margin-top: -2.5rem;
|
||||
}
|
||||
|
||||
%cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ---------- scss mixin --------- */
|
||||
|
||||
@mixin no-text-decoration {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@mixin sidebar-links($color: rgba(255, 255, 255, 0.5)) {
|
||||
color: $color;
|
||||
transition: color 0.35s ease-in-out;
|
||||
%sidebar-links {
|
||||
color: rgba(117, 117, 117, 0.9);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@mixin icon-round($diameter) {
|
||||
border: 1px solid;
|
||||
border-radius: 50%;
|
||||
width: $diameter;
|
||||
height: $diameter;
|
||||
}
|
||||
|
||||
@mixin ml-mr($value) {
|
||||
margin-left: $value;
|
||||
margin-right: $value;
|
||||
|
||||
@@ -27,20 +27,20 @@ html[mode=dark] {
|
||||
|
||||
/* -- Codes Snippet -- */
|
||||
|
||||
$code-radius: 6px;
|
||||
|
||||
%code-snippet-bg {
|
||||
background: var(--highlight-bg-color);
|
||||
}
|
||||
|
||||
%code-snippet-radius {
|
||||
border-radius: 6px;
|
||||
border-radius: $code-radius;
|
||||
}
|
||||
|
||||
%code-snippet-padding {
|
||||
padding: 1.5rem;
|
||||
padding: 1.2rem;
|
||||
}
|
||||
|
||||
$code-font-size: 0.85rem;
|
||||
|
||||
div > pre {
|
||||
@extend %code-snippet-bg;
|
||||
@extend %code-snippet-radius;
|
||||
@@ -65,26 +65,14 @@ div > pre {
|
||||
}
|
||||
|
||||
overflow: auto;
|
||||
.lineno {
|
||||
margin-left: 0.2rem;
|
||||
padding-right: 0.5rem;
|
||||
min-width: 2.2rem;
|
||||
text-align: right;
|
||||
color: var(--highlight-lineno-color);
|
||||
border-right: 1px solid var(--highlight-lineno-border-color);
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-bottom: 0;
|
||||
font-size: $code-font-size;
|
||||
line-height: 1.4rem;
|
||||
word-wrap: normal; /* Fixed Safari overflow-x */
|
||||
}
|
||||
|
||||
table {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
@@ -93,10 +81,30 @@ div > pre {
|
||||
word-break: normal; /* Fixed iOS safari linenos code break */
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.lineno {
|
||||
padding-right: 0.5rem;
|
||||
min-width: 2.2rem;
|
||||
text-align: right;
|
||||
color: var(--highlight-lineno-color);
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* set the dollar sign to non-selectable */
|
||||
.gp {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
} //.highlight
|
||||
|
||||
code {
|
||||
@@ -127,7 +135,7 @@ code {
|
||||
}
|
||||
|
||||
td.rouge-code {
|
||||
padding: 1.5rem 1.5rem 1.5rem 1rem;
|
||||
padding: 1.2rem 1.5rem 1.2rem 1rem;
|
||||
|
||||
// Prevent some browser extends from
|
||||
// changing the URL string of code block.
|
||||
@@ -144,7 +152,8 @@ div {
|
||||
&[class^='highlighter-rouge'],
|
||||
&.language-plaintext.highlighter-rouge,
|
||||
&.language-console.highlighter-rouge,
|
||||
&.language-terminal.highlighter-rouge {
|
||||
&.language-terminal.highlighter-rouge,
|
||||
&.nolineno {
|
||||
pre.lineno {
|
||||
display: none;
|
||||
}
|
||||
@@ -154,25 +163,100 @@ div {
|
||||
}
|
||||
}
|
||||
|
||||
div[class^='language-']::before {
|
||||
content: attr(lang);
|
||||
position: absolute;
|
||||
right: 2rem;
|
||||
margin-top: 3px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
color: var(--highlight-lineno-color);
|
||||
text-transform: uppercase;
|
||||
.code-header {
|
||||
background: var(--code-header-bg);
|
||||
border-top-left-radius: $code-radius;
|
||||
border-top-right-radius: $code-radius;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
line-height: 1.85rem;
|
||||
|
||||
// icons
|
||||
i {
|
||||
font-size: 1rem;
|
||||
color: var(--lang-badge-muted-color);
|
||||
|
||||
&.small {
|
||||
font-size: 70%;
|
||||
}
|
||||
}
|
||||
|
||||
// the label block
|
||||
span {
|
||||
padding-left: 0.35rem;
|
||||
|
||||
&::after {
|
||||
content: attr(text-data);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
color: var(--lang-badge-color);
|
||||
}
|
||||
|
||||
i {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
@at-root [file] #{&} > i {
|
||||
position: relative;
|
||||
top: 1px; // center the file icon
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// clipboard
|
||||
button {
|
||||
border: 1px solid var(--code-header-bg);
|
||||
border-radius: $code-radius;
|
||||
padding: 0;
|
||||
width: 1.95rem;
|
||||
background-color: inherit;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
|
||||
&[timeout] {
|
||||
&:hover {
|
||||
border-color: var(--clipboard-checked-color);
|
||||
}
|
||||
|
||||
i {
|
||||
color: var(--clipboard-checked-color);
|
||||
}
|
||||
}
|
||||
|
||||
&:not([timeout]):hover {
|
||||
background-color: rgba(128, 128, 128, 0.37);
|
||||
|
||||
i {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
div[class^='language-']::before {
|
||||
right: 3.1rem;
|
||||
}
|
||||
}
|
||||
@media all and (max-width: 576px) {
|
||||
.post-content {
|
||||
> div[class^='language-'] {
|
||||
@include ml-mr(-1.25rem);
|
||||
|
||||
@media (min-width: 1650px) {
|
||||
div[class^='language-']::before {
|
||||
right: 3.5rem;
|
||||
border-radius: 0;
|
||||
|
||||
.highlight {
|
||||
padding-left: 0.25rem;
|
||||
}
|
||||
|
||||
.code-header {
|
||||
border-radius: 0;
|
||||
padding-left: 0.4rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
/*
|
||||
* Mainly scss variables
|
||||
*/
|
||||
* The SCSS variables
|
||||
*/
|
||||
|
||||
/* --- ↓ width and height ---- */
|
||||
/* sidebar */
|
||||
|
||||
$tab-height: 3.2rem;
|
||||
$tab-cursor-height: 1.6rem;
|
||||
$sidebar-width: 260px !default; // the basic width
|
||||
$sidebar-width-small: 210px !default; // screen width: >= 850px, <= 1199px (iPad landscape)
|
||||
$sidebar-width-large: 350px !default; // screen width: >= 1650px
|
||||
|
||||
$sidebar-width-small: 210px;
|
||||
$sidebar-width-medium: 260px;
|
||||
$sidebar-width-large: 350px;
|
||||
/* tabs of sidebar */
|
||||
|
||||
$topbar-height: 3rem;
|
||||
$tab-count: 5 !default; // backward compatible (version <= 4.0.2)
|
||||
$tab-height: 3rem !default;
|
||||
$tab-cursor-height: 1.6rem !default;
|
||||
|
||||
$footer-height: 5rem;
|
||||
$cursor-width: 2px !default; // the cursor width of the selected tab
|
||||
|
||||
$main-content-max-width: 1150px;
|
||||
/* other framework sizes */
|
||||
|
||||
$panel-max-width: 300px;
|
||||
$topbar-height: 3rem !default;
|
||||
|
||||
$post-extend-min-height: 35rem;
|
||||
$footer-height: 5rem !default;
|
||||
$footer-height-mobile: 6rem !default; // screen width: <= 576px
|
||||
|
||||
$main-content-max-width: 1150px !default;
|
||||
|
||||
$panel-max-width: 300px !default;
|
||||
|
||||
$post-extend-min-height: 35rem !default;
|
||||
|
||||
/* syntax highlight */
|
||||
|
||||
$code-font-size: 0.85rem !default;
|
||||
|
||||
@@ -3,20 +3,6 @@
|
||||
*/
|
||||
|
||||
@mixin dark-syntax {
|
||||
/* ----- My styles ------ */
|
||||
--highlight-bg-color: #252525;
|
||||
--highlighter-rouge-color: #de6b18;
|
||||
--highlight-lineno-color: #6c6c6d;
|
||||
--highlight-lineno-border-color: #303435;
|
||||
--inline-code-bg: #272822;
|
||||
|
||||
.highlight {
|
||||
.gp { color: #818c96; }
|
||||
}
|
||||
|
||||
pre { color: #bfbfbf; } /* override Bootstrap */
|
||||
kbd { background-color: black; }
|
||||
|
||||
/* syntax highlight colors from https://raw.githubusercontent.com/jwarby/pygments-css/master/monokai.css */
|
||||
.highlight pre { background-color: var(--highlight-bg-color); }
|
||||
.highlight .hll { background-color: var(--highlight-bg-color); }
|
||||
@@ -81,4 +67,22 @@
|
||||
.highlight .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
|
||||
.highlight .gd { color: #f92672; background-color: #561c08; } /* Generic.Deleted & Diff Deleted */
|
||||
.highlight .gi { color: #a6e22e; background-color: #0b5858; } /* Generic.Inserted & Diff Inserted */
|
||||
|
||||
/* ----- custom styles ------ */
|
||||
|
||||
--highlight-bg-color: #252525;
|
||||
--highlighter-rouge-color: #de6b18;
|
||||
--highlight-lineno-color: #6c6c6d;
|
||||
--inline-code-bg: #272822;
|
||||
--code-header-bg: #353535;
|
||||
--lang-badge-color: #858586;
|
||||
--lang-badge-muted-color: #6c6c6d;
|
||||
--clipboard-checked-color: #2bcc2b;
|
||||
|
||||
.highlight {
|
||||
.gp { color: #818c96; }
|
||||
}
|
||||
|
||||
pre { color: #bfbfbf; } /* override Bootstrap */
|
||||
kbd { background-color: black; }
|
||||
}
|
||||
|
||||
@@ -3,26 +3,23 @@
|
||||
*/
|
||||
|
||||
@mixin dark-scheme {
|
||||
/* framework */
|
||||
--main-wrapper-bg: rgb(27, 27, 30);
|
||||
/* Framework color */
|
||||
--body-bg: var(--main-wrapper-bg);
|
||||
--topbar-wrapper-bg: rgb(39, 40, 43);
|
||||
--search-wrapper-bg: rgb(34, 34, 39);
|
||||
--search-icon-color: rgb(100, 102, 105);
|
||||
--input-focus-border-color: rgb(112, 114, 115);
|
||||
--mask-bg: rgb(68, 69, 70);
|
||||
--footer-bg-color: var(--main-wrapper-bg);
|
||||
|
||||
/* common color */
|
||||
--text-color: rgb(175, 176, 177);
|
||||
--heading-color: #cccccc;
|
||||
--text-muted-color: rgb(107, 116, 124);
|
||||
--link-color: rgb(138, 180, 248);
|
||||
--link-underline-color: rgb(82, 108, 150);
|
||||
--main-wrapper-bg: rgb(27, 27, 30);
|
||||
--main-border-color: rgb(44, 45, 45);
|
||||
--button-bg: rgb(39, 40, 43);
|
||||
--scrollbar-track-bg: rgba(0, 0, 0, 0.3);
|
||||
--scrollbar-thumb-bg: rgb(173 171 171 / 50%);
|
||||
|
||||
/* Common color */
|
||||
--text-color: rgb(175, 176, 177);
|
||||
--text-muted-color: rgb(107, 116, 124);
|
||||
--heading-color: #cccccc;
|
||||
--blockquote-border-color: rgb(66, 66, 66);
|
||||
--blockquote-text-color: rgb(117, 117, 117);
|
||||
--link-color: rgb(138, 180, 248);
|
||||
--link-underline-color: rgb(82, 108, 150);
|
||||
--button-bg: rgb(39, 40, 43);
|
||||
--btn-border-color: rgb(63, 65, 68);
|
||||
--btn-backtotop-color: var(--text-color);
|
||||
--btn-backtotop-border-color: var(--btn-border-color);
|
||||
@@ -33,21 +30,26 @@
|
||||
--checkbox-checked-color: var(--link-color);
|
||||
|
||||
/* Sidebar */
|
||||
--nav-cursor-color: rgb(183, 182, 182);
|
||||
--sidebar-bg: radial-gradient(circle, #242424 0%, #1d1f27 100%);
|
||||
--sidebar-muted-color: #6d6c6b;
|
||||
--sidebar-active-color: rgb(255 255 255 / 80%);
|
||||
--nav-cursor-color: rgb(183, 182, 182);
|
||||
--sidebar-btn-bg: rgb(117 116 116 / 20%);
|
||||
|
||||
/* Top Bar */
|
||||
/* Topbar */
|
||||
--topbar-text-color: var(--text-color);
|
||||
--topbar-wrapper-bg: rgb(39, 40, 43);
|
||||
--search-wrapper-bg: rgb(34, 34, 39);
|
||||
--search-wrapper-border-color: rgb(34, 34, 39);
|
||||
--search-icon-color: rgb(100, 102, 105);
|
||||
--input-focus-border-color: rgb(112, 114, 115);
|
||||
|
||||
/* Home page */
|
||||
--post-list-text-color: rgb(175, 176, 177);
|
||||
--btn-patinator-text-color: var(--text-color);
|
||||
--btn-paginator-hover-color: rgb(64, 65, 66);
|
||||
--btn-active-bg: rgba(28, 52, 94, 1);
|
||||
--btn-active-border-color: rgb(66, 94, 138);
|
||||
--btn-text-color: var(--text-color);
|
||||
--btn-paginator-border-color: var(--btn-border-color);
|
||||
--btn-paginator-shadow: var(--main-wrapper-bg);
|
||||
--btn-text-color: var(--text-color);
|
||||
--pin-bg: rgb(34 35 37);
|
||||
--pin-color: inherit;
|
||||
|
||||
@@ -75,6 +77,7 @@
|
||||
/* categories */
|
||||
--categories-border: rgb(64, 66, 69);
|
||||
--categories-hover-bg: rgb(73, 75, 76);
|
||||
--categories-icon-hover-color: white;
|
||||
|
||||
/* archives */
|
||||
--timeline-node-bg: rgb(150, 152, 156);
|
||||
@@ -82,6 +85,7 @@
|
||||
--timeline-year-dot-color: var(--timeline-color);
|
||||
|
||||
/* Footer */
|
||||
--footer-bg-color: var(--main-wrapper-bg);
|
||||
--footer-link: rgb(171, 171, 171);
|
||||
|
||||
.post-content img {
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
--highlight-bg-color: #f7f7f7;
|
||||
--highlighter-rouge-color: #2f2f2f;
|
||||
--highlight-lineno-color: #c2c6cc;
|
||||
--highlight-lineno-border-color: #e9ecef;
|
||||
--inline-code-bg: #f3f3f3;
|
||||
--code-header-bg: #eaeaea;
|
||||
--lang-badge-color: rgb(128 128 128 / 87%);
|
||||
--lang-badge-muted-color: rgb(128 128 128 / 36%);
|
||||
--clipboard-checked-color: #43c743;
|
||||
|
||||
} // light-syntax
|
||||
|
||||
@@ -3,22 +3,24 @@
|
||||
*/
|
||||
|
||||
@mixin light-scheme {
|
||||
/* Common */
|
||||
/* Framework color */
|
||||
--body-bg: #fafafa;
|
||||
--mask-bg: #c1c3c5;
|
||||
--main-wrapper-bg: white;
|
||||
--main-border-color: #f3f3f3;
|
||||
--btn-border-color: #e9ecef;
|
||||
--scrollbar-track-bg: rgba(0, 0, 0, 0.3);
|
||||
--scrollbar-thumb-bg: rgba(0, 0, 0, 0.3);
|
||||
|
||||
/* Common color */
|
||||
--text-color: #34343c;
|
||||
--text-muted-color: gray;
|
||||
--heading-color: black;
|
||||
--blockquote-border-color: #eee;
|
||||
--blockquote-text-color: #9a9a9a;
|
||||
--link-color: #2a408e;
|
||||
--link-underline-color: #dee2e6;
|
||||
--text-muted-color: gray;
|
||||
--tb-odd-bg: #fbfcfd;
|
||||
--tb-border-color: #eaeaea;
|
||||
--button-bg: #fff;
|
||||
--btn-border-color: #e9ecef;
|
||||
--btn-backtotop-color: #686868;
|
||||
--btn-backtotop-border-color: #f1f1f1;
|
||||
--btn-box-shadow: #eaeaea;
|
||||
@@ -26,16 +28,17 @@
|
||||
--checkbox-checked-color: #07a8f7;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar-bg: radial-gradient(
|
||||
circle,
|
||||
rgba(42, 30, 107, 1) 0%,
|
||||
rgba(35, 37, 46, 1) 100%);
|
||||
--nav-cursor-color: #fcfcfc;
|
||||
--sidebar-bg: #eeeeee;
|
||||
--sidebar-muted-color: #a2a19f;
|
||||
--sidebar-active-color: #424242;
|
||||
--nav-cursor-color: #757575;
|
||||
--sidebar-btn-bg: white;
|
||||
|
||||
/* Topbar */
|
||||
--topbar-wrapper-bg: white;
|
||||
--topbar-text-color: rgb(78, 78, 78);
|
||||
--search-wrapper-bg: #f5f5f5;
|
||||
--topbar-wrapper-bg: white;
|
||||
--search-wrapper-bg: rgb(245 245 245 / 50%);
|
||||
--search-wrapper-border-color: rgb(245 245 245);
|
||||
--search-tag-bg: #f8f9fa;
|
||||
--search-icon-color: #c2c6cc;
|
||||
--input-focus-border-color: var(--btn-border-color);
|
||||
@@ -43,12 +46,9 @@
|
||||
/* Home page */
|
||||
--post-list-text-color: dimgray;
|
||||
--btn-patinator-text-color: #555555;
|
||||
--btn-paginator-hover-color: #e9ecef;
|
||||
--btn-active-bg: #2a408e;
|
||||
--btn-active-border-color: #007bff;
|
||||
--btn-text-color: #f8f8f8;
|
||||
--btn-paginator-border-color: #f1f1f1;
|
||||
--btn-paginator-shadow: #4b92d2;
|
||||
--btn-paginator-hover-color: var(--sidebar-bg);
|
||||
--btn-paginator-border-color: var(--sidebar-bg);
|
||||
--btn-text-color: #676666;
|
||||
--pin-bg: #f5f5f5;
|
||||
--pin-color: #999fa4;
|
||||
|
||||
@@ -58,13 +58,19 @@
|
||||
--card-box-shadow: rgba(234, 234, 234, 0.7686274509803922);
|
||||
--label-color: #616161;
|
||||
--relate-post-date: rgba(30, 55, 70, 0.4);
|
||||
--footnote-target-bg: lightcyan;
|
||||
--tag-bg: rgba(0, 0, 0, 0.075);
|
||||
--tag-border: #dee2e6;
|
||||
--tag-shadow: var(--btn-border-color);
|
||||
--tag-hover: rgb(222, 226, 230);
|
||||
--categories-hover-bg: var(--btn-border-color);
|
||||
--tb-odd-bg: #fbfcfd;
|
||||
--tb-border-color: #eaeaea;
|
||||
--dash-color: silver;
|
||||
|
||||
/* Categories */
|
||||
--categories-hover-bg: var(--btn-border-color);
|
||||
--categories-icon-hover-color: darkslategray;
|
||||
|
||||
/* Archive */
|
||||
--timeline-color: rgba(0, 0, 0, 0.075);
|
||||
--timeline-node-bg: #c2c6cc;
|
||||
@@ -72,6 +78,5 @@
|
||||
|
||||
/* Footer */
|
||||
--footer-bg-color: #ffffff;
|
||||
--footnote-target-bg: lightcyan;
|
||||
--footer-link: #424242;
|
||||
} // light-scheme
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*!
|
||||
* The styles for Jekyll theme Chirpy
|
||||
*
|
||||
* Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy)
|
||||
* Chirpy v4.3.0 (https://github.com/cotes2020/jekyll-theme-chirpy)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
"addon/module",
|
||||
"addon/variables",
|
||||
"variables-hook",
|
||||
"addon/syntax",
|
||||
"addon/commons",
|
||||
|
||||
|
||||
@@ -8,24 +8,22 @@
|
||||
|
||||
.categories {
|
||||
margin-bottom: 2rem;
|
||||
|
||||
.card-header {
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
i {
|
||||
&.far,
|
||||
&.fas {
|
||||
font-size: 86%; // fontawesome icons
|
||||
}
|
||||
@extend %category-icon-color;
|
||||
|
||||
font-size: 86%; // fontawesome icons
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
padding-left: 2rem;
|
||||
> i {
|
||||
@extend %category-icon-color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
@@ -33,10 +31,6 @@
|
||||
|
||||
}
|
||||
|
||||
.card-header > span > i:first-child {
|
||||
@extend %category-icon-color;
|
||||
}
|
||||
|
||||
} // .categories
|
||||
|
||||
.category-trigger {
|
||||
@@ -45,11 +39,18 @@
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
color: #6c757d !important;
|
||||
> i.fas {
|
||||
|
||||
&:hover {
|
||||
i {
|
||||
color: var(--categories-icon-hover-color);
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
position: relative;
|
||||
height: 0.7rem;
|
||||
width: 1rem;
|
||||
transition: 300ms ease all;
|
||||
transition: transform 300ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,27 +3,24 @@
|
||||
*/
|
||||
|
||||
.pagination {
|
||||
font-size: 1rem;
|
||||
color: var(--btn-patinator-text-color);
|
||||
font-family: 'Lato', sans-serif;
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.page-item {
|
||||
.page-link {
|
||||
color: var(--btn-patinator-text-color);
|
||||
color: inherit;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--btn-paginator-border-color);
|
||||
font-family: 'Lato', sans-serif;
|
||||
background-color: var(--button-bg);
|
||||
&:hover {
|
||||
background-color: var(--btn-paginator-hover-color);
|
||||
@@ -31,9 +28,7 @@
|
||||
}
|
||||
&.active {
|
||||
.page-link {
|
||||
background-color: var(--btn-active-bg);
|
||||
border-color: var(--btn-active-border-color);
|
||||
box-shadow: 0 0 8px 0 var(--btn-paginator-shadow) !important;
|
||||
background-color: var(--btn-paginator-hover-color);
|
||||
color: var(--btn-text-color);
|
||||
}
|
||||
}
|
||||
@@ -49,9 +44,6 @@
|
||||
&:last-child .page-link {
|
||||
border-radius: 50%;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
} // .page-item
|
||||
|
||||
} // .pagination
|
||||
@@ -116,7 +108,15 @@
|
||||
/* Hide SideBar and TOC */
|
||||
@media all and (max-width: 830px) {
|
||||
.pagination {
|
||||
justify-content: center;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.page-item {
|
||||
&:not(:first-child):not(:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,11 +144,24 @@
|
||||
|
||||
.pagination {
|
||||
font-size: 0.85rem;
|
||||
.page-item .page-link {
|
||||
width: 2.2rem;
|
||||
height: 2.2rem;
|
||||
|
||||
.page-item {
|
||||
&:not(:last-child) {
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.page-index {
|
||||
display: none;
|
||||
}
|
||||
|
||||
} // .pagination
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,24 +23,12 @@
|
||||
padding-right: $pr;
|
||||
}
|
||||
|
||||
.timeago::before {
|
||||
content: attr(prefix);
|
||||
}
|
||||
|
||||
#post-wrapper .post-meta {
|
||||
> div:nth-child(2) {
|
||||
> span:not(:first-child)::before {
|
||||
@include dot;
|
||||
}
|
||||
}
|
||||
|
||||
#pv::after {
|
||||
content: " views";
|
||||
}
|
||||
|
||||
.readtime::after {
|
||||
content: " read";
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
@@ -151,14 +139,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
#toc li > a {
|
||||
line-height: 1rem;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
#toc li a {
|
||||
font-size: 0.8rem;
|
||||
|
||||
&.nav-link:not(.active) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nav[data-toggle=toc] {
|
||||
.nav {
|
||||
.nav > li > a.active {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Related Posts --- */
|
||||
@@ -221,9 +216,12 @@
|
||||
|
||||
#post-extend-wrapper {
|
||||
min-height: 2rem;
|
||||
|
||||
#disqus_thread {
|
||||
min-height: 7.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.post-tail-bottom a {
|
||||
@@ -252,7 +250,11 @@
|
||||
}
|
||||
}
|
||||
> i {
|
||||
padding-top: 0.35rem;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
|
||||
&:hover {
|
||||
@extend %btn-share-hovor;
|
||||
}
|
||||
@@ -311,16 +313,6 @@
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content > div[class^='language-'] {
|
||||
@include ml-mr(-1.25rem);
|
||||
|
||||
border-radius: 0;
|
||||
&::before { // the lang badge
|
||||
right: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
|
||||
3
_sass/variables-hook.scss
Normal file
3
_sass/variables-hook.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
Appending custom SCSS variables will override the default ones in `_sass/addon/variables.scsss`
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: About
|
||||
icon: fas fa-info
|
||||
icon: fas fa-info-circle
|
||||
order: 4
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layout: tags
|
||||
title: Tags
|
||||
icon: fas fa-tags
|
||||
icon: fas fa-tag
|
||||
order: 2
|
||||
---
|
||||
|
||||
@@ -11,11 +11,23 @@ redirect_from:
|
||||
dynamic_title: true
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<div class="lead">
|
||||
<p>Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. </p>
|
||||
<p>
|
||||
<a href="{{ '/' | relative_url }}">Head back Home</a>
|
||||
to try finding it again, or search for it on the
|
||||
<a href="{{ 'archives' | relative_url }}">Archives page</a>.
|
||||
|
||||
{%- capture _head_back -%}
|
||||
<a href="{{ '/' | relative_url }}">{{ site.data.locales[lang].not_found.head_back }}</a>
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- capture _archives_page -%}
|
||||
<a href="{{ 'archives' | relative_url }}">{{ site.data.locales[lang].not_found.archives_page }}</a>
|
||||
{%- endcapture -%}
|
||||
|
||||
<p>{{site.data.locales[lang].not_found.statment }}</p>
|
||||
|
||||
<p>{{ site.data.locales[lang].not_found.hint_template
|
||||
| replace: ':HEAD_BAK', _head_back
|
||||
| replace: ':ARCHIVES_PAGE', _archives_page }}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
---
|
||||
---
|
||||
|
||||
// see: /_sass/addon/commons.scss
|
||||
/*
|
||||
If the number of TAB files has changed, the following variable is required.
|
||||
And it must be defined before `@import`.
|
||||
*/
|
||||
$tab-count: {{ site.tabs | size | plus: 1 }}; // plus 1 for home tab
|
||||
|
||||
@import "jekyll-theme-chirpy";
|
||||
@import "{{ site.theme }}";
|
||||
|
||||
/* append your custom style below */
|
||||
|
||||
@@ -15,7 +15,7 @@ permalink: /feed.xml
|
||||
<uri>{{ "/" | absolute_url }}</uri>
|
||||
</author>
|
||||
<link rel="self" type="application/atom+xml" href="{{ page.url | absolute_url }}"/>
|
||||
<link rel="alternate" type="text/html" hreflang="{{ site.lang | default: 'en' }}"
|
||||
<link rel="alternate" type="text/html" hreflang="{{ site.lang }}"
|
||||
href="{{ '/' | absolute_url }}"/>
|
||||
<generator uri="https://jekyllrb.com/" version="{{ jekyll.version }}">Jekyll</generator>
|
||||
<rights> © {{ 'now' | date: '%Y' }} {{ site.social.name }} </rights>
|
||||
|
||||
@@ -11,7 +11,7 @@ layout: compress
|
||||
"tags": "{{ post.tags | join: ', ' }}",
|
||||
"date": "{{ post.date }}",
|
||||
{% include no-linenos.html content=post.content %}
|
||||
"snippet": "{{ content | strip_html | strip_newlines | remove_chars | escape | truncate: 300 | replace: '\', '\\\\' }}"
|
||||
"snippet": "{{ content | strip_html | strip_newlines | remove_chars | escape | replace: '\', '\\\\' }}"
|
||||
}{% unless forloop.last %},{% endunless %}
|
||||
{% endfor %}
|
||||
]
|
||||
|
||||
4
assets/js/dist/categories.min.js
vendored
4
assets/js/dist/categories.min.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* Chirpy v4.3.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),r=$("#search-result-wrapper"),d=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),f={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},p=function(){let e=!1;return{on(){e||(u.block(),r.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(d.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible(){return e}}}();function h(){return s.hasClass("loaded")}o.click(function(){f.on(),p.on(),i.focus()}),s.click(function(){f.off(),p.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):p.off():""!==i.val()&&(p.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),d.empty()):p.off(),i.focus(),t.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const s=$("body");return{toggle(){!1===o?s.attr(e,""):s.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),s=$("#toc-wrapper"),t=$(".access"),a=$("#search-input");let l,n=0;const r=o.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>r?(o.removeClass("topbar-down").addClass("topbar-up"),0<s.length&&s.removeClass("topbar-down"),0<t.length&&t.removeClass("topbar-down"),a.is(":focus")&&a.blur()):e+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),0<s.length&&s.addClass("topbar-down"),0<t.length&&t.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),s=e.text().trim();let t=(0<o.length?o:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==t&&e.text(t):e.text()!==s&&e.text(s))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){const e=$(".collapse");e.on("hide.bs.collapse",function(){var e="h_"+$(this).attr("id").substring("l_".length);e&&($(`#${e} .far.fa-folder-open`).attr("class","far fa-folder fa-fw"),$(`#${e} i.fas`).addClass("rotate"),$(`#${e}`).removeClass("hide-border-bottom"))}),e.on("show.bs.collapse",function(){var e="h_"+$(this).attr("id").substring("l_".length);e&&($(`#${e} .far.fa-folder`).attr("class","far fa-folder-open fa-fw"),$(`#${e} i.fas`).removeClass("rotate"),$(`#${e}`).addClass("hide-border-bottom"))})});
|
||||
$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),r=$("#search-result-wrapper"),d=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),f=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset:()=>o}}(),u={on(){o.addClass("unloaded"),l.addClass("unloaded"),e.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),o.removeClass("unloaded"),l.removeClass("unloaded"),e.removeClass("unloaded")}},p=function(){let o=!1;return{on(){o||(f.block(),r.removeClass("unloaded"),a.addClass("unloaded"),o=!0)},off(){o&&(d.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),f.release(),i.val(""),o=!1)},isVisible:()=>o}}();function h(){return s.hasClass("loaded")}e.click(function(){u.on(),p.on(),i.focus()}),s.click(function(){u.off(),p.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(o){8===o.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):p.off():""!==i.val()&&(p.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),d.empty()):p.off(),i.focus(),t.removeClass("visible")})}),$(function(){const o=function(){let o=!1;const e=$("body");return{toggle(){!1===o?e.attr("sidebar-display",""):e.removeAttr("sidebar-display"),o=!o}}}();$("#sidebar-trigger").click(o.toggle),$("#mask").click(o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),e=$("#toc-wrapper"),s=$(".access"),t=$("#search-input");let a,l=0;const n=5,r=o.outerHeight();$(window).scroll(function(o){$("#topbar-title").is(":hidden")&&(a=!0)}),setInterval(function(){a&&(!function(){var a=$(this).scrollTop();Math.abs(l-a)<=n||(a>l&&a>r?(o.removeClass("topbar-down").addClass("topbar-up"),e.length>0&&e.removeClass("topbar-down"),s.length>0&&s.removeClass("topbar-down"),t.is(":focus")&&t.blur()):a+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),e.length>0&&e.addClass("topbar-down"),s.length>0&&s.addClass("topbar-down")),l=a)}(),a=!1)},250)}),$(function(){const o=$("#topbar-title"),e=$("div.post>h1"),s=o.text().trim();let t=e.length>0?e.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||e.is(":hidden")||o.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?o.text()!==t&&o.text(t):o.text()!==s&&o.text(s)}),o.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){const o=$(".collapse");o.on("hide.bs.collapse",function(){const o="h_"+$(this).attr("id").substring("l_".length);o&&($(`#${o} .far.fa-folder-open`).attr("class","far fa-folder fa-fw"),$(`#${o} i.fas`).addClass("rotate"),$(`#${o}`).removeClass("hide-border-bottom"))}),o.on("show.bs.collapse",function(){const o="h_"+$(this).attr("id").substring("l_".length);o&&($(`#${o} .far.fa-folder`).attr("class","far fa-folder-open fa-fw"),$(`#${o} i.fas`).removeClass("rotate"),$(`#${o}`).addClass("hide-border-bottom"))})});
|
||||
4
assets/js/dist/commons.min.js
vendored
4
assets/js/dist/commons.min.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* Chirpy v4.3.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),d=$("#search-result-wrapper"),r=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),d.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(r.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),d.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible(){return e}}}();function h(){return s.hasClass("loaded")}o.click(function(){p.on(),f.on(),i.focus()}),s.click(function(){p.off(),f.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):f.off():""!==i.val()&&(f.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),r.empty()):f.off(),i.focus(),t.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const s=$("body");return{toggle(){!1===o?s.attr(e,""):s.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),s=$("#toc-wrapper"),t=$(".access"),a=$("#search-input");let l,n=0;const d=o.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>d?(o.removeClass("topbar-down").addClass("topbar-up"),0<s.length&&s.removeClass("topbar-down"),0<t.length&&t.removeClass("topbar-down"),a.is(":focus")&&a.blur()):e+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),0<s.length&&s.addClass("topbar-down"),0<t.length&&t.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),s=e.text().trim();let t=(0<o.length?o:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==t&&e.text(t):e.text()!==s&&e.text(s))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})});
|
||||
$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),d=$("#search-result-wrapper"),r=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset:()=>e}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),d.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(r.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),d.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible:()=>e}}();function h(){return s.hasClass("loaded")}o.click(function(){p.on(),f.on(),i.focus()}),s.click(function(){p.off(),f.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):f.off():""!==i.val()&&(f.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),r.empty()):f.off(),i.focus(),t.removeClass("visible")})}),$(function(){const e=function(){let e=!1;const o=$("body");return{toggle(){!1===e?o.attr("sidebar-display",""):o.removeAttr("sidebar-display"),e=!e}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#topbar-wrapper"),o=$("#toc-wrapper"),s=$(".access"),t=$("#search-input");let a,l=0;const n=5,d=e.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(a=!0)}),setInterval(function(){a&&(!function(){var a=$(this).scrollTop();Math.abs(l-a)<=n||(a>l&&a>d?(e.removeClass("topbar-down").addClass("topbar-up"),o.length>0&&o.removeClass("topbar-down"),s.length>0&&s.removeClass("topbar-down"),t.is(":focus")&&t.blur()):a+$(window).height()<$(document).height()&&(e.removeClass("topbar-up").addClass("topbar-down"),o.length>0&&o.addClass("topbar-down"),s.length>0&&s.addClass("topbar-down")),l=a)}(),a=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),s=e.text().trim();let t=o.length>0?o.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?e.text()!==t&&e.text(t):e.text()!==s&&e.text(s)}),e.click(function(){$("body,html").animate({scrollTop:0},800)})});
|
||||
4
assets/js/dist/home.min.js
vendored
4
assets/js/dist/home.min.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* Chirpy v4.3.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#search-cleaner"),s=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),r=$("#search-result-wrapper"),d=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),h={on(){e.addClass("unloaded"),l.addClass("unloaded"),t.addClass("unloaded"),n.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),t.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),r.removeClass("unloaded"),s.addClass("unloaded"),e=!0)},off(){e&&(d.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),a.removeClass("visible"),s.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible(){return e}}}();function p(){return o.hasClass("loaded")}t.click(function(){h.on(),f.on(),i.focus()}),o.click(function(){h.off(),f.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?p()?c.removeClass("unloaded"):f.off():""!==i.val()&&(f.on(),a.hasClass("visible")||a.addClass("visible"),p()&&c.addClass("unloaded"))}),a.on("click",function(){i.val(""),p()?(c.removeClass("unloaded"),d.empty()):f.off(),i.focus(),a.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#topbar-wrapper"),o=$("#toc-wrapper"),a=$(".access"),s=$("#search-input");let l,n=0;const r=t.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>r?(t.removeClass("topbar-down").addClass("topbar-up"),0<o.length&&o.removeClass("topbar-down"),0<a.length&&a.removeClass("topbar-down"),s.is(":focus")&&s.blur()):e+$(window).height()<$(document).height()&&(t.removeClass("topbar-up").addClass("topbar-down"),0<o.length&&o.addClass("topbar-down"),0<a.length&&a.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),t=$("div.post>h1"),o=e.text().trim();let a=(0<t.length?t:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||t.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==a&&e.text(a):e.text()!==o&&e.text(o))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){let s=$(".timeago").length,e=void 0;function t(){return $(".timeago").each(function(){if(0<$(this).children("i").length){let e=$(this).children("i");var t=e.text();$(this).text(function(e,t){let o=new Date,a=new Date(e);return e=void 0!==t?`${t} `:"",a.getFullYear()!==o.getFullYear()?(--s,e+a.toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric"})):a.getMonth()!==o.getMonth()?(--s,e+a.toLocaleString("en-US",{month:"short",day:"numeric"})):(t=Math.floor((o-a)/1e3),1<=(e=Math.floor(t/86400))?(--s,e+" day"+(1<e?"s":"")+" ago"):1<=(e=Math.floor(t/3600))?e+" hour"+(1<e?"s":"")+" ago":1<=(t=Math.floor(t/60))?t+" minute"+(1<t?"s":"")+" ago":"just now")}(t,$(this).attr("prep"))),$(this).append(e)}}),0===s&&void 0!==e&&clearInterval(e),s}0!==s&&0<t()&&(e=setInterval(t,6e4))});
|
||||
$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#search-cleaner"),l=$("#main"),n=$("#topbar-title"),s=$("#search-wrapper"),r=$("#search-result-wrapper"),i=$("#search-results"),d=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset:()=>e}}(),p={on(){e.addClass("unloaded"),n.addClass("unloaded"),t.addClass("unloaded"),s.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),s.removeClass("d-flex"),e.removeClass("unloaded"),n.removeClass("unloaded"),t.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),r.removeClass("unloaded"),l.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),a.removeClass("visible"),l.removeClass("unloaded"),u.release(),d.val(""),e=!1)},isVisible:()=>e}}();function h(){return o.hasClass("loaded")}t.click(function(){p.on(),f.on(),d.focus()}),o.click(function(){p.off(),f.off()}),d.focus(function(){s.addClass("input-focus")}),d.focusout(function(){s.removeClass("input-focus")}),d.on("keyup",function(e){8===e.keyCode&&""===d.val()?h()?c.removeClass("unloaded"):f.off():""!==d.val()&&(f.on(),a.hasClass("visible")||a.addClass("visible"),h()&&c.addClass("unloaded"))}),a.on("click",function(){d.val(""),h()?(c.removeClass("unloaded"),i.empty()):f.off(),d.focus(),a.removeClass("visible")})}),$(function(){const e=function(){let e=!1;const t=$("body");return{toggle(){!1===e?t.attr("sidebar-display",""):t.removeAttr("sidebar-display"),e=!e}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#topbar-wrapper"),t=$("#toc-wrapper"),o=$(".access"),a=$("#search-input");let l,n=0;const s=5,r=e.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(!function(){var l=$(this).scrollTop();Math.abs(n-l)<=s||(l>n&&l>r?(e.removeClass("topbar-down").addClass("topbar-up"),t.length>0&&t.removeClass("topbar-down"),o.length>0&&o.removeClass("topbar-down"),a.is(":focus")&&a.blur()):l+$(window).height()<$(document).height()&&(e.removeClass("topbar-up").addClass("topbar-down"),t.length>0&&t.addClass("topbar-down"),o.length>0&&o.addClass("topbar-down")),n=l)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),t=$("div.post>h1"),o=e.text().trim();let a=t.length>0?t.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||t.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?e.text()!==a&&e.text(a):e.text()!==o&&e.text(o)}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){let e=$(".timeago").length,t=void 0;const o=$("meta[name=day-prompt]").attr("content"),a=$("meta[name=hour-prompt]").attr("content"),l=$("meta[name=minute-prompt]").attr("content"),n=$("meta[name=justnow-prompt]").attr("content");function s(){return $(".timeago").each(function(){if($(this).children("i").length>0){let t=$(this).clone().children().remove().end().text(),s=$(this).children("i"),r=s.text();$(this).text(function(t,s){let r=new Date,i=new Date(t);if(i.getFullYear()!==r.getFullYear()||i.getMonth()!==r.getMonth())return s;let d=Math.floor((r-i)/1e3),c=Math.floor(d/86400);if(c>=1)return e-=1,` ${c} ${o}`;let u=Math.floor(d/3600);if(u>=1)return` ${u} ${a}`;let $=Math.floor(d/60);return $>=1?` ${$} ${l}`:n}(r,t)),$(this).append(s)}}),0===e&&void 0!==t&&clearInterval(t),e}0!==e&&s()>0&&(t=setInterval(s,6e4))});
|
||||
4
assets/js/dist/page.min.js
vendored
4
assets/js/dist/page.min.js
vendored
File diff suppressed because one or more lines are too long
4
assets/js/dist/post.min.js
vendored
4
assets/js/dist/post.min.js
vendored
File diff suppressed because one or more lines are too long
4
assets/js/dist/pvreport.min.js
vendored
4
assets/js/dist/pvreport.min.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* Chirpy v4.3.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
const getInitStatus=function(){let t=!1;return()=>{var e=t;return t=t||!0,e}}(),PvOpts=function(){function t(e){return $(e).attr("content")}function e(e){e=t(e);return void 0!==e&&!1!==e}return{getProxyMeta(){return t("meta[name=pv-proxy-endpoint]")},getLocalMeta(){return t("meta[name=pv-cache-path]")},hasProxyMeta(){return e("meta[name=pv-proxy-endpoint]")},hasLocalMeta(){return e("meta[name=pv-cache-path]")}}}(),PvStorage=function(){const a={KEY_PV:"pv",KEY_PV_SRC:"pv_src",KEY_CREATION:"pv_created_date"},t={LOCAL:"same-origin",PROXY:"cors"};function r(e){return localStorage.getItem(e)}function o(e,t){localStorage.setItem(e,t)}function n(e,t){o(a.KEY_PV,e),o(a.KEY_PV_SRC,t),o(a.KEY_CREATION,(new Date).toJSON())}return{keysCount(){return Object.keys(a).length},hasCache(){return null!==localStorage.getItem(a.KEY_PV)},getCache(){return JSON.parse(localStorage.getItem(a.KEY_PV))},saveLocalCache(e){n(e,t.LOCAL)},saveProxyCache(e){n(e,t.PROXY)},isExpired(){let e=new Date(r(a.KEY_CREATION));return e.setHours(e.getHours()+1),Date.now()>=e.getTime()},isFromLocal(){return r(a.KEY_PV_SRC)===t.LOCAL},isFromProxy(){return r(a.KEY_PV_SRC)===t.PROXY},newerThan(e){return PvStorage.getCache().totalsForAllResults["ga:pageviews"]>e.totalsForAllResults["ga:pageviews"]},inspectKeys(){if(localStorage.length===PvStorage.keysCount())for(let e=0;e<localStorage.length;e++)switch(localStorage.key(e)){case a.KEY_PV:case a.KEY_PV_SRC:case a.KEY_CREATION:break;default:return void localStorage.clear()}else localStorage.clear()}}}();function countUp(t,a,r){if(t<a){let e=new CountUp(r,t,a);e.error?console.error(e.error):e.start()}}function countPV(t,a){let r=0;if(void 0!==a)for(let e=0;e<a.length;++e)if(a[parseInt(e,10)][0]===t){r+=parseInt(a[parseInt(e,10)][1],10);break}return r}function tacklePV(e,t,a,r){let o=countPV(t,e);o=0===o?1:o,r?(r=parseInt(a.text().replace(/,/g,""),10),o>r&&countUp(r,o,a.attr("id"))):a.text((new Intl.NumberFormat).format(o))}function displayPageviews(e){if(void 0!==e){let t=getInitStatus();const a=e.rows;0<$("#post-list").length?$(".post-preview").each(function(){var e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)}):0<$(".post").length&&(e=window.location.pathname,tacklePV(a,e,$("#pv"),t))}}function fetchProxyPageviews(){PvOpts.hasProxyMeta()&&$.ajax({type:"GET",url:PvOpts.getProxyMeta(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:e=>{PvStorage.saveProxyCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchLocalPageviews(t=!1){return fetch(PvOpts.getLocalMeta()).then(e=>e.json()).then(e=>{t&&PvStorage.isFromProxy()&&PvStorage.newerThan(e)||(displayPageviews(e),PvStorage.saveLocalCache(JSON.stringify(e)))})}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()?(displayPageviews(PvStorage.getCache()),PvStorage.isExpired()?PvOpts.hasLocalMeta()?fetchLocalPageviews(!0).then(fetchProxyPageviews):fetchProxyPageviews():PvStorage.isFromLocal()&&fetchProxyPageviews()):PvOpts.hasLocalMeta()?fetchLocalPageviews().then(fetchProxyPageviews):fetchProxyPageviews())});
|
||||
const getInitStatus=function(){let e=!1;return()=>{let t=e;return e||(e=!0),t}}(),PvOpts=function(){function e(e){return $(e).attr("content")}function t(t){let a=e(t);return void 0!==a&&!1!==a}return{getProxyMeta:()=>e("meta[name=pv-proxy-endpoint]"),getLocalMeta:()=>e("meta[name=pv-cache-path]"),hasProxyMeta:()=>t("meta[name=pv-proxy-endpoint]"),hasLocalMeta:()=>t("meta[name=pv-cache-path]")}}(),PvStorage=function(){const e={KEY_PV:"pv",KEY_PV_SRC:"pv_src",KEY_CREATION:"pv_created_date"},t="same-origin",a="cors";function o(e){return localStorage.getItem(e)}function r(e,t){localStorage.setItem(e,t)}function n(t,a){r(e.KEY_PV,t),r(e.KEY_PV_SRC,a),r(e.KEY_CREATION,(new Date).toJSON())}return{keysCount:()=>Object.keys(e).length,hasCache:()=>null!==localStorage.getItem(e.KEY_PV),getCache:()=>JSON.parse(localStorage.getItem(e.KEY_PV)),saveLocalCache(e){n(e,t)},saveProxyCache(e){n(e,a)},isExpired(){let t=new Date(o(e.KEY_CREATION));return t.setHours(t.getHours()+1),Date.now()>=t.getTime()},isFromLocal:()=>o(e.KEY_PV_SRC)===t,isFromProxy:()=>o(e.KEY_PV_SRC)===a,newerThan:e=>PvStorage.getCache().totalsForAllResults["ga:pageviews"]>e.totalsForAllResults["ga:pageviews"],inspectKeys(){if(localStorage.length===PvStorage.keysCount())for(let t=0;t<localStorage.length;t++){switch(localStorage.key(t)){case e.KEY_PV:case e.KEY_PV_SRC:case e.KEY_CREATION:break;default:return void localStorage.clear()}}else localStorage.clear()}}}();function countUp(e,t,a){if(e<t){let o=new CountUp(a,e,t);o.error?console.error(o.error):o.start()}}function countPV(e,t){let a=0;if(void 0!==t)for(let o=0;o<t.length;++o){if(t[parseInt(o,10)][0]===e){a+=parseInt(t[parseInt(o,10)][1],10);break}}return a}function tacklePV(e,t,a,o){let r=countPV(t,e);if(r=0===r?1:r,o){const e=parseInt(a.text().replace(/,/g,""),10);r>e&&countUp(e,r,a.attr("id"))}else a.text((new Intl.NumberFormat).format(r))}function displayPageviews(e){if(void 0===e)return;let t=getInitStatus();const a=e.rows;if($("#post-list").length>0)$(".post-preview").each(function(){const e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)});else if($(".post").length>0){const e=window.location.pathname;tacklePV(a,e,$("#pv"),t)}}function fetchProxyPageviews(){PvOpts.hasProxyMeta()&&$.ajax({type:"GET",url:PvOpts.getProxyMeta(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:e=>{PvStorage.saveProxyCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchLocalPageviews(e=!1){return fetch(PvOpts.getLocalMeta()).then(e=>e.json()).then(t=>{e&&PvStorage.isFromProxy()&&PvStorage.newerThan(t)||(displayPageviews(t),PvStorage.saveLocalCache(JSON.stringify(t)))})}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()?(displayPageviews(PvStorage.getCache()),PvStorage.isExpired()?PvOpts.hasLocalMeta()?fetchLocalPageviews(!0).then(fetchProxyPageviews):fetchProxyPageviews():PvStorage.isFromLocal()&&fetchProxyPageviews()):PvOpts.hasLocalMeta()?fetchLocalPageviews().then(fetchProxyPageviews):fetchProxyPageviews())});
|
||||
8
assets/js/lib/jquery.disqusloader.min.js
vendored
8
assets/js/lib/jquery.disqusloader.min.js
vendored
@@ -1,8 +0,0 @@
|
||||
/*!
|
||||
disqusLoader.js v1.0
|
||||
A JavaScript plugin for lazy-loading Disqus comments widget.
|
||||
-
|
||||
By Osvaldas Valutis, www.osvaldas.info
|
||||
Available for use under the MIT License
|
||||
*/
|
||||
(function(e,g,h,d){var a=e(g),k=function(o,n){var q,p;return function(){var t=this,s=arguments,r=+new Date;q&&r<q+o?(clearTimeout(p),p=setTimeout(function(){q=r,n.apply(t,s)},o)):(q=r,n.apply(t,s))}},m=false,j=false,i=false,c=false,f="unloaded",b=e(),l=function(){if(!b.length||b.data("disqusLoaderStatus")=="loaded"){return true}var n=a.scrollTop();if(b.offset().top-n>a.height()*j||n-b.offset().top-b.outerHeight()-(a.height()*j)>0){return true}e("#disqus_thread").removeAttr("id");b.attr("id","disqus_thread").data("disqusLoaderStatus","loaded");if(f=="loaded"){DISQUS.reset({reload:true,config:i})}else{g.disqus_config=i;if(f=="unloaded"){f="loading";e.ajax({url:c,async:true,cache:true,dataType:"script",success:function(){f="loaded"}})}}};a.on("scroll resize",k(m,l));e.disqusLoader=function(o,n){n=e.extend({},{laziness:1,throttle:250,scriptUrl:false,disqusConfig:false},n);j=n.laziness+1;m=n.throttle;i=n.disqusConfig;c=c===false?n.scriptUrl:c;b=(typeof o=="string"?e(o):o).eq(0);b.data("disqusLoaderStatus","unloaded");l()}})(jQuery,window,document);
|
||||
@@ -1,21 +1,33 @@
|
||||
# Chirpy
|
||||
<div align="right">
|
||||
|
||||
Language: [English](https://github.com/cotes2020/jekyll-theme-chirpy#readme) | 简体中文
|
||||
中文(简体) /
|
||||
[EN](https://github.com/cotes2020/jekyll-theme-chirpy#readme)
|
||||
|
||||
[](https://rubygems.org/gems/jekyll-theme-chirpy)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
|
||||
[](https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
|
||||
[](https://996.icu)
|
||||
</div>
|
||||
|
||||
一个不一样的 Jekyll 主题,采用响应式设计,方便记录、管理、分享您的知识和经验。[懂的进 »](https://chirpy.cotes.info)
|
||||
<div align="center">
|
||||
|
||||
[](https://chirpy.cotes.info)
|
||||
# Chirpy Jekyll Theme
|
||||
|
||||
[](https://rubygems.org/gems/jekyll-theme-chirpy)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
|
||||
[](https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
|
||||
[](https://996.icu)
|
||||
|
||||
一款简约而强大、采用响应式设计的 Jekyll 主题,适合展示专业写作内容。
|
||||
|
||||
**[线上体验 →](https://chirpy.cotes.info)**
|
||||
|
||||
[](https://chirpy.cotes.info)
|
||||
|
||||
</div>
|
||||
|
||||
## 功能一览
|
||||
|
||||
- 本地化外观语言
|
||||
- 可配置的主题颜色
|
||||
- 文章置顶
|
||||
- 可配置的全局主题颜色
|
||||
- 文章最后修改日期
|
||||
- 文章目录
|
||||
- 自动推荐相关文章
|
||||
@@ -31,58 +43,27 @@ Language: [English](https://github.com/cotes2020/jekyll-theme-chirpy#readme) |
|
||||
- SEO 优化
|
||||
- 网站性能优化
|
||||
|
||||
|
||||
## 前提要求
|
||||
|
||||
参考 [Jekyll Docs](https://jekyllrb.com/docs/installation/) 安装 `Ruby`,`RubyGems`,`Jekyll` 和 `Bundler`,Docker 粉可免。
|
||||
|
||||
参考 [Jekyll Docs](https://jekyllrb.com/docs/installation/) 安装 `Ruby`,`RubyGems`,`Jekyll` 和 `Bundler`。
|
||||
|
||||
## 安装
|
||||
|
||||
有二法可得此主题:
|
||||
### 创建新仓库
|
||||
|
||||
- **从 RubyGems 安装** - 易于版本升级,隔离无关的主题项目文件,让您的仓库舒适清爽。
|
||||
- **从 GitHub 上 Fork** - 对个性化二次开发友好,但是难于升级,只适合专业开发人员使用。
|
||||
有两种方式可以创建一个使用本主题的仓库:
|
||||
|
||||
### RubyGems 安装
|
||||
- **[使用 Chirpy Starter](#使用-chirpy-starter)** - 易于版本升级,隔离无关的主题项目文件,让您的仓库舒适清爽。
|
||||
|
||||
在您的 Jekyll 站点的 `Gemfile` 添加:
|
||||
- **[从 GitHub 上 Fork](#从-github-上-fork)** - 对个性化二次开发友好,但是难于升级。除非您决定魔改此款主题或者参与代码贡献,否则不推荐使用此方式。
|
||||
|
||||
```ruby
|
||||
gem "jekyll-theme-chirpy"
|
||||
```
|
||||
#### 使用 Chirpy Starter
|
||||
|
||||
然后,添加这行到您的 Jekyll 站点的 `_config.yml`:
|
||||
[使用 Chirpy Starter][use-starter] 来快速创建 Jekyll 站点,命名为 `<GH_USERNAME>.github.io`,其中 `GH_USERNAME` 是您的 GitHub username。
|
||||
|
||||
```yaml
|
||||
theme: jekyll-theme-chirpy
|
||||
```
|
||||
#### 从 GitHub 上 Fork
|
||||
|
||||
接着执行:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
最后, 拷贝额外所需主题的 gem 文件(详见 [starter 项目][starter] 的文件目录)至您的 Jekyll 站点, 然后把主题的 `_config.yml` 全部内容附加到您的 Jekyll 站点的同名文件。
|
||||
|
||||
> **提示**: 定位主题的 gem 文件,可以执行:
|
||||
>
|
||||
```console
|
||||
$ bundle info --path jekyll-theme-chirpy
|
||||
```
|
||||
|
||||
或者您可以 [使用 starter template][use-starter] 来快速创建 Jekyll 站点,以省去复制主题 gem 文件的时间。
|
||||
|
||||
### 在 GitHub 上 Fork
|
||||
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) 然后克隆到本地。(友情提示:默认分支的代码处于开发状态,如果您想博客更加稳定,请切换到最新的 [Tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) 开始写作。)
|
||||
|
||||
安装依赖:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) 并改名为 `<GH_USERNAME>.github.io`。友情提示:默认分支的代码处于开发状态,如果您想博客更加稳定,请切换到最新的 [Tag][latest-tag] 开始写作。
|
||||
|
||||
接着执行文件初始化:
|
||||
|
||||
@@ -90,18 +71,28 @@ $ bundle
|
||||
$ bash tools/init.sh
|
||||
```
|
||||
|
||||
> 如果您不打算部署到 GitHub Pages, 在上述命令后附加参数选项 `--no-gh`。
|
||||
> **注**:如果您不打算部署到 GitHub Pages, 在上述命令后附加参数选项 `--no-gh`。
|
||||
|
||||
上述脚本完成了以下工作:
|
||||
上述脚本将会:
|
||||
|
||||
1. 从您的仓库中删除了:
|
||||
- `.travis.yml`
|
||||
- `_posts` 下的文件
|
||||
- `docs` 目录
|
||||
|
||||
2. 如果使用了参数 `--no-gh`,则会怒删 `.github`。否则,将会配置 GitHub Actions:把 `.github/workflows/pages-deploy.yml.hook` 的后缀 `.hook` 去除,然后删除 `.github` 里的其他目录和文件。
|
||||
2. 如果使用了参数 `--no-gh`,则会怒删文件夹 `.github`。否则,配置 GitHub Actions:把 `.github/workflows/pages-deploy.yml.hook` 的后缀 `.hook` 去除,然后删除 `.github` 里的其他目录和文件。
|
||||
|
||||
3. 自动提交一个 Commit 以保存上述文件的更改。
|
||||
3. 从 `.gitignore` 中删除 `Gemfile.lock`。
|
||||
|
||||
4. 自动提交一个 Commit 以保存上述文件的更改。
|
||||
|
||||
### 安装依赖:
|
||||
|
||||
首次运行本项目,需要先安装依赖:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
@@ -114,6 +105,12 @@ $ bash tools/init.sh
|
||||
- `timezone`
|
||||
- `lang`
|
||||
|
||||
### 自定义样式
|
||||
|
||||
如果您需要自定义样式, 拷贝主题的文件 `assets/css/style.scss` 到您站点的相同路径上,然后在该文件末尾添加样式。
|
||||
|
||||
自 [`v4.1.0`][chirpy-4.1.0] 起,如果您想覆盖文件 `_sass/addon/variables.scss` 里定义的 SASS 变量的默认值,新建文件 `_sass/variables-hook.scss`,然后重写您需要的变量即可。
|
||||
|
||||
### 本地运行
|
||||
|
||||
发布之前,在本地预览:
|
||||
@@ -131,36 +128,43 @@ $ docker run -it --rm \
|
||||
jekyll serve
|
||||
```
|
||||
|
||||
访问本地服务:<http://localhost:4000>
|
||||
稍候片刻,即可访问本地服务:_<http://localhost:4000>_
|
||||
|
||||
### 部署
|
||||
|
||||
部署开始前,把 `_config.yml` 的 `url` 改为 `https://<username>.github.io`(或者您的私有域名,如:`https://yourdomain.com`)。另外,如果您想使用 [Project 类型网站](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites),修改配置文件的 `baseurl` 为项目名称,以斜杠开头,如:`/project`。
|
||||
部署开始前,把 `_config.yml` 的 `url` 改为 `https://<username>.github.io`(或者您的私有域名,如:`https://yourdomain.com`)。另外,如果您想使用 [Project 类型网站](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites),修改配置文件的 `baseurl` 为项目名称,以斜杠开头,如:`/project`。
|
||||
|
||||
现在您可以选择下列其中一个方式去站点部署。
|
||||
|
||||
#### 部署到 GitHub Pages
|
||||
#### 使用 GitHub Actions 部署
|
||||
|
||||
由于安全原因,GitHub Pages 的构建强制加了 `safe`参数,这导致了我们不能使用插件去创建所需的附加页面。因此,我们可以使用 GitHub Actions 去构建站点,把站点文件存储在一个新分支上,再指定该分支作为 Pages 服务的源。
|
||||
由于安全原因,默认的 GitHub Pages 的构建强制加了 `safe`参数,这导致了我们不能使用插件去创建所需的附加页面。因此,我们可以使用 GitHub Actions 去构建站点,把站点文件存储在一个新分支上,再指定该分支作为 Pages 服务的源。
|
||||
|
||||
快速检查 GitHub Actions 构建需要的文件:
|
||||
|
||||
- 确保您的 Jekyll 站点存在文件 `.github/workflows/pages-deploy.yml`。没有的话,新建并填入[示例工作流][workflow]的内容, 注意参数 `on.push.branches` 的值必须和您的仓库默认分支名相同。
|
||||
- 检查您的 Jekyll 站点是否有文件 `tools/test.sh` 和 `tools/deploy.sh`. 没有的话, 从本仓库拷贝到您的 Jekyll 项目.
|
||||
- 确保您的 Jekyll 站点存在文件 `.github/workflows/pages-deploy.yml`。没有的话,新建并填入「[示例 Workflow][workflow]」的内容,注意参数 `on.push.branches` 的值必须和您的仓库默认分支名相同。
|
||||
|
||||
在 GitHub 把您的仓库命名为 `<GH-USERNAME>.github.io`,然后开始发布:
|
||||
- 检查您的 Jekyll 站点是否有文件 `tools/deploy.sh`。没有的话, 从本仓库拷贝到您的 Jekyll 项目。
|
||||
|
||||
- 再者,如果您已经把文件 `Gemfile.lock` 提交到了仓库里面,并且您运行本项目的操作系统不是 Linux,需要添加新的平台信息:
|
||||
|
||||
```console
|
||||
$ bundle lock --add-platform x86_64-linux
|
||||
```
|
||||
|
||||
完成上述条目后,到 GitHub 把您的仓库命名为 `<GH-USERNAME>.github.io`,然后开始发布:
|
||||
|
||||
1. 推送任意一个 commit 到 `origin/master` 以触发 GitHub Actions workflow。一旦 build 完毕并且成功,远端将会自动出现一个新分支 `gh-pages` 用来存储构建的站点文件。
|
||||
|
||||
2. 回到 GitHub 上的仓库, 通过 _Settings_ → _Options_ → _GitHub Pages_ 选择分支 `gh-pages` 作为[_发布源_](https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site):
|
||||
2. 回到 GitHub 上的仓库,选择标签 _Settings_ → 点击左侧导航栏的 _Pages_ → _GitHub Pages_ 选择分支 `gh-pages` 的 `/(root)` 作为「[发布源][pages-src]」:
|
||||
|
||||

|
||||

|
||||
|
||||
3. 按照 GitHub 指示的地址去访问您的网站。
|
||||
|
||||
#### 部署到其他 Pages 平台
|
||||
#### 手动构建部署
|
||||
|
||||
在 GitHub 之外的平台,例如 GitLab,就没法享受 **GitHub Actions** 的便利了。因此我们需要在本地构建站点(或者在其他第三方 CI 平台),然后推送站点文件到服务器上。
|
||||
在 GitHub 之外的平台,就没法享受 **GitHub Actions** 的便利了。因此您需要在本地构建站点,然后推送站点文件到服务器上。
|
||||
|
||||
在项目根目录,运行:
|
||||
|
||||
@@ -180,25 +184,45 @@ $ docker run -it --rm \
|
||||
|
||||
生成的静态文件将会在 `_site`, 把内部的文件上传到服务器即可。
|
||||
|
||||
### 升级
|
||||
|
||||
这取决于您如何使用这个 theme:
|
||||
|
||||
- 如果您是使用 theme gem(`Gemfile` 会有 `gem "jekyll-theme-chirpy"`),编辑 `Gemfile` 并更新 them gem 的版本号,譬如:
|
||||
```diff
|
||||
- gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1"
|
||||
+ gem "jekyll-theme-chirpy", "~> 3.3", ">= 3.3.0"
|
||||
```
|
||||
|
||||
接着执行以下命令:
|
||||
|
||||
```console
|
||||
$ bundle update jekyll-theme-chirpy
|
||||
```
|
||||
|
||||
随着 theme 版本的升级,运行站点的必要文件(详见 [Chirpy Starter][starter])以及配置选项会出现变化,请参阅「[升级指南](https://github.com/cotes2020/jekyll-theme-chirpy/wiki/Upgrade-Guide)」的改动细节去保持您仓库中的相关文件同步到最新版本。
|
||||
|
||||
- 如果您是以 fork 的方式使用(您站点的 `Gemfile` 会有 `gemspec`),那么合并上游 [最新的 tag][latest-tag] 到您的 Repo 以完成升级。期间很有可能会产生冲突 (conflicts),请务必耐心谨慎地解决它们。
|
||||
|
||||
## 文档
|
||||
|
||||
若想要更多细节以及更佳的阅读体验,请参阅 [线上教程](https://chirpy.cotes.info/categories/tutorial/)。 与此同时,[Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki) 也有一份教程的拷贝。
|
||||
若想要更多细节以及更佳的阅读体验,请参阅「[线上教程](https://chirpy.cotes.info/categories/tutorial/)」。 与此同时,「[Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki)」也有一份教程的拷贝。请注意,Demo 网站和 Wiki 上的文档都是基于最新的发行版本,而 `master` 分支的功能往往领先于现有文档。
|
||||
|
||||
## 参与贡献
|
||||
|
||||
三人行必有我师,欢迎提报告 bug, 帮助改进代码质量,或者提交新功能。具体操作规则请参考 [贡献指南](../.github/CONTRIBUTING.md),谢谢 🙏。
|
||||
三人行必有我师,欢迎提报告 bug,帮助改进代码质量,或者提交新功能。具体操作规则请参考「[贡献指南](../.github/CONTRIBUTING.md)」,谢谢 🙏。
|
||||
|
||||
## 鸣谢
|
||||
|
||||
这个主题的开发主要基于 [Jekyll](https://jekyllrb.com/) 生态、[Bootstrap](https://getbootstrap.com/)、[Font Awesome](https://fontawesome.com/) 和其他一些出色的工具 (相关文件中可以找到这些工具的版权信息)。头像和图标的设计来自于 [Clipart Max](https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/)。
|
||||
此款主题的开发主要基于 [Jekyll](https://jekyllrb.com/) 生态、[Bootstrap](https://getbootstrap.com/)、[Font Awesome](https://fontawesome.com/) 和其他一些出色的工具 (相关文件中可以找到这些工具的版权信息)。头像和图标的设计来自于 [Clipart Max](https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/)。
|
||||
|
||||
:tada: 感谢所有参与代码贡献的小伙伴, 他们的 GayHub ID 在这个[列表](https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors)。 另外, 提交过 issues(或者未被合并 PR) 的高富帅和白富美也不会被遗忘,他/她们帮助报告 bug、分享新点子或者启发了我写出更通俗易懂的文档。
|
||||
:tada: 感谢所有参与代码贡献的小伙伴,他们的 GayHub ID 在这个「[列表](https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors)」。 另外,提交过 issues(或者未被合并 PR)的高富帅和白富美也不会被遗忘,他/她们帮助报告 bug、分享新点子或者启发了我写出更通俗易懂的文档。
|
||||
|
||||
还有,感谢 [JetBrains][jb] 提供开源 License!
|
||||
|
||||
## 赞助
|
||||
|
||||
如果您喜欢这个主题或者它对您有帮助,请考虑打赏作者,您的支持将会极大地鼓励作者,并帮助作者更好地维护项目!
|
||||
如果您喜欢此款主题或者它对您有帮助,请考虑打赏作者,您的支持将会极大地鼓励作者,并帮助作者更好地维护项目!
|
||||
|
||||
[](https://www.buymeacoffee.com/coteschung)
|
||||
[][cn-donation]
|
||||
@@ -211,6 +235,9 @@ $ docker run -it --rm \
|
||||
[starter]: https://github.com/cotes2020/chirpy-starter
|
||||
[use-starter]: https://github.com/cotes2020/chirpy-starter/generate
|
||||
[workflow]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/workflows/pages-deploy.yml.hook
|
||||
[chirpy-4.1.0]: https://github.com/cotes2020/jekyll-theme-chirpy/releases/tag/v4.1.0
|
||||
[pages-src]: https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site
|
||||
[latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags
|
||||
|
||||
<!-- ReadMe links -->
|
||||
|
||||
|
||||
@@ -45,9 +45,8 @@ const postJs = () => {
|
||||
`${JS_SRC}/commons/*.js`,
|
||||
`${JS_SRC}/utils/img-extra.js`,
|
||||
`${JS_SRC}/utils/timeago.js`,
|
||||
`${JS_SRC}/utils/lang-badge.js`,
|
||||
`${JS_SRC}/utils/checkbox.js`,
|
||||
`${JS_SRC}/utils/copy-link.js`,
|
||||
`${JS_SRC}/utils/clipboard.js`,
|
||||
// 'smooth-scroll.js' must be called after ToC is ready
|
||||
`${JS_SRC}/utils/smooth-scroll.js`
|
||||
], 'post'
|
||||
@@ -67,7 +66,7 @@ const pageJs = () => {
|
||||
`${JS_SRC}/commons/*.js`,
|
||||
`${JS_SRC}/utils/checkbox.js`,
|
||||
`${JS_SRC}/utils/img-extra.js`,
|
||||
`${JS_SRC}/utils/copy-link.js`,
|
||||
`${JS_SRC}/utils/clipboard.js`
|
||||
], 'page'
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "jekyll-theme-chirpy"
|
||||
spec.version = "4.0.0"
|
||||
spec.version = "4.3.0"
|
||||
spec.authors = ["Cotes Chung"]
|
||||
spec.email = ["cotes.chung@gmail.com"]
|
||||
|
||||
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
||||
spec.license = "MIT"
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").select { |f|
|
||||
f.match(%r!^((assets\/(css|img|js\/[a-z])|_(includes|layouts|sass|config|data|tabs|plugins))|README|LICENSE|index)!i)
|
||||
f.match(%r!^((_(includes|layouts|sass|data|tabs|plugins)|assets)\/|_config|README|LICENSE|index)!i)
|
||||
}
|
||||
|
||||
spec.metadata = {
|
||||
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
|
||||
"plugin_type" => "theme"
|
||||
}
|
||||
|
||||
spec.required_ruby_version = ">= 2.4"
|
||||
|
||||
spec.add_runtime_dependency "jekyll", "~> 4.1"
|
||||
spec.add_runtime_dependency "jekyll-paginate", "~> 1.1"
|
||||
spec.add_runtime_dependency "jekyll-redirect-from", "~> 0.16"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jekyll-theme-chirpy",
|
||||
"version": "4.0.0",
|
||||
"version": "4.3.0",
|
||||
"description": "A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation.",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
|
||||
117
tools/bump.sh
117
tools/bump.sh
@@ -1,31 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# How does it work:
|
||||
#
|
||||
# 1. Bump latest version number to files:
|
||||
# - _sass/jekyll-theme-chirpy.scss
|
||||
# - _javascript/copyright
|
||||
# - assets/js/dist/*.js (will be built by gulp later)
|
||||
# - jekyll-theme-chirpy.gemspec
|
||||
# - package.json
|
||||
# 1. Bump latest version number to the following files:
|
||||
#
|
||||
# 2. Create a git-tag on release branch
|
||||
#
|
||||
# 3. Build a RubyGems package base on the latest git-tag
|
||||
# - _sass/jekyll-theme-chirpy.scss
|
||||
# - _javascript/copyright
|
||||
# - assets/js/dist/*.js (will be built by gulp later)
|
||||
# - jekyll-theme-chirpy.gemspec
|
||||
# - package.json
|
||||
#
|
||||
# 2. Then create a commit to automatically save the changes.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# Switch to 'master' branch or 'X-Y-stable' branch with argument '-m',
|
||||
#` and then run this script.
|
||||
# Run on the default branch or hotfix branch
|
||||
#
|
||||
#
|
||||
# Requires: Git, Gulp, RubyGems
|
||||
# Requires: Git, Gulp
|
||||
|
||||
set -eu
|
||||
|
||||
manual_release=false
|
||||
|
||||
ASSETS=(
|
||||
"_sass/jekyll-theme-chirpy.scss"
|
||||
"_javascript/copyright"
|
||||
@@ -48,12 +41,6 @@ check() {
|
||||
exit -1
|
||||
fi
|
||||
|
||||
# ensure the current branch is 'master' or running in 'manual' mode
|
||||
if [[ "$(git branch --show-current)" != "master" && $manual_release == "false" ]]; then
|
||||
echo "Error: This operation must be performed on the 'master' branch or '--manual' mode!"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
for i in "${!ASSETS[@]}"; do
|
||||
_check_src "${ASSETS[$i]}"
|
||||
done
|
||||
@@ -91,71 +78,6 @@ bump() {
|
||||
fi
|
||||
}
|
||||
|
||||
build_gem() {
|
||||
rm -f ./*.gem
|
||||
gem build "$GEM_SPEC"
|
||||
}
|
||||
|
||||
release() {
|
||||
_version="$1"
|
||||
_major=""
|
||||
_minor=""
|
||||
|
||||
IFS='.' read -r -a array <<< "$_version"
|
||||
|
||||
for elem in "${array[@]}"; do
|
||||
if [[ -z $_major ]]; then
|
||||
_major="$elem"
|
||||
elif [[ -z $_minor ]]; then
|
||||
_minor="$elem"
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
_release_branch="$_major-$_minor-stable"
|
||||
|
||||
if $manual_release; then
|
||||
echo -e "Bump version to $_version (manual release)\n"
|
||||
bump "$_version"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -z $(git branch -v | grep "$_release_branch") ]]; then
|
||||
git checkout -b "$_release_branch"
|
||||
else
|
||||
git checkout "$_release_branch"
|
||||
# cherry-pick the latest commit from master branch to release branch
|
||||
git cherry-pick "$(git rev-parse master)"
|
||||
fi
|
||||
|
||||
echo -e "Bump version to $_version\n"
|
||||
bump "$_version"
|
||||
|
||||
echo -e "Create tag v$_version\n"
|
||||
git tag "v$_version"
|
||||
|
||||
echo -e "Build the gem pakcage for v$_version\n"
|
||||
build_gem
|
||||
|
||||
# head back to master branch
|
||||
git checkout master
|
||||
# cherry-pick the latest commit from release branch to master branch
|
||||
git cherry-pick "$_release_branch" -x
|
||||
|
||||
}
|
||||
|
||||
help() {
|
||||
echo "Bump new version to Chirpy project"
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo " bash /path/to/bump.sh [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -m, --manual Manual relase, bump version only."
|
||||
echo " -h, --help Print this help information."
|
||||
}
|
||||
|
||||
main() {
|
||||
check
|
||||
|
||||
@@ -172,7 +94,8 @@ main() {
|
||||
exit -1
|
||||
fi
|
||||
|
||||
release "$_version"
|
||||
echo -e "Bump version to $_version\n"
|
||||
bump "$_version"
|
||||
|
||||
else
|
||||
|
||||
@@ -181,22 +104,4 @@ main() {
|
||||
|
||||
}
|
||||
|
||||
while (($#)); do
|
||||
opt="$1"
|
||||
case $opt in
|
||||
-m | --manual)
|
||||
manual_release=true
|
||||
shift
|
||||
;;
|
||||
-h | --help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown option '$opt'!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
main
|
||||
|
||||
106
tools/deploy.sh
106
tools/deploy.sh
@@ -1,22 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Deploy the content of _site to 'origin/<pages_branch>'
|
||||
# Build, test and then deploy the site content to 'origin/<pages_branch>'
|
||||
#
|
||||
# Requirement: html-proofer, jekyll
|
||||
#
|
||||
# Usage: See help information
|
||||
|
||||
set -eu
|
||||
|
||||
PAGES_BRANCH="gh-pages"
|
||||
|
||||
_no_branch=false
|
||||
SITE_DIR="_site"
|
||||
|
||||
_opt_dry_run=false
|
||||
|
||||
_config="_config.yml"
|
||||
|
||||
_no_pages_branch=false
|
||||
|
||||
_backup_dir="$(mktemp -d)"
|
||||
|
||||
_baseurl=""
|
||||
|
||||
help() {
|
||||
echo "Build, test and then deploy the site content to 'origin/<pages_branch>'"
|
||||
echo
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo " bash ./tools/deploy.sh [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo ' -c, --config "<config_a[,config_b[...]]>" Specify config file(s)'
|
||||
echo " --dry-run Build site and test, but not deploy"
|
||||
echo " -h, --help Print this information."
|
||||
}
|
||||
|
||||
init() {
|
||||
if [[ -z ${GITHUB_ACTION+x} ]]; then
|
||||
echo "ERROR: This script is not allowed to run outside of GitHub Action."
|
||||
if [[ -z ${GITHUB_ACTION+x} && $_opt_dry_run == 'false' ]]; then
|
||||
echo "ERROR: It is not allowed to deploy outside of the GitHub Action envrionment."
|
||||
echo "Type option '-h' to see the help information."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
_baseurl="$(grep '^baseurl:' _config.yml | sed "s/.*: *//;s/['\"]//g;s/#.*//")"
|
||||
}
|
||||
|
||||
build() {
|
||||
# clean up
|
||||
if [[ -d $SITE_DIR ]]; then
|
||||
rm -rf "$SITE_DIR"
|
||||
fi
|
||||
|
||||
# build
|
||||
JEKYLL_ENV=production bundle exec jekyll b -d "$SITE_DIR$_baseurl" --config "$_config"
|
||||
}
|
||||
|
||||
test() {
|
||||
bundle exec htmlproofer \
|
||||
--disable-external \
|
||||
--check-html \
|
||||
--allow_hash_href \
|
||||
"$SITE_DIR"
|
||||
}
|
||||
|
||||
resume_site_dir() {
|
||||
if [[ -n $_baseurl ]]; then
|
||||
# Move the site file to the regular directory '_site'
|
||||
mv "$SITE_DIR$_baseurl" "${SITE_DIR}-rename"
|
||||
rm -rf "$SITE_DIR"
|
||||
mv "${SITE_DIR}-rename" "$SITE_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_gh() {
|
||||
if [[ -z $(git branch -av | grep "$PAGES_BRANCH") ]]; then
|
||||
_no_branch=true
|
||||
_no_pages_branch=true
|
||||
git checkout -b "$PAGES_BRANCH"
|
||||
else
|
||||
git checkout "$PAGES_BRANCH"
|
||||
@@ -24,7 +82,7 @@ init() {
|
||||
}
|
||||
|
||||
backup() {
|
||||
mv _site/* "$_backup_dir"
|
||||
mv "$SITE_DIR"/* "$_backup_dir"
|
||||
mv .git "$_backup_dir"
|
||||
|
||||
# When adding custom domain from Github website,
|
||||
@@ -50,7 +108,7 @@ deploy() {
|
||||
git add -A
|
||||
git commit -m "[Automation] Site update No.${GITHUB_RUN_NUMBER}"
|
||||
|
||||
if $_no_branch; then
|
||||
if $_no_pages_branch; then
|
||||
git push -u origin "$PAGES_BRANCH"
|
||||
else
|
||||
git push -f
|
||||
@@ -59,9 +117,43 @@ deploy() {
|
||||
|
||||
main() {
|
||||
init
|
||||
build
|
||||
test
|
||||
resume_site_dir
|
||||
|
||||
if $_opt_dry_run; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
setup_gh
|
||||
backup
|
||||
flush
|
||||
deploy
|
||||
}
|
||||
|
||||
while (($#)); do
|
||||
opt="$1"
|
||||
case $opt in
|
||||
-c | --config)
|
||||
_config="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
# build & test, but not deploy
|
||||
_opt_dry_run=true
|
||||
shift
|
||||
;;
|
||||
-h | --help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
main
|
||||
|
||||
@@ -6,6 +6,8 @@ set -eu
|
||||
|
||||
ACTIONS_WORKFLOW=pages-deploy.yml
|
||||
|
||||
TEMP_SUFFIX="to-delete" # temporary file suffixes that make `sed -i` compatible with BSD and Linux
|
||||
|
||||
help() {
|
||||
echo "Usage:"
|
||||
echo
|
||||
@@ -16,6 +18,13 @@ help() {
|
||||
echo " -h, --help Print this help information."
|
||||
}
|
||||
|
||||
check_status() {
|
||||
if [[ -n $(git status . -s) ]]; then
|
||||
echo "Error: Commit unstaged files first, and then run this tool againt."
|
||||
exit -1
|
||||
fi
|
||||
}
|
||||
|
||||
check_init() {
|
||||
local _has_inited=false
|
||||
|
||||
@@ -40,25 +49,48 @@ check_init() {
|
||||
}
|
||||
|
||||
init_files() {
|
||||
|
||||
if $_no_gh; then
|
||||
rm -rf .github
|
||||
else
|
||||
## Change the files of `.github`
|
||||
|
||||
mv .github/workflows/$ACTIONS_WORKFLOW.hook .
|
||||
rm -rf .github
|
||||
mkdir -p .github/workflows
|
||||
mv ./${ACTIONS_WORKFLOW}.hook .github/workflows/${ACTIONS_WORKFLOW}
|
||||
|
||||
## Ensure the gh-actions trigger branch
|
||||
|
||||
_workflow=".github/workflows/${ACTIONS_WORKFLOW}"
|
||||
_default_branch="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
|
||||
_lineno="$(sed -n "/branches:/=" "$_workflow")"
|
||||
|
||||
sed -i.$TEMP_SUFFIX "$((_lineno + 1))s/- .*/- ${_default_branch}/" "$_workflow"
|
||||
rm -f "$_workflow.$TEMP_SUFFIX"
|
||||
|
||||
## Cleanup image settings in site config
|
||||
sed -i.$TEMP_SUFFIX "s/^img_cdn:.*/img_cdn: ''/;s/^avatar:.*/avatar: ''/" _config.yml
|
||||
rm -f _config.yml.$TEMP_SUFFIX
|
||||
|
||||
fi
|
||||
|
||||
# trace the gem lockfile on user-end
|
||||
sed -i.$TEMP_SUFFIX "/Gemfile.lock/d" .gitignore
|
||||
rm -f ".gitignore.$TEMP_SUFFIX"
|
||||
|
||||
# remove the other fies
|
||||
rm -f .travis.yml
|
||||
rm -rf _posts/* docs
|
||||
|
||||
# save changes
|
||||
git add -A && git add .github -f
|
||||
git commit -m "[Automation] Initialize the environment." -q
|
||||
|
||||
echo "[INFO] Initialization successful!"
|
||||
}
|
||||
|
||||
check_status
|
||||
|
||||
check_init
|
||||
|
||||
_no_gh=false
|
||||
|
||||
62
tools/release.sh
Executable file
62
tools/release.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# According to the GitLab flow release branching model,
|
||||
# cherry-pick the last commit on the main branch to the release branch,
|
||||
# and then create a tag and gem package on the release branch (naming format: 'release/<X.Y>').
|
||||
#
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# It can be run on main branch, and it should be used after just finishing the last feature in the version plan,
|
||||
# or just after merging the hotfix to the main branch.
|
||||
#
|
||||
# Requires: Git, Gulp
|
||||
|
||||
set -eu
|
||||
|
||||
GEM_SPEC="jekyll-theme-chirpy.gemspec"
|
||||
|
||||
check() {
|
||||
if [[ -n $(git status . -s) ]]; then
|
||||
echo "Error: Commit unstaged files first, and then run this tool againt."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [[ ! -f $GEM_SPEC ]]; then
|
||||
echo -e "Error: Missing file \"$GEM_SPEC\"!\n"
|
||||
exit -1
|
||||
fi
|
||||
}
|
||||
|
||||
release() {
|
||||
_default_branch="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
|
||||
_version="$(grep "spec.version" jekyll-theme-chirpy.gemspec | sed 's/.*= "//;s/".*//')" # X.Y.Z
|
||||
_release_branch="release/${_version%.*}"
|
||||
|
||||
if [[ -z $(git branch -v | grep "$_release_branch") ]]; then
|
||||
# create a new release branch
|
||||
git checkout -b "$_release_branch"
|
||||
else
|
||||
# cherry-pick the latest commit from default branch to release branch
|
||||
_last_commit="$(git rev-parse "$_default_branch")"
|
||||
git checkout "$_release_branch"
|
||||
git cherry-pick "$_last_commit" -m 1
|
||||
fi
|
||||
|
||||
# create new tag
|
||||
echo -e "Create tag v$_version\n"
|
||||
git tag "v$_version"
|
||||
|
||||
# build a gem package
|
||||
echo -e "Build the gem pakcage for v$_version\n"
|
||||
rm -f ./*.gem
|
||||
gem build "$GEM_SPEC"
|
||||
|
||||
}
|
||||
|
||||
main() {
|
||||
check
|
||||
release
|
||||
}
|
||||
|
||||
main
|
||||
@@ -1,67 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Using HTML-proofer to test site.
|
||||
#
|
||||
# Requirement: https://github.com/gjtorikian/html-proofer
|
||||
#
|
||||
# Usage: bash /path/to/test.sh [indicated path]
|
||||
|
||||
DEST=_site
|
||||
URL_IGNORE=cdn.jsdelivr.net
|
||||
|
||||
_build=false
|
||||
|
||||
help() {
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo " bash ./tools/test.sh [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " --build Run Jekyll build before test."
|
||||
echo " -d, --dir <path> Specify the test path."
|
||||
echo " -h, --help Print this information."
|
||||
}
|
||||
|
||||
if [[ -n $1 && -d $1 ]]; then
|
||||
DEST=$1
|
||||
fi
|
||||
|
||||
while (($#)); do
|
||||
opt="$1"
|
||||
case $opt in
|
||||
--build)
|
||||
_build=true
|
||||
shift
|
||||
;;
|
||||
-d | --dir)
|
||||
if [[ ! -d $2 ]]; then
|
||||
echo -e "Error: path '$2' doesn't exist\n"
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
DEST=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-h | --help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if $_build; then
|
||||
JEKYLL_ENV=production bundle exec jekyll b
|
||||
fi
|
||||
|
||||
bundle exec htmlproofer "$DEST" \
|
||||
--disable-external \
|
||||
--check-html \
|
||||
--empty_alt_ignore \
|
||||
--allow_hash_href \
|
||||
--url_ignore $URL_IGNORE
|
||||
Reference in New Issue
Block a user