From 90959c505b389ba2758e80761136b93dc9963829 Mon Sep 17 00:00:00 2001 From: happylittle7 Date: Mon, 7 Mar 2022 12:30:05 +0800 Subject: [PATCH] update local changes --- README.md | 9 +- assets/jsconfig.json | 16 +- assets/scss/partials/base.scss | 14 -- assets/scss/partials/layout/article.scss | 12 +- assets/scss/variables.scss | 1 + assets/ts/main.ts | 2 +- assets/ts/search.tsx | 174 ++++++++++++------ .../content/post/markdown-syntax/index.md | 4 + go.mod | 3 + i18n/zh-TW.yaml | 29 ++- .../partials/article/components/content.html | 4 +- .../partials/comments/provider/giscus.html | 1 + .../partials/comments/provider/twikoo.html | 2 +- .../partials/footer/components/script.html | 8 +- layouts/partials/footer/footer.html | 2 +- layouts/partials/sidebar/left.html | 3 +- 16 files changed, 191 insertions(+), 93 deletions(-) create mode 100644 go.mod diff --git a/README.md b/README.md index ddacf82..0e6caa2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## 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) @@ -35,7 +35,10 @@ It's necessary to use **Hugo Extended ≥ 0.87.0**. ## 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.* @@ -77,4 +80,4 @@ Some references that I took while building this theme: | Project | Licence| | ------- | ------| | [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) | \ No newline at end of file +| [MunifTanjim/minimo](https://github.com/MunifTanjim/minimo) | [MIT](https://github.com/MunifTanjim/minimo/blob/master/LICENSE) | diff --git a/assets/jsconfig.json b/assets/jsconfig.json index 9321136..377218c 100644 --- a/assets/jsconfig.json +++ b/assets/jsconfig.json @@ -1,10 +1,10 @@ { - "compilerOptions": { - "baseUrl": ".", - "paths": { - "*": [ - "*" - ] - }, - } + "compilerOptions": { + "baseUrl": ".", + "paths": { + "*": [ + "*" + ] + } + } } \ No newline at end of file diff --git a/assets/scss/partials/base.scss b/assets/scss/partials/base.scss index ab3bf42..f02dcbd 100644 --- a/assets/scss/partials/base.scss +++ b/assets/scss/partials/base.scss @@ -23,17 +23,3 @@ body { 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; -} -/**/ diff --git a/assets/scss/partials/layout/article.scss b/assets/scss/partials/layout/article.scss index 7059853..b421cfc 100644 --- a/assets/scss/partials/layout/article.scss +++ b/assets/scss/partials/layout/article.scss @@ -71,7 +71,8 @@ text-transform: unset; } - .article-copyright, .article-lastmod { + .article-copyright, + .article-lastmod { a { color: var(--body-text-color); } @@ -359,6 +360,12 @@ } } + .table-wrapper { + padding: 0 var(--card-padding); + overflow-x: auto; + display: block; + } + table { width: 100%; border-collapse: collapse; @@ -407,9 +414,10 @@ /// Negative margins blockquote, figure, - .gallery, pre, + .gallery, .video-wrapper, + .table-wrapper, .s_video_simple { margin-left: calc((var(--card-padding)) * -1); margin-right: calc((var(--card-padding)) * -1); diff --git a/assets/scss/variables.scss b/assets/scss/variables.scss index c75eb5c..8e371d6 100644 --- a/assets/scss/variables.scss +++ b/assets/scss/variables.scss @@ -8,6 +8,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff; } [data-scheme="dark"] { + color-scheme: dark; --pre-text-color: #f8f8f2; --pre-background-color: #272822; @import "partials/highlight/dark.scss"; diff --git a/assets/ts/main.ts b/assets/ts/main.ts index d79c127..625bbbc 100644 --- a/assets/ts/main.ts +++ b/assets/ts/main.ts @@ -58,7 +58,7 @@ let Stack = { /** * Add copy button to code block */ - const codeBlocks = document.querySelectorAll('.article-content .highlight'); + const codeBlocks = document.querySelectorAll('.article-content > div.highlight'); const copyText = `Copy`, copiedText = `Copied!`; codeBlocks.forEach(codeBlock => { diff --git a/assets/ts/search.tsx b/assets/ts/search.tsx index 8e4eb6f..68db7b3 100644 --- a/assets/ts/search.tsx +++ b/assets/ts/search.tsx @@ -8,6 +8,11 @@ interface pageData { matchCount: number } +interface match { + start: number, + end: number +} + /** * Escape HTML tags as HTML entities * Edited from: @@ -53,79 +58,131 @@ class Search { this.bindSearchForm(); } - private async searchKeywords(keywords: string[]) { - const rawData = await this.getData(); - let results: pageData[] = []; - - /// Sort keywords by their length - keywords.sort((a, b) => { - return b.length - a.length + /** + * Processes search matches + * @param str original text + * @param matches array of matches + * @param ellipsis whether to add ellipsis to the end of each match + * @param charLimit max length of preview string + * @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(`${replaceHTMLEnt(str.substring(item.start, end))}`); + 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) { + const titleMatches: match[] = [], + contentMatches: match[] = []; + let result = { ...item, preview: '', matchCount: 0 } - let matched = false; - - for (const keyword of keywords) { - if (keyword === '') continue; - - 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)} `; - } - } + const contentMatchAll = item.content.matchAll(regex); + for (const match of Array.from(contentMatchAll)) { + contentMatches.push({ + start: match.index, + end: match.index + match[0].length + }); } - if (matched) { - result.preview += '[...]'; - results.push(result); + const titleMatchAll = item.title.matchAll(regex); + for (const match of Array.from(titleMatchAll)) { + 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 b.matchCount - a.matchCount; }); } - public static marker(match) { - return '' + match + ''; - } - private async doSearch(keywords: string[]) { const startTime = performance.now(); @@ -150,6 +207,11 @@ class Search { /// Not fetched yet const jsonURL = this.form.dataset.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; @@ -160,7 +222,7 @@ class Search { const eventHandler = (e) => { e.preventDefault(); - const keywords = this.input.value; + const keywords = this.input.value.trim(); Search.updateQueryString(keywords, true); @@ -225,7 +287,7 @@ class Search {

