Import the framework.
24
404.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
# The 404 page
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT License
|
||||
layout: page
|
||||
title: "404: Page not found"
|
||||
|
||||
permalink: /404.html
|
||||
|
||||
redirect_from: # Same as site.blocklist
|
||||
- /norobots/
|
||||
- /assets/
|
||||
- /tabs/
|
||||
- /categories/
|
||||
- /tags/
|
||||
- /posts/
|
||||
|
||||
dynamic_title: true
|
||||
---
|
||||
|
||||
<div class="lead">
|
||||
<p>Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. </p>
|
||||
<p><a href="{{ site.baseurl }}/">Head back Home</a> to try finding it again, or search for it on the <a href="{{ site.baseurl }}/tabs/archives">Archives page</a>.</p>
|
||||
</div>
|
13
Gemfile
Normal file
|
@ -0,0 +1,13 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'jekyll', '>=3.8.6'
|
||||
|
||||
# Official Plugins
|
||||
group :jekyll_plugins do
|
||||
gem 'jekyll-paginate'
|
||||
gem 'jekyll-redirect-from'
|
||||
gem 'jekyll-seo-tag'
|
||||
end
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Cotes Chung
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
166
_config.yml
Normal file
|
@ -0,0 +1,166 @@
|
|||
# The Site Settings
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT licensed
|
||||
|
||||
|
||||
# jekyll-seo-tag settings › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
|
||||
#--------------------------
|
||||
|
||||
title: Chirpy
|
||||
|
||||
description: 'A text-based Jekyll theme.'
|
||||
|
||||
# Replace with your domain, e.g. "https://username.github.io"
|
||||
url: 'https://www.example.com'
|
||||
|
||||
author: Chirpy # change to your full name
|
||||
|
||||
logo: /assets/img/sample/profile.jpg # Support network resources.
|
||||
|
||||
github:
|
||||
username: github_username # change to your github username
|
||||
|
||||
twitter:
|
||||
username: twitter_username # change to your twitter username
|
||||
|
||||
social:
|
||||
name: Chirpy # change to your full name
|
||||
email: example@doamin.com # change to your email address
|
||||
links:
|
||||
- https://twitter.com/username # change to your twitter homepage
|
||||
- https://github.com/username # change to your github homepage
|
||||
# - https://www.facebook.com/username
|
||||
# - https://www.linkedin.com/in/username
|
||||
|
||||
google_site_verification: google_meta_tag_verification # change to your verification string
|
||||
|
||||
#--------------------------
|
||||
|
||||
# Change to your Google Analytics ID
|
||||
google_analytics:
|
||||
id: 'UA-*********-*'
|
||||
# Switch for Google Analytics pageviews. DO NOT enable it unless you know how to deploy the Google Analytics superProxy.
|
||||
pv: false
|
||||
|
||||
disqus:
|
||||
shortname: 'disqus' # Change to your Disqus shortname.
|
||||
comments: true # boolean type, the gobal switch of posts' comments.
|
||||
|
||||
# The year your website was first run.
|
||||
first_run: 2019
|
||||
|
||||
# boolean type, gobal switch for ToC in posts.
|
||||
toc: true
|
||||
|
||||
|
||||
# if your site type is Project Pages site, change below value to '/projectname'
|
||||
baseurl: ''
|
||||
|
||||
paginate: 10
|
||||
|
||||
markdown: kramdown
|
||||
|
||||
highlighter: rouge
|
||||
|
||||
kramdown:
|
||||
input: GFM
|
||||
syntax_highlighter: rouge
|
||||
syntax_highlighter_opts: # Rouge Options › https://github.com/jneen/rouge#full-options
|
||||
css_class: 'highlight'
|
||||
# default_lang: console
|
||||
span:
|
||||
line_numbers: false
|
||||
block:
|
||||
line_numbers: true
|
||||
start_line: 1
|
||||
|
||||
permalink: /posts/:title/
|
||||
|
||||
defaults:
|
||||
-
|
||||
scope:
|
||||
path: "" # An empty string here means all files in the project
|
||||
type: posts
|
||||
values:
|
||||
layout: post
|
||||
comments: true # Enable comments in posts.
|
||||
toc: true # Display TOC column in posts.
|
||||
location: Post
|
||||
breadcrumb:
|
||||
-
|
||||
label: Posts
|
||||
url: /
|
||||
-
|
||||
scope:
|
||||
path: _drafts
|
||||
values:
|
||||
comments: false
|
||||
-
|
||||
scope:
|
||||
path: tags
|
||||
values:
|
||||
location: Tag
|
||||
breadcrumb:
|
||||
-
|
||||
label: Home
|
||||
url: /
|
||||
-
|
||||
label: Tags
|
||||
url: /tabs/tags/
|
||||
-
|
||||
scope:
|
||||
path: categories
|
||||
values:
|
||||
location: Category
|
||||
breadcrumb:
|
||||
-
|
||||
label: Home
|
||||
url: /
|
||||
-
|
||||
label: Categories
|
||||
url: /tabs/categories/
|
||||
-
|
||||
scope:
|
||||
path: tabs
|
||||
values:
|
||||
layout: page
|
||||
dynamic_title: true # hide title in mobile screens.
|
||||
breadcrumb:
|
||||
-
|
||||
label: Home
|
||||
url: /
|
||||
|
||||
timezone: Asia/Shanghai
|
||||
|
||||
sass:
|
||||
sass_dir: /assets/css
|
||||
style: compressed
|
||||
|
||||
compress_html:
|
||||
clippings: all
|
||||
comments: ["<!-- ", " -->"]
|
||||
endings: [html, head, body, dt, dd, rt, rp, optgroup, option, colgroup, caption, thead, tbody, tfoot, tr, td, th]
|
||||
profile: false
|
||||
blanklines: false
|
||||
ignore:
|
||||
envs: []
|
||||
|
||||
exclude:
|
||||
- vendor/ # Avoid Jekyll mistakenly read the vender directory in Travis-CI's VM .
|
||||
- Gemfile.lock
|
||||
- Gemfile
|
||||
- run.sh
|
||||
- build.sh
|
||||
- init.sh
|
||||
- pv.sh
|
||||
|
||||
sitemap_exclude: # Sitemap will exclude the following items.
|
||||
- /norobots/
|
||||
- /assets/
|
||||
- /tabs/
|
||||
- /categories/
|
||||
- /tags/
|
||||
- /posts/
|
||||
- /404.html
|
||||
- /redirects.json
|
||||
- /search.json
|
17
_data/label.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
# The label text of site.
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
|
||||
tabs:
|
||||
- { name: "Home" }
|
||||
- { name: "Categories", path: tabs, url: categories }
|
||||
- { name: "Tags", path: tabs, url: tags }
|
||||
- { name: "Archives", path: tabs, url: archives }
|
||||
- { name: "About", path: tabs, url: about }
|
||||
|
||||
panel:
|
||||
lastmod: "Recent Update"
|
||||
trending_tags: "Trending Tags"
|
||||
toc: "Contents"
|
||||
|
||||
search_hint: "Search" # text show on search bar
|
8
_includes/date-format.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!--
|
||||
Define the liquid date formats.
|
||||
© 2019 Cotes Chung
|
||||
Published under the MIT License
|
||||
-->
|
||||
|
||||
{% assign TOOLTIP_DATE = "%a, %b %e, %Y, %l:%M %p %z" %}
|
||||
{% assign POST_DATE = "%b %e, %Y" %}
|
24
_includes/disqus.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!--
|
||||
The Disqus lazy loading.
|
||||
Powered by: https://osvaldas.info/lazy-loading-disqus-comments
|
||||
© 2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
|
||||
<div id="disqus" class="pt-2 pb-4">
|
||||
<p class="font-italic text-muted small">Comments powered by <a href="https://disqus.com/">Disqus</a>.</p>
|
||||
</div>
|
||||
|
||||
<script src="{{ site.baseurl }}/assets/lib/jquery.disqusloader.min.js"></script>
|
||||
<script>
|
||||
var options = {
|
||||
scriptUrl: '//{{ site.disqus.shortname }}.disqus.com/embed.js',
|
||||
|
||||
disqusConfig: function() {
|
||||
this.page.url = '{{ site.url | append: site.baseurl | append: page.url }}';
|
||||
this.page.identifier = '{{ page.url }}';
|
||||
}
|
||||
};
|
||||
|
||||
$.disqusLoader('#disqus', options);
|
||||
</script>
|
34
_includes/favicons.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!--
|
||||
The Favicons for Web, Android, Microsoft, and iOS (iPhone and iPad) Apps
|
||||
Generated by: https://www.favicon-generator.org/
|
||||
© 2019 Cotes Chung
|
||||
Published under the MIT license
|
||||
-->
|
||||
|
||||
{% capture icon_url %}{{ site.baseurl }}/assets/img/favicons{% endcapture %}
|
||||
|
||||
<link rel="shortcut icon" href="{{ icon_url }}/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="{{ icon_url }}/favicon.ico" type="image/x-icon">
|
||||
|
||||
<link rel="apple-touch-icon" href="{{ icon_url }}/apple-icon.png">
|
||||
<link rel="apple-touch-icon" href="{{ icon_url }}/apple-icon-precomposed.png">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="{{ icon_url }}/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="{{ icon_url }}/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="{{ icon_url }}/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="{{ icon_url }}/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="{{ icon_url }}/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="{{ icon_url }}/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="{{ icon_url }}/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="{{ icon_url }}/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ icon_url }}/apple-icon-180x180.png">
|
||||
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="{{ icon_url }}/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ icon_url }}/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="{{ icon_url }}/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ icon_url }}/favicon-16x16.png">
|
||||
|
||||
<link rel="manifest" href="{{ icon_url }}/manifest.json">
|
||||
<meta name='msapplication-config' content='{{ icon_url }}/browserconfig.xml'>
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="{{ icon_url }}/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
9
_includes/fixlinenos.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<!--
|
||||
Fixed kramdown code highlight rendering:
|
||||
https://github.com/penibelst/jekyll-compress-html/issues/101
|
||||
https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
|
||||
-->
|
||||
{% if _content contains '<pre class="highlight">' %}
|
||||
{% assign _content = _content | replace: '<pre class="highlight"><code', '<code' %}
|
||||
{% assign _content = _content | replace: '</code></pre>', '</code>' %}
|
||||
{% endif %}
|
24
_includes/footer.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!--
|
||||
The Footer
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
|
||||
<footer class="d-flex w-100 justify-content-center">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="copyright">
|
||||
{% assign first = site.first_run | plus: 0 %}
|
||||
{% assign last = 'now' | date: "%Y" | plus: 0 %}
|
||||
<p class="mb-0">
|
||||
© {% if last > first %}{{ first }}-{% endif %}{{-last-}}
|
||||
<a href="{{ site.social.links[0] }}" class="ml-1">{{ site.social.name }}</a>.
|
||||
<br>Powered by <a href="https://jekyllrb.com" target="_blank">Jekyll</a> & <a href="https://github.com/cotes2020/jekyll-theme-chirpy/">Chirpy</a>, hosted on <a href="https://pages.github.com/" target="_blank">GitHub Pages</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="license">
|
||||
<p class="mb-0">
|
||||
The blog posts on this site are licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div> <!-- div.d-flex -->
|
||||
</footer>
|
14
_includes/google-analytics.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!--
|
||||
The GA snippet
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '{{ site.google_analytics.id }}', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
53
_includes/head.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
<!--
|
||||
The Head
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
|
||||
<head>
|
||||
<title>
|
||||
{%- if page.layout == "home" -%}
|
||||
{{- site.title -}}
|
||||
{%- else -%}
|
||||
{{ page.title }} | {{ site.title }}
|
||||
{%- endif -%}
|
||||
</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
{% seo title=false %}
|
||||
|
||||
{% include favicons.html %}
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
|
||||
integrity="sha256-LA89z+k9fjgMKQ/kq4OO2Mrf8VltYml/VES+Rg0fh20=" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.11.2/css/all.min.css"
|
||||
integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ="
|
||||
crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="{{ site.baseurl }}/assets/css/styles.css">
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"
|
||||
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
document.jQuery || document.write('<script src="{{ site.baseurl }}/assets/lib/jquery-3.4.1.min.js"><\/script>');
|
||||
</script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.15.0/dist/umd/popper.min.js"
|
||||
integrity="sha256-fTuUgtT7O2rqoImwjrhDgbXTKUwyxxujIMRIK7TbuNU=" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js"
|
||||
integrity="sha256-5+02zu5UULQkO7w1GIr6vftCgMfFdZcAHeDtFnKZsBs=" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/commons.js" async></script>
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
{% include google-analytics.html %}
|
||||
{% endif %}
|
||||
|
||||
</head>
|
72
_includes/panel.html
Normal file
|
@ -0,0 +1,72 @@
|
|||
<!--
|
||||
The Pannel on right side (Desktop views)
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
|
||||
<div class="panel-group">
|
||||
|
||||
{% assign lastmod_list = "" | split: "" %}
|
||||
|
||||
{% for post in site.posts %}
|
||||
{% if post.date >= post.seo.date_modified or post.seo.date_modified == nil %}
|
||||
{% continue %}
|
||||
{% endif%}
|
||||
{% capture item %}
|
||||
{{ post.seo.date_modified }}::{{ post.title }}::{{ post.url }}
|
||||
{% endcapture %}
|
||||
{% assign lastmod_list = lastmod_list | push: item %}
|
||||
{% endfor %}
|
||||
|
||||
{% if lastmod_list.size > 0 %}
|
||||
<div id="panel-update" class="post mb-4"">
|
||||
<h3 data-toc-skip>
|
||||
{{ site.data.label.panel.lastmod }}
|
||||
</h3>
|
||||
<ul class="post-content pl-0 mt-2 pb-1">
|
||||
{% assign MAX_SIZE = 5 %}
|
||||
{% assign sum = 0 %}
|
||||
{% assign sorted_posts = lastmod_list | sort | reverse %}
|
||||
{% for post in sorted_posts %}
|
||||
{% assign meta = post | split: "::" %}
|
||||
<li><a href="{{ meta[2] | prepend: site.baseurl }}">{{ meta[1] }}</a></li>
|
||||
{% assign sum = sum | plus: 1 %}
|
||||
{% if sum >= MAX_SIZE %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div><!-- #panel-update -->
|
||||
{% endif %}
|
||||
|
||||
<div id="panel-tags">
|
||||
<h3 data-toc-skip>
|
||||
{{ site.data.label.panel.trending_tags }}
|
||||
</h3>
|
||||
<div class="d-flex flex-wrap mt-2 pb-1 pr-3">
|
||||
{% capture tags_array %}
|
||||
{% for tag in site.tags %}
|
||||
{{ tag[1] | size }}:{{ tag[0] | replace: ' ', '-' }}
|
||||
{% endfor %}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign MAX = 10 %}
|
||||
{% assign count = 0 %}
|
||||
{% assign trends = tags_array | split: " " | sort | reverse %}
|
||||
|
||||
<div>
|
||||
<!-- <p>tags_array->{{ tags_array }}</p> -->
|
||||
{% for trend in trends %}
|
||||
{% assign count = count | plus: 1 %}
|
||||
{% assign tag = trend | split: ":" | last %}
|
||||
<a class="post-tag" href="{{ site.baseurl }}/tags/{{ tag | downcase }}/">{{ tag | replace: '-', ' ' }}</a>
|
||||
{% if count >= MAX %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div><!-- #panel-tags -->
|
||||
|
||||
</div>
|
15
_includes/search-results.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!--
|
||||
The Search results
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
<div id="search-result-wrap">
|
||||
<div class="row justify-content-center bg-white">
|
||||
<div class="col-12 col-md-12 col-lg-11 col-xl-9 pl-xl-5 pr-xl-5 pb-5 mt-3 mb-3">
|
||||
<h2 class="mt-3 pt-3 ml-3 ml-md-5 ml-lg-0" data-toc-skip>Search Results</h2>
|
||||
<div class="post-content ml-1 ml-md-5 ml-lg-0">
|
||||
<ul id="search-results" ></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
13
_includes/search.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!--
|
||||
The Search
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
<script src="{{ site.baseurl }}/assets/lib/simple-jekyll-search-1.7.1.min.js"></script>
|
||||
<script>
|
||||
SimpleJekyllSearch({
|
||||
searchInput: document.getElementById('search-input'),
|
||||
resultsContainer: document.getElementById('search-results'),
|
||||
json: '{{ site.baseurl }}/search.json'
|
||||
})
|
||||
</script>
|
65
_includes/sidebar.html
Normal file
|
@ -0,0 +1,65 @@
|
|||
<!--
|
||||
The Side Bar
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
|
||||
<div id="nav-wrap">
|
||||
<div id="profile-wrap" class="d-flex justify-content-center">
|
||||
<div id="profile">
|
||||
<a href="{{ site.baseurl }}/" alt="profile-photo">
|
||||
{% assign profile_img = site.logo %}
|
||||
{% if profile_img | slice: 0 == '/' %}
|
||||
{% assign profile_img = profile_img | prepend: site.baseurl %}
|
||||
{% endif %}
|
||||
<img src="{{ profile_img }}"></img>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="site-title" class="d-flex justify-content-center align-items-center">
|
||||
<a href="{{ site.baseurl }}/">{{- site.title -}}</a>
|
||||
</div>
|
||||
<div id="site-subtitle" class="font-italic">{{ site.description }}</div>
|
||||
<ul class="nav flex-column">
|
||||
|
||||
{% assign page_urls = page.url | split: "/" %}
|
||||
|
||||
{% for item in site.data.label.tabs %}
|
||||
{% assign ref = site.baseurl | append: "/" %}
|
||||
|
||||
{% if item.path %}
|
||||
{% assign ref = ref | append: item.path | append: "/" %}
|
||||
{% if item.url %}
|
||||
{% assign ref = ref | append: item.url | append: "/" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<li class="nav-item d-flex justify-content-center
|
||||
{% if item.url == page_urls.last or
|
||||
item.name == "Home" and page.layout == "home" %}active{% endif %}">
|
||||
<a href="{{ ref }}" class="nav-link d-flex justify-content-center align-items-center w-100"><!-- <i class="{{ item.icon }}"></i> -->
|
||||
{{ item.name | upcase }}
|
||||
</a>
|
||||
</li> <!-- .nav-item -->
|
||||
{% endfor %}
|
||||
|
||||
<span class="cursor"></span>
|
||||
</ul> <!-- ul.nav.flex-column -->
|
||||
|
||||
</div><!-- #nav-wrap -->
|
||||
|
||||
<div class="contact d-flex justify-content-around mt-3">
|
||||
<a href="https://github.com/{{ site.github.username }}" target="_blank">
|
||||
<i class="fab fa-github"></i>
|
||||
</a>
|
||||
<a href="https://twitter.com/{{ site.twitter.username }}" target="_blank">
|
||||
<i class="fab fa-twitter"></i>
|
||||
</a>
|
||||
{% assign email = site.social.email | split: '@' %}
|
||||
<a href="javascript:window.open('mailto:' + ['{{ email[0] }}','{{ email[1] }}'].join('@'))">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</a>
|
||||
<a href="{{ site.baseurl }}/feed.xml" target="_blank">
|
||||
<i class="fas fa-rss"></i>
|
||||
</a>
|
||||
</div>
|
49
_includes/topbar.html
Normal file
|
@ -0,0 +1,49 @@
|
|||
<!--
|
||||
The Top Bar
|
||||
© 2017-2019 Cotes Chung
|
||||
MIT License
|
||||
-->
|
||||
<div id="topbar" class="bg-white row justify-content-center topbar-down">
|
||||
|
||||
<div id="topbar-main" class="d-flex h-100 align-items-center justify-content-between col-12 col-md-12 col-lg-11 col-xl-11 pl-md-2 pr-md-2 pl-lg-2 pr-lg-2">
|
||||
|
||||
<span id="breadcrumb">
|
||||
{% for item in page.breadcrumb %}
|
||||
{% if item.url %}
|
||||
<span>
|
||||
<a href="{{ site.baseurl }}{{ item.url | remove: '.html'}}">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<span>{{ item.label }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% unless page.layout == "home" %}
|
||||
<span>{{ page.title }}</span>
|
||||
{% endunless %}
|
||||
|
||||
</span><!-- endof #breadcrumb -->
|
||||
|
||||
<i id="sidebar-trigger" class="fas fa-bars fa-fw"></i>
|
||||
|
||||
<div id="topbar-title">
|
||||
{% if page.location %}
|
||||
{{- page.location -}}
|
||||
{% elsif page.layout == "home" %}
|
||||
{{- site.title -}}
|
||||
{% else %}
|
||||
{{- page.title -}}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<i id="search-trigger" class="fas fa-search fa-fw"></i>
|
||||
<span id="search-wrap">
|
||||
<i class="fas fa-search fa-fw"></i>
|
||||
<input class="form-control" id="search-input" type="search" placeholder="{{ site.data.label.search_hint }}...">
|
||||
</span>
|
||||
<a href="javascript:;">Cancel</a>
|
||||
</div>
|
||||
|
||||
</div>
|
26
_layouts/category.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
layout: page
|
||||
# The Category layout
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
---
|
||||
|
||||
{% include date-format.html %}
|
||||
|
||||
<div id="page-category">
|
||||
<h1>
|
||||
<i class="far fa-folder-open fa-fw text-muted"></i>
|
||||
{{ page.title }}
|
||||
<span class="lead text-muted pl-2">{{ site.categories[page.category] | size }}</span>
|
||||
</h1>
|
||||
|
||||
<ul class="post-content pl-0">
|
||||
{% for post in site.categories[page.category] %}
|
||||
<li class="d-flex justify-content-between pl-md-3 pr-md-3">
|
||||
<a href="{{ post.url | absolute_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
<span class="text-muted small">{{ post.date | date: POST_DATE }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
10
_layouts/compress.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
# Jekyll layout that compresses HTML
|
||||
# v3.1.0
|
||||
# http://jch.penibelst.de/
|
||||
# © 2014–2015 Anatol Broder
|
||||
# MIT License
|
||||
---
|
||||
|
||||
{% capture _LINE_FEED %}
|
||||
{% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment or site.compress_html.ignore.envs == "all" %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}</{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% for _element in site.compress_html.startings %}{% capture _start %}<{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _start %}{% endfor %}{% if _profile and site.compress_html.startings %}{% assign _profile_startings = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "<!-- -->" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% capture _comment_befores %}.{{ _content }}{% endcapture %}{% assign _comment_befores = _comment_befores | split: _comments.first %}{% for _comment_before in _comment_befores %}{% if forloop.first %}{% continue %}{% endif %}{% capture _comment_outside %}{% if _carry %}{{ _comments.first }}{% endif %}{{ _comment_before }}{% endcapture %}{% capture _comment %}{% unless _carry %}{{ _comments.first }}{% endunless %}{{ _comment_outside | split: _comments.last | first }}{% if _comment_outside contains _comments.last %}{{ _comments.last }}{% assign _carry = false %}{% else %}{% assign _carry = true %}{% endif %}{% endcapture %}{% assign _content = _content | remove_first: _comment %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% assign _pre_befores = _content | split: "<pre" %}{% assign _content = "" %}{% for _pre_before in _pre_befores %}{% assign _pres = _pre_before | split: "</pre>" %}{% assign _pres_after = "" %}{% if _pres.size != 0 %}{% if site.compress_html.blanklines %}{% assign _lines = _pres.last | split: _LINE_FEED %}{% capture _pres_after %}{% for _line in _lines %}{% assign _trimmed = _line | split: " " | join: " " %}{% if _trimmed != empty or forloop.last %}{% unless forloop.first %}{{ _LINE_FEED }}{% endunless %}{{ _line }}{% endif %}{% endfor %}{% endcapture %}{% else %}{% assign _pres_after = _pres.last | split: " " | join: " " %}{% endif %}{% endif %}{% capture _content %}{{ _content }}{% if _pre_before contains "</pre>" %}<pre{{ _pres.first }}</pre>{% endif %}{% unless _pre_before contains "</pre>" and _pres.size == 1 %}{{ _pres_after }}{% endunless %}{% endcapture %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " <e;<e; </e>;</e>;</e> ;</e>" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %} <table id="compress_html_profile_{{ site.time | date: "%Y%m%d" }}" class="compress_html_profile"> <thead> <tr> <td>Step <td>Bytes <tbody> <tr> <td>raw <td>{{ content | size }}{% if _profile_endings %} <tr> <td>endings <td>{{ _profile_endings }}{% endif %}{% if _profile_startings %} <tr> <td>startings <td>{{ _profile_startings }}{% endif %}{% if _profile_comments %} <tr> <td>comments <td>{{ _profile_comments }}{% endif %}{% if _profile_collapse %} <tr> <td>collapse <td>{{ _profile_collapse }}{% endif %}{% if _profile_clippings %} <tr> <td>clippings <td>{{ _profile_clippings }}{% endif %} </table>{% endif %}{% endif %}
|
44
_layouts/default.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
layout: compress
|
||||
# Default layout
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
{% include head.html %}
|
||||
|
||||
<body data-spy="scroll" data-target="#toc">
|
||||
<div id="sidebar" class="d-flex flex-column">
|
||||
{% include sidebar.html %}
|
||||
</div>
|
||||
<div id="main-wrap">
|
||||
{% include topbar.html %}
|
||||
<div id="main">
|
||||
<div class="row justify-content-center bg-white">
|
||||
|
||||
{% capture _content %}
|
||||
{{ content }}
|
||||
{% endcapture %}
|
||||
|
||||
{% include fixlinenos.html %}
|
||||
{{ _content }}
|
||||
|
||||
</div>
|
||||
{% include footer.html %}
|
||||
</div>
|
||||
{% include search-results.html %}
|
||||
</div>
|
||||
|
||||
<div id="mask"></div>
|
||||
|
||||
{% include search.html %}
|
||||
|
||||
<a id="back-to-top" href="#" class="btn btn-lg btn-box-shadow" role="button">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
</body>
|
||||
|
||||
</html>
|
128
_layouts/home.html
Normal file
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
layout: page
|
||||
# The Home page layout
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
---
|
||||
|
||||
{% include date-format.html %}
|
||||
|
||||
<div id="post-list">
|
||||
{% for post in paginator.posts %}
|
||||
<div class="post-preview">
|
||||
<h1>
|
||||
<a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
|
||||
</h1>
|
||||
<div class="post-content">
|
||||
<p>
|
||||
{{ post.content | strip_html | truncate: 200 }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="post-meta text-muted pt-1">
|
||||
<!-- posted date -->
|
||||
<i class="far fa-clock fa-fw"></i>
|
||||
<span class="timeago" data-toggle="tooltip" title="{{ post.date | date: TOOLTIP_DATE }}">
|
||||
{{ post.date | date: POST_DATE }}
|
||||
<i class="hidden">{{ post.date | date_to_xmlschema }}</i>
|
||||
</span>
|
||||
<!-- page views -->
|
||||
{% if site.google_analytics.pv %}
|
||||
<i class="far fa-eye fa-fw"></i>
|
||||
<span id="pv_{{-post.title-}}" class="pageviews">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div> <!-- .post-review -->
|
||||
{% endfor %}
|
||||
</div> <!-- #post-list -->
|
||||
|
||||
{% if paginator.total_pages > 0 %}
|
||||
<ul class="pagination mt-4 mb-0 pl-lg-2">
|
||||
<!-- left arrow -->
|
||||
{% if paginator.previous_page %}
|
||||
<li class="page-item">
|
||||
<a class="page-link btn-box-shadow" href="{{ site.baseurl }}{{ paginator.previous_page_path }}">
|
||||
<i class="fas fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link btn-box-shadow" href="#"><i class="fas fa-angle-left"></i></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<!-- endof left arrow -->
|
||||
|
||||
<!-- page numbers -->
|
||||
{% assign left_ellipsis = false %}
|
||||
{% assign right_ellipsis = false %}
|
||||
|
||||
{% for i in (1..paginator.total_pages) %}
|
||||
|
||||
{% assign pre = paginator.page | minus: 1 %}
|
||||
{% assign next = paginator.page | plus: 1 %}
|
||||
{% assign pre_less = pre | minus: 1 %}
|
||||
{% assign next_more = next | plus: 1 %}
|
||||
{% assign show = false %}
|
||||
|
||||
{% if paginator.page == 1 %}
|
||||
{% if i <= 3 or i == paginator.total_pages %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% elsif paginator.page == paginator.total_pages %}
|
||||
{% if i == 1 or i >= pre_less %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if i == 1 or i == paginator.total_pages%}
|
||||
{% assign show = true %}
|
||||
{% elsif i >= pre and i <= next %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if show %}
|
||||
<!-- show number -->
|
||||
<li class="page-item {% if i == paginator.page %} active{% endif %}">
|
||||
<a class="page-link btn-box-shadow" href="{{ site.baseurl }}/{% if i > 1%}page{{ i }}/{% endif %}">{{ i }}</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<!-- hide number -->
|
||||
{% if i < pre and left_ellipsis == false %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link btn-box-shadow">...</span>
|
||||
</li>
|
||||
{% assign left_ellipsis = true %}
|
||||
{% elsif i > next and right_ellipsis == false %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link btn-box-shadow">...</span>
|
||||
</li>
|
||||
{% assign right_ellipsis = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
<!-- right arrow -->
|
||||
{% if paginator.next_page %}
|
||||
<li class="page-item">
|
||||
<a class="page-link btn-box-shadow" href="{{ site.baseurl }}{{ paginator.next_page_path }}">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link btn-box-shadow" href="#"><i class="fas fa-angle-right"></i></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul> <!-- .pagination -->
|
||||
{% endif %}
|
||||
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/timeago.min.js"></script>
|
||||
|
||||
{% if site.google_analytics.pv %}
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/countUp.min.js" async></script>
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/pageviews.min.js" async></script>
|
||||
{% endif %}
|
29
_layouts/page.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
layout: default
|
||||
# The page layout
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
||||
|
||||
<div class="col-12 col-lg-11 col-xl-8">
|
||||
<div id="page" class="post pb-5 pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 pl-xl-3">
|
||||
|
||||
{% if page.dynamic_title %}
|
||||
|
||||
<h1 class="dynamic-title">{{ page.title }}</h1>
|
||||
<div class="post-content">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
|
||||
{{ content }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div> <!-- #page -->
|
||||
</div><!-- end .col-12 -->
|
||||
|
||||
<div id="panel-wrap" class="col-xl-3 pl-2">
|
||||
{% include panel.html %}
|
||||
</div>
|
117
_layouts/post.html
Normal file
|
@ -0,0 +1,117 @@
|
|||
---
|
||||
layout: default
|
||||
# The posts' layout
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
---
|
||||
|
||||
{% include date-format.html %}
|
||||
|
||||
<div class="col-12 col-lg-11 col-xl-8">
|
||||
<div id="post-wrap" class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 pl-xl-3">
|
||||
<div class="post">
|
||||
<h1 data-toc-skip>{{ page.title }}</h1>
|
||||
<div class="post-meta text-muted d-flex flex-column">
|
||||
<!-- Published Date and Categoreis -->
|
||||
<div>
|
||||
<span class="timeago" data-toggle="tooltip" title="{{ page.date | date: TOOLTIP_DATE }}">
|
||||
{{ page.date | date: POST_DATE }}
|
||||
<i class="hidden">{{ page.date | date_to_xmlschema }}</i>
|
||||
</span>
|
||||
{% if page.categories.size > 0 %}on{% endif %}
|
||||
{% for category in page.categories %}
|
||||
<a href='{{ site.baseurl }}/categories/{{ category | replace: ' ', '-' | downcase }}/'>{{ category }}</a>
|
||||
{%- unless forloop.last -%}, {%- endunless -%}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- lastmod -->
|
||||
{% if page.seo.date_modified > page.date %}
|
||||
<div>
|
||||
Updated
|
||||
<span class="timeago lastmod" data-toggle="tooltip" title="{{ page.seo.date_modified | date: TOOLTIP_DATE }}">
|
||||
{{ page.seo.date_modified | date: POST_DATE }}
|
||||
<i class="hidden">{{ page.seo.date_modified | date_to_xmlschema}}</i>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- page views -->
|
||||
{% if site.google_analytics.pv %}
|
||||
<div>
|
||||
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin"></i></span> views
|
||||
</div>
|
||||
{% endif %}
|
||||
</div> <!-- .post-meta -->
|
||||
|
||||
<div class="post-content">
|
||||
{% if page.image %}
|
||||
<img src="{{ page.image }}" class="img-rounded">
|
||||
{% endif %}
|
||||
{{ content }}
|
||||
</div><!-- .post-content -->
|
||||
|
||||
<div class="post-tail text-muted">
|
||||
<!-- Tags -->
|
||||
{% if page.tags.size > 0 %}
|
||||
<div class="mb-2">
|
||||
{% for tag in page.tags %}
|
||||
<a href="{{ site.baseurl }}/tags/{{ tag | replace: ' ', '-' | downcase }}/"
|
||||
class="post-tag no-text-decoration" >
|
||||
{{- tag -}}
|
||||
</a>{%- if forloop.last != true -%} {%- endif -%}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div><!-- endof .post-tail -->
|
||||
|
||||
</div> <!-- .post -->
|
||||
|
||||
<div class="post-pager d-flex justify-content-between">
|
||||
{% if page.previous.url %}
|
||||
<a href="{{ site.baseurl }}{{page.previous.url}}" class="btn btn-outline-primary">
|
||||
{% else %}
|
||||
<a href="javascript:;" class="btn btn-outline-primary disabled">
|
||||
{% endif %}
|
||||
<i class="fas fa-angle-left mr-1"></i>
|
||||
OLDER POST
|
||||
</a>
|
||||
|
||||
{% if page.next.url %}
|
||||
<a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary">
|
||||
{% else %}
|
||||
<a href="javascript:;" class="btn btn-outline-primary disabled">
|
||||
{% endif %}
|
||||
NEWER POST
|
||||
<i class="fas fa-angle-right ml-1"></i>
|
||||
</a>
|
||||
</div> <!-- end .post-pager -->
|
||||
|
||||
{% if site.disqus.comments and page.comments %}
|
||||
{% include disqus.html %}
|
||||
{% else %}
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
</div> <!-- #post-wrap -->
|
||||
</div> <!-- div.col-12..col-lg-11.col-xl-8 -->
|
||||
|
||||
<div id="post-panel" class="col-xl-3 pl-2">
|
||||
{% include panel.html %}
|
||||
{% if site.toc and page.toc %}
|
||||
<div id="toc-wrap" class="topbar-down pr-4">
|
||||
<h3 data-toc-skip class="pl-3 pt-2">
|
||||
{{ site.data.label.panel.toc }}
|
||||
</h3>
|
||||
<nav id="toc" data-toggle="toc"></nav>
|
||||
</div>
|
||||
<link rel="stylesheet" href="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css" />
|
||||
<script src="{{ site.baseurl }}/assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script>
|
||||
{% endif %}
|
||||
</div> <!-- #post-panel -->
|
||||
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/timeago.min.js"></script>
|
||||
|
||||
{% if site.google_analytics.pv %}
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/countUp.min.js" async></script>
|
||||
<script src="{{ site.baseurl }}/assets/js/dist/pageviews.min.js" async></script>
|
||||
{% endif %}
|
25
_layouts/tag.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
layout: page
|
||||
# The layout for Tag page
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
---
|
||||
|
||||
{% include date-format.html %}
|
||||
|
||||
<div id="page-tag">
|
||||
<h1>
|
||||
<i class="fa fa-tag fa-fw text-muted"></i>
|
||||
{{ page.title }}
|
||||
<span class="lead text-muted pl-2">{{ site.tags[page.tag] | size }}</span>
|
||||
</h1>
|
||||
<ul class="post-content pl-0">
|
||||
{% for post in site.tags[page.tag] %}
|
||||
<li class="d-flex justify-content-between pl-md-3 pr-md-3">
|
||||
<a href="{{ post.url | absolute_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
<span class="text-muted small">{{ post.date | date: POST_DATE }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
16
_scripts/py/init_all.py
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Automatic invokes all initial scripts for project.
|
||||
© 2018-2019 Cotes Chung
|
||||
Licensed under MIT
|
||||
"""
|
||||
|
||||
import update_posts_lastmod
|
||||
import pages_generator
|
||||
|
||||
|
||||
update_posts_lastmod
|
||||
|
||||
pages_generator
|
190
_scripts/py/pages_generator.py
Executable file
|
@ -0,0 +1,190 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Generates HTML pages for Categories and Tags in posts.
|
||||
|
||||
Dependencies:
|
||||
- git
|
||||
- ruamel.yaml
|
||||
|
||||
© 2018-2019 Cotes Chung
|
||||
MIT License
|
||||
'''
|
||||
|
||||
|
||||
import os
|
||||
import glob
|
||||
import shutil
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
from utils.common import get_yaml
|
||||
from utils.common import check_py_version
|
||||
|
||||
|
||||
DRAFTS_DIR = '_drafts'
|
||||
POSTS_DIR = ['_posts']
|
||||
|
||||
CATEGORIES_DIR = 'categories'
|
||||
CATEGORY_LAYOUT = 'category'
|
||||
|
||||
TAG_DIR = 'tags'
|
||||
TAG_LAYOUT = 'tag'
|
||||
|
||||
LEVEL = 3 # Tree level for current script file.
|
||||
|
||||
|
||||
def help():
|
||||
print("Usage: "
|
||||
" python pages_generator.py [Option]\n\n"
|
||||
"Options:\n"
|
||||
" -d, --drafts Enable drafts\n"
|
||||
" -v, --verbose Print verbose logs\n")
|
||||
|
||||
|
||||
def get_path(dir):
|
||||
path = os.path.abspath(__file__)
|
||||
count = LEVEL
|
||||
r_index = len(path)
|
||||
while r_index > 0:
|
||||
r_index -= 1
|
||||
if (path[r_index] == '/' or path[r_index] == '\\'):
|
||||
count -= 1
|
||||
if count == 0:
|
||||
return path[:r_index + 1] + dir
|
||||
|
||||
|
||||
def get_categories():
|
||||
all_categories = []
|
||||
yaml = YAML()
|
||||
|
||||
for dir in POSTS_DIR:
|
||||
path = get_path(dir)
|
||||
for file in glob.glob(os.path.join(path, '*.md')):
|
||||
meta = yaml.load(get_yaml(file)[0])
|
||||
|
||||
if 'category' in meta:
|
||||
if type(meta['category']) == list:
|
||||
err_msg = (
|
||||
"[Error] File {} 'category' type"
|
||||
" can not be LIST!").format(file)
|
||||
raise Exception(err_msg)
|
||||
else:
|
||||
if meta['category'] not in all_categories:
|
||||
all_categories.append(meta['category'])
|
||||
else:
|
||||
if 'categories' in meta:
|
||||
if type(meta['categories']) == str:
|
||||
error_msg = (
|
||||
"[Error] File {} 'categories' type"
|
||||
" can not be STR!").format(file)
|
||||
raise Exception(error_msg)
|
||||
|
||||
for ctg in meta['categories']:
|
||||
if ctg not in all_categories:
|
||||
all_categories.append(ctg)
|
||||
else:
|
||||
err_msg = (
|
||||
"[Error] File:{} at least "
|
||||
"have one category.").format(file)
|
||||
print(err_msg)
|
||||
|
||||
return all_categories
|
||||
|
||||
|
||||
def generate_category_pages(is_verbose):
|
||||
categories = get_categories()
|
||||
path = get_path(CATEGORIES_DIR)
|
||||
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
os.makedirs(path)
|
||||
|
||||
for category in categories:
|
||||
new_page = path + '/' + category.replace(' ', '-').lower() + '.html'
|
||||
with open(new_page, 'w+', encoding='utf-8') as html:
|
||||
html.write("---\n")
|
||||
html.write("layout: {}\n".format(CATEGORY_LAYOUT))
|
||||
html.write("title: {}\n".format(category))
|
||||
html.write("category: {}\n".format(category))
|
||||
html.write("---")
|
||||
|
||||
if is_verbose:
|
||||
print("[INFO] Created page: " + new_page)
|
||||
|
||||
change = subprocess.getoutput("git status categories -s")
|
||||
if change:
|
||||
print("[INFO] Succeed! {} category-pages created."
|
||||
.format(len(categories)))
|
||||
|
||||
|
||||
def get_all_tags():
|
||||
all_tags = []
|
||||
yaml = YAML()
|
||||
|
||||
for dir in POSTS_DIR:
|
||||
path = get_path(dir)
|
||||
for file in glob.glob(os.path.join(path, '*.md')):
|
||||
meta = yaml.load(get_yaml(file)[0])
|
||||
|
||||
if 'tags' in meta:
|
||||
for tag in meta['tags']:
|
||||
if tag not in all_tags:
|
||||
all_tags.append(tag)
|
||||
else:
|
||||
raise Exception("Didn't find 'tags' in \
|
||||
post '{}' !".format(file))
|
||||
|
||||
return all_tags
|
||||
|
||||
|
||||
def generate_tag_pages(is_verbose):
|
||||
all_tags = get_all_tags()
|
||||
tag_path = get_path(TAG_DIR)
|
||||
|
||||
if os.path.exists(tag_path):
|
||||
shutil.rmtree(tag_path)
|
||||
|
||||
os.makedirs(tag_path)
|
||||
|
||||
for tag in all_tags:
|
||||
tag_page = tag_path + '/' + tag.replace(' ', '-').lower() + '.html'
|
||||
with open(tag_page, 'w+', encoding='utf-8') as html:
|
||||
html.write("---\n")
|
||||
html.write("layout: {}\n".format(TAG_LAYOUT))
|
||||
html.write("title: {}\n".format(tag))
|
||||
html.write("tag: {}\n".format(tag))
|
||||
html.write("---")
|
||||
|
||||
if is_verbose:
|
||||
print("[INFO] Created page: " + tag_page)
|
||||
|
||||
change = subprocess.getoutput("git status tags -s")
|
||||
if change:
|
||||
print("[INFO] Succeed! {} tag-pages created.".format(len(all_tags)))
|
||||
|
||||
|
||||
def main():
|
||||
check_py_version()
|
||||
|
||||
is_verbose = False
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
for arg in sys.argv:
|
||||
if arg != sys.argv[0]:
|
||||
if arg == '-d' or arg == '--drafts':
|
||||
POSTS_DIR.insert(0, DRAFTS_DIR)
|
||||
elif arg == '-v' or arg == '--verbose':
|
||||
is_verbose = True
|
||||
else:
|
||||
help()
|
||||
return
|
||||
|
||||
generate_category_pages(is_verbose)
|
||||
generate_tag_pages(is_verbose)
|
||||
|
||||
|
||||
main()
|
121
_scripts/py/update_posts_lastmod.py
Executable file
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Update (or create if not existed) field 'seo.date_modified'
|
||||
in posts' Front Matter by their latest git commit date.
|
||||
|
||||
Dependencies:
|
||||
- git
|
||||
- ruamel.yaml
|
||||
|
||||
© 2018-2019 Cotes Chung
|
||||
Licensed under MIT
|
||||
"""
|
||||
|
||||
import sys
|
||||
import glob
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
from utils.common import get_yaml
|
||||
from utils.common import check_py_version
|
||||
|
||||
|
||||
POSTS_PATH = "_posts"
|
||||
|
||||
|
||||
def help():
|
||||
print("Usage: "
|
||||
" python update_posts_lastmod.py [option]\n"
|
||||
"Options:\n"
|
||||
" -v, --verbose Print verbose logs\n")
|
||||
|
||||
|
||||
def update_lastmod(verbose):
|
||||
count = 0
|
||||
yaml = YAML()
|
||||
|
||||
for post in glob.glob(os.path.join(POSTS_PATH, "*.md")):
|
||||
git_log_count = subprocess.getoutput(
|
||||
"git log --pretty=%ad \"{}\" | wc -l".format(post))
|
||||
|
||||
if git_log_count == "1":
|
||||
continue
|
||||
|
||||
git_lastmod = subprocess.getoutput(
|
||||
"git log -1 --pretty=%ad --date=iso \"{}\"".format(post))
|
||||
|
||||
if not git_lastmod:
|
||||
continue
|
||||
|
||||
lates_commit = subprocess.check_output(
|
||||
['git', 'log', '-1', '--pretty=%B', post]).decode('utf-8')
|
||||
|
||||
if "[Automation]" in lates_commit and "Lastmod" in lates_commit:
|
||||
continue
|
||||
|
||||
frontmatter, line_num = get_yaml(post)
|
||||
meta = yaml.load(frontmatter)
|
||||
|
||||
if 'seo' in meta:
|
||||
if ('date_modified' in meta['seo'] and
|
||||
meta['seo']['date_modified'] == git_lastmod):
|
||||
continue
|
||||
else:
|
||||
meta['seo']['date_modified'] = git_lastmod
|
||||
else:
|
||||
meta.insert(line_num, 'seo', dict(date_modified=git_lastmod))
|
||||
|
||||
output = 'new.md'
|
||||
if os.path.isfile(output):
|
||||
os.remove(output)
|
||||
|
||||
with open(output, 'w', encoding='utf-8') as new, \
|
||||
open(post, 'r', encoding='utf-8') as old:
|
||||
new.write("---\n")
|
||||
yaml.dump(meta, new)
|
||||
new.write("---\n")
|
||||
line_num += 2
|
||||
|
||||
lines = old.readlines()
|
||||
|
||||
for line in lines:
|
||||
if line_num > 0:
|
||||
line_num -= 1
|
||||
continue
|
||||
else:
|
||||
new.write(line)
|
||||
|
||||
shutil.move(output, post)
|
||||
count += 1
|
||||
|
||||
if verbose:
|
||||
print("[INFO] update 'lastmod' for:" + post)
|
||||
|
||||
if count > 0:
|
||||
print("[INFO] Success to update lastmod for {} post(s).".format(count))
|
||||
|
||||
|
||||
def main():
|
||||
check_py_version()
|
||||
|
||||
verbose = False
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
for arg in sys.argv:
|
||||
if arg == sys.argv[0]:
|
||||
continue
|
||||
else:
|
||||
if arg == '-v' or arg == '--verbose':
|
||||
verbose = True
|
||||
else:
|
||||
help()
|
||||
return
|
||||
|
||||
update_lastmod(verbose)
|
||||
|
||||
|
||||
main()
|
43
_scripts/py/utils/common.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Common functions to other scripts.
|
||||
|
||||
© 2018-2019 Cotes Chung
|
||||
MIT License
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def get_yaml(path):
|
||||
"""
|
||||
Return the Yaml block of a post and the linenumbers of it.
|
||||
"""
|
||||
end = False
|
||||
yaml = ""
|
||||
num = 0
|
||||
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
for line in f.readlines():
|
||||
if line.strip() == '---':
|
||||
if end:
|
||||
break
|
||||
else:
|
||||
end = True
|
||||
continue
|
||||
else:
|
||||
num += 1
|
||||
|
||||
yaml += line
|
||||
|
||||
return yaml, num
|
||||
|
||||
|
||||
def check_py_version():
|
||||
if not sys.version_info.major == 3 and sys.version_info.minor >= 5:
|
||||
print("WARNING: This script requires Python 3.5 or higher, "
|
||||
"however you are using Python {}.{}."
|
||||
.format(sys.version_info.major, sys.version_info.minor))
|
||||
sys.exit(1)
|
312
assets/css/_src/fonts.scss
Normal file
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* The field 'font-display' is added for Google-fonts.
|
||||
*
|
||||
* See https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700,900|Oswald|Lato
|
||||
*
|
||||
*/
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Lato Regular'), local('Lato-Regular'), url(https://fonts.gstatic.com/s/lato/v14/S6uyw4BMUTPHjxAwXjeu.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Lato Regular'), local('Lato-Regular'), url(https://fonts.gstatic.com/s/lato/v14/S6uyw4BMUTPHjx4wXg.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Oswald';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752HT8Ghe4.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Oswald';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752Fj8Ghe4.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Oswald';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752Fz8Ghe4.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Oswald';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Oswald Regular'), local('Oswald-Regular'), url(https://fonts.gstatic.com/s/oswald/v16/TK3iWkUHHAIjg752GT8G.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmhduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwkxduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmxduz8A.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlBduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmBduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmRduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdu.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmhduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwkxduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmxduz8A.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmhduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwkxduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmxduz8A.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlBduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmBduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwmRduz8A.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: local('Source Sans Pro Black'), local('SourceSansPro-Black'), url(https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdu.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
1518
assets/css/_src/main.scss
Normal file
157
assets/css/_src/syntax.scss
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*!
|
||||
* The syntax highlight.
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
.highlight .hll { background-color: #ffc; }
|
||||
.highlight .c { color: #999; } /* Comment */
|
||||
.highlight .err { color: #a00; background-color: #faa } /* Error */
|
||||
.highlight .k { color: #069; } /* Keyword */
|
||||
.highlight .o { color: #555 } /* Operator */
|
||||
.highlight .cm { color: #09f; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #099 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #999; } /* Comment.Single */
|
||||
.highlight .cs { color: #999; } /* Comment.Special */
|
||||
.highlight .gd { background-color: #fcc; border: 1px solid #c00 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #f00 } /* Generic.Error */
|
||||
.highlight .gh { color: #030; } /* Generic.Heading */
|
||||
.highlight .gi { background-color: #cfc; border: 1px solid #0c0 } /* Generic.Inserted */
|
||||
.highlight .go { color: #aaa } /* Generic.Output */
|
||||
.highlight .gp { color: #009; } /* Generic.Prompt */
|
||||
.highlight .gs { } /* Generic.Strong */
|
||||
.highlight .gu { color: #030; } /* Generic.Subheading */
|
||||
.highlight .gt { color: #9c6 } /* Generic.Traceback */
|
||||
.highlight .kc { color: #069; } /* Keyword.Constant */
|
||||
.highlight .kd { color: #069; } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #069; } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #069 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #069; } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #078; } /* Keyword.Type */
|
||||
.highlight .m { color: #f60 } /* Literal.Number */
|
||||
.highlight .s { color: #d44950 } /* Literal.String */
|
||||
.highlight .na { color: #4f9fcf } /* Name.Attribute */
|
||||
.highlight .nb { color: #366 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0a8; } /* Name.Class */
|
||||
.highlight .no { color: #360 } /* Name.Constant */
|
||||
.highlight .nd { color: #99f } /* Name.Decorator */
|
||||
.highlight .ni { color: #999; } /* Name.Entity */
|
||||
.highlight .ne { color: #c00; } /* Name.Exception */
|
||||
.highlight .nf { color: #c0f } /* Name.Function */
|
||||
.highlight .nl { color: #99f } /* Name.Label */
|
||||
.highlight .nn { color: #0cf; } /* Name.Namespace */
|
||||
.highlight .nt { color: #2f6f9f; } /* Name.Tag */
|
||||
.highlight .nv { color: #033 } /* Name.Variable */
|
||||
.highlight .ow { color: #000; } /* Operator.Word */
|
||||
.highlight .w { color: #bbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #f60 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #f60 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #f60 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #f60 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #c30 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #c30 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #c30; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #c30 } /* Literal.String.Double */
|
||||
.highlight .se { color: #c30; } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #c30 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #a00 } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #c30 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #3aa } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #c30 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #fc3 } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #366 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #033 } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #033 } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #033 } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #f60 } /* Literal.Number.Integer.Long */
|
||||
|
||||
/*-- Codes Snippet --*/
|
||||
|
||||
div.highlight,
|
||||
figure.highlight,
|
||||
.highlighter-rouge {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
overflow: auto;
|
||||
-moz-box-shadow: inset 0 0 2px #e9ecef;
|
||||
-webkit-box-shadow: inset 0 0 2px #e9ecef;
|
||||
box-shadow: inset 0 0 2px #e9ecef;
|
||||
}
|
||||
|
||||
.highlight .lineno {
|
||||
padding: .8rem .5rem;
|
||||
min-width: 2rem;
|
||||
text-align: right;
|
||||
color: rgba(140, 134, 126, 0.67);
|
||||
background: rgb(234, 236, 242);
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.highlight table {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.highlight td {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.highlight pre {
|
||||
margin-bottom: 0;
|
||||
font-size: .85rem;
|
||||
line-height: 1.4rem;
|
||||
word-wrap: normal; /* Fixed Safari overflow-x */
|
||||
}
|
||||
|
||||
.highlight table td pre {
|
||||
overflow: visible; /* Fixed iOS safari overflow-x */
|
||||
word-break: normal; /* Fixed iOS safari linenos code break */
|
||||
}
|
||||
|
||||
/* Override BS Inline-code style */
|
||||
.highlighter-rouge {
|
||||
color: black;
|
||||
margin-bottom: 1.2em;
|
||||
}
|
||||
|
||||
code {
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
code.highlighter-rouge {
|
||||
padding: 2px 4px;
|
||||
margin: 0 .3rem;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
td.rouge-code {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
/* code snippet radius */
|
||||
.highlighter-rouge,
|
||||
.highlight {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
||||
/* Hide line numbers for code snippets without specific language */
|
||||
div[class^='highlighter-rouge'] pre.lineno {
|
||||
display: none;
|
||||
}
|
||||
div[class^='highlighter-rouge'] td.rouge-code {
|
||||
padding: .8rem 1rem;
|
||||
}
|
9
assets/css/styles.scss
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
# Aggregation of CSS files.
|
||||
# © 2018-2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
||||
|
||||
@import "_src/main";
|
||||
@import "_src/syntax";
|
||||
@import "_src/fonts";
|
1
assets/data/proxy.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"proxyUrl":"https://your-gae.appspot.com/query?id=the_secrt_id"}
|
BIN
assets/img/favicons/android-icon-144x144.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/img/favicons/android-icon-192x192.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/img/favicons/android-icon-36x36.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
assets/img/favicons/android-icon-48x48.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/img/favicons/android-icon-72x72.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
assets/img/favicons/android-icon-96x96.png
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
assets/img/favicons/apple-icon-114x114.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/img/favicons/apple-icon-120x120.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/img/favicons/apple-icon-144x144.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/img/favicons/apple-icon-152x152.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/img/favicons/apple-icon-180x180.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/img/favicons/apple-icon-57x57.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
assets/img/favicons/apple-icon-60x60.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
assets/img/favicons/apple-icon-72x72.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
assets/img/favicons/apple-icon-76x76.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
assets/img/favicons/apple-icon-precomposed.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/img/favicons/apple-icon.png
Normal file
After Width: | Height: | Size: 21 KiB |
17
assets/img/favicons/browserconfig.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
# A part of the Favicons
|
||||
# © 2019 Cotes Chung
|
||||
# MIT License
|
||||
layout: compress
|
||||
---
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="{{ site.baseurl }}/assets/img/favicons/ms-icon-70x70.png" />
|
||||
<square150x150logo src="{{ site.baseurl }}/assets/img/favicons/ms-icon-150x150.png" />
|
||||
<square310x310logo src="{{ site.baseurl }}/assets/img/favicons/ms-icon-310x310.png" />
|
||||
<TileColor>#ffffff</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
assets/img/favicons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/img/favicons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
assets/img/favicons/favicon-96x96.png
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
assets/img/favicons/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
48
assets/img/favicons/manifest.json
Normal file
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
# A part of the Favicons
|
||||
# © 2019 Cotes Chung
|
||||
# MIT License
|
||||
layout: compress
|
||||
---
|
||||
|
||||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "{{ site.baseurl }}\/assets\/img\/favicons\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
BIN
assets/img/favicons/ms-icon-144x144.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/img/favicons/ms-icon-150x150.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/img/favicons/ms-icon-310x310.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
assets/img/favicons/ms-icon-70x70.png
Normal file
After Width: | Height: | Size: 6 KiB |
BIN
assets/img/sample/devices-mockup.png
Normal file
After Width: | Height: | Size: 222 KiB |
BIN
assets/img/sample/download-icons.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
assets/img/sample/mockup.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
assets/img/sample/profile.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/img/sample/upload-image.png
Normal file
After Width: | Height: | Size: 35 KiB |
18
assets/js/_src/_commons/back-to-top.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Reference: https://bootsnipp.com/snippets/featured/link-to-top-page
|
||||
*/
|
||||
$(window).scroll(function() {
|
||||
if ($(this).scrollTop() > 50
|
||||
&& $('#sidebar-trigger').css('display') == 'none') {
|
||||
$('#back-to-top').fadeIn();
|
||||
} else {
|
||||
$('#back-to-top').fadeOut();
|
||||
}
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('#back-to-top').click(function() {
|
||||
$('body,html').animate({scrollTop: 0}, 800);
|
||||
return false;
|
||||
});
|
||||
});
|
88
assets/js/_src/_commons/search-display.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* This script make #search-result-wrap switch to hidden or shown automatically.
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
|
||||
var offset = 0;
|
||||
|
||||
var btnCancel = $('#search-wrap + a');
|
||||
var btnSbTrigger = $('#sidebar-trigger');
|
||||
var btnSearchTrigger = $('#search-trigger');
|
||||
var btnCloseSearch = $('#search-wrap + a');
|
||||
var topbarTitle = $('#topbar-title');
|
||||
var searchWrap = $('#search-wrap');
|
||||
|
||||
/*--- Actions in small screens ---*/
|
||||
|
||||
btnSearchTrigger.click(function() {
|
||||
|
||||
offset = $(window).scrollTop();
|
||||
|
||||
$('body').addClass('no-scroll');
|
||||
// $('body').css('top', -offset + 'px');
|
||||
// $('html,body').addClass('input-focus');
|
||||
|
||||
btnSbTrigger.addClass('hidden');
|
||||
topbarTitle.addClass('hidden');
|
||||
btnSearchTrigger.addClass('hidden');
|
||||
|
||||
searchWrap.addClass('shown flex-grow-1');
|
||||
btnCancel.addClass('shown');
|
||||
|
||||
$('#main').addClass('hidden');
|
||||
$('#search-result-wrap').addClass('shown');
|
||||
$('#search-input').focus();
|
||||
|
||||
});
|
||||
|
||||
btnCancel.click(function() {
|
||||
|
||||
btnCancel.removeClass('shown');
|
||||
|
||||
$('#search-input').val('');
|
||||
$('#search-results').empty();
|
||||
|
||||
searchWrap.removeClass('shown flex-grow-1');
|
||||
|
||||
btnSbTrigger.removeClass('hidden');
|
||||
topbarTitle.removeClass('hidden');
|
||||
btnSearchTrigger.removeClass('hidden');
|
||||
|
||||
$('#main').removeClass('hidden');
|
||||
$('#search-result-wrap').removeClass('shown');
|
||||
|
||||
$('body').removeClass('no-scroll');
|
||||
// $('html,body').removeClass('input-focus');
|
||||
|
||||
$('html,body').scrollTop(offset);
|
||||
|
||||
});
|
||||
|
||||
/*--- Actions in large screens. ---*/
|
||||
|
||||
var isShown = false;
|
||||
|
||||
$('#search-input').on('input', function(){
|
||||
if (isShown == false) {
|
||||
offset = $(window).scrollTop();
|
||||
$('body,html').scrollTop(0);
|
||||
$('#search-result-wrap').addClass('shown');
|
||||
$('#main').addClass('hidden');
|
||||
isShown = true;
|
||||
}
|
||||
});
|
||||
|
||||
$('#search-input').on('keyup', function(e){
|
||||
var input = $('#search-input').val();
|
||||
if (e.keyCode == 8 && input == '' && btnCloseSearch.css('display') == 'none') {
|
||||
$('#main').removeClass('hidden');
|
||||
$('#search-result-wrap').removeClass('shown');
|
||||
$('body,html').scrollTop(offset);
|
||||
isShown = false;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
54
assets/js/_src/_commons/sidebar.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Expand or close the sidebar in mobile screens.
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
$(function(){
|
||||
|
||||
var isExpanded = false;
|
||||
|
||||
$("#sidebar-trigger").click(function() {
|
||||
if (isExpanded == false) {
|
||||
$("#sidebar").addClass("sidebar-expand");
|
||||
openModal();
|
||||
isExpanded = true;
|
||||
}
|
||||
});
|
||||
|
||||
$("#mask").click(function() {
|
||||
$("#sidebar").removeClass("sidebar-expand");
|
||||
closeModal();
|
||||
isExpanded = false;
|
||||
});
|
||||
|
||||
/**
|
||||
* ModalHelper helpers resolve the modal scrolling issue on mobile devices
|
||||
* https://github.com/twbs/bootstrap/issues/15852
|
||||
* requires document.scrollingElement polyfill https://github.com/yangg/scrolling-element
|
||||
*/
|
||||
var ModalHelper = (function(bodyCls) {
|
||||
var scrollTop;
|
||||
return {
|
||||
afterOpen: function() {
|
||||
scrollTop = document.scrollingElement.scrollTop;
|
||||
document.body.classList.add(bodyCls);
|
||||
document.body.style.top = -scrollTop + 'px';
|
||||
},
|
||||
beforeClose: function() {
|
||||
document.body.classList.remove(bodyCls);
|
||||
// scrollTop lost after set position:fixed, restore it back.
|
||||
document.scrollingElement.scrollTop = scrollTop;
|
||||
document.body.style.top = '';
|
||||
}
|
||||
};
|
||||
})('no-scroll');
|
||||
|
||||
function openModal() {
|
||||
ModalHelper.afterOpen();
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
ModalHelper.beforeClose();
|
||||
}
|
||||
|
||||
});
|
8
assets/js/_src/_commons/tooltip.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Initial Bootstrap Tooltip.
|
||||
* © 2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip({placement: "auto"});
|
||||
})
|
64
assets/js/_src/_commons/topbar-switch.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Hide Header on scroll down
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
var didScroll;
|
||||
var lastScrollTop = 0;
|
||||
var delta = 5;
|
||||
var topbarHeight = $('#topbar').outerHeight();
|
||||
|
||||
$(window).scroll(function(event) {
|
||||
if ($("#topbar-title").is(":hidden")) { // Not in small screens
|
||||
didScroll = true;
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
if (didScroll) {
|
||||
hasScrolled();
|
||||
didScroll = false;
|
||||
}
|
||||
}, 250);
|
||||
|
||||
function hasScrolled() {
|
||||
var st = $(this).scrollTop();
|
||||
|
||||
// Make sure they scroll more than delta
|
||||
if (Math.abs(lastScrollTop - st) <= delta)
|
||||
return;
|
||||
|
||||
if (st > lastScrollTop && st > topbarHeight) {
|
||||
// Scroll Down
|
||||
$('#topbar').removeClass('topbar-down').addClass('topbar-up');
|
||||
|
||||
if ( $('#toc-wrap').length > 0) {
|
||||
$('#toc-wrap').removeClass('topbar-down');
|
||||
}
|
||||
|
||||
if ( $('.panel-group').length > 0) {
|
||||
$('.panel-group').removeClass('topbar-down');
|
||||
}
|
||||
|
||||
if ($('#search-input').is(':focus')) {
|
||||
$('#search-input').blur(); // remove focus
|
||||
}
|
||||
|
||||
} else {
|
||||
// Scroll Up
|
||||
if (st + $(window).height() < $(document).height()) {
|
||||
$('#topbar').removeClass('topbar-up').addClass('topbar-down');
|
||||
if ( $('#toc-wrap').length > 0) {
|
||||
$('#toc-wrap').addClass('topbar-down');
|
||||
}
|
||||
if ( $('.panel-group').length > 0) {
|
||||
$('.panel-group').addClass('topbar-down');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastScrollTop = st;
|
||||
}
|
||||
});
|
44
assets/js/_src/_commons/topbar-title.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Topbar title auto change while scrolling in mobile screens.
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
$(function(){
|
||||
|
||||
var DEFAULT = $("#topbar-title").text().trim();
|
||||
var title = ($("div.post>h1").length > 0) ?
|
||||
$("div.post>h1").text().trim() : $("h1").text().trim();
|
||||
|
||||
if ($("#page-category").length || $("#page-tag").length) {
|
||||
/* The title in Category or Tag page will be '<title> <count_of_posts>' */
|
||||
if (/\s/.test(title)) {
|
||||
title = title.replace(/[0-9]/g, '').trim();
|
||||
}
|
||||
}
|
||||
|
||||
// Replace topbar title while scroll screens.
|
||||
$(window).scroll(function () {
|
||||
if ($("#post-list").length // in Home page
|
||||
|| $("div.post>h1").is(":hidden") // is tab pages
|
||||
|| $("#topbar-title").is(":hidden") // not mobile screens
|
||||
|| $("#sidebar.sidebar-expand").length) { // when the sidebar trigger is clicked
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($(this).scrollTop() >= 95) {
|
||||
if ($("#topbar-title").text() != title) {
|
||||
$("#topbar-title").text(title);
|
||||
}
|
||||
} else {
|
||||
if ($("#topbar-title").text() != DEFAULT) {
|
||||
$("#topbar-title").text(DEFAULT);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Click title remove hover effect.
|
||||
$('#topbar-title').click(function() {
|
||||
$('body,html').animate({scrollTop: 0}, 800);
|
||||
});
|
||||
|
||||
});
|
31
assets/js/_src/category-collapse.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Tab 'Categories' expand/close effect.
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
var child_prefix = "l_";
|
||||
var parent_prefix = "h_";
|
||||
|
||||
// close up Top
|
||||
$(".collapse").on("hide.bs.collapse", function() { // Bootstrap collapse events.
|
||||
var parent_id = parent_prefix + $(this).attr('id').substring(child_prefix.length);
|
||||
if (parent_id) {
|
||||
$("#" + parent_id + " .far.fa-folder-open").attr("class", "far fa-folder fa-fw");
|
||||
$("#" + parent_id + " i.fas.fa-angle-up").addClass("flip");
|
||||
$("#" + parent_id).removeClass("hide-border-bottom");
|
||||
}
|
||||
});
|
||||
|
||||
// expand Top Category
|
||||
$(".collapse").on("show.bs.collapse", function() {
|
||||
var parent_id = parent_prefix + $(this).attr('id').substring(child_prefix.length);
|
||||
if (parent_id) {
|
||||
$("#" + parent_id + " .far.fa-folder").attr("class", "far fa-folder-open fa-fw");
|
||||
$("#" + parent_id + " i.fas.fa-angle-up").removeClass("flip");
|
||||
$("#" + parent_id).addClass("hide-border-bottom");
|
||||
}
|
||||
});
|
||||
|
||||
});
|
111
assets/js/_src/pageviews.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* Count pageviews form GA or local cache file.
|
||||
*
|
||||
* Dependences:
|
||||
* - jQuery
|
||||
* - countUp.js(https://github.com/inorganik/countUp.js)
|
||||
*
|
||||
* © 2018-2019 Cotes Chung
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
function countUp(min, max, dest) {
|
||||
if (min < max) {
|
||||
var numAnim = new CountUp(dest, min, max);
|
||||
if (!numAnim.error) {
|
||||
numAnim.start();
|
||||
} else {
|
||||
console.error(numAnim.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function countPV(path, rows) {
|
||||
/* path permalink looks like: '/posts/post-title/' */
|
||||
var fileName = path.replace(/\/posts\//g, '').replace(/\//g, '.html'); /* e.g. post-title.html */
|
||||
var count = 0;
|
||||
|
||||
var _v2_url = path.replace(/posts\//g, ''); /* the v2.0+ blog permalink: "/post-title/" */
|
||||
|
||||
for (var i = 0; i < rows.length; ++i) {
|
||||
var gaPath = rows[i][0];
|
||||
if (gaPath == path ||
|
||||
gaPath == _v2_url ||
|
||||
gaPath.concat('/') == _v2_url ||
|
||||
gaPath.slice(gaPath.lastIndexOf('/') + 1) === fileName) { // old permalink record
|
||||
count += parseInt(rows[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
function displayPageviews(rows, hasInit) {
|
||||
if (rows === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($("#post-list").length > 0) { // the Home page
|
||||
$(".post-preview").each(function() {
|
||||
var path = $(this).children("h1").children("a").attr("href");
|
||||
var count = countPV(path, rows);
|
||||
count = (count == 0 ? 1 : count);
|
||||
|
||||
if (!hasInit) {
|
||||
$(this).find('.pageviews').text(count);
|
||||
} else {
|
||||
var initCount = parseInt($(this).find('.pageviews').text());
|
||||
if (count > initCount) {
|
||||
countUp(initCount, count, $(this).find('.pageviews').attr('id'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else if ($(".post").length > 0) { // the post
|
||||
var path = window.location.pathname;
|
||||
var count = countPV(path, rows);
|
||||
count = (count == 0 ? 1 : count);
|
||||
|
||||
if (!hasInit) {
|
||||
$('#pv').text(count);
|
||||
} else {
|
||||
var initCount = parseInt($('#pv').text());
|
||||
if (count > initCount) {
|
||||
countUp(initCount, count, 'pv');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$(function() {
|
||||
// load pageview if this page has .pageviews
|
||||
if ($('.pageviews').length > 0) {
|
||||
var hasInit = false;
|
||||
|
||||
// Get data from daily cache.
|
||||
$.getJSON('/assets/data/pageviews.json', function(data) {
|
||||
displayPageviews(data.rows, hasInit);
|
||||
hasInit = true;
|
||||
});
|
||||
|
||||
$.getJSON('/assets/data/proxy.json', function(data) {
|
||||
$.ajax({
|
||||
url: data.proxyUrl,
|
||||
dataType: 'jsonp',
|
||||
timeout: 2000,
|
||||
success: function(data) {
|
||||
displayPageviews(data.rows, hasInit);
|
||||
},
|
||||
error: function(xhr, status, err) {
|
||||
console.log("Failed to load pageviews from proxy server.");
|
||||
xhr.abort();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
} // endif
|
||||
|
||||
});
|
77
assets/js/_src/timeago.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Caculate the Timeago
|
||||
*
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
|
||||
function timeago(date, isLastmod) {
|
||||
var now = new Date();
|
||||
var past = new Date(date);
|
||||
var seconds = Math.floor((now - past) / 1000);
|
||||
|
||||
var year = Math.floor(seconds / 31536000);
|
||||
if (year >= 1) {
|
||||
return year + " year" + (year > 1 ? "s" : "") + " ago";
|
||||
}
|
||||
|
||||
var month = Math.floor(seconds / 2592000);
|
||||
if (month >= 1) {
|
||||
return month + " month" + (month > 1 ? "s" : "") + " ago";
|
||||
}
|
||||
|
||||
var week = Math.floor(seconds / 604800);
|
||||
if (week >= 1) {
|
||||
return week + " week" + (week > 1 ? "s" : "") + " ago";
|
||||
}
|
||||
|
||||
var day = Math.floor(seconds / 86400);
|
||||
if (day >= 1) {
|
||||
return day + " day" + (day > 1 ? "s" : "") + " ago";
|
||||
}
|
||||
|
||||
var hour = Math.floor(seconds / 3600);
|
||||
if (hour >= 1) {
|
||||
return hour + " hour" + (hour > 1 ? "s" : "") + " ago";
|
||||
}
|
||||
|
||||
var minute = Math.floor(seconds / 60);
|
||||
if (minute >= 1) {
|
||||
return minute + " minute" + (minute > 1 ? "s" : "") + " ago";
|
||||
}
|
||||
|
||||
return (isLastmod? "just" : "Just") + " now";
|
||||
}
|
||||
|
||||
|
||||
function updateTimeago() {
|
||||
$(".timeago").each(function() {
|
||||
if ($(this).children("i").length > 0) {
|
||||
var isLastmod = $(this).hasClass('lastmod');
|
||||
var node = $(this).children("i");
|
||||
var date = node.text(); /* ISO Dates: 'YYYY-MM-DDTHH:MM:SSZ' */
|
||||
$(this).text(timeago(date, isLastmod));
|
||||
$(this).append(node);
|
||||
}
|
||||
});
|
||||
|
||||
if (vote == 0 && intervalId != undefined) {
|
||||
clearInterval(intervalId); /* stop interval */
|
||||
}
|
||||
return vote;
|
||||
}
|
||||
|
||||
|
||||
var vote = $(".timeago").length;
|
||||
if (vote == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateTimeago() > 0) { /* run immediately */
|
||||
vote = $(".timeago").length; /* resume */
|
||||
var intervalId = setInterval(updateTimeago, 60000); /* loop every minutes */
|
||||
}
|
||||
|
||||
});
|
1
assets/js/dist/_commons/back-to-top.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(window).scroll(function(){if($(this).scrollTop()>50&&$("#sidebar-trigger").css("display")=="none"){$("#back-to-top").fadeIn()}else{$("#back-to-top").fadeOut()}});$(function(){$("#back-to-top").click(function(){$("body,html").animate({scrollTop:0},800);return false})});
|
1
assets/js/dist/_commons/search-display.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){var g=0;var e=$("#search-wrap + a");var c=$("#sidebar-trigger");var h=$("#search-trigger");var d=$("#search-wrap + a");var a=$("#topbar-title");var b=$("#search-wrap");h.click(function(){g=$(window).scrollTop();$("body").addClass("no-scroll");c.addClass("hidden");a.addClass("hidden");h.addClass("hidden");b.addClass("shown flex-grow-1");e.addClass("shown");$("#main").addClass("hidden");$("#search-result-wrap").addClass("shown");$("#search-input").focus()});e.click(function(){e.removeClass("shown");$("#search-input").val("");$("#search-results").empty();b.removeClass("shown flex-grow-1");c.removeClass("hidden");a.removeClass("hidden");h.removeClass("hidden");$("#main").removeClass("hidden");$("#search-result-wrap").removeClass("shown");$("body").removeClass("no-scroll");$("html,body").scrollTop(g)});var f=false;$("#search-input").on("input",function(){if(f==false){g=$(window).scrollTop();$("body,html").scrollTop(0);$("#search-result-wrap").addClass("shown");$("#main").addClass("hidden");f=true}});$("#search-input").on("keyup",function(j){var i=$("#search-input").val();if(j.keyCode==8&&i==""&&d.css("display")=="none"){$("#main").removeClass("hidden");$("#search-result-wrap").removeClass("shown");$("body,html").scrollTop(g);f=false}})});
|
1
assets/js/dist/_commons/sidebar.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){var d=false;$("#sidebar-trigger").click(function(){if(d==false){$("#sidebar").addClass("sidebar-expand");b();d=true}});$("#mask").click(function(){$("#sidebar").removeClass("sidebar-expand");c();d=false});var a=(function(e){var f;return{afterOpen:function(){f=document.scrollingElement.scrollTop;document.body.classList.add(e);document.body.style.top=-f+"px"},beforeClose:function(){document.body.classList.remove(e);document.scrollingElement.scrollTop=f;document.body.style.top=""}}})("no-scroll");function b(){a.afterOpen()}function c(){a.beforeClose()}});
|
1
assets/js/dist/_commons/tooltip.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){$('[data-toggle="tooltip"]').tooltip({placement:"auto"})});
|
1
assets/js/dist/_commons/topbar-switch.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){var d;var c=0;var e=5;var b=$("#topbar").outerHeight();$(window).scroll(function(f){if($("#topbar-title").is(":hidden")){d=true}});setInterval(function(){if(d){a();d=false}},250);function a(){var f=$(this).scrollTop();if(Math.abs(c-f)<=e){return}if(f>c&&f>b){$("#topbar").removeClass("topbar-down").addClass("topbar-up");if($("#toc-wrap").length>0){$("#toc-wrap").removeClass("topbar-down")}if($(".panel-group").length>0){$(".panel-group").removeClass("topbar-down")}if($("#search-input").is(":focus")){$("#search-input").blur()}}else{if(f+$(window).height()<$(document).height()){$("#topbar").removeClass("topbar-up").addClass("topbar-down");if($("#toc-wrap").length>0){$("#toc-wrap").addClass("topbar-down")}if($(".panel-group").length>0){$(".panel-group").addClass("topbar-down")}}}c=f}});
|
1
assets/js/dist/_commons/topbar-title.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){var a=$("#topbar-title").text().trim();var b=($("div.post>h1").length>0)?$("div.post>h1").text().trim():$("h1").text().trim();if($("#page-category").length||$("#page-tag").length){if(/\s/.test(b)){b=b.replace(/[0-9]/g,"").trim()}}$(window).scroll(function(){if($("#post-list").length||$("div.post>h1").is(":hidden")||$("#topbar-title").is(":hidden")||$("#sidebar.sidebar-expand").length){return false}if($(this).scrollTop()>=95){if($("#topbar-title").text()!=b){$("#topbar-title").text(b)}}else{if($("#topbar-title").text()!=a){$("#topbar-title").text(a)}}});$("#topbar-title").click(function(){$("body,html").animate({scrollTop:0},800)})});
|
1
assets/js/dist/category-collapse.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){var b="l_";var a="h_";$(".collapse").on("hide.bs.collapse",function(){var c=a+$(this).attr("id").substring(b.length);if(c){$("#"+c+" .far.fa-folder-open").attr("class","far fa-folder fa-fw");$("#"+c+" i.fas.fa-angle-up").addClass("flip");$("#"+c).removeClass("hide-border-bottom")}});$(".collapse").on("show.bs.collapse",function(){var c=a+$(this).attr("id").substring(b.length);if(c){$("#"+c+" .far.fa-folder").attr("class","far fa-folder-open fa-fw");$("#"+c+" i.fas.fa-angle-up").removeClass("flip");$("#"+c).addClass("hide-border-bottom")}})});
|
12
assets/js/dist/commons.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
# Aggregation of common JS.
|
||||
# © 2018-2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
||||
|
||||
{% include_relative _commons/back-to-top.min.js %}
|
||||
{% include_relative _commons/search-display.min.js %}
|
||||
{% include_relative _commons/sidebar.min.js %}
|
||||
{% include_relative _commons/topbar-switch.min.js %}
|
||||
{% include_relative _commons/topbar-title.min.js %}
|
||||
{% include_relative _commons/tooltip.min.js %}
|
1
assets/js/dist/countUp.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
var CountUp=function(h,b,i,e,g,n){var m=this;m.version=function(){return"1.9.3"};m.options={useEasing:true,useGrouping:true,separator:",",decimal:".",easingFn:c,formattingFn:d,prefix:"",suffix:"",numerals:[]};if(n&&typeof n==="object"){for(var k in m.options){if(n.hasOwnProperty(k)&&n[k]!==null){m.options[k]=n[k]}}}if(m.options.separator===""){m.options.useGrouping=false}else{m.options.separator=""+m.options.separator}var a=0;var l=["webkit","moz","ms","o"];for(var j=0;j<l.length&&!window.requestAnimationFrame;++j){window.requestAnimationFrame=window[l[j]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[l[j]+"CancelAnimationFrame"]||window[l[j]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(s,p){var o=new Date().getTime();var q=Math.max(0,16-(o-a));var r=window.setTimeout(function(){s(o+q)},q);a=o+q;return r}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(o){clearTimeout(o)}}function d(t){var v=(t<0),p,s,r,q,u,o;t=Math.abs(t).toFixed(m.decimals);t+="";p=t.split(".");s=p[0];r=p.length>1?m.options.decimal+p[1]:"";if(m.options.useGrouping){q="";for(u=0,o=s.length;u<o;++u){if(u!==0&&((u%3)===0)){q=m.options.separator+q}q=s[o-u-1]+q}s=q}if(m.options.numerals.length){s=s.replace(/[0-9]/g,function(x){return m.options.numerals[+x]});r=r.replace(/[0-9]/g,function(x){return m.options.numerals[+x]})}return(v?"-":"")+m.options.prefix+s+r+m.options.suffix}function c(p,o,r,q){return r*(-Math.pow(2,-10*p/q)+1)*1024/1023+o}function f(o){return(typeof o==="number"&&!isNaN(o))}m.initialize=function(){if(m.initialized){return true}m.error="";m.d=(typeof h==="string")?document.getElementById(h):h;if(!m.d){m.error="[CountUp] target is null or undefined";return false}m.startVal=Number(b);m.endVal=Number(i);if(f(m.startVal)&&f(m.endVal)){m.decimals=Math.max(0,e||0);m.dec=Math.pow(10,m.decimals);m.duration=Number(g)*1000||2000;m.countDown=(m.startVal>m.endVal);m.frameVal=m.startVal;m.initialized=true;return true}else{m.error="[CountUp] startVal ("+b+") or endVal ("+i+") is not a number";return false}};m.printValue=function(p){var o=m.options.formattingFn(p);if(m.d.tagName==="INPUT"){this.d.value=o}else{if(m.d.tagName==="text"||m.d.tagName==="tspan"){this.d.textContent=o}else{this.d.innerHTML=o}}};m.count=function(p){if(!m.startTime){m.startTime=p}m.timestamp=p;var o=p-m.startTime;m.remaining=m.duration-o;if(m.options.useEasing){if(m.countDown){m.frameVal=m.startVal-m.options.easingFn(o,0,m.startVal-m.endVal,m.duration)}else{m.frameVal=m.options.easingFn(o,m.startVal,m.endVal-m.startVal,m.duration)}}else{if(m.countDown){m.frameVal=m.startVal-((m.startVal-m.endVal)*(o/m.duration))}else{m.frameVal=m.startVal+(m.endVal-m.startVal)*(o/m.duration)}}if(m.countDown){m.frameVal=(m.frameVal<m.endVal)?m.endVal:m.frameVal}else{m.frameVal=(m.frameVal>m.endVal)?m.endVal:m.frameVal}m.frameVal=Math.round(m.frameVal*m.dec)/m.dec;m.printValue(m.frameVal);if(o<m.duration){m.rAF=requestAnimationFrame(m.count)}else{if(m.callback){m.callback()}}};m.start=function(o){if(!m.initialize()){return}m.callback=o;m.rAF=requestAnimationFrame(m.count)};m.pauseResume=function(){if(!m.paused){m.paused=true;cancelAnimationFrame(m.rAF)}else{m.paused=false;delete m.startTime;m.duration=m.remaining;m.startVal=m.frameVal;requestAnimationFrame(m.count)}};m.reset=function(){m.paused=false;delete m.startTime;m.initialized=false;if(m.initialize()){cancelAnimationFrame(m.rAF);m.printValue(m.startVal)}};m.update=function(o){if(!m.initialize()){return}o=Number(o);if(!f(o)){m.error="[CountUp] update() - new endVal is not a number: "+o;return}m.error="";if(o===m.frameVal){return}cancelAnimationFrame(m.rAF);m.paused=false;delete m.startTime;m.startVal=m.frameVal;m.endVal=o;m.countDown=(m.startVal>m.endVal);m.rAF=requestAnimationFrame(m.count)};if(m.initialize()){m.printValue(m.startVal)}};
|
1
assets/js/dist/pageviews.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
function countUp(c,a,b){if(c<a){var d=new CountUp(b,c,a);if(!d.error){d.start()}else{console.error(d.error)}}}function countPV(f,e){var g=f.replace(/\/posts\//g,"").replace(/\//g,".html");var d=0;var c=f.replace(/posts\//g,"");for(var b=0;b<e.length;++b){var a=e[b][0];if(a==f||a==c||a.concat("/")==c||a.slice(a.lastIndexOf("/")+1)===g){d+=parseInt(e[b][1])}}return d}function displayPageviews(d,b){if(d===undefined){return}if($("#post-list").length>0){$(".post-preview").each(function(){var h=$(this).children("h1").children("a").attr("href");var g=countPV(h,d);g=(g==0?1:g);if(!b){$(this).find(".pageviews").text(g)}else{var f=parseInt($(this).find(".pageviews").text());if(g>f){countUp(f,g,$(this).find(".pageviews").attr("id"))}}})}else{if($(".post").length>0){var e=window.location.pathname;var c=countPV(e,d);c=(c==0?1:c);if(!b){$("#pv").text(c)}else{var a=parseInt($("#pv").text());if(c>a){countUp(a,c,"pv")}}}}}$(function(){if($(".pageviews").length>0){var a=false;$.getJSON("/assets/data/pageviews.json",function(b){displayPageviews(b.rows,a);a=true});$.getJSON("/assets/data/proxy.json",function(b){$.ajax({url:b.proxyUrl,dataType:"jsonp",timeout:2000,success:function(c){displayPageviews(c.rows,a)},error:function(e,c,d){console.log("Failed to load pageviews from proxy server.");e.abort();return}})})}});
|
1
assets/js/dist/timeago.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
$(function(){function d(h,g){var f=new Date();var o=new Date(h);var n=Math.floor((f-o)/1000);var l=Math.floor(n/31536000);if(l>=1){return l+" year"+(l>1?"s":"")+" ago"}var k=Math.floor(n/2592000);if(k>=1){return k+" month"+(k>1?"s":"")+" ago"}var e=Math.floor(n/604800);if(e>=1){return e+" week"+(e>1?"s":"")+" ago"}var m=Math.floor(n/86400);if(m>=1){return m+" day"+(m>1?"s":"")+" ago"}var j=Math.floor(n/3600);if(j>=1){return j+" hour"+(j>1?"s":"")+" ago"}var i=Math.floor(n/60);if(i>=1){return i+" minute"+(i>1?"s":"")+" ago"}return(g?"just":"Just")+" now"}function c(){$(".timeago").each(function(){if($(this).children("i").length>0){var g=$(this).hasClass("lastmod");var f=$(this).children("i");var e=f.text();$(this).text(d(e,g));$(this).append(f)}});if(a==0&&b!=undefined){clearInterval(b)}return a}var a=$(".timeago").length;if(a==0){return}if(c()>0){a=$(".timeago").length;var b=setInterval(c,60000)}});
|
4
assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/*!
|
||||
* Bootstrap Table of Contents v1.0.1 (http://afeld.github.io/bootstrap-toc/)
|
||||
* Copyright 2015 Aidan Feldman
|
||||
* Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */nav[data-toggle=toc] .nav>li>a{display:block;padding:4px 20px;font-size:13px;font-weight:500;color:#767676}nav[data-toggle=toc] .nav>li>a:focus,nav[data-toggle=toc] .nav>li>a:hover{padding-left:19px;color:#563d7c;text-decoration:none;background-color:transparent;border-left:1px solid #563d7c}nav[data-toggle=toc] .nav-link.active,nav[data-toggle=toc] .nav-link.active:focus,nav[data-toggle=toc] .nav-link.active:hover{padding-left:18px;font-weight:700;color:#563d7c;background-color:transparent;border-left:2px solid #563d7c}nav[data-toggle=toc] .nav-link+ul{display:none;padding-bottom:10px}nav[data-toggle=toc] .nav .nav>li>a{padding-top:1px;padding-bottom:1px;padding-left:30px;font-size:12px;font-weight:400}nav[data-toggle=toc] .nav .nav>li>a:focus,nav[data-toggle=toc] .nav .nav>li>a:hover{padding-left:29px}nav[data-toggle=toc] .nav .nav>li>.active,nav[data-toggle=toc] .nav .nav>li>.active:focus,nav[data-toggle=toc] .nav .nav>li>.active:hover{padding-left:28px;font-weight:500}nav[data-toggle=toc] .nav-link.active+ul{display:block}
|
5
assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Table of Contents v1.0.1 (http://afeld.github.io/bootstrap-toc/)
|
||||
* Copyright 2015 Aidan Feldman
|
||||
* Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */
|
||||
!function(a){"use strict";window.Toc={helpers:{findOrFilter:function(e,t){var n=e.find(t);return e.filter(t).add(n).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(e){return a(e).text().trim().replace(/\'/gi,"").replace(/[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,64).replace(/^-+|-+$/gm,"").toLowerCase()||e.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),n=0;;n++){var r=t;if(0<n&&(r+="-"+n),!document.getElementById(r))return r}},generateAnchor:function(e){if(e.id)return e.id;var t=this.generateUniqueId(e);return e.id=t},createNavList:function(){return a('<ul class="nav navbar-nav"></ul>')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(e,t){var n=a('<a class="nav-link"></a>');n.attr("href","#"+e),n.text(t);var r=a("<li></li>");return r.append(n),r},generateNavItem:function(e){var t=this.generateAnchor(e),n=a(e),r=n.data("toc-text")||n.text();return this.generateNavEl(t,r)},getTopLevel:function(e){for(var t=1;t<=6;t++){if(1<this.findOrFilter(e,"h"+t).length)return t}return 1},getHeadings:function(e,t){var n="h"+t,r="h"+(t+1);return this.findOrFilter(e,n+","+r)},getNavLevel:function(e){return parseInt(e.tagName.charAt(1),10)},populateNav:function(r,a,e){var i,s=r,c=this;e.each(function(e,t){var n=c.generateNavItem(t);c.getNavLevel(t)===a?s=r:i&&s===r&&(s=c.createChildNavList(i)),s.append(n),i=n})},parseOps:function(e){var t;return(t=e.jquery?{$nav:e}:e).$scope=t.$scope||a(document.body),t}},init:function(e){(e=this.helpers.parseOps(e)).$nav.attr("data-toggle","toc");var t=this.helpers.createChildNavList(e.$nav),n=this.helpers.getTopLevel(e.$scope),r=this.helpers.getHeadings(e.$scope,n);this.helpers.populateNav(t,n,r)}},a(function(){a('nav[data-toggle="toc"]').each(function(e,t){var n=a(t);Toc.init(n)})})}(jQuery);
|
2
assets/lib/jquery-3.4.1.min.js
vendored
Normal file
8
assets/lib/jquery.disqusloader.min.js
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
disqusLoader.js v1.0
|
||||
A JavaScript plugin for lazy-loading Disqus comments widget.
|
||||
-
|
||||
By Osvaldas Valutis, www.osvaldas.info
|
||||
Available for use under the MIT License
|
||||
*/
|
||||
(function(e,g,h,d){var a=e(g),k=function(o,n){var q,p;return function(){var t=this,s=arguments,r=+new Date;q&&r<q+o?(clearTimeout(p),p=setTimeout(function(){q=r,n.apply(t,s)},o)):(q=r,n.apply(t,s))}},m=false,j=false,i=false,c=false,f="unloaded",b=e(),l=function(){if(!b.length||b.data("disqusLoaderStatus")=="loaded"){return true}var n=a.scrollTop();if(b.offset().top-n>a.height()*j||n-b.offset().top-b.outerHeight()-(a.height()*j)>0){return true}e("#disqus_thread").removeAttr("id");b.attr("id","disqus_thread").data("disqusLoaderStatus","loaded");if(f=="loaded"){DISQUS.reset({reload:true,config:i})}else{g.disqus_config=i;if(f=="unloaded"){f="loading";e.ajax({url:c,async:true,cache:true,dataType:"script",success:function(){f="loaded"}})}}};a.on("scroll resize",k(m,l));e.disqusLoader=function(o,n){n=e.extend({},{laziness:1,throttle:250,scriptUrl:false,disqusConfig:false},n);j=n.laziness+1;m=n.throttle;i=n.disqusConfig;c=c===false?n.scriptUrl:c;b=(typeof o=="string"?e(o):o).eq(0);b.data("disqusLoaderStatus","unloaded");l()}})(jQuery,window,document);
|
6
assets/lib/simple-jekyll-search-1.7.1.min.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* Simple-Jekyll-Search v1.7.1 (https://github.com/christian-fei/Simple-Jekyll-Search)
|
||||
* Copyright 2015-2018, Christian Fei
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
!function(){"use strict";var f={load:function(t,e){var n=window.XMLHttpRequest?new window.XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");n.open("GET",t,!0),n.onreadystatechange=(r=n,i=e,function(){if(4===r.readyState&&200===r.status)try{i(null,JSON.parse(r.responseText))}catch(t){i(t,null)}}),n.send();var r,i}};var n=function(t,e){var n=e.length,r=t.length;if(n<r)return!1;if(r===n)return t===e;t:for(var i=0,o=0;i<r;i++){for(var u=t.charCodeAt(i);o<n;)if(e.charCodeAt(o++)===u)continue t;return!1}return!0},e=new function(){this.matches=function(t,e){return n(e.toLowerCase(),t.toLowerCase())}};var r=new function(){this.matches=function(e,t){return!!e&&(e=e.trim().toLowerCase(),0<(t=t.toLowerCase()).split(" ").filter(function(t){return 0<=e.indexOf(t)}).length)}};var l={put:function(t){if(s(t))return c(t);if(e=t,Boolean(e)&&"[object Array]"===Object.prototype.toString.call(e))return function(t){var e=[];a();for(var n=0,r=t.length;n<r;n++)s(t[n])&&e.push(c(t[n]));return e}(t);var e;return undefined},clear:a,search:function(t){if(!t)return[];return function(t,e,n,r){for(var i=[],o=0;o<t.length&&i.length<r.limit;o++){var u=p(t[o],e,n,r);u&&i.push(u)}return i}(o,t,u.searchStrategy,u).sort(u.sort)},setOptions:function(t){(u=t||{}).fuzzy=t.fuzzy||!1,u.limit=t.limit||10,u.searchStrategy=t.fuzzy?e:r,u.sort=t.sort||i}};function i(){return 0}var o=[],u={};function a(){return o.length=0,o}function s(t){return Boolean(t)&&"[object Object]"===Object.prototype.toString.call(t)}function c(t){return o.push(t),o}function p(t,e,n,r){for(var i in t)if(!d(t[i],r.exclude)&&n.matches(t[i],e))return t}function d(t,e){for(var n=!1,r=0,i=(e=e||[]).length;r<i;r++){var o=e[r];!n&&new RegExp(t).test(o)&&(n=!0)}return n}u.fuzzy=!1,u.limit=10,u.searchStrategy=u.fuzzy?e:r,u.sort=i;var h={compile:function(r){return v.template.replace(v.pattern,function(t,e){var n=v.middleware(e,r[e],v.template);return void 0!==n?n:r[e]||t})},setOptions:function(t){v.pattern=t.pattern||v.pattern,v.template=t.template||v.template,"function"==typeof t.middleware&&(v.middleware=t.middleware)}},v={};v.pattern=/\{(.*?)\}/g,v.template="",v.middleware=function(){};var m={merge:function(t,e){var n={};for(var r in t)n[r]=t[r],"undefined"!=typeof e[r]&&(n[r]=e[r]);return n},isJSON:function(t){try{return!!(t instanceof Object&&JSON.parse(JSON.stringify(t)))}catch(e){return!1}}};!function(e){var r={searchInput:null,resultsContainer:null,json:[],success:Function.prototype,searchResultTemplate:'<li><a href="{url}" title="{desc}">{title}</a></li>',templateMiddleware:Function.prototype,sortMiddleware:function(){return 0},noResultsText:"No results found",limit:10,fuzzy:!1,exclude:[]},i=["searchInput","resultsContainer","json"],o=function t(e){if(n=e,!(n&&"undefined"!=typeof n.required&&n.required instanceof Array))throw new Error("-- OptionsValidator: required options missing");var n;if(!(this instanceof t))return new t(e);var r=e.required;this.getRequiredOptions=function(){return r},this.validate=function(e){var n=[];return r.forEach(function(t){"undefined"==typeof e[t]&&n.push(t)}),n}}({required:i});function u(t){r.success(t),l.put(t),r.searchInput.addEventListener("keyup",function(t){var e;e=t.which,-1===[13,16,20,37,38,39,40,91].indexOf(e)&&(n(),s(t.target.value))})}function n(){r.resultsContainer.innerHTML=""}function a(t){r.resultsContainer.innerHTML+=t}function s(t){var e;(e=t)&&0<e.length&&(n(),function(t){var e=t.length;if(0===e)return a(r.noResultsText);for(var n=0;n<e;n++)a(h.compile(t[n]))}(l.search(t)))}function c(t){throw new Error("SimpleJekyllSearch --- "+t)}e.SimpleJekyllSearch=function(t){var n;return 0<o.validate(t).length&&c("You must specify the following required options: "+i),r=m.merge(r,t),h.setOptions({template:r.searchResultTemplate,middleware:r.templateMiddleware}),l.setOptions({fuzzy:r.fuzzy,limit:r.limit,sort:r.sortMiddleware}),m.isJSON(r.json)?u(r.json):(n=r.json,f.load(n,function(t,e){t&&c("failed to get JSON ("+n+")"),u(e)})),{search:s}}}(window)}();
|
106
build.sh
Executable file
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Build jekyll site and store site files in ./_site
|
||||
# © 2019 Cotes Chung
|
||||
# Published under MIT License
|
||||
|
||||
|
||||
help() {
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo " bash build.sh [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -b, --baseurl <URL> The site relative url that start with slash, e.g. '/project'"
|
||||
echo " -h, --help Print the help information"
|
||||
echo " -d, --destination <DIR> Destination directory (defaults to ./_site)"
|
||||
}
|
||||
|
||||
|
||||
init() {
|
||||
set -eu
|
||||
|
||||
if [[ -d .container ]]; then
|
||||
rm -rf .container
|
||||
fi
|
||||
|
||||
if [[ -d _site ]]; then
|
||||
rm -rf _site
|
||||
fi
|
||||
|
||||
if [[ -d ../.chirpy-cache ]]; then
|
||||
rm -rf ../.chirpy-cache
|
||||
fi
|
||||
|
||||
mkdir ../.chirpy-cache
|
||||
cp -r * ../.chirpy-cache
|
||||
cp -r .git ../.chirpy-cache
|
||||
|
||||
mv ../.chirpy-cache .container
|
||||
}
|
||||
|
||||
|
||||
check_unset() {
|
||||
if [[ -z ${1:+unset} ]]
|
||||
then
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
CMD="JEKYLL_ENV=production bundle exec jekyll b"
|
||||
DEST=`realpath "./_site"`
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
opt="$1"
|
||||
case $opt in
|
||||
-b|--baseurl)
|
||||
check_unset $2
|
||||
|
||||
if [[ $2 == \/* ]]
|
||||
then
|
||||
CMD+=" -b $2"
|
||||
else
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-d|--destination)
|
||||
check_unset $2
|
||||
if [[ -d $2 ]]; then
|
||||
rm -rf $2
|
||||
fi
|
||||
DEST=$2
|
||||
shift;
|
||||
shift;
|
||||
;;
|
||||
-h|--help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
*) # unknown option
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
init
|
||||
|
||||
cd .container
|
||||
|
||||
echo "$ cd $(pwd)"
|
||||
python _scripts/py/init_all.py
|
||||
|
||||
CMD+=" -d $DEST"
|
||||
echo "\$ $CMD"
|
||||
eval $CMD
|
||||
|
||||
echo "$(date) - Build success, the Site files placed in _site."
|
||||
|
||||
cd .. && rm -rf .container
|
58
feed.xml
Normal file
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
layout: compress
|
||||
# Atom Feed, reference: https://validator.w3.org/feed/docs/atom.html
|
||||
# © 2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
||||
|
||||
{% capture source %}
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<id>{{ site.url }}</id>
|
||||
<title>{{ site.title }}</title>
|
||||
<subtitle>{{ site.description }}</subtitle>
|
||||
<updated>{{ site.time | date_to_xmlschema }}</updated>
|
||||
<author>
|
||||
<name>{{ site.author }}</name>
|
||||
<uri>{{ site.url }}</uri>
|
||||
</author>
|
||||
<link href="/feed.xml" rel="self" type="application/atom+xml" />
|
||||
<link href="{{ site.url }}" rel="alternate" type="text/html" />
|
||||
<generator uri="https://jekyllrb.com/" version="{{ jekyll.version }}">Jekyll</generator>
|
||||
<rights> © {{ 'now' | date: '%Y' }} {{ site.author }} </rights>
|
||||
<icon>{{ site.baseurl }}/assets/img/favicons/favicon.ico</icon>
|
||||
<logo>{{ site.baseurl }}/assets/img/favicons/favicon-96x96.png</logo>
|
||||
|
||||
{% for post in site.posts limit: 5 %}
|
||||
{% assign post_absolute_url = site.url | append: post.url %}
|
||||
<entry>
|
||||
<title>{{ post.title }}</title>
|
||||
<link href="{{ post_absolute_url }}" rel="alternate" type="text/html" title="{{ post.title }}" />
|
||||
<published>{{ post.date | date_to_xmlschema }}</published>
|
||||
{% if post.lastmod %}
|
||||
<updated>{{ post.lastmod | date_to_xmlschema }}</updated>
|
||||
{% else %}
|
||||
<updated>{{ site.time | date_to_xmlschema }}</updated>
|
||||
{% endif %}
|
||||
<id>{{ post_absolute_url }}</id>
|
||||
<content src="{{ post_absolute_url }}" />
|
||||
<author>
|
||||
<name>{{ site.author }}</name>
|
||||
</author>
|
||||
|
||||
{% if post.categories %}
|
||||
{% for category in post.categories %}
|
||||
<category term="{{ category }}" />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if post.summary %}
|
||||
<summary>{{ post.summary | strip }}</summary>
|
||||
{% else %}
|
||||
<summary>{{ post.content | strip_html | truncate: 200 }}</summary>
|
||||
{% endif %}
|
||||
|
||||
</entry>
|
||||
{% endfor %}
|
||||
</feed>
|
||||
{% endcapture %}
|
||||
{{ source | replace: '&', '&' }}
|
11
index.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
layout: home
|
||||
title: Home
|
||||
breadcrumb:
|
||||
-
|
||||
label: Posts
|
||||
|
||||
# Index page
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
56
init.sh
Executable file
|
@ -0,0 +1,56 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Initial the categories/tags pages and for posts.
|
||||
# © 2019 Cotes Chung
|
||||
# Published under MIT License
|
||||
|
||||
|
||||
CATEGORIES=false
|
||||
TAGS=false
|
||||
LASTMOD=false
|
||||
|
||||
set -eu
|
||||
|
||||
if [[ ! -z $(git status -s) ]]; then
|
||||
echo "Warning: Commit the changes of the repository first."
|
||||
git status -s
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python _scripts/py/init_all.py
|
||||
|
||||
msg="Updated"
|
||||
|
||||
if [[ ! -z $(git status categories -s) ]]; then
|
||||
git add categories/
|
||||
msg+=" Categories' pages"
|
||||
CATEGORIES=true
|
||||
fi
|
||||
|
||||
|
||||
if [[ ! -z $(git status tags -s) ]]; then
|
||||
git add tags/
|
||||
if [[ $CATEGORIES = true ]]; then
|
||||
msg+=" and"
|
||||
fi
|
||||
msg+=" Tags' pages"
|
||||
TAGS=true
|
||||
fi
|
||||
|
||||
if [[ ! -z $(git status _posts -s) ]]; then
|
||||
git add _posts/
|
||||
if [[ $CATEGORIES = true || $TAGS = true ]]; then
|
||||
msg+=" and"
|
||||
fi
|
||||
msg+=" Lastmod"
|
||||
LASTMOD=true
|
||||
fi
|
||||
|
||||
if [[ $CATEGORIES = true || $TAGS = true || $LASTMOD = true ]]; then
|
||||
msg+=" for post(s)."
|
||||
git commit -m "[Automation] $msg"
|
||||
else
|
||||
msg="Nothing changed."
|
||||
fi
|
||||
|
||||
echo $msg
|
21
pv.sh
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Fetch Google Analytics Pageviews reporting cache
|
||||
# and save as 'assets/data/pagevies.json'
|
||||
#
|
||||
# Requirement:
|
||||
# - jq
|
||||
# - wget
|
||||
#
|
||||
# © 2019 Cotes Chung
|
||||
# MIT Licensed
|
||||
|
||||
|
||||
URL_FILE=assets/data/proxy.json
|
||||
PV_CACHE=assets/data/pageviews.json
|
||||
|
||||
set -eu
|
||||
|
||||
PROXY_URL=$(jq -r '.proxyUrl' $URL_FILE)
|
||||
|
||||
wget $PROXY_URL -O $PV_CACHE
|
13
robots.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
# The robots rules
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT License
|
||||
layout: null
|
||||
permalink: robots.txt
|
||||
---
|
||||
|
||||
User-agent: *
|
||||
|
||||
Disallow: /norobots/
|
||||
|
||||
Sitemap: {{ site.url | append: site.baseurl }}/sitemap.xml
|
106
run.sh
Executable file
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Run jekyll site at http://127.0.0.1:4000
|
||||
# © 2019 Cotes Chung
|
||||
# Published under MIT License
|
||||
|
||||
|
||||
help() {
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo " bash run.sh [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -H, --host <HOST> Host to bind to"
|
||||
echo " -P, --port <PORT> Port to listen on"
|
||||
echo " -b, --baseurl <URL> The site relative url that start with slash, e.g. '/project'"
|
||||
echo " -h, --help Print the help information"
|
||||
}
|
||||
|
||||
|
||||
cleanup() {
|
||||
cd ../
|
||||
rm -rf .container
|
||||
}
|
||||
|
||||
|
||||
init() {
|
||||
|
||||
set -eu
|
||||
|
||||
if [[ -d .container ]]; then
|
||||
rm -rf .container
|
||||
fi
|
||||
|
||||
if [[ -d ../.chirpy-cache ]]; then
|
||||
rm -rf ../.chirpy-cache
|
||||
fi
|
||||
|
||||
mkdir ../.chirpy-cache
|
||||
cp -r * ../.chirpy-cache
|
||||
cp -r .git ../.chirpy-cache
|
||||
|
||||
mv ../.chirpy-cache .container
|
||||
|
||||
trap cleanup INT
|
||||
}
|
||||
|
||||
|
||||
check_unset() {
|
||||
if [[ -z ${1:+unset} ]]
|
||||
then
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
cmd="bundle exec jekyll s"
|
||||
|
||||
while (( $# ))
|
||||
do
|
||||
opt="$1"
|
||||
case $opt in
|
||||
-H|--host)
|
||||
check_unset $2
|
||||
cmd+=" -H $2"
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
-P|--port)
|
||||
check_unset $2
|
||||
cmd+=" -P $2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-b|--baseurl)
|
||||
check_unset $2
|
||||
if [[ $2 == \/* ]]
|
||||
then
|
||||
cmd+=" -b $2"
|
||||
else
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
init
|
||||
|
||||
cd .container
|
||||
python _scripts/py/init_all.py
|
||||
|
||||
echo "\$ $cmd"
|
||||
eval $cmd
|
14
search.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
layout: compress
|
||||
---
|
||||
[
|
||||
{% for post in site.posts %}
|
||||
{
|
||||
"title": "{{ post.title | escape }}",
|
||||
"url": "{{ site.baseurl }}{{ post.url }}",
|
||||
"categories": "{{ post.categories | join: ', '}}",
|
||||
"tags": "{{ post.tags | join: ', ' }}",
|
||||
"date": "{{ post.date }}"
|
||||
}{% unless forloop.last %},{% endunless %}
|
||||
{% endfor %}
|
||||
]
|
77
sitemap.xml
Normal file
|
@ -0,0 +1,77 @@
|
|||
---
|
||||
layout: compress
|
||||
# The Sitemap template
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{% for post in site.posts %}
|
||||
{% unless post.published == false %}
|
||||
|
||||
{% capture lastmod %}
|
||||
{% if post.lastmod %}
|
||||
{{ post.lastmod }}
|
||||
{% elsif post.date %}
|
||||
{{ post.date }}
|
||||
{% else %}
|
||||
{{ site.time }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
<url>
|
||||
<loc>{{ site.url | append: site.baseurl | append: post.url }}</loc>
|
||||
<lastmod>{{ lastmod | date_to_xmlschema }}</lastmod>
|
||||
|
||||
{% if post.sitemap.changefreq %}
|
||||
<changefreq>{{ post.sitemap.changefreq }}</changefreq>
|
||||
{% else %}
|
||||
<changefreq>monthly</changefreq>
|
||||
{% endif %}
|
||||
|
||||
{% if post.sitemap.priority %}
|
||||
<priority>{{ post.sitemap.priority }}</priority>
|
||||
{% else %}
|
||||
<priority>0.5</priority>
|
||||
{% endif %}
|
||||
</url>
|
||||
{% endunless %}
|
||||
{% endfor %}
|
||||
|
||||
{% for page in site.pages %}
|
||||
|
||||
{% if site.sitemap_exclude contains page.url %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% capture lastmod %}
|
||||
{% if page.lastmod %}
|
||||
{{ page.lastmod }}
|
||||
{% elsif page.date %}
|
||||
{{ page.date }}
|
||||
{% else %}
|
||||
{{ site.time }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
<url>
|
||||
<loc>{{ site.url | append: site.baseurl | append: page.url | remove: "index.html" }}</loc>
|
||||
<lastmod>{{ lastmod | date_to_xmlschema }}</lastmod>
|
||||
|
||||
{% if page.sitemap.changefreq %}
|
||||
<changefreq>{{ page.sitemap.changefreq }}</changefreq>
|
||||
{% else %}
|
||||
<changefreq>monthly</changefreq>
|
||||
{% endif %}
|
||||
|
||||
{% if page.sitemap.priority %}
|
||||
<priority>{{ page.sitemap.priority }}</priority>
|
||||
{% else %}
|
||||
<priority>0.3</priority>
|
||||
{% endif %}
|
||||
</url>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</urlset>
|
35
tabs/about.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
title: About
|
||||
|
||||
# The About page
|
||||
# © 2017-2019 Cotes Chung
|
||||
# MIT License
|
||||
---
|
||||
|
||||
**Chirpy** is an responsive web design Jekyll theme developed using Bootstrap 4.
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* Last modified date
|
||||
* Table of Contents
|
||||
* Disqus Comments
|
||||
* Syntax highlighting
|
||||
* Two-level Categories
|
||||
* Search
|
||||
* HTML compress
|
||||
* Atom feeds
|
||||
* Google Analytics
|
||||
* Pageviews (Advanced)
|
||||
|
||||
## Homepage
|
||||
|
||||
You can fork this project from the [Homepage](https://github.com/cotes2020/jekyll-theme-chirpy/). Any issues and suggestions are welcome!
|
||||
|
||||
## Usage
|
||||
|
||||
Follow the [tutorial posts]({{ site.baseurl }}/categories/tutorial/), it will help you build a site quickly.
|
||||
|
||||
## License
|
||||
|
||||
This project is published under the [MIT License](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE).
|