1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-19 14:14:17 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Cotes Chung
db82f71515 Bump version to 4.0.0 2021-04-30 14:10:23 +08:00
64 changed files with 450 additions and 841 deletions

View File

@@ -16,4 +16,4 @@ labels: question
- [ ] My question is based on the latest code of `master` branch. - [ ] My question is based on the latest code of `master` branch.
## Description ## Description
<!-- Please describe your question in detail. --> <!-- Please describe your question in detial. -->

View File

@@ -1,18 +0,0 @@
name: Intercept bad issues
on:
issues:
types: [opened, edited]
jobs:
auto_close_issues:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Auto close issues that did not follow template
uses: lucasbento/auto-close-issues@v1.0.2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template. Please DO NOT open another similar issue, try to edit the current issue according to the template, then it will be reopened automatically."
closed-issues-label: "🙁 Not following issue template"

View File

@@ -0,0 +1,20 @@
name: "Intercept bad issue/PRs"
on:
issues:
types: [opened]
pull_request:
types: [opened]
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Auto close issues/pr that did not follow template
uses: roots/issue-closer@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-pattern: "(\\[x\\]|\\[X\\]) I have read"
issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template."
pr-pattern: "(\\[x\\]|\\[X\\]) (Bug fix|New feature|Breaking change|Documentation update)|@dependabot"
pr-close-message: ":wave: Hi @${pull_request.user.login},\n\nThis PR is being automatically closed because it does not follow the PR template."

5
.gitignore vendored
View File

@@ -1,9 +1,6 @@
# hidden files # hidden files
.* .*
!.git* !.github
!.editorconfig
!.nojekyll
!.travis.yml
# bundler cache # bundler cache
_site _site

View File

