custom-chirpy 5.5.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.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +97 -0
  4. data/_data/assets/cross_origin.yml +62 -0
  5. data/_data/assets/self_host.yml +51 -0
  6. data/_data/authors.yml +17 -0
  7. data/_data/contact.yml +29 -0
  8. data/_data/locales/ar.yml +93 -0
  9. data/_data/locales/bg-BG.yml +83 -0
  10. data/_data/locales/cs-CZ.yml +91 -0
  11. data/_data/locales/de-DE.yml +82 -0
  12. data/_data/locales/el-GR.yml +93 -0
  13. data/_data/locales/en.yml +93 -0
  14. data/_data/locales/es-ES.yml +79 -0
  15. data/_data/locales/fi-FI.yml +92 -0
  16. data/_data/locales/fr-FR.yml +79 -0
  17. data/_data/locales/hu-HU.yml +81 -0
  18. data/_data/locales/id-ID.yml +79 -0
  19. data/_data/locales/it-IT.yml +93 -0
  20. data/_data/locales/ko-KR.yml +86 -0
  21. data/_data/locales/my-MM.yml +79 -0
  22. data/_data/locales/pt-BR.yml +79 -0
  23. data/_data/locales/ru-RU.yml +79 -0
  24. data/_data/locales/tr-TR.yml +79 -0
  25. data/_data/locales/uk-UA.yml +79 -0
  26. data/_data/locales/vi-VN.yml +77 -0
  27. data/_data/locales/zh-CN.yml +85 -0
  28. data/_data/share.yml +25 -0
  29. data/_includes/assets-origin.html +12 -0
  30. data/_includes/comments/disqus.html +54 -0
  31. data/_includes/comments/giscus.html +56 -0
  32. data/_includes/comments/utterances.html +51 -0
  33. data/_includes/comments.html +5 -0
  34. data/_includes/datetime.html +15 -0
  35. data/_includes/embed/twitch.html +4 -0
  36. data/_includes/embed/youtube.html +6 -0
  37. data/_includes/favicons.html +17 -0
  38. data/_includes/footer.html +36 -0
  39. data/_includes/google-analytics.html +14 -0
  40. data/_includes/head.html +115 -0
  41. data/_includes/js-selector.html +99 -0
  42. data/_includes/jsdelivr-combine.html +32 -0
  43. data/_includes/language-alias.html +70 -0
  44. data/_includes/mermaid.html +59 -0
  45. data/_includes/mode-toggle.html +129 -0
  46. data/_includes/no-linenos.html +10 -0
  47. data/_includes/post-nav.html +30 -0
  48. data/_includes/post-paginator.html +88 -0
  49. data/_includes/post-sharing.html +27 -0
  50. data/_includes/read-time.html +30 -0
  51. data/_includes/refactor-content.html +282 -0
  52. data/_includes/related-posts.html +103 -0
  53. data/_includes/search-loader.html +46 -0
  54. data/_includes/search-results.html +11 -0
  55. data/_includes/sidebar.html +106 -0
  56. data/_includes/toc.html +16 -0
  57. data/_includes/topbar.html +70 -0
  58. data/_includes/trending-tags.html +50 -0
  59. data/_includes/update-list.html +40 -0
  60. data/_layouts/archives.html +34 -0
  61. data/_layouts/categories.html +118 -0
  62. data/_layouts/category.html +22 -0
  63. data/_layouts/compress.html +10 -0
  64. data/_layouts/default.html +71 -0
  65. data/_layouts/home.html +94 -0
  66. data/_layouts/page.html +63 -0
  67. data/_layouts/post.html +141 -0
  68. data/_layouts/tag.html +21 -0
  69. data/_layouts/tags.html +23 -0
  70. data/_sass/addon/commons.scss +1731 -0
  71. data/_sass/addon/module.scss +163 -0
  72. data/_sass/addon/syntax.scss +275 -0
  73. data/_sass/addon/variables.scss +30 -0
  74. data/_sass/colors/dark-syntax.scss +87 -0
  75. data/_sass/colors/dark-typography.scss +170 -0
  76. data/_sass/colors/light-syntax.scss +83 -0
  77. data/_sass/colors/light-typography.scss +104 -0
  78. data/_sass/jekyll-theme-chirpy.scss +24 -0
  79. data/_sass/layout/archives.scss +136 -0
  80. data/_sass/layout/categories.scss +66 -0
  81. data/_sass/layout/category-tag.scss +73 -0
  82. data/_sass/layout/home.scss +178 -0
  83. data/_sass/layout/post.scss +378 -0
  84. data/_sass/layout/tags.scss +19 -0
  85. data/_sass/variables-hook.scss +3 -0
  86. data/assets/404.html +14 -0
  87. data/assets/css/style.scss +12 -0
  88. data/assets/feed.xml +61 -0
  89. data/assets/img/favicons/android-chrome-192x192.png +0 -0
  90. data/assets/img/favicons/android-chrome-512x512.png +0 -0
  91. data/assets/img/favicons/apple-touch-icon.png +0 -0
  92. data/assets/img/favicons/browserconfig.xml +13 -0
  93. data/assets/img/favicons/favicon-16x16.png +0 -0
  94. data/assets/img/favicons/favicon-32x32.png +0 -0
  95. data/assets/img/favicons/favicon.ico +0 -0
  96. data/assets/img/favicons/mstile-150x150.png +0 -0
  97. data/assets/img/favicons/site.webmanifest +26 -0
  98. data/assets/js/data/search.json +20 -0
  99. data/assets/js/data/swcache.js +54 -0
  100. data/assets/js/dist/categories.min.js +6 -0
  101. data/assets/js/dist/commons.min.js +6 -0
  102. data/assets/js/dist/home.min.js +6 -0
  103. data/assets/js/dist/misc.min.js +6 -0
  104. data/assets/js/dist/page.min.js +6 -0
  105. data/assets/js/dist/post.min.js +6 -0
  106. data/assets/js/dist/pvreport.min.js +6 -0
  107. data/assets/js/pwa/app.js +47 -0
  108. data/assets/js/pwa/sw.js +90 -0
  109. data/assets/js/pwa/unregister.js +12 -0
  110. data/assets/robots.txt +10 -0
  111. metadata +236 -0
