1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-18 21:53:26 +00:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Cotes Chung
a9b159299b Merge branch 'hotfix/4.3.3' 2021-10-20 06:29:16 +08:00
Cotes Chung
29ba2666ce Merge branch 'hotfix/4.3.2' 2021-10-15 00:56:42 +08:00
Cotes Chung
5ef1478148 Correct grammar and spelling in docs & issue templates
Also improve the Markdown code style
2021-10-12 03:27:28 +08:00
Cotes Chung
8877393fba Merge branch 'hotfix/4.3.1' 2021-10-01 18:49:21 +08:00
108 changed files with 1945 additions and 2752 deletions

View File

@@ -1,42 +1,15 @@
# How to Contribute
We want to thank you for sparing time to improve this project! Here are some guidelines for contributing
I want to thank you for sparing time to improve this project! Here are some guidelines for contributing
To ensure that the blog design is not confused, this project does not accept suggestions for design changes, such as color scheme, fonts, typography, etc. If your request is about an enhancement, it is recommended to first submit a [_Feature Request_](https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md) issue to discuss whether your idea fits the project.
## Basic Process
To ensure that the blog design is not confused, this project does not accept suggestions for design changes, such as color scheme, fonts, typography, etc. If your request is about an enhancement, it is recommended to first submit a [`Feature Request`](https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md) issue to discuss whether your idea fits the project.
Generally, contribute to the project by:
1. Fork this project on GitHub and clone it locally.
2. Create a new branch from the default branch and give it a descriptive name (e.g., `my-new-feature`, `fix-a-bug`).
3. After completing the development, submit a new _Pull Request_.
## Modifying JavaScript
If your contribution involves JS modification, please read the following sections.
### Inline Scripts
If you need to add comments to the inline JS (the JS code between the tags `<script>` and `</script>`), please use `/**/` instead of two slashes `//`. Because the HTML will be compressed by [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) during deployment, but it cannot handle the `//` properly. And this will disrupt the structure of the compressed HTML.
### External Scripts
If you need to add or modify JavaScripts in the directory `_javascript`, you need to install [Gulp.js](https://gulpjs.com/docs/en/getting-started/quick-start).
During development, real-time debugging can be performed through the following commands:
```console
$ bash tools/run.sh
```
Open another terminal tab and run:
```console
$ gulp dev # Type 'Ctrl + C' to stop
```
After debugging, run the command `gulp` (without any argument) will automatically output the compressed files to the directory `assests/js/dist/`.
2. Create a new branch from `master` and give it a descriptive name (e.g., `my-new-feature`, `fix-a-bug`).
3. After completing the development, commit and push to remote.
4. Submit a new pull request.
---

5
.github/FUNDING.yml vendored
View File

@@ -1,2 +1,3 @@
ko_fi: coteschung
custom: https://cotes.gitee.io/alipay-wechat-donation
custom:
- https://www.buymeacoffee.com/coteschung
- https://cotes.gitee.io/alipay-wechat-donation

View File

@@ -6,15 +6,12 @@ about: Create a report to help us improve
<!-- NOTE: Please maintain all sections, otherwise the issue will be automatically closed :) -->
## Checklist
<!-- Please complete the following list of tasks, and then check it by changing the "[ ]" to "[x]" -->
- [ ] I have read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design.
- [ ] There are no similar reports on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones).
- [ ] I have read the [tutorials](https://chirpy.cotes.info/categories/tutorial/) and know the correct effect of the functional design.
- [ ] There are no similar reports on existing issues (including closed ones).
- [ ] I found the bug on the latest code of the `master` branch.
## Describe the bug
<!-- A clear and concise description of what the bug is. -->
### To Reproduce
@@ -28,15 +25,12 @@ Steps to reproduce the behavior:
-->
### Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
### Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->
### Software
<!-- Please complete the following information -->
- Ruby version: <!-- by running: `ruby -v` -->
- Gem version: <!-- by running: `gem -v`-->
@@ -45,14 +39,12 @@ Steps to reproduce the behavior:
- Theme version: <!-- by running: `gem list | grep jekyll-theme-chirpy` -->
### Desktop
<!-- If necessary, uncomment and fill in the following list:
- OS: [e.g. macOS 10.15.6]
- Browser: [e.g. Chrome 85.0.4183.83 (64-bit)]
-->
### Smartphone
<!-- If necessary, uncomment and fill in the following list:
- Device: [e.g. iPhone 6]
- OS: [e.g. iOS 13.6.1]
@@ -60,5 +52,4 @@ Steps to reproduce the behavior:
-->
### Additional context
<!-- Add any other context about the problem here. -->

View File

@@ -7,29 +7,24 @@ labels: enhancement
<!-- NOTE: Please maintain all sections, otherwise the issue will be automatically closed :) -->
## Checklist
<!-- Please complete the following list of tasks, and then check it by changing the "[ ]" to "[x]" -->
- [ ] I have read the [contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/CONTRIBUTING.md).
- [ ] There is no similar request on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones).
- [ ] There is no similar request on existing issues (including closed ones).
- [ ] I have read the [project progress](https://github.com/cotes2020/jekyll-theme-chirpy/projects) and know the current progress of the project.
- [ ] I was in the `master` branch of the latest code.
## Is your feature request related to a problem? Please describe
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
## Describe the solution you'd like
<!-- A clear and concise description of what you want to happen. -->
## Describe alternatives you've considered
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
## Additional context
<!-- Add any other context or screenshots about the feature request here. -->

View File

@@ -1,6 +1,6 @@
---
name: Question
about: Ask whatever you want
about: Ask what ever you want
labels: question
---
@@ -10,11 +10,10 @@ labels: question
<!-- Please complete the following list of tasks, and then check it by changing the "[ ]" to "[x]" -->
- [ ] I have read the [newlest tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design.
- [ ] There is no similar question on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones).
- [ ] I have tried to find the answer on [Jekyll Forum](https://talk.jekyllrb.com/) and [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll).
- [ ] I have read the [tutorials](https://chirpy.cotes.info/categories/tutorial/) and know the correct effect of the functional design.
- [ ] There is no similar question on existing issues (including closed ones).
- [ ] I searched the Internet for related problems, but still couldn't solve them.
- [ ] My question is based on the latest code of the `master` branch.
## Description
<!-- Please describe your question in detail. -->

View File

@@ -29,14 +29,16 @@ Please describe the tests that you ran to verify your changes. Provide instructi
- Browser type & version:
- Operating system:
- Ruby version: <!-- by running: `ruby -v` -->
- Bundler version: <!-- by running: `bundle -v`-->
- Jekyll version: <!-- by running: `bundle list | grep " jekyll "` -->
- Bundler version:
- Ruby version:
- Jekyll version:
### Checklist
<!-- Select checkboxes by change the "[ ]" to "[x]" -->
- [ ] I have performed a self-review of my code
- [ ] My code follows the [Google style guidelines](https://google.github.io/styleguide/)
- [ ] I have performed a self-review of my own code
- [ ] I have commented on my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] Any dependent changes have been merged and published in downstream modules

View File

@@ -2,15 +2,15 @@ name: 'Continuous Integration'
on:
push:
branches-ignore:
- 'release/**'
- 'docs'
- 'production'
tags-ignore:
- '**'
- '*'
paths-ignore:
- '.github/**'
- '!.github/workflows/ci.yml'
- '.travis.yml'
- '.gitignore'
- 'docs/**'
- 'README.md'
- 'LICENSE'
pull_request:

View File

@@ -2,7 +2,7 @@ name: 'Automatic build'
on:
push:
branches:
- main
- master
paths-ignore:
- .gitignore
- README.md

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "assets/lib"]
path = assets/lib
url = https://github.com/cotes2020/chirpy-static-assets.git

View File

@@ -1 +0,0 @@

View File

@@ -1,41 +1,42 @@
os: linux
dist: bionic
language: ruby
rvm: 2.7.0
addons:
apt:
packages:
- libcurl4-openssl-dev # to avoid SSL error (for htmlproofer)
language: minimal
# Overriding to drop the `--development` flag which requires the Gemfile.lock at build
install: bundle install --jobs=3 --retry=3 --path=vendor/bundle
before_script: git -C "$HOME" clone "$BUILDER_REPO" --depth=1 -q
branches:
only:
- /^release\/(\d)+(\.(\d)+){1}$/
jobs:
include:
- stage: Upgrade
- 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
script: eval "$BUILD_CMD"
- stage: Starter
language: minimal
install: true # skip install step
script: eval "$FLUSH_STARTER"
- stage: Docs
cache: bundler
git:
depth: false # for posts' lastmod
script: eval "$DOCS_CMD"
depth: false # for posts' lastmod
stages:
- name: Upgrade
if: branch =~ /^v(\d)+(\.(\d)+){2}$/ OR tag IS present
- name: Starter
if: branch =~ /^v(\d)+(\.(\d)+){2}$/ OR tag IS present
- name: Docs
if: branch = docs
- name: Flush Starter
script: eval "$FLUSH_STARTER"
before_script:
- git -C "$HOME" clone "$BUILDER_REPO" --depth=1 -q
notifications:
email:

188
README.md
View File

@@ -1,50 +1,90 @@
<div align="right">
EN /
[中文(简体)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md)
</div>
<div align="center">
# Chirpy Jekyll Theme
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)](https://rubygems.org/gems/jekyll-theme-chirpy)
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/4e556876a3c54d5e8f2d2857c4f43894)](https://www.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cotes2020/jekyll-theme-chirpy&amp;utm_campaign=Badge_Grade)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b)](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)
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
[**Live Demo →**](https://cotes2020.github.io/chirpy-demo)
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
[![Devices Mockup](https://raw.githubusercontent.com/cotes2020/chirpy-images/main/commons/devices-mockup.png)](https://cotes2020.github.io/chirpy-demo)
[**Live Demo →**](https://chirpy.cotes.info)
[![Devices Mockup](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images@0a003683c0c3ca549d12c309f9b3e03ea20981e5/commons/devices-mockup.png)](https://chirpy.cotes.info)
</div>
## Features
- Localized Layout
- Dark/Light Theme Mode
- Configurable Theme Mode
- Pinned Posts
- Hierarchical Categories
- Last Modified Date for Posts
- Table of Contents
- Auto-generated Related Posts
- Automatically Recommend Related Posts
- Syntax Highlighting
- Mathematical Expressions
- Mermaid Diagram & Flowchart
- Disqus/Utterances/Giscus Comments
- Search
- Atom Feeds
- Disqus Comments
- Google Analytics
- GA Pageviews Reporting
- GA Pageviews Reporting (Advanced)
- SEO & Performance Optimization
## Prerequisites
## Quick Start
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`.
Before starting, please follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`. In addition, [Git](https://git-scm.com/) is also required to be installed.
## Installation
### Step 1. Creating a New Site
### Creating a New Site
Create a new repository from the [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/generate) and name it `<GH_USERNAME>.github.io`, where `GH_USERNAME` represents your GitHub username.
There are two ways to create a new repository for this theme:
### Step 2. Installing Dependencies
- [**Using the Chirpy Starter**](#option-1-using-the-chirpy-starter) - Easy to upgrade, isolates irrelevant project files so you can focus on writing.
- [**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.
#### Option 1. Using the Chirpy Starter
Create a new repository from the [**Chirpy Starter**][use-starter] and name it `<GH_USERNAME>.github.io`, where `GH_USERNAME` represents your GitHub username.
#### Option 2. Forking on GitHub
[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:
```console
$ bash tools/init.sh
```
> **Note**: If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
The above command will:
1. Removes some files or directories from your repository:
- `.travis.yml`
- files under `_posts`
- folder `docs`
2. If the option `--no-gh` is provided, the directory `.github` will be deleted. Otherwise, set up 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. 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 to the root directory of your site, and install dependencies as follows:
@@ -52,15 +92,32 @@ Before running for the first time, go to the root directory of your site, and in
$ bundle
```
### Step 3. Running Local Server
## Usage
Run the following command in the root directory of the site:
### Configuration
Update the variables of `_config.yml` as needed. Some of them are typical options:
- `url`
- `avatar`
- `timezone`
- `lang`
### Customing Stylesheet
If you need to customize the 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:
```console
$ bundle exec jekyll s
```
Or run with Docker:
Or run the site on Docker with the following command:
```console
$ docker run -it --rm \
@@ -69,29 +126,107 @@ $ docker run -it --rm \
jekyll serve
```
After a while, navigate to the site at <http://localhost:4000>.
After a while, the local service will be published at _<http://127.0.0.1:4000>_.
### Deployment
Before the deployment begins, check out the file `_config.yml` and make sure the `url` is configured correctly. Furthermore, if you prefer the [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to change the `baseurl` to your project name that starts with a slash, e.g, `/project-name`.
Now you can choose ONE of the following methods to deploy your Jekyll site.
#### 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 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 [sample 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/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 lock file:
```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 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.
![gh-pages-sources](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images@0a003683c0c3ca549d12c309f9b3e03ea20981e5/posts/20190809/gh-pages-sources.png)
3. Visit your website at the address indicated by GitHub.
#### Manually Build and Deploy
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, and build your site as follows:
```console
$ JEKYLL_ENV=production bundle exec jekyll b
```
Or build the site on Docker:
```console
$ docker run -it --rm \
--env JEKYLL_ENV=production \
--volume="$PWD:/srv/jekyll" \
jekyll/jekyll \
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 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 theme 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 on usage, please refer to the tutorial on the [demo website](https://cotes2020.github.io/chirpy-demo/) / [wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Note that the tutorial is based on the [latest tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags), and the features of the default branch are usually ahead of the 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). Please note that the tutorials on the demo website or Wiki are based on the latest release, and the features of `master` branch are usually ahead of the documentation.
## Contributing
Welcome to report bugs, improve code quality or submit a new feature. For more information, see [contributing guidelines](.github/CONTRIBUTING.md).
The old saying, "Two heads are better than one." Consequently, welcome to report bugs, improve code quality or submit a new feature. For more information, see [contributing guidelines](.github/CONTRIBUTING.md).
## Credits
This theme is mainly built with [Jekyll](https://jekyllrb.com/) ecosystem, [Bootstrap](https://getbootstrap.com/), [Font Awesome](https://fontawesome.com/) and some other wonderful tools (their copyright information can be found in the relevant files). The avatar and favicon design come from [Clipart Max](https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/).
:tada: Thanks to all the volunteers who contributed to this project, their GitHub IDs are on [this list](https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors). Also, I won't forget those guys who submitted the issues or unmerged PR because they reported bugs, shared ideas, or inspired me to write more readable documentation.
:tada: Thanks to all the volunteers who contributed to this project, their GitHub IDs are on [this list](https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors). Also, I won't forget those guys who submitted the issues or unmerged PR because they reported bugs, shared ideas or inspired me to write more readable documentation.
Last but not least, thank [JetBrains][jb] for providing the OSS development license.
Last but not least, thank [JetBrains][jb] for providing the open source license.
## Sponsoring
If you like this theme or find it helpful, please consider sponsoring me, because it will encourage and help me better maintain the project, I will be very grateful!
[![Ko-fi](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff5f5f?logo=ko-fi&logoColor=white)](https://ko-fi.com/coteschung)
[![Buy Me a Coffee](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff813f?logo=buy-me-a-coffee&logoColor=white)](https://www.buymeacoffee.com/coteschung)
[![Wechat Pay](https://img.shields.io/badge/-Tip%20Me%20on%20WeChat-brightgreen?logo=wechat&logoColor=white)][cn-donation]
[![Alipay](https://img.shields.io/badge/-Tip%20Me%20on%20Alipay-blue?logo=alipay&logoColor=white)][cn-donation]
@@ -99,6 +234,13 @@ If you like this theme or find it helpful, please consider sponsoring me, becaus
This work is published under [MIT](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE) License.
[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 -->
[jb]: https://www.jetbrains.com/?from=jekyll-theme-chirpy

View File

@@ -12,9 +12,6 @@ baseurl: ''
# otherwise, the layout language will use the default value of 'en'.
lang: en
# Additional parameters for datetime localization, optional. https://github.com/iamkun/dayjs/tree/dev/src/locale
prefer_datetime_locale:
# Change to your timezone http://www.timezoneconverter.com/cgi-bin/findzone/findzone
timezone: Asia/Shanghai
@@ -26,7 +23,9 @@ title: Chirpy # the main title
tagline: A text-focused Jekyll theme # it will display as the sub-title
description: >- # used by seo meta and the atom feed
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
A minimal, portfolio, sidebar,
bootstrap Jekyll theme with responsive web design
and focuses on text presentation.
# fill in the protocol & hostname for your site, e.g., 'https://username.github.io'
url: ''
@@ -50,13 +49,13 @@ social:
# - https://www.facebook.com/username
# - https://www.linkedin.com/in/username
google_site_verification: # fill in to your verification string
google_site_verification: google_meta_tag_verification # change to your verification string
# ↑ --------------------------
# The end of `jekyll-seo-tag` settings
google_analytics:
id: # fill in your Google Analytics ID
id: '' # fill in your Google Analytics ID
# Google Analytics pageviews report settings
pv:
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
@@ -80,7 +79,7 @@ theme_mode: # [light|dark]
# will be added to all image (site avatar & posts' images) paths starting with '/'
#
# e.g. 'https://cdn.com'
img_cdn: 'https://raw.githubusercontent.com/cotes2020/chirpy-images/main'
img_cdn: 'https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images@0a003683c0c3ca549d12c309f9b3e03ea20981e5'
# the avatar on sidebar, support local or CORS resources
avatar: '/commons/avatar.jpg'
@@ -88,32 +87,9 @@ avatar: '/commons/avatar.jpg'
# boolean type, the global switch for ToC in posts.
toc: true
comments:
active: # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable
# The active options are as follows:
disqus:
shortname: # fill with the Disqus shortname. https://help.disqus.com/en/articles/1717111-what-s-a-shortname
# utterances settings https://utteranc.es/
utterances:
repo: # <gh-username>/<repo>
issue_term: # < url | pathname | title | ...>
# Giscus options https://giscus.app
giscus:
repo: # <gh-username>/<repo>
repo_id:
category:
category_id:
mapping: # optional, default to 'pathname'
input_position: # optional, default to 'bottom'
lang: # optional, default to the value of `site.lang`
# Self-hosted static assets, optional https://github.com/cotes2020/chirpy-static-assets
assets:
self_host:
enabled: # boolean, keep empty means false
# specify the Jekyll environment, empty means both
# only works if `assets.self_host.enabled` is 'true'
env: # [development|production]
disqus:
comments: false # boolean type, the global switch for posts comments.
shortname: '' # Fill with your Disqus shortname. https://help.disqus.com/en/articles/1717111-what-s-a-shortname
paginate: 10
@@ -135,8 +111,10 @@ collections:
output: true
sort_by: order
defaults:
- scope:
-
scope:
path: '' # An empty string here means all files in the project
type: posts
values:
@@ -146,24 +124,19 @@ defaults:
# DO NOT modify the following parameter unless you are confident enough
# to update the code of all other post links in this project.
permalink: /posts/:title/
- scope:
-
scope:
path: _drafts
values:
comments: false
- scope:
-
scope:
path: ''
type: tabs # see `site.collections`
values:
layout: page
permalink: /:title/
- scope:
path: assets/img/favicons
values:
swcache: true
- scope:
path: assets/js/dist
values:
swcache: true
dynamic_title: true # Hide title in mobile screens.
sass:
style: compressed
@@ -181,11 +154,12 @@ exclude:
- '*.gem'
- '*.gemspec'
- tools
- docs
- README.md
- LICENSE
- gulpfile.js
- node_modules
- package*.json
- package.json
jekyll-archives:
enabled: [categories, tags]

View File

@@ -1,62 +0,0 @@
# CDNs
cdns:
# Google Fonts
- url: https://fonts.googleapis.com
- url: https://fonts.gstatic.com
args: crossorigin
- url: https://fonts.googleapis.com
# jsDelivr CDN
- url: https://cdn.jsdelivr.net
# fonts
webfonts: https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
# Libraries
jquery:
js: https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
bootstrap:
css: https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css
js: https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.bundle.min.js
bootstrap-toc:
css: https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.css
js: https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js
fontawesome:
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.11.2/css/all.min.css
search:
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
mermaid:
js: https://cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js
dayjs:
js:
common: https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js
locale: https://cdn.jsdelivr.net/npm/dayjs@1/locale/:LOCALE.min.js
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1/plugin/relativeTime.min.js
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1/plugin/localizedFormat.min.js
countup:
js: https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js
magnific-popup:
css: https://cdn.jsdelivr.net/npm/magnific-popup@1/dist/magnific-popup.min.css
js: https://cdn.jsdelivr.net/npm/magnific-popup@1/dist/jquery.magnific-popup.min.js
lozad:
js: https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js
clipboard:
js: https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js
polyfill:
js: https://polyfill.io/v3/polyfill.min.js?features=es6
mathjax:
js: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js

View File

@@ -1,51 +0,0 @@
# fonts
webfonts: /assets/lib/fonts/main.css
# Libraries
jquery:
js: /assets/lib/jquery-3.6.0/jquery.min.js
bootstrap:
css: /assets/lib/bootstrap-4.6.1/bootstrap.min.css
js: /assets/lib/bootstrap-4.6.1/bootstrap.bundle.min.js
bootstrap-toc:
css: /assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css
js: /assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js
fontawesome:
css: /assets/lib/fontawesome-free-5.15.4/css/all.min.css
search:
js: /assets/lib/simple-jekyll-search-1.10.0/simple-jekyll-search.min.js
mermaid:
js: /assets/lib/mermaid-8.13.10/mermaid.min.js
dayjs:
js:
common: /assets/lib/dayjs-1.10.7/dayjs.min.js
locale: /assets/lib/dayjs-1.10.7/locale/en.min.js
relativeTime: /assets/lib/dayjs-1.10.7/plugin/relativeTime.min.js
localizedFormat: /assets/lib/dayjs-1.10.7/plugin/localizedFormat.min.js
countup:
js: /assets/lib/countup.js-1.9.3/countUp.min.js
magnific-popup:
css: /assets/lib/magnific-popup-1.1.0/magnific-popup.css
js: /assets/lib/magnific-popup-1.1.0/jquery.magnific-popup.min.js
lozad:
js: /assets/lib/lozad-1.16.0/lozad.min.js
clipboard:
js: /assets/lib/clipboard-2.0.9/clipboard.min.js
polyfill:
js: /assets/lib/polyfill-v3-es6/polyfill.min.js
mathjax:
js: /assets/lib/mathjax-3.2.0/tex-chtml.js

View File

@@ -23,10 +23,18 @@ search:
no_results: Oops! No result founds.
panel:
lastmod: Recently Updated
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:
@@ -51,9 +59,13 @@ not_found:
# ----- Posts related labels -----
post:
written_by: By
posted: Posted
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:

View File

@@ -27,6 +27,14 @@ panel:
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:
@@ -51,9 +59,13 @@ not_found:
# ----- Posts related labels -----
post:
written_by: Oleh
posted: Diterbitkan
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:

View File

@@ -1,78 +0,0 @@
# 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: 바로가기
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: >-
명시되지 않는 한 이 사이트의 블로그 게시물은 작성자의
Creative Commons Attribution 4.0 International(CC BY 4.0) 라이선스에 따라 사용이 허가되었습니다.
meta: Powered by :PLATFORM with :THEME theme.
not_found:
statment: 해당 URL은 존재하지 않습니다.
hint_template: :HEAD_BAK을 눌러 다시 찾거나 :ARCHIVES_PAGE에서 검색해 주세요.
head_back: 홈으로 돌아가기
archives_page: 아카이브 페이지
# ----- Posts related labels -----
post:
written_by: By
posted: 게시
updated: 업데이트
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: 포스트

View File

@@ -1,78 +0,0 @@
# 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: အကြောင်းအရာများ
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: >-
အခြားမှတ်သားထားချက်များမှလွဲ၍ ဤဆိုက်ရှိ ဘလော့ဂ်ပို့စ်များသည် စာရေးသူ၏
Creative Commons Attribution 4.0 International (CC BY 4.0) အောက်တွင် လိုင်စင်ရထားပါသည်။
meta: Powered by :PLATFORM with :THEME theme.
not_found:
statment: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။
hint_template: ၎င်းကို ထပ်မံရှာဖွေရန် :HEAD_BAK , သို့မဟုတ် :ARCHIVES_PAGE တွင်ရှာပါ။
head_back: အဓိကစာမျက်နှာသို့ပြန်သွားပါ။
archives_page: မှတ်တမ်း​တိုက် စာမျက်နှာ။
# ----- Posts related labels -----
post:
written_by: ကရေးသားခဲ့သည်။
posted: တင်ထားခဲ့သည်။
updated: မွမ်းမံထားခဲ့သည်။
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: ပို့စ်များ

View File

@@ -1,78 +0,0 @@
# 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: Содержание
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: >-
Публикации на сайте защищены лицензией Creative Commons Attribution 4.0 International (CC BY 4.0),
если в тексте публикации не указано иное.
meta: Powered by :PLATFORM with :THEME theme.
not_found:
statment: Извините, эта ссылка указывает на ресурс который не существует.
hint_template: :HEAD_BAK чтобы снова осуществить поиск, или поищите :ARCHIVES_PAGE.
head_back: Вернитесь на домашнюю страницу
archives_page: архиве
# ----- Posts related labels -----
post:
written_by: Автор
posted: Время публикации
updated: Обновлено
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: публикации

View File

@@ -1,78 +0,0 @@
# 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: Зміст
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: >-
Публікації на сайті захищено ліцензією Creative Commons Attribution 4.0 International (CC BY 4.0),
якщо інше не вказано в тексті.
meta: Powered by :PLATFORM with :THEME theme.
not_found:
statment: Вибачте, це посилання вказує на ресурс, що не існує.
hint_template: :HEAD_BAK аби здійснити пошук, або пошукайте в :ARCHIVES_PAGE.
head_back: Поверніться на домашню сторінку
archives_page: архіві
# ----- Posts related labels -----
post:
written_by: Автор
posted: Час публікації
updated: Оновлено
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: публікації

View File

@@ -27,6 +27,14 @@ panel:
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:
@@ -50,9 +58,13 @@ not_found:
# ----- Posts related labels -----
post:
written_by: 作者
posted: 发表于
published: 发表于
updated: 更新于
timeago:
day: 天前
hour: 小时前
minute: 分钟前
just_now: 刚刚
words:
pageview_measure: 次浏览
read_time:

View File

@@ -13,7 +13,7 @@ platforms:
-
type: Telegram
icon: "fab fa-telegram"
link: "https://t.me/share/url?url=URL&text=TITLE"
link: "https://telegram.me/share?text=TITLE&url=URL"
# Uncomment below if you need to.
# -

View File

@@ -1,12 +0,0 @@
{% comment %} Site static assets origin {% endcomment %}
{% assign origin = 'cross_origin' %}
{% if site.assets.self_host.enabled %}
{% if site.assets.self_host.env %}
{% if site.assets.self_host.env == jekyll.environment %}
{% assign origin = 'self_host' %}
{% endif %}
{% else %}
{% assign origin = 'self_host' %}
{% endif %}
{% endif %}

View File

@@ -1,5 +0,0 @@
<!-- The comments switcher -->
{% if page.comments and site.comments.active %}
{% capture path %}comments/{{ site.comments.active }}.html{% endcapture %}
{% include {{ path }} %}
{% endif %}

View File

@@ -1,56 +0,0 @@
<!-- https://giscus.app/ -->
<script type="text/javascript">
$(function () {
const origin = "https://giscus.app";
const iframe = "iframe.giscus-frame";
const lightTheme = "light";
const darkTheme = "dark_dimmed";
let initTheme = lightTheme;
if ($("html[data-mode=dark]").length > 0
|| ($("html[data-mode]").length == 0
&& window.matchMedia("(prefers-color-scheme: dark)").matches)) {
initTheme = darkTheme;
}
let giscusAttributes = {
"src": "https://giscus.app/client.js",
"data-repo": "{{ site.comments.giscus.repo}}",
"data-repo-id": "{{ site.comments.giscus.repo_id }}",
"data-category": "{{ site.comments.giscus.category }}",
"data-category-id": "{{ site.comments.giscus.category_id }}",
"data-mapping": "{{ site.comments.giscus.mapping | default: 'pathname' }}",
"data-reactions-enabled": "1",
"data-emit-metadata": "0",
"data-theme": initTheme,
"data-input-position": "{{ site.comments.giscus.input_position | default: 'bottom' }}",
"data-lang": "{{ site.comments.giscus.lang | default: lang }}",
"crossorigin": "anonymous",
"async": ""
};
let giscusScript = document.createElement("script");
Object.entries(giscusAttributes).forEach(([key, value]) => giscusScript.setAttribute(key, value));
document.getElementById("tail-wrapper").appendChild(giscusScript);
addEventListener("message", (event) => {
if (event.source === window && event.data &&
event.data.direction === ModeToggle.ID) {
/* global theme mode changed */
const mode = event.data.message;
const theme = (mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme);
const message = {
setConfig: {
theme: theme
}
};
const giscus = document.querySelector(iframe).contentWindow;
giscus.postMessage({ giscus: message }, origin);
}
});
});
</script>

View File

@@ -1,51 +0,0 @@
<!-- https://utteranc.es/ -->
<script src="https://utteranc.es/client.js"
repo="{{ site.comments.utterances.repo }}"
issue-term="{{ site.comments.utterances.issue_term }}"
crossorigin="anonymous"
async>
</script>
<script type="text/javascript">
$(function() {
const origin = "https://utteranc.es";
const iframe = "iframe.utterances-frame";
const lightTheme = "github-light";
const darkTheme = "github-dark";
let initTheme = lightTheme;
if ($("html[data-mode=dark]").length > 0
|| ($("html[data-mode]").length == 0
&& window.matchMedia("(prefers-color-scheme: dark)").matches)) {
initTheme = darkTheme;
}
addEventListener("message", (event) => {
let theme;
/* credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> */
if (event.origin === origin) {
/* page initial */
theme = initTheme;
} else if (event.source === window && event.data &&
event.data.direction === ModeToggle.ID) {
/* global theme mode changed */
const mode = event.data.message;
theme = (mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme);
} else {
return;
}
const message = {
type: "set-theme",
theme: theme
};
const utterances = document.querySelector(iframe).contentWindow;
utterances.postMessage(message, origin);
});
});
</script>

View File

@@ -0,0 +1,15 @@
<!--
CSS selector for site.
-->
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
{% if site.toc and page.toc %}
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.css">
{% endif %}
{% if page.layout == 'page' or page.layout == 'post' %}
<!-- Manific Popup -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css">
{% endif %}

View File

@@ -1,6 +1,7 @@
<!--
The Disqus lazy loading.
-->
<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>.
@@ -8,7 +9,6 @@
</div>
<script type="text/javascript">
var disqus_config = function () {
this.page.url = '{{ page.url | absolute_url }}';
this.page.identifier = '{{ page.url }}';
@@ -20,7 +20,7 @@
if(entries[0].isIntersecting) {
(function () {
var d = document, s = d.createElement('script');
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
s.src = 'https://{{ site.disqus.shortname }}.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
@@ -46,8 +46,8 @@
const modeToggle = document.querySelector(".mode-toggle");
if (typeof modeToggle !== "undefined") {
/* modeToggle.addEventListener('click', reloadDisqus); // not pretty for 'color-scheme' */
if (modeToggle !== null) {
modeToggle.addEventListener('click', reloadDisqus);
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', reloadDisqus);
}

View File

@@ -3,7 +3,7 @@
-->
<footer class="d-flex w-100 justify-content-center">
<div class="d-flex justify-content-between align-items-center text-muted">
<div class="d-flex justify-content-between align-items-center">
<div class="footer-left">
<p class="mb-0">
© {{ 'now' | date: "%Y" }}

View File

@@ -6,13 +6,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Allow having a localized datetime different from the appearance language -->
{% if site.prefer_datetime_locale %}
<meta name="prefer-datetime-locale" content="{{ site.prefer_datetime_locale }}">
{% endif %}
{% 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 %}
@@ -34,24 +35,12 @@
{% include favicons.html %}
{% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %}
<link href="{{ site.data.assets[origin].webfonts | relative_url }}" rel="stylesheet">
{% else %}
{% for cdn in site.data.assets[origin].cdns %}
<link rel="preconnect" href="{{ cdn.url }}" {{ cdn.args }}>
<link rel="dns-prefetch" href="{{ cdn.url }}" {{ cdn.args }}>
{% endfor %}
<link rel="stylesheet" href="{{ site.data.assets[origin].webfonts }}">
{% endif %}
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous">
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
<!-- GA -->
{% if jekyll.environment == 'production'
and site.google_analytics.id != empty and site.google_analytics.id %}
{% if jekyll.environment == 'production' %}
<link rel="preconnect" href="https://www.google-analytics.com" crossorigin="use-credentials">
<link rel="dns-prefetch" href="https://www.google-analytics.com">
@@ -60,31 +49,27 @@
{% if site.google_analytics.pv.proxy_endpoint %}
{% assign proxy_url = site.google_analytics.pv.proxy_endpoint
| replace: "https://", "" | split: "/" | first | prepend: "https://" %}
| replace: "https://", "" | split: "/" | first | prepend: "https://" %}
<link rel="preconnect" href="{{ proxy_url }}" crossorigin="use-credentials">
<link rel="dns-prefetch" href="{{ proxy_url }}">
{% endif %}
{% endif %}
<!-- jsDelivr CDN -->
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
<!-- Bootstrap -->
<link rel="stylesheet" href="{{ site.data.assets[origin].bootstrap.css }}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="{{ site.data.assets[origin].fontawesome.css }}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.11.2/css/all.min.css">
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
{% if site.toc and page.toc %}
<link rel="stylesheet" href="{{ site.data.assets[origin].bootstrap-toc.css }}">
{% endif %}
{% if page.layout == 'page' or page.layout == 'post' %}
<!-- Manific Popup -->
<link rel="stylesheet" href="{{ site.data.assets[origin].magnific-popup.css }}">
{% endif %}
{% include css-selector.html %}
<!-- JavaScript -->
<script src="{{ site.data.assets[origin].jquery.js }}"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
</head>

View File

@@ -4,46 +4,17 @@
<!-- layout specified -->
{% if page.layout == 'post' %}
{% 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="{{ site.data.assets[origin].countup.js }}"></script>
<script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></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 & clipboard -->
{% assign _urls = site.data.assets[origin].magnific-popup.js
| append: ',' | append: site.data.assets[origin].lozad.js
| append: ',' | append: site.data.assets[origin].clipboard.js
%}
{% include jsdelivr-combine.html urls=_urls %}
{% endif %}
{% if page.layout == 'home'
or page.layout == 'post'
or page.layout == 'archives'
or page.layout == 'category'
or page.layout == 'tag' %}
{% if site.prefer_datetime_locale %}
{% assign locale = site.prefer_datetime_locale | downcase %}
{% else %}
{% assign locale = site.lang | split: '-' | first %}
{% endif %}
{% assign _urls = site.data.assets[origin].dayjs.js.common
| append: ',' | append: site.data.assets[origin].dayjs.js.locale
| replace: ':LOCALE', locale
| append: ',' | append: site.data.assets[origin].dayjs.js.relativeTime
| append: ',' | append: site.data.assets[origin].dayjs.js.localizedFormat
%}
{% include jsdelivr-combine.html urls=_urls %}
<!-- image lazy-loading & popup -->
<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,16 +22,12 @@
or page.layout == 'post'
or page.layout == 'page' %}
{% assign type = page.layout %}
{% elsif page.layout == 'archives'
or page.layout == 'category'
or page.layout == 'tag' %}
{% assign type = "misc" %}
{% else %}
{% assign type = "commons" %}
{% endif %}
{% capture script %}/assets/js/dist/{{ type }}.min.js{% endcapture %}
<script defer src="{{ script | relative_url }}"></script>
{% assign js = type | prepend: '/assets/js/dist/' | append: '.min.js' %}
<script defer src="{{ js | relative_url }}"></script>
{% if page.math %}
<!-- MathJax -->
@@ -79,21 +46,22 @@
}
};
</script>
<script src="{{ site.data.assets[origin].polyfill.js }}"></script>
<script id="MathJax-script" async src="{{ site.data.assets[origin].mathjax.js }}">
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
</script>
{% endif %}
<!-- commons -->
<script src="{{ site.data.assets[origin].bootstrap.js }}"></script>
<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>
<!-- GA -->
{% if site.google_analytics.id != empty and site.google_analytics.id %}
{% if site.google_analytics.id %}
{% include google-analytics.html %}
{% endif %}

View File

@@ -1,32 +0,0 @@
{% assign urls = include.urls | split: ',' %}
{% assign combined_urls = nil %}
{% assign domain = 'https://cdn.jsdelivr.net/' %}
{% for url in urls %}
{% if url contains domain %}
{% assign url_snippet = url | slice: domain.size, url.size %}
{% if combined_urls %}
{% assign combined_urls = combined_urls | append: ',' | append: url_snippet %}
{% else %}
{% assign combined_urls = domain | append: 'combine/' | append: url_snippet %}
{% endif %}
{% elsif url contains '//' %}
<script src="{{ url }}"></script>
{% else %}
<script src="{{ url | relative_url }}"></script>
{% endif %}
{% endfor %}
{% if combined_urls %}
<script src="{{ combined_urls }}"></script>
{% endif %}

View File

@@ -41,6 +41,8 @@
{{ 'Perl' }}
{% when 'php','php3','php4','php5' %}
{{ 'PHP' }}
{% when 'plaintext', 'text' %}
{{ 'Text' }}
{% when 'py' %}
{{ 'Python' }}
{% when 'rb' %}
@@ -63,7 +65,7 @@
{{ 'Vue.js' }}
{% when 'yml' %}
{{ 'YAML' }}
{% when 'css', 'html', 'scss', 'ssh', 'toml', 'xml', 'yaml', 'json' %}
{% when 'css', 'html', 'scss', 'ssh', 'toml', 'xml', 'yaml' %}
{{ _lang | upcase }}
{% else %}
{{ _lang | capitalize }}

View File

@@ -2,39 +2,13 @@
mermaid-js loader
-->
<script src="{{ site.data.assets[origin].mermaid.js }}"></script>
<script src="https://cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js"></script>
<script>
$(function() {
function updateMermaid(event) {
if (event.source === window && event.data &&
event.data.direction === ModeToggle.ID) {
const mode = event.data.message;
if (typeof mermaid === "undefined") {
return;
}
let expectedTheme = (mode === ModeToggle.DARK_MODE? "dark" : "default");
let config = { theme: expectedTheme };
/* Re-render the SVG <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> */
$(".mermaid").each(function() {
let svgCode = $(this).prev().children().html();
$(this).removeAttr("data-processed");
$(this).html(svgCode);
});
mermaid.initialize(config);
mermaid.init(undefined, ".mermaid");
}
}
let initTheme = "default";
if ($("html[data-mode=dark]").length > 0
|| ($("html[data-mode]").length == 0
if ($("html[mode=dark]").length > 0
|| ($("html[mode]").length == 0
&& window.matchMedia("(prefers-color-scheme: dark)").matches ) ) {
initTheme = "dark";
}
@@ -51,7 +25,5 @@
});
mermaid.initialize(mermaidConf);
window.addEventListener("message", updateMermaid);
});
</script>

View File

@@ -2,13 +2,14 @@
Switch the mode between dark and light.
-->
<i class="mode-toggle fas fa-adjust"></i>
<script type="text/javascript">
class ModeToggle {
static get MODE_KEY() { return "mode"; }
static get MODE_ATTR() { return "data-mode"; }
static get DARK_MODE() { return "dark"; }
static get LIGHT_MODE() { return "light"; }
static get ID() { return "mode-toggle"; }
constructor() {
if (this.hasMode) {
@@ -23,10 +24,10 @@
}
}
let self = this;
var self = this;
/* always follow the system prefers */
this.sysDarkPrefers.addEventListener("change", () => {
this.sysDarkPrefers.addListener(function() {
if (self.hasMode) {
if (self.isDarkMode) {
if (!self.isSysDarkPrefer) {
@@ -42,19 +43,34 @@
self.clearMode();
}
self.notify();
self.updateMermaid();
});
} /* constructor() */
setDark() {
$('html').attr(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
}
setLight() {
$('html').attr(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
}
clearMode() {
$('html').removeAttr(ModeToggle.MODE_KEY);
sessionStorage.removeItem(ModeToggle.MODE_KEY);
}
get sysDarkPrefers() { return window.matchMedia("(prefers-color-scheme: dark)"); }
get isSysDarkPrefer() { return this.sysDarkPrefers.matches; }
get isDarkMode() { return this.mode === ModeToggle.DARK_MODE; }
get isDarkMode() { return this.mode == ModeToggle.DARK_MODE; }
get isLightMode() { return this.mode === ModeToggle.LIGHT_MODE; }
get isLightMode() { return this.mode == ModeToggle.LIGHT_MODE; }
get hasMode() { return this.mode != null; }
@@ -63,67 +79,67 @@
/* get the current mode on screen */
get modeStatus() {
if (this.isDarkMode
|| (!this.hasMode && this.isSysDarkPrefer)) {
|| (!this.hasMode && this.isSysDarkPrefer) ) {
return ModeToggle.DARK_MODE;
} else {
return ModeToggle.LIGHT_MODE;
}
}
setDark() {
$('html').attr(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
updateMermaid() {
if (typeof mermaid !== "undefined") {
let expectedTheme = (this.modeStatus === ModeToggle.DARK_MODE? "dark" : "default");
let config = { theme: expectedTheme };
/* re-render the SVG <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> */
$(".mermaid").each(function() {
let svgCode = $(this).prev().children().html();
$(this).removeAttr("data-processed");
$(this).html(svgCode);
});
mermaid.initialize(config);
mermaid.init(undefined, ".mermaid");
}
}
setLight() {
$('html').attr(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
}
flipMode() {
if (this.hasMode) {
if (this.isSysDarkPrefer) {
if (this.isLightMode) {
this.clearMode();
} else {
this.setLight();
}
clearMode() {
$('html').removeAttr(ModeToggle.MODE_ATTR);
sessionStorage.removeItem(ModeToggle.MODE_KEY);
}
} else {
if (this.isDarkMode) {
this.clearMode();
} else {
this.setDark();
}
}
/* Notify another plugins that the theme mode has changed */
notify() {
window.postMessage({
direction: ModeToggle.ID,
message: this.modeStatus
}, "*");
}
} else {
if (this.isSysDarkPrefer) {
this.setLight();
} else {
this.setDark();
}
}
this.updateMermaid();
} /* flipMode() */
} /* ModeToggle */
const toggle = new ModeToggle();
let toggle = new ModeToggle();
function flipMode() {
if (toggle.hasMode) {
if (toggle.isSysDarkPrefer) {
if (toggle.isLightMode) {
toggle.clearMode();
} else {
toggle.setLight();
}
$(".mode-toggle").click(function() {
} else {
if (toggle.isDarkMode) {
toggle.clearMode();
} else {
toggle.setDark();
}
}
toggle.flipMode();
} else {
if (toggle.isSysDarkPrefer) {
toggle.setLight();
} else {
toggle.setDark();
}
}
toggle.notify();
} /* flipMode() */
});
</script>

View 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', ' ' }}

59
_includes/panel.html Normal file
View File

@@ -0,0 +1,59 @@
<!--
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">
{% include update-list.html %}
{% if update_list.size > 0 %}
<div id="access-lastmod" class="post">
<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 %}
{% assign index = item | split: "::" | last | plus: 0 %}
{% assign post = site.posts[index] %}
{% assign url = post.url | relative_url %}
<li><a href="{{ url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</div> <!-- #access-lastmod -->
{% endif %}
{% include trending-tags.html %}
{% if trending_tags.size > 0 %}
<div id="access-tags">
<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 %}
{% assign url = tag_name | slugify | url_encode | prepend: "/tags/" | append: "/" %}
<a class="post-tag" href="{{ url | relative_url }}">{{ tag_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
</div> <!-- .access -->
{% if include.toc %}
<!-- BS-toc.js will be loaded at medium priority -->
<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.locales[lang].panel.toc -}}
</span>
<nav id="toc" data-toggle="toc"></nav>
</div>
{% endif %}
</div> <!-- #panel-wrapper -->

View File

@@ -9,7 +9,7 @@
{% assign url = page.url | absolute_url %}
{% for share in site.data.share.platforms %}
{% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url | escape %}
{% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url %}
<a href="{{ link }}" data-toggle="tooltip" data-placement="top"
title="{{ share.type }}" target="_blank" rel="noopener" aria-label="{{ share.type }}">
<i class="fa-fw {{ share.icon }}"></i>
@@ -19,7 +19,7 @@
<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 }}"
data-title-succeed="{{ site.data.locales[lang].post.button.share_link.succeed }}">
title-succeed="{{ site.data.locales[lang].post.button.share_link.succeed }}">
</i>
</span>

View File

@@ -22,9 +22,9 @@
<!-- return element -->
<span class="readtime" data-toggle="tooltip" data-placement="bottom"
title="{{ words }} {{ site.data.locales[lang].post.words }}">
<em>{{- read_time -}}{{" "}}{{- site.data.locales[lang].post.read_time.unit -}}</em>
{{- 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 }}
{% assign _prompt_words = read_prompt | number_of_words: 'auto' %}
{% unless _prompt_words > 1 %}{{" "}}{% endunless %}{{ read_prompt }}
{%- endif -%}
</span>

View File

@@ -38,101 +38,63 @@
%}
{% endif %}
<!-- images -->
{% assign IMG_TAG = '<img ' %}
{% 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 %}
{% assign img_path_replacement = '<img src="' | append: site.baseurl | append: '/' %}
{% endif %}
{% assign _content = _content | replace: '<img src="/', img_path_replacement %}
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
{% assign _content = _content | replace: '<img src="', '<img data-proofer-ignore data-src="' %}
<!-- add image placehoder to prevent layout reflow -->
{% if _content contains IMG_TAG %}
{% assign _img_content = nil %}
{% assign _img_snippets = _content | split: IMG_TAG %}
{% for _img_snippet in _img_snippets %}
{% assign _images = _content | split: '<img ' %}
{% for _img in _images %}
{% if forloop.first %}
{% assign _img_content = _img_snippet %}
{% assign _img_content = _img %}
{% continue %}
{% endif %}
{% assign _width = nil %}
{% assign _height = nil %}
{% assign _src = nil %}
{% assign _left = _img_snippet | split: '>' | first %}
{% assign _right = _img_snippet | remove: _left %}
{% assign _left = _left | remove: ' /' %}
{% assign _left = _left | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
{% assign _attrs = _left | split: ' ' %}
{% assign _attrs = _img | split: '>' | first | split: ' ' %}
{% for _attr in _attrs %}
{% assign _pair = _attr | split: '=' %}
{% if _pair.size < 2 %}
{% continue %}
{% endif %}
{% capture _key %}{{ _pair | first }}{% endcapture %}
{% capture _value %}{{ _pair | last | replace: '"', '' }}{% endcapture %}
{% 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 %}
{% when 'src' %}
{% assign _src = _value %}
{% endcase %}
{% if _width and _height and _src %}
{% 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 %}
{% if _src %}
{% unless _src contains '://' %}
<!-- Add CDN URL -->
{% if site.img_cdn %}
{% assign _src_prefix = site.img_cdn %}
{% else %}
{% assign _src_prefix = site.baseurl %}
{% endif %}
<!-- Add image path -->
{% if page.img_path %}
{% assign _path = page.img_path %}
{% assign last_char = _path | slice: -1 %}
{% unless last_char == '/' %}
{% assign _path = _path | append: '/' %}
{% endunless %}
{% assign _src_prefix = _src_prefix | append: _path %}
{% endif %}
{% assign _final_src = _src_prefix | append: _src %}
{% assign _left = _left | replace: _src, _final_src %}
{% endunless %}
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
{% assign _left = _left | replace: 'src=', 'data-src=' %}
{% endif %}
<!-- Add SVG placehoder to prevent layout reflow -->
{% if _width and _height %}
{%- capture _svg -%}
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
{%- endcapture -%}
{% assign _left = _svg | append: ' ' | append: _left %}
{% endif %}
<!-- Bypass the HTML-proofer test -->
{% assign _left = _left | append: ' data-proofer-ignore' %}
{% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
{% unless _width and _height %}
{% assign _img_content = _img_content | append: '<img ' | append: _img %}
{% endunless %}
{% endfor %}
@@ -156,22 +118,22 @@
{% assign _left = _snippet | split: '><' | last%}
{% if _left contains 'file="' %}
{% assign _label_text = _left | split: 'file="' | last | split: '"' | first %}
{% 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 _label_text %}{% include language-alias.html language=_lang %}{% endcapture %}
{% capture _text %}{% include language-alias.html language=_lang %}{% endcapture %}
{% assign _label_icon = 'fas fa-code small' %}
{% endif %}
{% capture _label %}
<span data-label-text="{{ _label_text | strip }}"><i class="{{ _label_icon }}"></i></span>
<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" data-title-succeed="'
| 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>'
@@ -185,92 +147,6 @@
{% endif %}
<!-- Create heading anchors -->
{% assign heading_levels = '2,3,4,5' | split: ',' %}
{% assign _heading_content = _content %}
{% for level in heading_levels %}
{% capture mark_start %}<h{{ level }} id="{% endcapture %}
{% capture mark_end %}</h{{ level }}>{% endcapture %}
{% if _heading_content contains mark_start %}
{% assign _new_content = nil %}
{% assign heading_snippets = _heading_content | split: mark_start %}
{% for snippet in heading_snippets %}
{% if forloop.first %}
{% assign _new_content = snippet %}
{% continue %}
{% endif %}
{% assign id = snippet | split: '"' | first %}
{% capture anchor %}<a href="#{{ id }}" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>{% endcapture %}
{% assign left = snippet | split: mark_end | first %}
{% assign right = snippet | slice: left.size, snippet.size %}
{% assign left = left | replace: '">', '"><span class="mr-2">' | append: '</span>' %}
{% assign _new_content = _new_content | append: mark_start
| append: left | append: anchor | append: mark_end | append: right
%}
{% endfor %}
{% assign _heading_content = _new_content %}
{% endif %}
{% endfor %}
{% assign _content = _heading_content %}
<!-- Wrap prompt element of blockquote with the <div> tag -->
{% assign blockquote_start = '<blockquote class=' %}
{% assign blockquote_end = '</blockquote>' %}
{% assign cls_prefix = 'prompt-' %}
{% if _content contains blockquote_start %}
{% assign _prompt_content = nil %}
{% assign _prompt_snippets = _content | split: blockquote_start %}
{% for _snippet in _prompt_snippets %}
{% if forloop.first %}
{% assign _prompt_content = _snippet %}
{% continue %}
{% endif %}
{% assign left = _snippet | split: blockquote_end | first %}
{% assign right = _snippet | slice: left.size, _snippet.size %}
{% assign cls_str = left | split: '>' | first %}
{% assign cls_array = cls_str | remove: '"' | split: ' ' %}
{% assign is_prompt = false %}
{% for cls in cls_array %}
{% if cls contains cls_prefix %}
{% assign is_prompt = true %}
{% break %}
{% endif %}
{% endfor %}
{% unless is_prompt %}
{% assign _prompt_content = _prompt_content | append: blockquote_start | append: _snippet %}
{% continue %}
{% endunless %}
{% assign left = left | slice: cls_str.size, left.size %}
{% assign left = cls_str | append: '><div' | append: left | append: '</div>' %}
{% assign _prompt_content = _prompt_content | append: blockquote_start | append: left | append: right %}
{% endfor %}
{% assign _content = _prompt_content %}
{% endif %}
<!-- return -->

View File

@@ -94,7 +94,7 @@
<div class="text-muted small">
<p>
{% include no-linenos.html content=post.content %}
{{ content | markdownify | strip_html | truncate: 200 | escape }}
{{ content | markdownify | strip_html | truncate: 200 }}
</p>
</div>
</div>

View File

@@ -16,7 +16,7 @@
{% capture not_found %}<p class="mt-5">{{ site.data.locales[lang].search.no_results }}</p>{% endcapture %}
<script src="{{ site.data.assets[origin].search.js }}"></script>
<script src="https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js"></script>
<script>
SimpleJekyllSearch({

View File

@@ -4,7 +4,15 @@
<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.locales[lang].panel.trending_tags }}</h4>
{% include trending-tags.html %}
{% for tag in trending_tags %}
{% capture url %}/tags/{{ tag | slugify | url_encode }}/{% endcapture %}
<a class="post-tag" href="{{ url | relative_url }}">{{ tag | replace: '-', ' ' }}</a>
{% endfor %}
</div>
<div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
</div>

View File

@@ -2,19 +2,19 @@
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">
{% if site.avatar != empty and site.avatar %}
{% if site.avatar != '' and site.avatar %}
{% capture avatar_url %}
{% if site.avatar contains '://' %}
{%- if site.avatar contains '://' -%}
{{ site.avatar }}
{% elsif site.img_cdn != empty and site.img_cdn %}
{%- elsif site.img_cdn != '' and site.img_cdn -%}
{{ site.avatar | prepend: site.img_cdn }}
{% else %}
{%- else -%}
{{ site.avatar | relative_url }}
{% endif %}
{%- endif -%}
{% endcapture %}
<img src="{{ avatar_url }}" alt="avatar" onerror="this.style.display='none'">
{% endif %}
@@ -53,16 +53,6 @@
<div class="sidebar-bottom mt-auto d-flex flex-wrap justify-content-center align-items-center">
{% unless site.theme_mode %}
<button class="mode-toggle btn" aria-label="Switch Mode">
<i class="fas fa-adjust"></i>
</button>
{% if site.data.contact.size > 0 %}
<span class="icon-border"></span>
{% endif %}
{% endunless %}
{% for entry in site.data.contact %}
{% capture url %}
{%- if entry.type == 'github' -%}
@@ -81,6 +71,7 @@
{% if url %}
<a href="{{ url }}" aria-label="{{ entry.type }}"
{% unless site.theme_mode %}class="order-{{ forloop.index | plus: 2 }}"{% endunless %}
{% unless entry.noblank %}target="_blank" rel="noopener"{% endunless %}>
<i class="{{ entry.icon }}"></i>
</a>
@@ -88,6 +79,16 @@
{% endfor %}
{% unless site.theme_mode %}
{% if site.data.contact.size > 0 %}
<span class="icon-border order-2"></span>
{% endif %}
<span id="mode-toggle-wrapper" class="order-1">
{% include mode-toggle.html %}
</span>
{% endunless %}
</div> <!-- .sidebar-bottom -->
</div><!-- #sidebar -->

View File

@@ -1,15 +1,27 @@
<!--
Date format snippet
See: ${JS_ROOT}/utils/timeago.js
See: /assets/js/_utils/timeage.js
-->
<em class="timeago{% if include.class %} {{ include.class }}{% endif %}"
data-ts="{{ include.date | date: '%s' }}"
{% if include.tooltip %}
data-toggle="tooltip" data-placement="bottom" data-tooltip-df="llll"
{% endif %}
{% if include.capitalize %}
data-capitalize="true"
{% endif %}>
{{ include.date | date: '%Y-%m-%d' }}
</em>
{% 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 %}>
{%- 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 -%}
{{ include.date | date: post_long_df }}
{%- endif -%}
<i class="unloaded">{{ include.date | date_to_xmlschema }}</i>
</span>

View File

@@ -1,16 +0,0 @@
{% assign enable_toc = false %}
{% if site.toc and page.toc %}
{% if page.content contains '<h2' or page.content contains '<h3' %}
{% assign enable_toc = true %}
{% endif %}
{% endif %}
{% if enable_toc %}
<!-- BS-toc.js will be loaded at medium priority -->
<script src="{{ site.data.assets[origin].bootstrap-toc.js }}"></script>
<div id="toc-wrapper" class="pl-0 pr-4 mb-5">
<div class="panel-heading pl-3 pt-2 mb-2">{{- site.data.locales[lang].panel.toc -}}</div>
<nav id="toc" data-toggle="toc"></nav>
</div>
{% endif %}

View File

@@ -2,7 +2,7 @@
The Top Bar
-->
<div id="topbar-wrapper" class="row justify-content-center">
<div id="topbar-wrapper" class="row justify-content-center topbar-down">
<div id="topbar" class="col-11 d-flex h-100 align-items-center justify-content-between">
<span id="breadcrumb">
@@ -50,7 +50,7 @@
<div id="topbar-title">
{% if page.layout == 'home' %}
{{- site.data.locales[lang].title | default: site.title -}}
{% elsif page.collection == 'tabs' or page.layout == 'page' %}
{% elsif page.collection == 'tabs' %}
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
{{- site.data.locales[lang].tabs[tab_key] | default: page.title -}}
{% else %}
@@ -63,6 +63,7 @@
<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.locales[lang].search.hint | capitalize }}...">
<i class="fa fa-times-circle fa-fw" id="search-cleaner"></i>
</span>
<span id="search-cancel" >{{ site.data.locales[lang].search.cancel }}</span>
</div>

View File

@@ -34,17 +34,3 @@
{% endif %}
{% endfor %}
{% endfor %}
{% if trending_tags.size > 0 %}
<div id="access-tags">
<div class="panel-heading">{{- site.data.locales[lang].panel.trending_tags -}}</div>
<div class="d-flex flex-wrap mt-3 mb-1 mr-3">
{% for tag_name in trending_tags %}
{% assign url = tag_name | slugify | url_encode | prepend: "/tags/" | append: "/" %}
<a class="post-tag" href="{{ url | relative_url }}">{{ tag_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}

View File

@@ -22,19 +22,3 @@
{% for entry in all_list limit:MAX_SIZE %}
{% assign update_list = update_list | push: entry %}
{% endfor %}
{% if update_list.size > 0 %}
<div id="access-lastmod" class="post">
<div class="panel-heading">{{- site.data.locales[lang].panel.lastmod -}}</div>
<ul class="post-content pl-0 pb-1 ml-1 mt-2">
{% for item in update_list %}
{% assign index = item | split: "::" | last | plus: 0 %}
{% assign post = site.posts[index] %}
{% assign url = post.url | relative_url %}
<li><a href="{{ url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</div> <!-- #access-lastmod -->
{% endif %}

View File

@@ -1,19 +0,0 @@
/**
* A tool for locale datetime
*/
const LocaleHelper = (function () {
const $preferLocale = $('meta[name="prefer-datetime-locale"]');
const locale = $preferLocale.length > 0 ?
$preferLocale.attr('content').toLowerCase() : $('html').attr('lang').substr(0, 2);
const attrTimestamp = 'data-ts';
const attrDateFormat = 'data-df';
return {
locale: () => locale,
attrTimestamp: () => attrTimestamp,
attrDateFormat: () => attrDateFormat,
getTimestamp: ($elem) => Number($elem.attr(attrTimestamp)), // unix timestamp
getDateFormat: ($elem) => $elem.attr(attrDateFormat)
};
}());

View File

@@ -1,13 +0,0 @@
/*
* Listener for theme mode toggle
*/
$(function() {
$(".mode-toggle").click((e) => {
const $target = $(e.target);
let $btn = ($target.prop("tagName") === "button".toUpperCase() ?
$target : $target.parent());
$btn.blur(); // remove the clicking outline
flipMode();
});
});

View File

@@ -1,36 +0,0 @@
/**
* A tool for smooth scrolling and topbar switcher
*/
const ScrollHelper = (function () {
const $body = $("body");
const ATTR_TOPBAR_VISIBLE = "data-topbar-visible";
const topbarHeight = $("#topbar-wrapper").outerHeight();
let scrollUpCount = 0; // the number of times the scroll up was triggered by ToC or anchor
let topbarLocked = false;
let orientationLocked = false;
return {
hideTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, false),
showTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, true),
// scroll up
addScrollUpTask: () => {
scrollUpCount += 1;
if (!topbarLocked) { topbarLocked = true; }
},
popScrollUpTask: () => scrollUpCount -= 1,
hasScrollUpTask: () => scrollUpCount > 0,
topbarLocked: () => topbarLocked === true,
unlockTopbar: () => topbarLocked = false,
getTopbarHeight: () => topbarHeight,
// orientation change
orientationLocked: () => orientationLocked === true,
lockOrientation: () => orientationLocked = true,
unLockOrientation: () => orientationLocked = false
};
}());

View File

@@ -3,9 +3,12 @@
*/
$(function() {
const btnSbTrigger = $("#sidebar-trigger");
const btnSearchTrigger = $("#search-trigger");
const btnCancel = $("#search-cancel");
const btnClear = $("#search-cleaner");
const main = $("#main");
const topbarTitle = $("#topbar-title");
const searchWrapper = $("#search-wrapper");
@@ -30,7 +33,8 @@ $(function() {
};
}());
/*--- Actions in mobile screens (Sidebar hidden) ---*/
/*--- Actions in small screens (Sidebar unloaded) ---*/
const mobileSearchBar = (function () {
return {
@@ -71,6 +75,7 @@ $(function() {
hints.removeClass("unloaded");
}
resultWrapper.addClass("unloaded");
btnClear.removeClass("visible");
main.removeClass("unloaded");
// now the release method must be called after $(#main) display
@@ -87,6 +92,7 @@ $(function() {
}());
function isMobileView() {
return btnCancel.hasClass("loaded");
}
@@ -110,20 +116,38 @@ $(function() {
searchWrapper.removeClass("input-focus");
});
input.on("input", () => {
if (input.val() === "") {
if (isMobileView()) {
hints.removeClass("unloaded");
} else {
input.on("keyup", function(e) {
if (e.keyCode === 8 && input.val() === "") {
if (!isMobileView()) {
resultSwitch.off();
} else {
hints.removeClass("unloaded");
}
} else {
resultSwitch.on();
if (isMobileView()) {
hints.addClass("unloaded");
if (input.val() !== "") {
resultSwitch.on();
if (!btnClear.hasClass("visible")) {
btnClear.addClass("visible");
}
if (isMobileView()) {
hints.addClass("unloaded");
}
}
}
});
btnClear.on("click", function() {
input.val("");
if (isMobileView()) {
hints.removeClass("unloaded");
results.empty();
} else {
resultSwitch.off();
}
input.focus();
btnClear.removeClass("visible");
});
});

View File

@@ -0,0 +1,69 @@
/*
* Hide Header on scroll down
*/
$(function() {
const topbarWrapper = $("#topbar-wrapper");
const toc = $("#toc-wrapper");
const access = $(".access");
const searchInput = $("#search-input");
let didScroll;
let lastScrollTop = 0;
const delta = 5;
const topbarHeight = topbarWrapper.outerHeight();
function hasScrolled() {
var st = $(this).scrollTop();
/* Make sure they scroll more than delta */
if (Math.abs(lastScrollTop - st) <= delta) {
return;
}
if (st > lastScrollTop && st > topbarHeight) {
/* Scroll Down */
topbarWrapper.removeClass("topbar-down").addClass("topbar-up");
if (toc.length > 0) {
toc.removeClass("topbar-down");
}
if (access.length > 0) {
access.removeClass("topbar-down");
}
if (searchInput.is(":focus")) {
searchInput.blur(); /* remove focus */
}
} else if (st + $(window).height() < $(document).height()) {
/* Scroll Up */
topbarWrapper.removeClass("topbar-up").addClass("topbar-down");
if (toc.length > 0) {
toc.addClass("topbar-down");
}
if (access.length > 0) {
access.addClass("topbar-down");
}
}
lastScrollTop = st;
}
$(window).scroll(function(event) {
if ($("#topbar-title").is(":hidden")) { /* Not in small screens */
didScroll = true;
}
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
});

View File

@@ -1,90 +0,0 @@
/*
* Hide Header on scroll down
*/
$(function() {
const $searchInput = $("#search-input");
const delta = ScrollHelper.getTopbarHeight();
let didScroll;
let lastScrollTop = 0;
function hasScrolled() {
let st = $(this).scrollTop();
/* Make sure they scroll more than delta */
if (Math.abs(lastScrollTop - st) <= delta) {
return;
}
if (st > lastScrollTop ) { // Scroll Down
ScrollHelper.hideTopbar();
if ($searchInput.is(":focus")) {
$searchInput.blur(); /* remove focus */
}
} else { // Scroll up
// has not yet scrolled to the bottom of the screen, that is, there is still space for scrolling
if (st + $(window).height() < $(document).height()) {
if (ScrollHelper.hasScrollUpTask()) {
return;
}
if (ScrollHelper.topbarLocked()) { // avoid redundant scroll up event from smooth scrolling
ScrollHelper.unlockTopbar();
} else {
if (ScrollHelper.orientationLocked()) { // avoid device auto scroll up on orientation change
ScrollHelper.unLockOrientation();
} else {
ScrollHelper.showTopbar();
}
}
}
}
lastScrollTop = st;
} // hasScrolled()
function handleLandscape() {
if ($(window).scrollTop() === 0) {
return;
}
ScrollHelper.lockOrientation();
ScrollHelper.hideTopbar();
}
if (screen.orientation) {
screen.orientation.onchange = () => {
const type = screen.orientation.type;
if (type === "landscape-primary" || type === "landscape-secondary") {
handleLandscape();
}
};
} else {
// for the browsers that not support `window.screen.orientation` API
$(window).on("orientationchange",() => {
if ($(window).width() < $(window).height()) { // before rotating, it is still in portrait mode.
handleLandscape();
}
});
}
$(window).scroll(() => {
if (didScroll) {
return;
}
didScroll = true;
});
setInterval(() => {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
});

View File

@@ -1,66 +1,46 @@
/*
* Top bar title auto change while scrolling up/down in mobile screens.
* Top bar title auto change while scrolling in mobile screens.
*/
$(function() {
const titleSelector = "div.post>h1:first-of-type";
const $pageTitle = $(titleSelector);
const $topbarTitle = $("#topbar-title");
if ($pageTitle.length === 0 /* on Home page */
|| $pageTitle.hasClass("dynamic-title")
|| $topbarTitle.is(":hidden")) {/* not in mobile views */
return;
}
const topbarTitle = $("#topbar-title");
const postTitle = $("div.post>h1");
const defaultTitleText = $topbarTitle.text().trim();
let pageTitleText = $pageTitle.text().trim();
let hasScrolled = false;
let lastScrollTop = 0;
const DEFAULT = topbarTitle.text().trim();
let title = (postTitle.length > 0) ?
postTitle.text().trim() : $("h1").text().trim();
if ($("#page-category").length || $("#page-tag").length) {
/* The title in Category or Tag page will be "<title> <count_of_posts>" */
if (/\s/.test(pageTitleText)) {
pageTitleText = pageTitleText.replace(/[0-9]/g, "").trim();
if (/\s/.test(title)) {
title = title.replace(/[0-9]/g, "").trim();
}
}
// When the page is scrolled down and then refreshed, the topbar title needs to be initialized
if ($pageTitle.offset().top < $(window).scrollTop()) {
$topbarTitle.text(pageTitleText);
}
let options = {
rootMargin: '-48px 0px 0px 0px', // 48px equals to the topbar height (3rem)
threshold: [0, 1]
};
let observer = new IntersectionObserver((entries) => {
if (!hasScrolled) {
hasScrolled = true;
return;
/* Replace topbar title while scroll screens. */
$(window).scroll(function () {
if ($("#post-list").length /* in Home page */
|| postTitle.is(":hidden") /* is tab pages */
|| topbarTitle.is(":hidden") /* not mobile screens */
|| $("#sidebar.sidebar-expand").length) { /* when the sidebar trigger is clicked */
return false;
}
let curScrollTop = $(window).scrollTop();
let isScrollDown = lastScrollTop < curScrollTop;
lastScrollTop = curScrollTop;
let heading = entries[0];
if (isScrollDown) {
if (heading.intersectionRatio === 0) {
$topbarTitle.text(pageTitleText);
if ($(this).scrollTop() >= 95) {
if (topbarTitle.text() !== title) {
topbarTitle.text(title);
}
} else {
if (heading.intersectionRatio === 1) {
$topbarTitle.text(defaultTitleText);
if (topbarTitle.text() !== DEFAULT) {
topbarTitle.text(DEFAULT);
}
}
}, options);
});
observer.observe(document.querySelector(titleSelector));
/* Click title will scroll to top */
$topbarTitle.click(function() {
/* Click title remove hover effect. */
topbarTitle.click(function() {
$("body,html").animate({scrollTop: 0}, 800);
});

View File

@@ -1,5 +1,5 @@
/*!
* Chirpy v5.1.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* Chirpy v4.3.3 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung
* MIT Licensed
*/

View File

@@ -10,8 +10,6 @@ $(function() {
const btnSelector = '.code-header>button';
const ICON_SUCCESS = 'fas fa-check';
const ATTR_TIMEOUT = 'timeout';
const ATTR_TITLE_SUCCEED = 'data-title-succeed';
const ATTR_TITLE_ORIGIN = 'data-original-title';
const TIMEOUT = 2000; // in milliseconds
function isLocked(node) {
@@ -55,12 +53,12 @@ $(function() {
const ICON_DEFAULT = getIcon(btnSelector);
function showTooltip(btn) {
const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED);
$(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
const succeedTitle = $(btn).attr('title-succeed');
$(btn).attr('data-original-title', succeedTitle).tooltip('show');
}
function hideTooltip(btn) {
$(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN);
$(btn).tooltip('hide').removeAttr('data-original-title');
}
function setSuccessIcon(btn) {
@@ -117,14 +115,14 @@ $(function() {
// Switch tooltip title
const defaultTitle = target.attr(ATTR_TITLE_ORIGIN);
const succeedTitle = target.attr(ATTR_TITLE_SUCCEED);
const defaultTitle = target.attr('data-original-title');
const succeedTitle = target.attr('title-succeed');
target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
target.attr('data-original-title', succeedTitle).tooltip('show');
lock(target);
setTimeout(() => {
target.attr(ATTR_TITLE_ORIGIN, defaultTitle);
target.attr('data-original-title', defaultTitle);
unlock(target);
}, TIMEOUT);

View File

@@ -1,20 +0,0 @@
/**
* Update month/day to locale datetime
*
* Requirement: <https://github.com/iamkun/dayjs>
*/
$(function() {
dayjs.locale(LocaleHelper.locale());
dayjs.extend(window.dayjs_plugin_localizedFormat);
$(`[${LocaleHelper.attrTimestamp()}]`).each(function () {
const date = dayjs.unix(LocaleHelper.getTimestamp($(this)));
const df = LocaleHelper.getDateFormat($(this));
const text = date.format(df);
$(this).text(text);
$(this).removeAttr(LocaleHelper.attrTimestamp());
$(this).removeAttr(LocaleHelper.attrDateFormat());
});
});

View File

@@ -8,89 +8,74 @@
*/
$(function() {
const $topbarTitle = $("#topbar-title");
const REM = 16; // in pixels
const ATTR_SCROLL_FOCUS = "scroll-focus";
$("a[href*='#']")
.not("[href='#']")
.not("[href='#0']")
.click(function(event) {
if (this.pathname.replace(/^\//, "") !==
location.pathname.replace(/^\//, "")) {
return;
}
if (location.hostname !== this.hostname) {
return;
}
if (this.pathname.replace(/^\//, "") === location.pathname.replace(/^\//, "")) {
if (location.hostname === this.hostname) {
const hash = decodeURI(this.hash);
let toFootnoteRef = RegExp(/^#fnref:/).test(hash);
let toFootnote = toFootnoteRef ? false : RegExp(/^#fn:/).test(hash);
let selector = hash.includes(":") ? hash.replace(/\:/g, "\\:") : hash;
let $target = $(selector);
const REM = 16; /* 16px */
let isMobileViews = $topbarTitle.is(":visible");
let isPortrait = $(window).width() < $(window).height();
const hash = decodeURI(this.hash);
let isFnRef = RegExp(/^#fnref:/).test(hash);
let isFn = RegExp(/^#fn:/).test(hash);
let selector = hash.includes(":") ? hash.replace(/\:/, "\\:") : hash;
let target = $(selector);
if (typeof $target === "undefined") {
return;
}
if (target.length) {
event.preventDefault();
event.preventDefault();
if (history.pushState) { /* add hash to URL */
history.pushState(null, null, hash);
}
if (history.pushState) { /* add hash to URL */
history.pushState(null, null, hash);
}
let curOffset = $(this).offset().top;
let destOffset = target.offset().top;
const scrollUp = (destOffset < curOffset);
const topbarHeight = $("#topbar-wrapper").outerHeight();
let curOffset = $(window).scrollTop();
let destOffset = $target.offset().top -= REM / 2;
if (scrollUp && isFnRef) {
/* Avoid the top-bar covering `fnref` when scrolling up
because `fnref` has no `%anchor`(see: module.scss) style. */
destOffset -= (topbarHeight + REM / 2);
}
if (destOffset < curOffset) { // scroll up
ScrollHelper.hideTopbar();
ScrollHelper.addScrollUpTask();
$("html,body").animate({
scrollTop: destOffset
}, 800, () => {
if (isMobileViews && isPortrait) {
destOffset -= ScrollHelper.getTopbarHeight();
}
const $target = $(target);
$target.focus();
} else { // scroll down
if (isMobileViews && isPortrait) {
destOffset -= ScrollHelper.getTopbarHeight();
const SCROLL_MARK = "scroll-focus";
/* clean up old scroll mark */
if ($(`[${SCROLL_MARK}=true]`).length) {
$(`[${SCROLL_MARK}=true]`).attr(SCROLL_MARK, false);
}
/* Clean :target links */
if ($(":target").length) { /* element that visited by the URL with hash */
$(":target").attr(SCROLL_MARK, false);
}
/* set scroll mark to footnotes */
if (isFn || isFnRef) {
$target.attr(SCROLL_MARK, true);
}
if ($target.is(":focus")) { /* Checking if the target was focused */
return false;
} else {
$target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */
$target.focus(); /* Set focus again */
}
});
}
}
}
$("html").animate({
scrollTop: destOffset
}, 500, () => {
$target.focus();
/* clean up old scroll mark */
if ($(`[${ATTR_SCROLL_FOCUS}=true]`).length) {
$(`[${ATTR_SCROLL_FOCUS}=true]`).attr(ATTR_SCROLL_FOCUS, false);
}
/* Clean :target links */
if ($(":target").length) { /* element that visited by the URL with hash */
$(":target").attr(ATTR_SCROLL_FOCUS, false);
}
/* set scroll mark to footnotes */
if (toFootnote || toFootnoteRef) {
$target.attr(ATTR_SCROLL_FOCUS, true);
}
if ($target.is(":focus")) { /* Checking if the target was focused */
return false;
} else {
$target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */
$target.focus(); /* Set focus again */
}
if (ScrollHelper.hasScrollUpTask()) {
ScrollHelper.popScrollUpTask();
}
});
}); /* click() */
});

View File

@@ -1,87 +1,73 @@
/**
/*
* Calculate the Timeago
*
* Requirement: <https://github.com/iamkun/dayjs>
*/
$(function() {
const attrTimestamp = LocaleHelper.attrTimestamp();
const attrCapitalize = 'data-capitalize';
const $timeago = $(".timeago");
let timeagoTasks = $timeago.length;
const timeagoElem = $(".timeago");
let toRefresh = timeagoElem.length;
let intervalId = void 0;
dayjs.locale(LocaleHelper.locale());
dayjs.extend(window.dayjs_plugin_relativeTime);
dayjs.extend(window.dayjs_plugin_localizedFormat);
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 relativetime($elem) {
const now = dayjs();
const past = dayjs.unix(LocaleHelper.getTimestamp($elem));
function timeago(isoDate, dateStr) {
let now = new Date();
let past = new Date(isoDate);
let diffMonth = now.diff(past, 'month', true);
if (diffMonth > 10) { // year ago range: 11 months to 17months
$elem.removeAttr(attrTimestamp);
return past.format('ll'); // see: https://day.js.org/docs/en/display/format#list-of-localized-formats
if (past.getFullYear() !== now.getFullYear()
|| past.getMonth() !== now.getMonth()) {
return dateStr;
}
let diffMinute = now.diff(past, 'minute', true);
if (diffMinute > 44) { // an hour ago range: 45 to 89 minutes
$elem.removeAttr(attrTimestamp);
let seconds = Math.floor((now - past) / 1000);
let day = Math.floor(seconds / 86400);
if (day >= 1) {
toRefresh -= 1;
return ` ${day} ${dPrompt}`;
}
return past.fromNow();
let hour = Math.floor(seconds / 3600);
if (hour >= 1) {
return ` ${hour} ${hrPrompt}`;
}
let minute = Math.floor(seconds / 60);
if (minute >= 1) {
return ` ${minute} ${minPrompt}`;
}
return justnowPrompt;
}
function updateTimeago() {
$timeago.each(function() {
if (typeof $(this).attr(attrTimestamp) === 'undefined') {
timeagoTasks -= 1;
return;
}
let relativeTime = relativetime($(this));
const capitalize = $(this).attr(attrCapitalize);
if (typeof capitalize !== 'undefined' && capitalize === 'true') {
relativeTime = relativeTime.replace(/^\w/, (c) => c.toUpperCase());
}
if ($(this).text() !== relativeTime) {
$(this).text(relativeTime);
$(".timeago").each(function() {
if ($(this).children("i").length > 0) {
let dateStr = $(this).clone().children().remove().end().text();
let node = $(this).children("i");
let iosDate = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */
$(this).text(timeago(iosDate, dateStr));
$(this).append(node);
}
});
if (timeagoTasks === 0 && typeof intervalId !== "undefined") {
if (toRefresh === 0 && typeof intervalId !== "undefined") {
clearInterval(intervalId); /* stop interval */
}
return timeagoTasks;
return toRefresh;
}
function setupTooltips() {
$timeago.each(function() {
const tooltip = $(this).attr('data-toggle');
if (typeof tooltip === 'undefined' || tooltip !== 'tooltip') {
return;
}
const df = $(this).attr('data-tooltip-df');
const ts = LocaleHelper.getTimestamp($(this));
const dateStr = dayjs.unix(ts).format(df);
$(this).attr('data-original-title', dateStr);
$(this).removeAttr('data-tooltip-df');
});
}
if (timeagoTasks === 0) {
if (toRefresh === 0) {
return;
}
setupTooltips();
if (updateTimeago()) { /* run immediately */
intervalId = setInterval(updateTimeago, 60 * 1000); /* run every minute */
if (updateTimeago() > 0) { /* run immediately */
intervalId = setInterval(updateTimeago, 60000); /* run every minute */
}
});

View File

@@ -3,6 +3,8 @@ layout: page
# The Archives of posts.
---
{% include lang.html %}
<div id="archives" class="pl-xl-2">
{% for post in site.posts %}
@@ -16,11 +18,11 @@ layout: page
{% endif %}
<li>
<div>
{% assign ts = post.date | date: '%s' %}
<span class="date day" data-ts="{{ ts }}" data-df="DD">{{ post.date | date: "%d" }}</span>
<span class="date month small text-muted" data-ts="{{ ts }}" data-df="MMM">
{{ post.date | date: '%m' }}
</span>
{% capture this_day %}{{ post.date | date: "%d" }}{% 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">{% include no-zero-date.html date_str=this_month %}</span>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
</div>
</li>

View File

@@ -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_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" data-ts="{{ post.date | date: '%s' }}" data-df="ll">
{{ post.date | date: '%Y-%m-%d' }}
</span>
<span class="text-muted small">{{ post.date | date: post_df }}</span>
</li>
{% endfor %}
</ul>

View File

@@ -7,23 +7,17 @@ layout: compress
{% include lang.html %}
{% include assets-origin.html %}
{% capture prefer_mode %}
{% if site.theme_mode %}
data-mode="{{ site.theme_mode }}"
mode="{{ site.theme_mode }}"
{% endif %}
{% endcapture %}
<html lang="{{ site.lang }}"{{ prefer_mode }}>
<html lang="{{ site.lang }}" {{ prefer_mode }}>
{% include head.html %}
{% unless site.theme_mode %}
{% include mode-toggle.html %}
{% endunless %}
<body data-spy="scroll" data-target="#toc" data-topbar-visible="true">
<body data-spy="scroll" data-target="#toc">
{% include sidebar.html %}
@@ -32,7 +26,7 @@ layout: compress
<div id="main-wrapper">
<div id="main">
{{ content }}
{% include refactor-content.html content=content %}
{% include footer.html %}

View File

@@ -6,7 +6,7 @@ layout: page
{% include lang.html %}
{% assign pinned = site.posts | where: "pin", "true" %}
{% assign default = site.posts | where_exp: "item", "item.pin != true and item.hidden != true" %}
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
{% assign posts = "" | split: "" %}
@@ -53,30 +53,27 @@ layout: page
<div class="post-content">
<p>
{% include no-linenos.html content=post.content %}
{{ content | markdownify | strip_html | truncate: 200 | escape }}
{{ content | markdownify | strip_html | truncate: 200 }}
</p>
</div>
<div class="post-meta text-muted d-flex">
<div class="post-meta text-muted d-flex justify-content-between">
<div class="mr-auto">
<div>
<!-- posted date -->
<i class="far fa-calendar fa-fw"></i>
{% include timeago.html date=post.date tooltip=true capitalize=true %}
{% include timeago.html date=post.date tooltip=true %}
<!-- time to read -->
<i class="far fa-clock fa-fw"></i>
{% include read-time.html content=post.content %}
<!-- categories -->
{% if post.categories.size > 0 %}
<i class="far fa-folder-open fa-fw"></i>
<span>
{% for category in post.categories %}
{{ category }}
{%- unless forloop.last -%},{%- endunless -%}
{% endfor %}
</span>
<!-- page views -->
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<i class="far fa-eye fa-fw"></i>
<span id="pv_{{-post.title-}}" class="pageviews">
<i class="fas fa-spinner fa-spin fa-fw"></i>
</span>
{% endif %}
</div>

View File

@@ -1,66 +1,41 @@
---
layout: default
# The page layout
---
{% include lang.html %}
{% include assets-origin.html %}
<div class="row">
<!-- core -->
<div id="core-wrapper" class="col-12 col-lg-11 col-xl-8">
<div class="post pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% capture _content %}
{% if layout.refactor or page.layout == 'page' %}
{% include refactor-content.html content=content %}
{% else %}
{{ content }}
{% endif %}
{% endcapture %}
{% if page.layout == 'page' or page.collection == 'tabs'%}
{% assign title = site.data.locales[lang].tabs[tab_key] | default: page.title %}
<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">
{{ 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 }}
{{ content }}
</div>
{% else %}
{{ _content }}
{{ content }}
{% endif %}
</div> <!-- #page -->
</div><!-- .col-12 -->
</div>
</div> <!-- #core-wrapper -->
<!-- pannel -->
<div id="panel-wrapper" class="col-xl-3 pl-2 text-muted">
<div class="access">
{% include update-list.html %}
{% include trending-tags.html %}
</div>
{% for _include in layout.pannel_includes %}
{% assign _include_path = _include | append: '.html' %}
{% include {{ _include_path }} %}
{% endfor %}
</div>
{% include panel.html %}
</div>
<!-- tail -->
{% if layout.tail_includes %}
{% if site.disqus.comments and page.comments %}
<div class="row">
<div class="col-12 col-lg-11 col-xl-8">
<div id="tail-wrapper" class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% for _include in layout.tail_includes %}
{% assign _include_path = _include | append: '.html' %}
{% include {{ _include_path }} %}
{% endfor %}
</div>
</div>
<div class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% include disqus.html %}
</div> <!-- .pl-1 pr-1 -->
</div> <!-- .col-12 -->
</div> <!-- .row -->
{% endif %}

View File

@@ -1,144 +1,143 @@
---
layout: page
refactor: true
pannel_includes:
- toc
tail_includes:
- related-posts
- post-nav
- comments
layout: default
# The posts' layout
---
{% include lang.html %}
{% if page.image.src %}
{% capture bg %}
{% unless page.image.no_bg %}{{ 'bg' }}{% endunless %}
{% endcapture %}
<img src="{{ page.image.src }}" class="preview-img {{ bg | strip }}"
alt="{{ page.image.alt | default: "Preview Image" }}"
<div class="row">
{% if page.image.width %}
width="{{ page.image.width }}"
{% elsif page.image.w %}
width="{{ page.image.w }}"
{% endif %}
<div id="post-wrapper" class="col-12 col-lg-11 col-xl-8">
{% if page.image.height %}
height="{{ page.image.height }}"
{% elsif page.image.h %}
height="{{ page.image.h }}"
{% endif %}>
{% endif %}
<div class="post pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
<h1 data-toc-skip>{{ page.title }}</h1>
<h1 data-toc-skip>{{ page.title }}</h1>
<div class="post-meta text-muted">
<div class="post-meta text-muted d-flex flex-column">
<!-- Published date and author -->
<div>
<span class="semi-bold">
{{ page.author | default: site.social.name }}
</span>
{% capture _preposition %}{{ site.data.locales[lang].post.published }}{% endcapture %}
{% include timeago.html date=page.date tooltip=true preposition=_preposition %}
</div>
<!-- author -->
<div>
{% capture author_name %}{{ page.author.name | default: site.social.name }}{% endcapture %}
{% assign author_link = nil %}
<div>
<!-- lastmod -->
{% if page.last_modified_at %}
<span>
{{ site.data.locales[lang].post.updated }}
{% include timeago.html date=page.last_modified_at class="lastmod" tooltip=true %}
</span>
{% endif %}
{% if page.author.link %}
{% assign author_link = page.author.link %}
{% elsif author_name == site.social.name %}
{% assign author_link = site.social.links[0] %}
<!-- read time -->
{% 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>
{{ site.data.locales[lang].post.pageview_measure }}
{% endif %}
</div>
</div> <!-- .post-meta -->
<div class="post-content">
{% if page.image.src %}
<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 }}
</div>
<div class="post-tail-wrapper text-muted">
<!-- 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 %}
<a href='{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/'>{{ category }}</a>
{%- unless forloop.last -%}, {%- endunless -%}
{% endfor %}
</div>
{% endif %}
<!-- tags -->
{% if page.tags.size > 0 %}
<div class="post-tags">
<i class="fa fa-tags fa-fw mr-1"></i>
{% for tag in page.tags %}
<a href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
class="post-tag no-text-decoration" >
{{- tag -}}
</a>
{% endfor %}
</div>
{% endif %}
<div class="post-tail-bottom
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
<div class="license-wrapper">
{% 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 %}
</div><!-- .post-tail-bottom -->
</div><!-- div.post-tail -->
</div> <!-- .post -->
</div> <!-- #post-wrapper -->
{% assign enable_toc = false %}
{% if site.toc and page.toc %}
{% if content contains '<h2' or content contains '<h3' %}
{% assign enable_toc = true %}
{% endif %}
{% endif %}
{% include panel.html toc=enable_toc %}
</div> <!-- .row -->
<div class="row">
<div class="col-12 col-lg-11 col-xl-8">
<div id="post-extend-wrapper" class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% include related-posts.html %}
{% include post-nav.html %}
{% if site.disqus.comments and page.comments %}
{% include disqus.html %}
{% endif %}
{{ site.data.locales[lang].post.written_by }}
<em>
{% if author_link %}
<a href="{{ author_link }}">{{ author_name }}</a>
{% else %}
{{ author_name }}
{% endif %}
</em>
</div>
</div> <!-- #post-extend-wrapper -->
<div class="d-flex">
<div>
<!-- published date -->
<span>
{{ site.data.locales[lang].post.posted }}
{% include timeago.html date=page.date tooltip=true %}
</span>
</div> <!-- .col-* -->
<!-- lastmod date -->
{% if page.last_modified_at %}
<span>
{{ site.data.locales[lang].post.updated }}
{% include timeago.html date=page.last_modified_at tooltip=true %}
</span>
{% endif %}
<!-- read time -->
{% 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>
<em id="pv" class="pageviews">
<i class="fas fa-spinner fa-spin fa-fw"></i>
</em>
{{ site.data.locales[lang].post.pageview_measure }}
</span>
{% endif %}
</div>
</div> <!-- .d-flex -->
</div> <!-- .post-meta -->
<div class="post-content">
{{ content }}
</div>
<div class="post-tail-wrapper text-muted">
<!-- 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 %}
<a href='{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/'>{{ category }}</a>
{%- unless forloop.last -%}, {%- endunless -%}
{% endfor %}
</div>
{% endif %}
<!-- tags -->
{% if page.tags.size > 0 %}
<div class="post-tags">
<i class="fa fa-tags fa-fw mr-1"></i>
{% for tag in page.tags %}
<a href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
class="post-tag no-text-decoration" >
{{- tag -}}
</a>
{% endfor %}
</div>
{% endif %}
<div class="post-tail-bottom
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
<div class="license-wrapper">
{% 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 %}
</div><!-- .post-tail-bottom -->
</div><!-- div.post-tail-wrapper -->
</div> <!-- .row -->

View File

@@ -3,6 +3,8 @@ layout: page
# The layout for Tag page
---
{% include lang.html %}
<div id="page-tag">
<h1 class="pl-lg-2">
<i class="fa fa-tag fa-fw text-muted"></i>
@@ -10,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_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" data-ts="{{ post.date | date: '%s' }}" data-df="ll">
{{ post.date | date: '%Y-%m-%d' }}
</span>
<span class="text-muted small">{{ post.date | date: post_df }}</span>
</li>
{% endfor %}
</ul>

View File

@@ -1,8 +1,6 @@
---
title: Text and Typography
author:
name: Cotes Chung
link: https://github.com/cotes2020
author: Cotes Chung
date: 2019-08-08 11:33:00 +0800
categories: [Blogging, Demo]
tags: [typography]
@@ -54,8 +52,8 @@ Fluttering and dancing in the breeze.
### Unordered list
- Chapter
- Section
- Paragraph
- Section
- Paragraph
### Task list
@@ -74,23 +72,10 @@ Sun
Moon
: the natural satellite of the earth, visible by reflected light from the sun
## Block Quote
> This line shows the _block quote_.
## Prompts
> An example showing the `tip` type prompt.
{: .prompt-tip }
> An example showing the `info` type prompt.
{: .prompt-info }
> An example showing the `warning` type prompt.
{: .prompt-warning }
> An example showing the `danger` type prompt.
{: .prompt-danger }
> This line to shows the Block Quote.
## Tables
@@ -104,10 +89,12 @@ Moon
<http://127.0.0.1:4000>
## Footnote
Click the hook will locate the footnote[^footnote], and here is another footnote[^fn-nth-2].
## Images
- Default (with caption)
@@ -154,6 +141,7 @@ _shadow effect (visible in light mode)_
cherry :active, c, after b a, 1d
```
## Mathematics
The mathematics powered by [**MathJax**](https://www.mathjax.org/):
@@ -164,13 +152,11 @@ When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
## Inline code
This is an example of `Inline Code`.
## Filepath
Here is the `/path/to/the/file.extend`{: .filepath}.
## Code block

View File

@@ -1,19 +1,15 @@
---
title: Writing a New Post
author:
name: Cotes Chung
link: https://github.com/cotes2020
author: Cotes Chung
date: 2019-08-08 14:10:00 +0800
categories: [Blogging, Tutorial]
tags: [writing]
render_with_liquid: false
---
This post will guide you how to write a post on _Chirpy_ theme. Even if you have previous experience with Jekyll, this article is worth reading, because many features require specific variables to be set.
## Naming and Path
Create a new file named `YYYY-MM-DD-TITLE.EXTENSION`{: .filepath} and put it in the `_posts`{: .filepath} of the root directory. Please note that the `EXTENSION`{: .filepath} must be one of `md`{: .filepath} and `markdown`{: .filepath}. If you want to save time of creating files, please consider using the plugin [`Jekyll-Compose`](https://github.com/jekyll/jekyll-compose) to accomplish this.
Create a new file named `YYYY-MM-DD-TITLE.EXTENSION` and put it in the `_posts/` of the root directory. Please note that the `EXTENSION` must be one of `md` and `markdown`.
## Front Matter
@@ -28,39 +24,24 @@ tags: [TAG] # TAG names should always be lowercase
---
```
> The posts' _layout_ has been set to `post` by default, so there is no need to add the variable _layout_ in the Front Matter block.
{: .prompt-tip }
> **Note**: The posts' ***layout*** has been set to `post` by default, so there is no need to add the variable ***layout*** in the Front Matter block.
### Timezone of Date
### Timezone of date
In order to accurately record the release date of a post, you should not only set up the `timezone` of `_config.yml`{: .filepath} but also provide the post's timezone in variable `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
In order to accurately record the release date of a post, you should not only set up the `timezone` of `_config.yml` but also provide the post's timezone in variable `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
### Categories and Tags
The `categories` of each post are designed to contain up to two elements, and the number of elements in `tags` can be zero to infinity. For instance:
```yaml
---
categories: [Animal, Insect]
tags: [bee]
---
```
### Author Information
The author information of the post usually does not need to be filled in the _Front Matter_ , they will be obtained from variables `social.name` and the first entry of `social.links` of the configuration file by default. But you can also override it as follows:
```yaml
---
author:
name: Full Name
link: https://example.com
---
```
## Table of Contents
By default, the **T**able **o**f **C**ontents (TOC) is displayed on the right panel of the post. If you want to turn it off globally, go to `_config.yml`{: .filepath} and set the value of variable `toc` to `false`. If you want to turn off TOC for a specific post, add the following to the post's [Front Matter](https://jekyllrb.com/docs/front-matter/):
By default, the **T**able **o**f **C**ontents (TOC) is displayed on the right panel of the post. If you want to turn it off globally, go to `_config.yml` and set the value of variable `toc` to `false`. If you want to turn off TOC for a specific post, add the following to the post's [Front Matter](https://jekyllrb.com/docs/front-matter/):
```yaml
---
@@ -70,9 +51,7 @@ toc: false
## Comments
The global switch of comments is defined by variable `comments.active` in the file `_config.yml`{: .filepath}. After selecting a comment system for this variable, comments will be turned on for all posts.
If you want to close the comment for a specific post, add the following to the **Front Matter** of the post:
Similar to TOC, the [Disqus](https://disqus.com/) comments are loaded by default in each post, and the global switch is defined by variable `comments` in file `_config.yml` . If you want to close the comment for a specific post, add the following to the **Front Matter** of the post:
```yaml
---
@@ -104,7 +83,24 @@ Then you can use it like other markdown languages: surround the graph code with
## Images
### Caption
### Preview 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 imagethen it will become the caption and appear at the bottom of the image:
@@ -114,7 +110,7 @@ _Image Caption_
```
{: .nolineno}
### Size
### Image size
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:
@@ -123,19 +119,9 @@ In order to prevent the page content layout from shifting when the image is load
```
{: .nolineno}
Starting from _Chirpy v5.0.0_, `height` and `width` support abbreviations (`height` → `h`, `width` → `w`). The following example has the same effect as the above:
### Image position
```markdown
![Desktop View](/assets/img/sample/mockup.png){: w="700" h="400" }
```
{: .nolineno}
### Position
By default, the image is centered, but you can specify the position by using one of the classes `normal`, `left`, and `right`.
> Once the position is specified, the image caption should not be added.
{: .prompt-warning }
By default, the image is centered, but you can specify the position by using one of the classes `normal`, `left`, and `right`. For example:
- **Normal position**
@@ -160,7 +146,9 @@ By default, the image is centered, but you can specify the position by using one
```
{: .nolineno}
### Shadow
> **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:
@@ -171,7 +159,7 @@ The screenshots of the program window can be considered to show the shadow effec
### CDN URL
If you host the images on the CDN, you can save the time of repeatedly writing the CDN URL by assigning the variable `img_cdn` of `_config.yml`{: .filepath} file:
If you host the images on the CDN, you can save the time of repeatedly writing the CDN URL by assigning the variable `img_cdn` of `_config.yml` file:
```yaml
img_cdn: https://cdn.com
@@ -194,49 +182,6 @@ The parsing result will automatically add the CDN prefix `https://cdn.com` befor
```
{: .nolineno}
### Image Path
When a post contains many images, it will be a time-consuming task to repeatedly define the path of the images. To solve this, we can define this path in the YAML block of the post:
```yml
---
img_path: /img/path/
---
```
{: .nolineno }
And then, the image source of Markdown can write the file name directly:
```md
![The flower](flower.png)
```
{: .nolineno }
The output will be:
```html
<img src="/img/path/flower.png" alt="The flower">
```
{: .nolineno }
### Preview 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. The above section "[Size](#size)" also mentions this.
Starting from _Chirpy v5.0.0_, the attributes `height` and `width` can be abbreviated: `height` → `h`, `width` → `w`. In addition, the [`img_path`](#image-path) can also be passed to the preview image, that is, when it has been set, the attribute `src` only needs the image file name.
## Pinned Posts
You can pin one or more posts to the top of the home page, and the fixed posts are sorted in reverse order according to their release date. Enable by:
@@ -247,43 +192,15 @@ pin: true
---
```
## Prompts
There are several types of prompts: `tip`, `info`, `warning`, and `danger`. They can be generated by adding the class `prompt-{type}` to the blockquote. For example, define a prompt of type `info` as follows:
```md
> Example line for prompt.
{: .prompt-info }
```
{: .nolineno }
## Syntax
### Inline Code
```md
`inline code part`
```
{: .nolineno }
### Filepath Hightlight
```md
`/path/to/a/file.extend`{: .filepath}
```
{: .nolineno }
### Code Block
## Code Block
Markdown symbols ```` ``` ```` can easily create a code block as follows:
````md
```
This is a plaintext code snippet.
```
````
#### Specifying Language
### Specifying Language
Using ```` ```{language} ```` you will get a code block with syntax highlight:
@@ -293,23 +210,22 @@ key: value
```
````
> The Jekyll tag `{% highlight %}` is not compatible with this theme.
{: .prompt-danger }
> **Limitation**: The Jekyll style `highlight` tag is not compatible with this theme.
#### Line Number
### Line Number
By default, all languages except `plaintext`, `console`, and `terminal` will display line numbers. When you want to hide the line number of a code block, add the class `nolineno` to it:
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 }
{: .nolineno}
````
#### Specifying the Filename
### Specifying the Filename
You may have noticed that the code language will be displayed at the top of the code block. If you want to replace it with the file name, you can add the attribute `file` to achieve this:
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
@@ -318,7 +234,7 @@ You may have noticed that the code language will be displayed at the top of the
{: file="path/to/file" }
````
#### Liquid Codes
### Liquid Codes
If you want to display the **Liquid** snippet, surround the liquid code with `{% raw %}` and `{% endraw %}`:
@@ -337,3 +253,4 @@ Or adding `render_with_liquid: false` (Requires Jekyll 4.0 or higher) to the pos
## Learn More
For more knowledge about Jekyll posts, visit the [Jekyll Docs: Posts](https://jekyllrb.com/docs/posts/).

View File

@@ -1,8 +1,6 @@
---
title: Getting Started
author:
name: Cotes Chung
link: https://github.com/cotes2020
author: Cotes Chung
date: 2019-08-09 20:55:00 +0800
categories: [Blogging, Tutorial]
tags: [getting started]
@@ -11,7 +9,7 @@ pin: true
## Prerequisites
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`. In addition, [Git](https://git-scm.com/) is also required to be installed.
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`.
## Installation
@@ -36,18 +34,18 @@ And then execute:
$ bash tools/init.sh
```
> If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
{: .prompt-info }
> **Note**: If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
The above command will:
1. Removes some files or directories from your repository:
- `.travis.yml`{: .filepath}
- files under `_posts`{: .filepath}
- `.travis.yml`
- files under `_posts`
- folder `docs`
2. If the option `--no-gh` is provided, the directory `.github`{: .filepath} will be deleted. Otherwise, set up the GitHub Action workflow by removing the extension `.hook`{: .filepath} of `.github/workflows/pages-deploy.yml.hook`{: .filepath}, and then remove the other files and directories in the folder `.github`{: .filepath}.
2. If the option `--no-gh` is provided, the directory `.github` will be deleted. Otherwise, set up 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. Removes item `Gemfile.lock` from `.gitignore`{: .filepath}.
3. Removes item `Gemfile.lock` from `.gitignore`.
4. Creates a new commit to save the changes automatically.
@@ -63,7 +61,7 @@ $ bundle
### Configuration
Update the variables of `_config.yml`{: .filepath} as needed. Some of them are typical options:
Update the variables of `_config.yml` as needed. Some of them are typical options:
- `url`
- `avatar`
@@ -72,15 +70,9 @@ Update the variables of `_config.yml`{: .filepath} as needed. Some of them are t
### Customing Stylesheet
If you need to customize the stylesheet, copy the theme's `assets/css/style.scss`{: .filepath} to the same path on your Jekyll site, and then add the custom style at the end of the style file.
If you need to customize the 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`{: .filepath}, create a new file `_sass/variables-hook.scss`{: .filepath} and assign new values to the target variable in it.
### Customing Static Assets
Static assets configuration was introduced in version `5.1.0`. The CDN of the static assets is defined by file `_data/assets/cross_origin.yml`{: .filepath }, and you can replace some of them according to the network conditions in the region where your website is published.
Also, if you'd like to self-host the static assets, please refer to the [_chirpy-static-assets_](https://github.com/cotes2020/chirpy-static-assets#readme).
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
@@ -101,23 +93,23 @@ $ docker run -it --rm \
After a while, the local service will be published at _<http://127.0.0.1:4000>_.
## Deployment
### Deployment
Before the deployment begins, check out the file `_config.yml`{: .filepath} and make sure the `url` is configured correctly. Furthermore, if you prefer the [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to change the `baseurl` to your project name that starts with a slash, e.g, `/project-name`.
Before the deployment begins, check out the file `_config.yml` and make sure the `url` is configured correctly. Furthermore, if you prefer the [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to change the `baseurl` to your project name that starts with a slash, e.g, `/project-name`.
Now you can choose ONE of the following methods to deploy your Jekyll site.
### Deploy by Using Github Actions
#### 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 GitHub Pages service.
Quickly check the files needed for GitHub Actions build:
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`{: .filepath}. 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.
- 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.
- Ensure your Jekyll site has file `tools/deploy.sh`{: .filepath}. Otherwise, copy it from here to your Jekyll site.
- 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`{: .filepath} to the repo, and your runtime system is not Linux, don't forget to update the platform list in the lock file:
- 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 lock file:
```console
$ bundle lock --add-platform x86_64-linux
@@ -131,11 +123,11 @@ Now publish your Jekyll site by:
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.
![gh-pages-sources](/posts/20190809/gh-pages-sources.png){: width="1580" height="250" }
![gh-pages-sources](/posts/20190809/gh-pages-sources.png){: width="850" height="153" }
3. Visit your website at the address indicated by GitHub.
### Manually Build and Deploy
#### Manually Build and Deploy
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.
@@ -155,29 +147,29 @@ $ docker run -it --rm \
jekyll build
```
Unless you specified the output path, the generated site files will be placed in folder `_site`{: .filepath} of the project's root directory. Now you should upload those files to the target 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
### 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`{: .filepath}), editing the `Gemfile`{: .filepath} and update the version number of the theme gem, for example:
- 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 theme gem, for example:
```diff
```diff
- gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1"
+ gem "jekyll-theme-chirpy", "~> 3.3", ">= 3.3.0"
```
{: .nolineno file="Gemfile" }
```
{: .nolineno file="Gemfile" }
And then execute the following command:
And then execute the following command:
```console
```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.
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`{: .filepath} of your site), then merge the [latest upstream tags][latest-tag] into your Jekyll site to complete the upgrade.
- 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

View File

@@ -1,14 +1,12 @@
---
title: Customize the Favicon
author:
name: Cotes Chung
link: https://github.com/cotes2020
author: Cotes Chung
date: 2019-08-11 00:34:00 +0800
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/`{: .filepath}. You may want to replace them with your own. The following sections will guide you 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 to create and replace the default favicons.
## Generate the favicon
@@ -20,10 +18,10 @@ In the next step, the webpage will show all usage scenarios. You can keep the de
Download the generated package, unzip and delete the following two from the extracted files:
- `browserconfig.xml`{: .filepath}
- `site.webmanifest`{: .filepath}
- `browserconfig.xml`
- `site.webmanifest`
And then copy the remaining image files (`.PNG`{: .filepath} and `.ICO`{: .filepath}) to cover the original files in the directory `assets/img/favicons/`{: .filepath} of your Jekyll site. If your Jekyll site doesn't have this directory yet, just create one.
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 help you understand the changes to the favicon files:
@@ -31,8 +29,9 @@ The following table will help you understand the changes to the favicon files:
|---------------------|:---------------------------------:|:-----------:|
| `*.PNG` | ✓ | ✗ |
| `*.ICO` | ✓ | ✗ |
| `browserconfig.xml` | ✗ | ✓ |
| `site.webmanifest` | ✗ | ✓ |
> ✓ means keep, ✗ means delete.
{: .prompt-info }
> Note: ✓ means keep, ✗ means delete.
The next time you build the site, the favicon will be replaced with a customized edition.

View File

@@ -1,8 +1,6 @@
---
title: Enable Google Page Views
author:
name: Dinesh Prasanth Moluguwan Krishnamoorthy
link: https://github.com/SilleBille
author: Dinesh Prasanth Moluguwan Krishnamoorthy
date: 2021-01-03 18:32:00 -0500
categories: [Blogging, Tutorial]
tags: [google analytics, pageviews]
@@ -37,7 +35,7 @@ It should look like this:
![google-analytics-data-stream](/posts/20210103/01-google-analytics-data-stream.png){: 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`{: .filepath} file:
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
```yaml
google_analytics:
@@ -115,16 +113,15 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
1. Clone the **Google Analytics superProxy** project on Github: <https://github.com/googleanalytics/google-analytics-super-proxy> to your local.
2. Remove the first 2 lines in the [`src/app.yaml`{: .filepath}](https://github.com/googleanalytics/google-analytics-super-proxy/blob/master/src/app.yaml#L1-L2) file:
2. Remove the first 2 lines in the [`src/app.yaml`](https://github.com/googleanalytics/google-analytics-super-proxy/blob/master/src/app.yaml#L1-L2) file:
```diff
- application: your-project-id
- version: 1
```
```diff
- application: your-project-id
- version: 1
```
3. In `src/config.py`, add the `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` that you gathered from your App Engine Dashboard.
3. In `src/config.py`{: .filepath}, add the `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` that you gathered from your App Engine Dashboard.
4. Enter any random key for `XSRF_KEY`, your `config.py`{: .filepath} should look similar to this
4. Enter any random key for `XSRF_KEY`, your `config.py` should look similar to this
```python
#!/usr/bin/python2.7
@@ -146,11 +143,9 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
```
{: file="src/config.py"}
> 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.
{: .prompt-info }
**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.
5. From inside the `src/`{: .filepath} directory, deploy the app
5. From inside the src/ directory, deploy the app
```console
[root@bc96abf71ef8 src]# gcloud app deploy
@@ -207,9 +202,9 @@ In order to reduce the returned results and reduce the network bandwidth, we add
- **filters**: fill in `ga:pagePath=~^/posts/.*/$;ga:pagePath!@=`.
Among them, `;` means using _logical AND_ to concatenate two rules.
Among them, `;` means using _logical AND_ to concatenate two rules.
If the `site.baseurl` is specified, change the first filtering rule to `ga:pagePath=~^/BASE_URL/posts/.*/$`, where `BASE_URL` is the value of `site.baseurl`.
If the `site.baseurl` is specified, change the first filtering rule to `ga:pagePath=~^/BASE_URL/posts/.*/$`, where `BASE_URL` is the value of `site.baseurl`.
After <kbd>Run Query</kbd>, copy the generated contents of **API Query URI** at the bottom of the page and fill in the **Encoded URI for the query** of SuperProxy on GAE.
@@ -217,13 +212,14 @@ After the query is saved on GAE, a **Public Endpoint** (public access address) w
![superproxy-query](/posts/20210103/04-superproxy-query.png){: 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.
![superproxy-dashboard](/posts/20210103/05-superproxy-dashboard.png){: width="1210" height="694"}
Update the `_config.yml`{: .filepath} file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:
Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:
```yaml
google_analytics:

File diff suppressed because it is too large Load Diff

View File

@@ -10,39 +10,6 @@
font-family: 'Lato', 'Microsoft Yahei', sans-serif;
}
%section {
#core-wrapper & {
margin-top: 2.5rem;
margin-bottom: 1.25rem;
&:focus {
outline: none; /* avoid outline in Safari */
}
}
}
%anchor {
.anchor {
font-size: 80%;
}
@media (hover: hover) {
.anchor {
visibility: hidden;
opacity: 0;
transition: opacity 0.25s ease-in, visibility 0s ease-in 0.25s;
}
&:hover {
.anchor {
visibility: visible;
opacity: 1;
transition: opacity 0.25s ease-in, visibility 0s ease-in 0s;
}
}
}
}
%tag-hover {
background: var(--tag-hover);
transition: background 0.35s ease-in-out;
@@ -72,31 +39,30 @@
transition: color 0.35s ease-in-out;
}
%no-cursor {
user-select: none;
}
%no-bottom-border {
border-bottom: none;
}
%section {
#post-wrapper & {
line-height: 1.2;
margin-bottom: 1rem;
}
}
%anchor {
padding-top: 3.5rem;
margin-top: -2.5rem;
}
%cursor-pointer {
cursor: pointer;
}
%normal-font-style {
font-style: normal;
}
/* ---------- scss mixin --------- */
%img-caption {
+ em {
display: block;
text-align: center;
font-style: normal;
font-size: 80%;
padding: 0;
color: #6d6c6c;
}
@mixin no-text-decoration {
text-decoration: none;
}
%sidebar-links {
@@ -104,12 +70,6 @@
user-select: none;
}
/* ---------- scss mixin --------- */
@mixin no-text-decoration {
text-decoration: none;
}
@mixin ml-mr($value) {
margin-left: $value;
margin-right: $value;
@@ -124,12 +84,28 @@
opacity: 0.6;
}
@mixin semi-bold {
font-weight: 600;
}
@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) {
color: $color;
font-size: $font-size;
font-weight: $font-weight;
}
@mixin panel-label {
@include label(inherit);
display: block;
line-height: 1.2;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin-top: 0;
margin-bottom: 0;
letter-spacing: -0.02em;
}
@mixin align-center {
position: relative;
left: 50%;
@@ -137,15 +113,3 @@
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
@mixin prompt($type, $fw-icon, $icon-weight: 900) {
&.prompt-#{$type} {
background-color: var(--prompt-#{$type}-bg);
&::before {
content: $fw-icon;
color: var(--prompt-#{$type}-icon-color);
font-weight: $icon-weight;
}
}
}

View File

@@ -5,27 +5,23 @@
@import "colors/light-syntax";
@import "colors/dark-syntax";
html {
@media (prefers-color-scheme: light) {
&:not([data-mode]),
[data-mode=light] {
@include light-syntax;
}
html:not([mode]),
html[mode=light] {
@include light-syntax;
}
&[data-mode=dark] {
@include dark-syntax;
}
html[mode=dark] {
@include dark-syntax;
}
@media (prefers-color-scheme: dark) {
html:not([mode]),
html[mode=dark] {
@include dark-syntax;
}
@media (prefers-color-scheme: dark) {
&:not([data-mode]),
&[data-mode=dark] {
@include dark-syntax;
}
&[data-mode=light] {
@include light-syntax;
}
html[mode=light] {
@include light-syntax;
}
}
@@ -42,8 +38,13 @@ $code-radius: 6px;
}
%code-snippet-padding {
padding-left: 1rem;
padding-right: 1.5rem;
padding: 1.2rem;
}
div > pre {
@extend %code-snippet-bg;
@extend %code-snippet-radius;
@extend %code-snippet-padding;
}
.highlighter-rouge {
@@ -64,8 +65,6 @@ $code-radius: 6px;
}
overflow: auto;
padding-top: 0.5rem;
padding-bottom: 1rem;
pre {
margin-bottom: 0;
@@ -75,12 +74,19 @@ $code-radius: 6px;
}
table {
padding: 0;
border: 0;
td pre {
overflow: visible; /* Fixed iOS safari overflow-x */
word-break: normal; /* Fixed iOS safari linenos code break */
}
}
td {
padding: 0;
border: 0;
}
.lineno {
padding-right: 0.5rem;
min-width: 2.2rem;
@@ -99,7 +105,7 @@ $code-radius: 6px;
user-select: none;
}
} /* .highlight */
} //.highlight
code {
-webkit-hyphens: none;
@@ -114,38 +120,25 @@ code {
background-color: var(--inline-code-bg);
}
&.filepath {
background-color: inherit;
color: var(--filepath-text-color);
font-weight: 600;
padding: 0;
}
a > &.highlighter-rouge {
padding-bottom: 0; /* show link's underlinke */
@at-root a > &.highlighter-rouge {
padding-bottom: 0; // show link's underlinke
color: inherit;
}
a:hover > &.highlighter-rouge {
@at-root a:hover > &.highlighter-rouge {
border-bottom: none;
}
blockquote & {
blockquote &.highlighter-rouge {
color: inherit;
}
.highlight > & {
color: transparent;
}
}
td.rouge-code {
@extend %code-snippet-padding;
padding: 1.2rem 1.5rem 1.2rem 1rem;
/*
Prevent some browser extends from
changing the URL string of code block.
*/
// Prevent some browser extends from
// changing the URL string of code block.
a {
color: inherit !important;
border-bottom: none !important;
@@ -164,82 +157,63 @@ div {
pre.lineno {
display: none;
}
td.rouge-code {
padding-left: 1.5rem;
@extend %code-snippet-padding;
}
}
}
.code-header {
@extend %no-cursor;
$code-header-height: 2.25rem;
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;
height: $code-header-height;
line-height: 1.85rem;
&::before {
$dot-size: 0.75rem;
$dot-margin: 0.5rem;
// icons
i {
font-size: 1rem;
color: var(--lang-badge-muted-color);
content: "";
display: inline-block;
margin-left: 1rem;
width: $dot-size;
height: $dot-size;
border-radius: 50%;
background-color: var(--code-header-muted-color);
box-shadow:
($dot-size + $dot-margin) 0 0 var(--code-header-muted-color),
($dot-size + $dot-margin) * 2 0 0 var(--code-header-muted-color);
&.small {
font-size: 70%;
}
}
/* the label block */
// the label block
span {
/* label icon */
i {
font-size: 1rem;
margin-right: 0.4rem;
color: var(--code-header-icon-color);
padding-left: 0.35rem;
&.small {
font-size: 70%;
}
&::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 */
top: 1px; // center the file icon
margin-left: 0.25rem;
}
/* label text */
&::after {
content: attr(data-label-text);
font-size: 0.85rem;
font-weight: 600;
color: var(--code-header-text-color);
}
}
/* clipboard */
// clipboard
button {
@extend %cursor-pointer;
border: 1px solid transparent;
border: 1px solid var(--code-header-bg);
border-radius: $code-radius;
height: $code-header-height;
width: $code-header-height;
padding: 0;
width: 1.95rem;
background-color: inherit;
i {
color: var(--code-header-icon-color);
}
@extend %cursor-pointer;
&[timeout] {
&:hover {

View File

@@ -4,30 +4,30 @@
/* sidebar */
$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: 260px !default; // the basic width
$sidebar-width-small: 210px !default; // screen width: >= 850px, <= 1199px (iPad landscape)
$sidebar-width-large: 350px !default; // screen width: >= 1650px
/* tabs of sidebar */
$tab-count: 5 !default; /* backward compatible (version <= 4.0.2) */
$tab-count: 5 !default; // backward compatible (version <= 4.0.2)
$tab-height: 3rem !default;
$tab-cursor-height: 1.6rem !default;
$cursor-width: 2px !default; /* the cursor width of the selected tab */
$cursor-width: 2px !default; // the cursor width of the selected tab
/* other framework sizes */
$topbar-height: 3rem !default;
$footer-height: 5rem !default;
$footer-height-mobile: 6rem !default; /* screen width: <= 576px */
$footer-height-mobile: 6rem !default; // screen width: <= 576px
$main-content-max-width: 1150px !default;
$panel-max-width: 300px !default;
$bottom-min-height: 35rem !default;
$post-extend-min-height: 35rem !default;
/* syntax highlight */

View File

@@ -74,15 +74,15 @@
--highlighter-rouge-color: #de6b18;
--highlight-lineno-color: #6c6c6d;
--inline-code-bg: #272822;
--code-header-text-color: #6a6a6a;
--code-header-muted-color: rgb(60 60 60);
--code-header-icon-color: rgb(86 86 86);
--code-header-bg: #353535;
--lang-badge-color: #858586;
--lang-badge-muted-color: #6c6c6d;
--clipboard-checked-color: #2bcc2b;
--filepath-text-color: #bdbdbd;
.highlight {
.gp { color: #818c96; }
}
pre { color: #bfbfbf; } /* override Bootstrap */
kbd { background-color: black; }
}

View File

@@ -8,6 +8,8 @@
--mask-bg: rgb(68, 69, 70);
--main-wrapper-bg: rgb(27, 27, 30);
--main-border-color: rgb(44, 45, 45);
--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);
@@ -65,19 +67,6 @@
--card-bg: rgb(39, 40, 43);
--card-border-color: rgb(53, 53, 60);
--card-box-shadow: var(--main-wrapper-bg);
--preview-img-bg: radial-gradient(circle, rgb(22 22 24) 0%, rgb(32 32 32) 100%);
--kbd-wrap-color: #6a6a6a;
--kbd-text-color: #d3d3d3;
--kbd-bg-color: #242424;
--prompt-text-color: rgb(216 212 212 / 75%);
--prompt-tip-bg: rgba(77, 187, 95, 0.2);
--prompt-tip-icon-color: rgb(5 223 5 / 68%);
--prompt-info-bg: rgb(7 59 104 / 80%);
--prompt-info-icon-color: #0075d1;
--prompt-warning-bg: rgb(90 69 3 / 95%);
--prompt-warning-icon-color: rgb(255 165 0 / 80%);
--prompt-danger-bg: rgb(86 28 8 / 80%);
--prompt-danger-icon-color: #cd0202;
/* tags */
--tag-border: rgb(59, 79, 88);
@@ -95,8 +84,12 @@
--timeline-color: rgb(63, 65, 68);
--timeline-year-dot-color: var(--timeline-color);
.post img[data-src] {
filter: brightness(95%);
/* Footer */
--footer-bg-color: var(--main-wrapper-bg);
--footer-link: rgb(171, 171, 171);
.post-content img {
filter: brightness(90%);
}
hr {
@@ -123,13 +116,11 @@
.card-header {
background-color: var(--card-header-bg);
}
.list-group-item {
border-left: none;
border-right: none;
padding-left: 2rem;
border-color: var(--categories-border);
&:last-child {
border-bottom-color: var(--card-bg);
}
@@ -137,21 +128,13 @@
}
#archives li:nth-child(odd) {
background-image:
linear-gradient(
to left,
rgb(26, 26, 30),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(26, 26, 30)
);
background-image: linear-gradient(
to left,
rgb(26, 26, 30),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(26, 26, 30));
}
color-scheme: dark;
#disqus_thread {
color-scheme: none;
}
} /* dark-scheme */
} // dark-scheme

View File

@@ -71,14 +71,9 @@
--highlighter-rouge-color: #2f2f2f;
--highlight-lineno-color: #c2c6cc;
--inline-code-bg: #f3f3f3;
--code-header-text-color: #a3a3b1;
--code-header-muted-color: #ebebeb;
--code-header-icon-color: #d1d1d1;
--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;
[class^=prompt-] {
--inline-code-bg: #fbfafa;
--highlighter-rouge-color: rgb(82 82 82);
}
} /* light-syntax */
} // light-syntax

View File

@@ -8,6 +8,8 @@
--mask-bg: #c1c3c5;
--main-wrapper-bg: white;
--main-border-color: #f3f3f3;
--scrollbar-track-bg: rgba(0, 0, 0, 0.3);
--scrollbar-thumb-bg: rgba(0, 0, 0, 0.3);
/* Common color */
--text-color: #34343c;
@@ -64,23 +66,6 @@
--tb-odd-bg: #fbfcfd;
--tb-border-color: #eaeaea;
--dash-color: silver;
--preview-img-bg: radial-gradient(circle, rgb(255 255 255) 0%, rgb(249 249 249) 100%);
--kbd-wrap-color: #bdbdbd;
--kbd-text-color: var(--text-color);
--kbd-bg-color: white;
--prompt-text-color: rgb(46 46 46 / 77%);
--prompt-tip-bg: rgb(123 247 144 / 20%);
--prompt-tip-icon-color: #03b303;
--prompt-info-bg: #e1f5fe;
--prompt-info-icon-color: #0070cb;
--prompt-warning-bg: rgb(255 243 205);
--prompt-warning-icon-color: #ef9c03;
--prompt-danger-bg: rgb(248 215 218 / 56%);
--prompt-danger-icon-color: #df3c30;
[class^=prompt-] {
--link-underline-color: rgb(219 216 216);
}
/* Categories */
--categories-hover-bg: var(--btn-border-color);
@@ -91,4 +76,7 @@
--timeline-node-bg: #c2c6cc;
--timeline-year-dot-color: #ffffff;
} /* light-scheme */
/* Footer */
--footer-bg-color: #ffffff;
--footer-link: #424242;
} // light-scheme

View File

@@ -1,7 +1,7 @@
/*!
* The styles for Jekyll theme Chirpy
*
* Chirpy v5.1.0 (https://github.com/cotes2020/jekyll-theme-chirpy)
* Chirpy v4.3.3 (https://github.com/cotes2020/jekyll-theme-chirpy)
* © 2019 Cotes Chung
* MIT Licensed
*/

View File

@@ -41,7 +41,6 @@
&:not(:first-child) {
position: relative;
left: 4px;
&::after {
left: 67px;
}
@@ -99,7 +98,6 @@
.date {
white-space: nowrap;
display: inline-block;
&.month {
width: 1.4rem;
text-align: center;
@@ -122,7 +120,6 @@
z-index: 1;
}
}
&.day {
font-size: 85%;
font-family: 'Lato', sans-serif;
@@ -130,7 +127,7 @@
margin-right: -2px;
width: 1.2rem;
position: relative;
left: -0.15rem;
left: -.15rem;
}
} // #archives .date
@@ -139,7 +136,6 @@
@media all and (max-width: 576px) {
#archives {
margin-top: -1rem;
ul {
letter-spacing: 0;
}

View File

@@ -3,7 +3,7 @@
*/
.dash {
margin: 0 0.5rem 0.6rem 0.5rem;
margin: 0 .5rem .6rem .5rem;
border-bottom: 2px dotted var(--dash-color);
}
@@ -60,9 +60,8 @@
#page-tag {
ul > li {
&::before {
margin: 0 0.5rem;
margin: 0 .5rem;
}
> a {
white-space: nowrap;
overflow: hidden;

View File

@@ -22,29 +22,24 @@
border-radius: 50%;
border: 1px solid var(--btn-paginator-border-color);
background-color: var(--button-bg);
&:hover {
background-color: var(--btn-paginator-hover-color);
}
}
&.active {
.page-link {
background-color: var(--btn-paginator-hover-color);
color: var(--btn-text-color);
}
}
&.disabled {
cursor: not-allowed;
.page-link {
color: rgba(108, 117, 125, 0.57);
border-color: var(--btn-paginator-border-color);
background-color: var(--button-bg);
}
}
&:first-child .page-link,
&:last-child .page-link {
border-radius: 50%;
@@ -74,14 +69,9 @@
.post-meta {
i {
font-size: 0.73rem;
&:not(:first-child) {
margin-left: 1.2rem;
}
}
em {
@extend %normal-font-style;
span:not(:last-child) {
margin-right: 1.2rem;
}
}
@@ -89,7 +79,6 @@
margin-top: 0.6rem;
margin-bottom: 0.6rem;
color: var(--post-list-text-color);
> p {
/* Make preview shorter on the homepage */
margin: 0;
@@ -107,13 +96,13 @@
padding-left: 3px;
color: var(--pin-color);
}
> span {
display: none;
}
}
} // .post-preview
} // #post-list
/* Hide SideBar and TOC */
@@ -133,9 +122,9 @@
/* Sidebar is visible */
@media all and (min-width: 831px) {
#post-list {
margin-top: 1.5rem;
.post-preview .post-meta {
.pin {
background: var(--pin-bg);

View File

@@ -16,37 +16,27 @@
border-color: var(--btn-border-color);
}
@mixin dot($pl: 0.25rem, $pr: 0.25rem) {
@mixin dot($pl: 0.2rem, $pr: 0.4rem) {
content: "\2022";
color: rgba(158, 158, 158, 0.8);
padding-left: $pl;
padding-right: $pr;
}
%text-color {
color: var(--text-color);
}
h1 + .post-meta {
span + span::before {
@include dot;
}
em {
@extend %text-color;
a {
@extend %text-color;
#post-wrapper .post-meta {
> div:nth-child(2) {
> span:not(:first-child)::before {
@include dot;
}
}
}
img.preview-img {
margin-top: 3.75rem;
margin-bottom: 0;
border-radius: 6px;
.post-content {
.preview-img {
@include align-center;
&.bg[data-loaded=true] {
background: var(--preview-img-bg);
margin-top: 0;
margin-bottom: 2.5rem !important;
}
}
@@ -54,10 +44,6 @@ img.preview-img {
margin-top: 6rem;
border-bottom: 1px double var(--main-border-color);
font-size: 0.85rem;
.post-meta a:not(:hover) {
@extend %link-underline;
}
}
.post-tags {
@@ -123,7 +109,7 @@ img.preview-img {
white-space: normal;
}
} /* .post-navigation */
} // .post-navigation
@keyframes fade-up {
from {
@@ -145,6 +131,12 @@ img.preview-img {
top: 4rem;
transition: top 0.2s ease-in-out;
animation: fade-up 0.8s;
&.topbar-down {
top: 6rem;
}
> span {
@include panel-label;
}
}
#toc li a {
@@ -170,11 +162,6 @@ nav[data-toggle=toc] {
> h3 {
@include label(1.1rem, 600);
}
em {
@extend %normal-font-style;
}
.card {
border-color: var(--card-border-color);
background-color: var(--card-bg);
@@ -182,11 +169,9 @@ nav[data-toggle=toc] {
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
h3 {
@extend %text-color;
color: var(--text-color);
}
&:hover {
-webkit-transform: translate3d(0, -3px, 0);
transform: translate3d(0, -3px, 0);
@@ -215,7 +200,6 @@ nav[data-toggle=toc] {
ul {
list-style-type: none;
padding-inline-start: 1.5rem;
> li::before {
background: #c2c9d4;
width: 5px;
@@ -230,15 +214,12 @@ nav[data-toggle=toc] {
}
}
#tail-wrapper {
#post-extend-wrapper {
min-height: 2rem;
> div:last-of-type {
margin-bottom: 2rem;
}
#disqus_thread {
min-height: 8.5rem;
min-height: 7.5rem;
margin-bottom: 2rem;
}
}
@@ -257,21 +238,17 @@ nav[data-toggle=toc] {
.share-icons {
font-size: 1.2rem;
a {
&:not(:last-child) {
margin-right: 0.25rem;
}
&:hover {
text-decoration: none;
> i {
@extend %btn-share-hovor;
}
}
}
> i {
position: relative;
bottom: 1px;
@@ -282,32 +259,28 @@ nav[data-toggle=toc] {
@extend %btn-share-hovor;
}
}
.fab {
&.fa-twitter {
@include btn-sharing-color(rgba(29, 161, 242, 1));
}
&.fa-facebook-square {
@include btn-sharing-color(rgb(66, 95, 156));
}
&.fa-telegram {
@include btn-sharing-color(rgb(39, 159, 217));
}
&.fa-weibo {
@include btn-sharing-color(rgb(229, 20, 43));
}
}
} /* .share-icons */
} // .share-icons
.fas.fa-link {
@include btn-sharing-color(rgb(171, 171, 171));
}
} /* .share-wrapper */
} // .share-wrapper
.share-label {
@include label(inherit, 400, inherit);
@@ -319,10 +292,8 @@ nav[data-toggle=toc] {
.license-wrapper {
line-height: 1.2rem;
> a {
color: var(--text-color);
font-weight: 600;
&:hover {
@extend %link-hover;
}
@@ -331,19 +302,13 @@ nav[data-toggle=toc] {
span:last-child {
font-size: 0.85rem;
}
} /* .license-wrapper */
} // .license-wrapper
@media all and (max-width: 576px) {
.preview-img[data-src] {
margin-top: 2.2rem;
}
.post-tail-bottom {
-ms-flex-wrap: wrap-reverse !important;
flex-wrap: wrap-reverse !important;
> div:first-child {
>div:first-child {
width: 100%;
margin-top: 1rem;
}
@@ -356,17 +321,28 @@ nav[data-toggle=toc] {
}
}
@media all and (min-width: 768px) {
#post-wrapper {
.post-meta {
>div:not(:first-child)::before {
@include dot(0.5rem, 0.2rem);
}
&.flex-column {
-webkit-box-orient: horizontal !important;
-webkit-box-direction: normal !important;
-ms-flex-direction: row !important;
flex-direction: row !important;
}
}
} // .post
}
/* Hide SideBar and TOC */
@media all and (max-width: 849px) {
@media all and (max-width: 830px) {
.post-navigation {
padding-left: 0;
padding-right: 0;
margin-left: -0.5rem;
margin-right: -0.5rem;
}
.preview-img[data-src] {
max-width: 100vw;
border-radius: 0;
margin-left: -.5rem;
margin-right: -.5rem;
}
}

View File

@@ -10,7 +10,6 @@
letter-spacing: 0;
border: 1px solid var(--tag-border) !important;
box-shadow: 0 0 3px 0 var(--tag-shadow);
span {
margin-left: 0.6em;
font-size: 0.7em;

View File

@@ -4,5 +4,5 @@ icon: fas fa-info-circle
order: 4
---
> Add Markdown syntax content to file `_tabs/about.md`{: .filepath } and it will show up on this page.
{: .prompt-tip }
> **Note**: Add Markdown syntax content to file `_tabs/about.md` and it will show up on this page.

View File

@@ -7,6 +7,8 @@ redirect_from:
- /norobots/
- /assets/
- /posts/
dynamic_title: true
---
{% include lang.html %}

View File

@@ -1,6 +1,5 @@
---
layout: compress
swcache: true
---
[

View File

@@ -9,7 +9,13 @@ const resource = [
/* --- CSS --- */
'{{ "/assets/css/style.css" | relative_url }}',
/* --- PWA --- */
/* --- JavaScripts --- */
{% assign js_path = "/assets/js" | relative_url %}
'{{ js_path }}/dist/home.min.js',
'{{ js_path }}/dist/page.min.js',
'{{ js_path }}/dist/post.min.js',
'{{ js_path }}/dist/categories.min.js',
'{{ js_path }}/data/search.json',
'{{ "/app.js" | relative_url }}',
'{{ "/sw.js" | relative_url }}',
@@ -20,27 +26,30 @@ const resource = [
'{{ tab.url | relative_url }}',
{% endfor %}
/* --- Favicons & compressed JS --- */
{% assign cache_list = site.static_files | where: 'swcache', true %}
{% for file in cache_list %}
'{{ file.path | relative_url }}'{%- unless forloop.last -%},{%- endunless -%}
{% endfor %}
/* --- Favicons --- */
{% assign favicon_path = "/assets/img/favicons" | relative_url %}
'{{ favicon_path }}/android-chrome-192x192.png',
'{{ favicon_path }}/android-chrome-512x512.png',
'{{ favicon_path }}/apple-touch-icon.png',
'{{ favicon_path }}/favicon-16x16.png',
'{{ favicon_path }}/favicon-32x32.png',
'{{ favicon_path }}/favicon.ico',
'{{ favicon_path }}/mstile-150x150.png',
'{{ favicon_path }}/site.webmanifest',
'{{ favicon_path }}/browserconfig.xml'
];
/* The request url with below domain will be cached */
const allowedDomains = [
{% if site.google_analytics.id != empty and site.google_analytics.id %}
{% if site.google_analytics.id != '' %}
'www.googletagmanager.com',
'www.google-analytics.com',
{% endif %}
'{{ site.url | split: "//" | last }}',
{% if site.img_cdn contains '//' and site.img_cdn %}
'{{ site.img_cdn | split: '//' | last | split: '/' | first }}',
{% endif %}
'fonts.gstatic.com',
'fonts.googleapis.com',
'cdn.jsdelivr.net',

View File

@@ -1,6 +1,6 @@
/*!
* Chirpy v5.1.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* Chirpy v4.3.3 (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))});const LocaleHelper=function(){const e=$('meta[name="prefer-datetime-locale"]'),o=0<e.length?e.attr("content").toLowerCase():$("html").attr("lang").substr(0,2),t="data-ts",a="data-df";return{locale:()=>o,attrTimestamp:()=>t,attrDateFormat:()=>a,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(a)}}();$(function(){$(".mode-toggle").click(e=>{const o=$(e.target);let t=o.prop("tagName")==="button".toUpperCase()?o:o.parent();t.blur(),flipMode()})});const ScrollHelper=function(){const e=$("body"),o="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(o,!1),showTopbar:()=>e.attr(o,!0),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0<a,topbarLocked:()=>!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),t=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=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"),r.addClass("unloaded"),o.addClass("unloaded"),l.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),o.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)},isVisible(){return e}}}();function f(){return t.hasClass("loaded")}o.click(function(){p.on(),u.on(),i.focus()}),t.click(function(){p.off(),u.off()}),i.focus(function(){l.addClass("input-focus")}),i.focusout(function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const t=$("body");return{toggle(){!1===o?t.attr(e,""):t.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#search-input"),t=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).scroll(()=>{e=e||!0}),setInterval(()=>{e&&(function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=t)){if(e>a)ScrollHelper.hideTopbar(),o.is(":focus")&&o.blur();else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var o="div.post>h1:first-of-type";const t=$(o),n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);let e=new IntersectionObserver(e=>{var o,t;r?(o=$(window).scrollTop(),t=l<o,l=o,e=e[0],t?0===e.intersectionRatio&&n.text(a):1===e.intersectionRatio&&n.text(s)):r=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]});e.observe(document.querySelector(o)),n.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"))})});

View File

@@ -1,6 +1,6 @@
/*!
* Chirpy v5.1.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* Chirpy v4.3.3 (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))});const LocaleHelper=function(){const e=$('meta[name="prefer-datetime-locale"]'),o=0<e.length?e.attr("content").toLowerCase():$("html").attr("lang").substr(0,2),t="data-ts",a="data-df";return{locale:()=>o,attrTimestamp:()=>t,attrDateFormat:()=>a,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(a)}}();$(function(){$(".mode-toggle").click(e=>{const o=$(e.target);let t=o.prop("tagName")==="button".toUpperCase()?o:o.parent();t.blur(),flipMode()})});const ScrollHelper=function(){const e=$("body"),o="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(o,!1),showTopbar:()=>e.attr(o,!0),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0<a,topbarLocked:()=>!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),t=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),c=$("#search-input"),i=$("#search-hints"),d=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"),r.addClass("unloaded"),o.addClass("unloaded"),l.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),o.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),i.hasClass("unloaded")&&i.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),c.val(""),e=!1)},isVisible(){return e}}}();function f(){return t.hasClass("loaded")}o.click(function(){p.on(),u.on(),c.focus()}),t.click(function(){p.off(),u.off()}),c.focus(function(){l.addClass("input-focus")}),c.focusout(function(){l.removeClass("input-focus")}),c.on("input",()=>{""===c.val()?f()?i.removeClass("unloaded"):u.off():(u.on(),f()&&i.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const t=$("body");return{toggle(){!1===o?t.attr(e,""):t.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#search-input"),t=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).scroll(()=>{e=e||!0}),setInterval(()=>{e&&(function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=t)){if(e>a)ScrollHelper.hideTopbar(),o.is(":focus")&&o.blur();else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var o="div.post>h1:first-of-type";const t=$(o),n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);let e=new IntersectionObserver(e=>{var o,t;r?(o=$(window).scrollTop(),t=l<o,l=o,e=e[0],t?0===e.intersectionRatio&&n.text(a):1===e.intersectionRatio&&n.text(s)):r=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]});e.observe(document.querySelector(o)),n.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)})});

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +0,0 @@
/*!
* Chirpy v5.1.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))});const LocaleHelper=function(){const e=$('meta[name="prefer-datetime-locale"]'),t=0<e.length?e.attr("content").toLowerCase():$("html").attr("lang").substr(0,2),o="data-ts",a="data-df";return{locale:()=>t,attrTimestamp:()=>o,attrDateFormat:()=>a,getTimestamp:e=>Number(e.attr(o)),getDateFormat:e=>e.attr(a)}}();$(function(){$(".mode-toggle").click(e=>{const t=$(e.target);let o=t.prop("tagName")==="button".toUpperCase()?t:t.parent();o.blur(),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(t,!1),showTopbar:()=>e.attr(t,!0),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0<a,topbarLocked:()=>!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=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"),r.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)},isVisible(){return e}}}();function f(){return o.hasClass("loaded")}t.click(function(){p.on(),u.on(),i.focus()}),o.click(function(){p.off(),u.off()}),i.focus(function(){l.addClass("input-focus")}),i.focusout(function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(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=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).scroll(()=>{e=e||!0}),setInterval(()=>{e&&(function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.blur();else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var t="div.post>h1:first-of-type";const o=$(t),n=$("#topbar-title");if(0!==o.length&&!o.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=o.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),o.offset().top<$(window).scrollTop()&&n.text(a);let e=new IntersectionObserver(e=>{var t,o;r?(t=$(window).scrollTop(),o=l<t,l=t,e=e[0],o?0===e.intersectionRatio&&n.text(a):1===e.intersectionRatio&&n.text(s)):r=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]});e.observe(document.querySelector(t)),n.click(function(){$("body,html").animate({scrollTop:0},800)})}}),$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){const e=dayjs.unix(LocaleHelper.getTimestamp($(this)));var t=LocaleHelper.getDateFormat($(this)),t=e.format(t);$(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat())})});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
/*!
* Chirpy v5.1.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* Chirpy v4.3.3 (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())});

Submodule assets/lib deleted from d1d2ec17c8

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