jekyll-theme-chirpy-g 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +61 -0
- data/_data/locales/ar.yml +91 -0
- data/_data/locales/bg-BG.yml +81 -0
- data/_data/locales/cs-CZ.yml +89 -0
- data/_data/locales/de-DE.yml +87 -0
- data/_data/locales/el-GR.yml +91 -0
- data/_data/locales/en.yml +91 -0
- data/_data/locales/es-ES.yml +77 -0
- data/_data/locales/fa-IR.yaml +91 -0
- data/_data/locales/fi-FI.yml +90 -0
- data/_data/locales/fr-FR.yml +77 -0
- data/_data/locales/hu-HU.yml +92 -0
- data/_data/locales/id-ID.yml +77 -0
- data/_data/locales/it-IT.yml +90 -0
- data/_data/locales/ko-KR.yml +84 -0
- data/_data/locales/my-MM.yml +77 -0
- data/_data/locales/nl-NL.yml +90 -0
- data/_data/locales/pt-BR.yml +77 -0
- data/_data/locales/ru-RU.yml +87 -0
- data/_data/locales/sl-SI.yml +91 -0
- data/_data/locales/sv-SE.yml +91 -0
- data/_data/locales/th.yml +91 -0
- data/_data/locales/tr-TR.yml +77 -0
- data/_data/locales/uk-UA.yml +77 -0
- data/_data/locales/vi-VN.yml +76 -0
- data/_data/locales/zh-CN.yml +83 -0
- data/_data/locales/zh-TW.yml +83 -0
- data/_data/origin/basic.yml +39 -0
- data/_data/origin/cors.yml +54 -0
- data/_includes/analytics/cloudflare.html +6 -0
- data/_includes/analytics/fathom.html +6 -0
- data/_includes/analytics/goatcounter.html +6 -0
- data/_includes/analytics/google.html +13 -0
- data/_includes/analytics/matomo.html +13 -0
- data/_includes/analytics/umami.html +6 -0
- data/_includes/comment.html +5 -0
- data/_includes/comments/disqus.html +57 -0
- data/_includes/comments/giscus.html +55 -0
- data/_includes/comments/utterances.html +38 -0
- data/_includes/datetime.html +20 -0
- data/_includes/embed/audio.html +35 -0
- data/_includes/embed/bilibili.html +9 -0
- data/_includes/embed/twitch.html +8 -0
- data/_includes/embed/video.html +59 -0
- data/_includes/embed/youtube.html +9 -0
- data/_includes/favicons.html +19 -0
- data/_includes/footer.html +49 -0
- data/_includes/head.html +126 -0
- data/_includes/js-selector.html +86 -0
- data/_includes/jsdelivr-combine.html +26 -0
- data/_includes/lang.html +10 -0
- data/_includes/language-alias.html +70 -0
- data/_includes/media-url.html +37 -0
- data/_includes/metadata-hook.html +1 -0
- data/_includes/notification.html +24 -0
- data/_includes/origin-type.html +13 -0
- data/_includes/pageviews/goatcounter.html +21 -0
- data/_includes/post-description.html +25 -0
- data/_includes/post-nav.html +34 -0
- data/_includes/post-paginator.html +91 -0
- data/_includes/post-sharing.html +52 -0
- data/_includes/read-time.html +37 -0
- data/_includes/refactor-content.html +255 -0
- data/_includes/related-posts.html +94 -0
- data/_includes/search-loader.html +49 -0
- data/_includes/search-results.html +10 -0
- data/_includes/sidebar.html +97 -0
- data/_includes/toc-status.html +10 -0
- data/_includes/toc.html +9 -0
- data/_includes/topbar.html +77 -0
- data/_includes/trending-tags.html +46 -0
- data/_includes/update-list.html +40 -0
- data/_layouts/archives.html +35 -0
- data/_layouts/categories.html +138 -0
- data/_layouts/category.html +24 -0
- data/_layouts/compress.html +10 -0
- data/_layouts/default.html +86 -0
- data/_layouts/graph.html +8 -0
- data/_layouts/home.html +122 -0
- data/_layouts/page.html +20 -0
- data/_layouts/post.html +179 -0
- data/_layouts/tag.html +23 -0
- data/_layouts/tags.html +22 -0
- data/_sass/abstracts/_breakpoints.scss +73 -0
- data/_sass/abstracts/_index.scss +4 -0
- data/_sass/abstracts/_mixins.scss +80 -0
- data/_sass/abstracts/_placeholders.scss +160 -0
- data/_sass/abstracts/_variables.scss +30 -0
- data/_sass/base/_base.scss +476 -0
- data/_sass/base/_index.scss +4 -0
- data/_sass/base/_reset.scss +41 -0
- data/_sass/base/_syntax.scss +253 -0
- data/_sass/base/_typography.scss +266 -0
- data/_sass/components/_buttons.scss +51 -0
- data/_sass/components/_index.scss +2 -0
- data/_sass/components/_popups.scss +172 -0
- data/_sass/layout/_footer.scss +36 -0
- data/_sass/layout/_index.scss +4 -0
- data/_sass/layout/_panel.scss +70 -0
- data/_sass/layout/_sidebar.scss +258 -0
- data/_sass/layout/_topbar.scss +86 -0
- data/_sass/main.bundle.scss +2 -0
- data/_sass/main.scss +4 -0
- data/_sass/pages/_archives.scss +140 -0
- data/_sass/pages/_categories.scss +82 -0
- data/_sass/pages/_category-tag.scss +63 -0
- data/_sass/pages/_graph.scss +51 -0
- data/_sass/pages/_home.scss +173 -0
- data/_sass/pages/_index.scss +8 -0
- data/_sass/pages/_post.scss +498 -0
- data/_sass/pages/_search.scss +184 -0
- data/_sass/pages/_tags.scss +23 -0
- data/_sass/themes/_dark.scss +318 -0
- data/_sass/themes/_light.scss +330 -0
- data/assets/404.html +14 -0
- data/assets/css/jekyll-theme-chirpy-g.scss +10 -0
- data/assets/feed.xml +54 -0
- data/assets/img/favicons/android-chrome-192x192.png +0 -0
- data/assets/img/favicons/android-chrome-512x512.png +0 -0
- data/assets/img/favicons/apple-touch-icon.png +0 -0
- data/assets/img/favicons/browserconfig.xml +13 -0
- data/assets/img/favicons/favicon-16x16.png +0 -0
- data/assets/img/favicons/favicon-32x32.png +0 -0
- data/assets/img/favicons/favicon.ico +0 -0
- data/assets/img/favicons/mstile-150x150.png +0 -0
- data/assets/img/favicons/site.webmanifest +26 -0
- data/assets/js/data/graph.json +14 -0
- data/assets/js/data/mathjax.js +25 -0
- data/assets/js/data/search.json +20 -0
- data/assets/js/data/swconf.js +47 -0
- data/assets/js/dist/app.min.js +7 -0
- data/assets/js/dist/categories.min.js +4 -0
- data/assets/js/dist/commons.min.js +4 -0
- data/assets/js/dist/graph.min.js +4 -0
- data/assets/js/dist/home.min.js +4 -0
- data/assets/js/dist/misc.min.js +4 -0
- data/assets/js/dist/page.min.js +4 -0
- data/assets/js/dist/post.min.js +4 -0
- data/assets/js/dist/sw.min.js +7 -0
- data/assets/js/dist/theme.min.js +4 -0
- data/assets/robots.txt +10 -0
- metadata +286 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
<!-- The paginator for post list on HomgPage. -->
|
2
|
+
|
3
|
+
<nav aria-label="Page Navigation">
|
4
|
+
<ul class="pagination align-items-center mt-4 mb-0">
|
5
|
+
<!-- left arrow -->
|
6
|
+
{% if paginator.previous_page %}
|
7
|
+
{% assign prev_url = paginator.previous_page_path | relative_url %}
|
8
|
+
{% else %}
|
9
|
+
{% assign prev_url = '#' %}
|
10
|
+
{% endif %}
|
11
|
+
|
12
|
+
<li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
|
13
|
+
<a class="page-link" href="{{ prev_url }}" aria-label="previous-page">
|
14
|
+
<i class="fas fa-angle-left"></i>
|
15
|
+
</a>
|
16
|
+
</li>
|
17
|
+
|
18
|
+
<!-- page numbers -->
|
19
|
+
{% assign left_ellipsis = false %}
|
20
|
+
{% assign right_ellipsis = false %}
|
21
|
+
|
22
|
+
{% for i in (1..paginator.total_pages) %}
|
23
|
+
{% assign pre = paginator.page | minus: 1 %}
|
24
|
+
{% assign next = paginator.page | plus: 1 %}
|
25
|
+
{% assign pre_less = pre | minus: 1 %}
|
26
|
+
{% assign next_more = next | plus: 1 %}
|
27
|
+
{% assign show = false %}
|
28
|
+
|
29
|
+
{% if paginator.page == 1 %}
|
30
|
+
{% if i <= 3 or i == paginator.total_pages %}
|
31
|
+
{% assign show = true %}
|
32
|
+
{% endif %}
|
33
|
+
{% elsif paginator.page == paginator.total_pages %}
|
34
|
+
{% if i == 1 or i >= pre_less %}
|
35
|
+
{% assign show = true %}
|
36
|
+
{% endif %}
|
37
|
+
{% else %}
|
38
|
+
{% if i == 1 or i == paginator.total_pages %}
|
39
|
+
{% assign show = true %}
|
40
|
+
{% elsif i >= pre and i <= next %}
|
41
|
+
{% assign show = true %}
|
42
|
+
{% endif %}
|
43
|
+
{% endif %}
|
44
|
+
|
45
|
+
{% if show %}
|
46
|
+
<!-- show number -->
|
47
|
+
<li class="page-item {% if i == paginator.page %} active{% endif %}">
|
48
|
+
<a
|
49
|
+
class="page-link"
|
50
|
+
href="{% if i > 1 %}{{ site.paginate_path | replace: ':num', i | relative_url }}{% else %}{{ '/' | relative_url }}{% endif %}"
|
51
|
+
>
|
52
|
+
{{- i -}}
|
53
|
+
</a>
|
54
|
+
</li>
|
55
|
+
{% else %}
|
56
|
+
<!-- hide number -->
|
57
|
+
{% if i < pre and left_ellipsis == false %}
|
58
|
+
<li class="page-item disabled">
|
59
|
+
<span class="page-link">...</span>
|
60
|
+
</li>
|
61
|
+
{% assign left_ellipsis = true %}
|
62
|
+
{% elsif i > next and right_ellipsis == false %}
|
63
|
+
<li class="page-item disabled">
|
64
|
+
<span class="page-link">...</span>
|
65
|
+
</li>
|
66
|
+
{% assign right_ellipsis = true %}
|
67
|
+
{% endif %}
|
68
|
+
{% endif %}
|
69
|
+
{% endfor %}
|
70
|
+
|
71
|
+
<!-- mobile pagination -->
|
72
|
+
<li class="page-index align-middle">
|
73
|
+
<span>{{ paginator.page }}</span>
|
74
|
+
<span class="text-muted">/ {{ paginator.total_pages }}</span>
|
75
|
+
</li>
|
76
|
+
|
77
|
+
<!-- right arrow -->
|
78
|
+
{% if paginator.next_page_path %}
|
79
|
+
{% assign next_url = paginator.next_page_path | relative_url %}
|
80
|
+
{% else %}
|
81
|
+
{% assign next_url = '#' %}
|
82
|
+
{% endif %}
|
83
|
+
|
84
|
+
<li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
|
85
|
+
<a class="page-link" href="{{ next_url }}" aria-label="next-page">
|
86
|
+
<i class="fas fa-angle-right"></i>
|
87
|
+
</a>
|
88
|
+
</li>
|
89
|
+
</ul>
|
90
|
+
</nav>
|
91
|
+
<!-- .pagination -->
|
@@ -0,0 +1,52 @@
|
|
1
|
+
<!-- Post sharing snippet -->
|
2
|
+
|
3
|
+
<div class="share-wrapper d-flex align-items-center">
|
4
|
+
<span class="share-label text-muted">{{ site.data.locales[include.lang].post.share }}</span>
|
5
|
+
<span class="share-icons">
|
6
|
+
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
|
7
|
+
{% assign title = title | uri_escape %}
|
8
|
+
{% assign url = page.url | absolute_url | url_encode %}
|
9
|
+
|
10
|
+
{% for share in site.data.share.platforms -%}
|
11
|
+
{%- capture tooltip -%}
|
12
|
+
data-bs-toggle="tooltip" data-bs-placement="top" title="{{ share.type }}" aria-label="{{ share.type }}"
|
13
|
+
{%- endcapture -%}
|
14
|
+
|
15
|
+
{% if share.type == 'Mastodon' %}
|
16
|
+
<script defer type="module" src="https://cdn.jsdelivr.net/npm/@justinribeiro/share-to-mastodon/+esm"></script>
|
17
|
+
<button class="btn text-start" {{ tooltip }}>
|
18
|
+
<share-to-mastodon
|
19
|
+
class="share-mastodon"
|
20
|
+
message="{{ title }}"
|
21
|
+
url="{{ url }}"
|
22
|
+
{%- if share.instances -%}
|
23
|
+
customInstanceList="{{ share.instances | jsonify | xml_escape }}"
|
24
|
+
{%- endif %}
|
25
|
+
>
|
26
|
+
<i class="fa-fw {{ share.icon }}"></i>
|
27
|
+
</share-to-mastodon>
|
28
|
+
</button>
|
29
|
+
|
30
|
+
{% continue %}
|
31
|
+
{% endif %}
|
32
|
+
|
33
|
+
{% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url %}
|
34
|
+
|
35
|
+
<a href="{{ link }}" target="_blank" rel="noopener" {{ tooltip }}>
|
36
|
+
<i class="fa-fw {{ share.icon }}"></i>
|
37
|
+
</a>
|
38
|
+
{% endfor %}
|
39
|
+
|
40
|
+
<button
|
41
|
+
id="copy-link"
|
42
|
+
aria-label="Copy link"
|
43
|
+
class="btn small"
|
44
|
+
data-bs-toggle="tooltip"
|
45
|
+
data-bs-placement="top"
|
46
|
+
title="{{ site.data.locales[include.lang].post.button.share_link.title }}"
|
47
|
+
data-title-succeed="{{ site.data.locales[include.lang].post.button.share_link.succeed }}"
|
48
|
+
>
|
49
|
+
<i class="fa-fw fas fa-link pe-none fs-6"></i>
|
50
|
+
</button>
|
51
|
+
</span>
|
52
|
+
</div>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<!-- Calculate the post's reading time, and display the word count in tooltip -->
|
2
|
+
|
3
|
+
{% assign words = include.content | strip_html | number_of_words: 'auto' %}
|
4
|
+
|
5
|
+
<!-- words per minute -->
|
6
|
+
|
7
|
+
{% assign wpm = 180 %}
|
8
|
+
{% assign min_time = 1 %}
|
9
|
+
|
10
|
+
{% assign read_time = words | divided_by: wpm %}
|
11
|
+
|
12
|
+
{% unless read_time > 0 %}
|
13
|
+
{% assign read_time = min_time %}
|
14
|
+
{% endunless %}
|
15
|
+
|
16
|
+
{% capture read_prompt %}
|
17
|
+
{{- site.data.locales[include.lang].post.read_time.prompt -}}
|
18
|
+
{% endcapture %}
|
19
|
+
|
20
|
+
<!-- return element -->
|
21
|
+
<span
|
22
|
+
class="readtime"
|
23
|
+
data-bs-toggle="tooltip"
|
24
|
+
data-bs-placement="bottom"
|
25
|
+
title="{{ words }} {{ site.data.locales[include.lang].post.words }}"
|
26
|
+
>
|
27
|
+
<em>
|
28
|
+
{{- read_time -}}
|
29
|
+
{{ ' ' }}
|
30
|
+
{{- site.data.locales[include.lang].post.read_time.unit -}}
|
31
|
+
</em>
|
32
|
+
{%- if include.prompt -%}
|
33
|
+
{%- assign _prompt_words = read_prompt | number_of_words: 'auto' -%}
|
34
|
+
{%- unless _prompt_words > 1 -%}{{ ' ' }}{%- endunless -%}
|
35
|
+
{{ read_prompt }}
|
36
|
+
{%- endif -%}
|
37
|
+
</span>
|
@@ -0,0 +1,255 @@
|
|
1
|
+
<!-- Refactor the HTML structure -->
|
2
|
+
|
3
|
+
{% assign _content = include.content %}
|
4
|
+
|
5
|
+
<!--
|
6
|
+
In order to allow a wide table to scroll horizontally,
|
7
|
+
we suround the markdown table with `<div class="table-wrapper">` and `</div>`
|
8
|
+
-->
|
9
|
+
|
10
|
+
{% if _content contains '<table' %}
|
11
|
+
{% assign _content = _content
|
12
|
+
| replace: '<table', '<div class="table-wrapper"><table'
|
13
|
+
| replace: '</table>', '</table></div>'
|
14
|
+
| replace: '<code><div class="table-wrapper">', '<code>'
|
15
|
+
| replace: '</table></div></code>', '</table></code>'
|
16
|
+
%}
|
17
|
+
{% endif %}
|
18
|
+
|
19
|
+
<!--
|
20
|
+
Fixed kramdown code highlight rendering:
|
21
|
+
https://github.com/penibelst/jekyll-compress-html/issues/101
|
22
|
+
https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
|
23
|
+
-->
|
24
|
+
|
25
|
+
{% if _content contains '<pre class="highlight">' %}
|
26
|
+
{% assign _content = _content
|
27
|
+
| replace: '<div class="highlight"><pre class="highlight"><code', '<div class="highlight"><code'
|
28
|
+
| replace: '</code></pre></div>', '</code></div>'
|
29
|
+
%}
|
30
|
+
{% endif %}
|
31
|
+
|
32
|
+
<!-- Change the icon of checkbox -->
|
33
|
+
|
34
|
+
{% if _content contains '<input type="checkbox"' %}
|
35
|
+
{% assign _content = _content
|
36
|
+
| replace: '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />',
|
37
|
+
'<i class="fas fa-check-circle fa-fw checked"></i>'
|
38
|
+
| replace: '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />',
|
39
|
+
'<i class="far fa-circle fa-fw"></i>'
|
40
|
+
%}
|
41
|
+
{% endif %}
|
42
|
+
|
43
|
+
<!-- Handle images -->
|
44
|
+
|
45
|
+
{% assign IMG_TAG = '<img ' %}
|
46
|
+
|
47
|
+
{% if _content contains IMG_TAG %}
|
48
|
+
{% assign _img_content = null %}
|
49
|
+
{% assign _img_snippets = _content | split: IMG_TAG %}
|
50
|
+
|
51
|
+
{% for _img_snippet in _img_snippets %}
|
52
|
+
{% if forloop.first %}
|
53
|
+
{% assign _img_content = _img_snippet %}
|
54
|
+
{% continue %}
|
55
|
+
{% endif %}
|
56
|
+
|
57
|
+
{% assign _left = _img_snippet | split: '>' | first %}
|
58
|
+
{% assign _right = _img_snippet | remove: _left %}
|
59
|
+
|
60
|
+
{% unless _left contains 'src=' %}
|
61
|
+
{% continue %}
|
62
|
+
{% endunless %}
|
63
|
+
|
64
|
+
{% assign _left = _left | remove: ' /' | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
|
65
|
+
{% assign _attrs = _left | split: '" ' %}
|
66
|
+
|
67
|
+
{% assign _src = null %}
|
68
|
+
{% assign _lqip = null %}
|
69
|
+
{% assign _class = null %}
|
70
|
+
|
71
|
+
{% for _attr in _attrs %}
|
72
|
+
{% unless _attr contains '=' %}
|
73
|
+
{% continue %}
|
74
|
+
{% endunless %}
|
75
|
+
|
76
|
+
{% assign _pair = _attr | split: '="' %}
|
77
|
+
{% capture _key %}{{ _pair | first }}{% endcapture %}
|
78
|
+
{% capture _value %}{{ _pair | last | remove: '"' }}{% endcapture %}
|
79
|
+
|
80
|
+
{% case _key %}
|
81
|
+
{% when 'src' %}
|
82
|
+
{% assign _src = _value %}
|
83
|
+
{% when 'lqip' %}
|
84
|
+
{% assign _lqip = _value %}
|
85
|
+
{% when 'class' %}
|
86
|
+
{% assign _class = _value %}
|
87
|
+
{% endcase %}
|
88
|
+
{% endfor %}
|
89
|
+
|
90
|
+
<!-- take out classes -->
|
91
|
+
{% if _class %}
|
92
|
+
{% capture _old_class %}class="{{ _class }}"{% endcapture %}
|
93
|
+
{% assign _left = _left | remove: _old_class %}
|
94
|
+
{% endif %}
|
95
|
+
|
96
|
+
{% assign _final_src = null %}
|
97
|
+
{% assign _lazyload = true %}
|
98
|
+
|
99
|
+
{%- capture _img_url -%}
|
100
|
+
{% include media-url.html src=_src subpath=page.media_subpath %}
|
101
|
+
{%- endcapture -%}
|
102
|
+
|
103
|
+
{% assign _path_prefix = _img_url | remove: _src %}
|
104
|
+
|
105
|
+
{% unless _src contains '//' %}
|
106
|
+
{% assign _final_src = _path_prefix | append: _src %}
|
107
|
+
{% assign _src_alt = 'src="' | append: _path_prefix %}
|
108
|
+
{% assign _left = _left | replace: 'src="', _src_alt %}
|
109
|
+
{% endunless %}
|
110
|
+
|
111
|
+
{% if _lqip %}
|
112
|
+
{% assign _lazyload = false %}
|
113
|
+
{% assign _class = _class | append: ' blur' %}
|
114
|
+
|
115
|
+
{% unless _lqip contains 'data:' %}
|
116
|
+
{% assign _lqip_alt = 'lqip="' | append: _path_prefix %}
|
117
|
+
{% assign _left = _left | replace: 'lqip="', _lqip_alt %}
|
118
|
+
{% endunless %}
|
119
|
+
|
120
|
+
<!-- add image placeholder -->
|
121
|
+
{% assign _left = _left | replace: 'src=', 'data-src=' | replace: ' lqip=', ' data-lqip="true" src=' %}
|
122
|
+
|
123
|
+
{% else %}
|
124
|
+
{% assign _class = _class | append: ' shimmer' %}
|
125
|
+
{% endif %}
|
126
|
+
|
127
|
+
<!-- lazy-load images -->
|
128
|
+
{% if _lazyload %}
|
129
|
+
{% assign _left = _left | append: ' loading="lazy"' %}
|
130
|
+
{% endif %}
|
131
|
+
|
132
|
+
{% if page.layout == 'home' %}
|
133
|
+
<!-- create the image wrapper -->
|
134
|
+
{% assign _wrapper_start = '<div class="preview-img ' | append: _class | append: '">' %}
|
135
|
+
|
136
|
+
{% assign _img_content = _img_content | append: _wrapper_start %}
|
137
|
+
{% assign _right = _right | prepend: '></div' %}
|
138
|
+
|
139
|
+
{% else %}
|
140
|
+
<!-- make sure the `<img>` is wrapped by `<a>` -->
|
141
|
+
{% assign _parent = _right | slice: 1, 4 %}
|
142
|
+
|
143
|
+
{% if _parent == '</a>' %}
|
144
|
+
<!-- add class to exist <a> tag -->
|
145
|
+
{% assign _size = _img_content | size | minus: 1 %}
|
146
|
+
{% capture _class %}
|
147
|
+
class="img-link{% unless _lqip %} shimmer{% endunless %}"
|
148
|
+
{% endcapture %}
|
149
|
+
{% assign _img_content = _img_content | slice: 0, _size | append: _class | append: '>' %}
|
150
|
+
|
151
|
+
{% else %}
|
152
|
+
<!-- create the image wrapper -->
|
153
|
+
{% assign _wrapper_start = _final_src
|
154
|
+
| default: _src
|
155
|
+
| prepend: '<a href="'
|
156
|
+
| append: '" class="popup img-link '
|
157
|
+
| append: _class
|
158
|
+
| append: '">'
|
159
|
+
%}
|
160
|
+
|
161
|
+
{% assign _img_content = _img_content | append: _wrapper_start %}
|
162
|
+
{% assign _right = '></a' | append: _right %}
|
163
|
+
{% endif %}
|
164
|
+
{% endif %}
|
165
|
+
|
166
|
+
<!-- combine -->
|
167
|
+
{% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
|
168
|
+
{% endfor %}
|
169
|
+
|
170
|
+
{% if _img_content %}
|
171
|
+
{% assign _content = _img_content %}
|
172
|
+
{% endif %}
|
173
|
+
{% endif %}
|
174
|
+
|
175
|
+
<!-- Add header for code snippets -->
|
176
|
+
|
177
|
+
{% if _content contains '<div class="highlight"><code>' %}
|
178
|
+
{% assign _code_spippets = _content | split: '<div class="highlight"><code>' %}
|
179
|
+
{% assign _new_content = '' %}
|
180
|
+
|
181
|
+
{% for _snippet in _code_spippets %}
|
182
|
+
{% if forloop.last %}
|
183
|
+
{% assign _new_content = _new_content | append: _snippet %}
|
184
|
+
|
185
|
+
{% else %}
|
186
|
+
{% assign _left = _snippet | split: '><' | last %}
|
187
|
+
|
188
|
+
{% if _left contains 'file="' %}
|
189
|
+
{% assign _label_text = _left | split: 'file="' | last | split: '"' | first %}
|
190
|
+
{% assign _label_icon = 'far fa-file-code fa-fw' %}
|
191
|
+
{% else %}
|
192
|
+
{% assign _lang = _left | split: 'language-' | last | split: ' ' | first %}
|
193
|
+
{% capture _label_text %}{% include language-alias.html language=_lang %}{% endcapture %}
|
194
|
+
{% assign _label_icon = 'fas fa-code fa-fw small' %}
|
195
|
+
{% endif %}
|
196
|
+
|
197
|
+
{% capture _label %}
|
198
|
+
<span data-label-text="{{ _label_text | strip }}"><i class="{{ _label_icon }}"></i></span>
|
199
|
+
{% endcapture %}
|
200
|
+
|
201
|
+
{% assign _new_content = _new_content
|
202
|
+
| append: _snippet
|
203
|
+
| append: '<div class="code-header">'
|
204
|
+
| append: _label
|
205
|
+
| append: '<button aria-label="copy" data-title-succeed="'
|
206
|
+
| append: site.data.locales[include.lang].post.button.copy_code.succeed
|
207
|
+
| append: '"><i class="far fa-clipboard"></i></button></div>'
|
208
|
+
| append: '<div class="highlight"><code>'
|
209
|
+
%}
|
210
|
+
{% endif %}
|
211
|
+
{% endfor %}
|
212
|
+
|
213
|
+
{% assign _content = _new_content %}
|
214
|
+
{% endif %}
|
215
|
+
|
216
|
+
<!-- Create heading anchors -->
|
217
|
+
|
218
|
+
{% assign heading_levels = '2,3,4,5' | split: ',' %}
|
219
|
+
{% assign _heading_content = _content %}
|
220
|
+
|
221
|
+
{% for level in heading_levels %}
|
222
|
+
{% assign mark_start = '<h' | append: level | append: ' id="' %}
|
223
|
+
{% assign mark_end = '</h' | append: level | append: '>' %}
|
224
|
+
|
225
|
+
{% if _heading_content contains mark_start %}
|
226
|
+
{% assign _new_content = null %}
|
227
|
+
{% assign heading_snippets = _heading_content | split: mark_start %}
|
228
|
+
|
229
|
+
{% for snippet in heading_snippets %}
|
230
|
+
{% if forloop.first %}
|
231
|
+
{% assign _new_content = snippet %}
|
232
|
+
{% continue %}
|
233
|
+
{% endif %}
|
234
|
+
|
235
|
+
{% assign id = snippet | split: '"' | first %}
|
236
|
+
{% assign anchor = '<a href="#'
|
237
|
+
| append: id
|
238
|
+
| append: '" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>'
|
239
|
+
%}
|
240
|
+
|
241
|
+
{% assign left = snippet | split: mark_end | first %}
|
242
|
+
{% assign right = snippet | slice: left.size, snippet.size %}
|
243
|
+
{% assign left = left | replace_first: '">', '"><span class="me-2">' | append: '</span>' %}
|
244
|
+
|
245
|
+
{% assign _new_content = _new_content | append: mark_start | append: left | append: anchor | append: right %}
|
246
|
+
{% endfor %}
|
247
|
+
|
248
|
+
{% assign _heading_content = _new_content %}
|
249
|
+
{% endif %}
|
250
|
+
{% endfor %}
|
251
|
+
|
252
|
+
{% assign _content = _heading_content %}
|
253
|
+
|
254
|
+
<!-- return -->
|
255
|
+
{{ _content }}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
<!-- Recommend the other 3 posts according to the tags and categories of the current post. -->
|
2
|
+
|
3
|
+
<!-- The total size of related posts -->
|
4
|
+
{% assign TOTAL_SIZE = 3 %}
|
5
|
+
|
6
|
+
<!-- An random integer that bigger than 0 -->
|
7
|
+
{% assign TAG_SCORE = 1 %}
|
8
|
+
|
9
|
+
<!-- Equals to TAG_SCORE / {max_categories_hierarchy} -->
|
10
|
+
{% assign CATEGORY_SCORE = 0.5 %}
|
11
|
+
|
12
|
+
{% assign SEPARATOR = ':' %}
|
13
|
+
|
14
|
+
{% assign match_posts = '' | split: '' %}
|
15
|
+
|
16
|
+
{% for category in page.categories %}
|
17
|
+
{% assign match_posts = match_posts | push: site.categories[category] | uniq %}
|
18
|
+
{% endfor %}
|
19
|
+
|
20
|
+
{% for tag in page.tags %}
|
21
|
+
{% assign match_posts = match_posts | push: site.tags[tag] | uniq %}
|
22
|
+
{% endfor %}
|
23
|
+
|
24
|
+
{% assign match_posts = match_posts | reverse %}
|
25
|
+
{% assign last_index = match_posts.size | minus: 1 %}
|
26
|
+
{% assign score_list = '' | split: '' %}
|
27
|
+
|
28
|
+
{% for i in (0..last_index) %}
|
29
|
+
{% assign post = match_posts[i] %}
|
30
|
+
|
31
|
+
{% if post.url == page.url %}
|
32
|
+
{% continue %}
|
33
|
+
{% endif %}
|
34
|
+
|
35
|
+
{% assign score = 0 %}
|
36
|
+
|
37
|
+
{% for tag in post.tags %}
|
38
|
+
{% if page.tags contains tag %}
|
39
|
+
{% assign score = score | plus: TAG_SCORE %}
|
40
|
+
{% endif %}
|
41
|
+
{% endfor %}
|
42
|
+
|
43
|
+
{% for category in post.categories %}
|
44
|
+
{% if page.categories contains category %}
|
45
|
+
{% assign score = score | plus: CATEGORY_SCORE %}
|
46
|
+
{% endif %}
|
47
|
+
{% endfor %}
|
48
|
+
|
49
|
+
{% if score > 0 %}
|
50
|
+
{% capture score_item %}{{ score }}{{ SEPARATOR }}{{ i }}{% endcapture %}
|
51
|
+
{% assign score_list = score_list | push: score_item %}
|
52
|
+
{% endif %}
|
53
|
+
{% endfor %}
|
54
|
+
|
55
|
+
{% assign index_list = '' | split: '' %}
|
56
|
+
|
57
|
+
{% if score_list.size > 0 %}
|
58
|
+
{% assign score_list = score_list | sort | reverse %}
|
59
|
+
{% for entry in score_list limit: TOTAL_SIZE %}
|
60
|
+
{% assign index = entry | split: SEPARATOR | last %}
|
61
|
+
{% assign index_list = index_list | push: index %}
|
62
|
+
{% endfor %}
|
63
|
+
{% endif %}
|
64
|
+
|
65
|
+
{% assign relate_posts = '' | split: '' %}
|
66
|
+
|
67
|
+
{% for index in index_list %}
|
68
|
+
{% assign i = index | to_integer %}
|
69
|
+
{% assign relate_posts = relate_posts | push: match_posts[i] %}
|
70
|
+
{% endfor %}
|
71
|
+
|
72
|
+
{% if relate_posts.size > 0 %}
|
73
|
+
<aside id="related-posts" aria-labelledby="related-label">
|
74
|
+
<h3 class="mb-4" id="related-label">
|
75
|
+
{{- site.data.locales[include.lang].post.relate_posts -}}
|
76
|
+
</h3>
|
77
|
+
<nav class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4 mb-4">
|
78
|
+
{% for post in relate_posts %}
|
79
|
+
<article class="col">
|
80
|
+
<a href="{{ post.url | relative_url }}" class="post-preview card h-100">
|
81
|
+
<div class="card-body">
|
82
|
+
{% include datetime.html date=post.date lang=include.lang %}
|
83
|
+
<h4 class="pt-0 my-2">{{ post.title }}</h4>
|
84
|
+
<div class="text-muted">
|
85
|
+
<p>{% include post-description.html %}</p>
|
86
|
+
</div>
|
87
|
+
</div>
|
88
|
+
</a>
|
89
|
+
</article>
|
90
|
+
{% endfor %}
|
91
|
+
</nav>
|
92
|
+
</aside>
|
93
|
+
<!-- #related-posts -->
|
94
|
+
{% endif %}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<!--
|
2
|
+
Jekyll Simple Search loader
|
3
|
+
See: <https://github.com/christian-fei/Simple-Jekyll-Search>
|
4
|
+
-->
|
5
|
+
|
6
|
+
{% capture result_elem %}
|
7
|
+
<article class="px-1 px-sm-2 px-lg-4 px-xl-0">
|
8
|
+
<header>
|
9
|
+
<h2><a href="{url}">{title}</a></h2>
|
10
|
+
<div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">
|
11
|
+
{categories}
|
12
|
+
{tags}
|
13
|
+
</div>
|
14
|
+
</header>
|
15
|
+
<p>{content}</p>
|
16
|
+
</article>
|
17
|
+
{% endcapture %}
|
18
|
+
|
19
|
+
{% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
|
20
|
+
|
21
|
+
<script>
|
22
|
+
{% comment %} Note: dependent library will be loaded in `js-selector.html` {% endcomment %}
|
23
|
+
document.addEventListener('DOMContentLoaded', () => {
|
24
|
+
SimpleJekyllSearch({
|
25
|
+
searchInput: document.getElementById('search-input'),
|
26
|
+
resultsContainer: document.getElementById('search-results'),
|
27
|
+
json: '{{ '/assets/js/data/search.json' | relative_url }}',
|
28
|
+
searchResultTemplate: '{{ result_elem | strip_newlines }}',
|
29
|
+
noResultsText: '{{ not_found }}',
|
30
|
+
templateMiddleware: function(prop, value, template) {
|
31
|
+
if (prop === 'categories') {
|
32
|
+
if (value === '') {
|
33
|
+
return `${value}`;
|
34
|
+
} else {
|
35
|
+
return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
if (prop === 'tags') {
|
40
|
+
if (value === '') {
|
41
|
+
return `${value}`;
|
42
|
+
} else {
|
43
|
+
return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
});
|
48
|
+
});
|
49
|
+
</script>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!-- The Search results -->
|
2
|
+
|
3
|
+
<div id="search-result-wrapper" class="d-flex justify-content-center d-none">
|
4
|
+
<div class="col-11 content">
|
5
|
+
<div id="search-hints">
|
6
|
+
{% include_cached trending-tags.html %}
|
7
|
+
</div>
|
8
|
+
<div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
|
9
|
+
</div>
|
10
|
+
</div>
|
@@ -0,0 +1,97 @@
|
|
1
|
+
<!-- The Side Bar -->
|
2
|
+
|
3
|
+
<aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end">
|
4
|
+
<header class="profile-wrapper">
|
5
|
+
<a href="{{ '/' | relative_url }}" id="avatar" class="rounded-circle">
|
6
|
+
{%- if site.avatar != empty and site.avatar -%}
|
7
|
+
{%- capture avatar_url -%}
|
8
|
+
{% include media-url.html src=site.avatar %}
|
9
|
+
{%- endcapture -%}
|
10
|
+
<img src="{{- avatar_url -}}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
11
|
+
{%- endif -%}
|
12
|
+
</a>
|
13
|
+
|
14
|
+
<a class="site-title d-block" href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
15
|
+
<p class="site-subtitle fst-italic mb-0">{{ site.tagline }}</p>
|
16
|
+
</header>
|
17
|
+
<!-- .profile-wrapper -->
|
18
|
+
|
19
|
+
<nav class="flex-column flex-grow-1 w-100 ps-0">
|
20
|
+
<ul class="nav">
|
21
|
+
<!-- home -->
|
22
|
+
<li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}">
|
23
|
+
<a href="{{ '/' | relative_url }}" class="nav-link">
|
24
|
+
<i class="fa-fw fas fa-home"></i>
|
25
|
+
<span>{{ site.data.locales[include.lang].tabs.home | upcase }}</span>
|
26
|
+
</a>
|
27
|
+
</li>
|
28
|
+
<!-- the real tabs -->
|
29
|
+
{% for tab in site.tabs %}
|
30
|
+
<li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}">
|
31
|
+
<a href="{{ tab.url | relative_url }}" class="nav-link">
|
32
|
+
<i class="fa-fw {{ tab.icon }}"></i>
|
33
|
+
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %}
|
34
|
+
|
35
|
+
<span>{{ site.data.locales[include.lang].tabs.[tab_name] | default: tab.title | upcase }}</span>
|
36
|
+
</a>
|
37
|
+
</li>
|
38
|
+
<!-- .nav-item -->
|
39
|
+
{% endfor %}
|
40
|
+
</ul>
|
41
|
+
</nav>
|
42
|
+
|
43
|
+
<div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
|
44
|
+
{% unless site.theme_mode %}
|
45
|
+
<button type="button" class="btn btn-link nav-link" aria-label="Switch Mode" id="mode-toggle">
|
46
|
+
<i class="fas fa-adjust"></i>
|
47
|
+
</button>
|
48
|
+
|
49
|
+
{% if site.data.contact.size > 0 %}
|
50
|
+
<span class="icon-border"></span>
|
51
|
+
{% endif %}
|
52
|
+
{% endunless %}
|
53
|
+
|
54
|
+
{% for entry in site.data.contact %}
|
55
|
+
{% case entry.type %}
|
56
|
+
{% when 'github', 'twitter' %}
|
57
|
+
{%- capture url -%}
|
58
|
+
https://{{ entry.type }}.com/{{ site[entry.type].username }}
|
59
|
+
{%- endcapture -%}
|
60
|
+
{% when 'email' %}
|
61
|
+
{% assign email = site.social.email | split: '@' %}
|
62
|
+
{%- capture url -%}
|
63
|
+
javascript:location.href = 'mailto:' + ['{{ email[0] }}','{{ email[1] }}'].join('@')
|
64
|
+
{%- endcapture -%}
|
65
|
+
{% when 'rss' %}
|
66
|
+
{% assign url = '/feed.xml' | relative_url %}
|
67
|
+
{% else %}
|
68
|
+
{% assign url = entry.url %}
|
69
|
+
{% endcase %}
|
70
|
+
|
71
|
+
{% if url %}
|
72
|
+
<a
|
73
|
+
href="{{ url }}"
|
74
|
+
aria-label="{{ entry.type }}"
|
75
|
+
{% assign link_types = '' %}
|
76
|
+
|
77
|
+
{% unless entry.noblank %}
|
78
|
+
target="_blank"
|
79
|
+
{% assign link_types = 'noopener noreferrer' %}
|
80
|
+
{% endunless %}
|
81
|
+
|
82
|
+
{% if entry.type == 'mastodon' %}
|
83
|
+
{% assign link_types = link_types | append: ' me' | strip %}
|
84
|
+
{% endif %}
|
85
|
+
|
86
|
+
{% unless link_types == empty %}
|
87
|
+
rel="{{ link_types }}"
|
88
|
+
{% endunless %}
|
89
|
+
>
|
90
|
+
<i class="{{ entry.icon }}"></i>
|
91
|
+
</a>
|
92
|
+
{% endif %}
|
93
|
+
{% endfor %}
|
94
|
+
</div>
|
95
|
+
<!-- .sidebar-bottom -->
|
96
|
+
</aside>
|
97
|
+
<!-- #sidebar -->
|