- +
{item.image &&
diff --git a/exampleSite/content/post/markdown-syntax/index.md b/exampleSite/content/post/markdown-syntax/index.md index 85fdcff..be381a0 100644 --- a/exampleSite/content/post/markdown-syntax/index.md +++ b/exampleSite/content/post/markdown-syntax/index.md @@ -69,6 +69,10 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou | -------- | -------- | ------ | | *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 block with backticks diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1cf4674 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/CaiJimmy/hugo-theme-stack + +go 1.12 diff --git a/i18n/zh-TW.yaml b/i18n/zh-TW.yaml index 871d937..7163879 100644 --- a/i18n/zh-TW.yaml +++ b/i18n/zh-TW.yaml @@ -4,6 +4,18 @@ toggleMenu: darkMode: other: 夜晚模式 +list: + page: + one: "{{ .Count }} 個頁面" + other: "{{ .Count }} 個頁面" + + section: + other: Section + + subsection: + one: Subsection + other: Subsections + article: back: other: 返回 @@ -18,13 +30,15 @@ article: other: 最後更新 readingTime: + one: "閱讀時間: {{ .Count }} 分鐘" other: "閱讀時間: {{ .Count }} 分鐘" notFound: title: - other: 404 錯誤 + other: 404 錯誤:( + subtitle: - other: 頁面不存在 + other: 頁面並不存在:( widget: archives: @@ -43,7 +57,14 @@ search: other: 搜尋 placeholder: - other: 輸入關鍵字... + other: 請輸入關鍵字... resultTitle: - other: "#PAGES_COUNT 個結果 (用時 #TIME_SECONDS 秒)" + other: "#PAGES_COUNT 個結果 (花了 #TIME_SECONDS 秒)" + +footer: + builtWith: + other: 使用 {{ .Generator }} 建造 + + designedBy: + other: 自豪的使用由 {{ .DesignedBy }} 設計的 {{ .Theme }} \ No newline at end of file diff --git a/layouts/partials/article/components/content.html b/layouts/partials/article/components/content.html index fc0f8f6..61e536c 100644 --- a/layouts/partials/article/components/content.html +++ b/layouts/partials/article/components/content.html @@ -1,3 +1,5 @@
- {{ .Content }} + + {{ $wrappedTable := printf "
${1}
" }} + {{ .Content | replaceRE "((?:.|\n)+?
)" $wrappedTable | safeHTML }}
diff --git a/layouts/partials/comments/provider/giscus.html b/layouts/partials/comments/provider/giscus.html index f36ead9..f43b71f 100644 --- a/layouts/partials/comments/provider/giscus.html +++ b/layouts/partials/comments/provider/giscus.html @@ -9,6 +9,7 @@ data-reactions-enabled="{{- default 1 .reactionsEnabled -}}" data-emit-metadata="{{- default 0 .emitMetadata -}}" data-theme="{{- default `light` .lightTheme -}}" + data-lang="zh-TW" crossorigin="anonymous" async > diff --git a/layouts/partials/comments/provider/twikoo.html b/layouts/partials/comments/provider/twikoo.html index 4dbf976..30c7033 100644 --- a/layouts/partials/comments/provider/twikoo.html +++ b/layouts/partials/comments/provider/twikoo.html @@ -1,4 +1,4 @@ - +