jekyll-theme-chirpy 6.5.5 → 7.0.0

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -6
  3. data/_data/origin/basic.yml +3 -10
  4. data/_data/origin/cors.yml +17 -22
  5. data/_includes/analytics/cloudflare.html +7 -0
  6. data/_includes/analytics/goatcounter.html +6 -0
  7. data/_includes/analytics/google.html +13 -0
  8. data/_includes/analytics/matomo.html +14 -0
  9. data/_includes/analytics/umami.html +6 -0
  10. data/_includes/comments/disqus.html +5 -5
  11. data/_includes/comments/giscus.html +3 -3
  12. data/_includes/comments/utterances.html +4 -5
  13. data/_includes/comments.html +3 -3
  14. data/_includes/embed/audio.html +35 -0
  15. data/_includes/embed/bilibili.html +3 -4
  16. data/_includes/embed/video.html +59 -0
  17. data/_includes/embed/youtube.html +1 -1
  18. data/_includes/footer.html +8 -1
  19. data/_includes/head.html +21 -25
  20. data/_includes/js-selector.html +31 -37
  21. data/_includes/lang.html +3 -1
  22. data/_includes/{img-url.html → media-url.html} +8 -8
  23. data/_includes/mermaid.html +31 -27
  24. data/_includes/mode-toggle.html +24 -51
  25. data/_includes/pageviews/goatcounter.html +18 -0
  26. data/_includes/post-description.html +16 -0
  27. data/_includes/refactor-content.html +1 -1
  28. data/_includes/related-posts.html +2 -4
  29. data/_includes/search-loader.html +1 -1
  30. data/_includes/search-results.html +1 -1
  31. data/_includes/sidebar.html +2 -2
  32. data/_includes/toc.html +2 -2
  33. data/_includes/topbar.html +1 -1
  34. data/_layouts/compress.html +2 -2
  35. data/_layouts/default.html +3 -8
  36. data/_layouts/home.html +2 -5
  37. data/_layouts/post.html +17 -4
  38. data/_sass/addon/commons.scss +38 -46
  39. data/_sass/colors/typography-dark.scss +0 -4
  40. data/_sass/dist/bootstrap.css +5 -0
  41. data/_sass/layout/post.scss +23 -10
  42. data/_sass/main.bundle.scss +2 -0
  43. data/assets/css/jekyll-theme-chirpy.scss +5 -1
  44. data/assets/feed.xml +1 -8
  45. data/assets/js/data/mathjax.js +25 -0
  46. data/assets/js/data/swconf.js +0 -14
  47. data/assets/js/dist/app.min.js +4 -0
  48. data/assets/js/dist/categories.min.js +2 -2
  49. data/assets/js/dist/commons.min.js +2 -2
  50. data/assets/js/dist/home.min.js +2 -2
  51. data/assets/js/dist/misc.min.js +2 -2
  52. data/assets/js/dist/page.min.js +2 -2
  53. data/assets/js/dist/post.min.js +2 -2
  54. data/assets/js/dist/sw.min.js +5 -0
  55. metadata +22 -12
  56. data/_includes/goatcounter.html +0 -8
  57. data/_includes/google-analytics.html +0 -14
  58. data/assets/js/pwa/app.js +0 -54
  59. data/assets/js/pwa/sw.js +0 -101
@@ -1,25 +1,25 @@
1
1
  {%- comment -%}
2
- Generate image final URL based on `site.img_cdn`, `page.img_path`
2
+ Generate media resource final URL based on `site.cdn`, `page.media_subpath`
3
3
 
4
4
  Arguments:
5
- src - required, basic image path
6
- img_path - optional, relative path of image
5
+ src - required, basic media resources path
6
+ subpath - optional, relative path of media resources
7
7
  absolute - optional, boolean, if true, generate absolute URL
8
8
 
9
9
  Return:
10
- image URL
10
+ media resources URL
11
11
  {%- endcomment -%}
12
12
 
13
13
  {% assign url = include.src %}
14
14
 
15
15
  {%- if url -%}
16
16
  {% unless url contains ':' %}
17
- {%- comment -%} Add page image path prefix {%- endcomment -%}
18
- {% assign url = include.img_path | default: '' | append: '/' | append: url %}
17
+ {%- comment -%} Add media resources subpath prefix {%- endcomment -%}
18
+ {% assign url = include.subpath | default: '' | append: '/' | append: url %}
19
19
 
20
20
  {%- comment -%} Prepend CND URL {%- endcomment -%}
