Skip to content

Commit 69afdc7

Browse files
committed
feat: enhance button and folding modules with improved argument parsing and HTML generation
- Updated btn.js to support both '::' and ',' as argument separators, improving flexibility in button creation. - Refactored btns.js to streamline button container and cell creation, including enhanced handling for icons and images. - Improved folding.js by simplifying argument parsing and refining content rendering with markdown processing.
1 parent 38ea515 commit 69afdc7

3 files changed

Lines changed: 150 additions & 93 deletions

File tree

scripts/modules/btn.js

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,85 @@
11
"use strict";
22

3+
/**
4+
* Single Button module for Hexo theme Redefine
5+
* Creates standalone button elements
6+
*/
7+
8+
/**
9+
* Creates a single button
10+
*
11+
* @param {Array} args - Button arguments (class, text, url, icon)
12+
* @returns {String} HTML for a single button
13+
*/
314
function postBtn(args) {
4-
if (/::/g.test(args)) {
5-
args = args.join(" ").split("::");
15+
// Parse arguments - support both '::' and ',' as separators
16+
let parsedArgs;
17+
const argsStr = args.join(" ");
18+
19+
if (argsStr.includes("::")) {
20+
parsedArgs = argsStr.split("::");
621
} else {
7-
args = args.join(" ").split(",");
22+
parsedArgs = argsStr.split(",");
823
}
24+
25+
// Default values
926
let cls = "";
1027
let text = "";
1128
let url = "";
1229
let icon = "";
13-
if (args.length > 3) {
14-
cls = args[0];
15-
text = args[1];
16-
url = args[2];
17-
icon = args[3];
18-
} else if (args.length > 2) {
19-
if (args[2].indexOf(" fa-") > -1) {
20-
// text, url, icon
21-
text = args[0];
22-
url = args[1];
23-
icon = args[2];
24-
} else {
25-
cls = args[0];
26-
text = args[1];
27-
url = args[2];
28-
}
29-
} else if (args.length > 1) {
30-
text = args[0];
31-
url = args[1];
32-
} else if (args.length > 0) {
33-
text = args[0];
30+
31+
// Parse arguments based on count
32+
switch(parsedArgs.length) {
33+
case 4: // class, text, url, icon
34+
cls = parsedArgs[0];
35+
text = parsedArgs[1];
36+
url = parsedArgs[2];
37+
icon = parsedArgs[3];
38+
break;
39+
40+
case 3:
41+
// Check if third arg is an icon (contains fa-)
42+
if (parsedArgs[2].includes("fa-")) {
43+
// text, url, icon
44+
text = parsedArgs[0];
45+
url = parsedArgs[1];
46+
icon = parsedArgs[2];
47+
} else {
48+
// class, text, url
49+
cls = parsedArgs[0];
50+
text = parsedArgs[1];
51+
url = parsedArgs[2];
52+
}
53+
break;
54+
55+
case 2: // text, url
56+
text = parsedArgs[0];
57+
url = parsedArgs[1];
58+
break;
59+
60+
case 1: // text only
61+
text = parsedArgs[0];
62+
break;
3463
}
35-
64+
65+
// Clean up values
3666
cls = cls.trim();
3767
icon = icon.trim();
3868
text = text.trim();
3969
url = url.trim();
40-
if (url.length > 0) {
41-
url = "href='" + url + "'";
42-
}
43-
if (cls.length > 0) {
44-
cls = " " + cls;
45-
}
46-
if (icon.length > 0) {
47-
return `<a class="button ${cls}" ${url} title='${text}'><i class='${icon}'></i> ${text}</a>`;
70+
71+
// Build attributes
72+
const hrefAttr = url ? `href='${url}'` : '';
73+
const classAttr = cls ? `${cls}` : '';
74+
75+
// Build button HTML
76+
if (icon) {
77+
return `<a class="button ${classAttr}" ${hrefAttr} title='${text}'><i class='${icon}'></i> ${text}</a>`;
4878
}
49-
return `<a class="button ${cls}" ${url} title='${text}'>${text}</a>`;
79+
80+
return `<a class="button ${classAttr}" ${hrefAttr} title='${text}'>${text}</a>`;
5081
}
5182

83+
// Register Hexo tags
5284
hexo.extend.tag.register("btn", postBtn);
5385
hexo.extend.tag.register("button", postBtn);

scripts/modules/btns.js

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,71 @@
11
'use strict';
22

3+
/**
4+
* Buttons module for Hexo theme Redefine
5+
* Creates button containers and button elements
6+
*/
7+
8+
/**
9+
* Creates a buttons container
10+
*
11+
* @param {Array} args - Class names for the container
12+
* @param {String} content - Button content (cells)
13+
* @returns {String} HTML for the buttons container
14+
*/
315
function postBtns(args, content) {
4-
return `<div class="btns ${args.join(' ')}">
16+
const classes = args.join(' ');
17+
return `<div class="btns ${classes}">
518
${content}
619
</div>`;
720
}
821

22+
/**
23+
* Creates a single button cell
24+
*
25+
* @param {Array} args - Button properties (text, url, icon/image)
26+
* @returns {String} HTML for a single button
27+
*/
928
function postCell(args, content) {
10-
if(/::/g.test(args)){
11-
args = args.join(' ').split('::');
12-
}
13-
else{
14-
args = args.join(' ').split(',');
15-
}
16-
let text = args[0] || '';
17-
let url = args[1] || '';
18-
text = text.trim();
19-
url = url.trim();
20-
if (url.length > 0) {
21-
url = 'href=\'' + url + '\'';
29+
// Parse arguments - support both '::' and ',' as separators
30+
let parsedArgs;
31+
const argsStr = args.join(' ');
32+
33+
if (argsStr.includes('::')) {
34+
parsedArgs = argsStr.split('::');
35+
} else {
36+
parsedArgs = argsStr.split(',');
2237
}
23-
let icon = '';
24-
let img = hexo.theme.config.default.image;
25-
if (args.length > 2) {
26-
if (args[2].indexOf(' fa-') > -1) {
27-
icon = args[2].trim();
38+
39+
// Extract button properties
40+
const text = (parsedArgs[0] || '').trim();
41+
const url = (parsedArgs[1] || '').trim();
42+
const buttonClasses = ['button'];
43+
44+
// Handle URL
45+
const hrefAttr = url ? `href='${url}'` : '';
46+
47+
// Handle icon or image
48+
let iconOrImage = '';
49+
50+
if (parsedArgs.length > 2) {
51+
const iconOrImgSrc = parsedArgs[2].trim();
52+
53+
// Check if it's a FontAwesome icon
54+
if (iconOrImgSrc.includes('fa-')) {
55+
iconOrImage = `<i class='${iconOrImgSrc}'></i> `;
2856
} else {
29-
img = args[2].trim();
57+
// Use specified image or default
58+
const imgSrc = iconOrImgSrc || hexo.theme.config.default.image;
59+
iconOrImage = `<img src='${imgSrc}'>`;
3060
}
3161
}
32-
if (icon.length > 0) {
33-
return `<a class="button ${cls}" ${url} title='${text}'><i class='${icon}'></i> ${text}</a>`;
34-
}
35-
return `<a class="button ${cls}" ${url} title='${text}'><img src='${img}'>${text}</a>`;
36-
62+
63+
// Return complete button HTML
64+
return `<a class="${buttonClasses.join(' ')}" ${hrefAttr} title='${text}'>${iconOrImage}${text}</a>`;
3765
}
3866

67+
// Register Hexo tags
3968
hexo.extend.tag.register('btns', postBtns, {ends: true});
4069
hexo.extend.tag.register('buttons', postBtns, {ends: true});
4170
hexo.extend.tag.register('cell', postCell);
71+

scripts/modules/folding.js

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,34 @@
1-
/**
2-
* folding.js
3-
* transplant from hexo-theme-volantis
4-
* Modify by Evan
5-
*/
6-
7-
81
'use strict';
92

10-
function postFolding(args, content) {
11-
if (/::/g.test(args)) {
12-
args = args.join(' ').split('::');
13-
}
14-
else {
15-
args = args.join(' ').split(',');
16-
}
17-
let style = '';
18-
let title = '';
19-
if (args.length > 1) {
20-
style = args[0].trim();
21-
title = args[1].trim();
22-
} else if (args.length > 0) {
23-
title = args[0].trim();
24-
}
25-
if (style != undefined) {
26-
return `<details class="${style}" data-header-exclude><summary><i class="fa-solid fa-chevron-right"></i>${title} </summary>
27-
<div class='content'>
28-
${hexo.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('').replace("h1","p class='h1'").replace("h2","p class='h2'").replace("h3","p class='h3'").replace("h4","p class='h4'").replace("h5","p class='h5'").replace("h6","p class='h6'")}
29-
</div>
30-
</details>`;
31-
}
32-
return `<details data-header-exclude><summary><i class="fa-solid fa-chevron-right"></i>${title} </summary>
33-
<div class='content'>
34-
${hexo.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('').replace("h1","p class='h1'").replace("h2","p class='h2'").replace("h3","p class='h3'").replace("h4","p class='h4'").replace("h5","p class='h5'").replace("h6","p class='h6'")}
35-
</div>
36-
</details>`;
37-
}
3+
const postFolding = (args, content) => {
4+
// Parse arguments - support both '::' and ',' as delimiters
5+
const delimiter = args.join(' ').includes('::') ? '::' : ',';
6+
const [style, title = ''] = args.join(' ').split(delimiter).map(arg => arg.trim());
7+
8+
// Render markdown content
9+
const renderedContent = hexo.render.renderSync({
10+
text: content,
11+
engine: 'markdown'
12+
}).split('\n').join('');
13+
14+
// Replace heading tags with paragraph tags that have heading classes
15+
const processedContent = renderedContent.replace(
16+
/<(h[1-6])>/g,
17+
(_, tag) => `<p class='${tag}'>`
18+
).replace(
19+
/<\/(h[1-6])>/g,
20+
() => '</p>'
21+
);
22+
23+
// Build the HTML with or without custom style
24+
const styleAttr = style ? ` class="${style}"` : '';
25+
26+
return `<details${styleAttr} data-header-exclude>
27+
<summary><i class="fa-solid fa-chevron-right"></i>${title} </summary>
28+
<div class='content'>
29+
${processedContent}
30+
</div>
31+
</details>`;
32+
};
3833

3934
hexo.extend.tag.register('folding', postFolding, {ends: true});

0 commit comments

Comments
 (0)