2025-2-26-fixed
This commit is contained in:
55
themes/next/scripts/events/index.js
Normal file
55
themes/next/scripts/events/index.js
Normal file
@ -0,0 +1,55 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
hexo.on('generateBefore', () => {
|
||||
// Merge config.
|
||||
require('./lib/config')(hexo);
|
||||
// Add filter type `theme_inject`
|
||||
require('./lib/injects')(hexo);
|
||||
});
|
||||
|
||||
hexo.on('generateAfter', () => {
|
||||
if (!hexo.theme.config.reminder) return;
|
||||
const https = require('https');
|
||||
const path = require('path');
|
||||
const { version } = require(path.normalize('../../package.json'));
|
||||
https.get('https://api.github.com/repos/theme-next/hexo-theme-next/releases/latest', {
|
||||
headers: {
|
||||
'User-Agent': 'Theme NexT Client'
|
||||
}
|
||||
}, res => {
|
||||
let result = '';
|
||||
res.on('data', data => {
|
||||
result += data;
|
||||
});
|
||||
res.on('end', () => {
|
||||
try {
|
||||
let latest = JSON.parse(result).tag_name.replace('v', '').split('.');
|
||||
let current = version.split('.');
|
||||
let isOutdated = false;
|
||||
for (let i = 0; i < Math.max(latest.length, current.length); i++) {
|
||||
if (!current[i] || latest[i] > current[i]) {
|
||||
isOutdated = true;
|
||||
break;
|
||||
}
|
||||
if (latest[i] < current[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isOutdated) {
|
||||
hexo.log.warn(`Your theme NexT is outdated. Current version: v${current.join('.')}, latest version: v${latest.join('.')}`);
|
||||
hexo.log.warn('Visit https://github.com/theme-next/hexo-theme-next/releases for more information.');
|
||||
} else {
|
||||
hexo.log.info('Congratulations! Your are using the latest version of theme NexT.');
|
||||
}
|
||||
} catch (err) {
|
||||
hexo.log.error('Failed to detect version info. Error message:');
|
||||
hexo.log.error(err);
|
||||
}
|
||||
});
|
||||
}).on('error', err => {
|
||||
hexo.log.error('Failed to detect version info. Error message:');
|
||||
hexo.log.error(err);
|
||||
});
|
||||
});
|
||||
60
themes/next/scripts/events/lib/config.js
Normal file
60
themes/next/scripts/events/lib/config.js
Normal file
@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
|
||||
function isObject(item) {
|
||||
return item && typeof item === 'object' && !Array.isArray(item);
|
||||
}
|
||||
|
||||
function merge(target, source) {
|
||||
for (const key in source) {
|
||||
if (isObject(target[key]) && isObject(source[key])) {
|
||||
merge(target[key], source[key]);
|
||||
} else {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
module.exports = hexo => {
|
||||
let data = hexo.locals.get('data');
|
||||
|
||||
/**
|
||||
* Merge configs from _data/next.yml into hexo.theme.config.
|
||||
* If `override`, configs in next.yml will rewrite configs in hexo.theme.config.
|
||||
* If next.yml not exists, merge all `theme_config.*` into hexo.theme.config.
|
||||
*/
|
||||
if (data.next) {
|
||||
if (data.next.override) {
|
||||
hexo.theme.config = data.next;
|
||||
} else {
|
||||
merge(hexo.config, data.next);
|
||||
merge(hexo.theme.config, data.next);
|
||||
}
|
||||
} else {
|
||||
merge(hexo.theme.config, hexo.config.theme_config);
|
||||
}
|
||||
|
||||
if (hexo.theme.config.cache && hexo.theme.config.cache.enable && hexo.config.relative_link) {
|
||||
hexo.log.warn('Since caching is turned on, the `relative_link` option in Hexo `_config.yml` is set to `false` to avoid potential hazards.');
|
||||
hexo.config.relative_link = false;
|
||||
}
|
||||
hexo.config.meta_generator = false;
|
||||
|
||||
// Custom languages support. Introduced in NexT v6.3.0.
|
||||
if (data.languages) {
|
||||
let { language } = hexo.config;
|
||||
let { i18n } = hexo.theme;
|
||||
|
||||
const mergeLang = lang => {
|
||||
i18n.set(lang, merge(i18n.get([lang]), data.languages[lang]));
|
||||
};
|
||||
|
||||
if (Array.isArray(language)) {
|
||||
for (let lang of language) {
|
||||
mergeLang(lang);
|
||||
}
|
||||
} else {
|
||||
mergeLang(language);
|
||||
}
|
||||
}
|
||||
};
|
||||
19
themes/next/scripts/events/lib/injects-point.js
Normal file
19
themes/next/scripts/events/lib/injects-point.js
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
views: [
|
||||
'head',
|
||||
'header',
|
||||
'sidebar',
|
||||
'postMeta',
|
||||
'postBodyEnd',
|
||||
'footer',
|
||||
'bodyEnd',
|
||||
'comment'
|
||||
],
|
||||
styles: [
|
||||
'variable',
|
||||
'mixin',
|
||||
'style'
|
||||
]
|
||||
};
|
||||
85
themes/next/scripts/events/lib/injects.js
Normal file
85
themes/next/scripts/events/lib/injects.js
Normal file
@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const points = require('./injects-point');
|
||||
const defaultExtname = '.swig';
|
||||
|
||||
// Defining stylus types
|
||||
class StylusInject {
|
||||
constructor(base_dir) {
|
||||
this.base_dir = base_dir;
|
||||
this.files = [];
|
||||
}
|
||||
push(file) {
|
||||
// Get absolute path base on hexo dir
|
||||
this.files.push(path.resolve(this.base_dir, file));
|
||||
}
|
||||
}
|
||||
|
||||
// Defining view types
|
||||
class ViewInject {
|
||||
constructor(base_dir) {
|
||||
this.base_dir = base_dir;
|
||||
this.raws = [];
|
||||
}
|
||||
raw(name, raw, ...args) {
|
||||
// Set default extname
|
||||
if (path.extname(name) === '') {
|
||||
name += defaultExtname;
|
||||
}
|
||||
this.raws.push({name, raw, args});
|
||||
}
|
||||
file(name, file, ...args) {
|
||||
// Set default extname from file's extname
|
||||
if (path.extname(name) === '') {
|
||||
name += path.extname(file);
|
||||
}
|
||||
// Get absolute path base on hexo dir
|
||||
this.raw(name, fs.readFileSync(path.resolve(this.base_dir, file), 'utf8'), ...args);
|
||||
}
|
||||
}
|
||||
|
||||
// Init injects
|
||||
function initInject(base_dir) {
|
||||
let injects = {};
|
||||
points.styles.forEach(item => {
|
||||
injects[item] = new StylusInject(base_dir);
|
||||
});
|
||||
points.views.forEach(item => {
|
||||
injects[item] = new ViewInject(base_dir);
|
||||
});
|
||||
return injects;
|
||||
}
|
||||
|
||||
module.exports = hexo => {
|
||||
// Exec theme_inject filter
|
||||
let injects = initInject(hexo.base_dir);
|
||||
hexo.execFilterSync('theme_inject', injects);
|
||||
hexo.theme.config.injects = {};
|
||||
|
||||
// Inject stylus
|
||||
points.styles.forEach(type => {
|
||||
hexo.theme.config.injects[type] = injects[type].files;
|
||||
});
|
||||
|
||||
// Inject views
|
||||
points.views.forEach(type => {
|
||||
let configs = Object.create(null);
|
||||
hexo.theme.config.injects[type] = [];
|
||||
// Add or override view.
|
||||
injects[type].raws.forEach((injectObj, index) => {
|
||||
let name = `inject/${type}/${injectObj.name}`;
|
||||
hexo.theme.setView(name, injectObj.raw);
|
||||
configs[name] = {
|
||||
layout : name,
|
||||
locals : injectObj.args[0],
|
||||
options: injectObj.args[1],
|
||||
order : injectObj.args[2] || index
|
||||
};
|
||||
});
|
||||
// Views sort.
|
||||
hexo.theme.config.injects[type] = Object.values(configs)
|
||||
.sort((x, y) => x.order - y.order);
|
||||
});
|
||||
};
|
||||
45
themes/next/scripts/filters/comment/changyan.js
Normal file
45
themes/next/scripts/filters/comment/changyan.js
Normal file
@ -0,0 +1,45 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const { iconText } = require('./common');
|
||||
|
||||
// Add comment
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.changyan.enable || !theme.changyan.appid || !theme.changyan.appkey) return;
|
||||
|
||||
injects.comment.raw('changyan', `
|
||||
<div class="comments">
|
||||
<div id="SOHUCS"></div>
|
||||
</div>
|
||||
`, {}, {cache: true});
|
||||
|
||||
injects.bodyEnd.file('changyan', path.join(hexo.theme_dir, 'layout/_third-party/comments/changyan.swig'));
|
||||
|
||||
});
|
||||
|
||||
// Add post_meta
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.changyan.enable || !theme.changyan.appid || !theme.changyan.appkey) return;
|
||||
|
||||
injects.postMeta.raw('changyan', `
|
||||
{% if post.comments %}
|
||||
<span class="post-meta-item">
|
||||
${iconText('far fa-comment', 'changyan')}
|
||||
{% if is_post() %}
|
||||
<a title="changyan" href="{{ url_for(post.path) }}#SOHUCS" itemprop="discussionUrl">
|
||||
<span id="changyan_count_unit" class="post-comments-count hc-comment-count" data-xid="{{ post.path }}" itemprop="commentCount"></span>
|
||||
</a>
|
||||
{% else %}
|
||||
<a title="changyan" href="{{ url_for(post.path) }}#SOHUCS" itemprop="discussionUrl">
|
||||
<span id="url::{{ post.permalink }}" class="cy_cmt_count" data-xid="{{ post.path }}" itemprop="commentCount"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
`, {}, {}, theme.changyan.post_meta_order);
|
||||
|
||||
});
|
||||
23
themes/next/scripts/filters/comment/common.js
Normal file
23
themes/next/scripts/filters/comment/common.js
Normal file
@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
function capitalize(input) {
|
||||
return input.toString().charAt(0).toUpperCase() + input.toString().substr(1);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
iconText(icon, key, defaultValue) {
|
||||
if (!defaultValue) {
|
||||
defaultValue = capitalize(key);
|
||||
}
|
||||
return `
|
||||
<span class="post-meta-item-icon">
|
||||
<i class="${icon}"></i>
|
||||
</span>
|
||||
{%- set post_meta_comment = __('post.comments.${key}') %}
|
||||
{%- if post_meta_comment == 'post.comments.${key}' %}
|
||||
{%- set post_meta_comment = '${defaultValue}' %}
|
||||
{%- endif %}
|
||||
<span class="post-meta-item-text">{{ post_meta_comment + __('symbol.colon') }}</span>
|
||||
`;
|
||||
}
|
||||
};
|
||||
34
themes/next/scripts/filters/comment/default-config.js
Normal file
34
themes/next/scripts/filters/comment/default-config.js
Normal file
@ -0,0 +1,34 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
injects.comment.raws.forEach(element => {
|
||||
// Set default button content
|
||||
let injectName = path.basename(element.name, path.extname(element.name));
|
||||
element.args[0] = Object.assign({
|
||||
configKey: injectName,
|
||||
class : injectName,
|
||||
button : injectName
|
||||
}, element.args[0]);
|
||||
// Get locals and config
|
||||
let locals = element.args[0];
|
||||
let config = hexo.theme.config.comments;
|
||||
// Set activeClass
|
||||
if (config.active === locals.configKey) {
|
||||
config.activeClass = locals.class;
|
||||
}
|
||||
// Set custom button content
|
||||
if (config.nav) {
|
||||
let nav = config.nav[locals.configKey] || {};
|
||||
if (nav.order) {
|
||||
element.args[2] = nav.order;
|
||||
}
|
||||
if (nav.text) {
|
||||
locals.button = nav.text;
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 99999);
|
||||
41
themes/next/scripts/filters/comment/disqus.js
Normal file
41
themes/next/scripts/filters/comment/disqus.js
Normal file
@ -0,0 +1,41 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const { iconText } = require('./common');
|
||||
|
||||
// Add comment
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.disqus.enable || !theme.disqus.shortname) return;
|
||||
|
||||
injects.comment.raw('disqus', `
|
||||
<div class="comments">
|
||||
<div id="disqus_thread">
|
||||
<noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
|
||||
</div>
|
||||
</div>
|
||||
`, {}, {cache: true});
|
||||
|
||||
injects.bodyEnd.file('disqus', path.join(hexo.theme_dir, 'layout/_third-party/comments/disqus.swig'));
|
||||
|
||||
});
|
||||
|
||||
// Add post_meta
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.disqus.enable || !theme.disqus.shortname || !theme.disqus.count) return;
|
||||
|
||||
injects.postMeta.raw('disqus', `
|
||||
{% if post.comments %}
|
||||
<span class="post-meta-item">
|
||||
${iconText('far fa-comment', 'disqus')}
|
||||
<a title="disqus" href="{{ url_for(post.path) }}#disqus_thread" itemprop="discussionUrl">
|
||||
<span class="post-comments-count disqus-comment-count" data-disqus-identifier="{{ post.path }}" itemprop="commentCount"></span>
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
`, {}, {}, theme.disqus.post_meta_order);
|
||||
|
||||
});
|
||||
22
themes/next/scripts/filters/comment/disqusjs.js
Normal file
22
themes/next/scripts/filters/comment/disqusjs.js
Normal file
@ -0,0 +1,22 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
// Add comment
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.disqusjs.enable || !theme.disqusjs.shortname || !theme.disqusjs.apikey) return;
|
||||
|
||||
injects.comment.raw('disqusjs', `
|
||||
<div class="comments">
|
||||
<div id="disqus_thread">
|
||||
<noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
|
||||
</div>
|
||||
</div>
|
||||
`, {}, {cache: true});
|
||||
|
||||
injects.bodyEnd.file('disqusjs', path.join(hexo.theme_dir, 'layout/_third-party/comments/disqusjs.swig'));
|
||||
|
||||
});
|
||||
16
themes/next/scripts/filters/comment/gitalk.js
Normal file
16
themes/next/scripts/filters/comment/gitalk.js
Normal file
@ -0,0 +1,16 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
// Add comment
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.gitalk.enable) return;
|
||||
|
||||
injects.comment.raw('gitalk', '<div class="comments" id="gitalk-container"></div>', {}, {cache: true});
|
||||
|
||||
injects.bodyEnd.file('gitalk', path.join(hexo.theme_dir, 'layout/_third-party/comments/gitalk.swig'));
|
||||
|
||||
});
|
||||
20
themes/next/scripts/filters/comment/livere.js
Normal file
20
themes/next/scripts/filters/comment/livere.js
Normal file
@ -0,0 +1,20 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
// Add comment
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.livere_uid) return;
|
||||
|
||||
injects.comment.raw('livere', `
|
||||
<div class="comments">
|
||||
<div id="lv-container" data-id="city" data-uid="{{ theme.livere_uid }}"></div>
|
||||
</div>
|
||||
`, {}, {cache: true});
|
||||
|
||||
injects.bodyEnd.file('livere', path.join(hexo.theme_dir, 'layout/_third-party/comments/livere.swig'));
|
||||
|
||||
});
|
||||
35
themes/next/scripts/filters/comment/valine.js
Normal file
35
themes/next/scripts/filters/comment/valine.js
Normal file
@ -0,0 +1,35 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const { iconText } = require('./common');
|
||||
|
||||
// Add comment
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.valine.enable || !theme.valine.appid || !theme.valine.appkey) return;
|
||||
|
||||
injects.comment.raw('valine', '<div class="comments" id="valine-comments"></div>', {}, {cache: true});
|
||||
|
||||
injects.bodyEnd.file('valine', path.join(hexo.theme_dir, 'layout/_third-party/comments/valine.swig'));
|
||||
|
||||
});
|
||||
|
||||
// Add post_meta
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let theme = hexo.theme.config;
|
||||
if (!theme.valine.enable || !theme.valine.appid || !theme.valine.appkey) return;
|
||||
|
||||
injects.postMeta.raw('valine', `
|
||||
{% if post.comments and (is_post() or theme.valine.comment_count) %}
|
||||
<span class="post-meta-item">
|
||||
${iconText('far fa-comment', 'valine')}
|
||||
<a title="valine" href="{{ url_for(post.path) }}#valine-comments" itemprop="discussionUrl">
|
||||
<span class="post-comments-count valine-comment-count" data-xid="{{ url_for(post.path) }}" itemprop="commentCount"></span>
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
`, {}, {}, theme.valine.post_meta_order);
|
||||
|
||||
});
|
||||
24
themes/next/scripts/filters/default-injects.js
Normal file
24
themes/next/scripts/filters/default-injects.js
Normal file
@ -0,0 +1,24 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const points = require('../events/lib/injects-point');
|
||||
|
||||
hexo.extend.filter.register('theme_inject', injects => {
|
||||
let filePath = hexo.theme.config.custom_file_path;
|
||||
|
||||
if (!filePath) return;
|
||||
|
||||
points.views.forEach(key => {
|
||||
if (filePath[key]) {
|
||||
injects[key].file('custom', filePath[key]);
|
||||
}
|
||||
});
|
||||
|
||||
points.styles.forEach(key => {
|
||||
if (filePath[key]) {
|
||||
injects[key].push(filePath[key]);
|
||||
}
|
||||
});
|
||||
|
||||
}, 99);
|
||||
71
themes/next/scripts/filters/front-matter.js
Normal file
71
themes/next/scripts/filters/front-matter.js
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Modify front-matter.
|
||||
*
|
||||
* Some keys are included by Hexo, please don't use them.
|
||||
* e.g. layout title date updated comments tags categories permalink keywords
|
||||
*
|
||||
* Some keys are generated by Hexo, don't use them either.
|
||||
* e.g. content excerpt more source full_source path permalink prev next raw photos link
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const keys = ['toc', 'reward_settings', 'quicklink'];
|
||||
|
||||
function showWarnLog(source, variable) {
|
||||
hexo.log.warn(`front-matter: '${variable}' has deprecated, source: ${source}`);
|
||||
hexo.log.warn('see: https://github.com/theme-next/hexo-theme-next/pull/1211');
|
||||
}
|
||||
|
||||
function compatibleBeforeAssign(page) {
|
||||
if (page.quicklink === true) {
|
||||
page.quicklink = {enable: true};
|
||||
showWarnLog(page.source, 'quicklink:true');
|
||||
}
|
||||
if (page.quicklink === false) {
|
||||
page.quicklink = {enable: false};
|
||||
showWarnLog(page.source, 'quicklink:true');
|
||||
}
|
||||
}
|
||||
|
||||
function compatibleAfterAssign(page) {
|
||||
if (page.reward !== undefined) {
|
||||
page.reward_settings.enable = page.reward;
|
||||
showWarnLog(page.source, 'reward');
|
||||
}
|
||||
if (page.toc_number !== undefined) {
|
||||
page.toc.number = page.toc_number;
|
||||
showWarnLog(page.source, 'toc_number');
|
||||
}
|
||||
if (page.toc_max_depth !== undefined) {
|
||||
page.toc.max_depth = page.toc_max_depth;
|
||||
showWarnLog(page.source, 'toc_max_depth');
|
||||
}
|
||||
}
|
||||
|
||||
hexo.extend.filter.register('template_locals', locals => {
|
||||
const { page, theme } = locals;
|
||||
|
||||
compatibleBeforeAssign(page);
|
||||
|
||||
keys.forEach(key => {
|
||||
page[key] = Object.assign({}, theme[key], page[key]);
|
||||
});
|
||||
|
||||
compatibleAfterAssign(page);
|
||||
|
||||
// Set default value for toc.max_depth
|
||||
if (!page.toc.max_depth) {
|
||||
page.toc.max_depth = 6;
|
||||
}
|
||||
|
||||
// Set home or archive quicklink
|
||||
if (page.__index) {
|
||||
page.quicklink.enable = theme.quicklink.home;
|
||||
}
|
||||
if (page.archive) {
|
||||
page.quicklink.enable = theme.quicklink.archive;
|
||||
}
|
||||
});
|
||||
26
themes/next/scripts/filters/locals.js
Normal file
26
themes/next/scripts/filters/locals.js
Normal file
@ -0,0 +1,26 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
hexo.extend.filter.register('template_locals', locals => {
|
||||
const { env, config } = hexo;
|
||||
const { __, theme } = locals;
|
||||
const { i18n } = hexo.theme;
|
||||
// Hexo & NexT version
|
||||
locals.hexo_version = env.version;
|
||||
locals.next_version = require(path.normalize('../../package.json')).version;
|
||||
// Language & Config
|
||||
locals.title = __('title') !== 'title' ? __('title') : config.title;
|
||||
locals.subtitle = __('subtitle') !== 'subtitle' ? __('subtitle') : config.subtitle;
|
||||
locals.author = __('author') !== 'author' ? __('author') : config.author;
|
||||
locals.description = __('description') !== 'description' ? __('description') : config.description;
|
||||
locals.languages = [...i18n.languages];
|
||||
locals.languages.splice(locals.languages.indexOf('default'), 1);
|
||||
locals.page.lang = locals.page.lang || locals.page.language;
|
||||
// Creative Commons
|
||||
locals.ccURL = 'https://creativecommons.org/' + (theme.creative_commons.license === 'zero' ? 'publicdomain/zero/1.0/' : 'licenses/' + theme.creative_commons.license + '/4.0/') + (theme.creative_commons.language || '');
|
||||
// PJAX
|
||||
locals.pjax = theme.pjax ? ' data-pjax' : '';
|
||||
});
|
||||
53
themes/next/scripts/filters/minify.js
Normal file
53
themes/next/scripts/filters/minify.js
Normal file
@ -0,0 +1,53 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
hexo.extend.filter.register('after_generate', () => {
|
||||
const theme = hexo.theme.config;
|
||||
if (!theme.minify) return;
|
||||
|
||||
const lists = hexo.route.list();
|
||||
const velocity = lists.filter(list => list.includes('lib/velocity'));
|
||||
const fontawesome = lists.filter(list => list.includes('lib/font-awesome'));
|
||||
|
||||
if (!theme.bookmark.enable) {
|
||||
hexo.route.remove('js/bookmark.js');
|
||||
}
|
||||
|
||||
if (!theme.motion.enable) {
|
||||
hexo.route.remove('js/motion.js');
|
||||
velocity.forEach(path => {
|
||||
hexo.route.remove(path);
|
||||
});
|
||||
}
|
||||
|
||||
if (theme.motion.enable && theme.vendors.velocity && theme.vendors.velocity_ui) {
|
||||
velocity.forEach(path => {
|
||||
hexo.route.remove(path);
|
||||
});
|
||||
}
|
||||
|
||||
if (theme.vendors.fontawesome) {
|
||||
fontawesome.forEach(path => {
|
||||
hexo.route.remove(path);
|
||||
});
|
||||
}
|
||||
|
||||
if (theme.vendors.anime) {
|
||||
hexo.route.remove('lib/anime.min.js');
|
||||
}
|
||||
|
||||
if (!theme.algolia_search.enable) {
|
||||
hexo.route.remove('js/algolia-search.js');
|
||||
}
|
||||
|
||||
if (!theme.local_search.enable) {
|
||||
hexo.route.remove('js/local-search.js');
|
||||
}
|
||||
|
||||
if (theme.scheme === 'Muse' || theme.scheme === 'Mist') {
|
||||
hexo.route.remove('js/schemes/pisces.js');
|
||||
} else if (theme.scheme === 'Pisces' || theme.scheme === 'Gemini') {
|
||||
hexo.route.remove('js/schemes/muse.js');
|
||||
}
|
||||
});
|
||||
27
themes/next/scripts/filters/post.js
Normal file
27
themes/next/scripts/filters/post.js
Normal file
@ -0,0 +1,27 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
hexo.extend.filter.register('after_post_render', data => {
|
||||
const { config } = hexo;
|
||||
const theme = hexo.theme.config;
|
||||
if (!theme.exturl && !theme.lazyload) return;
|
||||
if (theme.lazyload) {
|
||||
data.content = data.content.replace(/(<img[^>]*) src=/img, '$1 data-src=');
|
||||
}
|
||||
if (theme.exturl) {
|
||||
const url = require('url');
|
||||
const siteHost = url.parse(config.url).hostname || config.url;
|
||||
data.content = data.content.replace(/<a[^>]* href="([^"]+)"[^>]*>([^<]+)<\/a>/img, (match, href, html) => {
|
||||
// Exit if the href attribute doesn't exists.
|
||||
if (!href) return match;
|
||||
|
||||
// Exit if the url has same host with `config.url`, which means it's an internal link.
|
||||
let link = url.parse(href);
|
||||
if (!link.protocol || link.hostname === siteHost) return match;
|
||||
|
||||
return `<span class="exturl" data-url="${Buffer.from(href).toString('base64')}">${html}<i class="fa fa-external-link-alt"></i></span>`;
|
||||
});
|
||||
}
|
||||
|
||||
}, 0);
|
||||
84
themes/next/scripts/helpers/engine.js
Normal file
84
themes/next/scripts/helpers/engine.js
Normal file
@ -0,0 +1,84 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const crypto = require('crypto');
|
||||
|
||||
hexo.extend.helper.register('next_inject', function(point) {
|
||||
return hexo.theme.config.injects[point]
|
||||
.map(item => this.partial(item.layout, item.locals, item.options))
|
||||
.join('');
|
||||
});
|
||||
|
||||
hexo.extend.helper.register('next_js', function(...urls) {
|
||||
const { js } = hexo.theme.config;
|
||||
return urls.map(url => this.js(`${js}/${url}`)).join('');
|
||||
});
|
||||
|
||||
hexo.extend.helper.register('next_vendors', function(url) {
|
||||
if (url.startsWith('//')) return url;
|
||||
const internal = hexo.theme.config.vendors._internal;
|
||||
return this.url_for(`${internal}/${url}`);
|
||||
});
|
||||
|
||||
hexo.extend.helper.register('post_edit', function(src) {
|
||||
const theme = hexo.theme.config;
|
||||
if (!theme.post_edit.enable) return '';
|
||||
return this.next_url(theme.post_edit.url + src, '<i class="fa fa-pencil-alt"></i>', {
|
||||
class: 'post-edit-link',
|
||||
title: this.__('post.edit')
|
||||
});
|
||||
});
|
||||
|
||||
hexo.extend.helper.register('post_nav', function(post) {
|
||||
const theme = hexo.theme.config;
|
||||
if (theme.post_navigation === false || (!post.prev && !post.next)) return '';
|
||||
const prev = theme.post_navigation === 'right' ? post.prev : post.next;
|
||||
const next = theme.post_navigation === 'right' ? post.next : post.prev;
|
||||
const left = prev ? `
|
||||
<a href="${this.url_for(prev.path)}" rel="prev" title="${prev.title}">
|
||||
<i class="fa fa-chevron-left"></i> ${prev.title}
|
||||
</a>` : '';
|
||||
const right = next ? `
|
||||
<a href="${this.url_for(next.path)}" rel="next" title="${next.title}">
|
||||
${next.title} <i class="fa fa-chevron-right"></i>
|
||||
</a>` : '';
|
||||
return `
|
||||
<div class="post-nav">
|
||||
<div class="post-nav-item">${left}</div>
|
||||
<div class="post-nav-item">${right}</div>
|
||||
</div>`;
|
||||
});
|
||||
|
||||
hexo.extend.helper.register('gitalk_md5', function(path) {
|
||||
let str = this.url_for(path);
|
||||
str.replace('index.html', '');
|
||||
return crypto.createHash('md5').update(str).digest('hex');
|
||||
});
|
||||
|
||||
hexo.extend.helper.register('canonical', function() {
|
||||
// https://support.google.com/webmasters/answer/139066
|
||||
const { permalink } = hexo.config;
|
||||
let url = this.url.replace(/index\.html$/, '');
|
||||
if (!permalink.endsWith('.html')) {
|
||||
url = url.replace(/\.html$/, '');
|
||||
}
|
||||
return `<link rel="canonical" href="${url}">`;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get page path given a certain language tag
|
||||
*/
|
||||
hexo.extend.helper.register('i18n_path', function(language) {
|
||||
const { path, lang } = this.page;
|
||||
const base = path.startsWith(lang) ? path.slice(lang.length + 1) : path;
|
||||
return this.url_for(`${this.languages.indexOf(language) === 0 ? '' : '/' + language}/${base}`);
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the language name
|
||||
*/
|
||||
hexo.extend.helper.register('language_name', function(language) {
|
||||
const name = hexo.theme.i18n.__(language)('name');
|
||||
return name === 'name' ? language : name;
|
||||
});
|
||||
29
themes/next/scripts/helpers/font.js
Normal file
29
themes/next/scripts/helpers/font.js
Normal file
@ -0,0 +1,29 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
hexo.extend.helper.register('next_font', () => {
|
||||
const config = hexo.theme.config.font;
|
||||
|
||||
if (!config || !config.enable) return '';
|
||||
|
||||
const fontDisplay = '&display=swap';
|
||||
const fontSubset = '&subset=latin,latin-ext';
|
||||
const fontStyles = ':300,300italic,400,400italic,700,700italic';
|
||||
const fontHost = config.host || '//fonts.googleapis.com';
|
||||
|
||||
//Get a font list from config
|
||||
let fontFamilies = ['global', 'title', 'headings', 'posts', 'codes'].map(item => {
|
||||
if (config[item] && config[item].family && config[item].external) {
|
||||
return config[item].family + fontStyles;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
fontFamilies = fontFamilies.filter(item => item !== '');
|
||||
fontFamilies = [...new Set(fontFamilies)];
|
||||
fontFamilies = fontFamilies.join('|');
|
||||
|
||||
// Merge extra parameters to the final processed font string
|
||||
return fontFamilies ? `<link rel="stylesheet" href="${fontHost}/css?family=${fontFamilies.concat(fontDisplay, fontSubset)}">` : '';
|
||||
});
|
||||
45
themes/next/scripts/helpers/next-config.js
Normal file
45
themes/next/scripts/helpers/next-config.js
Normal file
@ -0,0 +1,45 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const url = require('url');
|
||||
|
||||
/**
|
||||
* Export theme config to js
|
||||
*/
|
||||
hexo.extend.helper.register('next_config', function() {
|
||||
let { config, theme, next_version } = this;
|
||||
config.algolia = config.algolia || {};
|
||||
let exportConfig = {
|
||||
hostname : url.parse(config.url).hostname || config.url,
|
||||
root : config.root,
|
||||
scheme : theme.scheme,
|
||||
version : next_version,
|
||||
exturl : theme.exturl,
|
||||
sidebar : theme.sidebar,
|
||||
copycode : theme.codeblock.copy_button,
|
||||
back2top : theme.back2top,
|
||||
bookmark : theme.bookmark,
|
||||
fancybox : theme.fancybox,
|
||||
mediumzoom: theme.mediumzoom,
|
||||
lazyload : theme.lazyload,
|
||||
pangu : theme.pangu,
|
||||
comments : theme.comments,
|
||||
algolia : {
|
||||
appID : config.algolia.applicationID,
|
||||
apiKey : config.algolia.apiKey,
|
||||
indexName: config.algolia.indexName,
|
||||
hits : theme.algolia_search.hits,
|
||||
labels : theme.algolia_search.labels
|
||||
},
|
||||
localsearch: theme.local_search,
|
||||
motion : theme.motion
|
||||
};
|
||||
if (config.search) {
|
||||
exportConfig.path = config.search.path;
|
||||
}
|
||||
return `<script id="hexo-configurations">
|
||||
var NexT = window.NexT || {};
|
||||
var CONFIG = ${JSON.stringify(exportConfig)};
|
||||
</script>`;
|
||||
});
|
||||
61
themes/next/scripts/helpers/next-url.js
Normal file
61
themes/next/scripts/helpers/next-url.js
Normal file
@ -0,0 +1,61 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const { htmlTag } = require('hexo-util');
|
||||
const url = require('url');
|
||||
|
||||
hexo.extend.helper.register('next_url', function(path, text, options = {}) {
|
||||
const { config } = this;
|
||||
const data = url.parse(path);
|
||||
const siteHost = url.parse(config.url).hostname || config.url;
|
||||
|
||||
const theme = hexo.theme.config;
|
||||
let exturl = '';
|
||||
let tag = 'a';
|
||||
let attrs = { href: this.url_for(path) };
|
||||
|
||||
// If `exturl` enabled, set spanned links only on external links.
|
||||
if (theme.exturl && data.protocol && data.hostname !== siteHost) {
|
||||
tag = 'span';
|
||||
exturl = 'exturl';
|
||||
const encoded = Buffer.from(path).toString('base64');
|
||||
attrs = {
|
||||
class : exturl,
|
||||
'data-url': encoded
|
||||
};
|
||||
}
|
||||
|
||||
for (let key in options) {
|
||||
|
||||
/**
|
||||
* If option have `class` attribute, add it to
|
||||
* 'exturl' class if `exturl` option enabled.
|
||||
*/
|
||||
if (exturl !== '' && key === 'class') {
|
||||
attrs[key] += ' ' + options[key];
|
||||
} else {
|
||||
attrs[key] = options[key];
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.class && Array.isArray(attrs.class)) {
|
||||
attrs.class = attrs.class.join(' ');
|
||||
}
|
||||
|
||||
// If it's external link, rewrite attributes.
|
||||
if (data.protocol && data.hostname !== siteHost) {
|
||||
attrs.external = null;
|
||||
|
||||
if (!theme.exturl) {
|
||||
// Only for simple link need to rewrite/add attributes.
|
||||
attrs.rel = 'noopener';
|
||||
attrs.target = '_blank';
|
||||
} else {
|
||||
// Remove rel attributes for `exturl` in main menu.
|
||||
attrs.rel = null;
|
||||
}
|
||||
}
|
||||
|
||||
return htmlTag(tag, attrs, decodeURI(text), false);
|
||||
});
|
||||
37
themes/next/scripts/renderer.js
Normal file
37
themes/next/scripts/renderer.js
Normal file
@ -0,0 +1,37 @@
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
const nunjucks = require('nunjucks');
|
||||
const path = require('path');
|
||||
|
||||
function njkCompile(data) {
|
||||
const templateDir = path.dirname(data.path);
|
||||
const env = nunjucks.configure(templateDir, {
|
||||
autoescape: false
|
||||
});
|
||||
env.addFilter('attr', (dictionary, key, value) => {
|
||||
dictionary[key] = value;
|
||||
return dictionary;
|
||||
});
|
||||
env.addFilter('json', dictionary => {
|
||||
return JSON.stringify(dictionary || '');
|
||||
});
|
||||
return nunjucks.compile(data.text, env, data.path);
|
||||
}
|
||||
|
||||
function njkRenderer(data, locals) {
|
||||
return njkCompile(data).render(locals);
|
||||
}
|
||||
|
||||
// Return a compiled renderer.
|
||||
njkRenderer.compile = function(data) {
|
||||
const compiledTemplate = njkCompile(data);
|
||||
// Need a closure to keep the compiled template.
|
||||
return function(locals) {
|
||||
return compiledTemplate.render(locals);
|
||||
};
|
||||
};
|
||||
|
||||
hexo.extend.renderer.register('njk', 'html', njkRenderer);
|
||||
hexo.extend.renderer.register('swig', 'html', njkRenderer);
|
||||
31
themes/next/scripts/tags/button.js
Normal file
31
themes/next/scripts/tags/button.js
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* button.js | https://theme-next.org/docs/tag-plugins/button
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function postButton(args) {
|
||||
args = args.join(' ').split(',');
|
||||
let url = args[0];
|
||||
let text = args[1] || '';
|
||||
let icon = args[2] || '';
|
||||
let title = args[3] || '';
|
||||
|
||||
if (!url) {
|
||||
hexo.log.warn('URL can NOT be empty.');
|
||||
}
|
||||
|
||||
text = text.trim();
|
||||
icon = icon.trim();
|
||||
icon = icon.startsWith('fa') ? icon : 'fa fa-' + icon;
|
||||
title = title.trim();
|
||||
|
||||
return `<a class="btn" href="${url}"${title.length > 0 ? ` title="${title}"` : ''}>
|
||||
${icon.length > 0 ? `<i class="${icon}"></i>` : ''}${text}
|
||||
</a>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('button', postButton, {ends: false});
|
||||
hexo.extend.tag.register('btn', postButton, {ends: false});
|
||||
23
themes/next/scripts/tags/caniuse.js
Normal file
23
themes/next/scripts/tags/caniuse.js
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* caniuse.js | https://theme-next.org/docs/tag-plugins/caniuse
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function caniUse(args) {
|
||||
args = args.join('').split('@');
|
||||
var feature = args[0];
|
||||
var periods = args[1] || 'current';
|
||||
|
||||
if (!feature) {
|
||||
hexo.log.warn('Caniuse feature can NOT be empty.');
|
||||
return '';
|
||||
}
|
||||
|
||||
return `<iframe data-feature="${feature}" src="https://caniuse.bitsofco.de/embed/index.html?feat=${feature}&periods=${periods}&accessible-colours=false" frameborder="0" width="100%" height="400px"></iframe>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('caniuse', caniUse);
|
||||
hexo.extend.tag.register('can', caniUse);
|
||||
18
themes/next/scripts/tags/center-quote.js
Normal file
18
themes/next/scripts/tags/center-quote.js
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* center-quote.js | https://theme-next.org/docs/tag-plugins/
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function centerQuote(args, content) {
|
||||
return `<blockquote class="blockquote-center">
|
||||
<i class="fa fa-quote-left"></i>
|
||||
${hexo.render.renderSync({ text: content, engine: 'markdown' })}
|
||||
<i class="fa fa-quote-right"></i>
|
||||
</blockquote>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('centerquote', centerQuote, {ends: true});
|
||||
hexo.extend.tag.register('cq', centerQuote, {ends: true});
|
||||
141
themes/next/scripts/tags/group-pictures.js
Normal file
141
themes/next/scripts/tags/group-pictures.js
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* group-pictures.js | https://theme-next.org/docs/tag-plugins/group-pictures
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
var LAYOUTS = {
|
||||
2: {
|
||||
1: [1, 1],
|
||||
2: [2]
|
||||
},
|
||||
3: {
|
||||
1: [3],
|
||||
2: [1, 2],
|
||||
3: [2, 1]
|
||||
},
|
||||
4: {
|
||||
1: [1, 2, 1],
|
||||
2: [1, 3],
|
||||
3: [2, 2],
|
||||
4: [3, 1]
|
||||
},
|
||||
5: {
|
||||
1: [1, 2, 2],
|
||||
2: [2, 1, 2],
|
||||
3: [2, 3],
|
||||
4: [3, 2]
|
||||
},
|
||||
6: {
|
||||
1: [1, 2, 3],
|
||||
2: [1, 3, 2],
|
||||
3: [2, 1, 3],
|
||||
4: [2, 2, 2],
|
||||
5: [3, 3]
|
||||
},
|
||||
7: {
|
||||
1: [1, 2, 2, 2],
|
||||
2: [1, 3, 3],
|
||||
3: [2, 2, 3],
|
||||
4: [2, 3, 2],
|
||||
5: [3, 2, 2]
|
||||
},
|
||||
8: {
|
||||
1: [1, 2, 2, 3],
|
||||
2: [1, 2, 3, 2],
|
||||
3: [1, 3, 2, 2],
|
||||
4: [2, 2, 2, 2],
|
||||
5: [2, 3, 3],
|
||||
6: [3, 2, 3],
|
||||
7: [3, 3, 2]
|
||||
},
|
||||
9: {
|
||||
1: [1, 2, 3, 3],
|
||||
2: [1, 3, 2, 3],
|
||||
3: [2, 2, 2, 3],
|
||||
4: [2, 2, 3, 2],
|
||||
5: [2, 3, 2, 2],
|
||||
6: [3, 2, 2, 2],
|
||||
7: [3, 3, 3]
|
||||
},
|
||||
10: {
|
||||
1: [1, 3, 3, 3],
|
||||
2: [2, 2, 3, 3],
|
||||
3: [2, 3, 2, 3],
|
||||
4: [2, 3, 3, 2],
|
||||
5: [3, 2, 2, 3],
|
||||
6: [3, 2, 3, 2],
|
||||
7: [3, 3, 2, 2]
|
||||
}
|
||||
};
|
||||
|
||||
function groupBy(group, data) {
|
||||
var r = [];
|
||||
for (let count of group) {
|
||||
r.push(data.slice(0, count));
|
||||
data = data.slice(count);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
var templates = {
|
||||
|
||||
dispatch: function(pictures, group, layout) {
|
||||
var rule = LAYOUTS[group] ? LAYOUTS[group][layout] : null;
|
||||
return rule ? this.getHTML(groupBy(rule, pictures)) : templates.defaults(pictures);
|
||||
},
|
||||
|
||||
/**
|
||||
* Defaults Layout
|
||||
*
|
||||
* □ □ □
|
||||
* □ □ □
|
||||
* ...
|
||||
*
|
||||
* @param pictures
|
||||
*/
|
||||
defaults: function(pictures) {
|
||||
var ROW_SIZE = 3;
|
||||
var rows = pictures.length / ROW_SIZE;
|
||||
var pictureArr = [];
|
||||
|
||||
for (var i = 0; i < rows; i++) {
|
||||
pictureArr.push(pictures.slice(i * ROW_SIZE, (i + 1) * ROW_SIZE));
|
||||
}
|
||||
|
||||
return this.getHTML(pictureArr);
|
||||
},
|
||||
|
||||
getHTML: function(rows) {
|
||||
var rowHTML = rows.map(row => {
|
||||
return `<div class="group-picture-row">${this.getColumnHTML(row)}</div>`;
|
||||
}).join('');
|
||||
|
||||
return `<div class="group-picture-container">${rowHTML}</div>`;
|
||||
},
|
||||
|
||||
getColumnHTML: function(pictures) {
|
||||
var columnWidth = 100 / pictures.length;
|
||||
var columnStyle = `style="width: ${columnWidth}%;"`;
|
||||
return pictures.map(picture => {
|
||||
return `<div class="group-picture-column" ${columnStyle}>${picture}</div>`;
|
||||
}).join('');
|
||||
}
|
||||
};
|
||||
|
||||
function groupPicture(args, content) {
|
||||
args = args[0].split('-');
|
||||
var group = parseInt(args[0], 10);
|
||||
var layout = parseInt(args[1], 10);
|
||||
|
||||
content = hexo.render.renderSync({text: content, engine: 'markdown'});
|
||||
|
||||
var pictures = content.match(/<img[\s\S]*?>/g);
|
||||
|
||||
return `<div class="group-picture">${templates.dispatch(pictures, group, layout)}</div>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('grouppicture', groupPicture, {ends: true});
|
||||
hexo.extend.tag.register('gp', groupPicture, {ends: true});
|
||||
19
themes/next/scripts/tags/label.js
Normal file
19
themes/next/scripts/tags/label.js
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* label.js | https://theme-next.org/docs/tag-plugins/label
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function postLabel(args) {
|
||||
args = args.join(' ').split('@');
|
||||
var classes = args[0] || 'default';
|
||||
var text = args[1] || '';
|
||||
|
||||
!text && hexo.log.warn('Label text must be defined!');
|
||||
|
||||
return `<span class="label ${classes.trim()}">${text}</span>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('label', postLabel, {ends: false});
|
||||
16
themes/next/scripts/tags/mermaid.js
Normal file
16
themes/next/scripts/tags/mermaid.js
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* mermaid.js | https://theme-next.org/docs/tag-plugins/mermaid
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function mermaid(args, content) {
|
||||
return `<pre class="mermaid" style="text-align: center;">
|
||||
${args.join(' ')}
|
||||
${content}
|
||||
</pre>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('mermaid', mermaid, {ends: true});
|
||||
16
themes/next/scripts/tags/note.js
Normal file
16
themes/next/scripts/tags/note.js
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* note.js | https://theme-next.org/docs/tag-plugins/note
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function postNote(args, content) {
|
||||
return `<div class="note ${args.join(' ')}">
|
||||
${hexo.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('')}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('note', postNote, {ends: true});
|
||||
hexo.extend.tag.register('subnote', postNote, {ends: true});
|
||||
14
themes/next/scripts/tags/pdf.js
Normal file
14
themes/next/scripts/tags/pdf.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* pdf.js | https://theme-next.org/docs/tag-plugins/pdf
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function pdf(args) {
|
||||
let theme = hexo.theme.config;
|
||||
return `<div class="pdfobject-container" data-target="${args[0]}" data-height="${args[1] || theme.pdf.height}"></div>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('pdf', pdf, {ends: false});
|
||||
61
themes/next/scripts/tags/tabs.js
Normal file
61
themes/next/scripts/tags/tabs.js
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* tabs.js | https://theme-next.org/docs/tag-plugins/tabs
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function postTabs(args, content) {
|
||||
var tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;
|
||||
|
||||
args = args.join(' ').split(',');
|
||||
var tabName = args[0];
|
||||
var tabActive = Number(args[1]) || 0;
|
||||
|
||||
var matches = [];
|
||||
var match;
|
||||
var tabId = 0;
|
||||
var tabNav = '';
|
||||
var tabContent = '';
|
||||
|
||||
!tabName && hexo.log.warn('Tabs block must have unique name!');
|
||||
|
||||
while ((match = tabBlock.exec(content)) !== null) {
|
||||
matches.push(match[1]);
|
||||
matches.push(match[2]);
|
||||
}
|
||||
|
||||
for (var i = 0; i < matches.length; i += 2) {
|
||||
var tabParameters = matches[i].split('@');
|
||||
var postContent = matches[i + 1];
|
||||
var tabCaption = tabParameters[0] || '';
|
||||
var tabIcon = tabParameters[1] || '';
|
||||
var tabHref = '';
|
||||
|
||||
postContent = hexo.render.renderSync({text: postContent, engine: 'markdown'}).trim();
|
||||
|
||||
tabId += 1;
|
||||
tabHref = (tabName + ' ' + tabId).toLowerCase().split(' ').join('-');
|
||||
|
||||
((tabCaption.length === 0) && (tabIcon.length === 0)) && (tabCaption = tabName + ' ' + tabId);
|
||||
|
||||
var isOnlyicon = tabIcon.length > 0 && tabCaption.length === 0 ? ' style="text-align: center;"' : '';
|
||||
let icon = tabIcon.trim();
|
||||
icon = icon.startsWith('fa') ? icon : 'fa fa-' + icon;
|
||||
tabIcon.length > 0 && (tabIcon = `<i class="${icon}"${isOnlyicon}></i>`);
|
||||
|
||||
var isActive = (tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1) ? ' active' : '';
|
||||
tabNav += `<li class="tab${isActive}"><a href="#${tabHref}">${tabIcon + tabCaption.trim()}</a></li>`;
|
||||
tabContent += `<div class="tab-pane${isActive}" id="${tabHref}">${postContent}</div>`;
|
||||
}
|
||||
|
||||
tabNav = `<ul class="nav-tabs">${tabNav}</ul>`;
|
||||
tabContent = `<div class="tab-content">${tabContent}</div>`;
|
||||
|
||||
return `<div class="tabs" id="${tabName.toLowerCase().split(' ').join('-')}">${tabNav + tabContent}</div>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('tabs', postTabs, {ends: true});
|
||||
hexo.extend.tag.register('subtabs', postTabs, {ends: true});
|
||||
hexo.extend.tag.register('subsubtabs', postTabs, {ends: true});
|
||||
13
themes/next/scripts/tags/video.js
Normal file
13
themes/next/scripts/tags/video.js
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* video.js | https://theme-next.org/docs/tag-plugins/video
|
||||
*/
|
||||
|
||||
/* global hexo */
|
||||
|
||||
'use strict';
|
||||
|
||||
function postVideo(args) {
|
||||
return `<video src="${args}" preload="metadata" controls playsinline poster="">Sorry, your browser does not support the video tag.</video>`;
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('video', postVideo, {ends: false});
|
||||
Reference in New Issue
Block a user