Compare commits

...
17 Commits
Author SHA1 Message Date
Jimmy CaiandGitHub 9e08854681 release: 3.7.0 2022-01-20 11:12:16 +00:00
zhixuanandGitHub 0af9d23e49 feat(article): add scroll for table (#428)
* feat: table can't scroll & delete scrollbar style for Chromium

* Undo some line breaks

* Add a table with overflow to exampleSite
2022-01-20 12:09:25 +01:00
Jimmy CaiandGitHub 3b98d3ba05 feat(sidebar): link avatar to homepage (#465)
closes https://github.com/CaiJimmy/hugo-theme-stack/issues/399
2022-01-20 11:38:16 +01:00
Andreas DeiningerandGitHub fe661c8c38 feat: turn stack theme into a hugo module (#460)
* Turn stack theme into a hugo module
2022-01-20 11:16:28 +01:00
bfd1eb8400 feat: add custom.ts (#461)
* feat: add custom.ts

* Load custom.ts only if it exists

This change avoids loading an empty .js file

Co-authored-by: Jimmy Cai <[email protected]>
2022-01-19 16:35:15 +01:00
tanmxandGitHub eebaea81e8 feat(comment): update twikoo version to 1.4.15 (#464) 2022-01-19 15:22:51 +01:00
zhixuanandGitHub ca260db07e fix(shortcode): conflict with gist shortcode (#455) 2022-01-19 01:12:29 +01:00
Jimmy CaiandGitHub 4764a92df3 refactor(search): avoid issue with one character keyword (#447)
* refactor(search): avoid issue with one character keyword

closes https://github.com/CaiJimmy/hugo-theme-stack/issues/184

* Remove keyword sorts

* fix typo: secion -> section

* fix(search): avoid matching html entity

* Use | operator to concatenate keywords

Idea from https://github.com/CaiJimmy/hugo-theme-stack/pull/436

* Add missing `matchCount`

* Limit preview length

* Don't add ellipsis to title

* add comment to `processMatches`

* Initialize DOMParser only once

* Remove marker function

* Deal with blank search

* Use const keyword for constant arrays
2022-01-18 23:19:30 +01:00
Jimmy CaiandGitHub 86cbc1b682 fix(README): demo site link
closes #449
2022-01-03 14:15:05 +01:00
Jimmy CaiandGitHub d165621568 release: 3.6.0 2021-12-29 00:32:08 +01:00
Nathan HarkenriderandGitHub dde6a10cab feat: implement cache busting for CSS (#444) 2021-12-28 23:28:33 +01:00
Jimmy CaiandGitHub a669b60cdd chore(exampleSite): make default pages use page bundle feature
To avoid confusions
2021-12-28 10:33:48 +00:00
Jimmy CaiandGitHub 455e23f22b feat: page links (#446) 2021-12-28 11:28:20 +01:00
Jimmy CaiandGitHub 4e2c8e74be fix: add missing diff syntax highlight (#445)
closes: https://github.com/CaiJimmy/hugo-theme-stack/issues/434
2021-12-28 10:48:22 +01:00
HAHWULandGitHub 359e4b34c1 Update i18n(ko) (#418)
Add dark mode, list-section, list-subsction, article-back, article-tableOfContents, article-readingTime
2021-12-04 21:16:22 +01:00
Paul-Henri ZimmerlinandGitHub 195b8d8076 fix(i18n/fr): add missing translations for reading time (#416) 2021-12-04 21:10:42 +01:00
zhixuanandGitHub 497643b363 feat: add alt message for archive & related contents images (#411) 2021-12-04 21:05:53 +01:00
28 changed files with 373 additions and 176 deletions
+6 -3
View File
@@ -5,7 +5,7 @@
## Demo ## Demo
[Example Site](https://theme-stack.jimmycai.com/) [Example Site](https://demo.stack.jimmycai.com/)
[![Netlify Status](https://api.netlify.com/api/v1/badges/a2d2807a-a905-4bcb-97da-8da8d847da3d/deploy-status)](https://app.netlify.com/sites/hugo-theme-stack/deploys) [![Netlify Status](https://api.netlify.com/api/v1/badges/a2d2807a-a905-4bcb-97da-8da8d847da3d/deploy-status)](https://app.netlify.com/sites/hugo-theme-stack/deploys)
@@ -35,7 +35,10 @@ It's necessary to use **Hugo Extended ≥ 0.87.0**.
## Installation ## Installation
Clone / Download this repository to `theme` folder, and edit your site config following `exampleSite/config.yaml`. * Route 1: Clone / Download this repository to `theme` folder
* Route 2: Turn your site into a hugo module and add this theme as a module dependency
Edit your site config following `exampleSite/config.yaml`.
*Note: Remove `config.toml` if there is one in the site folder.* *Note: Remove `config.toml` if there is one in the site folder.*
@@ -77,4 +80,4 @@ Some references that I took while building this theme:
| Project | Licence| | Project | Licence|
| ------- | ------| | ------- | ------|
| [artchen/hexo-theme-element](https://github.com/artchen/hexo-theme-element) | [MIT](https://github.com/artchen/hexo-theme-element/blob/master/LICENSE) | | [artchen/hexo-theme-element](https://github.com/artchen/hexo-theme-element) | [MIT](https://github.com/artchen/hexo-theme-element/blob/master/LICENSE) |
| [MunifTanjim/minimo](https://github.com/MunifTanjim/minimo) | [MIT](https://github.com/MunifTanjim/minimo/blob/master/LICENSE) | | [MunifTanjim/minimo](https://github.com/MunifTanjim/minimo) | [MIT](https://github.com/MunifTanjim/minimo/blob/master/LICENSE) |
+2
View File
@@ -6,5 +6,7 @@
"*" "*"
] ]
}, },
"lib": ["es2020", "dom"],
"jsx": "preserve"
} }
} }
-14
View File
@@ -23,17 +23,3 @@ body {
scrollbar-color: var(--scrollbar-thumb) transparent; scrollbar-color: var(--scrollbar-thumb) transparent;
} }
/**/ /**/
/* scrollbar styles for Chromium */
::-webkit-scrollbar {
height: auto;
}
::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
}
::-webkit-scrollbar-track {
background-color: transparent;
}
/**/
+93 -90
View File
@@ -10,7 +10,8 @@
} }
/* Other */ /* Other */
.chroma .x {} .chroma .x {
}
/* Error */ /* Error */
.chroma .err { .chroma .err {
@@ -40,367 +41,369 @@
.chroma .hl { .chroma .hl {
display: block; display: block;
width: 100%; width: 100%;
background-color: #ffffcc background-color: #ffffcc;
} }
/* LineNumbersTable */ /* LineNumbersTable */
.chroma .lnt { .chroma .lnt {
margin-right: 0.4em; margin-right: 0.4em;
padding: 0 0.4em 0 0.4em; padding: 0 0.4em 0 0.4em;
color: #7f7f7f color: #7f7f7f;
} }
/* LineNumbers */ /* LineNumbers */
.chroma .ln { .chroma .ln {
margin-right: 0.4em; margin-right: 0.4em;
padding: 0 0.4em 0 0.4em; padding: 0 0.4em 0 0.4em;
color: #7f7f7f color: #7f7f7f;
} }
/* Keyword */ /* Keyword */
.chroma .k { .chroma .k {
color: #00a8c8 color: #00a8c8;
} }
/* KeywordConstant */ /* KeywordConstant */
.chroma .kc { .chroma .kc {
color: #00a8c8 color: #00a8c8;
} }
/* KeywordDeclaration */ /* KeywordDeclaration */
.chroma .kd { .chroma .kd {
color: #00a8c8 color: #00a8c8;
} }
/* KeywordNamespace */ /* KeywordNamespace */
.chroma .kn { .chroma .kn {
color: #f92672 color: #f92672;
} }
/* KeywordPseudo */ /* KeywordPseudo */
.chroma .kp { .chroma .kp {
color: #00a8c8 color: #00a8c8;
} }
/* KeywordReserved */ /* KeywordReserved */
.chroma .kr { .chroma .kr {
color: #00a8c8 color: #00a8c8;
} }
/* KeywordType */ /* KeywordType */
.chroma .kt { .chroma .kt {
color: #00a8c8 color: #00a8c8;
} }
/* Name */ /* Name */
.chroma .n { .chroma .n {
color: #111111 color: #111111;
} }
/* NameAttribute */ /* NameAttribute */
.chroma .na { .chroma .na {
color: #75af00 color: #75af00;
} }
/* NameBuiltin */ /* NameBuiltin */
.chroma .nb { .chroma .nb {
color: #111111 color: #111111;
} }
/* NameBuiltinPseudo */ /* NameBuiltinPseudo */
.chroma .bp { .chroma .bp {
color: #111111 color: #111111;
} }
/* NameClass */ /* NameClass */
.chroma .nc { .chroma .nc {
color: #75af00 color: #75af00;
} }
/* NameConstant */ /* NameConstant */
.chroma .no { .chroma .no {
color: #00a8c8 color: #00a8c8;
} }
/* NameDecorator */ /* NameDecorator */
.chroma .nd { .chroma .nd {
color: #75af00 color: #75af00;
} }
/* NameEntity */ /* NameEntity */
.chroma .ni { .chroma .ni {
color: #111111 color: #111111;
} }
/* NameException */ /* NameException */
.chroma .ne { .chroma .ne {
color: #75af00 color: #75af00;
} }
/* NameFunction */ /* NameFunction */
.chroma .nf { .chroma .nf {
color: #75af00 color: #75af00;
} }
/* NameFunctionMagic */ /* NameFunctionMagic */
.chroma .fm { .chroma .fm {
color: #111111 color: #111111;
} }
/* NameLabel */ /* NameLabel */
.chroma .nl { .chroma .nl {
color: #111111 color: #111111;
} }
/* NameNamespace */ /* NameNamespace */
.chroma .nn { .chroma .nn {
color: #111111 color: #111111;
} }
/* NameOther */ /* NameOther */
.chroma .nx { .chroma .nx {
color: #75af00 color: #75af00;
} }
/* NameProperty */ /* NameProperty */
.chroma .py { .chroma .py {
color: #111111 color: #111111;
} }
/* NameTag */ /* NameTag */
.chroma .nt { .chroma .nt {
color: #f92672 color: #f92672;
} }
/* NameVariable */ /* NameVariable */
.chroma .nv { .chroma .nv {
color: #111111 color: #111111;
} }
/* NameVariableClass */ /* NameVariableClass */
.chroma .vc { .chroma .vc {
color: #111111 color: #111111;
} }
/* NameVariableGlobal */ /* NameVariableGlobal */
.chroma .vg { .chroma .vg {
color: #111111 color: #111111;
} }
/* NameVariableInstance */ /* NameVariableInstance */
.chroma .vi { .chroma .vi {
color: #111111 color: #111111;
} }
/* NameVariableMagic */ /* NameVariableMagic */
.chroma .vm { .chroma .vm {
color: #111111 color: #111111;
} }
/* Literal */ /* Literal */
.chroma .l { .chroma .l {
color: #ae81ff color: #ae81ff;
} }
/* LiteralDate */ /* LiteralDate */
.chroma .ld { .chroma .ld {
color: #d88200 color: #d88200;
} }
/* LiteralString */ /* LiteralString */
.chroma .s { .chroma .s {
color: #d88200 color: #d88200;
} }
/* LiteralStringAffix */ /* LiteralStringAffix */
.chroma .sa { .chroma .sa {
color: #d88200 color: #d88200;
} }
/* LiteralStringBacktick */ /* LiteralStringBacktick */
.chroma .sb { .chroma .sb {
color: #d88200 color: #d88200;
} }
/* LiteralStringChar */ /* LiteralStringChar */
.chroma .sc { .chroma .sc {
color: #d88200 color: #d88200;
} }
/* LiteralStringDelimiter */ /* LiteralStringDelimiter */
.chroma .dl { .chroma .dl {
color: #d88200 color: #d88200;
} }
/* LiteralStringDoc */ /* LiteralStringDoc */
.chroma .sd { .chroma .sd {
color: #d88200 color: #d88200;
} }
/* LiteralStringDouble */ /* LiteralStringDouble */
.chroma .s2 { .chroma .s2 {
color: #d88200 color: #d88200;
} }
/* LiteralStringEscape */ /* LiteralStringEscape */
.chroma .se { .chroma .se {
color: #8045ff color: #8045ff;
} }
/* LiteralStringHeredoc */ /* LiteralStringHeredoc */
.chroma .sh { .chroma .sh {
color: #d88200 color: #d88200;
} }
/* LiteralStringInterpol */ /* LiteralStringInterpol */
.chroma .si { .chroma .si {
color: #d88200 color: #d88200;
} }
/* LiteralStringOther */ /* LiteralStringOther */
.chroma .sx { .chroma .sx {
color: #d88200 color: #d88200;
} }
/* LiteralStringRegex */ /* LiteralStringRegex */
.chroma .sr { .chroma .sr {
color: #d88200 color: #d88200;
} }
/* LiteralStringSingle */ /* LiteralStringSingle */
.chroma .s1 { .chroma .s1 {
color: #d88200 color: #d88200;
} }
/* LiteralStringSymbol */ /* LiteralStringSymbol */
.chroma .ss { .chroma .ss {
color: #d88200 color: #d88200;
} }
/* LiteralNumber */ /* LiteralNumber */
.chroma .m { .chroma .m {
color: #ae81ff color: #ae81ff;
} }
/* LiteralNumberBin */ /* LiteralNumberBin */
.chroma .mb { .chroma .mb {
color: #ae81ff color: #ae81ff;
} }
/* LiteralNumberFloat */ /* LiteralNumberFloat */
.chroma .mf { .chroma .mf {
color: #ae81ff color: #ae81ff;
} }
/* LiteralNumberHex */ /* LiteralNumberHex */
.chroma .mh { .chroma .mh {
color: #ae81ff color: #ae81ff;
} }
/* LiteralNumberInteger */ /* LiteralNumberInteger */
.chroma .mi { .chroma .mi {
color: #ae81ff color: #ae81ff;
} }
/* LiteralNumberIntegerLong */ /* LiteralNumberIntegerLong */
.chroma .il { .chroma .il {
color: #ae81ff color: #ae81ff;
} }
/* LiteralNumberOct */ /* LiteralNumberOct */
.chroma .mo { .chroma .mo {
color: #ae81ff color: #ae81ff;
} }
/* Operator */ /* Operator */
.chroma .o { .chroma .o {
color: #f92672 color: #f92672;
} }
/* OperatorWord */ /* OperatorWord */
.chroma .ow { .chroma .ow {
color: #f92672 color: #f92672;
} }
/* Punctuation */ /* Punctuation */
.chroma .p { .chroma .p {
color: #111111 color: #111111;
} }
/* Comment */ /* Comment */
.chroma .c { .chroma .c {
color: #75715e color: #75715e;
} }
/* CommentHashbang */ /* CommentHashbang */
.chroma .ch { .chroma .ch {
color: #75715e color: #75715e;
} }
/* CommentMultiline */ /* CommentMultiline */
.chroma .cm { .chroma .cm {
color: #75715e color: #75715e;
} }
/* CommentSingle */ /* CommentSingle */
.chroma .c1 { .chroma .c1 {
color: #75715e color: #75715e;
} }
/* CommentSpecial */ /* CommentSpecial */
.chroma .cs { .chroma .cs {
color: #75715e color: #75715e;
} }
/* CommentPreproc */ /* CommentPreproc */
.chroma .cp { .chroma .cp {
color: #75715e color: #75715e;
} }
/* CommentPreprocFile */ /* CommentPreprocFile */
.chroma .cpf { .chroma .cpf {
color: #75715e color: #75715e;
} }
/* Generic */ /* Generic */
.chroma .g {} .chroma .g {
}
/* GenericDeleted */ /* GenericDeleted */
.chroma .gd {} .chroma .gd {
color: #f92672;
}
/* GenericEmph */ /* GenericEmph */
.chroma .ge { .chroma .ge {
font-style: italic font-style: italic;
} }
/* GenericError */ /* GenericError */
.chroma .gr {} .chroma .gr {
}
/* GenericHeading */ /* GenericHeading */
.chroma .gh {} .chroma .gh {
}
/* GenericInserted */ /* GenericInserted */
.chroma .gi {} .chroma .gi {
color: #7ca727;
}
/* GenericOutput */ /* GenericOutput */
.chroma .go {} .chroma .go {
}
/* GenericPrompt */ /* GenericPrompt */
.chroma .gp {} .chroma .gp {
}
/* GenericStrong */ /* GenericStrong */
.chroma .gs { .chroma .gs {
font-weight: bold font-weight: bold;
} }
/* GenericSubheading */ /* GenericSubheading */
.chroma .gu {} .chroma .gu {
color: #75715e;
}
/* GenericTraceback */ /* GenericTraceback */
.chroma .gt {} .chroma .gt {
}
/* GenericUnderline */ /* GenericUnderline */
.chroma .gl {} .chroma .gl {
}
/* TextWhitespace */ /* TextWhitespace */
.chroma .w {} .chroma .w {
}
+10 -2
View File
@@ -71,7 +71,8 @@
text-transform: unset; text-transform: unset;
} }
.article-copyright, .article-lastmod { .article-copyright,
.article-lastmod {
a { a {
color: var(--body-text-color); color: var(--body-text-color);
} }
@@ -359,6 +360,12 @@
} }
} }
.table-wrapper {
padding: 0 var(--card-padding);
overflow-x: auto;
display: block;
}
table { table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
@@ -407,9 +414,10 @@
/// Negative margins /// Negative margins
blockquote, blockquote,
figure, figure,
.gallery,
pre, pre,
.gallery,
.video-wrapper, .video-wrapper,
.table-wrapper,
.s_video_simple { .s_video_simple {
margin-left: calc((var(--card-padding)) * -1); margin-left: calc((var(--card-padding)) * -1);
margin-right: calc((var(--card-padding)) * -1); margin-right: calc((var(--card-padding)) * -1);
+1
View File
@@ -8,6 +8,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
} }
[data-scheme="dark"] { [data-scheme="dark"] {
color-scheme: dark;
--pre-text-color: #f8f8f2; --pre-text-color: #f8f8f2;
--pre-background-color: #272822; --pre-background-color: #272822;
@import "partials/highlight/dark.scss"; @import "partials/highlight/dark.scss";
+1 -1
View File
@@ -58,7 +58,7 @@ let Stack = {
/** /**
* Add copy button to code block * Add copy button to code block
*/ */
const codeBlocks = document.querySelectorAll('.article-content .highlight'); const codeBlocks = document.querySelectorAll('.article-content > div.highlight');
const copyText = `Copy`, const copyText = `Copy`,
copiedText = `Copied!`; copiedText = `Copied!`;
codeBlocks.forEach(codeBlock => { codeBlocks.forEach(codeBlock => {
+118 -56
View File
@@ -8,6 +8,11 @@ interface pageData {
matchCount: number matchCount: number
} }
interface match {
start: number,
end: number
}
/** /**
* Escape HTML tags as HTML entities * Escape HTML tags as HTML entities
* Edited from: * Edited from:
@@ -53,79 +58,131 @@ class Search {
this.bindSearchForm(); this.bindSearchForm();
} }
private async searchKeywords(keywords: string[]) { /**
const rawData = await this.getData(); * Processes search matches
let results: pageData[] = []; * @param str original text
* @param matches array of matches
/// Sort keywords by their length * @param ellipsis whether to add ellipsis to the end of each match
keywords.sort((a, b) => { * @param charLimit max length of preview string
return b.length - a.length * @param offset how many characters before and after the match to include in preview
* @returns preview string
*/
private static processMatches(str: string, matches: match[], ellipsis: boolean = true, charLimit = 140, offset = 20): string {
matches.sort((a, b) => {
return a.start - b.start;
}); });
let i = 0,
lastIndex = 0,
charCount = 0;
const resultArray: string[] = [];
while (i < matches.length) {
const item = matches[i];
/// item.start >= lastIndex (equal only for the first iteration)
/// because of the while loop that comes after, iterating over variable j
if (ellipsis && item.start - offset > lastIndex) {
resultArray.push(`${replaceHTMLEnt(str.substring(lastIndex, lastIndex + offset))} [...] `);
resultArray.push(`${replaceHTMLEnt(str.substring(item.start - offset, item.start))}`);
charCount += offset * 2;
}
else {
/// If the match is too close to the end of last match, don't add ellipsis
resultArray.push(replaceHTMLEnt(str.substring(lastIndex, item.start)));
charCount += item.start - lastIndex;
}
let j = i + 1,
end = item.end;
/// Include as many matches as possible
/// [item.start, end] is the range of the match
while (j < matches.length && matches[j].start <= end) {
end = Math.max(matches[j].end, end);
++j;
}
resultArray.push(`<mark>${replaceHTMLEnt(str.substring(item.start, end))}</mark>`);
charCount += end - item.start;
i = j;
lastIndex = end;
if (ellipsis && charCount > charLimit) break;
}
/// Add the rest of the string
if (lastIndex < str.length) {
let end = str.length;
if (ellipsis) end = Math.min(end, lastIndex + offset);
resultArray.push(`${replaceHTMLEnt(str.substring(lastIndex, end))}`);
if (ellipsis && end != str.length) {
resultArray.push(` [...]`);
}
}
return resultArray.join('');
}
private async searchKeywords(keywords: string[]) {
const rawData = await this.getData();
const results: pageData[] = [];
const regex = new RegExp(keywords.filter((v, index, arr) => {
arr[index] = escapeRegExp(v);
return v.trim() !== '';
}).join('|'), 'gi');
for (const item of rawData) { for (const item of rawData) {
const titleMatches: match[] = [],
contentMatches: match[] = [];
let result = { let result = {
...item, ...item,
preview: '', preview: '',
matchCount: 0 matchCount: 0
} }
let matched = false; const contentMatchAll = item.content.matchAll(regex);
for (const match of Array.from(contentMatchAll)) {
for (const keyword of keywords) { contentMatches.push({
if (keyword === '') continue; start: match.index,
end: match.index + match[0].length
const regex = new RegExp(escapeRegExp(replaceHTMLEnt(keyword)), 'gi'); });
const contentMatch = regex.exec(result.content);
regex.lastIndex = 0; /// Reset regex
const titleMatch = regex.exec(result.title);
regex.lastIndex = 0; /// Reset regex
if (titleMatch) {
result.title = result.title.replace(regex, Search.marker);
}
if (titleMatch || contentMatch) {
matched = true;
++result.matchCount;
let start = 0,
end = 100;
if (contentMatch) {
start = contentMatch.index - 20;
end = contentMatch.index + 80
if (start < 0) start = 0;
}
if (result.preview.indexOf(keyword) !== -1) {
result.preview = result.preview.replace(regex, Search.marker);
}
else {
if (start !== 0) result.preview += `[...] `;
result.preview += `${result.content.slice(start, end).replace(regex, Search.marker)} `;
}
}
} }
if (matched) { const titleMatchAll = item.title.matchAll(regex);
result.preview += '[...]'; for (const match of Array.from(titleMatchAll)) {
results.push(result); titleMatches.push({
start: match.index,
end: match.index + match[0].length
});
} }
if (titleMatches.length > 0) result.title = Search.processMatches(result.title, titleMatches, false);
if (contentMatches.length > 0) {
result.preview = Search.processMatches(result.content, contentMatches);
}
else {
/// If there are no matches in the content, use the first 140 characters as preview
result.preview = replaceHTMLEnt(result.content.substring(0, 140));
}
result.matchCount = titleMatches.length + contentMatches.length;
if (result.matchCount > 0) results.push(result);
} }
/** Result with more matches appears first */ /// Result with more matches appears first
return results.sort((a, b) => { return results.sort((a, b) => {
return b.matchCount - a.matchCount; return b.matchCount - a.matchCount;
}); });
} }
public static marker(match) {
return '<mark>' + match + '</mark>';
}
private async doSearch(keywords: string[]) { private async doSearch(keywords: string[]) {
const startTime = performance.now(); const startTime = performance.now();
@@ -150,6 +207,11 @@ class Search {
/// Not fetched yet /// Not fetched yet
const jsonURL = this.form.dataset.json; const jsonURL = this.form.dataset.json;
this.data = await fetch(jsonURL).then(res => res.json()); this.data = await fetch(jsonURL).then(res => res.json());
const parser = new DOMParser();
for (const item of this.data) {
item.content = parser.parseFromString(item.content, 'text/html').body.innerText;
}
} }
return this.data; return this.data;
@@ -160,7 +222,7 @@ class Search {
const eventHandler = (e) => { const eventHandler = (e) => {
e.preventDefault(); e.preventDefault();
const keywords = this.input.value; const keywords = this.input.value.trim();
Search.updateQueryString(keywords, true); Search.updateQueryString(keywords, true);
@@ -225,7 +287,7 @@ class Search {
<a href={item.permalink}> <a href={item.permalink}>
<div class="article-details"> <div class="article-details">
<h2 class="article-title" dangerouslySetInnerHTML={{ __html: item.title }}></h2> <h2 class="article-title" dangerouslySetInnerHTML={{ __html: item.title }}></h2>
<secion class="article-preview" dangerouslySetInnerHTML={{ __html: item.preview }}></secion> <section class="article-preview" dangerouslySetInnerHTML={{ __html: item.preview }}></section>
</div> </div>
{item.image && {item.image &&
<div class="article-image"> <div class="article-image">
+5 -2
View File
@@ -22,6 +22,9 @@ _testmain.go
*.exe *.exe
*.test *.test
/public public
/themes themes
resources
assets/jsconfig.json
.DS_Store .DS_Store
+37
View File
@@ -0,0 +1,37 @@
---
title: Links
links:
- title: GitHub
description: GitHub is the world's largest software development platform.
website: https://github.com
image: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
- title: TypeScript
description: TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
website: https://www.typescriptlang.org
image: ts-logo-128.jpg
menu:
main:
weight: -50
params:
icon: link
comments: false
---
To use this feature, add `links` section to frontmatter.
This page's frontmatter:
```yaml
links:
- title: GitHub
description: GitHub is the world's largest software development platform.
website: https://github.com
image: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
- title: TypeScript
description: TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
website: https://www.typescriptlang.org
image: ts-logo-128.jpg
```
`image` field accepts both local and external images.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -69,6 +69,10 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou
| -------- | -------- | ------ | | -------- | -------- | ------ |
| *italics* | **bold** | `code` | | *italics* | **bold** | `code` |
| A | B | C | D | E | F |
|----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|------------------------------------------------------------|----------------------------------------------------------------------|
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. | Phasellus ultricies, sapien non euismod aliquam, dui ligula tincidunt odio, at accumsan nulla sapien eget ex. | Proin eleifend dictum ipsum, non euismod ipsum pulvinar et. Vivamus sollicitudin, quam in pulvinar aliquam, metus elit pretium purus | Proin sit amet velit nec enim imperdiet vehicula. | Ut bibendum vestibulum quam, eu egestas turpis gravida nec | Sed scelerisque nec turpis vel viverra. Vivamus vitae pretium sapien |
## Code Blocks ## Code Blocks
#### Code block with backticks #### Code block with backticks
@@ -113,6 +117,16 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou
</html> </html>
{{< /highlight >}} {{< /highlight >}}
#### Diff code block
```diff
[dependencies.bevy]
git = "https://github.com/bevyengine/bevy"
rev = "11f52b8c72fc3a568e8bb4a4cd1f3eb025ac2e13"
- features = ["dynamic"]
+ features = ["jpeg", "dynamic"]
```
## List Types ## List Types
#### Ordered List #### Ordered List
+3
View File
@@ -0,0 +1,3 @@
module github.com/CaiJimmy/hugo-theme-stack
go 1.12
+4
View File
@@ -29,6 +29,10 @@ article:
lastUpdatedOn: lastUpdatedOn:
other: Dernière mise à jour le other: Dernière mise à jour le
readingTime:
one: "{{ .Count }} minute de lecture"
other: "{{ .Count }} minutes de lecture"
notFound: notFound:
title: title:
other: Page non trouvée other: Page non trouvée
+30
View File
@@ -1,15 +1,42 @@
toggleMenu: toggleMenu:
other: 메뉴 여닫기 other: 메뉴 여닫기
darkMode:
other: 다크 모드
list:
page:
one: "{{ .Count }} 페이지"
other: "{{ .Count }} 페이지"
section:
other: 섹션
subsection:
one: 서브섹션
other: 서브섹션
article: article:
back:
other: 뒤로가기
tableOfContents:
other: 목차
relatedContents: relatedContents:
other: 관련 글 other: 관련 글
lastUpdatedOn: lastUpdatedOn:
other: "마지막 수정: " other: "마지막 수정: "
readingTime:
one: "{{ .Count }} 분 정도"
other: "{{ .Count }} 분 정도"
notFound: notFound:
title: title:
other: 찾을 수 없음 other: 찾을 수 없음
subtitle: subtitle:
other: 페이지를 찾을 수 없습니다. other: 페이지를 찾을 수 없습니다.
@@ -19,6 +46,7 @@ widget:
other: 보관함 other: 보관함
more: more:
other: 더보기 other: 더보기
tagCloud: tagCloud:
title: title:
other: 태그 other: 태그
@@ -26,8 +54,10 @@ widget:
search: search:
title: title:
other: 검색 other: 검색
placeholder: placeholder:
other: 검색어를 입력하세요... other: 검색어를 입력하세요...
resultTitle: resultTitle:
other: "#PAGES_COUNT 페이지 (#TIME_SECONDS 초)" other: "#PAGES_COUNT 페이지 (#TIME_SECONDS 초)"
+4
View File
@@ -15,6 +15,10 @@
{{ define "main" }} {{ define "main" }}
{{ partial "article/article.html" . }} {{ partial "article/article.html" . }}
{{ if .Params.links }}
{{ partial "article/components/links" . }}
{{ end }}
{{ partial "article/components/related-contents" . }} {{ partial "article/components/related-contents" . }}
{{ if not (eq .Params.comments false) }} {{ if not (eq .Params.comments false) }}
@@ -29,6 +29,7 @@
<img src="{{ $Permalink }}" <img src="{{ $Permalink }}"
width="{{ $Width }}" width="{{ $Width }}"
height="{{ $Height }}" height="{{ $Height }}"
alt="{{ .Title }}"
loading="lazy"> loading="lazy">
{{ else }} {{ else }}
<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" /> <img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
+3 -2
View File
@@ -20,8 +20,9 @@
<img src="{{ $Permalink }}" <img src="{{ $Permalink }}"
width="{{ $Width }}" width="{{ $Width }}"
height="{{ $Height }}" height="{{ $Height }}"
loading="lazy" loading="lazy"
data-key="{{ .context.Slug }}" alt="Featured image of post {{ .context.Title }}"
{{ with .context.Slug }}data-key="{{ . }}" {{ end }}
data-hash="{{ $imageRaw.Data.Integrity }}"> data-hash="{{ $imageRaw.Data.Integrity }}">
{{ else }} {{ else }}
<img src="{{ $image.permalink }}" loading="lazy" data-key="{{ .context.Slug }}" data-hash="{{ $image.permalink }}"/> <img src="{{ $image.permalink }}" loading="lazy" data-key="{{ .context.Slug }}" data-hash="{{ $image.permalink }}"/>
@@ -1,3 +1,5 @@
<section class="article-content"> <section class="article-content">
{{ .Content }} <!-- Refer to https://discourse.gohugo.io/t/responsive-tables-in-markdown/10639/5 -->
{{ $wrappedTable := printf "<div class=\"table-wrapper\">${1}</div>" }}
{{ .Content | replaceRE "(<table>(?:.|\n)+?</table>)" $wrappedTable | safeHTML }}
</section> </section>
@@ -0,0 +1,26 @@
<div class="article-list--compact links">
{{ range $i, $link := .Params.links }}
<article>
<a href="{{ $link.website }}" target="_blank" rel="noopener">
<div class="article-details">
<h2 class="article-title">
{{- $link.title -}}
</h2>
<footer class="article-time">
{{ with $link.description }}
{{ . }}
{{ else }}
{{ $link.website }}
{{ end }}
</footer>
</div>
{{ with $link.image }}
<div class="article-image">
<img src="{{ . }}" loading="lazy">
</div>
{{ end }}
</a>
</article>
{{ end }}
</div>
@@ -1,4 +1,4 @@
<script src="//cdn.jsdelivr.net/npm/[email protected].3/dist/twikoo.all.min.js"></script> <script src="//cdn.jsdelivr.net/npm/[email protected].15/dist/twikoo.all.min.js"></script>
<div id="tcomment"></div> <div id="tcomment"></div>
<style> <style>
.twikoo { .twikoo {
@@ -3,4 +3,10 @@
{{- $opts := dict "minify" hugo.IsProduction -}} {{- $opts := dict "minify" hugo.IsProduction -}}
{{- $script := resources.Get "ts/main.ts" | js.Build $opts -}} {{- $script := resources.Get "ts/main.ts" | js.Build $opts -}}
<script type="text/javascript" src="{{ $script.RelPermalink }}" defer></script> <script type="text/javascript" src="{{ $script.RelPermalink }}" defer></script>
{{- with resources.Get "ts/custom.ts" -}}
{{/* Place your custom script in HUGO_SITE_FOLDER/assets/ts/custom.ts */}}
{{- $customScript := . | js.Build $opts -}}
<script type="text/javascript" src="{{ $customScript.RelPermalink }}" defer></script>
{{- end -}}
+1 -1
View File
@@ -1,4 +1,4 @@
{{- $ThemeVersion := "3.5.0" -}} {{- $ThemeVersion := "3.7.0" -}}
<footer class="site-footer"> <footer class="site-footer">
<section class="copyright"> <section class="copyright">
&copy; &copy;
+1 -1
View File
@@ -1,3 +1,3 @@
{{ $sass := resources.Get "scss/style.scss" }} {{ $sass := resources.Get "scss/style.scss" }}
{{ $style := $sass | resources.ToCSS | minify }} {{ $style := $sass | resources.ToCSS | minify | resources.Fingerprint "sha256" }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}"> <link rel="stylesheet" href="{{ $style.RelPermalink }}">
+2 -1
View File
@@ -9,6 +9,7 @@
{{ with .Site.Params.sidebar.avatar }} {{ with .Site.Params.sidebar.avatar }}
{{ if (default true .enabled) }} {{ if (default true .enabled) }}
<figure class="site-avatar"> <figure class="site-avatar">
<a href="{{ .Site.BaseURL | relLangURL }}">
{{ if not .local }} {{ if not .local }}
<img src="{{ .src }}" width="300" height="300" class="site-logo" loading="lazy" alt="Avatar"> <img src="{{ .src }}" width="300" height="300" class="site-logo" loading="lazy" alt="Avatar">
{{ else }} {{ else }}
@@ -22,7 +23,7 @@
{{ errorf "Failed loading avatar from %q" . }} {{ errorf "Failed loading avatar from %q" . }}
{{ end }} {{ end }}
{{ end }} {{ end }}
</a>
{{ with $.Site.Params.sidebar.emoji }} {{ with $.Site.Params.sidebar.emoji }}
<span class="emoji">{{ . }}</span> <span class="emoji">{{ . }}</span>
{{ end }} {{ end }}