21
- {% if site.img_cdn %}
22
- {% assign url = site.img_cdn | append: '/' | append: url %}
21
+ {% if site.cdn %}
22
+ {% assign url = site.cdn | append: '/' | append: url %}
23
23
  {% endif %}
24
24
 
25
25
  {% assign url = url | replace: '///', '/' | replace: '//', '/' | replace: ':/', '://' %}
@@ -1,29 +1,33 @@
1
1
  <!-- mermaid-js loader -->
2
2
  <script type="text/javascript">
3
- (function () {
4
- function updateMermaid(event) {
5
- if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
6
- const mode = event.data.message;
7
-
8
- if (typeof mermaid === 'undefined') {
9
- return;
10
- }
11
-
12
- let expectedTheme = mode === ModeToggle.DARK_MODE ? 'dark' : 'default';
13
- let config = { theme: expectedTheme };
14
-
15
- /* Re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> */
16
- $('.mermaid').each(function () {
17
- let svgCode = $(this).prev().children().html();
18
- $(this).removeAttr('data-processed');
19
- $(this).html(svgCode);
20
- });
21
-
22
- mermaid.initialize(config);
23
- mermaid.init(undefined, '.mermaid');
3
+ function updateMermaid(event) {
4
+ if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
5
+ const mode = event.data.message;
6
+
7
+ if (typeof mermaid === 'undefined') {
8
+ return;
24
9
  }
10
+
11
+ let expectedTheme = mode === ModeToggle.DARK_MODE ? 'dark' : 'default';
12
+ let config = { theme: expectedTheme };
13
+
14
+ {%- comment -%}
15
+ Re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344>
16
+ {%- endcomment -%}
17
+ const mermaidList = document.getElementsByClassName('mermaid');
18
+
19
+ [...mermaidList].forEach((elem) => {
20
+ const svgCode = elem.previousSibling.children.item(0).innerHTML;
21
+ elem.innerHTML = svgCode;
22
+ elem.removeAttribute('data-processed');
23
+ });
24
+
25
+ mermaid.initialize(config);
26
+ mermaid.init(undefined, '.mermaid');
25
27
  }
28
+ }
26
29
 
30
+ (function () {
27
31
  let initTheme = 'default';
28
32
  const html = document.documentElement;
29
33
 
@@ -35,15 +39,16 @@
35
39
  }
36
40
 
37
41
  let mermaidConf = {
38
- theme: initTheme /* <default|dark|forest|neutral> */
42
+ theme: initTheme {%- comment -%} <default | dark | forest | neutral> {%- endcomment -%}
39
43
  };
40
44
 
41
- /* Create mermaid tag */
42
- document.querySelectorAll('pre>code.language-mermaid').forEach((elem) => {
45
+ {%- comment -%} Create mermaid tag {%- endcomment -%}
46
+ const basicList = document.getElementsByClassName('language-mermaid');
47
+ [...basicList].forEach((elem) => {
43
48
  const svgCode = elem.textContent;
44
49
  const backup = elem.parentElement;
45
- backup.classList.add('unloaded');
46
- /* create mermaid node */
50
+ backup.classList.add('d-none');
51
+ {%- comment -%} create mermaid node {%- endcomment -%}
47
52
  let mermaid = document.createElement('pre');
48
53
  mermaid.classList.add('mermaid');
49
54
  const text = document.createTextNode(svgCode);
@@ -52,7 +57,6 @@
52
57
  });
53
58
 
54
59
  mermaid.initialize(mermaidConf);
55
-
56
60
  window.addEventListener('message', updateMermaid);
57
61
  })();
58
62
  </script>
@@ -19,45 +19,32 @@
19
19
  }
20
20
 
21
21
  constructor() {
22
- if (this.hasMode) {
23
- if (this.isDarkMode) {
24
- if (!this.isSysDarkPrefer) {
25
- this.setDark();
26
- }
27
- } else {
28
- if (this.isSysDarkPrefer) {
29
- this.setLight();
30
- }
31
- }
32
- }
33
-
34
22
  let self = this;
35
23
 
36
- /* always follow the system prefers */
24
+ {%- comment -%} always follow the system prefers {%- endcomment -%}
37
25
  this.sysDarkPrefers.addEventListener('change', () => {
38
26
  if (self.hasMode) {
39
- if (self.isDarkMode) {
40
- if (!self.isSysDarkPrefer) {
41
- self.setDark();
42
- }
43
- } else {
44
- if (self.isSysDarkPrefer) {
45
- self.setLight();
46
- }
47
- }
48
-
49
27
  self.clearMode();
50
28
  }
51
-
52
29
  self.notify();
53
30
  });
54
- } /* constructor() */
31
+
32
+ if (!this.hasMode) {
33
+ return;
34
+ }
35
+
36
+ if (this.isDarkMode) {
37
+ this.setDark();
38
+ } else {
39
+ this.setLight();
40
+ }
41
+ }
55
42
 
56
43
  get sysDarkPrefers() {
57
44
  return window.matchMedia('(prefers-color-scheme: dark)');
58
45
  }
59
46
 
60
- get isSysDarkPrefer() {
47
+ get isPreferDark() {
61
48
  return this.sysDarkPrefers.matches;
62
49
  }
63
50
 
@@ -65,10 +52,6 @@
65
52
  return this.mode === ModeToggle.DARK_MODE;
66
53
  }
67
54
 
68
- get isLightMode() {
69
- return this.mode === ModeToggle.LIGHT_MODE;
70
- }
71
-
72
55
  get hasMode() {
73
56
  return this.mode != null;
74
57
  }
@@ -77,12 +60,12 @@
77
60
  return sessionStorage.getItem(ModeToggle.MODE_KEY);
78
61
  }