@@ -1,70 +1,47 @@
<div align="right"> # Chirpy
<a href="https://github.com/cotes2020/jekyll-theme-chirpy#readme">EN</a> |
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md">中文 (简体)</a>
</div>
<div align="center"> Language: English | [简体中文](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md)
<h1>Chirpy Jekyll Theme</h1>
<p>
<a href="https://rubygems.org/gems/jekyll-theme-chirpy">
<img alt="Gem Version" src="https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen"></img>
</a>
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush">
<img alt="Build Status" src="https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push"></img>
</a>
<a href="https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard">
<img alt="Codacy Badge" src="https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b"></img>
</a>
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE">
<img alt="GitHub license" src="https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg"></img>
</a>
<a href="https://996.icu">
<img alt="996.icu" src="https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg"></img>
</a>
</p>
</div>
A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation. Designed to help you easily record and share your knowledge. [![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)](https://rubygems.org/gems/jekyll-theme-chirpy)
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b)](https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard)
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
[Live Demo »](https://chirpy.cotes.info) A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation. Designed to help you record and share your knowledge easily. [Live Demo »](https://chirpy.cotes.info)
<p align="center"> [![Devices Mockup](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png)](https://chirpy.cotes.info)
<a href="https://chirpy.cotes.info">
<img alt="Devices Mockup" src="https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png"></img>
</a>
</p>
## Features ## Features
- Localized Layout
- Configurable Theme Mode
- Pinned Posts - Pinned Posts
- Hierarchical Categories - Configurable theme mode
- Last Modified Date for Posts - Double-level Categories
- Last modified date for posts
- Table of Contents - Table of Contents
- Automatically Recommend Related Posts - Automatically recommend related posts
- Syntax Highlighting - Syntax highlighting
- Mathematical Expressions - Mathematical expressions
- Mermaid Diagram & Flowchart - Mermaid diagram & flowchart
- Search - Search
- Atom Feeds - Atom Feeds
- Disqus Comments - Disqus Comments
- Google Analytics - Google Analytics
- GA Pageviews Reporting (Advanced) - GA Pageviews reporting (Advanced)
- SEO & Performance Optimization - SEO and Performance Optimization
## Prerequisites ## Prerequisites
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`. Please note that the version of `Ruby` must meet the requirements of the theme on [RubyGems.org](https://rubygems.org/gems/jekyll-theme-chirpy). Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
## Installation ## Installation
There are two ways to get the theme: There are two ways to get the theme:
- **[Install from RubyGems](#install-from-rubygems)** - Easy to update, isolate irrelevant project files so you can focus on writing. - **Install from RubyGems** - Easy to update, isolate irrelevant project files so you can focus on writing.
- **[Fork on GitHub](#fork-on-github)** - Convenient for custom development, but difficult to update, only suitable for web developers. - **Fork on GitHub** - Convenient for custom development, but difficult to update, only suitable for web developers.
### Install from RubyGems ### Installing the Theme Gem
Add this line to your Jekyll site's `Gemfile`: Add this line to your Jekyll site's `Gemfile`:
@@ -84,19 +61,15 @@ And then execute:
$ bundle $ bundle
``` ```
Next, go to the installed local theme path: Finally, copy the required files from the theme's gem (for detailed files, see [starter project][starter]) to your Jekyll site.
```console > **Hint**: To locate the installed themes gem, execute:
$ cd "$(bundle info --path jekyll-theme-chirpy)"
```
And then copy the critical files (for details, see [starter project][starter]) from the theme's gem to your Jekyll site.
> ⚠️ **Watch out for duplicate files!**
> >
> If your Jekyll site is created by the `jekyll new` command, there will be `index.markdown` and `about.markdown` in the root directory of your site. Please be sure to remove them, otherwise they will overwrite the `index.html` and `_tabs/about.html` from this project, resulting in blank or messy pages. > ```console
> $ bundle info --path jekyll-theme-chirpy
> ```
As an alternative, which we recommend, you can create a Jekyll site [**using the starter template**][use-starter] to save time copying files from the theme's gem. We've prepared everything you need there! Or you can [**use the starter template**][use-starter] to create a Jekyll site to save time copying files from the theme's gem. We have prepared everything for you there!
### Fork on GitHub ### Fork on GitHub
@@ -138,12 +111,6 @@ Update the variables of `_config.yml` as needed. Some of them are typical option
- `timezone` - `timezone`
- `lang` - `lang`
### Customing Stylesheet
If you need to customize stylesheet, copy the theme's `assets/css/style.scss` to the same path on your Jekyll site, and then add the custom style at the end of the style file.
Starting from `v4.1.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`, create a new file `_sass/variables-hook.scss` and assign new values to the target variable in it.
### Running Local Server ### Running Local Server
You may want to preview the site contents before publishing, so just run it by: You may want to preview the site contents before publishing, so just run it by:
@@ -214,7 +181,7 @@ Unless you specified the output path, the generated site files will be placed in
## Documentation ## Documentation
For more details and a better reading experience, please check out the [tutorials on the demo site](https://chirpy.cotes.info/categories/tutorial/). In the meanwhile, a copy of the tutorial is also available on the [Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Please note that the tutorials on the demo website or Wiki are based on the latest release, and the features of `master` branch usually ahead of the documentation. For more details and a better reading experience, please check out the [tutorials on the demo site](https://chirpy.cotes.info/categories/tutorial/). In the meanwhile, a copy of the tutorial is also available on the [Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki).
## Contributing ## Contributing

View File

@@ -7,16 +7,14 @@ theme: jekyll-theme-chirpy
# change below value to '/projectname'. # change below value to '/projectname'.
baseurl: '' baseurl: ''
# The language of the site layout http://www.lingoes.net/en/translator/langcode.htm # the HTML language tag https://www.w3.org/International/questions/qa-choosing-language-tags
# Go to folder '_data/locales' to check the available language options lang: en-US
lang: en
# Change to your timezone http://www.timezoneconverter.com/cgi-bin/findzone/findzone # Change to your timezone http://www.timezoneconverter.com/cgi-bin/findzone/findzone
timezone: Asia/Shanghai timezone: Asia/Shanghai
# jekyll-seo-tag settings https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md # jekyll-seo-tag settings https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
# -------------------------- # --------------------------
title: Chirpy # the main title title: Chirpy # the main title
tagline: A text-focused Jekyll theme # it will display as the sub-title tagline: A text-focused Jekyll theme # it will display as the sub-title
@@ -49,9 +47,7 @@ social:
# - https://www.linkedin.com/in/username # - https://www.linkedin.com/in/username
google_site_verification: google_meta_tag_verification # change to your verification string google_site_verification: google_meta_tag_verification # change to your verification string
# --------------------------
# ↑ --------------------------
google_analytics: google_analytics:
id: '' # fill in your Google Analytics ID id: '' # fill in your Google Analytics ID

7
_data/date_format.yml Normal file
View File

@@ -0,0 +1,7 @@
# The date format
tooltip: "%a, %b %e, %Y, %l:%M %p %z"
post:
long: "%b %e, %Y"
short: "%b %e"

19
_data/label.yml Normal file
View File

@@ -0,0 +1,19 @@
# The label text of site.
panel:
lastmod: Recent Update
trending_tags: Trending Tags
toc: Contents
post:
relate_posts: Further Reading
share: Share
button:
next: Newer
previous: Older
search_hint: Search # text show on search bar
pin_prompt: Pinned # pinned prompt
read_time_unit: min # see posts' time to read

View File

@@ -1,87 +0,0 @@
# The layout text of site
# ----- Commons label -----
layout:
post: Post
category: Category
tag: Tag
# The tabs of sidebar
tabs:
# format: <filename_without_extension>: <value>
home: Home
categories: Categories
tags: Tags
archives: Archives
about: About
# text displayed in the search bar
search:
hint: search
cancel: Cancel
panel:
lastmod: Recent Update
trending_tags: Trending Tags
toc: Contents
# The liquid date format http://strftime.net/
date_format:
tooltip: '%a, %b %e, %Y, %l:%M %p %z'
post:
long: '%b %e, %Y'
short: '%b %e'
archive_month: '%b'
copyright:
# Shown at the bottom of the post
license:
template: This post is licensed under :LICENSE_NAME by the author.
name: CC BY 4.0
link: https://creativecommons.org/licenses/by/4.0/
# Displayed in the footer
brief: Some rights reserved.
verbose: >-
Except where otherwise noted, the blog posts on this site are licensed
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.
meta: Powered by :PLATFORM with :THEME theme.
not_found:
statment: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
hint_template: :HEAD_BAK to try finding it again, or search for it on the :ARCHIVES_PAGE.
head_back: Head back Home
archives_page: Archives page
# ----- Posts related labels -----
post:
published: 'on'
updated: Updated
timeago:
day: days ago
hour: hours ago
minute: minutes ago
just_now: just now
words: words
pageview_measure: views
read_time:
unit: min
prompt: read
relate_posts: Further Reading
share: Share
button:
next: Newer
previous: Older
copy:
title: Copy link
succeed: Link copied successfully!
# pinned prompt of posts list on homepage
pin_prompt: Pinned
# categories page
categories:
category_measure: categories
post_measure: posts

View File

@@ -1,86 +0,0 @@
# The layout text of site
# ----- Commons label -----
layout:
post: 文章
category: 分类
tag: 标签
# The tabs of sidebar
tabs:
# format: <filename_without_extension>: <value>
home: 首页
categories: 分类
tags: 标签
archives: 归档
about: 关于
# text displayed in the search bar
search:
hint: 搜索
cancel: 取消
panel:
lastmod: 最近更新
trending_tags: 热门标签
toc: 文章内容
# The liquid date format http://strftime.net/
date_format:
tooltip: '%F, %R %z'
post:
long: '%F'
short: '%m-%d'
archive_month: '%m月'
copyright:
# Shown at the bottom of the post
license:
template: 本文由作者按照 :LICENSE_NAME 进行授权
name: CC BY 4.0
link: https://creativecommons.org/licenses/by/4.0/
# Displayed in the footer
brief: 保留部分权利。
verbose: >-
除非另有说明,本网站上的博客文章均由作者按照知识共享署名 4.0 国际 (CC BY 4.0) 许可协议进行授权。
meta: 本站由 :PLATFORM 生成,采用 :THEME 主题。
not_found:
statment: 抱歉,我们放错了该 URL或者它指向了不存在的内容。
hint_template: :HEAD_BAK尝试再次查找它或在:ARCHIVES_PAGE上搜索它。
head_back: 返回主页
archives_page: 归档页面
# ----- Posts related labels -----
post:
published: 发表于
updated: 更新于
timeago:
day: 天前
hour: 小时前
minute: 分钟前
just_now: 刚刚
words:
pageview_measure: 次浏览
read_time:
unit: 分钟
prompt: 阅读
relate_posts: 相关文章
share: 分享
button:
next: 下一篇
previous: 上一篇
copy:
title: 分享链接
succeed: 链接已复制!
# pinned prompt of posts list on homepage
pin_prompt: 顶置
# categories page
categories:
category_measure: 个分类
post_measure: 篇文章

11
_data/rights.yml Normal file
View File

@@ -0,0 +1,11 @@
# License data
license:
name: CC BY 4.0
link: "https://creativecommons.org/licenses/by/4.0/"
brief: Some rights reserved.
verbose: >-
Except where otherwise noted, the blog posts on this site are licensed
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.

View File

@@ -8,28 +8,21 @@
<p class="mb-0"> <p class="mb-0">
© {{ 'now' | date: "%Y" }} © {{ 'now' | date: "%Y" }}
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>. <a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
{% if site.data.locales[site.lang].copyright.brief %} {% if site.data.rights.brief %}
<span data-toggle="tooltip" data-placement="top" <span data-toggle="tooltip" data-placement="top"
title="{{ site.data.locales[site.lang].copyright.verbose }}">{{ site.data.locales[site.lang].copyright.brief }}</span> title="{{ site.data.rights.verbose }}">{{ site.data.rights.brief }}</span>
{% endif %} {% endif %}
</p> </p>
</div> </div>
<div class="footer-right"> <div class="footer-right">
<p class="mb-0"> <p class="mb-0">
{% capture _platform %} Powered by
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a> <a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
{% endcapture %} with
<a href="https://github.com/cotes2020/jekyll-theme-chirpy"
{% capture _theme %} target="_blank" rel="noopener">Chirpy</a>
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a> theme.
{% endcapture %}
{{ site.data.locales[site.lang].meta
| default: 'Powered by :PLATFORM with :THEME theme.'
| replace: ':PLATFORM', _platform | replace: ':THEME', _theme
}}
</p> </p>
</div> </div>

View File

@@ -8,12 +8,6 @@
{% if page.layout == 'home' or page.layout == 'post' %} {% if page.layout == 'home' or page.layout == 'post' %}
<!-- i18n for timeago.js -->
<meta name="day-prompt" content="{{ site.data.locales[site.lang].post.timeago.day | default: "d ago" }}">
<meta name="hour-prompt" content="{{ site.data.locales[site.lang].post.timeago.hour | default: "hr ago" }}">
<meta name="minute-prompt" content="{{ site.data.locales[site.lang].post.timeago.minute | default: "min ago" }}">
<meta name="justnow-prompt" content="{{ site.data.locales[site.lang].post.timeago.just_now | default: "just now" }}">
{% if site.google_analytics.pv.proxy_endpoint %} {% if site.google_analytics.pv.proxy_endpoint %}
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}"> <meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
{% endif %} {% endif %}
@@ -68,8 +62,13 @@
{% include css-selector.html %} {% include css-selector.html %}
<!-- JavaScript --> <!-- JavaScripts -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
<script defer
src="https://cdn.jsdelivr.net/combine/npm/popper.js@1.15.0,npm/bootstrap@4/dist/js/bootstrap.min.js"></script>
{% include js-selector.html %}
</head> </head>

View File

@@ -2,19 +2,18 @@
JS selector for site. JS selector for site.
--> -->
<!-- layout specified -->
{% if page.layout == 'home' or page.layout == 'post' %} {% if page.layout == 'home' or page.layout == 'post' %}
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %} {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<!-- pv-report needs countup.js --> <!-- pv-report needs countup.js -->
<script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></script> <script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></script>
<script defer src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script> <script async src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if page.layout == 'post' or page.layout == 'page' %} {% if page.layout == 'post' or page.layout == 'page' %}
<!-- image lazy-loading & popup --> <!-- image lazy-loading & popup -->
<script src="https://cdn.jsdelivr.net/combine/npm/lozad/dist/lozad.min.js,npm/magnific-popup@1/dist/jquery.magnific-popup.min.js"></script> <script async
src="https://cdn.jsdelivr.net/combine/npm/lozad/dist/lozad.min.js,npm/magnific-popup@1/dist/jquery.magnific-popup.min.js"></script>
{% endif %} {% endif %}
{% if page.layout == 'home' {% if page.layout == 'home'
@@ -52,10 +51,6 @@
</script> </script>
{% endif %} {% endif %}
<!-- commons -->
<script src="https://cdn.jsdelivr.net/combine/npm/popper.js@1.16.1,npm/bootstrap@4/dist/js/bootstrap.min.js"></script>
{% if jekyll.environment == 'production' %} {% if jekyll.environment == 'production' %}
<!-- PWA --> <!-- PWA -->
<script defer src="{{ '/app.js' | relative_url }}"></script> <script defer src="{{ '/app.js' | relative_url }}"></script>

View File

@@ -1,13 +0,0 @@
{% comment %}
Remove the zero padding from a month/day string
{% endcomment %}
{% assign ret = include.date_str %}
{% assign _first_chat = ret | slice: 0 %}
{% if _first_chat == '0' %}
{% assign _last_idx = ret.size | minus: 1 %}
{% assign ret = ret | slice: 1, _last_idx %}
{% endif %}
{{ ret | replace: ' 0', ' ' }}

View File

@@ -11,7 +11,7 @@
{% if update_list.size > 0 %} {% if update_list.size > 0 %}
<div id="access-lastmod" class="post"> <div id="access-lastmod" class="post">
<span>{{- site.data.locales[site.lang].panel.lastmod | default: 'Recent Update' -}}</span> <span>{{- site.data.label.panel.lastmod | default: 'Recent Update' -}}</span>
<ul class="post-content pl-0 pb-1 ml-1 mt-2"> <ul class="post-content pl-0 pb-1 ml-1 mt-2">
{% for item in update_list %} {% for item in update_list %}
@@ -30,7 +30,7 @@
{% if trending_tags.size > 0 %} {% if trending_tags.size > 0 %}
<div id="access-tags"> <div id="access-tags">
<span>{{- site.data.locales[site.lang].panel.trending_tags | default: 'Trending Tags' -}}</span> <span>{{- site.data.label.panel.trending_tags | default: 'Trending Tags' -}}</span>
<div class="d-flex flex-wrap mt-3 mb-1 mr-3"> <div class="d-flex flex-wrap mt-3 mb-1 mr-3">
{% for tag_name in trending_tags %} {% for tag_name in trending_tags %}
@@ -48,7 +48,7 @@
<script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js"></script>
<div id="toc-wrapper" class="pl-0 pr-4 mb-5"> <div id="toc-wrapper" class="pl-0 pr-4 mb-5">
<span class="pl-3 pt-2 mb-2"> <span class="pl-3 pt-2 mb-2">
{{- site.data.locales[site.lang].panel.toc | default: 'Contents' -}} {{- site.data.label.panel.toc | default: 'Contents' -}}
</span> </span>
<nav id="toc" data-toggle="toc"></nav> <nav id="toc" data-toggle="toc"></nav>
</div> </div>

View File

@@ -5,24 +5,24 @@
<div class="post-navigation d-flex justify-content-between"> <div class="post-navigation d-flex justify-content-between">
{% if page.previous.url %} {% if page.previous.url %}
<a href="{{ site.baseurl }}{{ page.previous.url }}" class="btn btn-outline-primary" <a href="{{ site.baseurl }}{{ page.previous.url }}" class="btn btn-outline-primary"
prompt="{{ site.data.locales[site.lang].post.button.previous | default: 'previous' }}"> prompt="{{ site.data.label.post.button.previous | default: 'previous' }}">
<p>{{ page.previous.title }}</p> <p>{{ page.previous.title }}</p>
</a> </a>
{% else %} {% else %}
<span class="btn btn-outline-primary disabled" <span class="btn btn-outline-primary disabled"
prompt="{{ site.data.locales[site.lang].post.button.previous | default: 'previous' }}"> prompt="{{ site.data.label.post.button.previous | default: 'previous' }}">
<p>-</p> <p>-</p>
</span> </span>
{% endif %} {% endif %}
{% if page.next.url %} {% if page.next.url %}
<a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary" <a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary"
prompt="{{ site.data.locales[site.lang].post.button.next | default: 'next' }}"> prompt="{{ site.data.label.post.button.next | default: 'next' }}">
<p>{{ page.next.title }}</p> <p>{{ page.next.title }}</p>
</a> </a>
{% else %} {% else %}
<span class="btn btn-outline-primary disabled" <span class="btn btn-outline-primary disabled"
prompt="{{ site.data.locales[site.lang].post.button.next | default: 'next' }}"> prompt="{{ site.data.label.post.button.next | default: 'next' }}">
<p>-</p> <p>-</p>
</span> </span>
{% endif %} {% endif %}

View File

@@ -2,14 +2,13 @@
The paginator for post list on HomgPage. The paginator for post list on HomgPage.
--> -->
<ul class="pagination align-items-center mt-4 mb-0 pl-lg-2"> <ul class="pagination mt-4 mb-0 pl-lg-2">
<!-- left arrow --> <!-- left arrow -->
{% if paginator.previous_page %} {% if paginator.previous_page %}
{% assign prev_url = paginator.previous_page_path | relative_url %} {% assign prev_url = paginator.previous_page_path | relative_url %}
{% else %} {% else %}
{% assign prev_url = "#" %} {% assign prev_url = "#" %}
{% endif %} {% endif %}
<li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}"> <li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
<a class="page-link btn-box-shadow" href="{{ prev_url }}" aria-label="previous-page"> <a class="page-link btn-box-shadow" href="{{ prev_url }}" aria-label="previous-page">
<i class="fas fa-angle-left"></i> <i class="fas fa-angle-left"></i>
@@ -66,19 +65,12 @@
{% endfor %} {% endfor %}
<!-- mobile pagination -->
<li class="page-index align-middle">
<span>{{ paginator.page }}</span>
<span class="text-muted">/ {{ paginator.total_pages }}</span>
</li>
<!-- right arrow --> <!-- right arrow -->
{% if paginator.next_page_path %} {% if paginator.next_page_path %}
{% assign next_url = paginator.next_page_path | relative_url %} {% assign next_url = paginator.next_page_path | relative_url %}
{% else %} {% else %}
{% assign next_url = "#" %} {% assign next_url = "#" %}
{% endif %} {% endif %}
<li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}"> <li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
<a class="page-link btn-box-shadow" href="{{ next_url }}" aria-label="next-page"> <a class="page-link btn-box-shadow" href="{{ next_url }}" aria-label="next-page">
<i class="fas fa-angle-right"></i> <i class="fas fa-angle-right"></i>

View File

@@ -3,7 +3,7 @@
--> -->
<div class="share-wrapper"> <div class="share-wrapper">
<span class="share-label text-muted mr-1">{{ site.data.locales[site.lang].post.share | default: 'Share' }}</span> <span class="share-label text-muted mr-1">{{ site.data.label.post.share | default: 'Share' }}</span>
<span class="share-icons"> <span class="share-icons">
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %} {% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
{% assign url = page.url | absolute_url %} {% assign url = page.url | absolute_url %}
@@ -16,10 +16,8 @@
</a> </a>
{% endfor %} {% endfor %}
<i class="fa-fw fas fa-link small" onclick="copyLink('', '{{ site.data.locales[site.lang].post.button.copy.succeed }}')" <i class="fa-fw fas fa-link small" onclick="copyLink()"
data-toggle="tooltip" data-placement="top" data-toggle="tooltip" data-placement="top" title="Copy link"></i>
title="{{ site.data.locales[site.lang].post.button.copy.title }}">
</i>
</span> </span>
</div> </div>

View File

@@ -1,11 +1,9 @@
<!-- <!--
Calculate the post's reading time, and display the word count in tooltip Calculate the post's reading time, and display the word count in tooltip
--> -->
{% assign words = include.content | strip_html | number_of_words: "auto" %} {% assign words = include.content | strip_html | number_of_words: "auto" %}
<!-- words per minute --> <!-- words per minute -->
{% assign wpm = 180 %} {% assign wpm = 180 %}
{% assign min_time = 1 %} {% assign min_time = 1 %}
@@ -15,15 +13,7 @@
{% assign read_time = min_time %} {% assign read_time = min_time %}
{% endunless %} {% endunless %}
{% capture read_prompt %}
{{- site.data.locales[site.lang].post.read_time.prompt | default: "read" -}}
{% endcapture %}
<!-- return element --> <!-- return element -->
<span class="readtime" data-toggle="tooltip" data-placement="bottom" <span class="readtime" data-toggle="tooltip" data-placement="bottom" title="{{ words }} words">
title="{{ words }} {{ site.data.locales[site.lang].post.words | default: "words" }}"> {{- read_time -}}{{" "}}{{- site.data.label.read_time_unit | default: "min" -}}
{{- read_time -}}{{" "}}{{- site.data.locales[site.lang].post.read_time.unit | default: "min" -}}
{%- if include.prompt -%}
{% unless site.lang contains 'zh' %}{{" "}}{% endunless %}{{ read_prompt }}
{%- endif -%}
</span> </span>

View File

@@ -8,7 +8,6 @@
In order to allow a wide table to scroll horizontally, In order to allow a wide table to scroll horizontally,
we suround the markdown table with `<div class="table-wrapper">` and `</div>` we suround the markdown table with `<div class="table-wrapper">` and `</div>`
--> -->
{% if _content contains '<table>' %} {% if _content contains '<table>' %}
{% assign _content = _content {% assign _content = _content
| replace: '<table>', '<div class="table-wrapper"><table>' | replace: '<table>', '<div class="table-wrapper"><table>'
@@ -22,7 +21,6 @@
https://github.com/penibelst/jekyll-compress-html/issues/101 https://github.com/penibelst/jekyll-compress-html/issues/101
https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901 https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
--> -->
{% if _content contains '<pre class="highlight">' %} {% if _content contains '<pre class="highlight">' %}
{% assign _content = _content {% assign _content = _content
| replace: '<div class="highlight"><pre class="highlight"><code', '<div class="highlight"><code' | replace: '<div class="highlight"><pre class="highlight"><code', '<div class="highlight"><code'
@@ -31,20 +29,14 @@
{% endif %} {% endif %}
<!-- Add attribute 'hide-bullet' to the checkbox list --> <!-- Add attribute 'hide-bullet' to the checkbox list -->
{% if _content contains '<li class="task-list-item"><' %} {% if _content contains '<li class="task-list-item"><' %}
{% assign _content = _content {% assign _content = _content
| replace: '"task-list-item"><', '"task-list-item" hide-bullet><' | replace: '"task-list-item"><', '"task-list-item" hide-bullet><'
%} %}
{% endif %} {% endif %}
<!-- images -->
{% if _content contains '<img src="' %} {% if _content contains '<img src="' %}
<!-- add CDN prefix if it exists -->
{% if site.img_cdn != '' %} {% if site.img_cdn != '' %}
{% assign img_path_replacement = '<img src="' | append: site.img_cdn | append: '/' %} {% assign img_path_replacement = '<img src="' | append: site.img_cdn | append: '/' %}
{% else %} {% else %}
@@ -54,77 +46,16 @@
{% assign _content = _content | replace: '<img src="/', img_path_replacement %} {% assign _content = _content | replace: '<img src="/', img_path_replacement %}
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> --> <!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
{% assign img_placehodler
= 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' %}
{% assign _content = _content | replace: '<img src="', '<img data-proofer-ignore data-src="' %} {% assign lozad_replacement = '<img src="'
| append: img_placehodler
| append: '" data-src="' %}
<!-- add image placehoder to prevent layout reflow --> {% assign _content = _content | replace: '<img src="', lozad_replacement %}
{% assign _img_content = nil %}
{% assign _images = _content | split: '<img ' %}
{% for _img in _images %}
{% if forloop.first %}
{% assign _img_content = _img %}
{% continue %}
{% endif %}
{% assign _width = nil %}
{% assign _height = nil %}
{% assign _attrs = _img | split: '>' | first | split: ' ' %}
{% for _attr in _attrs %}
{% capture _key %}{{ _attr | split: '=' | first }}{% endcapture %}
{% capture _value %}{{ _attr | split: '=' | last | replace: '"', '' }}{% endcapture %}
{% case _key %}
{% when 'width' %}
{% assign _width = _value %}
{% when 'height' %}
{% assign _height = _value %}
{% endcase %}
{% if _width and _height %}
{% capture _svg %}data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{_width}} {{_height}}'%3E%3C/svg%3E{% endcapture %}
{% assign _img_content = _img_content | append: '<img src="' | append: _svg | append: '" ' | append: _img %}
{% break %}
{% endif %}
{% endfor %}
{% unless _width and _height %}
{% assign _img_content = _img_content | append: '<img ' | append: _img %}
{% endunless %}
{% endfor %}
{% assign _content = _img_content %}
{% endif %} {% endif %}
<!-- Add lang-badge for code snippets -->
{% if _content contains '<div class="language-' %}
{% assign _code_splits = _content | split: '<div class="language-' %}
{% assign _new_content = nil %}
{% for _snippet in _code_splits %}
{% if forloop.first %}
{% assign _new_content = _snippet %}
{% else %}
{% assign _lang = _snippet | split: ' ' | first %}
{% capture _tag_head %}<div lang="{{_lang}}" class="language-{% endcapture %}
{% assign _new_content = _new_content | append: _tag_head | append: _snippet %}
{% endif %}
{% endfor %}
{% if _new_content %}
{% assign _content = _new_content %}
{% endif %}
{% endif %}
<!-- return --> <!-- return -->
{{ _content }} {{ _content }}

View File

@@ -81,7 +81,7 @@
{% if index_list.size > 0 %} {% if index_list.size > 0 %}
<div id="related-posts" class="mt-5 mb-2 mb-sm-4"> <div id="related-posts" class="mt-5 mb-2 mb-sm-4">
<h3 class="pt-2 mt-1 mb-4 ml-1" <h3 class="pt-2 mt-1 mb-4 ml-1"
data-toc-skip>{{ site.data.locales[site.lang].post.relate_posts | default: 'Further Reading' }}</h3> data-toc-skip>{{ site.data.label.post.relate_posts | default: 'Further Reading' }}</h3>
<div class="card-deck mb-4"> <div class="card-deck mb-4">
{% for entry in index_list %} {% for entry in index_list %}
{% assign index = entry | plus: 0 %} {% assign index = entry | plus: 0 %}

View File

@@ -4,7 +4,7 @@
<div id="search-result-wrapper" class="d-flex justify-content-center unloaded"> <div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
<div class="col-12 col-sm-11 post-content"> <div class="col-12 col-sm-11 post-content">
<div id="search-hints"> <div id="search-hints">
<h4 class="text-muted mb-4">{{ site.data.locales[site.lang].panel.trending_tags | default: 'Trending Tags' }}</h4> <h4 class="text-muted mb-4">{{ site.data.label.panel.trending_tags | default: 'Trending Tags' }}</h4>
{% include trending-tags.html %} {% include trending-tags.html %}

View File

@@ -2,7 +2,8 @@
The Side Bar The Side Bar
--> -->
<div id="sidebar" class="d-flex flex-column align-items-end" lang="{{lang}}"> <div id="sidebar" class="d-flex flex-column align-items-end">
<div class="profile-wrapper text-center"> <div class="profile-wrapper text-center">
<div id="avatar"> <div id="avatar">
<a href="{{ '/' | relative_url }}" alt="avatar" class="mx-auto"> <a href="{{ '/' | relative_url }}" alt="avatar" class="mx-auto">
@@ -20,19 +21,19 @@
</div> </div>
<div class="site-title mt-3"> <div class="site-title mt-3">
<a href="{{ '/' | relative_url }}">{{ site.title }}</a> <a href="{{ '/' | relative_url }}">{{- site.title -}}</a>
</div> </div>
<div class="site-subtitle font-italic">{{ site.tagline }}</div>
<div class="site-subtitle font-italic">{{- site.tagline -}}</div>
</div><!-- .profile-wrapper --> </div><!-- .profile-wrapper -->
<ul class="w-100"> <ul class="w-100">
<!-- home --> <!-- home -->
<li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}"> <li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}">
<a href="{{ '/' | relative_url }}" class="nav-link"> <a href="{{ '/' | relative_url }}" class="nav-link">
<i class="fa-fw fas fa-home ml-xl-3 mr-xl-3 unloaded"></i> <i class="fa-fw fas fa-home ml-xl-3 mr-xl-3 unloaded"></i>
<span>{{ site.data.locales[site.lang].tabs.home | default: "home" | upcase }}</span> <span>{{ "HOME" }}</span>
</a> </a>
</li> </li>
<!-- the real tabs --> <!-- the real tabs -->
@@ -40,9 +41,7 @@
<li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}"> <li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}">
<a href="{{ tab.url | relative_url }}" class="nav-link"> <a href="{{ tab.url | relative_url }}" class="nav-link">
<i class="fa-fw {{ tab.icon }} ml-xl-3 mr-xl-3 unloaded"></i> <i class="fa-fw {{ tab.icon }} ml-xl-3 mr-xl-3 unloaded"></i>
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %} <span>{{ tab.title | upcase }}</span>
<span>{{ site.data.locales[site.lang].tabs.[tab_name] | default: tab.title | upcase }}</span>
</a> </a>
</li> <!-- .nav-item --> </li> <!-- .nav-item -->
{% endfor %} {% endfor %}

View File

@@ -3,25 +3,29 @@
See: /assets/js/_utils/timeage.js See: /assets/js/_utils/timeage.js
--> -->
{% assign tooltip_df = site.data.locales[site.lang].date_format.tooltip | default: '%a, %b %e, %Y, %l:%M %p %z' %} {% assign tooltip_df = site.data.date_format.tooltip | default: '%a, %b %e, %Y, %l:%M %p %z' %}
{% assign post_long_df = site.data.locales[site.lang].date_format.post.long | default: '%b %e, %Y' %} {% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
{% assign post_short_df = site.data.locales[site.lang].date_format.post.short | default: '%b %e' %} {% assign post_short_df = site.data.date_format.post.short | default: '%b %e' %}
{% if include.preposition %}
{{ include.preposition }}
{% endif %}
<span class="timeago {% if include.class %}{{ include.class }}{% endif %}" <span class="timeago {% if include.class %}{{ include.class }}{% endif %}"
{% if include.tooltip %} {% if include.tooltip %}
data-toggle="tooltip" data-toggle="tooltip"
data-placement="bottom" data-placement="bottom"
title="{{ include.date | date: tooltip_df }}" title="{{ include.date | date: tooltip_df }}"
{% endif %}> {% endif %}
{%- assign this_year = site.time | date: "%Y" -%}
{%- assign post_year = include.date | date: "%Y" -%} {% if include.prefix %}prefix="{{ include.prefix }} "{% endif%}
{%- if post_year == this_year -%} {% if include.prep %}prep="{{ include.prep }}"{% endif %} >
{% assign this_year = site.time | date: "%Y" %}
{% assign post_year = include.date | date: "%Y" %}
{% if post_year == this_year %}
{{ include.date | date: post_short_df }} {{ include.date | date: post_short_df }}
{%- else -%} {% else %}
{{ include.date | date: post_long_df }} {{ include.date | date: post_long_df }}
{%- endif -%} {% endif %}
<i class="unloaded">{{ include.date | date_to_xmlschema }}</i> <i class="unloaded">{{ include.date | date_to_xmlschema }}</i>
</span> </span>

View File

@@ -8,35 +8,34 @@
{% assign paths = page.url | split: '/' %} {% assign paths = page.url | split: '/' %}
{% if paths.size == 0 or page.layout == 'home' %} {% if paths.size == 0 %}
<!-- index page --> <!-- index page -->
<span>{{ site.data.locales[site.lang].tabs.home | default: 'home' | capitalize }}</span> <span>{{ 'Posts' }}</span>
{% else %} {% else %}
{% for item in paths %} {% for item in paths %}
{% if forloop.first %} {% if forloop.first %}
{% unless page.layout == 'post' %}
<span> <span>
<a href="{{ '/' | relative_url }}"> <a href="{{ '/' | relative_url }}">{{ 'Home' }}</a>
{{ site.data.locales[site.lang].tabs.home | default: 'home' | capitalize }}
</a>
</span> </span>
{% endunless %}
{% elsif forloop.last %} {% elsif forloop.last %}
<span>{{ page.title }}</span>
{% if page.collection == 'tabs' %} {% else %}
<span>{{ site.data.locales[site.lang].tabs[item] | default: page.title }}</span> <span>
{% else %} {% assign url = item %}
<span>{{ page.title }}</span> {% if item == 'posts' and page.layout == 'post' %}
{% assign url = '/' %}
{% endif %} {% endif %}
<a href="{{ url | relative_url }}">
{{ item | capitalize }}
</a>
</span>
{% elsif page.layout == 'category' or page.layout == 'tag' %}
<span>
<a href="{{ item | relative_url }}">
{{ site.data.locales[site.lang].tabs[item] | default: page.title }}
</a>
</span>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@@ -49,12 +48,11 @@
<div id="topbar-title"> <div id="topbar-title">
{% if page.layout == 'home' %} {% if page.layout == 'home' %}
{{- site.data.locales[site.lang].title | default: site.title -}} {{- site.title -}}
{% elsif page.collection == 'tabs' %} {% elsif page.dynamic_title %}
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%} {{- page.title -}}
{{- site.data.locales[site.lang].tabs[tab_key] | default: page.title -}}
{% else %} {% else %}
{{- site.data.locales[site.lang].layout[page.layout] | default: page.layout | capitalize -}} {{- page.layout | capitalize -}}
{% endif %} {% endif %}
</div> </div>
@@ -62,10 +60,10 @@
<span id="search-wrapper" class="align-items-center"> <span id="search-wrapper" class="align-items-center">
<i class="fas fa-search fa-fw"></i> <i class="fas fa-search fa-fw"></i>
<input class="form-control" id="search-input" type="search" <input class="form-control" id="search-input" type="search"
aria-label="search" autocomplete="off" placeholder="{{ site.data.locales[site.lang].search.hint | default: 'Search' | capitalize }}..."> aria-label="search" autocomplete="off" placeholder="{{ site.data.label.search_hint | default: 'Search' }}...">
<i class="fa fa-times-circle fa-fw" id="search-cleaner"></i> <i class="fa fa-times-circle fa-fw" id="search-cleaner"></i>
</span> </span>
<span id="search-cancel" >{{ site.data.locales[site.lang].search.cancel | default: 'Cancel' }}</span> <span id="search-cancel" >Cancel</span>
</div> </div>
</div> </div>

View File

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

View File

@@ -2,7 +2,7 @@
* Copy current page url to clipboard. * Copy current page url to clipboard.
*/ */
function copyLink(url, msg) { function copyLink(url) {
if (!url || 0 === url.length) { if (!url || 0 === url.length) {
url = window.location.href; url = window.location.href;
} }
@@ -13,10 +13,6 @@ function copyLink(url, msg) {
document.execCommand("copy"); document.execCommand("copy");
$temp.remove(); $temp.remove();
let feedback = "Link copied successfully!"; alert("Link copied successfully!");
if (msg && msg.length > 0) {
feedback = msg;
}
alert(feedback);
} }

View File

@@ -11,10 +11,10 @@ $(function() {
return; return;
} }
/* lazy loading */ /* lozy loading */
const imgList = document.querySelectorAll(`${IMG_SCOPE} img[data-src]`); const imgs = document.querySelectorAll(`${IMG_SCOPE} img[data-src]`);
const observer = lozad(imgList); const observer = lozad(imgs);
observer.observe(); observer.observe();
/* popup */ /* popup */
@@ -40,8 +40,9 @@ $(function() {
} }
}); });
/* markup the image links */
$(`${IMG_SCOPE} a`).has('img').addClass('img-link'); /* markup the image links */
$(`${IMG_SCOPE} a`).has("img").addClass('img-link');
}); });

View File

@@ -0,0 +1,20 @@
/**
* Add language indicator to code snippets
*/
$(function() {
const prefix = "language-";
const regex = new RegExp(`^${prefix}([a-z])+$`);
$(`div[class^=${prefix}`).each(function() {
let classes = $(this).attr("class").split(" ");
classes.forEach((_class) => {
if (regex.test(_class)) {
let lang = _class.substring(prefix.length);
$(this).attr("lang", `${lang}`);
}
});
});
});

View File

@@ -10,18 +10,26 @@ $(function() {
let intervalId = void 0; let intervalId = void 0;
const dPrompt = $("meta[name=day-prompt]").attr("content"); function timeago(iso, preposition) {
const hrPrompt = $("meta[name=hour-prompt]").attr("content");
const minPrompt = $("meta[name=minute-prompt]").attr("content");
const justnowPrompt = $("meta[name=justnow-prompt]").attr("content");
function timeago(isoDate, dateStr) {
let now = new Date(); let now = new Date();
let past = new Date(isoDate); let past = new Date(iso);
let prep = (typeof preposition !== "undefined" ? `${preposition} ` : "");
if (past.getFullYear() !== now.getFullYear() if (past.getFullYear() !== now.getFullYear()) {
|| past.getMonth() !== now.getMonth()) { toRefresh -= 1;
return dateStr; return prep + past.toLocaleString("en-US", {
year: "numeric",
month: "short",
day: "numeric"
});
}
if (past.getMonth() !== now.getMonth()) {
toRefresh -= 1;
return prep + past.toLocaleString("en-US", {
month: "short",
day: "numeric"
});
} }
let seconds = Math.floor((now - past) / 1000); let seconds = Math.floor((now - past) / 1000);
@@ -29,29 +37,28 @@ $(function() {
let day = Math.floor(seconds / 86400); let day = Math.floor(seconds / 86400);
if (day >= 1) { if (day >= 1) {
toRefresh -= 1; toRefresh -= 1;
return ` ${day} ${dPrompt}`; return day + " day" + (day > 1 ? "s" : "") + " ago";
} }
let hour = Math.floor(seconds / 3600); let hour = Math.floor(seconds / 3600);
if (hour >= 1) { if (hour >= 1) {
return ` ${hour} ${hrPrompt}`; return hour + " hour" + (hour > 1 ? "s" : "") + " ago";
} }
let minute = Math.floor(seconds / 60); let minute = Math.floor(seconds / 60);
if (minute >= 1) { if (minute >= 1) {
return ` ${minute} ${minPrompt}`; return minute + " minute" + (minute > 1 ? "s" : "") + " ago";
} }
return justnowPrompt; return "just now";
} }
function updateTimeago() { function updateTimeago() {
$(".timeago").each(function() { $(".timeago").each(function() {
if ($(this).children("i").length > 0) { if ($(this).children("i").length > 0) {
let dateStr = $(this).clone().children().remove().end().text();
let node = $(this).children("i"); let node = $(this).children("i");
let iosDate = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */ let date = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */
$(this).text(timeago(iosDate, dateStr)); $(this).text(timeago(date, $(this).attr("prep")));
$(this).append(node); $(this).append(node);
} }
}); });

View File

@@ -3,8 +3,8 @@ layout: page
# The Archives of posts. # The Archives of posts.
--- ---
<div id="archives" class="pl-xl-2">
<div id="archives" class="pl-xl-2">
{% for post in site.posts %} {% for post in site.posts %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %} {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% capture pre_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %} {% capture pre_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
@@ -17,10 +17,9 @@ layout: page
<li> <li>
<div> <div>
{% capture this_day %}{{ post.date | date: "%d" }}{% endcapture %} {% capture this_day %}{{ post.date | date: "%d" }}{% endcapture %}
{% capture _mth_df %}{{ site.data.locales[site.lang].date_format.post.archive_month | default: "%b" }}{% endcapture %} {% capture this_month %}{{ post.date | date: "%b" }}{% endcapture %}
{% capture this_month %}{{ post.date | date: _mth_df }}{% endcapture %}
<span class="date day">{{ this_day }}</span> <span class="date day">{{ this_day }}</span>
<span class="date month small text-muted">{% include no-zero-date.html date_str=this_month %}</span> <span class="date month small text-muted">{{ this_month }}</span>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a> <a href="{{ post.url | relative_url }}">{{ post.title }}</a>
</div> </div>
</li> </li>

View File

@@ -3,6 +3,7 @@ layout: page
# All the Categories of posts # All the Categories of posts
--- ---
{% assign HEAD_PREFIX = "h_" %} {% assign HEAD_PREFIX = "h_" %}
{% assign LIST_PREFIX = "l_" %} {% assign LIST_PREFIX = "l_" %}
@@ -32,23 +33,28 @@ layout: page
<div class="card categories"> <div class="card categories">
<!-- top-category --> <!-- top-category -->
<div id="{{ HEAD_PREFIX }}{{ group_index }}" <div class="card-header d-flex justify-content-between hide-border-bottom"
class="card-header d-flex justify-content-between hide-border-bottom"> id="{{ HEAD_PREFIX }}{{ group_index }}">
<span> <span>
<i class="far fa-folder{% if sub_categories_size > 0 %}-open{% endif %} fa-fw"></i> {% if sub_categories_size > 0 %}
<i class="far fa-folder-open fa-fw"></i>
{% capture _category_url %}/categories/{{ category_name | slugify | url_encode }}/{% endcapture %} {% else %}
<a href="{{ _category_url | relative_url }}" class="ml-1 mr-2">{{ category_name }}</a> <i class="far fa-folder fa-fw"></i>
{% endif %}
<a href="{{ site.baseurl }}/categories/{{ category_name | slugify | url_encode }}/"
class="ml-1 mr-2">
{{ category_name }}
</a>
<!-- content count --> <!-- content count -->
{% assign top_posts_size = site.categories[category_name] | size %} {% assign top_posts_size = site.categories[category_name] | size %}
<span class="text-muted small font-weight-light"> <span class="text-muted small font-weight-light">
{% if sub_categories_size > 0 %} {% if sub_categories_size > 0 %}
{{ sub_categories_size }} {{ sub_categories_size }}
{{ site.data.locales[site.lang].categories.category_measure | default: 'categories' }}, {% if sub_categories_size > 1 %}categories{% else %}category{% endif %},
{% endif %} {% endif %}
{{ top_posts_size }} {{ top_posts_size }}
{{ site.data.locales[site.lang].categories.post_measure | default: 'posts' }} post{% if top_posts_size > 1 %}s{% endif %}
</span> </span>
</span> </span>
@@ -74,14 +80,11 @@ layout: page
{% for sub_category in sub_categories %} {% for sub_category in sub_categories %}
<li class="list-group-item"> <li class="list-group-item">
<i class="far fa-folder fa-fw"></i> <i class="far fa-folder fa-fw"></i>
<a href="{{ site.baseurl }}/categories/{{ sub_category | slugify | url_encode }}/"
{% capture _sub_ctg_url %}/categories/{{ sub_category | slugify | url_encode }}/{% endcapture %} class="ml-1 mr-2">{{ sub_category }}</a>
<a href="{{ _sub_ctg_url | relative_url }}" class="ml-1 mr-2">{{ sub_category }}</a>
{% assign posts_size = site.categories[sub_category] | size %} {% assign posts_size = site.categories[sub_category] | size %}
<span class="text-muted small font-weight-light"> <span class="text-muted small font-weight-light">{{ posts_size }}
{{ posts_size }} post{% if posts_size > 1 %}s{% endif %}
{{ site.data.locales[site.lang].categories.post_measure | default: 'posts' }}
</span> </span>
</li> </li>
{% endfor %} {% endfor %}

View File

@@ -11,13 +11,13 @@ layout: page
</h1> </h1>
<ul class="post-content pl-0"> <ul class="post-content pl-0">
{% assign post_df = site.data.locales[site.lang].date_format.post.long | default: '%b %e, %Y' %} {% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
{% for post in page.posts %} {% for post in page.posts %}
<li class="d-flex justify-content-between pl-md-3 pr-md-3"> <li class="d-flex justify-content-between pl-md-3 pr-md-3">
<a href="{{ post.url | relative_url }}">{{ post.title }}</a> <a href="{{ post.url | relative_url }}">{{ post.title }}</a>
<span class="dash flex-grow-1"></span> <span class="dash flex-grow-1"></span>
<span class="text-muted small">{{ post.date | date: post_df }}</span> <span class="text-muted small">{{ post.date | date: post_long_df }}</span>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>

View File

@@ -11,7 +11,7 @@ layout: compress
{% endif %} {% endif %}
{% endcapture %} {% endcapture %}
<html lang="{{ site.lang | default: 'en' }}" {{ prefer_mode }}> <html lang="{{ site.lang | default: "en-US" }}" {{ prefer_mode }}>
{% include head.html %} {% include head.html %}
@@ -46,8 +46,6 @@ layout: compress
{% include search-loader.html %} {% include search-loader.html %}
{% include js-selector.html %}
</body> </body>
</html> </html>

View File

@@ -3,9 +3,9 @@ layout: page
# The Home page layout # The Home page layout
--- ---
{% assign pinned = site.posts | where: "pin", "true" %}
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
{% assign pinned = site.posts | where_exp: "item", "item.pin == true" %}
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
{% assign posts = "" | split: "" %} {% assign posts = "" | split: "" %}
<!-- Get pinned posts --> <!-- Get pinned posts -->
@@ -39,6 +39,7 @@ layout: page
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<div id="post-list"> <div id="post-list">
{% for post in posts %} {% for post in posts %}
@@ -78,7 +79,7 @@ layout: page
{% if post.pin %} {% if post.pin %}
<div class="pin"> <div class="pin">
<i class="fas fa-thumbtack fa-fw"></i> <i class="fas fa-thumbtack fa-fw"></i>
<span>{{ site.data.locales[site.lang].post.pin_prompt | default: 'Pinned' }}</span> <span>{{ site.data.label.pin_prompt | default: 'Pinned' }}</span>
</div> </div>
{% endif %} {% endif %}

View File

@@ -7,14 +7,7 @@ layout: default
<div class="col-12 col-lg-11 col-xl-8"> <div class="col-12 col-lg-11 col-xl-8">
<div id="page" class="post pb-5 pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 mb-md-4"> <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 %} {% if page.dynamic_title %}
<h1 class="dynamic-title"> <h1 class="dynamic-title">{{ page.title }}</h1>
{% if page.collection == 'tabs' %}
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
{{- site.data.locales[site.lang].tabs[tab_key] | default: page.title -}}
{% else %}
{{- page.title -}}
{% endif %}
</h1>
<div class="post-content"> <div class="post-content">
{{ content }} {{ content }}
</div> </div>

View File

@@ -17,28 +17,24 @@ layout: default
<span class="semi-bold"> <span class="semi-bold">
{{ page.author | default: site.social.name }} {{ page.author | default: site.social.name }}
</span> </span>
{% capture _preposition %}{{ site.data.locales[site.lang].post.published | default: 'on' }}{% endcapture %} {% include timeago.html date=page.date prep="on" tooltip=true %}
{% include timeago.html date=page.date tooltip=true preposition=_preposition %}
</div> </div>
<div> <div>
<!-- lastmod --> <!-- lastmod -->
{% if page.last_modified_at %} {% if page.last_modified_at %}
<span> <span>
{{ site.data.locales[site.lang].post.updated | default: 'Updated' }} {% include timeago.html date=page.last_modified_at
{% include timeago.html date=page.last_modified_at class="lastmod" tooltip=true %} class="lastmod" prefix="Updated" tooltip=true %}
</span> </span>
{% endif %} {% endif %}
<!-- read time --> <!-- read time -->
{% include read-time.html content=content prompt=true %} {% include read-time.html content=content %}
<!-- page views --> <!-- page views -->
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %} {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<span id="pv" class="pageviews"> <span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span>
<i class="fas fa-spinner fa-spin fa-fw"></i>
</span>
{{ site.data.locales[site.lang].post.pageview_measure | default: "views" }}
{% endif %} {% endif %}
</div> </div>
@@ -48,11 +44,7 @@ layout: default
<div class="post-content"> <div class="post-content">
{% if page.image.src %} {% if page.image.src %}
<img src="{{ page.image.src }}" <img src="{{ page.image.src }}" class="preview-img" alt="{{ page.image.alt | default: "Preview Image" }}">
class="preview-img"
alt="{{ page.image.alt | default: "Preview Image" }}"
{% if page.image.width %}width="{{ page.image.width }}"{% endif %}
{% if page.image.height %}height="{{ page.image.height }}"{% endif %}>
{% endif %} {% endif %}
{{ content }} {{ content }}
@@ -63,7 +55,6 @@ layout: default
<!-- categories --> <!-- categories -->
{% if page.categories.size > 0 %} {% if page.categories.size > 0 %}
<div class="post-meta mb-3"> <div class="post-meta mb-3">
<i class="far fa-folder-open fa-fw mr-1"></i> <i class="far fa-folder-open fa-fw mr-1"></i>
{% for category in page.categories %} {% for category in page.categories %}
@@ -88,16 +79,13 @@ layout: default
<div class="post-tail-bottom <div class="post-tail-bottom
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2"> d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
{% if site.data.rights.license %}
<div class="license-wrapper"> <div class="license-wrapper">
{% if site.data.locales[site.lang].copyright.license.template %} This post is licensed under
{% capture _replacement %} <a href="{{ site.data.rights.license.link }}">{{ site.data.rights.license.name }}</a>
<a href="{{ site.data.locales[site.lang].copyright.license.link }}"> by the author.
{{ site.data.locales[site.lang].copyright.license.name }}
</a>
{% endcapture %}
{{ site.data.locales[site.lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
{% endif %}
</div> </div>
{% endif %}
{% include post-sharing.html %} {% include post-sharing.html %}

View File

@@ -3,6 +3,7 @@ layout: page
# The layout for Tag page # The layout for Tag page
--- ---
<div id="page-tag"> <div id="page-tag">
<h1 class="pl-lg-2"> <h1 class="pl-lg-2">
<i class="fa fa-tag fa-fw text-muted"></i> <i class="fa fa-tag fa-fw text-muted"></i>
@@ -10,13 +11,13 @@ layout: page
<span class="lead text-muted pl-2">{{ page.posts | size }}</span> <span class="lead text-muted pl-2">{{ page.posts | size }}</span>
</h1> </h1>
<ul class="post-content pl-0"> <ul class="post-content pl-0">
{% assign post_df = site.data.locales[site.lang].date_format.post.long | default: '%b %e, %Y' %} {% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
{% for post in page.posts %} {% for post in page.posts %}
<li class="d-flex justify-content-between pl-md-3 pr-md-3"> <li class="d-flex justify-content-between pl-md-3 pr-md-3">
<a href="{{ post.url | relative_url }}">{{ post.title }}</a> <a href="{{ post.url | relative_url }}">{{ post.title }}</a>
<span class="dash flex-grow-1"></span> <span class="dash flex-grow-1"></span>
<span class="text-muted small">{{ post.date | date: post_df }}</span> <span class="text-muted small">{{ post.date | date: post_long_df }}</span>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>

View File

@@ -8,8 +8,6 @@ math: true
mermaid: true mermaid: true
image: image:
src: https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png src: https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png
width: 850
height: 585
--- ---
This post is to show Markdown syntax rendering on [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork), you can also use it as an example of writing. Now, let's start looking at text and typography. This post is to show Markdown syntax rendering on [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork), you can also use it as an example of writing. Now, let's start looking at text and typography.
@@ -52,7 +50,7 @@ Fluttering and dancing in the breeze.
### Unordered list ### Unordered list
- Chapter - Chapter
- Section - Setcion
- Paragraph - Paragraph
### Task list ### Task list
@@ -99,34 +97,39 @@ Click the hook will locate the footnote[^footnote], and here is another footnote
- Default (with caption) - Default (with caption)
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="972" height="589" } ![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png)
_Full screen width and center alignment_ _Full screen width and center alignment_
<br> <br>
- Specify width
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="400"}
_400px image width_
- Shadow - Shadow
![Window shadow](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/window.png){: .shadow width="1548" height="864" style="max-width: 90%" } ![Shadow Avatar](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/window.png){: .shadow width="90%" }
_shadow effect (visible in light mode)_ _shadow effect (visible in light mode)_
<br> <br>
- Left aligned - Left aligned
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="972" height="589" style="max-width: 70%" .normal} ![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="350" .normal}
<br> <br>
- Float to left - Float to left
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="972" height="589" style="max-width: 200px" .left} ![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="240" .left}
"A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space." "A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space."
<br> <br>
- Float to right - Float to right
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="972" height="589" style="max-width: 200px" .right} ![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="240" .right}
"A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space." "A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space."
<br> <br>

View File

@@ -84,21 +84,16 @@ Then you can use it like other markdown language: surround the graph code with `
### Preview image ### Preview image
If you want to add an image to the top of the post contents, specify the attribute `src`, `width`, `height` and `alt` for the image: If you want to add an image to the top of the post contents, specify the url and alt attribute for the image:
```yaml ```yaml
--- ---
image: image:
src: /path/to/image/file src: /path/to/image/file
width: 1000 # in pixels
height: 400 # in pixels
alt: image alternative text alt: image alternative text
--- ---
``` ```
Except for `alt`, all other options are necessary, especially the `width` and `height`, which are related to user experience and web page loading performance. Later section ["Image size"](#image-size) will also mention this.
### Image caption ### Image caption
Add italics to the next line of an imagethen it will become the caption and appear at the bottom of the image: Add italics to the next line of an imagethen it will become the caption and appear at the bottom of the image:
@@ -110,10 +105,10 @@ _Image Caption_
### Image size ### Image size
In order to prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image: You can specify the width (and height) of a image with `width`:
```markdown ```markdown
![Desktop View](/assets/img/sample/mockup.png){: width="700" height="400" } ![Desktop View](/assets/img/sample/mockup.png){: width="400"}
``` ```
### Image position ### Image position
@@ -125,19 +120,19 @@ By default, the image is centered, but you can specify the position by using one
Image will be left aligned in below sample: Image will be left aligned in below sample:
```markdown ```markdown
![Desktop View](/assets/img/sample/mockup.png){: .normal } ![Desktop View](/assets/img/sample/mockup.png){: .normal}
``` ```
- **Float to the left** - **Float to the left**
```markdown ```markdown
![Desktop View](/assets/img/sample/mockup.png){: .left } ![Desktop View](/assets/img/sample/mockup.png){: .left}
``` ```
- **Float to the right** - **Float to the right**
```markdown ```markdown
![Desktop View](/assets/img/sample/mockup.png){: .right } ![Desktop View](/assets/img/sample/mockup.png){: .right}
``` ```
> **Limitation**: Once you specify the position of an image, it is forbidden to add the image caption. > **Limitation**: Once you specify the position of an image, it is forbidden to add the image caption.
@@ -147,9 +142,10 @@ By default, the image is centered, but you can specify the position by using one
The screenshots of the program window can be considered to show the shadow effect, and the shadow will be visible in the `light` mode: The screenshots of the program window can be considered to show the shadow effect, and the shadow will be visible in the `light` mode:
```markdown ```markdown
![Desktop View](/assets/img/sample/mockup.png){: .shadow } ![Desktop View](/assets/img/sample/mockup.png){: .shadow}
``` ```
### CDN URL ### CDN URL
If you host the images on the CDN, you can save the time of repeatedly writing the CDN url by assigning the variable `img_cdn` of `_config.yml` file: If you host the images on the CDN, you can save the time of repeatedly writing the CDN url by assigning the variable `img_cdn` of `_config.yml` file:

View File

@@ -9,16 +9,16 @@ pin: true
## Prerequisites ## Prerequisites
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`. Please note that the version of `Ruby` must meet the requirements of the theme on [RubyGems.org](https://rubygems.org/gems/jekyll-theme-chirpy). Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
## Installation ## Installation
There are two ways to get the theme: There are two ways to get the theme:
- **[Install from RubyGems](#install-from-rubygems)** - Easy to update, isolate irrelevant project files so you can focus on writing. - **Install from RubyGems** - Easy to update, isolate irrelevant project files so you can focus on writing.
- **[Fork on GitHub](#fork-on-github)** - Convenient for custom development, but difficult to update, only suitable for web developers. - **Fork on GitHub** - Convenient for custom development, but difficult to update, only suitable for web developers.
### Install from RubyGems ### Installing the Theme Gem
Add this line to your Jekyll site's `Gemfile`: Add this line to your Jekyll site's `Gemfile`:
@@ -38,19 +38,15 @@ And then execute:
$ bundle $ bundle
``` ```
Next, go to the installed local theme path: Finally, copy the required files from the theme's gem (for detailed files, see [starter project][starter]) to your Jekyll site.
```console > **Hint**: To locate the installed themes gem, execute:
$ cd "$(bundle info --path jekyll-theme-chirpy)"
```
And then copy the critical files (for details, see [starter project][starter]) from the theme's gem to your Jekyll site.
> ⚠️ **Watch out for duplicate files!**
> >
> If your Jekyll site is created by the `jekyll new` command, there will be `index.markdown` and `about.markdown` in the root directory of your site. Please be sure to remove them, otherwise they will overwrite the `index.html` and `_tabs/about.html` from this project, resulting in blank or messy pages. > ```console
> $ bundle info --path jekyll-theme-chirpy
> ```
As an alternative, which we recommend, you can create a Jekyll site [**using the starter template**][use-starter] to save time copying files from the theme's gem. We've prepared everything you need there! Or you can [**use the starter template**][use-starter] to create a Jekyll site to save time copying files from the theme's gem. We have prepared everything for you there!
### Fork on GitHub ### Fork on GitHub
@@ -92,12 +88,6 @@ Update the variables of `_config.yml` as needed. Some of them are typical option
- `timezone` - `timezone`
- `lang` - `lang`
### Customing Stylesheet
If you need to customize stylesheet, copy the theme's `assets/css/style.scss` to the same path on your Jekyll site, and then add the custom style at the end of the style file.
Starting from `v4.1.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`, create a new file `_sass/variables-hook.scss` and assign new values to the target variable in it.
### Running Local Server ### Running Local Server
You may want to preview the site contents before publishing, so just run it by: You may want to preview the site contents before publishing, so just run it by:
@@ -140,7 +130,7 @@ Now publish your Jekyll site by:
2. Browse to your repo's landing page on GitHub and select the branch `gh-pages` as the [publishing source](https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) through _Settings__Options__GitHub Pages_: 2. Browse to your repo's landing page on GitHub and select the branch `gh-pages` as the [publishing source](https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) through _Settings__Options__GitHub Pages_:
![gh-pages-sources](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190809/gh-pages-sources.png){: width="850" height="153" } ![gh-pages-sources](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190809/gh-pages-sources.png)
3. Visit your website at the address indicated by GitHub. 3. Visit your website at the address indicated by GitHub.

View File

@@ -33,7 +33,7 @@ With your property created, you now need to set up Data Stream to track your blo
It should look like this: It should look like this:
![google-analytics-data-stream](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/01-google-analytics-data-stream.png){: width="1086" height="542"} ![google-analytics-data-stream](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/01-google-analytics-data-stream.png)
Now, click on the new data stream and grab the **Measurement ID**. It should look something like `G-V6XXXXXXXX`. Copy this to your `_config.yml` file Now, click on the new data stream and grab the **Measurement ID**. It should look something like `G-V6XXXXXXXX`. Copy this to your `_config.yml` file
@@ -48,7 +48,7 @@ google_analytics:
When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pickup your changes. You should now be able to monitor your traffic in realtime. When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pickup your changes. You should now be able to monitor your traffic in realtime.
![google-analytics-realtime](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/02-google-analytics-realtime.png){: width="616" height="557"} ![google-analytics-realtime](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/02-google-analytics-realtime.png)
## Setup Page Views ## Setup Page Views
@@ -183,7 +183,7 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
If everything went good, you'll get this screen: If everything went good, you'll get this screen:
![superProxy-deployed](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/03-superProxy-deployed.png){: width="1366" height="354"} ![superProxy-deployed](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/03-superProxy-deployed.png)
### Create Google Analytics Query ### Create Google Analytics Query
@@ -208,14 +208,14 @@ After <kbd>Run Query</kbd>, copy the generated contents of **API Query URI** at
After the query is saved on GAE, a **Public Endpoint** (public access address) will be generated, and we will get the query result in JSON format when accessing it. Finally, click <kbd>Enable Endpoint</kbd> in **Public Request Endpoint** to make the query effective, and click <kbd>Start Scheduling</kbd> in **Scheduling** to start the scheduled task. After the query is saved on GAE, a **Public Endpoint** (public access address) will be generated, and we will get the query result in JSON format when accessing it. Finally, click <kbd>Enable Endpoint</kbd> in **Public Request Endpoint** to make the query effective, and click <kbd>Start Scheduling</kbd> in **Scheduling** to start the scheduled task.
![superproxy-query](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/04-superproxy-query.png){: width="1100" height="126"} ![superproxy-query](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/04-superproxy-query.png)
## Configure Chirpy to Display Page View ## Configure Chirpy to Display Page View
Once all the hard part is done, it is very easy to enable the Page View on Chirpy theme. Your superProxy dashboard should look something like below and you can grab the required values. Once all the hard part is done, it is very easy to enable the Page View on Chirpy theme. Your superProxy dashboard should look something like below and you can grab the required values.
![superproxy-dashboard](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/05-superproxy-dashboard.png){: width="1210" height="694"} ![superproxy-dashboard](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/05-superproxy-dashboard.png)
Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following: Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:

View File

@@ -107,7 +107,6 @@ a {
img { img {
max-width: 100%; max-width: 100%;
height: auto;
} }
blockquote { blockquote {
@@ -364,29 +363,9 @@ footer {
overflow-wrap: break-word; overflow-wrap: break-word;
word-wrap: break-word; word-wrap: break-word;
@mixin caption {
+ em {
display: block;
text-align: center;
font-style: normal;
font-size: 80%;
padding: 0;
color: #6d6c6c;
}
}
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
img[data-src] { img[data-src] {
margin: 0.5rem 0; margin: 0.5rem 0;
&[data-loaded=true] {
animation: fade-in linear .5s;
}
&.left { &.left {
float: left; float: left;
margin: 0.75rem 1rem 1rem 0; margin: 0.75rem 1rem 1rem 0;
@@ -401,8 +380,6 @@ footer {
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08)); filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
} }
@include caption;
} }
a { a {
@@ -427,7 +404,14 @@ footer {
} }
&.img-link { &.img-link {
@include caption; + em {
display: block;
text-align: center;
font-style: normal;
font-size: 80%;
padding: 0;
color: #6d6c6c;
}
} }
} // a } // a
@@ -605,6 +589,8 @@ figure .mfp-title {
/* --- sidebar layout --- */ /* --- sidebar layout --- */
$tab-count: 5 !default;
$sidebar-display: "sidebar-display"; $sidebar-display: "sidebar-display";
#sidebar { #sidebar {
@@ -615,7 +601,7 @@ $sidebar-display: "sidebar-display";
left: 0; left: 0;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
width: $sidebar-width; width: $sidebar-width-medium;
z-index: 99; z-index: 99;
background: var(--sidebar-bg); background: var(--sidebar-bg);
@@ -724,6 +710,7 @@ $sidebar-display: "sidebar-display";
width: 100%; width: 100%;
&:last-child { &:last-child {
$cursor-width: 3px;
a { a {
position: relative; position: relative;
@@ -753,12 +740,12 @@ $sidebar-display: "sidebar-display";
@for $i from 1 through $tab-count { @for $i from 1 through $tab-count {
$offset: $tab-count - $i; $offset: $tab-count - $i;
$top: -$offset * $tab-height + ($tab-height - $tab-cursor-height) / 2; $top: -$offset * $tab-height + $tab-cursor-height / 2;
@if $i < $tab-count { @if $i < $tab-count {
> li.active:nth-child(#{$i}), > li.active:nth-child(#{$i}),
> li.nav-item:nth-child(#{$i}):hover { > li.nav-item:nth-child(#{$i}):hover {
~ li:last-child::after { ~li:last-child::after {
@include fix-cursor($top); @include fix-cursor($top);
} }
} }
@@ -852,7 +839,7 @@ $sidebar-display: "sidebar-display";
height: $topbar-height; height: $topbar-height;
position: fixed; position: fixed;
top: 0; top: 0;
left: $sidebar-width; /* same as sidebar width */ left: 260px; /* same as sidebar width */
right: 0; right: 0;
transition: top 0.2s ease-in-out; transition: top 0.2s ease-in-out;
z-index: 50; z-index: 50;
@@ -893,7 +880,7 @@ $sidebar-display: "sidebar-display";
#search-wrapper { #search-wrapper {
display: flex; display: flex;
width: 85%; width: 95%;
border-radius: 1rem; border-radius: 1rem;
border: 1px solid var(--search-wrapper-bg); border: 1px solid var(--search-wrapper-bg);
background: var(--search-wrapper-bg); background: var(--search-wrapper-bg);
@@ -1096,7 +1083,7 @@ $sidebar-display: "sidebar-display";
@media all and (max-width: 576px) { @media all and (max-width: 576px) {
$footer-height: $footer-height-mobile; // overwrite $footer-height: 6rem; // overwrite
#main > div.row:first-child > div:first-child { #main > div.row:first-child > div:first-child {
min-height: calc(100vh - #{$topbar-height} - #{$footer-height}); min-height: calc(100vh - #{$topbar-height} - #{$footer-height});
@@ -1170,7 +1157,7 @@ $sidebar-display: "sidebar-display";
#topbar-wrapper, #topbar-wrapper,
#main-wrapper { #main-wrapper {
transform: translateX(#{$sidebar-width}); transform: translateX(#{$sidebar-width-medium});
} }
} }
@@ -1178,8 +1165,8 @@ $sidebar-display: "sidebar-display";
#sidebar { #sidebar {
@extend %slide; @extend %slide;
transform: translateX(-#{$sidebar-width}); // hide transform: translateX(-#{$sidebar-width-medium}); // hide
-webkit-transform: translateX(-#{$sidebar-width}); -webkit-transform: translateX(-#{$sidebar-width-medium});
.cursor { .cursor {
-webkit-transition: none; -webkit-transition: none;
@@ -1277,7 +1264,7 @@ $sidebar-display: "sidebar-display";
} }
#main-wrapper { #main-wrapper {
margin-left: $sidebar-width; margin-left: $sidebar-width-medium;
} }
.profile-wrapper { .profile-wrapper {

View File

@@ -39,6 +39,8 @@ html[mode=dark] {
padding: 1.5rem; padding: 1.5rem;
} }
$code-font-size: 0.85rem;
div > pre { div > pre {
@extend %code-snippet-bg; @extend %code-snippet-bg;
@extend %code-snippet-radius; @extend %code-snippet-radius;
@@ -63,28 +65,6 @@ div > pre {
} }
overflow: auto; overflow: auto;
pre {
margin-bottom: 0;
font-size: $code-font-size;
line-height: 1.4rem;
word-wrap: normal; /* Fixed Safari overflow-x */
}
table {
padding: 0;
border: 0;
td pre {
overflow: visible; /* Fixed iOS safari overflow-x */
word-break: normal; /* Fixed iOS safari linenos code break */
}
}
td {
padding: 0;
border: 0;
}
.lineno { .lineno {
margin-left: 0.2rem; margin-left: 0.2rem;
padding-right: 0.5rem; padding-right: 0.5rem;
@@ -99,12 +79,24 @@ div > pre {
-o-user-select: none; -o-user-select: none;
user-select: none; user-select: none;
} }
pre {
/* set the dollar sign to non-selectable */ margin-bottom: 0;
.gp { font-size: $code-font-size;
user-select: none; line-height: 1.4rem;
word-wrap: normal; /* Fixed Safari overflow-x */
}
table {
padding: 0;
border: 0;
td pre {
overflow: visible; /* Fixed iOS safari overflow-x */
word-break: normal; /* Fixed iOS safari linenos code break */
}
}
td {
padding: 0;
border: 0;
} }
} //.highlight } //.highlight
code { code {

View File

@@ -1,34 +1,22 @@
/* /*
* The SCSS variables * Mainly scss variables
*/ */
/* sidebar */ /* --- ↓ width and height ---- */
$sidebar-width: 260px !default; // the basic width $tab-height: 3.2rem;
$sidebar-width-small: 210px !default; // screen width: >= 850px, <= 1199px (iPad landscape) $tab-cursor-height: 1.6rem;
$sidebar-width-large: 350px !default; // screen width: >= 1650px
/* tabs of sidebar */ $sidebar-width-small: 210px;
$sidebar-width-medium: 260px;
$sidebar-width-large: 350px;
$tab-count: 5 !default; // backward compatible (version <= 4.0.2) $topbar-height: 3rem;
$tab-height: 3.2rem !default;
$tab-cursor-height: 1.6rem !default;
$cursor-width: 3px !default; // the cursor width of the selected tab $footer-height: 5rem;
/* other framework sizes */ $main-content-max-width: 1150px;
$topbar-height: 3rem !default; $panel-max-width: 300px;
$footer-height: 5rem !default; $post-extend-min-height: 35rem;
$footer-height-mobile: 6rem !default; // screen width: <= 576px
$main-content-max-width: 1150px !default;
$panel-max-width: 300px !default;
$post-extend-min-height: 35rem !default;
/* syntax highlight */
$code-font-size: 0.85rem !default;

View File

@@ -1,7 +1,7 @@
/*! /*!
* The styles for Jekyll theme Chirpy * The styles for Jekyll theme Chirpy
* *
* Chirpy v4.1.1 (https://github.com/cotes2020/jekyll-theme-chirpy) * Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy)
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
@@ -12,7 +12,6 @@
"addon/module", "addon/module",
"addon/variables", "addon/variables",
"variables-hook",
"addon/syntax", "addon/syntax",
"addon/commons", "addon/commons",

View File

@@ -3,24 +3,27 @@
*/ */
.pagination { .pagination {
color: var(--btn-patinator-text-color); font-size: 1rem;
font-family: 'Lato', sans-serif;
a:hover { a:hover {
text-decoration: none; text-decoration: none;
} }
.page-item { .page-item {
.page-link { .page-link {
color: inherit; color: var(--btn-patinator-text-color);
width: 2.5rem; width: 2.5rem;
height: 2.5rem; height: 2.5rem;
padding: 0; padding: 0;
text-align: center;
display: -webkit-box; display: -webkit-box;
display: flex;
-webkit-box-pack: center; -webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center; -webkit-box-align: center;
align-items: center;
border-radius: 50%; border-radius: 50%;
border: 1px solid var(--btn-paginator-border-color); border: 1px solid var(--btn-paginator-border-color);
font-family: 'Lato', sans-serif;
background-color: var(--button-bg); background-color: var(--button-bg);
&:hover { &:hover {
background-color: var(--btn-paginator-hover-color); background-color: var(--btn-paginator-hover-color);
@@ -46,6 +49,9 @@
&:last-child .page-link { &:last-child .page-link {
border-radius: 50%; border-radius: 50%;
} }
&:not(:last-child) {
margin-right: 0.7rem;
}
} // .page-item } // .page-item
} // .pagination } // .pagination
@@ -110,15 +116,7 @@
/* Hide SideBar and TOC */ /* Hide SideBar and TOC */
@media all and (max-width: 830px) { @media all and (max-width: 830px) {
.pagination { .pagination {
justify-content: space-evenly; justify-content: center;
.page-item {
&:not(:first-child):not(:last-child) {
display: none;
}
}
} }
} }
@@ -146,24 +144,11 @@
.pagination { .pagination {
font-size: 0.85rem; font-size: 0.85rem;
.page-item .page-link {
.page-item { width: 2.2rem;
&:not(:last-child) { height: 2.2rem;
margin-right: 0.7rem;
}
.page-link {
width: 2rem;
height: 2rem;
}
} }
}
.page-index {
display: none;
}
} // .pagination
} }

View File

@@ -23,12 +23,24 @@
padding-right: $pr; padding-right: $pr;
} }
.timeago::before {
content: attr(prefix);
}
#post-wrapper .post-meta { #post-wrapper .post-meta {
> div:nth-child(2) { > div:nth-child(2) {
> span:not(:first-child)::before { > span:not(:first-child)::before {
@include dot; @include dot;
} }
} }
#pv::after {
content: " views";
}
.readtime::after {
content: " read";
}
} }
.post-content { .post-content {

View File

@@ -1,3 +0,0 @@
/*
Appending custom SCSS variables will override the default ones in `_sass/addon/variables.scsss`
*/

View File

@@ -12,20 +12,10 @@ dynamic_title: true
--- ---
<div class="lead"> <div class="lead">
<p>Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. </p>
{%- capture _head_back -%} <p>
<a href="{{ '/' | relative_url }}">{{ site.data.locales[site.lang].not_found.head_back }}</a> <a href="{{ '/' | relative_url }}">Head back Home</a>
{%- endcapture -%} to try finding it again, or search for it on the
<a href="{{ 'archives' | relative_url }}">Archives page</a>.
{%- capture _archives_page -%}
<a href="{{ 'archives' | relative_url }}">{{ site.data.locales[site.lang].not_found.archives_page }}</a>
{%- endcapture -%}
<p>{{site.data.locales[site.lang].not_found.statment }}</p>
<p>{{ site.data.locales[site.lang].not_found.hint_template
| replace: ':HEAD_BAK', _head_back
| replace: ':ARCHIVES_PAGE', _archives_page }}
</p> </p>
</div> </div>

View File

@@ -1,12 +1,7 @@
--- ---
--- ---
/* // see: /_sass/addon/commons.scss
If the number of TAB files has changed, the following variable is required.
And it must be defined before `@import`.
*/
$tab-count: {{ site.tabs | size | plus: 1 }}; // plus 1 for home tab $tab-count: {{ site.tabs | size | plus: 1 }}; // plus 1 for home tab
@import "{{ site.theme }}"; @import "jekyll-theme-chirpy";
/* append your custom style below */

View File

@@ -1,6 +1,6 @@
/*! /*!
* Chirpy v4.1.1 (https://github.com/cotes2020/jekyll-theme-chirpy/) * Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),r=$("#search-result-wrapper"),d=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),f=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset:()=>o}}(),u={on(){o.addClass("unloaded"),l.addClass("unloaded"),e.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),o.removeClass("unloaded"),l.removeClass("unloaded"),e.removeClass("unloaded")}},p=function(){let o=!1;return{on(){o||(f.block(),r.removeClass("unloaded"),a.addClass("unloaded"),o=!0)},off(){o&&(d.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),f.release(),i.val(""),o=!1)},isVisible:()=>o}}();function h(){return s.hasClass("loaded")}e.click(function(){u.on(),p.on(),i.focus()}),s.click(function(){u.off(),p.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(o){8===o.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):p.off():""!==i.val()&&(p.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),d.empty()):p.off(),i.focus(),t.removeClass("visible")})}),$(function(){const o=function(){let o=!1;const e=$("body");return{toggle(){!1===o?e.attr("sidebar-display",""):e.removeAttr("sidebar-display"),o=!o}}}();$("#sidebar-trigger").click(o.toggle),$("#mask").click(o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),e=$("#toc-wrapper"),s=$(".access"),t=$("#search-input");let a,l=0;const n=5,r=o.outerHeight();$(window).scroll(function(o){$("#topbar-title").is(":hidden")&&(a=!0)}),setInterval(function(){a&&(!function(){var a=$(this).scrollTop();Math.abs(l-a)<=n||(a>l&&a>r?(o.removeClass("topbar-down").addClass("topbar-up"),e.length>0&&e.removeClass("topbar-down"),s.length>0&&s.removeClass("topbar-down"),t.is(":focus")&&t.blur()):a+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),e.length>0&&e.addClass("topbar-down"),s.length>0&&s.addClass("topbar-down")),l=a)}(),a=!1)},250)}),$(function(){const o=$("#topbar-title"),e=$("div.post>h1"),s=o.text().trim();let t=e.length>0?e.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||e.is(":hidden")||o.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?o.text()!==t&&o.text(t):o.text()!==s&&o.text(s)}),o.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){const o=$(".collapse");o.on("hide.bs.collapse",function(){const o="h_"+$(this).attr("id").substring("l_".length);o&&($(`#${o} .far.fa-folder-open`).attr("class","far fa-folder fa-fw"),$(`#${o} i.fas`).addClass("rotate"),$(`#${o}`).removeClass("hide-border-bottom"))}),o.on("show.bs.collapse",function(){const o="h_"+$(this).attr("id").substring("l_".length);o&&($(`#${o} .far.fa-folder`).attr("class","far fa-folder-open fa-fw"),$(`#${o} i.fas`).removeClass("rotate"),$(`#${o}`).addClass("hide-border-bottom"))})}); $(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),r=$("#search-result-wrapper"),d=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),f={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},p=function(){let e=!1;return{on(){e||(u.block(),r.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(d.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible(){return e}}}();function h(){return s.hasClass("loaded")}o.click(function(){f.on(),p.on(),i.focus()}),s.click(function(){f.off(),p.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):p.off():""!==i.val()&&(p.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),d.empty()):p.off(),i.focus(),t.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const s=$("body");return{toggle(){!1===o?s.attr(e,""):s.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),s=$("#toc-wrapper"),t=$(".access"),a=$("#search-input");let l,n=0;const r=o.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>r?(o.removeClass("topbar-down").addClass("topbar-up"),0<s.length&&s.removeClass("topbar-down"),0<t.length&&t.removeClass("topbar-down"),a.is(":focus")&&a.blur()):e+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),0<s.length&&s.addClass("topbar-down"),0<t.length&&t.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),s=e.text().trim();let t=(0<o.length?o:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==t&&e.text(t):e.text()!==s&&e.text(s))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){const e=$(".collapse");e.on("hide.bs.collapse",function(){var e="h_"+$(this).attr("id").substring("l_".length);e&&($(`#${e} .far.fa-folder-open`).attr("class","far fa-folder fa-fw"),$(`#${e} i.fas`).addClass("rotate"),$(`#${e}`).removeClass("hide-border-bottom"))}),e.on("show.bs.collapse",function(){var e="h_"+$(this).attr("id").substring("l_".length);e&&($(`#${e} .far.fa-folder`).attr("class","far fa-folder-open fa-fw"),$(`#${e} i.fas`).removeClass("rotate"),$(`#${e}`).addClass("hide-border-bottom"))})});

View File

@@ -1,6 +1,6 @@
/*! /*!
* Chirpy v4.1.1 (https://github.com/cotes2020/jekyll-theme-chirpy/) * Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),d=$("#search-result-wrapper"),r=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset:()=>e}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),d.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(r.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),d.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible:()=>e}}();function h(){return s.hasClass("loaded")}o.click(function(){p.on(),f.on(),i.focus()}),s.click(function(){p.off(),f.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):f.off():""!==i.val()&&(f.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),r.empty()):f.off(),i.focus(),t.removeClass("visible")})}),$(function(){const e=function(){let e=!1;const o=$("body");return{toggle(){!1===e?o.attr("sidebar-display",""):o.removeAttr("sidebar-display"),e=!e}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#topbar-wrapper"),o=$("#toc-wrapper"),s=$(".access"),t=$("#search-input");let a,l=0;const n=5,d=e.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(a=!0)}),setInterval(function(){a&&(!function(){var a=$(this).scrollTop();Math.abs(l-a)<=n||(a>l&&a>d?(e.removeClass("topbar-down").addClass("topbar-up"),o.length>0&&o.removeClass("topbar-down"),s.length>0&&s.removeClass("topbar-down"),t.is(":focus")&&t.blur()):a+$(window).height()<$(document).height()&&(e.removeClass("topbar-up").addClass("topbar-down"),o.length>0&&o.addClass("topbar-down"),s.length>0&&s.addClass("topbar-down")),l=a)}(),a=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),s=e.text().trim();let t=o.length>0?o.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?e.text()!==t&&e.text(t):e.text()!==s&&e.text(s)}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}); $(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),s=$("#search-cancel"),t=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),d=$("#search-result-wrapper"),r=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),s.addClass("loaded")},off(){s.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),d.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(r.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),d.addClass("unloaded"),t.removeClass("visible"),a.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible(){return e}}}();function h(){return s.hasClass("loaded")}o.click(function(){p.on(),f.on(),i.focus()}),s.click(function(){p.off(),f.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?h()?c.removeClass("unloaded"):f.off():""!==i.val()&&(f.on(),t.hasClass("visible")||t.addClass("visible"),h()&&c.addClass("unloaded"))}),t.on("click",function(){i.val(""),h()?(c.removeClass("unloaded"),r.empty()):f.off(),i.focus(),t.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const s=$("body");return{toggle(){!1===o?s.attr(e,""):s.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),s=$("#toc-wrapper"),t=$(".access"),a=$("#search-input");let l,n=0;const d=o.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>d?(o.removeClass("topbar-down").addClass("topbar-up"),0<s.length&&s.removeClass("topbar-down"),0<t.length&&t.removeClass("topbar-down"),a.is(":focus")&&a.blur()):e+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),0<s.length&&s.addClass("topbar-down"),0<t.length&&t.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),s=e.text().trim();let t=(0<o.length?o:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(t)&&(t=t.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==t&&e.text(t):e.text()!==s&&e.text(s))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})});

View File

@@ -1,6 +1,6 @@
/*! /*!
* Chirpy v4.1.1 (https://github.com/cotes2020/jekyll-theme-chirpy/) * Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#search-cleaner"),l=$("#main"),n=$("#topbar-title"),s=$("#search-wrapper"),r=$("#search-result-wrapper"),i=$("#search-results"),d=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset:()=>e}}(),p={on(){e.addClass("unloaded"),n.addClass("unloaded"),t.addClass("unloaded"),s.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),s.removeClass("d-flex"),e.removeClass("unloaded"),n.removeClass("unloaded"),t.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),r.removeClass("unloaded"),l.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),a.removeClass("visible"),l.removeClass("unloaded"),u.release(),d.val(""),e=!1)},isVisible:()=>e}}();function h(){return o.hasClass("loaded")}t.click(function(){p.on(),f.on(),d.focus()}),o.click(function(){p.off(),f.off()}),d.focus(function(){s.addClass("input-focus")}),d.focusout(function(){s.removeClass("input-focus")}),d.on("keyup",function(e){8===e.keyCode&&""===d.val()?h()?c.removeClass("unloaded"):f.off():""!==d.val()&&(f.on(),a.hasClass("visible")||a.addClass("visible"),h()&&c.addClass("unloaded"))}),a.on("click",function(){d.val(""),h()?(c.removeClass("unloaded"),i.empty()):f.off(),d.focus(),a.removeClass("visible")})}),$(function(){const e=function(){let e=!1;const t=$("body");return{toggle(){!1===e?t.attr("sidebar-display",""):t.removeAttr("sidebar-display"),e=!e}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#topbar-wrapper"),t=$("#toc-wrapper"),o=$(".access"),a=$("#search-input");let l,n=0;const s=5,r=e.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(!function(){var l=$(this).scrollTop();Math.abs(n-l)<=s||(l>n&&l>r?(e.removeClass("topbar-down").addClass("topbar-up"),t.length>0&&t.removeClass("topbar-down"),o.length>0&&o.removeClass("topbar-down"),a.is(":focus")&&a.blur()):l+$(window).height()<$(document).height()&&(e.removeClass("topbar-up").addClass("topbar-down"),t.length>0&&t.addClass("topbar-down"),o.length>0&&o.addClass("topbar-down")),n=l)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),t=$("div.post>h1"),o=e.text().trim();let a=t.length>0?t.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||t.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?e.text()!==a&&e.text(a):e.text()!==o&&e.text(o)}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){let e=$(".timeago").length,t=void 0;const o=$("meta[name=day-prompt]").attr("content"),a=$("meta[name=hour-prompt]").attr("content"),l=$("meta[name=minute-prompt]").attr("content"),n=$("meta[name=justnow-prompt]").attr("content");function s(){return $(".timeago").each(function(){if($(this).children("i").length>0){let t=$(this).clone().children().remove().end().text(),s=$(this).children("i"),r=s.text();$(this).text(function(t,s){let r=new Date,i=new Date(t);if(i.getFullYear()!==r.getFullYear()||i.getMonth()!==r.getMonth())return s;let d=Math.floor((r-i)/1e3),c=Math.floor(d/86400);if(c>=1)return e-=1,` ${c} ${o}`;let u=Math.floor(d/3600);if(u>=1)return` ${u} ${a}`;let $=Math.floor(d/60);return $>=1?` ${$} ${l}`:n}(r,t)),$(this).append(s)}}),0===e&&void 0!==t&&clearInterval(t),e}0!==e&&s()>0&&(t=setInterval(s,6e4))}); $(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#search-cleaner"),s=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),r=$("#search-result-wrapper"),d=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),h={on(){e.addClass("unloaded"),l.addClass("unloaded"),t.addClass("unloaded"),n.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),t.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),r.removeClass("unloaded"),s.addClass("unloaded"),e=!0)},off(){e&&(d.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),r.addClass("unloaded"),a.removeClass("visible"),s.removeClass("unloaded"),u.release(),i.val(""),e=!1)},isVisible(){return e}}}();function p(){return o.hasClass("loaded")}t.click(function(){h.on(),f.on(),i.focus()}),o.click(function(){h.off(),f.off()}),i.focus(function(){n.addClass("input-focus")}),i.focusout(function(){n.removeClass("input-focus")}),i.on("keyup",function(e){8===e.keyCode&&""===i.val()?p()?c.removeClass("unloaded"):f.off():""!==i.val()&&(f.on(),a.hasClass("visible")||a.addClass("visible"),p()&&c.addClass("unloaded"))}),a.on("click",function(){i.val(""),p()?(c.removeClass("unloaded"),d.empty()):f.off(),i.focus(),a.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#topbar-wrapper"),o=$("#toc-wrapper"),a=$(".access"),s=$("#search-input");let l,n=0;const r=t.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>r?(t.removeClass("topbar-down").addClass("topbar-up"),0<o.length&&o.removeClass("topbar-down"),0<a.length&&a.removeClass("topbar-down"),s.is(":focus")&&s.blur()):e+$(window).height()<$(document).height()&&(t.removeClass("topbar-up").addClass("topbar-down"),0<o.length&&o.addClass("topbar-down"),0<a.length&&a.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),t=$("div.post>h1"),o=e.text().trim();let a=(0<t.length?t:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||t.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==a&&e.text(a):e.text()!==o&&e.text(o))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){let s=$(".timeago").length,e=void 0;function t(){return $(".timeago").each(function(){if(0<$(this).children("i").length){let e=$(this).children("i");var t=e.text();$(this).text(function(e,t){let o=new Date,a=new Date(e);return e=void 0!==t?`${t} `:"",a.getFullYear()!==o.getFullYear()?(--s,e+a.toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric"})):a.getMonth()!==o.getMonth()?(--s,e+a.toLocaleString("en-US",{month:"short",day:"numeric"})):(t=Math.floor((o-a)/1e3),1<=(e=Math.floor(t/86400))?(--s,e+" day"+(1<e?"s":"")+" ago"):1<=(e=Math.floor(t/3600))?e+" hour"+(1<e?"s":"")+" ago":1<=(t=Math.floor(t/60))?t+" minute"+(1<t?"s":"")+" ago":"just now")}(t,$(this).attr("prep"))),$(this).append(e)}}),0===s&&void 0!==e&&clearInterval(e),s}0!==s&&0<t()&&(e=setInterval(t,6e4))});

View File

@@ -1,6 +1,6 @@
/*! /*!
* Chirpy v4.1.1 (https://github.com/cotes2020/jekyll-theme-chirpy/) * Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
function copyLink(e,o){e&&0!==e.length||(e=window.location.href);const t=$("<input>");$("body").append(t),t.val(e).select(),document.execCommand("copy"),t.remove();let s="Link copied successfully!";o&&o.length>0&&(s=o),alert(s)}$(function(){$(window).scroll(()=>{$(this).scrollTop()>50&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),t=$("#search-cancel"),s=$("#search-cleaner"),a=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),i=$("#search-result-wrapper"),c=$("#search-results"),d=$("#search-input"),r=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset:()=>e}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),i.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(c.empty(),r.hasClass("unloaded")&&r.removeClass("unloaded"),i.addClass("unloaded"),s.removeClass("visible"),a.removeClass("unloaded"),u.release(),d.val(""),e=!1)},isVisible:()=>e}}();function h(){return t.hasClass("loaded")}o.click(function(){p.on(),f.on(),d.focus()}),t.click(function(){p.off(),f.off()}),d.focus(function(){n.addClass("input-focus")}),d.focusout(function(){n.removeClass("input-focus")}),d.on("keyup",function(e){8===e.keyCode&&""===d.val()?h()?r.removeClass("unloaded"):f.off():""!==d.val()&&(f.on(),s.hasClass("visible")||s.addClass("visible"),h()&&r.addClass("unloaded"))}),s.on("click",function(){d.val(""),h()?(r.removeClass("unloaded"),c.empty()):f.off(),d.focus(),s.removeClass("visible")})}),$(function(){const e=function(){let e=!1;const o=$("body");return{toggle(){!1===e?o.attr("sidebar-display",""):o.removeAttr("sidebar-display"),e=!e}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#topbar-wrapper"),o=$("#toc-wrapper"),t=$(".access"),s=$("#search-input");let a,l=0;const n=5,i=e.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(a=!0)}),setInterval(function(){a&&(!function(){var a=$(this).scrollTop();Math.abs(l-a)<=n||(a>l&&a>i?(e.removeClass("topbar-down").addClass("topbar-up"),o.length>0&&o.removeClass("topbar-down"),t.length>0&&t.removeClass("topbar-down"),s.is(":focus")&&s.blur()):a+$(window).height()<$(document).height()&&(e.removeClass("topbar-up").addClass("topbar-down"),o.length>0&&o.addClass("topbar-down"),t.length>0&&t.addClass("topbar-down")),l=a)}(),a=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),t=e.text().trim();let s=o.length>0?o.text().trim():$("h1").text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(s)&&(s=s.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){if($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)return!1;$(this).scrollTop()>=95?e.text()!==s&&e.text(s):e.text()!==t&&e.text(t)}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){$("input[type=checkbox]").addClass("unloaded"),$("input[type=checkbox][checked]").before('<i class="fas fa-check-circle checked"></i>'),$("input[type=checkbox]:not([checked])").before('<i class="far fa-circle"></i>')}),$(function(){const e="#main > div.row:first-child > div:first-child";if($(`${e} img`).length<=0)return;const o=document.querySelectorAll(`${e} img[data-src]`);lozad(o).observe(),$(`${e} p > img[data-src],${e} img[data-src].preview-img`).each(function(){let e=$(this).next();const o="EM"===e.prop("tagName")?e.text():"",t=$(this).attr("data-src");$(this).wrap(`<a href="${t}" title="${o}" class="popup"></a>`)}),$(".popup").magnificPopup({type:"image",closeOnContentClick:!0,showCloseBtn:!1,zoom:{enabled:!0,duration:300,easing:"ease-in-out"}}),$(`${e} a`).has("img").addClass("img-link")}); function copyLink(e){e&&0!==e.length||(e=window.location.href);const o=$("<input>");$("body").append(o),o.val(e).select(),document.execCommand("copy"),o.remove(),alert("Link copied successfully!")}$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){const e=$("#sidebar-trigger"),o=$("#search-trigger"),t=$("#search-cancel"),a=$("#search-cleaner"),s=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),i=$("#search-result-wrapper"),c=$("#search-results"),d=$("#search-input"),r=$("#search-hints"),u=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),o.addClass("unloaded"),n.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),n.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),o.removeClass("unloaded")}},f=function(){let e=!1;return{on(){e||(u.block(),i.removeClass("unloaded"),s.addClass("unloaded"),e=!0)},off(){e&&(c.empty(),r.hasClass("unloaded")&&r.removeClass("unloaded"),i.addClass("unloaded"),a.removeClass("visible"),s.removeClass("unloaded"),u.release(),d.val(""),e=!1)},isVisible(){return e}}}();function h(){return t.hasClass("loaded")}o.click(function(){p.on(),f.on(),d.focus()}),t.click(function(){p.off(),f.off()}),d.focus(function(){n.addClass("input-focus")}),d.focusout(function(){n.removeClass("input-focus")}),d.on("keyup",function(e){8===e.keyCode&&""===d.val()?h()?r.removeClass("unloaded"):f.off():""!==d.val()&&(f.on(),a.hasClass("visible")||a.addClass("visible"),h()&&r.addClass("unloaded"))}),a.on("click",function(){d.val(""),h()?(r.removeClass("unloaded"),c.empty()):f.off(),d.focus(),a.removeClass("visible")})}),$(function(){var e=function(){const e="sidebar-display";let o=!1;const t=$("body");return{toggle(){!1===o?t.attr(e,""):t.removeAttr(e),o=!o}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const o=$("#topbar-wrapper"),t=$("#toc-wrapper"),a=$(".access"),s=$("#search-input");let l,n=0;const i=o.outerHeight();$(window).scroll(function(e){$("#topbar-title").is(":hidden")&&(l=!0)}),setInterval(function(){l&&(function(){var e=$(this).scrollTop();Math.abs(n-e)<=5||(e>n&&e>i?(o.removeClass("topbar-down").addClass("topbar-up"),0<t.length&&t.removeClass("topbar-down"),0<a.length&&a.removeClass("topbar-down"),s.is(":focus")&&s.blur()):e+$(window).height()<$(document).height()&&(o.removeClass("topbar-up").addClass("topbar-down"),0<t.length&&t.addClass("topbar-down"),0<a.length&&a.addClass("topbar-down")),n=e)}(),l=!1)},250)}),$(function(){const e=$("#topbar-title"),o=$("div.post>h1"),t=e.text().trim();let a=(0<o.length?o:$("h1")).text().trim();($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),$(window).scroll(function(){return!($("#post-list").length||o.is(":hidden")||e.is(":hidden")||$("#sidebar.sidebar-expand").length)&&void(95<=$(this).scrollTop()?e.text()!==a&&e.text(a):e.text()!==t&&e.text(t))}),e.click(function(){$("body,html").animate({scrollTop:0},800)})}),$(function(){$("input[type=checkbox]").addClass("unloaded"),$("input[type=checkbox][checked]").before('<i class="fas fa-check-circle checked"></i>'),$("input[type=checkbox]:not([checked])").before('<i class="far fa-circle"></i>')}),$(function(){var e="#main > div.row:first-child > div:first-child";if(!($(`${e} img`).length<=0)){var o=document.querySelectorAll(`${e} img[data-src]`);const t=lozad(o);t.observe(),$(`${e} p > img[data-src],${e} img[data-src].preview-img`).each(function(){let e=$(this).next();var o="EM"===e.prop("tagName")?e.text():"",t=$(this).attr("data-src");$(this).wrap(`<a href="${t}" title="${o}" class="popup"></a>`)}),$(".popup").magnificPopup({type:"image",closeOnContentClick:!0,showCloseBtn:!1,zoom:{enabled:!0,duration:300,easing:"ease-in-out"}}),$(`${e} a`).has("img").addClass("img-link")}});

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
/*! /*!
* Chirpy v4.1.1 (https://github.com/cotes2020/jekyll-theme-chirpy/) * Chirpy v4.0.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
const getInitStatus=function(){let e=!1;return()=>{let t=e;return e||(e=!0),t}}(),PvOpts=function(){function e(e){return $(e).attr("content")}function t(t){let a=e(t);return void 0!==a&&!1!==a}return{getProxyMeta:()=>e("meta[name=pv-proxy-endpoint]"),getLocalMeta:()=>e("meta[name=pv-cache-path]"),hasProxyMeta:()=>t("meta[name=pv-proxy-endpoint]"),hasLocalMeta:()=>t("meta[name=pv-cache-path]")}}(),PvStorage=function(){const e={KEY_PV:"pv",KEY_PV_SRC:"pv_src",KEY_CREATION:"pv_created_date"},t="same-origin",a="cors";function o(e){return localStorage.getItem(e)}function r(e,t){localStorage.setItem(e,t)}function n(t,a){r(e.KEY_PV,t),r(e.KEY_PV_SRC,a),r(e.KEY_CREATION,(new Date).toJSON())}return{keysCount:()=>Object.keys(e).length,hasCache:()=>null!==localStorage.getItem(e.KEY_PV),getCache:()=>JSON.parse(localStorage.getItem(e.KEY_PV)),saveLocalCache(e){n(e,t)},saveProxyCache(e){n(e,a)},isExpired(){let t=new Date(o(e.KEY_CREATION));return t.setHours(t.getHours()+1),Date.now()>=t.getTime()},isFromLocal:()=>o(e.KEY_PV_SRC)===t,isFromProxy:()=>o(e.KEY_PV_SRC)===a,newerThan:e=>PvStorage.getCache().totalsForAllResults["ga:pageviews"]>e.totalsForAllResults["ga:pageviews"],inspectKeys(){if(localStorage.length===PvStorage.keysCount())for(let t=0;t<localStorage.length;t++){switch(localStorage.key(t)){case e.KEY_PV:case e.KEY_PV_SRC:case e.KEY_CREATION:break;default:return void localStorage.clear()}}else localStorage.clear()}}}();function countUp(e,t,a){if(e<t){let o=new CountUp(a,e,t);o.error?console.error(o.error):o.start()}}function countPV(e,t){let a=0;if(void 0!==t)for(let o=0;o<t.length;++o){if(t[parseInt(o,10)][0]===e){a+=parseInt(t[parseInt(o,10)][1],10);break}}return a}function tacklePV(e,t,a,o){let r=countPV(t,e);if(r=0===r?1:r,o){const e=parseInt(a.text().replace(/,/g,""),10);r>e&&countUp(e,r,a.attr("id"))}else a.text((new Intl.NumberFormat).format(r))}function displayPageviews(e){if(void 0===e)return;let t=getInitStatus();const a=e.rows;if($("#post-list").length>0)$(".post-preview").each(function(){const e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)});else if($(".post").length>0){const e=window.location.pathname;tacklePV(a,e,$("#pv"),t)}}function fetchProxyPageviews(){PvOpts.hasProxyMeta()&&$.ajax({type:"GET",url:PvOpts.getProxyMeta(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:e=>{PvStorage.saveProxyCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchLocalPageviews(e=!1){return fetch(PvOpts.getLocalMeta()).then(e=>e.json()).then(t=>{e&&PvStorage.isFromProxy()&&PvStorage.newerThan(t)||(displayPageviews(t),PvStorage.saveLocalCache(JSON.stringify(t)))})}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()?(displayPageviews(PvStorage.getCache()),PvStorage.isExpired()?PvOpts.hasLocalMeta()?fetchLocalPageviews(!0).then(fetchProxyPageviews):fetchProxyPageviews():PvStorage.isFromLocal()&&fetchProxyPageviews()):PvOpts.hasLocalMeta()?fetchLocalPageviews().then(fetchProxyPageviews):fetchProxyPageviews())}); const getInitStatus=function(){let t=!1;return()=>{var e=t;return t=t||!0,e}}(),PvOpts=function(){function t(e){return $(e).attr("content")}function e(e){e=t(e);return void 0!==e&&!1!==e}return{getProxyMeta(){return t("meta[name=pv-proxy-endpoint]")},getLocalMeta(){return t("meta[name=pv-cache-path]")},hasProxyMeta(){return e("meta[name=pv-proxy-endpoint]")},hasLocalMeta(){return e("meta[name=pv-cache-path]")}}}(),PvStorage=function(){const a={KEY_PV:"pv",KEY_PV_SRC:"pv_src",KEY_CREATION:"pv_created_date"},t={LOCAL:"same-origin",PROXY:"cors"};function r(e){return localStorage.getItem(e)}function o(e,t){localStorage.setItem(e,t)}function n(e,t){o(a.KEY_PV,e),o(a.KEY_PV_SRC,t),o(a.KEY_CREATION,(new Date).toJSON())}return{keysCount(){return Object.keys(a).length},hasCache(){return null!==localStorage.getItem(a.KEY_PV)},getCache(){return JSON.parse(localStorage.getItem(a.KEY_PV))},saveLocalCache(e){n(e,t.LOCAL)},saveProxyCache(e){n(e,t.PROXY)},isExpired(){let e=new Date(r(a.KEY_CREATION));return e.setHours(e.getHours()+1),Date.now()>=e.getTime()},isFromLocal(){return r(a.KEY_PV_SRC)===t.LOCAL},isFromProxy(){return r(a.KEY_PV_SRC)===t.PROXY},newerThan(e){return PvStorage.getCache().totalsForAllResults["ga:pageviews"]>e.totalsForAllResults["ga:pageviews"]},inspectKeys(){if(localStorage.length===PvStorage.keysCount())for(let e=0;e<localStorage.length;e++)switch(localStorage.key(e)){case a.KEY_PV:case a.KEY_PV_SRC:case a.KEY_CREATION:break;default:return void localStorage.clear()}else localStorage.clear()}}}();function countUp(t,a,r){if(t<a){let e=new CountUp(r,t,a);e.error?console.error(e.error):e.start()}}function countPV(t,a){let r=0;if(void 0!==a)for(let e=0;e<a.length;++e)if(a[parseInt(e,10)][0]===t){r+=parseInt(a[parseInt(e,10)][1],10);break}return r}function tacklePV(e,t,a,r){let o=countPV(t,e);o=0===o?1:o,r?(r=parseInt(a.text().replace(/,/g,""),10),o>r&&countUp(r,o,a.attr("id"))):a.text((new Intl.NumberFormat).format(o))}function displayPageviews(e){if(void 0!==e){let t=getInitStatus();const a=e.rows;0<$("#post-list").length?$(".post-preview").each(function(){var e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)}):0<$(".post").length&&(e=window.location.pathname,tacklePV(a,e,$("#pv"),t))}}function fetchProxyPageviews(){PvOpts.hasProxyMeta()&&$.ajax({type:"GET",url:PvOpts.getProxyMeta(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:e=>{PvStorage.saveProxyCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchLocalPageviews(t=!1){return fetch(PvOpts.getLocalMeta()).then(e=>e.json()).then(e=>{t&&PvStorage.isFromProxy()&&PvStorage.newerThan(e)||(displayPageviews(e),PvStorage.saveLocalCache(JSON.stringify(e)))})}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()?(displayPageviews(PvStorage.getCache()),PvStorage.isExpired()?PvOpts.hasLocalMeta()?fetchLocalPageviews(!0).then(fetchProxyPageviews):fetchProxyPageviews():PvStorage.isFromLocal()&&fetchProxyPageviews()):PvOpts.hasLocalMeta()?fetchLocalPageviews().then(fetchProxyPageviews):fetchProxyPageviews())});

View File

@@ -1,44 +1,21 @@
<div align="right"> # Chirpy
<a href="https://github.com/cotes2020/jekyll-theme-chirpy#readme">EN</a> |
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md">中文 (简体)</a>
</div>
<div align="center"> Language: [English](https://github.com/cotes2020/jekyll-theme-chirpy#readme) | 简体中文
<h1>Chirpy Jekyll Theme</h1>
<p>
<a href="https://rubygems.org/gems/jekyll-theme-chirpy">
<img alt="Gem Version" src="https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen"></img>
</a>
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush">
<img alt="Build Status" src="https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push"></img>
</a>
<a href="https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard">
<img alt="Codacy Badge" src="https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b"></img>
</a>
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE">
<img alt="GitHub license" src="https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg"></img>
</a>
<a href="https://996.icu">
<img alt="996.icu" src="https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg"></img>
</a>
</p>
</div>
一个采用了最简化、侧边栏、响应式设计的 Jekyll 主题,专注于文本展示,旨在帮助您轻松地记录和分享知识。 [![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)](https://rubygems.org/gems/jekyll-theme-chirpy)
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b)](https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard)
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
[在线体验 »](https://chirpy.cotes.info) 一个不一样的 Jekyll 主题,采用响应式设计,方便记录、管理、分享您的知识和经验。[懂的进 »](https://chirpy.cotes.info)
<p align="center"> [![Devices Mockup](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png)](https://chirpy.cotes.info)
<a href="https://chirpy.cotes.info">
<img alt="Devices Mockup" src="https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png"></img>
</a>
</p>
## 功能一览 ## 功能一览
- 本地化外观语言
- 可配置的主题颜色
- 文章置顶 - 文章置顶
- 可配置的全局主题颜色
- 文章最后修改日期 - 文章最后修改日期
- 文章目录 - 文章目录
- 自动推荐相关文章 - 自动推荐相关文章
@@ -57,16 +34,17 @@
## 前提要求 ## 前提要求
参考 [Jekyll Docs](https://jekyllrb.com/docs/installation/) 安装 `Ruby``RubyGems``Jekyll``Bundler`。需要注意的是,`Ruby` 的版本必须与主题在 [RubyGems.org](https://rubygems.org/gems/jekyll-theme-chirpy) 上的要求一致. 参考 [Jekyll Docs](https://jekyllrb.com/docs/installation/) 安装 `Ruby``RubyGems``Jekyll``Bundler`Docker 粉可免。
## 安装 ## 安装
有二法可得此主题: 有二法可得此主题:
- **[从 RubyGems 安装](#从-rubygems-安装)** - 易于版本升级,隔离无关的主题项目文件,让您的仓库舒适清爽。 - **从 RubyGems 安装** - 易于版本升级,隔离无关的主题项目文件,让您的仓库舒适清爽。
- **[从 GitHub 上 Fork](#从-github-上-fork)** - 对个性化二次开发友好,但是难于升级,只适合专业开发人员使用。 - **从 GitHub 上 Fork** - 对个性化二次开发友好,但是难于升级,只适合专业开发人员使用。
### RubyGems 安装 ### RubyGems 安装
在您的 Jekyll 站点的 `Gemfile` 添加: 在您的 Jekyll 站点的 `Gemfile` 添加:
@@ -86,22 +64,17 @@ theme: jekyll-theme-chirpy
$ bundle $ bundle
``` ```
然后,进入主题的 gem 目录: 最后, 拷贝额外所需主题的 gem 文件(详见 [starter 项目][starter] 的文件目录)至您的 Jekyll 站点, 然后把主题的 `_config.yml` 全部内容附加到您的 Jekyll 站点的同名文件。
> **提示**: 定位主题的 gem 文件,可以执行:
>
```console ```console
$ cd "$(bundle info --path jekyll-theme-chirpy)" $ bundle info --path jekyll-theme-chirpy
``` ```
拷贝运行站点所需主题的 gem 文件(详见 [starter 仓库][starter] 的文件目录)至您的 Jekyll 站点, 然后把主题的 `_config.yml` 全部内容附加到您的 Jekyll 站点的同名文件 或者您可以 [使用 starter template][use-starter] 来快速创建 Jekyll 站点,以省去复制主题 gem 文件的时间
> ⚠️ **留意重叠的文件!** ### 在 GitHub 上 Fork
>
> 如果您的网站是通过命令 `jekyll new` 创建的,那么站点的根目录会存在文件 `index.markdown` 和 `about.markdown`。 请务必删除它们, 否则在网站构建后将覆盖主题的 `index.html` 和 `_tabs/about.html`,引起空白或错乱的页面出现。
作为替代方案,同时也被我们力荐,您可以 [使用 starter template][use-starter] 来快速创建 Jekyll 站点,以省去复制主题 gem 文件的时间。那里早已为您准备好建站需要的一切!
### 从 GitHub 上 Fork
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) 然后克隆到本地。(友情提示:默认分支的代码处于开发状态,如果您想博客更加稳定,请切换到最新的 [Tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) 开始写作。) [Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) 然后克隆到本地。(友情提示:默认分支的代码处于开发状态,如果您想博客更加稳定,请切换到最新的 [Tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) 开始写作。)
@@ -141,12 +114,6 @@ $ bash tools/init.sh
- `timezone` - `timezone`
- `lang` - `lang`
### 自定义样式
如果您需要自定义样式, 拷贝主题的文件 `assets/css/style.scss` 到您站点的相同路径上,然后在该文件末尾添加样式。
`v4.1.0` 起,如果您想覆盖文件 `_sass/addon/variables.scss` 里定义的 SASS 变量的默认值,新建文件 `_sass/variables-hook.scss`,然后重写您需要的变量即可。
### 本地运行 ### 本地运行
发布之前,在本地预览: 发布之前,在本地预览:
@@ -215,7 +182,7 @@ $ docker run -it --rm \
## 文档 ## 文档
若想要更多细节以及更佳的阅读体验,请参阅 [线上教程](https://chirpy.cotes.info/categories/tutorial/)。 与此同时,[Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki) 也有一份教程的拷贝。请注意Demo 网站和 Wiki 上的文档都是基于最新的发行版本,而 `master` 分支的功能往往领先于现有文档。 若想要更多细节以及更佳的阅读体验,请参阅 [线上教程](https://chirpy.cotes.info/categories/tutorial/)。 与此同时,[Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki) 也有一份教程的拷贝。
## 参与贡献 ## 参与贡献

View File

@@ -45,6 +45,7 @@ const postJs = () => {
`${JS_SRC}/commons/*.js`, `${JS_SRC}/commons/*.js`,
`${JS_SRC}/utils/img-extra.js`, `${JS_SRC}/utils/img-extra.js`,
`${JS_SRC}/utils/timeago.js`, `${JS_SRC}/utils/timeago.js`,
`${JS_SRC}/utils/lang-badge.js`,
`${JS_SRC}/utils/checkbox.js`, `${JS_SRC}/utils/checkbox.js`,
`${JS_SRC}/utils/copy-link.js`, `${JS_SRC}/utils/copy-link.js`,
// 'smooth-scroll.js' must be called after ToC is ready // 'smooth-scroll.js' must be called after ToC is ready

View File

@@ -2,7 +2,7 @@
Gem::Specification.new do |spec| Gem::Specification.new do |spec|
spec.name = "jekyll-theme-chirpy" spec.name = "jekyll-theme-chirpy"
spec.version = "4.1.1" spec.version = "4.0.0"
spec.authors = ["Cotes Chung"] spec.authors = ["Cotes Chung"]
spec.email = ["cotes.chung@gmail.com"] spec.email = ["cotes.chung@gmail.com"]
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
spec.license = "MIT" spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0").select { |f| spec.files = `git ls-files -z`.split("\x0").select { |f|
f.match(%r!^((_(includes|layouts|sass|data|tabs|plugins)|assets)\/|_config|README|LICENSE|index)!i) f.match(%r!^((assets\/(css|img|js\/[a-z])|_(includes|layouts|sass|config|data|tabs|plugins))|README|LICENSE|index)!i)
} }
spec.metadata = { spec.metadata = {
@@ -23,8 +23,6 @@ Gem::Specification.new do |spec|
"plugin_type" => "theme" "plugin_type" => "theme"
} }
spec.required_ruby_version = [">= 2.4", "< 3.0"]
spec.add_runtime_dependency "jekyll", "~> 4.1" spec.add_runtime_dependency "jekyll", "~> 4.1"
spec.add_runtime_dependency "jekyll-paginate", "~> 1.1" spec.add_runtime_dependency "jekyll-paginate", "~> 1.1"
spec.add_runtime_dependency "jekyll-redirect-from", "~> 0.16" spec.add_runtime_dependency "jekyll-redirect-from", "~> 0.16"

View File

@@ -1,6 +1,6 @@
{ {
"name": "jekyll-theme-chirpy", "name": "jekyll-theme-chirpy",
"version": "4.1.1", "version": "4.0.0",
"description": "A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation.", "description": "A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation.",
"main": "index.js", "main": "index.js",
"directories": { "directories": {

View File

@@ -2,32 +2,29 @@
# #
# How does it work: # How does it work:
# #
# 1. Cherry pick the latest commit from default branch # 1. Bump latest version number to files:
# to the target release branch if the target release branch already existed.
#
# 2. Bump latest version number to the following files:
#
# - _sass/jekyll-theme-chirpy.scss # - _sass/jekyll-theme-chirpy.scss
# - _javascript/copyright # - _javascript/copyright
# - assets/js/dist/*.js (will be built by gulp later) # - assets/js/dist/*.js (will be built by gulp later)
# - jekyll-theme-chirpy.gemspec # - jekyll-theme-chirpy.gemspec
# - package.json # - package.json
# #
# 3. Create a git-tag on release branch # 2. Create a git-tag on release branch
# #
# 4. Build a RubyGems package base on the latest git-tag # 3. Build a RubyGems package base on the latest git-tag
# #
# #
# Usage: # Usage:
# #
# Run on default branch, if run on other branch requires parameter '-m' (manual mode). # Switch to 'master' branch or 'X-Y-stable' branch with argument '-m',
#` and then run this script.
# #
# #
# Requires: Git, Gulp, RubyGems # Requires: Git, Gulp, RubyGems
set -eu set -eu
opt_manual=false manual_release=false
ASSETS=( ASSETS=(
"_sass/jekyll-theme-chirpy.scss" "_sass/jekyll-theme-chirpy.scss"
@@ -38,10 +35,6 @@ GEM_SPEC="jekyll-theme-chirpy.gemspec"
NODE_META="package.json" NODE_META="package.json"
DEFAULT_BRANCH="master"
_working_branch="$(git branch --show-current)"
_check_src() { _check_src() {
if [[ ! -f $1 && ! -d $1 ]]; then if [[ ! -f $1 && ! -d $1 ]]; then
echo -e "Error: Missing file \"$1\"!\n" echo -e "Error: Missing file \"$1\"!\n"
@@ -55,8 +48,8 @@ check() {
exit -1 exit -1
fi fi
# ensure working on default branch or running in 'manual' mode # ensure the current branch is 'master' or running in 'manual' mode
if [[ $_working_branch != $DEFAULT_BRANCH && $opt_manual == "false" ]]; then if [[ "$(git branch --show-current)" != "master" && $manual_release == "false" ]]; then
echo "Error: This operation must be performed on the 'master' branch or '--manual' mode!" echo "Error: This operation must be performed on the 'master' branch or '--manual' mode!"
exit -1 exit -1
fi fi
@@ -107,7 +100,6 @@ release() {
_version="$1" _version="$1"
_major="" _major=""
_minor="" _minor=""
_new_release_branch=false
IFS='.' read -r -a array <<< "$_version" IFS='.' read -r -a array <<< "$_version"
@@ -123,7 +115,7 @@ release() {
_release_branch="$_major-$_minor-stable" _release_branch="$_major-$_minor-stable"
if $opt_manual; then if $manual_release; then
echo -e "Bump version to $_version (manual release)\n" echo -e "Bump version to $_version (manual release)\n"
bump "$_version" bump "$_version"
exit 0 exit 0
@@ -131,11 +123,10 @@ release() {
if [[ -z $(git branch -v | grep "$_release_branch") ]]; then if [[ -z $(git branch -v | grep "$_release_branch") ]]; then
git checkout -b "$_release_branch" git checkout -b "$_release_branch"
_new_release_branch=true
else else
git checkout "$_release_branch" git checkout "$_release_branch"
# cherry-pick the latest commit from master branch to release branch # cherry-pick the latest commit from master branch to release branch
git cherry-pick "$(git rev-parse $DEFAULT_BRANCH)" git cherry-pick "$(git rev-parse master)"
fi fi
echo -e "Bump version to $_version\n" echo -e "Bump version to $_version\n"
@@ -147,14 +138,10 @@ release() {
echo -e "Build the gem pakcage for v$_version\n" echo -e "Build the gem pakcage for v$_version\n"
build_gem build_gem
# head back to working branch # head back to master branch
git checkout "$_working_branch" git checkout master
# cherry-pick the latest commit from release branch to master branch
if [[ $_working_branch == $DEFAULT_BRANCH ]]; then git cherry-pick "$_release_branch" -x
if $_new_release_branch; then
git merge "$_release_branch"
fi
fi
} }
@@ -198,7 +185,7 @@ while (($#)); do
opt="$1" opt="$1"
case $opt in case $opt in
-m | --manual) -m | --manual)
opt_manual=true manual_release=true
shift shift
;; ;;
-h | --help) -h | --help)

View File

@@ -7,6 +7,7 @@
# Usage: bash /path/to/test.sh [indicated path] # Usage: bash /path/to/test.sh [indicated path]
DEST=_site DEST=_site
URL_IGNORE=cdn.jsdelivr.net
_build=false _build=false
@@ -61,4 +62,6 @@ fi
bundle exec htmlproofer "$DEST" \ bundle exec htmlproofer "$DEST" \
--disable-external \ --disable-external \
--check-html \ --check-html \
--allow_hash_href --empty_alt_ignore \
--allow_hash_href \
--url_ignore $URL_IGNORE