@@ -0,0 +1,129 @@
1
+ <!--
2
+ Switch the mode between dark and light.
3
+ -->
4
+
5
+ <script type="text/javascript">
6
+ class ModeToggle {
7
+ static get MODE_KEY() { return "mode"; }
8
+ static get MODE_ATTR() { return "data-mode"; }
9
+ static get DARK_MODE() { return "dark"; }
10
+ static get LIGHT_MODE() { return "light"; }
11
+ static get ID() { return "mode-toggle"; }
12
+
13
+ constructor() {
14
+ if (this.hasMode) {
15
+ if (this.isDarkMode) {
16
+ if (!this.isSysDarkPrefer) {
17
+ this.setDark();
18
+ }
19
+ } else {
20
+ if (this.isSysDarkPrefer) {
21
+ this.setLight();
22
+ }
23
+ }
24
+ }
25
+
26
+ let self = this;
27
+
28
+ /* always follow the system prefers */
29
+ this.sysDarkPrefers.addEventListener("change", () => {
30
+ if (self.hasMode) {
31
+ if (self.isDarkMode) {
32
+ if (!self.isSysDarkPrefer) {
33
+ self.setDark();
34
+ }
35
+
36
+ } else {
37
+ if (self.isSysDarkPrefer) {
38
+ self.setLight();
39
+ }
40
+ }
41
+
42
+ self.clearMode();
43
+ }
44
+
45
+ self.notify();
46
+
47
+ });
48
+
49
+ } /* constructor() */
50
+
51
+ get sysDarkPrefers() { return window.matchMedia("(prefers-color-scheme: dark)"); }
52
+
53
+ get isSysDarkPrefer() { return this.sysDarkPrefers.matches; }
54
+
55
+ get isDarkMode() { return this.mode === ModeToggle.DARK_MODE; }
56
+
57
+ get isLightMode() { return this.mode === ModeToggle.LIGHT_MODE; }
58
+
59
+ get hasMode() { return this.mode != null; }
60
+
61
+ get mode() { return sessionStorage.getItem(ModeToggle.MODE_KEY); }
62
+
63
+ /* get the current mode on screen */
64
+ get modeStatus() {
65
+ if (this.isDarkMode
66
+ || (!this.hasMode && this.isSysDarkPrefer)) {
67
+ return ModeToggle.DARK_MODE;
68
+ } else {
69
+ return ModeToggle.LIGHT_MODE;
70
+ }
71
+ }
72
+
73
+ setDark() {
74
+ $('html').attr(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
75
+ sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
76
+ }
77
+
78
+ setLight() {
79
+ $('html').attr(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
80
+ sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
81
+ }
82
+
83
+ clearMode() {
84
+ $('html').removeAttr(ModeToggle.MODE_ATTR);
85
+ sessionStorage.removeItem(ModeToggle.MODE_KEY);
86
+ }
87
+
88
+ /* Notify another plugins that the theme mode has changed */
89
+ notify() {
90
+ window.postMessage({
91
+ direction: ModeToggle.ID,
92
+ message: this.modeStatus
93
+ }, "*");
94
+ }
95
+
96
+ } /* ModeToggle */
97
+
98
+ const toggle = new ModeToggle();
99
+
100
+ function flipMode() {
101
+ if (toggle.hasMode) {
102
+ if (toggle.isSysDarkPrefer) {
103
+ if (toggle.isLightMode) {
104
+ toggle.clearMode();
105
+ } else {
106
+ toggle.setLight();
107
+ }
108
+
109
+ } else {
110
+ if (toggle.isDarkMode) {
111
+ toggle.clearMode();
112
+ } else {
113
+ toggle.setDark();
114
+ }
115
+ }
116
+
117
+ } else {
118
+ if (toggle.isSysDarkPrefer) {
119
+ toggle.setLight();
120
+ } else {
121
+ toggle.setDark();
122
+ }
123
+ }
124
+
125
+ toggle.notify();
126
+
127
+ } /* flipMode() */
128
+
129
+ </script>
@@ -0,0 +1,10 @@
1
+ {% comment %}
2
+ Remove the line number of the code snippet.
3
+ {% endcomment %}
4
+
5
+ {% assign content = include.content %}
6
+
7
+ {% if content contains '<td class="rouge-gutter gl"><pre class="lineno">' %}
8
+ {% assign content = content | replace: '<td class="rouge-gutter gl"><pre class="lineno">', '<!-- <td class="rouge-gutter gl"><pre class="lineno">'%}
9
+ {% assign content = content | replace: '</td><td class="rouge-code">', '</td> --><td class="rouge-code">' %}
10
+ {% endif %}
@@ -0,0 +1,30 @@
1
+ <!--
2
+ Navigation buttons at the bottom of the post.
3
+ -->
4
+
5
+ <div class="post-navigation d-flex justify-content-between">
6
+ {% if page.previous.url %}
7
+ <a href="{{ site.baseurl }}{{ page.previous.url }}" class="btn btn-outline-primary"
8
+ prompt="{{ site.data.locales[site.lang].post.button.previous }}">
9
+ <p>{{ page.previous.title }}</p>
10
+ </a>
11
+ {% else %}
12
+ <div class="btn btn-outline-primary disabled"
13
+ prompt="{{ site.data.locales[site.lang].post.button.previous }}">
14
+ <p>-</p>
15
+ </div>
16
+ {% endif %}
17
+
18
+ {% if page.next.url %}
19
+ <a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary"
20
+ prompt="{{ site.data.locales[site.lang].post.button.next }}">
21
+ <p>{{ page.next.title }}</p>
22
+ </a>
23
+ {% else %}
24
+ <div class="btn btn-outline-primary disabled"
25
+ prompt="{{ site.data.locales[site.lang].post.button.next }}">
26
+ <p>-</p>
27
+ </div>
28
+ {% endif %}
29
+
30
+ </div>
@@ -0,0 +1,88 @@
1
+ <!--
2
+ The paginator for post list on HomgPage.
3
+ -->
4
+
5
+ <ul class="pagination align-items-center mt-4 pl-lg-2">
6
+ <!-- left arrow -->
7
+ {% if paginator.previous_page %}
8
+ {% assign prev_url = paginator.previous_page_path | relative_url %}
9
+ {% else %}
10
+ {% assign prev_url = "#" %}
11
+ {% endif %}
12
+
13
+ <li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
14
+ <a class="page-link btn-box-shadow" href="{{ prev_url }}" aria-label="previous-page">
15
+ <i class="fas fa-angle-left"></i>
16
+ </a>
17
+ </li>
18
+
19
+ <!-- page numbers -->
20
+ {% assign left_ellipsis = false %}
21
+ {% assign right_ellipsis = false %}
22
+
23
+ {% for i in (1..paginator.total_pages) %}
24
+
25
+ {% assign pre = paginator.page | minus: 1 %}
26
+ {% assign next = paginator.page | plus: 1 %}
27
+ {% assign pre_less = pre | minus: 1 %}
28
+ {% assign next_more = next | plus: 1 %}
29
+ {% assign show = false %}
30
+
31
+ {% if paginator.page == 1 %}
32
+ {% if i <= 3 or i == paginator.total_pages %}
33
+ {% assign show = true %}
34
+ {% endif %}
35
+ {% elsif paginator.page == paginator.total_pages %}
36
+ {% if i == 1 or i >= pre_less %}
37
+ {% assign show = true %}
38
+ {% endif %}
39
+ {% else %}
40
+ {% if i == 1 or i == paginator.total_pages%}
41
+ {% assign show = true %}
42
+ {% elsif i >= pre and i <= next %}
43
+ {% assign show = true %}
44
+ {% endif %}
45
+ {% endif %}
46
+
47
+ {% if show %}
48
+ <!-- show number -->
49
+ <li class="page-item {% if i == paginator.page %} active{% endif %}">
50
+ <a class="page-link btn-box-shadow" href="{% if i > 1 %}{{ site.paginate_path | replace: ':num', i | relative_url }}{% else %}{{ '/' | relative_url }}{% endif %}">{{ i }}</a>
51
+ </li>
52
+ {% else %}
53
+ <!-- hide number -->
54
+ {% if i < pre and left_ellipsis == false %}
55
+ <li class="page-item disabled">
56
+ <span class="page-link btn-box-shadow">...</span>
57
+ </li>
58
+ {% assign left_ellipsis = true %}
59
+ {% elsif i > next and right_ellipsis == false %}
60
+ <li class="page-item disabled">
61
+ <span class="page-link btn-box-shadow">...</span>
62
+ </li>
63
+ {% assign right_ellipsis = true %}
64
+ {% endif %}
65
+ {% endif %}
66
+
67
+ {% endfor %}
68
+
69
+ <!-- mobile pagination -->
70
+ <li class="page-index align-middle">
71
+ <span>{{ paginator.page }}</span>
72
+ <span class="text-muted">/ {{ paginator.total_pages }}</span>
73
+ </li>
74
+
75
+ <!-- right arrow -->
76
+ {% if paginator.next_page_path %}
77
+ {% assign next_url = paginator.next_page_path | relative_url %}
78
+ {% else %}
79
+ {% assign next_url = "#" %}
80
+ {% endif %}
81
+
82
+ <li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
83
+ <a class="page-link btn-box-shadow" href="{{ next_url }}" aria-label="next-page">
84
+ <i class="fas fa-angle-right"></i>
85
+ </a>
86
+ </li>
87
+
88
+ </ul> <!-- .pagination -->
@@ -0,0 +1,27 @@
1
+ <!--
2
+ Post sharing snippet
3
+ -->
4
+
5
+ <div class="share-wrapper">
6
+ <span class="share-label text-muted mr-1">{{ site.data.locales[site.lang].post.share }}</span>
7
+ <span class="share-icons">
8
+ {% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
9
+ {% assign title = title | uri_escape %}
10
+ {% assign url = page.url | absolute_url | url_encode %}
11
+
12
+ {% for share in site.data.share.platforms %}
13
+ {% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url %}
14
+ <a href="{{ link }}" data-toggle="tooltip" data-placement="top"
15
+ title="{{ share.type }}" target="_blank" rel="noopener" aria-label="{{ share.type }}">
16
+ <i class="fa-fw {{ share.icon }}"></i>
17
+ </a>
18
+ {% endfor %}
19
+
20
+ <i id="copy-link" class="fa-fw fas fa-link small"
21
+ data-toggle="tooltip" data-placement="top"
22
+ title="{{ site.data.locales[site.lang].post.button.share_link.title }}"
23
+ data-title-succeed="{{ site.data.locales[site.lang].post.button.share_link.succeed }}">
24
+ </i>
25
+
26
+ </span>
27
+ </div>
@@ -0,0 +1,30 @@
1
+ <!--
2
+ Calculate the post's reading time, and display the word count in tooltip
3
+ -->
4
+
5
+ {% assign words = include.content | strip_html | number_of_words: "auto" %}
6
+
7
+ <!-- words per minute -->
8
+
9
+ {% assign wpm = 180 %}
10
+ {% assign min_time = 1 %}
11
+
12
+ {% assign read_time = words | divided_by: wpm %}
13
+
14
+ {% unless read_time > 0 %}
15
+ {% assign read_time = min_time %}
16
+ {% endunless %}
17
+
18
+ {% capture read_prompt %}
19
+ {{- site.data.locales[site.lang].post.read_time.prompt -}}
20
+ {% endcapture %}
21
+
22
+ <!-- return element -->
23
+ <span class="readtime" data-toggle="tooltip" data-placement="bottom"
24
+ title="{{ words }} {{ site.data.locales[site.lang].post.words }}">
25
+ <em>{{- read_time -}}{{" "}}{{- site.data.locales[site.lang].post.read_time.unit -}}</em>
26
+ {%- if include.prompt -%}
27
+ {%- assign _prompt_words = read_prompt | number_of_words: 'auto' -%}
28
+ {%- unless _prompt_words > 1 -%}{{ " " }}{%- endunless -%}{{ read_prompt }}
29
+ {%- endif -%}
30
+ </span>
@@ -0,0 +1,282 @@
1
+ <!--
2
+ Refactor the HTML structure.
3
+ -->
4
+
5
+ {% assign _content = include.content %}
6
+
7
+ <!--
8
+ In order to allow a wide table to scroll horizontally,
9
+ we suround the markdown table with `<div class="table-wrapper">` and `</div>`
10
+ -->
11
+
12
+ {% if _content contains '<table' %}
13
+ {% assign _content = _content
14
+ | replace: '<table', '<div class="table-wrapper"><table'
15
+ | replace: '</table>', '</table></div>'
16
+ | replace: '<code><div class="table-wrapper">', '<code>'
17
+ | replace: '</table></div></code>', '</table></code>'
18
+ %}
19
+ {% endif %}
20
+
21
+ <!--
22
+ Fixed kramdown code highlight rendering:
23
+ https://github.com/penibelst/jekyll-compress-html/issues/101
24
+ https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
25
+ -->
26
+
27
+ {% if _content contains '<pre class="highlight">' %}
28
+ {% assign _content = _content
29
+ | replace: '<div class="highlight"><pre class="highlight"><code', '<div class="highlight"><code'
30
+ | replace: '</code></pre></div>', '</code></div>'
31
+ %}
32
+ {% endif %}
33
+
34
+ <!-- Change the icon of checkbox -->
35
+ {% if _content contains '<input type="checkbox"' %}
36
+ {% assign _content = _content
37
+ | replace:
38
+ '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />',
39
+ '<i class="fas fa-check-circle fa-fw checked"></i>'
40
+ | replace:
41
+ '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />',
42
+ '<i class="far fa-circle fa-fw"></i>'
43
+ %}
44
+ {% endif %}
45
+
46
+ <!-- images -->
47
+
48
+ {% assign IMG_TAG = '<img ' %}
49
+
50
+ {% if _content contains IMG_TAG %}
51
+ {% assign _img_content = nil %}
52
+ {% assign _img_snippets = _content | split: IMG_TAG %}
53
+
54
+ <!-- CDN URL -->
55
+ {% if site.img_cdn %}
56
+ {% if site.img_cdn contains '//' %}
57
+ {% assign _path_prefix = site.img_cdn %}
58
+ {% else %}
59
+ {% assign _path_prefix = site.img_cdn | relative_url %}
60
+ {% endif %}
61
+ {% else %}
62
+ {% assign _path_prefix = site.baseurl %}
63
+ {% endif %}
64
+
65
+ <!-- Add image path -->
66
+ {% if page.img_path %}
67
+ {% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
68
+ {% assign _path_prefix = _path_prefix | append: _path %}
69
+ {% endif %}
70
+
71
+ {% for _img_snippet in _img_snippets %}
72
+ {% if forloop.first %}
73
+ {% assign _img_content = _img_snippet %}
74
+ {% continue %}
75
+ {% endif %}
76
+
77
+ {% assign _left = _img_snippet | split: '>' | first %}
78
+ {% assign _right = _img_snippet | remove: _left %}
79
+
80
+ {% unless _left contains 'src=' %}
81
+ {% continue %}
82
+ {% endunless %}
83
+
84
+ {% assign _left = _left | remove: ' /' | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
85
+ {% assign _attrs = _left | split: '" ' %}
86
+
87
+ {% assign _width = nil %}
88
+ {% assign _height = nil %}
89
+ {% assign _lqip = nil %}
90
+ {% assign _class = nil %}
91
+
92
+ {% for _attr in _attrs %}
93
+ {% unless _attr contains '=' %}
94
+ {% continue %}
95
+ {% endunless %}
96
+
97
+ {% assign _pair = _attr | remove: '"' | split: '=' %}
98
+ {% capture _key %}{{ _pair | first }}{% endcapture %}
99
+ {% capture _value %}{{ _pair | last }}{% endcapture %}
100
+
101
+ {% case _key %}
102
+ {% when 'width' %}
103
+ {% assign _width = _value %}
104
+ {% when 'height' %}
105
+ {% assign _height = _value %}
106
+ {% when 'src' %}
107
+ {% assign _src = _value %}
108
+ {% when 'lqip' %}
109
+ {% assign _lqip = _value %}
110
+ {% when 'class' %}
111
+ {% assign _class = _value %}
112
+ {% endcase %}
113
+
114
+ {% endfor %}
115
+
116
+ <!-- take out classes -->
117
+ {% if _class %}
118
+ {% capture _old_class %}class="{{ _class }}"{% endcapture %}
119
+ {% assign _left = _left | remove: _old_class %}
120
+ {% endif %}
121
+
122
+ {% assign _final_src = nil %}
123
+
124
+ {% unless _src contains '//' %}
125
+ {% assign _final_src = _path_prefix | append: _src %}
126
+ {% capture _src_from %}"{{ _src }}"{% endcapture %}
127
+ {% capture _src_to %}"{{ _final_src }}"{% endcapture %}
128
+ {% assign _left = _left | replace: _src_from, _src_to %}
129
+ {% endunless %}
130
+
131
+ {% if _lqip %}
132
+ {% unless _lqip contains ':' %}
133
+ {% assign _final_lqip = _path_prefix | append: _lqip %}
134
+ {% capture _lqip_from %}"{{ _lqip }}"{% endcapture %}
135
+ {% capture _lqip_to %}"{{ _final_lqip }}"{% endcapture %}
136
+ {% assign _left = _left | replace: _lqip_from, _lqip_to %}
137
+ {% endunless %}
138
+ {% endif %}
139
+
140
+ <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
141
+ {% assign _left = _left | replace: 'src=', 'data-src=' %}
142
+ {% if _left contains 'class=' %}
143
+ {% assign _left = _left | replace: 'class="', 'class="lazyload '%}
144
+ {% else %}
145
+ {% assign _left = _left | append: ' class="lazyload"' %}
146
+ {% endif %}
147
+
148
+ <!-- add image placeholder -->
149
+ {% if _lqip %}
150
+ {% assign _left = _left | replace: ' lqip=', ' data-lqip="true" src=' %}
151
+ {% else %}
152
+ {% if _width and _height %}
153
+ <!-- add SVG placehoder -->
154
+ {%- capture _svg -%}
155
+ src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
156
+ {%- endcapture -%}
157
+ {% assign _left = _svg | append: ' ' | append: _left %}
158
+ {% assign _class = _class | append: ' shimmer' %}
159
+ {% endif %}
160
+ {% endif %}
161
+
162
+ <!-- Bypass the HTML-proofer test -->
163
+ {% assign _left = _left | append: ' data-proofer-ignore' %}
164
+
165
+ <!-- make sure the `<img>` is wrapped by `<a>` -->
166
+ {% assign _parent = _right | slice: 1, 4 %}
167
+
168
+ {% if _parent == '</a>' %}
169
+ <!-- add class to exist <a> tag -->
170
+ {% assign _size = _img_content | size | minus: 1 %}
171
+ {% capture _class %}
172
+ class="img-link{% unless _lqip %} shimmer{% endunless %}"
173
+ {% endcapture %}
174
+ {% assign _img_content = _img_content | slice: 0, _size | append: _class | append: '>' %}
175
+
176
+ {% else %}
177
+ <!-- create the image wrapper -->
178
+ {%- capture _wrapper_start -%}
179
+ <a href="{{ _final_src | default: _src }}" class="popup img-link {{ _class }}">
180
+ {%- endcapture -%}
181
+ {% assign _img_content = _img_content | append: _wrapper_start %}
182
+ {% assign _right = _right | prepend: '></a' %}
183
+ {% endif %}
184
+
185
+ <!-- combine -->
186
+ {% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
187
+
188
+ {% endfor %}
189
+
190
+ {% if _img_content %}
191
+ {% assign _content = _img_content %}
192
+ {% endif %}
193
+
194
+ {% endif %}
195
+
196
+ <!-- Add header for code snippets -->
197
+
198
+ {% if _content contains '<div class="highlight"><code>' %}
199
+ {% assign _code_spippets = _content | split: '<div class="highlight"><code>' %}
200
+ {% assign _new_content = '' %}
201
+
202
+ {% for _snippet in _code_spippets %}
203
+
204
+ {% if forloop.last %}
205
+ {% assign _new_content = _new_content | append: _snippet %}
206
+
207
+ {% else %}
208
+
209
+ {% assign _left = _snippet | split: '><' | last%}
210
+
211
+ {% if _left contains 'file="' %}
212
+ {% assign _label_text = _left | split: 'file="' | last | split: '"' | first %}
213
+ {% assign _label_icon = 'far fa-file-code' %}
214
+ {% else %}
215
+ {% assign _lang = _left | split: 'language-' | last | split: ' ' | first %}
216
+ {% capture _label_text %}{% include language-alias.html language=_lang %}{% endcapture %}
217
+ {% assign _label_icon = 'fas fa-code small' %}
218
+ {% endif %}
219
+
220
+ {% capture _label %}
221
+ <span data-label-text="{{ _label_text | strip }}"><i class="{{ _label_icon }}"></i></span>
222
+ {% endcapture %}
223
+
224
+ {% assign _new_content = _new_content | append: _snippet
225
+ | append: '<div class="code-header">'
226
+ | append: _label
227
+ | append: '<button aria-label="copy" data-title-succeed="'
228
+ | append: site.data.locales[site.lang].post.button.copy_code.succeed
229
+ | append: '"><i class="far fa-clipboard"></i></button></div>'
230
+ | append: '<div class="highlight"><code>'
231
+ %}
232
+
233
+ {% endif %}
234
+
235
+ {% endfor %}
236
+
237
+ {% assign _content = _new_content %}
238
+
239
+ {% endif %}
240
+
241
+ <!-- Create heading anchors -->
242
+
243
+ {% assign heading_levels = '2,3,4,5' | split: ',' %}
244
+ {% assign _heading_content = _content %}
245
+
246
+ {% for level in heading_levels %}
247
+ {% capture mark_start %}<h{{ level }} id="{% endcapture %}
248
+ {% capture mark_end %}</h{{ level }}>{% endcapture %}
249
+
250
+ {% if _heading_content contains mark_start %}
251
+ {% assign _new_content = nil %}
252
+ {% assign heading_snippets = _heading_content | split: mark_start %}
253
+
254
+ {% for snippet in heading_snippets %}
255
+ {% if forloop.first %}
256
+ {% assign _new_content = snippet %}
257
+ {% continue %}
258
+ {% endif %}
259
+
260
+ {% assign id = snippet | split: '"' | first %}
261
+ {% capture anchor %}<a href="#{{ id }}" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>{% endcapture %}
262
+
263
+ {% assign left = snippet | split: mark_end | first %}
264
+ {% assign right = snippet | slice: left.size, snippet.size %}
265
+ {% assign left = left | replace_first: '">', '"><span class="mr-2">' | append: '</span>' %}
266
+
267
+ {% assign _new_content = _new_content | append: mark_start
268
+ | append: left | append: anchor | append: right
269
+ %}
270
+
271
+ {% endfor %}
272
+
273
+ {% assign _heading_content = _new_content %}
274
+
275
+ {% endif %}
276
+ {% endfor %}
277
+
278
+ {% assign _content = _heading_content %}
279
+
280
+ <!-- return -->
281
+
282
+ {{ _content }}