79
62
 
80
- /* get the current mode on screen */
63
+ {%- comment -%} get the current mode on screen {%- endcomment -%}
81
64
  get modeStatus() {
82
- if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) {
83
- return ModeToggle.DARK_MODE;
65
+ if (this.hasMode) {
66
+ return this.mode;
84
67
  } else {
85
- return ModeToggle.LIGHT_MODE;
68
+ return this.isPreferDark ? ModeToggle.DARK_MODE : ModeToggle.LIGHT_MODE;
86
69
  }
87
70
  }
88
71
 
@@ -101,7 +84,9 @@
101
84
  sessionStorage.removeItem(ModeToggle.MODE_KEY);
102
85
  }
103
86
 
104
- /* Notify another plugins that the theme mode has changed */
87
+ {%- comment -%}
88
+ Notify another plugins that the theme mode has changed
89
+ {%- endcomment -%}
105
90
  notify() {
106
91
  window.postMessage(
107
92
  {
@@ -114,21 +99,9 @@
114
99
 
115
100
  flipMode() {
116
101
  if (this.hasMode) {
117
- if (this.isSysDarkPrefer) {
118
- if (this.isLightMode) {
119
- this.clearMode();
120
- } else {
121
- this.setLight();
122
- }
123
- } else {
124
- if (this.isDarkMode) {
125
- this.clearMode();
126
- } else {
127
- this.setDark();
128
- }
129
- }
102
+ this.clearMode();
130
103
  } else {
131
- if (this.isSysDarkPrefer) {
104
+ if (this.isPreferDark) {
132
105
  this.setLight();
133
106
  } else {
134
107
  this.setDark();
@@ -136,8 +109,8 @@
136
109
  }
137
110
 
138
111
  this.notify();
139
- } /* flipMode() */
140
- } /* ModeToggle */
112
+ }
113
+ }
141
114
 
142
115
  const modeToggle = new ModeToggle();
143
116
  </script>
@@ -0,0 +1,18 @@
1
+ <!-- Display GoatCounter pageviews -->
2
+ <script>
3
+ let pv = document.getElementById('pageviews');
4
+
5
+ if (pv !== null) {
6
+ const uri = location.pathname.replace(/\/$/, '');
7
+ const url = `https://{{ site.analytics.goatcounter.id }}.goatcounter.com/counter/${encodeURIComponent(uri)}.json`;
8
+
9
+ fetch(url)
10
+ .then((response) => response.json())
11
+ .then((data) => {
12
+ pv.innerText = new Intl.NumberFormat().format(data.count);
13
+ })
14
+ .catch((error) => {
15
+ pv.innerText = '1';
16
+ });
17
+ }
18
+ </script>
@@ -0,0 +1,16 @@
1
+ {%- comment -%}
2
+ Get post description or generate it from the post content.
3
+ {%- endcomment -%}
4
+
5
+ {%- assign max_length = include.max_length | default: 200 -%}
6
+
7
+ {%- capture description -%}
8
+ {%- if post.description -%}
9
+ {{- post.description -}}
10
+ {%- else -%}
11
+ {%- include no-linenos.html content=post.content -%}
12
+ {{- content | markdownify | strip_html -}}
13
+ {%- endif -%}
14
+ {%- endcapture -%}
15
+
16
+ {{- description | strip | truncate: max_length | escape -}}
@@ -97,7 +97,7 @@
97
97
  {% assign _lazyload = true %}
98
98
 
99
99
  {%- capture _img_url -%}
100
- {% include img-url.html src=_src img_path=page.img_path %}
100
+ {% include media-url.html src=_src subpath=page.media_subpath %}
101
101
  {%- endcapture -%}
102
102
 
103
103
  {% assign _path_prefix = _img_url | remove: _src %}
@@ -21,6 +21,7 @@
21
21
  {% assign match_posts = match_posts | push: site.tags[tag] | uniq %}
22
22
  {% endfor %}
23
23
 
24
+ {% assign match_posts = match_posts | reverse %}
24
25
  {% assign last_index = match_posts.size | minus: 1 %}
25
26
  {% assign score_list = '' | split: '' %}
26
27
 
@@ -81,10 +82,7 @@
81
82
  {% include datetime.html date=post.date lang=include.lang %}
82
83
  <h4 class="pt-0 my-2">{{ post.title }}</h4>
83
84
  <div class="text-muted">
84
- <p>
85
- {% include no-linenos.html content=post.content %}
86
- {{ content | markdownify | strip_html | truncate: 200 | escape }}
87
- </p>
85
+ <p>{% include post-description.html %}</p>
88
86
  </div>
89
87
  </div>
90
88
  </a>
@@ -19,7 +19,7 @@
19
19
  {% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
20
20
 
21
21
  <script>
22
- /* Note: dependent library will be loaded in `js-selector.html` */
22
+ {%- comment -%} Note: dependent library will be loaded in `js-selector.html` {%- endcomment -%}
23
23
  SimpleJekyllSearch({
24
24
  searchInput: document.getElementById('search-input'),
25
25
  resultsContainer: document.getElementById('search-results'),
@@ -1,6 +1,6 @@
1
1
  <!-- The Search results -->
2
2
 
3
- <div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
3
+ <div id="search-result-wrapper" class="d-flex justify-content-center d-none">
4
4
  <div class="col-11 content">
5
5
  <div id="search-hints">
6
6
  {% include_cached trending-tags.html %}
@@ -5,7 +5,7 @@
5
5
  <a href="{{ '/' | relative_url }}" id="avatar" class="rounded-circle">
6
6
  {%- if site.avatar != empty and site.avatar -%}
7
7
  {%- capture avatar_url -%}
8
- {% include img-url.html src=site.avatar %}
8
+ {% include media-url.html src=site.avatar %}
9
9
  {%- endcapture -%}
10
10
  <img src="{{- avatar_url -}}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
11
11
  {%- endif -%}
@@ -44,7 +44,7 @@
44
44
 
45
45
  <div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
46
46
  {% unless site.theme_mode %}
47
- <button type="button" class="mode-toggle btn" aria-label="Switch Mode">
47
+ <button type="button" class="btn btn-link nav-link" aria-label="Switch Mode" id="mode-toggle">
48
48
  <i class="fas fa-adjust"></i>
49
49
  </button>
50
50
 
data/_includes/toc.html CHANGED
@@ -6,8 +6,8 @@
6
6
  {% endif %}
7
7
 
8
8
  {% if enable_toc %}
9
- <section id="toc-wrapper" class="ps-0 pe-4">
10
- <h2 class="panel-heading ps-3 pt-2 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
9
+ <section id="toc-wrapper" class="d-none ps-0 pe-4">
10
+ <h2 class="panel-heading ps-3 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
11
11
  <nav id="toc"></nav>
12
12
  </section>
13
13
  {% endif %}
@@ -59,7 +59,7 @@
59
59
  <i class="fas fa-search fa-fw"></i>
60
60
  </button>
61
61
 
62
- <search class="align-items-center ms-3 ms-lg-0">
62
+ <search id="search" class="align-items-center ms-3 ms-lg-0">
63
63
  <i class="fas fa-search fa-fw"></i>
64
64
  <input
65
65
  class="form-control"
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  # Jekyll layout that compresses HTML
3
- # v3.1.0
3
+ # v3.2.0
4
4
  # http://jch.penibelst.de/
5
5
  # © 2014–2015 Anatol Broder
6
6
  # MIT License
7
7
  ---
8
8
 
9
9
  {% capture _LINE_FEED %}
10
- {% 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 %}
10
+ {% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment or site.compress_html.ignore.envs == "all" or page.compress_html == false %}{{ 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 %}
@@ -13,7 +13,7 @@ layout: compress
13
13
  {% endif %}
14
14
 
15
15
  <!-- `site.alt_lang` can specify a language different from the UI -->
16
- <html lang="{{ site.alt_lang | default: site.lang }}" {{ prefer_mode }}>
16
+ <html lang="{{ page.lang | default: site.alt_lang | default: site.lang }}" {{ prefer_mode }}>
17
17
  {% include head.html %}
18
18
 
19
19
  <body>
@@ -75,13 +75,8 @@ layout: compress
75
75
  {% endif %}
76
76
 
77
77
  <!-- JavaScripts -->
78
+ {% include js-selector.html lang=lang %}
78
79
 
79
- {% include js-selector.html %}
80
-
81
- {% if page.mermaid %}
82
- {% include mermaid.html %}
83
- {% endif %}
84
-
85
- {% include_cached search-loader.html %}
80
+ {% include_cached search-loader.html lang=lang %}
86
81
  </body>
87
82
  </html>
data/_layouts/home.html CHANGED
@@ -49,7 +49,7 @@ refactor: true
49
49
  {% if post.image %}
50
50
  {% assign src = post.image.path | default: post.image %}
51
51
  {% unless src contains '//' %}
52
- {% assign src = post.img_path | append: '/' | append: src | replace: '//', '/' %}
52
+ {% assign src = post.media_subpath | append: '/' | append: src | replace: '//', '/' %}
53
53
  {% endunless %}
54
54
 
55
55
  {% assign alt = post.image.alt | xml_escape | default: 'Preview Image' %}
@@ -72,10 +72,7 @@ refactor: true
72
72
  <h1 class="card-title my-2 mt-md-0">{{ post.title }}</h1>
73
73
 
74
74
  <div class="card-text content mt-0 mb-3">
75
- <p>
76
- {% include no-linenos.html content=post.content %}
77
- {{ content | markdownify | strip_html | truncate: 200 | escape }}
78
- </p>
75
+ <p>{% include post-description.html %}</p>
79
76
  </div>
80
77
 
81
78
  <div class="post-meta flex-grow-1 d-flex align-items-end">
data/_layouts/post.html CHANGED
@@ -14,6 +14,9 @@ tail_includes:
14
14
  <article class="px-1">
15
15
  <header>
16
16
  <h1 data-toc-skip>{{ page.title }}</h1>
17
+ {% if page.description %}
18
+ <p class="post-desc fw-light mb-4">{{ page.description }}</p>
19
+ {% endif %}
17
20
 
18
21
  <div class="post-meta text-muted">
19
22
  <!-- published date -->
@@ -74,12 +77,22 @@ tail_includes:
74
77
  </em>
75
78
  </span>
76
79
 
77
- <!-- read time -->
78
- {% include read-time.html content=content prompt=true lang=lang %}
80
+ <div>
81
+ <!-- pageviews -->
82
+ {% if site.pageviews.provider and site.analytics[site.pageviews.provider].id %}
83
+ <span>
84
+ <em id="pageviews">
85
+ <i class="fas fa-spinner fa-spin small"></i>
86
+ </em>
87
+ {{ site.data.locales[lang].post.pageview_measure }}
88
+ </span>
89
+ {% endif %}
90
+
91
+ <!-- read time -->
92
+ {% include read-time.html content=content prompt=true lang=lang %}
93
+ </div>
79
94
  </div>
80
- <!-- .d-flex -->
81
95
  </div>
82
- <!-- .post-meta -->
83
96
  </header>
84
97
 
85
98
  <div class="content">
@@ -129,6 +129,11 @@ kbd {
129
129
  box-shadow: inset 0 -2px 0 var(--kbd-wrap-color);
130
130
  }
131
131
 
132
+ hr {
133
+ border-color: var(--main-border-color);
134
+ opacity: 1;
135
+ }
136
+
132
137
  footer {
133
138
  background-color: var(--main-bg);
134
139
  height: $footer-height;
@@ -364,7 +369,6 @@ main {
364
369
 
365
370
  h1 {
366
371
  margin-top: 2rem;
367
- margin-bottom: 1.5rem;
368
372
  }
369
373
 
370
374
  p {
@@ -550,17 +554,32 @@ main {
550
554
  width: 100%;
551
555
  height: 100%;
552
556
  margin-bottom: 1rem;
557
+ aspect-ratio: 16 / 9;
553
558
 
554
559
  @extend %rounded;
555
560
 
556
- &.youtube,
557
- &.bilibili {
558
- aspect-ratio: 16 / 9;
559
- }
560
-
561
561
  &.twitch {
562
562
  aspect-ratio: 310 / 189;
563
563
  }
564
+
565
+ &.file {
566
+ display: block;
567
+ width: auto;
568
+ height: auto;
569
+ max-width: 100%;
570
+ max-height: 100%;
571
+ margin: auto;
572
+ margin-bottom: 0;
573
+ }
574
+
575
+ @extend %img-caption;
576
+ }
577
+
578
+ .embed-audio {
579
+ width: 100%;
580
+ display: block;
581
+
582
+ @extend %img-caption;
564
583
  }
565
584
 
566
585
  /* --- buttons --- */
@@ -577,26 +596,6 @@ main {
577
596
 
578
597
  /* --- Effects classes --- */
579
598
 
580
- .loaded {
581
- display: block !important;
582
-
583
- @at-root .d-flex#{&} {
584
- display: flex !important;
585
- }
586
- }
587
-
588
- .unloaded {
589
- display: none !important;
590
- }
591
-
592
- .visible {
593
- visibility: visible !important;
594
- }
595
-
596
- .hidden {
597
- visibility: hidden !important;
598
- }
599
-
600
599
  .flex-grow-1 {
601
600
  flex-grow: 1 !important;
602
601
  }
@@ -653,18 +652,6 @@ main {
653
652
 
654
653
  /* --- Overriding --- */
655
654
 
656
- /* magnific-popup */
657
-
658
- figure .mfp-title {
659
- text-align: center;
660
- padding-right: 0;
661
- margin-top: 0.5rem;
662
- }
663
-
664
- .mfp-img {
665
- transition: none;
666
- }
667
-
668
655
  /* mermaid */
669
656
  .mermaid {
670
657
  text-align: center;
@@ -836,7 +823,10 @@ $btn-mb: 0.5rem;
836
823
  display: flex;
837
824
  align-items: center;
838
825
  justify-content: center;
839
- box-shadow: var(--sidebar-border-color) 0 0 0 1px;
826
+
827
+ &:not(:focus-visible) {
828
+ box-shadow: var(--sidebar-border-color) 0 0 0 1px;
829
+ }
840
830
 
841
831
  &:hover {
842
832
  background-color: var(--sidebar-hover-bg);
@@ -857,10 +847,7 @@ $btn-mb: 0.5rem;
857
847
  line-height: $btn-size;
858
848
  }
859
849
 
860
- .mode-toggle {
861
- padding: 0;
862
- border: 0;
863
-
850
+ #mode-toggle {
864
851
  @extend %button;
865
852
  @extend %sidebar-links;
866
853
  @extend %sidebar-link-hover;
@@ -1139,7 +1126,8 @@ search {
1139
1126
  /* --- button back-to-top --- */
1140
1127
 
1141
1128
  #back-to-top {
1142
- display: none;
1129
+ visibility: hidden;
1130
+ opacity: 0;
1143
1131
  z-index: 1;
1144
1132
  cursor: pointer;
1145
1133
  position: fixed;
@@ -1152,8 +1140,7 @@ search {
1152
1140
  height: $back2top-size;
1153
1141
  border-radius: 50%;
1154
1142
  border: 1px solid var(--btn-backtotop-border-color);
1155
- transition: transform 0.2s ease-out;
1156
- -webkit-transition: transform 0.2s ease-out;
1143
+ transition: opacity 0.5s ease-in-out, transform 0.2s ease-out;
1157
1144
 
1158
1145
  &:hover {
1159
1146
  transform: translate3d(0, -5px, 0);
@@ -1165,6 +1152,11 @@ search {
1165
1152
  position: relative;
1166
1153
  bottom: 2px;
1167
1154
  }
1155
+
1156
+ &.show {
1157
+ opacity: 1;
1158
+ visibility: visible;
1159
+ }
1168
1160
  }
1169
1161
 
1170
1162
  #notification {
@@ -104,10 +104,6 @@
104
104
  display: none;
105
105
  }
106
106
 
107
- hr {
108
- border-color: var(--main-border-color);
109
- }
110
-
111
107
  /* categories */
112
108
  .categories.card,
113
109
  .list-group-item {