hexo-theme-gnix 3.3.1 → 4.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.
package/README.md CHANGED
@@ -51,4 +51,6 @@ bun i hexo-renderer-markdown-exit
51
51
  </tr>
52
52
  </table>
53
53
 
54
+ ## Credit
54
55
 
56
+ [ppoffice/hexo-theme-icarus: A simple, delicate, and modern theme for the static site generator Hexo.](https://github.com/ppoffice/hexo-theme-icarus)
@@ -33,7 +33,6 @@ module.exports = (hexo) => {
33
33
  const site = {
34
34
  posts: locals.posts.map(mapPost),
35
35
  tags: locals.tags.map(mapTag),
36
- categories: locals.categories.map(mapTag),
37
36
  };
38
37
  const index_pages = this.theme.config?.search?.index_pages;
39
38
  if (index_pages === false) {
@@ -18,4 +18,7 @@ module.exports = (hexo) => {
18
18
  cdn = this.config.providers?.cdn ? this.config.providers.cdn : "jsdelivr";
19
19
  return getCDN(cdn, _package, version, filename);
20
20
  });
21
+ hexo.extend.helper.register("is_tags", function (page = null) {
22
+ return (page === null ? this.page : page).__tags === true;
23
+ });
21
24
  };
@@ -1,11 +1,8 @@
1
1
  module.exports = (hexo) => {
2
2
  require("./hexo/filter/locals")(hexo);
3
3
  require("./hexo/generator/insight")(hexo);
4
- require("./hexo/generator/categories")(hexo);
5
- require("./hexo/generator/category")(hexo);
6
4
  require("./hexo/generator/tags")(hexo);
7
- require("./hexo/helper/cdn")(hexo);
8
- require("./hexo/helper/page")(hexo);
9
5
  require("./hexo/view").init(hexo);
6
+ require("./hexo/helper")(hexo);
10
7
  require("./hexo/renderer")(hexo);
11
8
  };
@@ -10,13 +10,12 @@ module.exports = class extends Component {
10
10
 
11
11
  const inlineCSS = `
12
12
  .article-meta {
13
- font-family: var(--font-monospace);
14
13
  font-size: 0.8rem;
15
- overflow-x: auto;
14
+ color: var(--subtext1);
16
15
  margin-bottom: 0.1rem;
17
16
  }
18
17
 
19
- .article-meta a {
18
+ a.archive-title {
20
19
  color: var(--text);
21
20
 
22
21
  &:hover {
@@ -24,10 +23,6 @@ module.exports = class extends Component {
24
23
  }
25
24
  }
26
25
 
27
- .article-meta span {
28
- padding-right: 0.5rem;
29
- }
30
-
31
26
  span.year {
32
27
  position: absolute;
33
28
  top: 1.5rem;
@@ -36,7 +31,7 @@ module.exports = class extends Component {
36
31
  font-size: 7.5rem;
37
32
  font-weight: bolder;
38
33
  font-family: Paris2024;
39
- color: hsl(from var(--mauve) h s l / 0.15);
34
+ color: hsl(from var(--lavender) h s l / 0.15);
40
35
  line-height: 1;
41
36
  user-select: none;
42
37
  }
@@ -55,7 +50,7 @@ module.exports = class extends Component {
55
50
  .archive-item + .archive-item {
56
51
  border: none;
57
52
  margin-top: 0;
58
- padding-top: 1rem;
53
+ padding-top: .5rem;
59
54
  }
60
55
  `;
61
56
  function renderArticleList(posts, year, month = null) {
@@ -68,25 +63,16 @@ module.exports = class extends Component {
68
63
  <div class="card">
69
64
  <div class="card-content">
70
65
  <span class="year">
71
- {month === null
72
- ? year
73
- : isValid(time)
74
- ? format(time, "LLLL yyyy")
75
- : year}
66
+ {month === null ? year : isValid(time) ? format(time, "LLLL yyyy") : year}
76
67
  </span>
77
68
  <div class="timeline">
78
69
  {posts.map((post) => {
79
- const categories = post.categories.map((category) => ({
80
- url: url_for(category.path),
81
- name: category.name,
82
- }));
83
70
  return (
84
71
  <ArticleMedia
85
72
  url={url_for(post.link || post.path)}
86
73
  title={post.title}
87
74
  date={date(post.date)}
88
75
  dateXml={date_xml(post.date)}
89
- categories={categories}
90
76
  />
91
77
  );
92
78
  })}
@@ -105,9 +91,7 @@ module.exports = class extends Component {
105
91
  articleList = Object.keys(years)
106
92
  .sort((a, b) => b - a)
107
93
  .map((year) => {
108
- const posts = page.posts.filter(
109
- (p) => p.date.year() === parseInt(year, 10),
110
- );
94
+ const posts = page.posts.filter((p) => p.date.year() === parseInt(year, 10));
111
95
  return renderArticleList(posts, year, null);
112
96
  });
113
97
  } else {
@@ -14,9 +14,7 @@ function getWordCount(content) {
14
14
  }
15
15
  content = content.replace(/<\/?[a-z][^>]*>/gi, "");
16
16
  content = content.trim();
17
- return content
18
- ? (content.match(/[\u00ff-\uffff]|[a-zA-Z]+/g) || []).length
19
- : 0;
17
+ return content ? (content.match(/[\u00ff-\uffff]|[a-zA-Z]+/g) || []).length : 0;
20
18
  }
21
19
 
22
20
  module.exports = class extends Component {
@@ -36,45 +34,27 @@ module.exports = class extends Component {
36
34
  {/* Main content */}
37
35
  <div class="card article-wrapper">
38
36
  {/* Cover image */}
39
- {cover ? (
40
- <ArticleCover
41
- page={page}
42
- cover={cover}
43
- index={index}
44
- helper={helper}
45
- />
46
- ) : null}
47
- <article
48
- class={`card-content article${"direction" in page ? ` ${page.direction}` : ""}`}
49
- >
37
+ {cover ? <ArticleCover page={page} cover={cover} index={index} helper={helper} /> : null}
38
+ <article class={`card-content article${"direction" in page ? ` ${page.direction}` : ""}`}>
50
39
  {/* Title */}
51
40
  {page.title !== "" && index ? (
52
41
  <h2 class="article-title">
53
42
  <a href={url_for(page.link || page.path)}>{page.title}</a>
54
43
  </h2>
55
44
  ) : null}
56
- {page.title !== "" && !index ? (
57
- <h1 class="article-title">{page.title}</h1>
58
- ) : null}
45
+ {page.title !== "" && !index ? <h1 class="article-title">{page.title}</h1> : null}
59
46
 
60
47
  {/* Metadata - Medium style */}
61
48
  {page.layout !== "page" ? (
62
49
  <div class="article-header-meta">
63
50
  <div class="article-meta-info">
64
51
  {page.date && (
65
- <time
66
- class="article-date"
67
- datetime={page.date.toISOString()}
68
- >
52
+ <time class="article-date" datetime={page.date.toISOString()}>
69
53
  {format(page.date, "LLL dd")}
70
54
  </time>
71
55
  )}
72
- {page.date && (wordCount > 0 || !index) && (
73
- <span class="meta-separator">·</span>
74
- )}
75
- {wordCount > 0 && (
76
- <span class="article-reading-time">{readTime} min</span>
77
- )}
56
+ {page.date && (wordCount > 0 || !index) && <span class="meta-separator">·</span>}
57
+ {wordCount > 0 && <span class="article-reading-time">{readTime} min</span>}
78
58
  {!index && (
79
59
  <Fragment>
80
60
  <span class="meta-separator">·</span>
@@ -88,42 +68,18 @@ module.exports = class extends Component {
88
68
  </Fragment>
89
69
  )}
90
70
  </div>
91
- <div class="article-taxonomy">
92
- {page.categories?.length ? (
93
- <div class="article-categories">
94
- {page.categories.map((category, idx) => (
95
- <Fragment>
96
- {idx > 0 && <span class="meta-separator">/</span>}
97
- <a
98
- class="article-category"
99
- href={url_for(category.path)}
100
- >
101
- {category.name}
102
- </a>
103
- </Fragment>
104
- ))}
105
- </div>
106
- ) : null}
107
- {page.categories?.length && page.tags?.length ? (
108
- <span class="meta-separator">·</span>
109
- ) : null}
110
- {page.tags?.length ? (
111
- <div class="article-tags-inline">
112
- {page.tags.map((tag, idx) => (
113
- <Fragment>
114
- {idx > 0 && <span class="meta-separator">,</span>}
115
- <a
116
- class="article-tag"
117
- rel="tag"
118
- href={url_for(tag.path)}
119
- >
120
- {tag.name}
121
- </a>
122
- </Fragment>
123
- ))}
124
- </div>
125
- ) : null}
126
- </div>
71
+ {page.tags?.length ? (
72
+ <div class="article-tags-inline">
73
+ {page.tags.map((tag, idx) => (
74
+ <Fragment>
75
+ {idx > 0 && <span class="meta-separator">,</span>}
76
+ <a class="article-tag" rel="tag" href={url_for(tag.path)}>
77
+ {tag.name}
78
+ </a>
79
+ </Fragment>
80
+ ))}
81
+ </div>
82
+ ) : null}
127
83
  </div>
128
84
  ) : null}
129
85
 
@@ -135,22 +91,13 @@ module.exports = class extends Component {
135
91
  }}
136
92
  ></div>
137
93
  {/* Licensing block */}
138
- {!index &&
139
- article &&
140
- article.licenses &&
141
- Object.keys(article.licenses) ? (
142
- <ArticleLicensing.Cacheable
143
- page={page}
144
- config={config}
145
- helper={helper}
146
- />
94
+ {!index && article && article.licenses && Object.keys(article.licenses) ? (
95
+ <ArticleLicensing.Cacheable page={page} config={config} helper={helper} />
147
96
  ) : null}
148
97
  </article>
149
98
  </div>
150
99
  {/* Comment */}
151
- {!index ? (
152
- <Comment config={config} page={page} helper={helper} />
153
- ) : null}
100
+ {!index ? <Comment config={config} page={page} helper={helper} /> : null}
154
101
  </Fragment>
155
102
  );
156
103
  }
@@ -5,10 +5,7 @@ module.exports = class extends Component {
5
5
  const { page, cover, helper } = this.props;
6
6
  const { url_for } = helper;
7
7
 
8
- const imageSrcset = `${cover}?w=256 256w, ${cover}?w=800 800w, ${cover}?w=1500 1500w, ${cover}?w=2000 2000w, ${cover} 6144w`;
9
- const coverLQIP = (
10
- <img class="cover-lqip" alt="lqip" src={`${cover}?q=10&blur=25`} />
11
- );
8
+ const imageSrcset = `${cover}?w=800 800w, ${cover}?w=1500 1500w, ${cover}?w=2000 2000w, ${cover} 6144w`;
12
9
  const CoverImage = (
13
10
  <img
14
11
  class="fill"
@@ -25,7 +22,6 @@ module.exports = class extends Component {
25
22
  <div class="card-image">
26
23
  <a href={url_for(page.link || page.path)} class="image is-7by3">
27
24
  {CoverImage}
28
- {coverLQIP}
29
25
  </a>
30
26
  </div>
31
27
  );
@@ -2,33 +2,23 @@
2
2
  * Article media component, used in article lists such as archive page and recent posts widget
3
3
  */
4
4
  const { Component } = require("inferno");
5
- const { format, parseISO, isValid } = require("date-fns");
5
+ const { format, parseISO } = require("date-fns");
6
6
 
7
7
  module.exports = class extends Component {
8
8
  render() {
9
- const { url, title, date, categories } = this.props;
9
+ const { url, title, date } = this.props;
10
10
  // Formatted like May.15
11
- let formattedDate = "";
12
- const d = typeof date === "string" ? parseISO(date) : date;
13
- formattedDate = isValid(d) ? format(d, "MMM.dd") : "";
14
- const categoryTags = [];
15
- categories.forEach((category, i) => {
16
- categoryTags.push(<a href={category.url}>{category.name}</a>);
17
- if (i < categories.length - 1) {
18
- categoryTags.push("/");
19
- }
20
- });
11
+ const formattedDate = format(parseISO(date), "MMM dd");
21
12
 
22
13
  return (
23
14
  <article class="archive-item">
24
15
  <div>
25
16
  <p class="article-meta">
26
17
  <span>{formattedDate}</span>
27
- {categoryTags.length ? <span>{categoryTags}</span> : null}
28
- </p>
29
- <p class="title" style="font-size: 1em;">
30
- <a href={url}>{title}</a>
31
18
  </p>
19
+ <a class="archive-title" href={url}>
20
+ {title}
21
+ </a>
32
22
  </div>
33
23
  </article>
34
24
  );
@@ -14,12 +14,8 @@ function getPageTitle(page, siteTitle, helper) {
14
14
  } else if (helper.is_year()) {
15
15
  title += `: ${page.year}`;
16
16
  }
17
- } else if (helper.is_category()) {
18
- title = `${helper._p("common.category", 1)}: ${page.category}`;
19
17
  } else if (helper.is_tag()) {
20
18
  title = `${helper._p("common.tag", 1)}: ${page.tag}`;
21
- } else if (helper.is_categories()) {
22
- title = helper._p("common.category", Infinity);
23
19
  } else if (helper.is_tags()) {
24
20
  title = helper._p("common.tag", Infinity);
25
21
  }
@@ -43,8 +39,7 @@ module.exports = class extends Component {
43
39
  favicon,
44
40
  } = head;
45
41
 
46
- const noIndex =
47
- helper.is_archive() || helper.is_category() || helper.is_tag();
42
+ const noIndex = helper.is_archive() || helper.is_tag();
48
43
 
49
44
  const language = page.lang || page.language || config.language;
50
45
 
@@ -95,8 +90,7 @@ module.exports = class extends Component {
95
90
  if (
96
91
  typeof structured_data === "object" &&
97
92
  structured_data !== null &&
98
- ((Array.isArray(structured_data.image) &&
99
- structured_data.image.length > 0) ||
93
+ ((Array.isArray(structured_data.image) && structured_data.image.length > 0) ||
100
94
  typeof structured_data.image === "string")
101
95
  ) {
102
96
  structuredImages = structured_data.image;
@@ -150,9 +144,7 @@ module.exports = class extends Component {
150
144
  page.content ||
151
145
  config.description
152
146
  }
153
- keywords={
154
- (page.tags?.length ? page.tags : undefined) || config.keywords
155
- }
147
+ keywords={(page.tags?.length ? page.tags : undefined) || config.keywords}
156
148
  url={open_graph.url || page.permalink || url}
157
149
  images={openGraphImages}
158
150
  siteName={open_graph.site_name || config.title}
@@ -229,13 +221,7 @@ module.exports = class extends Component {
229
221
  onload="this.onload=null;this.rel='stylesheet'"
230
222
  />
231
223
  <link rel="stylesheet" href="/css/shiki/shiki.css" />
232
- <Plugins
233
- site={site}
234
- config={config}
235
- helper={helper}
236
- page={page}
237
- head={true}
238
- />
224
+ <Plugins site={site} config={config} helper={helper} page={page} head={true} />
239
225
  {adsenseClientId ? (
240
226
  <script
241
227
  data-ad-client={adsenseClientId}
@@ -42,7 +42,6 @@ Insight.Cacheable = cacheComponent(Insight, "search.insight", (props) => {
42
42
  untitled: helper.__("search.untitled"),
43
43
  posts: helper._p("common.post", Infinity),
44
44
  pages: helper._p("common.page", Infinity),
45
- categories: helper._p("common.category", Infinity),
46
45
  tags: helper._p("common.tag", Infinity),
47
46
  },
48
47
  contentUrl: helper.url_for("/content.json"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-gnix",
3
- "version": "3.3.1",
3
+ "version": "4.0.0",
4
4
  "author": "Efterklang <gaojiaxing0220@gmail.com>",
5
5
  "license": "MIT",
6
6
  "description": "Second generation of Hexo theme Icarus, now with Catppuccin flavor and night mode support.",
@@ -7,7 +7,7 @@
7
7
  border-radius: 8px;
8
8
  border-style: solid;
9
9
  border-width: 1.5px;
10
- margin: 0.5em 0;
10
+ margin: 1.5em 0 !important;
11
11
  padding: 10px 12px 10px 15px;
12
12
 
13
13
  svg {
@@ -411,7 +411,6 @@ html {
411
411
  box-sizing: border-box;
412
412
  height: 100%;
413
413
  font-size: 16px;
414
- scroll-behavior: smooth;
415
414
  min-width: 300px;
416
415
  overflow-x: hidden;
417
416
  overflow-y: scroll;
@@ -511,7 +510,6 @@ video {
511
510
  overflow: hidden;
512
511
  }
513
512
 
514
- .card-image .cover-lqip,
515
513
  .card-image .fill {
516
514
  position: absolute;
517
515
  top: 0;
@@ -521,15 +519,6 @@ video {
521
519
  object-fit: cover;
522
520
  }
523
521
 
524
- .card-image .cover-lqip {
525
- z-index: 1;
526
- transition: opacity 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
527
- }
528
-
529
- .card-image .fill.loaded + .cover-lqip {
530
- display: none;
531
- }
532
-
533
522
  .card-content {
534
523
  padding: 1.25rem;
535
524
  border-radius: 0;
@@ -606,7 +595,7 @@ video {
606
595
  .theme-selector-modal {
607
596
  position: fixed;
608
597
  inset: 0;
609
- z-index: 1;
598
+ z-index: 100;
610
599
  display: flex;
611
600
  align-items: center;
612
601
  justify-content: center;
@@ -740,8 +729,10 @@ video {
740
729
  .pagination-next,
741
730
  .pagination-previous {
742
731
  height: 2.5em;
743
- border-radius: 4px;
732
+ border-radius: 10px;
744
733
  font-size: 1.1em;
734
+ font-weight: bolder;
735
+ color: var(--text);
745
736
  margin: 0.25rem;
746
737
  padding: 0 0.5em;
747
738
  justify-content: center;
@@ -759,13 +750,6 @@ video {
759
750
  min-width: 1.5em;
760
751
  }
761
752
 
762
- .pagination-next,
763
- .pagination-previous {
764
- padding-left: 0.75em;
765
- padding-right: 0.75em;
766
- white-space: nowrap;
767
- }
768
-
769
753
  .pagination-ellipsis {
770
754
  pointer-events: none;
771
755
  }
@@ -925,55 +909,69 @@ video {
925
909
  overflow: auto;
926
910
  word-wrap: break-word;
927
911
  font-family: var(--font-article);
928
- font-size: 1.25rem;
929
- line-height: 1.68;
912
+ font-size: 1rem;
913
+ line-height: 1.5;
930
914
  letter-spacing: -0.003em;
931
915
 
916
+ ::selection {
917
+ color: inherit;
918
+ text-decoration: underline wavy;
919
+ text-decoration-color: var(--mauve);
920
+ }
921
+
932
922
  h2 {
933
923
  font-size: 2em;
934
924
  font-weight: 700;
935
925
  line-height: 1.25;
936
926
  letter-spacing: -0.02em;
937
- margin-bottom: 0.5em;
938
- }
939
-
940
- h2:not(:first-child) {
941
- margin-top: 1.5em;
927
+ margin: 1.2rem 0 1rem;
942
928
  }
943
929
 
944
930
  h3 {
945
- font-size: 1.625em;
931
+ font-size: 1.875em;
946
932
  font-weight: 700;
947
- line-height: 1.3;
933
+ line-height: 1.25;
948
934
  letter-spacing: -0.015em;
949
- margin-bottom: 0.5em;
935
+ margin: 1.2rem 0 1rem;
950
936
  }
951
937
 
952
938
  h4 {
953
- font-size: 1.375em;
939
+ font-size: 1.5em;
954
940
  font-weight: 600;
955
- line-height: 1.35;
941
+ line-height: 1.25;
956
942
  letter-spacing: -0.01em;
957
- margin-bottom: 0.5em;
943
+ margin: 1.2rem 0 1rem;
958
944
  }
959
945
 
960
946
  h5 {
961
947
  font-size: 1.25em;
962
948
  font-weight: 600;
963
- line-height: 1.4;
949
+ line-height: 1.25;
964
950
  letter-spacing: -0.005em;
965
- margin-bottom: 0.5em;
951
+ margin: 1.2rem 0 1rem;
966
952
  }
967
953
 
968
954
  h6 {
969
- font-size: 1.125em;
955
+ font-size: 1.2em;
970
956
  font-weight: 600;
971
- line-height: 1.45;
972
- margin-bottom: 0.5em;
957
+ line-height: 1.25;
958
+ margin: 1.2rem 0 1rem;
973
959
  }
974
960
 
975
961
  .p:not(:last-child) {
976
- margin-bottom: 0.5em;
962
+ margin-bottom: 1rem;
963
+ }
964
+
965
+ p,
966
+ blockquote,
967
+ ul,
968
+ ol,
969
+ dl,
970
+ table,
971
+ pre,
972
+ details {
973
+ margin-top: 0;
974
+ margin-bottom: 1rem;
977
975
  }
978
976
 
979
977
  p:last-child,
@@ -984,14 +982,13 @@ video {
984
982
  }
985
983
 
986
984
  li + li {
987
- margin-top: 0.5em;
985
+ margin-top: 0.25em;
988
986
  }
989
987
 
990
988
  img,
991
989
  video {
992
990
  display: block;
993
- margin: 0 auto;
994
- margin-bottom: 2rem;
991
+ margin: 0 0 1rem 0;
995
992
  border-radius: 2px;
996
993
  }
997
994
 
@@ -1002,16 +999,16 @@ video {
1002
999
 
1003
1000
  ol {
1004
1001
  list-style-position: outside;
1005
- margin-left: 2em;
1006
- margin-top: 1.5em;
1007
- margin-bottom: 1.5em;
1002
+ padding-left: 2em;
1003
+ margin-top: 0;
1004
+ margin-bottom: 0;
1008
1005
  }
1009
1006
 
1010
1007
  ul {
1011
1008
  list-style: disc outside;
1012
- margin-left: 2em;
1013
- margin-top: 1.5em;
1014
- margin-bottom: 1.5em;
1009
+ padding-left: 2em;
1010
+ margin-top: 0;
1011
+ margin-bottom: 0;
1015
1012
  }
1016
1013
 
1017
1014
  ul ul {
@@ -1029,21 +1026,24 @@ video {
1029
1026
 
1030
1027
  math {
1031
1028
  overflow: auto;
1032
- margin-bottom: 0.5em;
1029
+ margin-bottom: 1rem;
1030
+ }
1031
+
1032
+ iframe {
1033
+ overflow: auto;
1033
1034
  }
1034
1035
 
1035
1036
  figure {
1036
- margin-left: 2em;
1037
- margin-right: 2em;
1037
+ margin: 1em 2.5rem;
1038
1038
  text-align: center;
1039
1039
  }
1040
1040
 
1041
1041
  figure:not(:first-child) {
1042
- margin-top: 2em;
1042
+ margin-top: 1.5rem;
1043
1043
  }
1044
1044
 
1045
1045
  figure:not(:last-child) {
1046
- margin-bottom: 2em;
1046
+ margin-bottom: 1rem;
1047
1047
  }
1048
1048
 
1049
1049
  figure img {
@@ -1058,9 +1058,11 @@ video {
1058
1058
  -webkit-overflow-scrolling: touch;
1059
1059
  overflow-x: auto;
1060
1060
  font-size: 0.85em;
1061
- padding: 1.25em 1.5em;
1061
+ padding: 1rem;
1062
+ margin: 0 0 1rem 0;
1062
1063
  white-space: pre;
1063
1064
  word-wrap: normal;
1065
+ line-height: 1.45;
1064
1066
  }
1065
1067
 
1066
1068
  sub,
@@ -1112,8 +1114,8 @@ table {
1112
1114
  border-spacing: 0;
1113
1115
  border-radius: 8px;
1114
1116
  overflow: hidden;
1115
- margin: 0.875em 0;
1116
- font-size: 0.875em;
1117
+ margin: 1rem 0;
1118
+ font-size: 1rem;
1117
1119
  border: 1px solid var(--surface0);
1118
1120
  }
1119
1121
 
@@ -1146,16 +1148,16 @@ blockquote {
1146
1148
  position: relative;
1147
1149
  padding: 1.5rem 2rem 1.5rem 3rem;
1148
1150
  margin: 1.5rem 0;
1149
- border-left: 4px solid var(--red);
1151
+ border-left: 2px solid var(--red);
1150
1152
  border-radius: 0 8px 8px 0;
1151
1153
  font-family: var(--font-serif);
1152
1154
  font-style: italic;
1153
- font-size: 1.05rem;
1154
- line-height: 1.6;
1155
+ font-size: 1rem;
1156
+ line-height: 1.5;
1155
1157
  }
1156
1158
 
1157
1159
  blockquote:before {
1158
- content: '"';
1160
+ content: '';
1159
1161
  position: absolute;
1160
1162
  left: 0.5rem;
1161
1163
  top: 0.2rem;
@@ -1218,23 +1220,8 @@ input.task-list-item-checkbox:checked::before {
1218
1220
  color: var(--base);
1219
1221
  }
1220
1222
 
1221
- .title {
1222
- word-break: break-word;
1223
- margin-bottom: 0.4em;
1224
- position: relative;
1225
- display: inline-block;
1226
- transition: color 0.3s ease-out;
1227
- font-size: 3em;
1228
- font-weight: 800;
1229
- line-height: 1.2;
1230
- }
1231
-
1232
- .title .tag {
1233
- vertical-align: middle;
1234
- }
1235
-
1236
1223
  code {
1237
- font-size: 0.875em;
1224
+ font-size: 0.85em;
1238
1225
  font-weight: 400;
1239
1226
  font-family: var(--font-monospace);
1240
1227
  padding: 0 0.15em;
@@ -1253,7 +1240,7 @@ strong {
1253
1240
  hr {
1254
1241
  border: none;
1255
1242
  display: block;
1256
- height: 2px;
1243
+ height: 0.25em;
1257
1244
  margin: 1.5rem 0;
1258
1245
  }
1259
1246
 
@@ -1370,14 +1357,14 @@ section {
1370
1357
  }
1371
1358
 
1372
1359
  .article-meta-info,
1373
- .article-taxonomy {
1360
+ .article-tags-inline {
1374
1361
  display: flex;
1375
1362
  align-items: center;
1376
1363
  flex-wrap: wrap;
1377
1364
  gap: 0.3rem;
1378
1365
  }
1379
1366
 
1380
- .article-taxonomy {
1367
+ .article-tags-inline {
1381
1368
  /* Push to the right */
1382
1369
  margin-left: auto;
1383
1370
  }
@@ -150,7 +150,7 @@ figure.shiki {
150
150
  position: absolute;
151
151
  bottom: 1rem;
152
152
  width: 100%;
153
- z-index: 1000;
153
+ z-index: 50;
154
154
  display: flex;
155
155
  justify-content: center;
156
156
  align-items: center;
@@ -118,7 +118,7 @@ function loadInsight(config, translation) {
118
118
  const text = findAndHighlight(item.text, keywords, 100);
119
119
  return searchItem(title, text, item.link);
120
120
  } else {
121
- // Categories / Tags
121
+ // Tags
122
122
  const name = findAndHighlight(item.name, keywords);
123
123
  return searchItem(name, null, item.link);
124
124
  }
@@ -197,7 +197,6 @@ function loadInsight(config, translation) {
197
197
  return {
198
198
  posts: executeSearch(json.posts, ["title", "text"], [3, 1]),
199
199
  pages: executeSearch(json.pages, ["title", "text"], [3, 1]),
200
- categories: executeSearch(json.categories, ["name", "slug"], [1, 1]),
201
200
  tags: executeSearch(json.tags, ["name", "slug"], [1, 1]),
202
201
  };
203
202
  }
@@ -1,12 +0,0 @@
1
- // Generates the <root>/categories page
2
- module.exports = (hexo) => {
3
- hexo.extend.generator.register("categories", (locals) => {
4
- return {
5
- path: "categories/",
6
- layout: ["categories"],
7
- data: Object.assign({}, locals, {
8
- __categories: true,
9
- }),
10
- };
11
- });
12
- };
@@ -1,52 +0,0 @@
1
- /**
2
- * Register the Hexo generator for generating <code>/category/</code> pages.
3
- * @module hexo/generator/category
4
- */
5
- const pagination = require("hexo-pagination");
6
-
7
- /**
8
- * Register the Hexo generator for generating <code>/category/</code> pages.
9
- * <p>
10
- * An array of parent categories will be attached to the page local
11
- * variables.
12
- *
13
- * @param {Hexo} hexo The Hexo instance.
14
- */
15
- module.exports = (hexo) => {
16
- hexo.extend.generator.register("category", function (locals) {
17
- const config = this.config;
18
- const paginationDir = config.pagination_dir || "page";
19
- const perPage =
20
- (config.category_generator ? config.category_generator.per_page : null) ||
21
- 0;
22
- const orderBy =
23
- (config.category_generator ? config.category_generator.order_by : null) ||
24
- "-date";
25
-
26
- function findParent(category) {
27
- let parents = [];
28
- if (typeof category === "object" && "parent" in category) {
29
- const parent = locals.categories
30
- .filter((cat) => cat._id === category.parent)
31
- .first();
32
- parents = findParent(parent).concat([parent]);
33
- }
34
- return parents;
35
- }
36
-
37
- return locals.categories.reduce((result, category) => {
38
- const posts = category.posts.sort(orderBy);
39
- const data = pagination(category.path, posts, {
40
- perPage: perPage,
41
- layout: ["category", "archive", "index"],
42
- format: `${paginationDir}/%d/`,
43
- data: {
44
- category: category.name,
45
- parents: findParent(category),
46
- },
47
- });
48
-
49
- return result.concat(data);
50
- }, []);
51
- });
52
- };
@@ -1,27 +0,0 @@
1
- /**
2
- * Register the Hexo helper functions for a Hexo page/post.
3
- * @module hexo/helper/page
4
- */
5
-
6
- /**
7
- * Register the Hexo helper functions for a Hexo page/post.
8
- *
9
- * @param {Hexo} hexo The Hexo instance.
10
- * @example
11
- * // Use the function below to test if the given page is the /categories page
12
- * // Need to be combined with lib/hexo/generator/categories
13
- * is_categories(page);
14
- *
15
- * // Use the function below to test if the given page is the /tags page
16
- * // Need to be combined with lib/hexo/generator/tags
17
- * is_tags(page);
18
- */
19
- module.exports = (hexo) => {
20
- hexo.extend.helper.register("is_categories", function (page = null) {
21
- return (page === null ? this.page : page).__categories === true;
22
- });
23
-
24
- hexo.extend.helper.register("is_tags", function (page = null) {
25
- return (page === null ? this.page : page).__tags === true;
26
- });
27
- };
@@ -1,147 +0,0 @@
1
- const { Component, cacheComponent } = require("../include/util/common");
2
-
3
- class Categories extends Component {
4
- renderList(categories, showCount) {
5
- return categories.map((category) => (
6
- <li class="category-list-item">
7
- <a class={`category-link`} href={category.url}>
8
- <span>{category.name}</span>
9
- {showCount ? <span class="category-count">{category.count}</span> : null}
10
- </a>
11
- {category.children.length ? (
12
- <ul class="category-sublist">{this.renderList(category.children, false)}</ul>
13
- ) : null}
14
- </li>
15
- ));
16
- }
17
-
18
- render() {
19
- const { showCount, categories } = this.props;
20
- const categoriesCSS = `
21
- .category-list-item {
22
- list-style: none;
23
- margin-bottom: 0.4em;
24
- }
25
- .category-link {
26
- display: flex;
27
- align-items: center;
28
- justify-content: space-between;
29
- padding: 0.6em 0.8em;
30
- border-radius: 8px;
31
- color: var(--text);
32
- background-color: transparent;
33
- text-decoration: none;
34
- transition: all 0.2s ease;
35
- font-weight: 400;
36
- }
37
- .category-link:hover {
38
- background-color: var(--base) !important;
39
- transform: translateX(4px);
40
- }
41
- .category-link span:first-child {
42
- flex: 1;
43
- }
44
- .category-count {
45
- padding: 0.15em 0.6em;
46
- border-radius: 10px;
47
- min-width: 1.5em;
48
- text-align: center;
49
- }
50
- .category-sublist {
51
- margin-left: 0.8em;
52
- padding-left: 0.8em;
53
- border-left: 2px solid var(--surface0);
54
- margin-top: 0.4em;
55
- list-style: none;
56
- }
57
- `;
58
-
59
- return (
60
- <div class="card widget" data-type="categories">
61
- <style>{categoriesCSS}</style>
62
- <div class="card-content" style="padding: 1.2em;">
63
- <ul style="list-style: none; padding: 0; margin: 0;">
64
- {this.renderList(categories, showCount)}
65
- </ul>
66
- </div>
67
- </div>
68
- );
69
- }
70
- }
71
-
72
- Categories.Cacheable = cacheComponent(Categories, "widget.categories", (props) => {
73
- const { page, helper, widget = {} } = props;
74
- const {
75
- categories = props.site.categories,
76
- orderBy = "name",
77
- order = 1,
78
- showCurrent = false,
79
- showCount = true,
80
- } = widget;
81
- const { url_for, _p } = helper;
82
-
83
- if (!categories || !categories.length) {
84
- return null;
85
- }
86
-
87
- const depth = parseInt(props.depth, 10);
88
-
89
- function prepareQuery(parent) {
90
- const query = {};
91
-
92
- if (parent) {
93
- query.parent = parent;
94
- } else {
95
- query.parent = { $exists: false };
96
- }
97
-
98
- return categories
99
- .find(query)
100
- .sort(orderBy, order)
101
- .filter((cat) => cat.length);
102
- }
103
-
104
- function hierarchicalList(level, parent) {
105
- return prepareQuery(parent).map((cat, _) => {
106
- let children = [];
107
- if (!depth || level + 1 < depth) {
108
- children = hierarchicalList(level + 1, cat._id);
109
- }
110
-
111
- let isCurrent = false;
112
- if (showCurrent && page) {
113
- for (let j = 0; j < cat.length; j++) {
114
- const post = cat.posts.data[j];
115
- if (post && post._id === page._id) {
116
- isCurrent = true;
117
- break;
118
- }
119
- }
120
- // special case: category page
121
- isCurrent = isCurrent || page.base?.startsWith(cat.path);
122
- }
123
-
124
- return {
125
- children,
126
- isCurrent,
127
- name: cat.name,
128
- count: cat.length,
129
- url: url_for(cat.path),
130
- };
131
- });
132
- }
133
-
134
- return {
135
- showCount,
136
- categories: hierarchicalList(0),
137
- title: _p("common.category", Infinity),
138
- };
139
- });
140
-
141
- module.exports = class extends Component {
142
- render() {
143
- const { site, page, helper } = this.props;
144
-
145
- return <Categories.Cacheable site={site} page={page} helper={helper} />;
146
- }
147
- };
@@ -1,38 +0,0 @@
1
- const { Component, Fragment } = require("../include/util/common");
2
- const Index = require("./index");
3
-
4
- module.exports = class extends Component {
5
- render() {
6
- const { config, page, helper } = this.props;
7
- const { url_for, _p } = helper;
8
-
9
- return (
10
- <Fragment>
11
- <nav class="breadcrumb" aria-label="breadcrumbs">
12
- <ul>
13
- <li>
14
- {" "}
15
- <font style="color: var(--green)">$</font>&nbsp;ls&nbsp;
16
- <a href={url_for("/categories/")}>
17
- {_p("common.category", Infinity)}
18
- </a>
19
- </li>
20
- {page.parents.map((category) => {
21
- return (
22
- <li>
23
- <a href={url_for(category.path)}>{category.name}</a>
24
- </li>
25
- );
26
- })}
27
- <li class="is-active">
28
- <a href="#" aria-current="page">
29
- {page.category}
30
- </a>
31
- </li>
32
- </ul>
33
- </nav>
34
- <Index config={config} page={page} helper={helper} />
35
- </Fragment>
36
- );
37
- }
38
- };