@jinyaoma/vuepress-theme-mustom
Version:
Simple design theme for VuePress,Blog,耀 の 个人网站 | Mark の Personal Website (QQ Group: 595614161)
401 lines (382 loc) • 11.1 kB
JavaScript
const md5 = require("md5");
const path = require("path");
const fs = require("fs");
const combineThemeConfig = (themeConfig, object) => {
for (const key in object) {
if (object[key] instanceof Array) {
if (!themeConfig.hasOwnProperty(key)) {
themeConfig[key] = [];
}
themeConfig[key] = themeConfig[key].concat(object[key]);
} else if (typeof object[key] === "object") {
if (!themeConfig.hasOwnProperty(key)) {
themeConfig[key] = {};
}
combineThemeConfig(themeConfig[key], object[key]);
} else {
if (!themeConfig.hasOwnProperty(key)) {
themeConfig[key] = object[key];
}
}
}
};
const generateGallery = (context) => {
let result = {
page: {},
list: []
};
let projectPath = "./";
const regex = /^.+\.(bmp|png|jpeg|jpg|gif|svg|webp)$/;
if (process.argv.length === 4 && /(dev|build)/.test(process.argv[2])) {
const projectName = process.argv[3];
projectPath = path.resolve(
process.cwd(),
projectName,
".vuepress/public/gallery"
);
} else if (process.argv.length === 3 && /(dev|build)/.test(process.argv[2])) {
projectPath = path.resolve(process.cwd(), ".vuepress/public/gallery");
}
if (fs.existsSync(projectPath) && fs.statSync(projectPath).isDirectory()) {
const ls = fs.readdirSync(projectPath);
if (ls && ls.length) {
ls.forEach((filename) => {
regex.test(filename) &&
result.list.push({
name: filename,
url: context.base + "gallery/" + filename
});
});
result.page = {
path: "/gallery/",
frontmatter: {
layout: "Layout",
title: "图库 | Gallery",
gallery: {
enabled: true
}
}
};
}
}
return result;
};
module.exports = (themeConfig, context) => {
const gallery = generateGallery(context);
combineThemeConfig(themeConfig, {
skins: [
{
name: "default", // locale match
color: "#696969"
},
{
name: "whiteblack", // locale match
color: "linear-gradient(120deg, #666666, #999999, #333333)"
},
{
name: "jshine", // locale match
color: "linear-gradient(120deg, #ff3300, #cc66ff, #00ccff)"
},
{
name: "memariani", // locale match
color: "linear-gradient(120deg, #cc6699, #6666cc, #33cccc)"
}
],
settings: [
{
name: "nightshift",
icon: '<i class="fas fa-adjust fa-fw"></i>'
},
{
name: "nocanvas",
icon: '<i class="fas fa-video-slash fa-fw"></i>'
},
{
name: "language",
icon: '<i class="fas fa-globe-asia fa-fw"></i>'
}
],
panels: [
{
caption: "categories",
icon: '<i class="fas fa-folder-open fa-fw"></i>'
},
{
caption: "tags",
icon: '<i class="fas fa-tags fa-fw"></i>'
}
],
hitokoto: {
api: "//v1.hitokoto.cn",
type: "l" // https://developer.hitokoto.cn/sentence/#请求参数
},
gallery: gallery.list
});
const name = "vuepress-theme-mustom";
const plugins = [
[
// https://vuepress-plugin-blog.ulivz.com/
"@vuepress/blog",
{
directories: [
{
id: "post",
title: "归档 | Archive",
dirname: "_posts",
path: "/archive/",
pagination: {
lengthPerPage: Infinity
},
layout: "Archive",
itemLayout: "Post"
}
],
frontmatters: [
{
id: "tags",
title: "标签 | Tags",
keys: ["tags"],
path: "/tag/",
scopeLayout: "Archive"
},
{
id: "categories",
title: "分类 | Categories",
keys: ["categories"],
path: "/category/",
scopeLayout: "Archive"
}
],
sitemap: {
hostname: themeConfig.domain || "https://ma-jinyao.cn",
dateFormatter:
themeConfig.dateFormatter ||
((time) => new Date(time).toISOString())
},
comment:
themeConfig.comment /* { // https://vuepress-plugin-blog.ulivz.com/guide/getting-started.html#comment
service: 'vssue',
owner: 'You',
repo: 'Your repo',
clientId: 'Your clientId',
clientSecret: 'Your clientSecret',
}*/
}
],
[
// https://vuepress.github.io/zh/plugins/zooming/
"vuepress-plugin-zooming",
{
selector: ".markdown-body img",
delay: 1000,
options: {
bgColor: "#000000ee",
scaleBase: 0.9,
zIndex: 999999999
}
}
],
[
// https://vuepress.github.io/zh/plugins/table-of-contents/
"vuepress-plugin-table-of-contents"
],
//[ // https://vuepress.github.io/zh/plugins/smooth-scroll/
// 'vuepress-plugin-smooth-scroll',
//],
[
// https://vuepress.github.io/zh/plugins/serve/
"vuepress-plugin-serve"
],
[
// https://vuepress.github.io/zh/plugins/mathjax/
"vuepress-plugin-mathjax"
],
[
// https://www.vuepress.cn/plugin/official/plugin-pwa.html
"@vuepress/pwa",
themeConfig.pwa || {}
],
[
// https://www.vuepress.cn/plugin/official/plugin-search.html
"@vuepress/search",
{
searchMaxSuggestions: 10
}
],
[
// https://shigma.github.io/markdown-it-pangu/vuepress.html
"vuepress-plugin-pangu"
],
[
// https://vuepress.github.io/zh/plugins/nprogress/
"vuepress-plugin-nprogress"
],
[
// https://github.com/JoeyBling/vuepress-plugin-helper-live2d
"vuepress-plugin-helper-live2d",
{
log: false,
live2d: {
enable: true,
model: "haruto",
display: {
position: "right",
width: 180,
height: 270,
hOffset: 48,
vOffset: 0
},
mobile: {
show: false
},
react: {
opacity: 1
}
}
}
],
[
// https://sns.goyfe.com/guide/
"vuepress-plugin-social-share",
themeConfig.socialShare /*{
networks: ['qq', 'weibo', 'douban', 'email', 'whatsapp', 'twitter', 'facebook', 'reddit', 'telegram', 'line'],
email: 'jinyao.ma@outlook.com',
fallbackImage: '/social-share.png',
autoQuote: true,
isPlain: true
}*/
],
[
// https://github.com/tolking/vuepress-plugin-img-lazy
"vuepress-plugin-img-lazy"
]
];
const alias = (o) => {
return {
"@theme": context.themeAPI.themePath
};
};
const define = (o) => {
return {
BUILD_TIMESTAMP: Date.now(),
BUILD_YEAR: new Date().getFullYear(),
VUEPRESS_OFFICIAL_SITE: "//vuepress.vuejs.org/",
THEME_REPO_URL: "//github.com/jinyaoMa/vuepress-theme-mustom",
THEME_NAME: name,
THEME_SHORTNAME: "Mustom",
THEME_AUTHOR: "jinyaoMa",
THEME_AUTHOR_LINK: "//github.com/jinyaoMa",
CC_LICENSE_LINK: "//creativecommons.org/licenses/by-nc-sa/4.0/"
};
};
const additionalPages = [
{
path: "/",
frontmatter: {
layout: "Home"
}
},
gallery.page
];
const extendPageData = ($page) => {
$page.frontmatter.lang = "zh-CN";
const content = $page._strippedContent;
// pangu
if (content) {
const pangunode = require("./scripts/pangunode");
$page.frontmatter.title = $page.title = pangunode($page.title || "");
$page._strippedContent = pangunode($page._strippedContent || "");
$page.excerpt = pangunode($page.excerpt || "");
}
if (
$page.frontmatter.records &&
$page.frontmatter.records.items &&
$page.frontmatter.records.items.length
) {
const pangunode = require("./scripts/pangunode");
$page.frontmatter.records.items.forEach((item) => {
item.summary = pangunode(item.summary || "");
});
}
// word count
if (content) {
const zh = (content.match(/[\u4E00-\u9FA5]/g) || []).length;
const en = (
content
.replace(/[\u4E00-\u9FA5]/g, "")
.match(
/[a-zA-Z0-9_\u0392-\u03c9\u0400-\u04FF]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|[\u00E4\u00C4\u00E5\u00C5\u00F6\u00D6]+|\w+/g
) || []
).length;
const min2read = zh / 150 + en / 100;
$page.frontmatter.wordcount = zh + en;
$page.frontmatter.min2read = min2read < 1 ? "1" : parseInt(min2read, 10);
} else {
$page.frontmatter.wordcount = 0;
$page.frontmatter.min2read = 0;
}
// extract cover
if (content) {
const matches = content.match(/\!\[[^\]]*\]\(\s*([^\)]+)\s*\)/) || [];
if (matches.length > 1) {
$page.frontmatter.cover = $page.frontmatter.image = matches[1].replace(
/\s+['"][^'"]+['"]$/,
""
);
} else {
$page.frontmatter.cover = null;
}
}
// generate desc
if (!$page.frontmatter.meta || !$page.frontmatter.meta.length) {
$page.frontmatter.meta = [];
}
if (content) {
if (content.trim().length === 0) {
$page.frontmatter.meta.push({
name: "description",
content:
$page.frontmatter.title + " - " + $page._computed.$description
});
} else {
$page.frontmatter.meta.push({
name: "description",
content:
content
.replace(/\r?\n|\r/g, "")
.replace(/<!--[^>]+-->/g, " | ")
.substr(0, 146) + " ..." // length 150
});
}
} else {
$page.frontmatter.meta.push({
name: "description",
content: $page.frontmatter.title + " - " + $page._computed.$description
});
}
// change post link
if (typeof $page.regularPath !== "undefined") {
const matches = $page.regularPath.match(/\/_posts\/(.+)(\.html)/);
if (matches && matches.length === 3) {
const pathArr = md5(decodeURIComponent(matches[1]));
$page.frontmatter.permalink = "/post/" + pathArr;
}
}
// add empty content flag
if (
typeof content !== "string" ||
content === "" ||
content.trim().length === 0
) {
$page.frontmatter.isContentEmpty = true;
}
};
return {
name,
plugins,
alias,
define,
additionalPages,
extendPageData
};
};