1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-18 13:44:15 +00:00

Compare commits

..

41 Commits
v2.1 ... v2.2.1

Author SHA1 Message Date
Cotes Chung
bcd394598b Fixed heading layout in blockquote. 2020-05-22 20:49:27 +08:00
Cotes Chung
6d38f643ae Disable PWA at local. 2020-05-22 20:25:52 +08:00
Cotes Chung
532e7ad451 Fixed a bug in the Categories hierarchy. (#48, #57)
When one post have only one category will hit the bug.
2020-05-22 18:06:40 +08:00
Cotes Chung
08d4ce77e2 Fixed HTML tag. 2020-05-14 22:00:04 +08:00
Cotes Chung
8a46286373 Resume the trending tags on search results.
for mobile views
2020-05-13 21:13:33 +08:00
Cotes Chung
8db0e2d238 Speed up PV display. 2020-05-12 02:16:36 +08:00
Cotes Chung
0f5c2b5c9d Added exclude list for PWA caching. 2020-05-12 01:40:39 +08:00
Cotes Chung
d8e45694bd New feature: PWA 2020-05-10 04:02:52 +08:00
Cotes Chung
b64598358d Improved compress tool & Updated the Footer. 2020-05-09 01:15:33 +08:00
Cotes Chung
ac9dc4d9ac Remove line number from post snippet (#51).
Involves:
- Home page
- relate posts
- search results
- feed
2020-05-09 01:15:33 +08:00
Cotes Chung
3f843f010a Avoid color sparkles when switching modes.
- the search bar (desktop view)
- the site title.
2020-05-09 01:15:33 +08:00
Cotes Chung
9c3d3fdeed Improved loading performance by merging CSS files. 2020-05-09 01:15:33 +08:00
Cotes Chung
8c4b186c52 Improved responsive design for search results.
in mobile views.
2020-05-04 00:56:56 +08:00
Karl Sandin
2cc399d015 Fix to search result overflow (#51)
* Fix to search result overflow
2020-05-04 00:53:00 +08:00
Cotes Chung
f3295c6d0c Remove unused gems. 2020-05-02 19:18:14 +08:00
Cotes Chung
4685bba313 Fixed page creator script tool(issues #47). 2020-05-02 18:26:57 +08:00
Cotes Chung
b543f3e19b Resume avatar brightness. 2020-05-01 02:18:04 +08:00
Cotes Chung
e561dfb9be Simplified the lazy loading of post images. 2020-05-01 02:18:04 +08:00
Cotes Chung
7b3e0f741a Fixed json parse issue on search. 2020-04-24 15:16:52 +08:00
Cotes Chung
7cea137bf4 Fixed special characters in URL. 2020-04-24 14:49:45 +08:00
Cotes Chung
8c21272048 Swap the mode toggle icon. 2020-04-23 22:11:50 +08:00
Cotes Chung
078dab0299 Omit PV cache file from output. 2020-04-23 22:11:50 +08:00
Cotes Chung
f6d9ea10e2 Optimized the home page layout.
for tablet and above
2020-04-23 22:11:50 +08:00
Cotes Chung
d8a5ed194b Update lang-button style. 2020-04-23 22:11:50 +08:00
Cotes Chung
6f42bbc6e5 Fix issue #37. 2020-04-23 22:11:50 +08:00
Cotes Chung
74921c6570 Update contributing guidelines. 2020-04-23 22:11:50 +08:00
Cotes Chung
5b27222b86 Improve the layout of Categories. 2020-04-23 22:11:50 +08:00
Cotes Chung
648b199be8 Reduce the brightness in dark mode.
affect:
- images
- site title text
2020-04-23 22:11:50 +08:00
Cotes Chung
ae2b464492 Improved the travis config. 2020-04-23 22:11:50 +08:00
Cotes Chung
1209879bed Update the tutorials. 2020-04-23 22:11:50 +08:00
Cotes Chung
99aadd61c1 Replace python with bash. 2020-04-23 22:11:50 +08:00
Cotes Chung
b30d673367 Omit readme from the output. 2020-04-09 03:08:56 +08:00
Cotes Chung
b393e12e30 Optimized typography. 2020-04-09 03:08:56 +08:00
Cotes Chung
3e8dc979c6 Optimized topbar responsive layout. 2020-04-08 02:12:25 +08:00
Cotes Chung
00928c90b7 Prettified the script log format. 2020-04-08 02:12:25 +08:00
Cotes Chung
caf8dec568 Update the post meta design. 2020-04-08 02:12:25 +08:00
Cotes Chung
2423dbc726 Optimized page layout. 2020-04-08 02:12:25 +08:00
Cotes Chung
23784b3295 Optimized table color. 2020-04-08 02:12:25 +08:00
Cotes Chung
4e4e71dff2 Update the CI config. 2020-04-08 02:12:25 +08:00
Cotes Chung
456f04112c Removed the border of code snippets. 2020-04-08 02:12:25 +08:00
Cotes Chung
af6f6a2812 Document improvement. 2020-04-08 02:12:25 +08:00
70 changed files with 1181 additions and 1406 deletions

View File

@@ -2,19 +2,13 @@
I want to thank you for sparing a time to improve this project! Here are some guidelines for contributing
## Bug Reporting
To ensure that the blog design is not confused, this project do not accept suggestions for design changes, such as colors scheme, fonts, typography, etc. If your request is about enhancement, it is recommended to first submit a `Feature Request` type issue to discuss whether your idea fits the project.
If you found a bug, please ensure it doesn't appear in other existing [issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues). After that, [create a new issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues/new/choose) with template `Bug Report` and follow it's illustration to describe the situation.
Generally, contribute to the project by:
## Code Optimization
If you are willing to improve some of the existing code, such as performance optimization, code simplification, or even correct spelling errors of variable names, please submit a new PR to help us.
## Feature Request
Basically, to ensure that the blog design is not confused, we do not accept suggestions for design changes, such as colors scheme, fonts, typography, etc. As long as your request is not a design issue, it is recommended to first submit a `Feature Request` issue to discuss whether your idea fits the project. Once the discussion is complete and the request is approved, fork this project, complete the development of new features, and submit a `Pull Request`. What's more, the PR should be merged into `master` branch without conflict.
1. Fork this project.
2. Create a new branch `my-new-freature`(or `fix-a-bug`), then complete the development, commit and push.
3. Submit a new `Pull Request`.
---

View File

@@ -29,12 +29,10 @@ jobs:
with:
ruby-version: '2.6.x'
- uses: actions/setup-python@v1
with:
python-version: '3.7.x'
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Bundle Caching
id: bundle-cache
@@ -45,20 +43,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gems-
- id: get-pip-cache-path
run: |
echo "::set-output name=path::`pip show pip | grep "Location" | awk '{print $2}'`"
- name: Pip caching
id: pip-cache
uses: actions/cache@v1
with:
path: ${{ steps.get-pip-cache-path.outputs.path }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install gnu-coreutils for macOS
- name: Install GNU-Coreutils(for macOS)
if: runner.os == 'macOS'
run: |
brew install coreutils
@@ -77,11 +62,6 @@ jobs:
run: |
bundle install --local
- name: Pip installing
if: steps.pip-cache.outputs.cache-hit != 'true'
run: |
pip install -r _scripts/py/requirements.txt
- name: Build Site
run: |
bash tools/build.sh

View File

@@ -5,11 +5,10 @@ language: ruby
rvm: 2.6.5
before_install:
- pyenv global 3.7.6
- bundle config path 'vendor/bundle'
install:
- pip install -r _scripts/py/requirements.txt
- bundle install --path vendor/bundle --quiet
- bundle install --quiet
addons:
apt:

View File

@@ -12,6 +12,3 @@ end
group :test do
gem "html-proofer"
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]

View File

@@ -1,33 +1,18 @@
# Jekyll Theme Chirpy
# Chirpy
🌏 English • [简体中文](docs/README_zh-CN.md)
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=event%3Apush)
[![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)
Language: English | [简体中文](docs/README_zh-CN.md)
A minimal, sidebar, responsive web design Jekyll theme, focusing on text presentation, aim to help you easily record and share your knowledge. [Live Demo »](https://chirpy.cotes.info)
A minimal, portfolio, sidebar, bootstrap Jekyll theme with responsive web design and focuses on text exhibition. It will help you easily record and share your knowledge.
**Features**
* Auto Dark Mode
* Posts' Last Modified Date
* Table of Contents
* Automatically Recommend Related Posts
* Syntax highlighting
* Two Level Categories
* Search
* Atom Feeds
* Disqus Comments
* Google Analytics
* GA Pageviews (Advanced)
* SEO Tag
* Performance Optimization
[![devices-mockup](https://raw.githubusercontent.com/cotes2020/jekyll-theme-chirpy/master/assets/img/sample/devices-mockup.png)](https://chirpy.cotes.info)
[![Devices Mockup](https://raw.githubusercontent.com/cotes2020/jekyll-theme-chirpy/master/assets/img/sample/devices-mockup.png)](https://chirpy.cotes.info)
## Table of Contents
* [Features](#features)
* [Installing](#installing)
* [Usage](#usage)
* [Contributing](#contributing)
@@ -35,14 +20,28 @@ A minimal, portfolio, sidebar, bootstrap Jekyll theme with responsive web design
* [Support](#support)
* [License](#license)
## Features
* Configurable theme mode
* Two-level Categories
* Last modified date for posts
* Table of Contents
* Automatically recommend related posts
* Syntax highlighting
* Search
* Atom Feeds
* Disqus Comments
* Google Analytics
* GA Pageviews reporting (Advanced)
* SEO and Performance Optimization
## Installing
### Prerequisites
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installtion of basic environment (`Ruby `, `RubyGems` and `Bundler`). In order to use the script tools to save time, we also need to install [Python](https://www.python.org/downloads/)(version 3.5 or abover) and [ruamel.yaml](https://pypi.org/project/ruamel.yaml/).
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installtion of basic environment (`Ruby `, `RubyGems` and `Bundler`).
In addition, if your machine is running Debian or macOS, make sure the [GNU coreutils](https://www.gnu.org/software/coreutils/) is installed. Otherwise, get it by:
To improve the writing experience, we need to use some script tools. If your machine is running Debian or macOS, make sure that [GNU coreutils](https://www.gnu.org/software/coreutils/) is installed. Otherwise, install by:
* Debian
@@ -62,12 +61,12 @@ $ brew install coreutils
[Fork **Chirpy** from GitHub](https://github.com/cotes2020/jekyll-theme-chirpy/fork), then clone your forked repo to local:
```console
$ git clone git@github.com:USER/jekyll-theme-chirpy.git
$ git clone git@github.com:USER/jekyll-theme-chirpy.git -b master
```
replace the `USER` above to your GitHub username.
and replace the `USER` above to your GitHub username.
The first time you run or build the project on your machine, perform the installation of Jekyll plugins. Go to the root of repo and run:
The first time you run or build the project on local machine, perform the installation of Jekyll plugins. Go to the root of repo and run:
```terminal
$ bundle install
@@ -116,9 +115,9 @@ As mentioned above, some files or directories should be removed from your repo:
- .github
### Customization
### Configuration
Basically, go to `_config.yml` and customize the variables as needed, some of them are typical options:
Generally, go to `_config.yml` and configure the variables as needed. Some of them are typical options:
* `url`
@@ -145,7 +144,7 @@ Basically, go to `_config.yml` and customize the variables as needed, some of th
### Run Locally
You may want to preview the site before publishing, so just run the script tool:
You may want to preview the site content before publishing, so just run the script tool:
```terminal
$ bash tools/run.sh
@@ -157,7 +156,7 @@ Few days later, you may find that the file modification(e.g. edits to a post) do
### Deploying to GitHub Pages
Before the deployment begins, ensure the `url` in file `_config.yml` has been set to `https://<username>.github.io`(or the custom domain, if you have. e.g. `https://yourdomain.com`). What's more, if you prefer to the [Project site](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites), change `baseurl` of file `_config.yml` to your project name, starting with a slash. e.g. `/project`.
Before the deployment begins, checkout the file `_config.yml` and make sure that the `url` has been configured. What's more, if you prefer the [Project site on GitHub](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and also use the default domain `<username>.github.io`, remember to change the `baseurl` to your project name that starting with a slash. For example, `/project`.
#### Option 1: Built by GitHub Pages
@@ -170,7 +169,7 @@ By deploying the site in this way, you're allowed to push the source code direct
|Site Type | Repo's Name|
|:---|:---|
|User or Organization | `<username>.github.io`|
|Project| any one except `<username>.github.io`, let's say `project`|
|Project| Any one except `<username>.github.io`, let's say `project`|
**2**. Commit the changes of the repo first, then run the initialization script:
@@ -211,7 +210,7 @@ For security reasons, GitHub Pages runs on `safe` mode, which means the third-pa
|Site Type | Repo's Name|
|:---|:---|
|User or Organization | `<username>.github.io`|
|Project| any one except `<username>.github.io`, let's say `project`|
|Project| Any one except `<username>.github.io`, let's say `project`|
and clone it.
@@ -232,7 +231,10 @@ The generated static files will be placed in the root of `/path/to/local/project
|User or Organization | `https://<username>.github.io/`|
|Project| `https://<username>.github.io/project/`|
and enjoy!
#### Finishing work
No matter which way you choose to deploy the website on GitHub, please enforce the `HTTPS` for it. See official docs: [Configuring a publishing source for your GitHub Pages site](https://help.github.com/en/github/working-with-github-pages/securing-your-github-pages-site-with-https).
### Documentation
@@ -240,7 +242,7 @@ For more details and the better reading experience, please check out the [tutori
## Contributing
The old saying: "Two heads are better than one. Five heads are better than two." So, 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

View File

@@ -186,6 +186,7 @@ exclude:
- Gemfile
- tools
- docs
- README.md
sitemap_exclude: # Sitemap will exclude the following items.
fuzzy:

View File

@@ -7,15 +7,11 @@
license:
link: "https://creativecommons.org/licenses/by/4.0/"
prompt: This post is licensed under
name: CC BY 4.0
icons:
- "fab fa-creative-commons"
- "fab fa-creative-commons-by"
link: "https://creativecommons.org/licenses/by/4.0/"
brief: Some rights reserved.
verbose: >-
The blog posts on this site are licensed
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License.
Except where otherwise noted, the blog posts on this site are licensed
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.

View File

@@ -12,9 +12,9 @@
<p class="mb-0">
© {{ 'now' | date: "%Y" }}
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
{% if site.data.right.brief %}
{% if site.data.rights.brief %}
<span data-toggle="tooltip" data-placement="top"
title="{{ site.data.right.verbose }}">{{ site.data.right.brief }}</span>
title="{{ site.data.rights.verbose }}">{{ site.data.rights.brief }}</span>
{% endif %}
</p>
</div>
@@ -23,8 +23,9 @@
<p class="mb-0">
Powered by
<a href="https://jekyllrb.com" target="_blank">Jekyll</a>
with theme
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/">Chirpy</a>.
with
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/">Chirpy</a>
theme.
</p>
</div>

View File

@@ -53,8 +53,6 @@
integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ="
crossorigin="anonymous">
<link rel="preload" as="style" href="{{ site.baseurl }}/assets/css/main.css">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
integrity="sha256-LA89z+k9fjgMKQ/kq4OO2Mrf8VltYml/VES+Rg0fh20=" crossorigin="anonymous">
@@ -64,37 +62,45 @@
integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ="
crossorigin="anonymous">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/main.css">
{% if page.layout == 'home' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/home.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/home.css">
{% elsif page.layout == 'page' %}
{% if page.title == 'Categories' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/categories.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/categories.css">
{% elsif page.title == 'Tags' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/tags.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/tags.css">
{% elsif page.title == 'Archives' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/archives.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/archives.css">
{% else %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/page.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/page.css">
{% endif %}
{% elsif page.layout == 'category' or page.layout == 'tag' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/category-tag.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/category-tag.css">
{% elsif page.layout == 'post' %}
<link rel="preload" as="style" href="{{ site.baseurl }}/assets/css/post.css">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/post.css">
{% if site.toc and page.toc %}
<link rel="preload" as="style" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css" />
{% endif %}
{% endif %}
{% if page.title == 'Categories' and page.layout == 'page' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/categories.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/categories.css">
{% endif %}
{% if page.title == 'Tags' and page.layout == 'page' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/tags.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/tags.css">
{% endif %}
{% if page.layout == 'category' or page.layout == 'tag' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/category-tag.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/category-tag.css">
{% endif %}
{% if page.title == 'Archives' and page.layout == 'page' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/archives.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/archives.css">
{% endif %}
{% if page.title == 'About' and page.layout == 'page' %}
<link rel="preload" href="{{ site.baseurl }}/assets/css/syntax.css" as="style">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/syntax.css">
{% endif %}
<!-- jquery -->
<link rel="preload" as="script"
@@ -130,24 +136,17 @@
{% endif %}
{% endif %}
{% if page.layout == 'post' %}
<link rel="preload" as="style" href="{{ site.baseurl }}/assets/css/post.css">
<link rel="preload" as="style" href="{{ site.baseurl }}/assets/css/syntax.css">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/post.css">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/syntax.css">
{% if site.toc and page.toc %}
<link rel="preload" as="style" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css">
<link rel="preload" as="script" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js">
<link rel="stylesheet" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css" />
<script src="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js" async></script>
<script src="{{ site.baseurl }}/assets/js/dist/toc.min.js" async></script>
{% endif %}
{% if site.toc and page.toc and page.layout == 'post' %}
<link rel="preload" as="script" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js">
<script src="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js" async></script>
<script src="{{ site.baseurl }}/assets/js/dist/toc.min.js" async></script>
{% endif %}
<script src="{{ site.baseurl }}/assets/js/dist/tooltip-loader.min.js" async></script>
<!-- PWA -->
{% if jekyll.environment == 'production' %}
<script src="{{ '/app.js' | relative_url }}" defer></script>
{% endif %}
</head>

View File

@@ -1,7 +1,7 @@
<!-- image lazy load -->
<!-- image lazy load: https://github.com/ApoorvSaxena/lozad.js -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
<script type="text/javascript">
const observer = lozad();
const el = document.querySelectorAll('#post-wrapper img');
const observer = lozad(el);
observer.observe();
</script>

View File

@@ -7,8 +7,8 @@
MIT License
-->
<i class="mode-toggle fas fa-sun" light-mode-invisible></i>
<i class="mode-toggle fas fa-moon" dark-mode-invisible></i>
<i class="mode-toggle fas fa-sun" dark-mode-invisible></i>
<i class="mode-toggle fas fa-moon" light-mode-invisible></i>
<script type="text/javascript">

12
_includes/no-linenos.html Normal file
View File

@@ -0,0 +1,12 @@
{% comment %}
Remove line numbers from code snippets.
v2.2
https://github.com/cotes2020/jekyll-theme-chirpy
© 2020 Cotes Chung
Published under the MIT License
{% endcomment %}
{% if _content contains '<td class="rouge-gutter gl"><pre class="lineno">' %}
{% assign _content = _content | replace: '<td class="rouge-gutter gl"><pre class="lineno">', '<!-- <td class="rouge-gutter gl"><pre class="lineno">'%}
{% assign _content = _content | replace: '</td><td class="rouge-code">', '</td> --><td class="rouge-code">' %}
{% endif %}

View File

@@ -6,50 +6,55 @@
MIT License
-->
<div id="panel-wrapper" class="col-xl-3 pl-2 topbar-down">
<div id="panel-wrapper" class="col-xl-3 pl-2 text-muted topbar-down">
<div class="access">
{% assign lastmod_list = "" | split: "" %}
{% assign index = 0 %}
{% for post in site.posts %}
{% if post.seo.date_modified > post.date and post.seo.date_modified != nil %}
{% capture item %}
{{ post.seo.date_modified }}::{{ index }}
{% endcapture %}
{% assign lastmod_list = lastmod_list | push: item %}
{% endif %}
{% assign index = index | plus: 1 %}
{% endfor %}
{% if site.data.updates %}
{% include update_list.html %}
{% if update_list.size > 0 %}
{% if lastmod_list.size > 0 %}
<div id="access-lastmod" class="post">
<h3 data-toc-skip>
{{- site.data.label.panel.lastmod -}}
</h3>
<ul class="post-content pl-0 pb-1 ml-1 mt-2">
{% assign MAX_SIZE = 5 %}
{% assign sum = 0 %}
{% assign lastmod_list = lastmod_list | sort | reverse %}
{% for item in lastmod_list %}
{% assign index = item | split: "::" | last | plus: 0 %}
{% assign post = site.posts[index] %}
<li><a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a></li>
{% assign sum = sum | plus: 1 %}
{% if sum >= MAX_SIZE %}
{% break %}
{% endif %}
{% endfor %}
{% for item in update_list %}
{% assign post_url = item | split: "::" | last | prepend: "/posts/" | append: "/" %}
{% assign post = site.posts | where: "url", post_url | first %}
{% if post %}
{% assign url = post.url | prepend: site.baseurl %}
<li><a href="{{ url }}">{{ post.title }}</a></li>
{% assign sum = sum | plus: 1 %}
{% if sum >= MAX_SIZE %} {% break %} {% endif %}
{% endif %}
{% endfor %}
</ul>
</div><!-- #access-lastmod -->
{% endif %}
{% endif %}
{% endif %} <!-- site.data.updates -->
<div id="access-tags">
<h3 data-toc-skip>
{{- site.data.label.panel.trending_tags -}}
</h3>
<div class="d-flex flex-wrap mt-3 mb-1 mr-3">
{% include trending-tags.html %}
{% include trending-tags.html %}
{% for tag in trending_tags %}
{% capture url %}/tags/{{ tag | downcase | url_encode }}/{% endcapture %}
<a class="post-tag" href="{{ url | relative_url }}">{{ tag | replace: '-', ' ' }}</a>
{% endfor %}
</div>
</div>

View File

@@ -8,7 +8,7 @@
-->
<div class="share-wrapper">
<span class="share-label ml-1 mr-1">{{ site.data.share.label }}</span>
<span class="share-label text-muted mr-1">{{ site.data.share.label }}</span>
<span class="share-icons">
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
{% assign url = page.url | relative_url | prepend: site.url %}

View File

@@ -58,7 +58,9 @@
</span>
<h3 class="pt-0 mt-1 mb-3" data-toc-skip>{{ post.title }}</h3>
<div class="text-muted small">
<p>{{ post.content | markdownify | strip_html | truncate: 200 | replace: '&', '&amp;' }}</p>
{% assign content = post.content %}
{% include no-linenos.html %}
<p>{{ content | markdownify | strip_html | truncate: 200 | replace: '&', '&amp;' }}</p>
</div>
</div>
</a>

View File

@@ -8,8 +8,12 @@
<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
<div class="col-12 col-xl-11 post-content">
<div id="search-hints">
<h4 class="text-muted">{{ site.data.label.panel.trending_tags }}</h4>
<h4 class="text-muted mb-4">{{ site.data.label.panel.trending_tags }}</h4>
{% include trending-tags.html %}
{% for tag in trending_tags %}
{% capture url %}/tags/{{ tag | downcase | 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

@@ -1,26 +1,30 @@
<!--
{% comment %}
The trending tags list
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2019 Cotes Chung
MIT Licensed
-->
{% endcomment %}
{% assign MAX = 10 %}
{% capture tags_array %}
{% for tag in site.tags %}
{{ tag[1] | size }}:{{ tag[0] | replace: ' ', '-' }}
{{ tag[1] | size }}::{{ tag[0] | replace: ' ', '-' }}
{% endfor %}
{% endcapture %}
{% assign trends = tags_array | split: " " | sort | reverse %}
{% assign all_tags = tags_array | split: " " | sort | reverse %}
{% assign count = 0 %}
{% for trend in trends %}
{% assign trending_tags = "" | split: "" %}
{% for iter in all_tags %}
{% assign count = count | plus: 1 %}
{% assign tag = trend | split: ":" | last %}
<a class="post-tag" href="{{ site.baseurl }}/tags/{{ tag | downcase }}/">{{ tag | replace: '-', ' ' }}</a>
{% assign tag = iter | split: "::" | last %}
{% assign trending_tags = trending_tags | push: tag %}
{% if count >= MAX %}
{% break %}
{% endif %}

View File

@@ -0,0 +1,21 @@
{% comment %}
Get the last 5 post from lastmod list.
v2.2
https://github.com/cotes2020/jekyll-theme-chirpy
© 2020 Cotes Chung
MIT License
{% endcomment %}
{% assign MAX_SIZE = 5 %}
{% assign sum = 0 %}
{% assign update_list = "" | split: "" %}
{% for entry in site.data.updates %}
{% capture elem %}
{{- entry.lastmod -}}::{{- entry.filename -}}
{% endcapture %}
{% assign update_list = update_list | push: elem %}
{% endfor %}
{% assign update_list = update_list | sort | reverse %}

View File

@@ -20,11 +20,14 @@ layout: compress
{% include head.html %}
<body data-spy="scroll" data-target="#toc">
<div id="sidebar" class="d-flex flex-column">
{% include sidebar.html %}
</div>
{% include topbar.html %}
<div id="main-wrapper">
{% include topbar.html %}
<div id="main">
{% capture _content %}
@@ -37,7 +40,8 @@ layout: compress
{% include footer.html %}
</div>
{% include search-results.html %}
</div>
</div> <!-- #main-wrapper -->
<div id="mask"></div>

View File

@@ -15,11 +15,13 @@ layout: page
</h1>
<div class="post-content">
<p>
{{ post.content | strip_html | truncate: 200 | replace: '&', '&amp;' }}
{% assign _content = post.content %}
{% include no-linenos.html %}
{{ _content | markdownify | strip_html | truncate: 200 }}
</p>
</div>
<div class="post-meta text-muted pt-1">
<div class="post-meta text-muted">
<!-- posted date -->
<i class="far fa-clock fa-fw"></i>
<span class="timeago" data-toggle="tooltip" data-placement="bottom"

View File

@@ -9,7 +9,7 @@ layout: default
<div class="row">
<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 pl-xl-3 mb-md-4">
<div id="page" class="post pb-5 pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 mb-md-4">
{% if page.dynamic_title %}
<h1 class="dynamic-title">{{ page.title }}</h1>
<div class="post-content">

View File

@@ -16,63 +16,80 @@ layout: default
<h1 data-toc-skip>{{ page.title }}</h1>
<div class="post-meta text-muted d-flex flex-column">
<!-- Published Date and Categoreis -->
<!-- Published date and author -->
<div>
Posted
<span class="timeago" data-toggle="tooltip" data-placement="bottom"
title="{{ page.date | date: site.data.date_format.tooltip }}">
{{ page.date | date: site.data.date_format.post }}
<i class="unloaded">{{ page.date | date_to_xmlschema }}</i>
</span>
{% if page.categories.size > 0 %}on{% endif %}
{% for category in page.categories %}
<a href='{{ site.baseurl }}/categories/{{ category | replace: ' ', '-' | downcase | url_encode }}/'>{{ category }}</a>
{%- unless forloop.last -%}, {%- endunless -%}
{% endfor %}
by
<span class="author">
{% if page.author %}
{{ page.author }}
{% else%}
{{ site.author }}
{% endif %}
</span>
</div>
<!-- lastmod -->
{%- capture filename -%}
{{ page.url | split: "/" | last }}
{%- endcapture -%}
{% assign record = site.data.updates | where: "filename", filename | first %}
{% if record %}
<div>
Updated
<span class="timeago lastmod"
data-toggle="tooltip" data-placement="bottom"
title="{{ record.lastmod | date: site.data.date_format.tooltip }}">
{{ record.lastmod | date: site.data.date_format.post }}
<i class="unloaded">{{ record.lastmod | date_to_xmlschema}}</i>
</span>
</div>
{% endif %}
<!-- page views -->
{% if site.google_analytics.pv.enabled %}
<div>
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span> views
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span>
views
</div>
{% endif %}
</div> <!-- .post-meta -->
<div class="post-content">
{% if page.image %}
<img src="{{ page.image }}">
{% endif %}
<!-- Add lozad class into image tags. see: <https://github.com/ApoorvSaxena/lozad.js#usage> -->
{% if content contains '<img src=' %}
{% capture loading %}
{{ "/assets/img/commons/loading.png" | relative_url }}
{% endcapture %}
{% assign replacement = '<img class="lozad" src=' | append: loading | append: ' data-src=' %}
{{ content | replace: '<img src=', replacement }}
{% else %}
{{ content }}
<img src="{{ page.image }}">
{% endif %}
{{ content }}
</div>
<div class="post-tail-wrapper text-muted">
<!-- lastmod -->
{% if page.seo.date_modified > page.date %}
<div>
Updated
<span class="timeago lastmod"
data-toggle="tooltip" data-placement="top"
title="{{ page.seo.date_modified | date: site.data.date_format.tooltip }}">
{{ page.seo.date_modified | date: site.data.date_format.post }}
<i class="unloaded">{{ page.seo.date_modified | date_to_xmlschema}}</i>
</span>
<!-- 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 | replace: ' ', '-' | downcase | url_encode }}/'>{{ category }}</a>
{%- unless forloop.last -%}, {%- endunless -%}
{% endfor %}
</div>
{% endif %}
<!-- Tags -->
<!-- tags -->
{% if page.tags.size > 0 %}
<div class="pt-3">
<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 | replace: ' ', '-' | downcase | url_encode }}/"
class="post-tag no-text-decoration" >
@@ -84,18 +101,11 @@ layout: default
<div class="post-tail-bottom
d-flex justify-content-between align-items-center pt-5 pb-2">
{% if site.data.right.license %}
{% if site.data.rights.license %}
<div class="license-wrapper">
<span class="license-text ml-1 mr-1">
{{ site.data.right.license.prompt }}
<a href="{{ site.data.right.license.link }}">
{{ site.data.right.license.name }}
{% for icon in site.data.right.license.icons %}
<i class="{{ icon }}"></i>
{% endfor %}
</a>
</span>
This post is licensed under
<a href="{{ site.data.rights.license.link }}">{{ site.data.rights.license.name }}</a>
by the author.
</div>
{% endif %}

View File

@@ -1,5 +1,6 @@
---
title: "Text and Typography"
title: Text and Typography
author: Cotes Chung
date: 2019-08-08 11:33:00 +0800
categories: [Blogging, Demo]
tags: [typography]

View File

@@ -1,5 +1,6 @@
---
title: "Writing a New Post"
title: Writing a New Post
author: Cotes Chung
date: 2019-08-08 14:10:00 +0800
categories: [Blogging, Tutorial]
tags: [writing]
@@ -24,33 +25,36 @@ tags: [TAG] # TAG names should always be lowercase
> **Note**: The posts' ***layout*** has been set to `post` by default, so there is no need to add the variable ***layout*** in Front Matter block.
- **Timezone of date**
### Timezone of date
In order to accurately record the release date of a post, you should not only setup the `timezone` of `_config.yml` but also provide the the post's timezone in field `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 setup the `timezone` of `_config.yml` but also provide the the post's timezone in field `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
- **Categories and Tags**
### Categories and Tags
The `categories` of each post is designed to contain up to two elements, and the number of elements in `tags` can be zero to infinity.
The `categories` of each post is designed to contain up to two elements, and the number of elements in `tags` can be zero to infinity.
The list of posts belonging to the same category/tag is recorded on a separate page. The number of such *category*/*tag* type pages is equal to the number of `categories`/`tags` for all posts, they must match perfectly.
The list of posts belonging to the same category/tag is recorded on a separate page. The number of such *category*/*tag* type pages is equal to the number of `categories`/`tags` for all posts, they must match perfectly.
let's say there is a post with front matter:
let's say there is a post with front matter:
```yaml
categories: [Animal, Insect]
tags: bee
```
then we should have two *category* type pages placed in folder `categories` of root and one *tag* type page placed in folder `tags` of root:
then we should have two *category* type pages placed in folder `categories` of root and one *tag* type page placed in folder `tags` of root:
```terminal
jekyll-theme-chirpy
├── categories
│   ├── animal.html
│   └── tutorial.html
── tags
  └── bee.html
│   └── insect.html
── tags
  └── bee.html
...
```
and the content of a *category* type page is
and the content of a *category* type page is
```yaml
---
layout: category
@@ -59,7 +63,8 @@ category: CATEGORY_NAME # e.g. Insect
---
```
the content of a *tag* type page is
the content of a *tag* type page is
```yaml
---
layout: tag
@@ -68,20 +73,23 @@ tag: TAG_NAME # e.g. bee
---
```
With the increasing number of posts, the number of categories and tags will increase several times! If we still manually create these *category*/*tag* type files, it will obviously be a super time-consuming job, and it is very likely to miss some of them(i.e. when you click on the missing `category` or `tag` link from a post or somewhere, it will complain to you '404'). The good news is that we got a lovely script tool `_scripts/py/pages_generator.py` to finish the boring task. Basically we will use it via `tools/init.sh` instead of running it separately. Check out its use case [here]({{ "/posts/getting-started/#option-1-built-by-github-pages" | relative_url }}).
With the increasing number of posts, the number of categories and tags will increase several times! If we still manually create these *category*/*tag* type files, it will obviously be a super time-consuming job, and it is very likely to miss some of them(i.e. when you click on the missing `category` or `tag` link from a post or somewhere, it will complain to you '404'). The good news is that we got a lovely script tool `_scripts/sh/create_pages.sh` to finish the boring task. Basically we will use it via `tools/init.sh` instead of running it separately. Check out its use case [here]({{ "/posts/getting-started/#option-1-built-by-github-pages" | relative_url }}).
- **Last modified date**
## Last modified date
The last modified date of a post is obtained according to its latest git commit date, and all the modified date of the posts should be stored in `_data/updates.yml`. For example:
The last modified date of the posts is recorded as `seo.date_modified`, for example:
```yaml
---
seo:
date_modified: 2020-01-04 17:05:41 +0800
---
-
filename: getting-started # the post filename without date and extension
lastmod: 2020-04-13 00:38:56 +0800 # the post last modified date
-
...
```
This date is equal to the lastest git-commit date of the post file and can be automatically generated by the tool script `_scripts/py/update_posts_lastmod.py`. Similar to the other script `pages_generator.py` mentioned above, it is also be called from `tools/init.sh`, so it doesn't have to be used separately.
You can choose to create this file manually, but as you may notice, the better approach is to let it be automatically generated by a tool script. And `_scripts/sh/dump_lastmod.py` was born for this! Similar to the another script `_scripts/sh/create_pages.sh` mentioned above, it is also be called from `tools/init.sh`, so it doesn't have to be used separately.
When some posts have been modified since their published date and also the file `_data/updates.yml` was created correctly, a list with the label **Recent Updates** will be displayed in the right panel of the desktop view, which records the five most recently modified articles.
## Table of Contents

View File

@@ -1,15 +1,16 @@
---
title: Getting Started
author: Cotes Chung
date: 2019-08-09 20:55:00 +0800
categories: [Blogging, Tutorial]
tags: [getting started]
---
## Preparation
## Prerequisites
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installtion of basic environment (Ruby, RubyGem, Bundler and Jekyll). In order to use the script tools to save time, we also need to install [Python](https://www.python.org/downloads/)(version 3.5 or abover) and [ruamel.yaml](https://pypi.org/project/ruamel.yaml/).
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installtion of basic environment (`Ruby `, `RubyGems` and `Bundler`).
In addition, if your machine is running Debian or macOS, make sure you have the [GNU coreutils](https://www.gnu.org/software/coreutils/) installed. Otherwise, get it by:
To improve the writing experience, we need to use some script tools. If your machine is running Debian or macOS, make sure that [GNU coreutils](https://www.gnu.org/software/coreutils/) is installed. Otherwise, install by:
* Debian
@@ -24,18 +25,26 @@ $ brew install coreutils
```
## Install Jekyll Plugins
## Jekyll Plugins
Go to the root of repo and run:
[Fork **Chirpy** from GitHub](https://github.com/cotes2020/jekyll-theme-chirpy/fork), then clone your forked repo to local:
```console
$ git clone git@github.com:USER/jekyll-theme-chirpy.git -b master
```
and replace the `USER` above to your GitHub username.
The first time you run or build the project on local machine, perform the installation of Jekyll plugins. Go to the root of repo and run:
```terminal
$ bundle install
```
`bundle` will install all the dependent Jekyll Plugins listed in file `Gemfile` automatically.
`bundle` will automatically install all the dependent Jekyll Plugins that listed in the `Gemfile`.
## File Structure
## Directory Structure
The main files and related brief introductions are listed below.
@@ -73,7 +82,7 @@ As mentioned above, some files or directories should be removed from your repo:
## Configuration
Basically, go to `_config.yml` and customize the variables as needed, some of them are typical options:
Generally, go to `_config.yml` and configure the variables as needed. Some of them are typical options:
* `url`
@@ -100,7 +109,7 @@ Basically, go to `_config.yml` and customize the variables as needed, some of th
## Run Locally
You may want to preview the site before publishing, so just run the script tool:
You may want to preview the site content before publishing, so just run the script tool:
```terminal
$ bash tools/run.sh
@@ -112,7 +121,7 @@ Few days later, you may find that the file changes does not refresh in real time
## Deploying to GitHub Pages
Before the deployment begins, ensure the `url` in file `_config.yml` has been set to `https://<username>.github.io`(or the custom domain, if you have. e.g. `https://yourdomain.com`). What's more, if you prefer to the [Project site](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites), change `baseurl` of file `_config.yml` to your project name, starting with a slash. e.g. `/project`.
Before the deployment begins, checkout the file `_config.yml` and make sure that the `url` has been configured. What's more, if you prefer the [Project site on GitHub](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and also use the default domain `<username>.github.io`, remember to change the `baseurl` to your project name that starting with a slash. For example, `/project`.
### Option 1: Built by GitHub Pages
@@ -126,7 +135,7 @@ By deploying the site in this way, you're allowed to push the source code direct
|Site Type | Repo's Name|
|:---|:---|
|User or Organization | `<username>.github.io`|
|Project| any one except `<username>.github.io`, let's say `project`|
|Project| Any one except `<username>.github.io`, let's say `project`|
**2**. Commit the changes of the repo first, then run the initialization script:
@@ -168,7 +177,7 @@ For security reasons, GitHub Pages runs on `safe` mode, which means the third-pa
|Site Type | Repo's Name|
|:---|:---|
|User or Organization | `<username>.github.io`|
|Project| any one except `<username>.github.io`, let's say `project`|
|Project| Any one except `<username>.github.io`, let's say `project`|
and clone it.
@@ -189,4 +198,6 @@ The generated static files will be placed in the root of `/path/to/local/project
|User or Organization | `https://<username>.github.io/`|
|Project| `https://<username>.github.io/project/`|
and enjoy!
### Finishing work
No matter which way you choose to deploy the website on GitHub, please enforce the `HTTPS` for it. See official docs: [Configuring a publishing source for your GitHub Pages site](https://help.github.com/en/github/working-with-github-pages/securing-your-github-pages-site-with-https).

View File

@@ -1,5 +1,6 @@
---
title: "Customize the Favicon"
title: Customize the Favicon
author: Cotes Chung
date: 2019-08-11 00:34:00 +0800
categories: [Blogging, Tutorial]
tags: [favicon]

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Automatic invokes all initial scripts for project.
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2018-2019 Cotes Chung
Licensed under MIT
"""
import update_posts_lastmod
import pages_generator
update_posts_lastmod
pages_generator

View File

@@ -1,205 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Generates HTML pages for Categories and Tags in posts.
Dependencies:
- git
- ruamel.yaml
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2018-2019 Cotes Chung
MIT License
'''
import os
import shutil
import sys
import subprocess
from ruamel.yaml import YAML
from utils.common import get_yaml
from utils.common import get_makrdown_files
from utils.common import check_py_version
DRAFTS_DIR = '_drafts'
POSTS_DIR = ['_posts']
CATEGORIES_DIR = 'categories'
CATEGORY_LAYOUT = 'category'
TAG_DIR = 'tags'
TAG_LAYOUT = 'tag'
LEVEL = 3 # Tree level for current script file.
def help():
print("Usage: "
" python pages_generator.py [Option]\n\n"
"Options:\n"
" -d, --drafts Enable drafts\n"
" -v, --verbose Print verbose logs\n")
def get_path(dir):
path = os.path.abspath(__file__)
count = LEVEL
r_index = len(path)
while r_index > 0:
r_index -= 1
if (path[r_index] == '/' or path[r_index] == '\\'):
count -= 1
if count == 0:
return path[:r_index + 1] + dir
def get_categories():
all_categories = []
yaml = YAML()
for dir in POSTS_DIR:
path = get_path(dir)
posts = get_makrdown_files(path)
for file in posts:
meta = yaml.load(get_yaml(file)[0])
if 'category' in meta:
if type(meta['category']) == list:
err_msg = (
"[Error] File {} 'category' type"
" can not be LIST!").format(file)
raise Exception(err_msg)
else:
if meta['category'] not in all_categories:
all_categories.append(meta['category'])
else:
if 'categories' in meta:
if type(meta['categories']) == str:
error_msg = (
"[Error] File {} 'categories' type"
" can not be STR!").format(file)
raise Exception(error_msg)
for ctg in meta['categories']:
if ctg not in all_categories:
all_categories.append(ctg)
else:
err_msg = (
"[Error] File:{} at least "
"have one category.").format(file)
print(err_msg)
return all_categories
def generate_category_pages(is_verbose):
categories = get_categories()
if len(categories) <= 0:
return
path = get_path(CATEGORIES_DIR)
if os.path.exists(path):
shutil.rmtree(path)
os.makedirs(path)
for category in categories:
new_page = path + '/' + category.replace(' ', '-').lower() + '.html'
with open(new_page, 'w+', encoding='utf-8') as html:
html.write("---\n")
html.write("layout: {}\n".format(CATEGORY_LAYOUT))
html.write("title: {}\n".format(category))
html.write("category: {}\n".format(category))
html.write("---")
if is_verbose:
print("[INFO] Created page: " + new_page)
change = subprocess.getoutput("git status categories -s")
if change:
print("[INFO] Succeed! {} category-pages created."
.format(len(categories)))
def get_all_tags():
all_tags = []
yaml = YAML()
for dir in POSTS_DIR:
path = get_path(dir)
posts = get_makrdown_files(path)
for file in posts:
meta = yaml.load(get_yaml(file)[0])
if 'tags' in meta:
for tag in meta['tags']:
if tag not in all_tags:
all_tags.append(tag)
else:
raise Exception("Didn't find 'tags' in \
post '{}' !".format(file))
return all_tags
def generate_tag_pages(is_verbose):
all_tags = get_all_tags()
if len(all_tags) <= 0:
return
tag_path = get_path(TAG_DIR)
if os.path.exists(tag_path):
shutil.rmtree(tag_path)
os.makedirs(tag_path)
for tag in all_tags:
tag_page = tag_path + '/' + tag.replace(' ', '-').lower() + '.html'
with open(tag_page, 'w+', encoding='utf-8') as html:
html.write("---\n")
html.write("layout: {}\n".format(TAG_LAYOUT))
html.write("title: {}\n".format(tag))
html.write("tag: {}\n".format(tag))
html.write("---")
if is_verbose:
print("[INFO] Created page: " + tag_page)
change = subprocess.getoutput("git status tags -s")
if change:
print("[INFO] Succeed! {} tag-pages created.".format(len(all_tags)))
def main():
check_py_version()
is_verbose = False
if len(sys.argv) > 1:
for arg in sys.argv:
if arg != sys.argv[0]:
if arg == '-d' or arg == '--drafts':
POSTS_DIR.insert(0, DRAFTS_DIR)
elif arg == '-v' or arg == '--verbose':
is_verbose = True
else:
help()
return
generate_category_pages(is_verbose)
generate_tag_pages(is_verbose)
main()

View File

@@ -1,2 +0,0 @@
ruamel.yaml==0.16.5
ruamel.yaml.clib==0.1.2

View File

@@ -1,174 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Update (or create if not existed) field 'seo.date_modified'
in posts' Front Matter by their latest git commit date.
Dependencies:
- git
- ruamel.yaml
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2018-2019 Cotes Chung
Licensed under MIT
"""
import sys
import os
import getopt
import subprocess
import shutil
import datetime
import time
from enum import Enum
from ruamel.yaml import YAML
from utils.common import get_yaml
from utils.common import get_makrdown_files
from utils.common import check_py_version
Date = Enum('Date', ('GIT', 'FS'))
POSTS_PATH = '_posts'
def help():
print("Usage: "
" python update_posts_lastmod.py [options]\n"
"Options:\n"
" -f, --file <file path> Read a file.\n"
" -d, --dir <directory path> Read from a directory.\n"
" -h, --help Print help information\n"
" -v, --verbose Print verbose logs\n"
" -t, --datetime < git | fs > Chose post's datetime source, "
"'git' for git-log, 'fs' for filesystem, default to 'git'.\n")
def update_lastmod(posts, verbose, date):
count = 0
yaml = YAML()
for post in posts:
lastmod = ''
if date == Date.GIT:
git_log_count = subprocess.getoutput(
"git log --pretty=%ad \"{}\" | wc -l".format(post))
if git_log_count == "1":
continue
git_lastmod = subprocess.getoutput(
"git log -1 --pretty=%ad --date=iso \"{}\"".format(post))
if not git_lastmod:
continue
lates_commit = subprocess.check_output(
['git', 'log', '-1', '--pretty=%B', post]).decode('utf-8')
if "[Automation]" in lates_commit and "Lastmod" in lates_commit:
continue
lastmod = git_lastmod
elif date == Date.FS:
t = os.path.getmtime(post)
dt = datetime.datetime.fromtimestamp(t)
lastmod = dt.strftime('%F %T') + time.strftime(' %z')
frontmatter, line_num = get_yaml(post)
meta = yaml.load(frontmatter)
if 'seo' in meta:
if ('date_modified' in meta['seo'] and
meta['seo']['date_modified'] == lastmod):
continue
else:
meta['seo']['date_modified'] = lastmod
else:
meta.insert(line_num, 'seo', dict(date_modified=lastmod))
output = 'new.md'
if os.path.isfile(output):
os.remove(output)
with open(output, 'w', encoding='utf-8') as new, \
open(post, 'r', encoding='utf-8') as old:
new.write("---\n")
yaml.dump(meta, new)
new.write("---\n")
line_num += 2
lines = old.readlines()
for line in lines:
if line_num > 0:
line_num -= 1
continue
else:
new.write(line)
shutil.move(output, post)
count += 1
if verbose:
print("[INFO] update 'lastmod' for:" + post)
if count > 0:
print("[INFO] Success to update lastmod for {} post(s).".format(count))
def main(argv):
check_py_version()
specific = False
posts = []
verbose = False
date = Date.GIT
try:
opts, args = getopt.getopt(
argv, "hf:d:vt:",
["file=", "dir=", "help", "verbose", "datetime="])
except getopt.GetoptError:
help()
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
help()
sys.exit()
elif opt == '-f' or opt == '--file':
posts.append(arg)
specific = True
elif opt == '-d' or opt == '--dir':
posts = get_makrdown_files(arg)
specific = True
elif opt == '-v' or opt == '--verbose':
verbose = True
elif opt == '-t' or opt == '--datetime':
if arg == 'git':
date = Date.GIT
elif arg == 'fs':
date = Date.FS
else:
help()
sys.exit(2)
if not specific:
posts = get_makrdown_files(POSTS_PATH)
update_lastmod(posts, verbose, date)
main(sys.argv[1:])

View File

@@ -1,57 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Common functions to other scripts.
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2018-2019 Cotes Chung
MIT License
'''
import sys
import os
import glob
def get_yaml(path):
"""
Return the Yaml block of a post and the linenumbers of it.
"""
end = False
yaml = ""
num = 0
with open(path, 'r', encoding='utf-8') as f:
for line in f.readlines():
if line.strip() == '---':
if end:
break
else:
end = True
continue
else:
num += 1
yaml += line
return yaml, num
def get_makrdown_files(path):
MD_EXTENSIONS = ["md", "markdown", "markdn", "mdown"]
ret_files = []
for extension in MD_EXTENSIONS:
ret_files.extend(glob.glob(os.path.join(path, "*." + extension)))
return ret_files
def check_py_version():
if not sys.version_info.major == 3 and sys.version_info.minor >= 5:
print("WARNING: This script requires Python 3.5 or higher, "
"however you are using Python {}.{}."
.format(sys.version_info.major, sys.version_info.minor))
sys.exit(1)

154
_scripts/sh/create_pages.sh Executable file
View File

@@ -0,0 +1,154 @@
#!/usr/local/bin/bash
#
# Create HTML pages for Categories and Tags in posts.
#
# Usage:
# Call from the '_posts' sibling directory.
#
# v2.2
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2020 Cotes Chung
# Published under MIT License
set -eu
TYPE_CATEGORY=0
TYPE_TAG=1
category_count=0
tag_count=0
_read_yaml() {
local _endline=$(grep -n "\-\-\-" $1 | cut -d: -f 1 | sed -n '2p')
head -$_endline $1
}
read_categories() {
local _yaml=$(_read_yaml $1)
local _categories=$(echo "$_yaml" | grep "^categories:")
local _category=$(echo "$_yaml" | grep "^category:")
if [[ ! -z "$_categories" ]]; then
echo "$_categories" | sed "s/categories: *//;s/\[//;s/\]//;s/, */,/g;s/\"//g;s/'//g"
elif [[ ! -z "_category" ]]; then
echo "$_category" | sed "s/category: *//;s/\[//;s/\]//;s/, */,/g;s/\"//g;s/'//g"
fi
}
read_tags() {
local _yaml=$(_read_yaml $1)
echo "$_yaml" | grep "^tags:" | sed "s/tags: *//;s/\[//;s/\]//;s/, */,/g;s/\"//g;s/'//g"
}
init() {
if [[ -d categories ]]; then
rm -rf categories
fi
if [[ -d tags ]]; then
rm -rf tags
fi
mkdir categories tags
}
create_category() {
local _name=$1
local _filepath="categories/$(echo $_name | sed 's/ /-/g' | awk '{print tolower($0)}').html"
if [[ ! -f $_filepath ]]; then
echo "---" > $_filepath
echo "layout: category" >> $_filepath
echo "title: $_name" >> $_filepath
echo "category: $_name" >> $_filepath
echo "---" >> $_filepath
((category_count=category_count+1))
fi
}
create_tag() {
local _name=$1
local _filepath="tags/$( echo $_name | sed "s/ /-/g;s/'//g" | awk '{print tolower($0)}' ).html"
if [[ ! -f $_filepath ]]; then
echo "---" > $_filepath
echo "layout: tag" >> $_filepath
echo "title: $_name" >> $_filepath
echo "tag: $_name" >> $_filepath
echo "---" >> $_filepath
((tag_count=tag_count+1))
fi
}
#########################################
# Create HTML pages for Categories/Tags.
# Arguments:
# $1 - an array string
# $2 - type specified option
#########################################
create_pages() {
if [[ $1 == '' ]]; then
exit 0
fi
# split string to array
IFS_BAK=$IFS
IFS=','
local _string=$1
case $2 in
$TYPE_CATEGORY)
for i in ${_string#,}; do
create_category $i
done
;;
$TYPE_TAG)
for i in ${_string#,}; do
create_tag $i
done
;;
*)
;;
esac
IFS=$IFS_BAK
}
main() {
init
for _file in $(ls "_posts")
do
local _path="_posts/$_file"
local _categories=$(read_categories "$_path")
local _tags=$(read_tags "$_path")
create_pages "$_categories" $TYPE_CATEGORY
create_pages "$_tags" $TYPE_TAG
done
if [[ $category_count -gt 0 ]]; then
echo "[INFO] Succeed! $category_count category-pages created."
fi
if [[ $tag_count -gt 0 ]]; then
echo "[INFO] Succeed! $tag_count tag-pages created."
fi
}
main

89
_scripts/sh/dump_lastmod.sh Executable file
View File

@@ -0,0 +1,89 @@
#!/bin/bash
#
# Find out the posts that have been modified and record
# its lastmod information to file '_data/updates.yml'
#
# Usage:
# Call from the '_posts' sibling directory.
#
# v2.2
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2020 Cotes Chung
# Published under MIT License
set -eu
POST_DIR=_posts
OUTPUT_DIR=_data
OUTPUT_FILE=updates.yml
_init() {
if [[ ! -d "$OUTPUT_DIR" ]]; then
mkdir "$OUTPUT_DIR"
fi
if [[ -f "$OUTPUT_DIR/$OUTPUT_FILE" ]]; then
rm -f "$OUTPUT_DIR/$OUTPUT_FILE"
fi
touch "$OUTPUT_DIR/$OUTPUT_FILE"
}
_has_changed() {
local _log_count=`git log --pretty=%ad $1 | wc -l | sed 's/ *//'`
_log_count=$(($_log_count + 0))
if [[ $_log_count > 1 ]]; then
return 0 # true
fi
return 1 # false
}
###################################
# Storage the posts' lastmod.
#
# Args:
# - $1 the post's filename
# - $2 the post's filepath
# Output:
# the file '_data/updates.yml'
###################################
_dump() {
local _lasmod="`git log -1 --pretty=%ad --date=iso $2`"
echo "-" >> "$OUTPUT_DIR/$OUTPUT_FILE"
echo " filename: '$1'" >> "$OUTPUT_DIR/$OUTPUT_FILE"
echo " lastmod: '$_lasmod'" >> "$OUTPUT_DIR/$OUTPUT_FILE"
}
main() {
_init
local _count=0
for _file in $(ls -r "$POST_DIR")
do
_filepath="$POST_DIR/$_file"
_filename="${_file%.*}" # jekyll cannot read the extension of a file, so omit it.
_filename=${_filename:11} # remove the date
if _has_changed "$_filepath"; then
_dump "$_filename" "$_filepath"
((_count=_count+1))
fi
done
if [[ $_count > 0 ]]; then
echo "[INFO] Success to update lastmod for $_count post(s)."
fi
}
main

View File

@@ -33,6 +33,6 @@ if [[ -f "$1" ]]; then
fi
if [[ $related_dir == "_posts" ]]; then
python $3/_scripts/py/init_all.py
python $3/_scripts/py/update_posts_lastmod.py -f "$dest/$(basename $1)" -t fs
bash $3/_scripts/sh/create_pages.sh
bash $3/_scripts/sh/dump_lastmod.sh
fi

12
app.js Normal file
View File

@@ -0,0 +1,12 @@
---
layout: compress
# Chirpy v2.2
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2020 Cotes Chung
# MIT Licensed
---
/* Registering Service Worker */
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('{{ "/sw.js" | relative_url }}');
};

View File

@@ -1,312 +1,8 @@
/*
* The field 'font-display' is added for Google-fonts.
*
* See https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700,900|Oswald|Lato
* See: <https://fonts.google.com/>
*
*/
/* latin-ext */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Lato Regular'), local('Lato-Regular'), url(https://fonts.gstatic.com/s/lato/v14/S6uyw4BMUTPHjxAwXjeu.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Lato Regular'), local('Lato-Regular'), url(https://fonts.gstatic.com/s/lato/v14/S6uyw4BMUTPHjx4wXg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic */
@font-face {
font-family: 'Oswald';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752HT8Ghe4.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Oswald';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752Fj8Ghe4.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Oswald';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752Fz8Ghe4.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Oswald';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752GT8G.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmhduz8A.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwkxduz8A.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmxduz8A.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlBduz8A.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmBduz8A.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmRduz8A.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdu.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmhduz8A.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwkxduz8A.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmxduz8A.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmhduz8A.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwkxduz8A.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmxduz8A.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlBduz8A.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmBduz8A.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmRduz8A.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 900;
font-display: swap;
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdu.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@import url('https://fonts.googleapis.com/css?family=Lato|Roboto+Condensed:400,700|Source+Sans+Pro:400,600,700,900&display=swap');

View File

@@ -1,6 +1,4 @@
---
---
/*!
/*
* The main styles.
* v2.0
* https://github.com/cotes2020/jekyll-theme-chirpy
@@ -53,15 +51,9 @@ html[mode=dark] {
}
html, body {
height: 100%;
font-size: 16px;
}
/* Solved jumping scrollbar */
html {
overflow-y: scroll;
}
body {
line-height: 1.75rem;
background: var(--body-bg);
@@ -72,10 +64,10 @@ body {
/*--- sidebar layout ---*/
$tab-height: 3.3rem;
$tab-cursor-height: 1.6rem;
$tab-count: {{ site.data.tabs | size }};
$sidebar-display: "sidebar-display";
#sidebar {
@include pl-pr(0);
position: fixed;
@@ -85,12 +77,10 @@ $tab-count: {{ site.data.tabs | size }};
overflow-y: auto;
width: $sidebar-width-medium;
z-index: 99;
-webkit-transition: transform 0.4s ease;
transition: transform 0.4s ease;
background: rgb(42, 30, 107);
background: var(--sidebar-bg);
a {
@include sidebar-icon;
@include sidebar-links;
}
.sidebar-bottom {
.icon-border+a { // the icon behide mode-toggle
@@ -178,7 +168,7 @@ $tab-count: {{ site.data.tabs | size }};
#mode-toggle-wrapper {
i {
@include sidebar-icon;
@include sidebar-links;
margin-right: 0;
font-size: 1.05rem;
text-align: center;
@@ -236,11 +226,10 @@ $tab-count: {{ site.data.tabs | size }};
img {
width: 100%;
height: 100%;
background-size: cover;
background-repeat: no-repeat;
-webkit-transition: all .5s !important;
-moz-transition: all .5s !important;
transition: all .5s !important;
-webkit-transition: transform .5s;
-moz-transition: transform .5s;
transition: transform .5s;
&:hover {
-ms-transform: scale(1.2);
-moz-transform: scale(1.2);
@@ -253,7 +242,7 @@ $tab-count: {{ site.data.tabs | size }};
#site-title {
text-align: center;
a {
color: #b6b6b6;
// color: var(--site-title-color);
font-weight: 900;
font-size: 1.5rem;
letter-spacing: .5px;
@@ -273,10 +262,6 @@ $tab-count: {{ site.data.tabs | size }};
margin: .5rem 1.5rem 2rem 1.5rem;
}
.sidebar-expand {
box-shadow: 4px 0 8px 0 rgba(0, 0, 0, 0.2), 6px 0 20px 0 rgba(0, 0, 0, 0.19) !important;
}
#search-result-wrapper {
display: none;
position: fixed;
@@ -337,7 +322,6 @@ $tab-count: {{ site.data.tabs | size }};
border: 1px solid var(--search-wrapper-bg);
background: var(--search-wrapper-bg);
padding: 0 .5rem;
transition: background-color .15s ease-in-out,border-color .15s ease-in-out;
i {
z-index: 2;
font-size: .9rem;
@@ -398,14 +382,15 @@ $tab-count: {{ site.data.tabs | size }};
a {
@extend %link-color;
@extend %no-bottom-border;
@extend %heading;
font-size: 1.4rem;
font-weight: 400;
line-height: 2.5rem;
&:hover {
@extend %link-hover;
}
}
>div {
max-width: 100%;
&:not(:last-child) {
margin-bottom: 1rem;
}
@@ -447,10 +432,8 @@ $tab-count: {{ site.data.tabs | size }};
left: 0;
height: 100%;
width: 100%;
background: var(--mask-bg);
opacity: 0.5;
z-index: 1;
@at-root .sidebar-expand~& {
@at-root [#{$sidebar-display}] & {
display: block!important;
}
}
@@ -460,12 +443,9 @@ $tab-count: {{ site.data.tabs | size }};
#main-wrapper {
background-color: var(--main-wrapper-bg);
position: relative;
min-height: 100%;
min-height: 100vh;
padding-bottom: $footer-height;
@include pl-pr(0);
margin-left: 260px;
transition: transform 0.4s ease;
-webkit-transition: transform 0.4s ease;
}
#main>div.row:first-child>div {
@@ -513,6 +493,8 @@ footer {
}
}
a {
@include semi-bold;
color: var(---footer-link);
&:link {
@include no-text-decoration;
}
@@ -521,14 +503,8 @@ footer {
@include no-text-decoration;
}
}
.footer-left a {
@extend %footer-content;
}
.footer-right {
text-align: right;
a {
@extend %footer-content;
}
}
}
@@ -540,7 +516,6 @@ footer {
margin-right: 1.5rem;
margin-top: 3rem;
margin-bottom: 4rem;
color: #6c757d;
&:only-child {
position: -webkit-sticky; /* Safari */
position: sticky;
@@ -561,8 +536,7 @@ footer {
margin-top: 0;
margin-bottom: 0;
letter-spacing: -0.02em;
font-size: 1rem;
font-family: 'Oswald', sans-serif;
@include label(inherit, 600);
}
.post-content {
font-size: .9rem;
@@ -641,29 +615,35 @@ footer {
/*--- Typography ---*/
h1 {
@extend %heading;
font-size: 1.8rem;
font-weight: 400;
}
h2 {
@extend %heading;
@extend %section;
@extend %anchor;
font-size: 1.35rem;
font-size: 1.4rem;
}
h3 {
@extend %heading;
@extend %section;
@extend %anchor;
font-size: 1.25rem;
}
h4 {
@extend %heading;
@extend %section;
@extend %anchor;
font-size: 1.15rem;
}
h5 {
@extend %heading;
@extend %section;
@extend %anchor;
font-size: 1.1rem;
}
@@ -752,9 +732,6 @@ a {
@extend %no-bottom-border;
}
}
.license-wrapper .license-text &:hover {
@extend %link-hover;
}
} // a
@@ -791,12 +768,12 @@ table {
&:nth-child(2n) {
background-color: var(--tb-even-bg);
}
&:last-child:nth-child(2n) {
border-bottom: solid 1px var(--tb-even-border-color);
}
&:nth-child(2n + 1) {
background-color: var(--tb-odd-bg);
}
& {
border-bottom: 1px solid var(--tb-border-color);
}
}
th {
@extend %table-cell;
@@ -857,13 +834,14 @@ table {
min-width: 2rem;
text-align: center;
background: var(--tag-bg);
border-radius: .34rem;
border-radius: .3rem;
padding: 0 .4rem;
color: #818182;
line-height: 1.6rem;
&:not(:first-child) {
margin-left: .2rem;
color: inherit;
line-height: 1.3rem;
&:not(:last-child) {
margin-right: .2rem;
}
&:hover {
@extend %tag-hover;
border-bottom: none;
@@ -875,7 +853,7 @@ table {
/* --- buttons --- */
.btn-lang {
border: 1px solid !important;
padding: 0 3px 1px 3px;
padding: 1px 3px;
border-radius: 3px;
color: var(--link-color);
&:focus {
@@ -904,11 +882,6 @@ table {
visibility: hidden !important;
}
.no-scroll {
position: fixed;
width: 100%;
}
.flex-grow-1 {
-ms-flex-positive: 1!important;
flex-grow: 1!important;
@@ -946,6 +919,7 @@ table {
box-shadow: none;
border-color: var(--input-focus-border-color) !important;
background: center !important;
transition: background-color .15s ease-in-out,border-color .15s ease-in-out;
}
/*--- Responsive Design ---*/
@@ -1005,62 +979,38 @@ table {
}
/* Sidebar is visibal */
@media all and (min-width: 831px) {
#profile-wrapper {
margin-top: 3rem;
}
#search-wrapper {
width: 22%;
min-width: 150px;
}
/* button 'back-to-Top' position */
#back-to-top {
bottom: 5.5rem;
right: 1.2rem;
}
.topbar-up {
box-shadow: none !important;
}
#topbar-title {
text-align: left;
}
footer>div.d-flex {
width: 92%;
}
}
/* iPad 9.7" horizontal */
@media all and (min-width: 992px) and (max-width: 1024px) {
#main-wrapper .col-lg-11 {
-webkit-box-flex: 0;
-ms-flex: 0 0 96%;
flex: 0 0 96%;
max-width: 96%;
}
}
/* Hide SideBar and TOC */
/* Hide Sidebar and TOC */
@media all and (max-width: 830px) {
%slide {
-webkit-transition: transform 0.4s ease;
transition: transform 0.4s ease;
}
.sidebar-expand {
transform: translateX(0) !important;
~#main-wrapper {
transform: translateX(#{$sidebar-width-medium}) !important;
html, body {
overflow-x: hidden;
}
[#{$sidebar-display}] {
#sidebar {
transform: translateX(0);
}
#topbar-wrapper,
#main-wrapper {
transform: translateX(#{$sidebar-width-medium});
}
}
#sidebar {
@extend %slide;
transform: translateX(-#{$sidebar-width-medium}); // hide
-webkit-transform: translateX(-#{$sidebar-width-medium});
.cursor {
-webkit-transition: none;
-moz-transition: none;
@@ -1068,8 +1018,13 @@ table {
}
}
#topbar-wrapper {
@extend %slide;
}
#main-wrapper {
margin-left: 0;
@extend %slide;
padding-top: $topbar-height;
}
#search-result-wrapper {
@@ -1089,8 +1044,6 @@ table {
}
#topbar-wrapper {
position: -webkit-sticky;
position: sticky;
left: 0;
}
@@ -1159,6 +1112,57 @@ table {
}
/* Sidebar visible */
@media all and (min-width: 831px) {
/* Solved jumping scrollbar */
html {
overflow-y: scroll;
}
#main-wrapper {
margin-left: $sidebar-width-medium;
}
#profile-wrapper {
margin-top: 3rem;
}
#search-wrapper {
width: 22%;
min-width: 150px;
}
/* button 'back-to-Top' position */
#back-to-top {
bottom: 5.5rem;
right: 1.2rem;
}
.topbar-up {
box-shadow: none !important;
}
#topbar-title {
text-align: left;
}
footer>div.d-flex {
width: 92%;
}
}
/* iPad 9.7" horizontal */
@media all and (min-width: 992px) and (max-width: 1024px) {
#main-wrapper .col-lg-11 {
-webkit-box-flex: 0;
-ms-flex: 0 0 96%;
flex: 0 0 96%;
max-width: 96%;
}
}
/* Compact icons in sidebar & TOC hidden */
@media all and (min-width: 832px) and (max-width: 1199px) {
@@ -1180,6 +1184,10 @@ table {
width: calc(100% - 210px);
}
#search-results>div {
max-width: 700px;
}
#site-title {
font-size: 1.3rem;
margin-left: 0!important;
@@ -1219,10 +1227,6 @@ table {
-ms-flex-pack: center!important;
justify-content: center!important;
}
#search-results>div {
max-width: 700px;
}
}
@@ -1477,6 +1481,10 @@ table {
- (1920px - #{$sidebar-width-large}) ) /* 100% - 350px - (1920px - 350px); */
}
#topbar {
max-width: calc(#{$main-content-max-width} + 20px)
}
#main>div.row {
padding-left: calc((100% - #{$main-content-max-width} - 2%) / 2);
}

View File

@@ -37,6 +37,10 @@
border-bottom: none;
}
%heading {
font-family: 'Lato', 'Microsoft Yahei', sans-serif;
}
%section {
#post-wrapper & {
line-height: 1.2;
@@ -45,27 +49,21 @@
}
%anchor {
#post-wrapper &,
#page & {
.post-content>&,
#page>& {
padding-top: 3.5rem;
margin-top: -2.5rem;
}
}
%footer-content {
font-weight: 600;
color: var(---footer-link);
}
/*---------- scss mixin ---------*/
@mixin no-text-decoration {
text-decoration: none;
}
@mixin sidebar-icon {
color: rgba(255, 255, 255, 0.5);
@mixin sidebar-links($color: rgba(255, 255, 255, 0.5)) {
color: $color;
transition: color 0.35s ease-in-out;
user-select: none;
margin: 0 .25rem;
@@ -91,3 +89,14 @@
@mixin input-placeholder {
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;
font-family: 'Roboto Condensed', 'Microsoft Yahei', sans-serif;
}

View File

@@ -1,5 +1,3 @@
---
---
/*
* The syntax highlight.
* v2.0
@@ -12,12 +10,6 @@
@import "_colors/dark-syntax";
@mixin highlight-box-shadow($val) {
-moz-box-shadow: $val;
-webkit-box-shadow: $val;
box-shadow: $val;
}
html:not([mode]), html[mode=light] {
@include light-syntax;
}
@@ -56,12 +48,10 @@ html[mode=dark] {
.highlight {
@extend %code-snippet-radius;
background: var(--highlight-bg-color);
@at-root figure#{&} {
background: var(--highlight-bg-color);
}
overflow: auto;
@include highlight-box-shadow(inset 0 0 2px #c2c6cc);
.lineno {
margin: .8rem 0rem;
padding: 0 .5rem;
@@ -105,9 +95,8 @@ code {
hyphens: none;
&.highlighter-rouge {
padding: 2px 4px;
margin: 0 .3rem;
margin: 0 .15rem;
border-radius: 4px;
border: 1px solid var(--code-highlighter-rouge);
}
@at-root a>&.highlighter-rouge {
padding-bottom: 0; // show link's underlinke

View File

@@ -9,6 +9,9 @@
/*--- ↓ width and height ----*/
$tab-height: 3.3rem;
$tab-cursor-height: 1.6rem;
$sidebar-width-small: 210px;
$sidebar-width-medium: 260px;
$sidebar-width-large: 350px;

View File

@@ -77,7 +77,6 @@
/*----- My styles ------*/
--code-highlighter-rouge: #272822;
--highlight-bg-color: #272822;
--highlighter-rouge-color: #de6b18;
@@ -85,7 +84,6 @@
--highlight-lineno-border-color: #3c4042;
.highlight {
@include highlight-box-shadow(none);
.gp { color: #818c96; }
}
pre { color: #818c96 } /* override Bootstrap */

View File

@@ -34,7 +34,7 @@
--card-bg: rgb(39, 40, 33);
--card-header-bg: rgb(51, 50, 50);
--label-relate-post: rgb(164, 175, 181);
--label-color: rgb(108, 117, 125);
/* Sidebar */
--nav-cursor-color: rgb(183, 182, 182);
@@ -58,8 +58,7 @@
--tag-hover: rgb(43, 56, 62);
--tb-odd-bg: rgba(52, 53, 42, 0.52); /* odd rows of the posts' table */
--tb-even-bg: rgb(31, 31, 34); /* even rows of the posts' table */
--tb-even-border-color: var(--tb-odd-bg);
--tb-even-border-color: var(--tb-odd-bg);
--tb-border-color: var(--tb-odd-bg);
--footnote-target-bg: rgb(63, 81, 181);
--btn-share-color: #6c757d;
--btn-share-hover-color: #bfc1ca;
@@ -86,6 +85,9 @@
/* Footer */
---footer-link: rgb(146, 146, 146);
.post-content img {
filter: brightness(90%);
}
hr {
border-color: var(--main-border-color);

View File

@@ -71,7 +71,6 @@
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
/*--- custom light colors ---*/
--code-highlighter-rouge: #e9ecef;
--highlight-bg-color: #f7f7f7;
--highlighter-rouge-color: #353a3d;
--highlight-lineno-color: #c2c6cc;

View File

@@ -18,7 +18,7 @@
--btn-border-color: #e9ecef;
--text-color: #343a40;
--text-color: #333333;
--blockquote-border-color: #eee;
@@ -30,9 +30,9 @@
--text-muted-color: gray;
--tb-odd-bg: #f8f9fa;
--tb-odd-bg: #fbfcfd;
--tb-even-border-color: rgba(210, 215, 217, 0.75);
--tb-border-color: #eaeaea;
--button-bg: #fff;
@@ -55,8 +55,6 @@
--topbar-text-color: rgb(78, 78, 78);
--search-wrapper-bg: #fff;
--search-wrapper-bg: #f5f5f5;
--search-tag-bg: #f8f9fa;
@@ -89,7 +87,7 @@
--card-box-shadow: rgba(234, 234, 234, 0.7686274509803922);
--label-relate-post: #353a3d;
--label-color: #808080;
--relate-post-date: rgba(30, 55, 70, .4);

View File

@@ -1,12 +1,13 @@
---
# Style for Archives
# v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
/*!
Style for Archives
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2019 Cotes Chung
MIT License
*/
{% include_relative _addon/main.scss %}
%date-timeline {
content: "";
@@ -18,6 +19,10 @@
background-color: var(--timeline-color);
}
%date-font {
font-family: 'Roboto Condensed', sans-serif;
}
#archives {
letter-spacing: 0.03rem;
li {
@@ -37,7 +42,7 @@
span.lead {
font-size: 1.5rem;
font-family: 'Oswald', sans-serif;
@extend %date-font;
position: relative;
left: 8px;
@@ -75,7 +80,7 @@
&.month {
width: 1.4rem;
text-align: center;
font-family: 'Oswald', sans-serif;
@extend %date-font;
~a::before {
/* A dot for Month and Day */
content: "";
@@ -96,7 +101,7 @@
}
&.day {
font-size: 85%;
font-family: sans-serif;
font-family: 'Lato', sans-serif;
text-align: center;
margin-right: -2px;
width: 1.2rem;

View File

@@ -1,12 +1,13 @@
---
# Style for Tab Categories
# v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
/*!
Style for Tab Categories
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2019 Cotes Chung
MIT License
*/
{% include_relative _addon/main.scss %}
%category-icon-color {
color: gray;

View File

@@ -1,13 +1,13 @@
---
# Style for page Category and Tag
# v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
/*!
Style for page Category and Tag
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2019 Cotes Chung
MIT License
*/
@import "_addon/module";
{% include_relative _addon/main.scss %}
#page-category, #page-tag {
ul>li {

View File

@@ -1,13 +1,12 @@
---
# Style for Homepage
# v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
/*!
Style for Homepage
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2019 Cotes Chung
MIT License
*/
{% include_relative _addon/main.scss %}
#post-list {
margin-top: 1rem;
@@ -112,6 +111,11 @@
/* Sidebar is visible */
@media all and (min-width: 831px) {
#post-list {
margin-top: 1.5rem;
}
.pagination {
font-size: .85rem;
}

10
assets/css/page.scss Normal file
View File

@@ -0,0 +1,10 @@
---
# The default style for layout Page
# v2.2
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2020 Cotes Chung
# MIT License
---
{% include_relative _addon/main.scss %}
{% include_relative _addon/syntax.scss %}

View File

@@ -1,13 +1,14 @@
---
# Post-specific style
# v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
/*!
Post-specific style
v2.0
https://github.com/cotes2020/jekyll-theme-chirpy
© 2019 Cotes Chung
MIT License
*/
@import "_addon/variables";
{% include_relative _addon/main.scss %}
{% include_relative _addon/syntax.scss %}
$prompt-older: "{{ site.data.label.post.button.previous }}";
$prompt-newer: "{{ site.data.label.post.button.next }}";
@@ -26,25 +27,33 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
border-color: var(--btn-border-color);
}
.post img {
margin-top: .5rem;
margin-bottom: 1.5rem;
max-width: 100%;
height: auto;
// filter: drop-shadow(2px 4px 6px rgba(0,0,0,0.08));
position: relative;
left: 50%;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
.author {
@include semi-bold;
}
.post {
img {
max-width: 100%;
margin-top: .5rem;
margin-bottom: 1.5rem;
position: relative;
left: 50%;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
}
.post-tail-wrapper {
margin-top: 5rem;
margin-top: 4rem;
border-bottom: 1px double var(--main-border-color);
font-size: 0.85rem;
}
.post-tags {
line-height: 2rem;
}
.post-navigation {
padding-top: 3rem;
padding-bottom: 2rem;
@@ -128,9 +137,7 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
top: 6rem;
}
>h3 {
font-size: 1rem;
font-family: 'Oswald', sans-serif;
color: gray;
@include label(inherit, 600);
}
}
@@ -145,9 +152,7 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
#related-posts {
>h3 {
color: gray;
font-size: 1.1rem;
font-family: 'Oswald', sans-serif;
@include label(1.1rem, 600);
}
.card {
border: 1px solid var(--card-border-color);
@@ -157,7 +162,7 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
-moz-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
h3 {
color: var(--label-relate-post);
color: var(--text-color);
}
&:hover {
-webkit-transform: translate3d(0, -3px, 0);
@@ -260,7 +265,7 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
.share-label {
font-family: 'Oswald', sans-serif;
@include label(inherit, 400, inherit);
&::after {
content: ":";
}
@@ -268,8 +273,11 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
.license-wrapper {
line-height: 1.2rem;
.license-text>a {
>a {
font-weight: 600;
&:hover {
@extend %link-hover;
}
}
i {
font-weight: 400;
@@ -282,10 +290,11 @@ $prompt-newer: "{{ site.data.label.post.button.next }}";
@media all and (max-width: 576px) {
.post-tail-bottom {
-ms-flex-wrap: wrap!important;
flex-wrap: wrap!important;
-ms-flex-wrap: wrap-reverse!important;
flex-wrap: wrap-reverse!important;
>div:first-child {
margin-bottom: 1rem;
width: 100%;
margin-top: 1rem;
}
}
}

View File

@@ -1,13 +1,13 @@
---
# Styles for Tab Tags
# v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
/*!
* Styles for Tab Tags
* v2.0
* https://github.com/cotes2020/jekyll-theme-chirpy
* © 2019 Cotes Chung
* MIT License
*/
{% include_relative _addon/main.scss %}
.tag {
border-radius: 0.7em;

116
assets/data/cache-list.js Normal file
View File

@@ -0,0 +1,116 @@
---
# The list to be cached by PWA
# Chirpy v2.2
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2020 Cotes Chung
# MIT Licensed
---
const include = [
/*--- CSS ---*/
'{{ "/assets/css/home.css" | relative_url }}',
'{{ "/assets/css/categories.css" | relative_url }}',
'{{ "/assets/css/tags.css" | relative_url }}',
'{{ "/assets/css/archives.css" | relative_url }}',
'{{ "/assets/css/page.css" | relative_url }}',
'{{ "/assets/css/post.css" | relative_url }}',
'{{ "/assets/css/category-tag.css" | relative_url }}',
'{{ "/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css" | relative_url }}',
/*--- Javascripts ---*/
'{{ "/assets/js/dist/commons.js" | relative_url }}',
'{{ "/assets/js/dist/timeago.min.js" | relative_url }}',
'{{ "/assets/js/dist/category-collapse.min.js" | relative_url }}',
'{{ "/assets/js/dist/toc.min.js" | relative_url }}',
'{{ "/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js" | relative_url }}',
/*--- HTML ---*/
/* Tabs */
{% for tab in site.data.tabs %}
{% capture item %}
{%- unless tab.name == 'Home' -%}
/tabs/{{ tab.name | downcase }}
{%- endunless -%}
{{- "/" -}}
{% endcapture %}
'{{ item | relative_url }}',
{% endfor %}
/* The posts of first Home page and recent update list */
{% assign post_list = "" | split: "" %}
{% assign sum = 0 %}
{% for post in site.posts %}
{% assign post_list = post_list | push: post.url %}
{% assign sum = sum | plus: 1 %}
{% if sum >= site.paginate %}
{% break %}
{% endif %}
{% endfor %}
{% include update_list.html %}
{% for item in update_list %}
{% assign url = item | split: "::" | last | prepend: "/posts/" | append: "/" %}
{% assign post_list = post_list | push: url %}
{% endfor %}
{% assign post_list = post_list | uniq %}
{% for url in post_list %}
'{{ url }}',
{% endfor %}
/* Trending tags */
{% include trending-tags.html %}
{% for tag in trending_tags %}
{% capture tag_url %}/tags/{{ tag | downcase | url_encode }}/{% endcapture %}
'{{ tag_url | relative_url }}',
{% endfor %}
/*--- Icons ---*/
{%- capture icon_url -%}
{{ "/assets/img/favicons" | relative_url }}
{%- endcapture -%}
'{{ icon_url }}/favicon.ico',
'{{ icon_url }}/apple-icon.png',
'{{ icon_url }}/apple-icon-precomposed.png',
'{{ icon_url }}/apple-icon-57x57.png',
'{{ icon_url }}/apple-icon-60x60.png',
'{{ icon_url }}/apple-icon-72x72.png',
'{{ icon_url }}/apple-icon-76x76.png',
'{{ icon_url }}/apple-icon-114x114.png',
'{{ icon_url }}/apple-icon-120x120.png',
'{{ icon_url }}/apple-icon-144x144.png',
'{{ icon_url }}/apple-icon-152x152.png',
'{{ icon_url }}/apple-icon-180x180.png',
'{{ icon_url }}/android-icon-192x192.png',
'{{ icon_url }}/favicon-32x32.png',
'{{ icon_url }}/favicon-96x96.png',
'{{ icon_url }}/favicon-16x16.png',
'{{ icon_url }}/ms-icon-144x144.png',
'{{ icon_url }}/manifest.json',
'{{ icon_url }}/browserconfig.xml',
/*--- Others ---*/
{% if site.google_analytics.pv.enabled %}
'{{ "/assets/lib/countUp.min.js" | relative_url }}',
'{{ "/assets/js/dist/pageviews.min.js" | relative_url }}',
{% endif %}
'{{ "/assets/data/search.json" | relative_url }}',
'{{ "/404.html" | relative_url }}',
'{{ "/app.js" | relative_url }}',
'{{ "/sw.js" | relative_url }}'
];
const exclude = [
'/assets/data/pv-data.json',
'/img.shields.io/'
];

View File

@@ -1,12 +1,11 @@
---
layout: compress
---
const proxyData = '{"url": "{{ site.google_analytics.pv.proxy_endpoint }}"}';
{%- capture pv_data -%}
{%- if site.google_analytics.pv.cache and site.google_analytics.pv.enabled -%}
{% include_relative pageviews.json %}
{% include_relative _pageviews.json %}
{%- endif -%}
{%- endcapture -%}

View File

@@ -1,5 +1,4 @@
---
layout: compress
---
[
@@ -10,7 +9,9 @@ layout: compress
"categories": "{{ post.categories | join: ', '}}",
"tags": "{{ post.tags | join: ', ' }}",
"date": "{{ post.date }}",
"snippet": "{{ post.content | strip_html | strip_newlines | remove_chars | escape | truncate: 300 }}"
{% assign content = post.content %}
{% include no-linenos.html %}
"snippet": "{{ content | strip_html | strip_newlines | remove_chars | escape | truncate: 300 | replace: '\', '\\\\' }}"
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

View File

@@ -1,51 +1,58 @@
---
layout: compress
#
# A part of the Favicons
# v2.0
# Chirpy v2.0
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2019 Cotes Chung
# MIT License
---
{% assign icon_url = "/assets/img/favicons/" | relative_url %}
{
"name": "App",
"icons": [
{
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-36x36.png",
"sizes": "36x36",
"type": "image\/png",
"density": "0.75"
},
{
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": "1.0"
},
{
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": "1.5"
},
{
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": "2.0"
},
{
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": "3.0"
},
{
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-192x192.png",
"sizes": "192x192",
"type": "image\/png",
"density": "4.0"
}
]
"name": "{{ site.title }}",
"short_name": "{{ site.title }}",
"description": "{{ site.description }}",
"icons": [
{
"src": "{{ icon_url }}/android-icon-36x36.png",
"sizes": "36x36",
"type": "image/png",
"density": "0.75"
},
{
"src": "{{ icon_url }}/android-icon-48x48.png",
"sizes": "48x48",
"type": "image/png",
"density": "1.0"
},
{
"src": "{{ icon_url }}/android-icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"density": "1.5"
},
{
"src": "{{ icon_url }}/android-icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"density": "2.0"
},
{
"src": "{{ icon_url }}/android-icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"density": "3.0"
},
{
"src": "{{ icon_url }}/android-icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"density": "4.0"
}],
"start_url": "{{ '/index.html' | relative_url }}",
"display": "fullscreen",
"theme_color": "#2a1e6b",
"background_color": "white"
}

View File

@@ -29,10 +29,8 @@ $(function() {
return {
block: function() {
offset = $(window).scrollTop();
$('body').addClass('no-scroll');
},
release: function() {
$('body').removeClass('no-scroll');
$('html,body').scrollTop(offset);
},
getOffset: function() {

View File

@@ -5,52 +5,30 @@
* © 2018-2019 Cotes Chung
* MIT License
*/
$(function(){
var isExpanded = false;
$(function() {
$("#sidebar-trigger").click(function() {
if (isExpanded == false) {
$("#sidebar").addClass("sidebar-expand");
openModal();
isExpanded = true;
}
});
var sidebarUtil = (function() {
const ATTR_DISPLAY = "sidebar-display";
var isExpanded = false;
var body = $('body');
$("#mask").click(function() {
$("#sidebar").removeClass("sidebar-expand");
closeModal();
isExpanded = false;
});
/**
* ModalHelper helpers resolve the modal scrolling issue on mobile devices
* https://github.com/twbs/bootstrap/issues/15852
* requires document.scrollingElement polyfill https://github.com/yangg/scrolling-element
*/
var ModalHelper = (function(bodyCls) {
var scrollTop;
return {
afterOpen: function() {
scrollTop = document.scrollingElement.scrollTop;
document.body.classList.add(bodyCls);
document.body.style.top = -scrollTop + 'px';
},
beforeClose: function() {
document.body.classList.remove(bodyCls);
// scrollTop lost after set position:fixed, restore it back.
document.scrollingElement.scrollTop = scrollTop;
document.body.style.top = '';
toggle: function() {
if (isExpanded == false) {
body.attr(ATTR_DISPLAY, '');
} else {
body.removeAttr(ATTR_DISPLAY);
}
isExpanded = !isExpanded;
}
};
})('no-scroll');
}
function openModal() {
ModalHelper.afterOpen();
}
})();
function closeModal() {
ModalHelper.beforeClose();
}
$("#sidebar-trigger").click(sidebarUtil.toggle);
$('#mask').click(sidebarUtil.toggle);
});

View File

@@ -184,12 +184,12 @@ $(function() {
if ($('.pageviews').length > 0) {
let originPvData = pageviews ? JSON.parse(pageviews) : undefined;
let cache = PvCache.getData();
if (cache) {
if (PvCache.isExpired()) {
if (PvCache.isProxyCache() ) {
let originPvData = pageviews ? JSON.parse(pageviews) : undefined;
if (originPvData) {
if (PvCache.newerThan(originPvData)) {
displayPageviews(cache);
@@ -215,6 +215,7 @@ $(function() {
}
} else {
let originPvData = pageviews ? JSON.parse(pageviews) : undefined;
fetchOriginPageviews(originPvData);
fetchProxyPageviews();
}

View File

@@ -1 +1 @@
$(function(){var j=$("#sidebar-trigger");var o=$("#search-trigger");var h=$("#search-cancel");var b=$("#search-cleaner");var e=$("#main");var c=$("#topbar-title");var k=$("#search-wrapper");var i=$("#search-result-wrapper");var g=$("#search-results");var l=$("#search-input");var a=$("#search-hints");var d=(function(){var p=0;return{block:function(){p=$(window).scrollTop();$("body").addClass("no-scroll")},release:function(){$("body").removeClass("no-scroll");$("html,body").scrollTop(p)},getOffset:function(){return p}}})();var m=(function(){return{on:function(){j.addClass("unloaded");c.addClass("unloaded");o.addClass("unloaded");k.addClass("d-flex");h.addClass("loaded")},off:function(){h.removeClass("loaded");k.removeClass("d-flex");j.removeClass("unloaded");c.removeClass("unloaded");o.removeClass("unloaded")}}})();var n=(function(){var p=false;return{on:function(){if(!p){i.removeClass("unloaded");e.addClass("hidden");p=true;d.block()}},off:function(){if(p){g.empty();if(a.hasClass("unloaded")){a.removeClass("unloaded")}i.addClass("unloaded");b.removeClass("visable");e.removeClass("hidden");l.val("");p=false;d.release()}},isVisable:function(){return p}}})();function f(){return h.hasClass("loaded")}o.click(function(){m.on();n.on();l.focus()});h.click(function(){m.off();n.off()});l.focus(function(){k.addClass("input-focus")});l.focusout(function(){k.removeClass("input-focus")});l.on("keyup",function(p){if(p.keyCode==8&&l.val()==""){if(!f()){n.off()}else{a.removeClass("unloaded")}}else{if(l.val()!=""){n.on();if(!b.hasClass("visible")){b.addClass("visable")}if(f()){a.addClass("unloaded")}}}});b.on("click",function(){l.val("");if(f()){a.removeClass("unloaded");g.empty()}else{n.off()}l.focus();b.removeClass("visable")})});
$(function(){var j=$("#sidebar-trigger");var o=$("#search-trigger");var h=$("#search-cancel");var b=$("#search-cleaner");var e=$("#main");var c=$("#topbar-title");var k=$("#search-wrapper");var i=$("#search-result-wrapper");var g=$("#search-results");var l=$("#search-input");var a=$("#search-hints");var d=(function(){var p=0;return{block:function(){p=$(window).scrollTop()},release:function(){$("html,body").scrollTop(p)},getOffset:function(){return p}}})();var m=(function(){return{on:function(){j.addClass("unloaded");c.addClass("unloaded");o.addClass("unloaded");k.addClass("d-flex");h.addClass("loaded")},off:function(){h.removeClass("loaded");k.removeClass("d-flex");j.removeClass("unloaded");c.removeClass("unloaded");o.removeClass("unloaded")}}})();var n=(function(){var p=false;return{on:function(){if(!p){i.removeClass("unloaded");e.addClass("hidden");p=true;d.block()}},off:function(){if(p){g.empty();if(a.hasClass("unloaded")){a.removeClass("unloaded")}i.addClass("unloaded");b.removeClass("visable");e.removeClass("hidden");l.val("");p=false;d.release()}},isVisable:function(){return p}}})();function f(){return h.hasClass("loaded")}o.click(function(){m.on();n.on();l.focus()});h.click(function(){m.off();n.off()});l.focus(function(){k.addClass("input-focus")});l.focusout(function(){k.removeClass("input-focus")});l.on("keyup",function(p){if(p.keyCode==8&&l.val()==""){if(!f()){n.off()}else{a.removeClass("unloaded")}}else{if(l.val()!=""){n.on();if(!b.hasClass("visible")){b.addClass("visable")}if(f()){a.addClass("unloaded")}}}});b.on("click",function(){l.val("");if(f()){a.removeClass("unloaded");g.empty()}else{n.off()}l.focus();b.removeClass("visable")})});

View File

@@ -1 +1 @@
$(function(){var d=false;$("#sidebar-trigger").click(function(){if(d==false){$("#sidebar").addClass("sidebar-expand");b();d=true}});$("#mask").click(function(){$("#sidebar").removeClass("sidebar-expand");c();d=false});var a=(function(e){var f;return{afterOpen:function(){f=document.scrollingElement.scrollTop;document.body.classList.add(e);document.body.style.top=-f+"px"},beforeClose:function(){document.body.classList.remove(e);document.scrollingElement.scrollTop=f;document.body.style.top=""}}})("no-scroll");function b(){a.afterOpen()}function c(){a.beforeClose()}});
$(function(){var a=(function(){const c="sidebar-display";var d=false;var b=$("body");return{toggle:function(){if(d==false){b.attr(c,"")}else{b.removeAttr(c)}d=!d}}})();$("#sidebar-trigger").click(a.toggle);$("#mask").click(a.toggle)});

View File

@@ -1 +1 @@
function countUp(b,a,d){if(b<a){var c=new CountUp(d,b,a);if(!c.error){c.start()}else{console.error(c.error)}}}function countPV(f,e){var g=f.replace(/\/posts\//g,"").replace(/\//g,".html");var d=0;var c=f.replace(/posts\//g,"");for(var b=0;b<e.length;++b){var a=e[b][0];if(a==f||a==c||a.concat("/")==c||a.slice(a.lastIndexOf("/")+1)===g){d+=parseInt(e[b][1])}}return d}function tacklePV(e,f,d,b){var c=countPV(f,e);c=(c==0?1:c);if(!b){d.text(new Intl.NumberFormat().format(c))}else{var a=parseInt(d.text().replace(/,/g,""));if(c>a){countUp(a,c,d.attr("id"))}}}function displayPageviews(c){if(c===undefined){return}var a=getInitStatus();var b=c.rows;if($("#post-list").length>0){$(".post-preview").each(function(){var e=$(this).children("h1").children("a").attr("href");tacklePV(b,e,$(this).find(".pageviews"),a)})}else{if($(".post").length>0){var d=window.location.pathname;tacklePV(b,d,$("#pv"),a)}}}var getInitStatus=(function(){var a=false;return function(){let ret=a;if(!a){a=true}return ret}})();var PvCache=(function(){const e="pv";const b="pv-created-date";const d="pv-type";var c={ORIGIN:"origin",PROXY:"proxy"};function a(g){return localStorage.getItem(g)}function f(g,h){localStorage.setItem(g,h)}return{getData:function(){return JSON.parse(localStorage.getItem(e))},saveOriginCache:function(g){f(e,g);f(d,c.ORIGIN);f(b,new Date().toJSON())},saveProxyCache:function(g){f(e,g);f(d,c.PROXY);f(b,new Date().toJSON())},isOriginCache:function(){return a(d)==c.ORIGIN},isProxyCache:function(){return a(d)==c.PROXY},isExpired:function(){if(PvCache.isOriginCache()){let date=new Date(a(b));date.setDate(date.getDate()+1);return Date.now()>=date.getTime()}else{if(PvCache.isProxyCache()){let date=new Date(a(b));date.setHours(date.getHours()+1);return Date.now()>=date.getTime()}}return false},getAllPagevies:function(){return PvCache.getData().totalsForAllResults["ga:pageviews"]},newerThan:function(g){return PvCache.getAllPagevies()>g.totalsForAllResults["ga:pageviews"]}}})();function fetchOriginPageviews(a){if(a===undefined){return}displayPageviews(a);PvCache.saveOriginCache(JSON.stringify(a))}function fetchProxyPageviews(){let proxy=JSON.parse(proxyData);$.ajax({type:"GET",url:proxy.url,dataType:"jsonp",jsonpCallback:"displayPageviews",success:function(b,c,a){PvCache.saveProxyCache(JSON.stringify(b))},error:function(a,c,b){console.log("Failed to load pageviews from proxy server: "+b)}})}$(function(){if($(".pageviews").length>0){let originPvData=pageviews?JSON.parse(pageviews):undefined;let cache=PvCache.getData();if(cache){if(PvCache.isExpired()){if(PvCache.isProxyCache()){if(originPvData){if(PvCache.newerThan(originPvData)){displayPageviews(cache)}else{fetchOriginPageviews(originPvData)}}fetchProxyPageviews()}else{if(PvCache.isOriginCache()){fetchOriginPageviews(originPvData);fetchProxyPageviews()}}}else{displayPageviews(cache);if(PvCache.isOriginCache()){fetchProxyPageviews()}}}else{fetchOriginPageviews(originPvData);fetchProxyPageviews()}}});
function countUp(b,a,d){if(b<a){var c=new CountUp(d,b,a);if(!c.error){c.start()}else{console.error(c.error)}}}function countPV(f,e){var g=f.replace(/\/posts\//g,"").replace(/\//g,".html");var d=0;var c=f.replace(/posts\//g,"");for(var b=0;b<e.length;++b){var a=e[b][0];if(a==f||a==c||a.concat("/")==c||a.slice(a.lastIndexOf("/")+1)===g){d+=parseInt(e[b][1])}}return d}function tacklePV(e,f,d,b){var c=countPV(f,e);c=(c==0?1:c);if(!b){d.text(new Intl.NumberFormat().format(c))}else{var a=parseInt(d.text().replace(/,/g,""));if(c>a){countUp(a,c,d.attr("id"))}}}function displayPageviews(c){if(c===undefined){return}var a=getInitStatus();var b=c.rows;if($("#post-list").length>0){$(".post-preview").each(function(){var e=$(this).children("h1").children("a").attr("href");tacklePV(b,e,$(this).find(".pageviews"),a)})}else{if($(".post").length>0){var d=window.location.pathname;tacklePV(b,d,$("#pv"),a)}}}var getInitStatus=(function(){var a=false;return function(){let ret=a;if(!a){a=true}return ret}})();var PvCache=(function(){const e="pv";const b="pv-created-date";const d="pv-type";var c={ORIGIN:"origin",PROXY:"proxy"};function a(g){return localStorage.getItem(g)}function f(g,h){localStorage.setItem(g,h)}return{getData:function(){return JSON.parse(localStorage.getItem(e))},saveOriginCache:function(g){f(e,g);f(d,c.ORIGIN);f(b,new Date().toJSON())},saveProxyCache:function(g){f(e,g);f(d,c.PROXY);f(b,new Date().toJSON())},isOriginCache:function(){return a(d)==c.ORIGIN},isProxyCache:function(){return a(d)==c.PROXY},isExpired:function(){if(PvCache.isOriginCache()){let date=new Date(a(b));date.setDate(date.getDate()+1);return Date.now()>=date.getTime()}else{if(PvCache.isProxyCache()){let date=new Date(a(b));date.setHours(date.getHours()+1);return Date.now()>=date.getTime()}}return false},getAllPagevies:function(){return PvCache.getData().totalsForAllResults["ga:pageviews"]},newerThan:function(g){return PvCache.getAllPagevies()>g.totalsForAllResults["ga:pageviews"]}}})();function fetchOriginPageviews(a){if(a===undefined){return}displayPageviews(a);PvCache.saveOriginCache(JSON.stringify(a))}function fetchProxyPageviews(){let proxy=JSON.parse(proxyData);$.ajax({type:"GET",url:proxy.url,dataType:"jsonp",jsonpCallback:"displayPageviews",success:function(b,c,a){PvCache.saveProxyCache(JSON.stringify(b))},error:function(a,c,b){console.log("Failed to load pageviews from proxy server: "+b)}})}$(function(){if($(".pageviews").length>0){let cache=PvCache.getData();if(cache){if(PvCache.isExpired()){if(PvCache.isProxyCache()){let originPvData=pageviews?JSON.parse(pageviews):undefined;if(originPvData){if(PvCache.newerThan(originPvData)){displayPageviews(cache)}else{fetchOriginPageviews(originPvData)}}fetchProxyPageviews()}else{if(PvCache.isOriginCache()){fetchOriginPageviews(originPvData);fetchProxyPageviews()}}}else{displayPageviews(cache);if(PvCache.isOriginCache()){fetchProxyPageviews()}}}else{let originPvData=pageviews?JSON.parse(pageviews):undefined;fetchOriginPageviews(originPvData);fetchProxyPageviews()}}});

View File

@@ -1,14 +1,26 @@
# Jekyll Theme Chirpy
# Chirpy
🌏 [English](../README.md) • 简体中文
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=event%3Apush)
[![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)
选择语言: [English](../README.md) | 简体中文
一个不一样的响应式设计 Jekyll 主题(内附神秘工具),采用响应式设计,方便记录、管理、分享你的知识和经验。
一个不一样的 Jekyll 主题(内附神秘工具),采用响应式设计,方便记录、管理、分享你的知识和经验。
[![Devices Mockup](https://raw.githubusercontent.com/cotes2020/jekyll-theme-chirpy/master/assets/img/sample/devices-mockup.png)](https://chirpy.cotes.info)
**功能一览**
## 目录
* [功能预览](#功能预览)
* [安装](#安装)
* [运行指南](#运行指南)
* [参与贡献](#参与贡献)
* [感谢](#感谢)
* [赞助](#赞助)
* [许可证书](#许可证书)
## 功能预览
* 自动暗夜模式
* 文章最后修改日期
@@ -25,24 +37,13 @@
* 网站性能优化
[![devices-mockup](https://raw.githubusercontent.com/cotes2020/jekyll-theme-chirpy/master/assets/img/sample/devices-mockup.png)](https://chirpy.cotes.info)
## 目录
* [安装](#安装)
* [运行指南](#运行指南)
* [参与贡献](#参与贡献)
* [感谢](#感谢)
* [赞助](#赞助)
* [许可证书](#许可证书)
## 安装
### 准备工作
按照 [Jekyll 官方文档](https://jekyllrb.com/docs/installation/) 完成基础环境的安装 (RubyRubyGemBundler 和 Jekyll)。为了使用项目内免费提供的脚本工具,你还需要安装 [Python](https://www.python.org/downloads/)( >= 3.5) 和 [ruamel.yaml](https://pypi.org/project/ruamel.yaml/)。
按照 [Jekyll 官方文档](https://jekyllrb.com/docs/installation/) 完成基础环境的安装 (RubyRubyGemBundler 和 Jekyll)。
如果你的机器系统是 Debian 或者 macOS则需要确保安装了 [GNU coreutils](https://www.gnu.org/software/coreutils/)。否则,通过以下方式获得:
为了使用项目内免费提供的脚本工具提升你的写作体验,如果你的机器系统是 Debian 或者 macOS则需要确保安装了 [GNU coreutils](https://www.gnu.org/software/coreutils/)。否则,通过以下方式获得:
* Debian
@@ -59,16 +60,16 @@
接着,[fork](https://github.com/cotes2020/jekyll-theme-chirpy/fork) 一份代码,然后克隆你 Fork 的仓库到本地机器上。
```console
$ git clone git@github.com:USER/jekyll-theme-chirpy.git
$ git clone git@github.com:USER/jekyll-theme-chirpy.git -b master
```
`USER` 替换为你的 GitHub username。
把上述的`USER` 替换为你的 GitHub username。
### 安装 Jekyll 插件
根目录下运行:
本地首次运行或编译,请在项目根目录下运行:
```terminal
$ bundle install

View File

@@ -50,7 +50,10 @@ layout: compress
{% if post.summary %}
<summary>{{ post.summary | strip }}</summary>
{% else %}
<summary>{{ post.content | strip_html | truncate: 200 }}</summary>
<summary>
{% assign content = post.content %}
{% include no-linenos.html %}
{{ content | strip_html | truncate: 200 }}</summary>
{% endif %}
</entry>

62
sw.js Normal file
View File

@@ -0,0 +1,62 @@
---
layout: compress
# Chirpy v2.2
# https://github.com/cotes2020/jekyll-theme-chirpy
# © 2020 Cotes Chung
# MIT Licensed
---
self.importScripts('{{ "/assets/data/cache-list.js" | relative_url }}');
var cacheName = 'chirpy-{{ "now" | date: "%Y%m%d.%H%M" }}';
function isExcluded(url) {
for (const rule of exclude) {
if (url.indexOf(rule) != -1) {
return true;
}
}
return false;
}
self.addEventListener('install', (e) => {
self.skipWaiting();
e.waitUntil(
caches.open(cacheName).then((cache) => {
return cache.addAll(include);
})
);
});
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then((r) => {
/* console.log('[Service Worker] Fetching resource: ' + e.request.url); */
return r || fetch(e.request).then((response) => {
return caches.open(cacheName).then((cache) => {
if (!isExcluded(e.request.url)) {
/* console.log('[Service Worker] Caching new resource: ' + e.request.url); */
cache.put(e.request, response.clone());
}
return response;
});
});
})
);
});
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(keyList.map((key) => {
if(key !== cacheName) {
return caches.delete(key);
}
}));
})
);
});

View File

@@ -13,17 +13,21 @@ title: Categories
{% for category in sort_categories %}
{% assign category_name = category | first %}
{% assign posts_of_category = category | last %}
{% assign first_post = posts_of_category[0] %}
{% assign first_post = posts_of_category | first %}
{% if category_name == first_post.categories[0] %}
{% assign sub_categories = "" %}
{% assign sub_categories = "" | split: "" %}
{% for post in posts_of_category %}
{% if post.categories.size > 1 %}
{% assign sub_categories = sub_categories | append: post.categories[1] | append: "|" %}
{% assign second_category = post.categories[1] %}
{% if second_category %}
{% unless sub_categories contains second_category %}
{% assign sub_categories = sub_categories | push: second_category %}
{% endunless %}
{% endif %}
{% endfor %}
{% assign sub_categories = sub_categories | split: "|" | uniq | sort %}
{% assign sub_categories = sub_categories | sort %}
{% assign sub_categories_size = sub_categories | size %}
<div class="card categories">
@@ -35,10 +39,11 @@ title: Categories
{% else %}
<i class="far fa-folder fa-fw"></i>
{% endif %}
<a href="{{ site.baseurl }}/categories/{{ category_name | replace: ' ', '-' | downcase | url_encode }}/">{{ category_name }}</a>
<a href="{{ site.baseurl }}/categories/{{ category_name | replace: ' ', '-' | downcase | url_encode }}/"
class="ml-1 mr-2">{{ category_name }}</a>
<!-- content count -->
{% assign top_posts_size = site.categories[category_name] | size %}
<span class="text-muted small font-weight-light pl-2">
<span class="text-muted small font-weight-light">
{% if sub_categories_size > 0 %}
{{ sub_categories_size }}
{% if sub_categories_size > 1 %}categories{% else %}category{% endif %},
@@ -65,9 +70,11 @@ title: Categories
<ul class="list-group">
{% for sub_category in sub_categories %}
<li class="list-group-item">
<i class="far fa-folder fa-fw"></i>&nbsp;<a href="{{ site.baseurl }}/categories/{{ sub_category | replace: ' ', '-' | downcase | url_encode }}/">{{ sub_category }}</a>
<i class="far fa-folder fa-fw"></i>
<a href="{{ site.baseurl }}/categories/{{ sub_category | replace: ' ', '-' | downcase | url_encode }}/"
class="ml-1 mr-2">{{ sub_category }}</a>
{% assign posts_size = site.categories[sub_category] | size %}
<span class="text-muted small font-weight-light pl-2">{{ posts_size }}
<span class="text-muted small font-weight-light">{{ posts_size }}
post{% if posts_size > 1 %}s{% endif %}
</span>
</li>

View File

@@ -17,7 +17,7 @@ CONTAINER=${WORK_DIR}/.container
DEST=${WORK_DIR}/_site
help() {
_help() {
echo "Usage:"
echo
echo " bash build.sh [options]"
@@ -29,7 +29,7 @@ help() {
}
init() {
_init() {
cd $WORK_DIR
if [[ -d $CONTAINER ]]; then
@@ -40,18 +40,19 @@ init() {
jekyll clean
fi
temp=$(mktemp -d)
cp -r * $temp
cp -r .git $temp
mv $temp $CONTAINER
local _temp=$(mktemp -d)
cp -r * $_temp
cp -r .git $_temp
mv $_temp $CONTAINER
}
build() {
_build() {
cd $CONTAINER
echo "$ cd $(pwd)"
python _scripts/py/init_all.py
bash _scripts/sh/create_pages.sh
bash _scripts/sh/dump_lastmod.sh
CMD+=" -d ${DEST}"
echo "\$ $CMD"
@@ -70,10 +71,10 @@ build() {
}
check_unset() {
_check_unset() {
if [[ -z ${1:+unset} ]]
then
help
_help
exit 1
fi
}
@@ -85,36 +86,36 @@ main() {
opt="$1"
case $opt in
-b|--baseurl)
check_unset $2
_check_unset $2
if [[ $2 == \/* ]]
then
CMD+=" -b $2"
else
help
_help
exit 1
fi
shift
shift
;;
-d|--destination)
check_unset $2
_check_unset $2
DEST=$(realpath $2)
shift;
shift;
;;
-h|--help)
help
_help
exit 0
;;
*) # unknown option
help
_help
exit 1
;;
esac
done
init
build
_init
_build
}
main "$@"

View File

@@ -15,16 +15,26 @@ LASTMOD=false
WORK_DIR=$(dirname $(dirname $(realpath "$0")))
check_status() {
if [[ ! -z $(git status _posts -s) ]]; then
echo "Warning: Commit the changes of the directory '_posts' first."
git status -s | grep '_posts'
exit 1
fi
local _watching_dirs=(
"_post"
"_data")
for i in "${!_watching_dirs[@]}"
do
local _dir=${_watching_dirs[${i}]}
if [[ ! -z $(git status $_dir -s) ]]; then
echo "Warning: Commit the changes of the directory '$_dir' first."
git status -s | grep $_dir
exit 1
fi
done
}
update_files() {
python _scripts/py/init_all.py
bash _scripts/sh/create_pages.sh
bash _scripts/sh/dump_lastmod.sh
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
}
@@ -49,8 +59,8 @@ commit() {
TAGS=true
fi
if [[ ! -z $(git status _posts -s) ]]; then
git add _posts/
if [[ ! -z $(git status _data -s) ]]; then
git add _data
if [[ $CATEGORIES = true || $TAGS = true ]]; then
msg+=","
else

View File

@@ -58,6 +58,11 @@ function compress() {
if [[ -d "$src" ]]; then
compress $src $2 $item # recursion
else
if [[ -z $(git status $src -s) ]]; then
continue
fi
if [[ ! -d "$2/${sub_dir}" ]]; then
mkdir -p $2/${sub_dir}
fi

View File

@@ -21,7 +21,7 @@ cmd="bundle exec jekyll s"
realtime=false
help() {
_help() {
echo "Usage:"
echo
echo " bash run.sh [options]"
@@ -36,7 +36,7 @@ help() {
}
cleanup() {
_cleanup() {
if [[ -d _site || -d .jekyll-cache ]]; then
jekyll clean
fi
@@ -46,7 +46,7 @@ cleanup() {
}
init() {
_init() {
if [[ -d ${WORK_DIR}/${CONTAINER} ]]; then
rm -rf ${WORK_DIR}/${CONTAINER}
@@ -57,19 +57,19 @@ init() {
cp -r ${WORK_DIR}/.git $temp
mv $temp ${WORK_DIR}/${CONTAINER}
trap cleanup INT
trap _cleanup INT
}
check_unset() {
_check_unset() {
if [[ -z ${1:+unset} ]]; then
help
_help
exit 1
fi
}
check_command() {
_check_command() {
if [[ -z $(command -v $1) ]]; then
echo "Error: command '$1' not found !"
echo "Hint: Get '$1' on <$2>"
@@ -79,10 +79,11 @@ check_command() {
main() {
init
_init
cd ${WORK_DIR}/${CONTAINER}
python _scripts/py/init_all.py
bash _scripts/sh/create_pages.sh
bash _scripts/sh/dump_lastmod.sh
if [[ $realtime = true ]]; then
fswatch -0 -e "\\$CONTAINER" -e "\.git" ${WORK_DIR} | xargs -0 -I {} bash ./${SYNC_TOOL} {} $WORK_DIR . &
@@ -98,24 +99,24 @@ do
opt="$1"
case $opt in
-H|--host)
check_unset $2
_check_unset $2
cmd+=" -H $2"
shift # past argument
shift # past value
;;
-P|--port)
check_unset $2
_check_unset $2
cmd+=" -P $2"
shift
shift
;;
-b|--baseurl)
check_unset $2
_check_unset $2
if [[ $2 == \/* ]]
then
cmd+=" -b $2"
else
help
_help
exit 1
fi
shift
@@ -126,20 +127,21 @@ do
shift
;;
-r|--realtime)
check_command fswatch 'http://emcrisostomo.github.io/fswatch/'
_check_command fswatch 'http://emcrisostomo.github.io/fswatch/'
realtime=true
shift
;;
-h|--help)
help
_help
exit 0
;;
*)
# unknown option
help
_help
exit 1
;;
esac
done
main