@lyhue1991/wxgzh 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli/fix.js +3 -0
- package/dist/cli/index.js +7 -1
- package/dist/cli/md2html.js +1 -1
- package/dist/core/fixer.js +32 -7
- package/dist/core/themes.js +1 -1
- package/package.json +1 -1
- package/styles/black.css +12 -6
- package/styles/blue.css +12 -6
- package/styles/brown.css +12 -6
- package/styles/default.css +12 -6
- package/styles/green.css +12 -6
- package/styles/orange.css +12 -6
- package/styles/red.css +12 -6
- package/styles/yellow.css +12 -6
package/README.md
CHANGED
package/dist/cli/fix.js
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -101,8 +101,11 @@ async function runDefaultPipeline(articlePath, options) {
|
|
|
101
101
|
const { fixHtmlFile } = await Promise.resolve().then(() => __importStar(require('../core/fixer')));
|
|
102
102
|
const { WechatClient } = await Promise.resolve().then(() => __importStar(require('../core/wechat')));
|
|
103
103
|
const wechat = new WechatClient((0, config_1.resolveWechatCredentials)(config));
|
|
104
|
-
await fixHtmlFile(htmlPath, { upload: true, wechat });
|
|
104
|
+
const fixResult = await fixHtmlFile(htmlPath, { upload: true, wechat });
|
|
105
105
|
(0, logger_1.info)(`已修复并上传正文图片: ${htmlPath}`);
|
|
106
|
+
for (const message of fixResult.skippedImages) {
|
|
107
|
+
(0, logger_1.warn)(message);
|
|
108
|
+
}
|
|
106
109
|
let finalCoverPath = resolveCoverValue(options.cover) ?? parsed.metadata.cover;
|
|
107
110
|
if (finalCoverPath && !node_path_1.default.isAbsolute(finalCoverPath)) {
|
|
108
111
|
finalCoverPath = node_path_1.default.resolve(node_path_1.default.dirname(absoluteArticle), finalCoverPath);
|
|
@@ -127,6 +130,9 @@ async function runDefaultPipeline(articlePath, options) {
|
|
|
127
130
|
}
|
|
128
131
|
async function main() {
|
|
129
132
|
const program = new commander_1.Command();
|
|
133
|
+
// 外层命令与子命令存在同名选项(如 publish 的 --cover),必须启用 positional options:
|
|
134
|
+
// 子命令名之后出现的选项只归子命令所有,避免外层 --cover/--no-cover 吞掉 publish 的 --cover 参数
|
|
135
|
+
program.enablePositionalOptions();
|
|
130
136
|
program
|
|
131
137
|
.name('wxgzh')
|
|
132
138
|
.description('把 Markdown 文章处理成微信公众号草稿,支持主题、图片修复、封面生成与一键发布')
|
package/dist/cli/md2html.js
CHANGED
|
@@ -18,7 +18,7 @@ async function convertMarkdownFile(inputPath, outputPath, options) {
|
|
|
18
18
|
const raw = await (0, promises_1.readFile)(absoluteInputPath, 'utf8');
|
|
19
19
|
const parsed = (0, parser_1.parseMarkdown)(raw);
|
|
20
20
|
const config = await (0, config_1.loadConfig)({ account: options?.account ?? parsed.metadata.account });
|
|
21
|
-
const resolvedTheme = options?.theme ?? parsed.metadata.theme ?? config.defaultTheme ??
|
|
21
|
+
const resolvedTheme = options?.theme ?? parsed.metadata.theme ?? config.defaultTheme ?? (0, themes_1.getDefaultThemeName)();
|
|
22
22
|
const html = await (0, converter_1.renderMarkdownToHtml)(parsed.body, {
|
|
23
23
|
...parsed.metadata,
|
|
24
24
|
account: options?.account ?? parsed.metadata.account ?? config.account,
|
package/dist/core/fixer.js
CHANGED
|
@@ -41,9 +41,27 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
41
41
|
const cheerio = __importStar(require("cheerio"));
|
|
42
42
|
const converter_1 = require("./converter");
|
|
43
43
|
const fs_1 = require("../utils/fs");
|
|
44
|
+
const LAZY_SOURCE_ATTRIBUTE = 'data-src';
|
|
44
45
|
function isRemoteUrl(value) {
|
|
45
46
|
return /^https?:\/\//i.test(value);
|
|
46
47
|
}
|
|
48
|
+
function isPlaceholderValue(value) {
|
|
49
|
+
const trimmed = value.trim();
|
|
50
|
+
return trimmed === '' || trimmed.startsWith('data:') || trimmed === 'about:blank';
|
|
51
|
+
}
|
|
52
|
+
function isUsableSource(value) {
|
|
53
|
+
return value !== undefined && !isPlaceholderValue(value);
|
|
54
|
+
}
|
|
55
|
+
function pickImageSource(lazySource, directSource) {
|
|
56
|
+
// 微信保存页等懒加载结构:真实地址在 data-src,src 可能是空白占位图
|
|
57
|
+
if (isUsableSource(lazySource)) {
|
|
58
|
+
return lazySource.trim();
|
|
59
|
+
}
|
|
60
|
+
if (isUsableSource(directSource)) {
|
|
61
|
+
return directSource.trim();
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
47
65
|
function toCdnUrl(cdn, source) {
|
|
48
66
|
const cleanBase = cdn.replace(/\/+$/, '');
|
|
49
67
|
const fileName = node_path_1.default.basename(source);
|
|
@@ -70,20 +88,26 @@ async function fixHtmlFile(articlePath, options) {
|
|
|
70
88
|
const sourceBaseDir = metadata.sourceDir ? node_path_1.default.resolve(metadata.sourceDir) : node_path_1.default.dirname(articlePath);
|
|
71
89
|
$('script,iframe').remove();
|
|
72
90
|
const images = $('img').toArray();
|
|
73
|
-
|
|
91
|
+
const skippedImages = [];
|
|
92
|
+
let imageCount = 0;
|
|
93
|
+
for (const [index, element] of images.entries()) {
|
|
74
94
|
const image = $(element);
|
|
75
|
-
const source = image.attr('src');
|
|
76
|
-
if (
|
|
95
|
+
const source = pickImageSource(image.attr(LAZY_SOURCE_ATTRIBUTE), image.attr('src'));
|
|
96
|
+
if (source === undefined) {
|
|
97
|
+
skippedImages.push(`第 ${index + 1} 张图片缺少可用地址(src 与 data-src 均为空或占位图),已跳过`);
|
|
77
98
|
continue;
|
|
78
99
|
}
|
|
100
|
+
let finalSource = source;
|
|
79
101
|
if (options.upload && options.wechat && !source.includes('mmbiz.qpic.cn')) {
|
|
80
|
-
|
|
81
|
-
image.attr('src', uploadedUrl);
|
|
102
|
+
finalSource = await options.wechat.uploadArticleImage(resolveImageSource(sourceBaseDir, source));
|
|
82
103
|
image.attr('data-original-src', source);
|
|
83
104
|
}
|
|
84
105
|
else if (options.cdn && !isRemoteUrl(source)) {
|
|
85
|
-
|
|
106
|
+
finalSource = toCdnUrl(options.cdn, source);
|
|
86
107
|
}
|
|
108
|
+
// 真实地址统一回写 src,并移除懒加载占位属性,避免渲染端读到占位图
|
|
109
|
+
image.attr('src', finalSource);
|
|
110
|
+
image.removeAttr(LAZY_SOURCE_ATTRIBUTE);
|
|
87
111
|
image.attr('style', [
|
|
88
112
|
'display:block',
|
|
89
113
|
'max-width:100%',
|
|
@@ -91,7 +115,8 @@ async function fixHtmlFile(articlePath, options) {
|
|
|
91
115
|
'margin:0 auto',
|
|
92
116
|
'border-radius:6px'
|
|
93
117
|
].join(';'));
|
|
118
|
+
imageCount += 1;
|
|
94
119
|
}
|
|
95
120
|
await (0, fs_1.writeTextFile)(articlePath, $.html());
|
|
96
|
-
return { imageCount
|
|
121
|
+
return { imageCount, skippedImages };
|
|
97
122
|
}
|
package/dist/core/themes.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.assertThemeExists = assertThemeExists;
|
|
|
9
9
|
exports.getDefaultThemeName = getDefaultThemeName;
|
|
10
10
|
const node_fs_1 = require("node:fs");
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
const DEFAULT_THEME = '
|
|
12
|
+
const DEFAULT_THEME = 'black';
|
|
13
13
|
function getStylesDir() {
|
|
14
14
|
return node_path_1.default.resolve(__dirname, '../../styles');
|
|
15
15
|
}
|
package/package.json
CHANGED
package/styles/black.css
CHANGED
|
@@ -70,17 +70,23 @@ h1 {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
h2{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
display: block;
|
|
74
|
+
width: 100%;
|
|
75
|
+
font-size: 18px;
|
|
76
|
+
font-weight: 800;
|
|
77
|
+
padding: 8px 14px;
|
|
78
|
+
line-height: 1.4;
|
|
76
79
|
margin-top: 1.85em;
|
|
77
80
|
margin-bottom: 1.15em;
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
margin-left: 0;
|
|
82
|
+
border-bottom: none;
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
background: #000;
|
|
85
|
+
color: #fff;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
h3 {
|
|
83
|
-
font-size:
|
|
89
|
+
font-size: 16px;
|
|
84
90
|
line-height: 1.15;
|
|
85
91
|
margin-top: 2.285714em;
|
|
86
92
|
margin-bottom: 1.15em;
|
package/styles/blue.css
CHANGED
|
@@ -71,20 +71,26 @@ h1 {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
h2{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
display: block;
|
|
75
|
+
width: 100%;
|
|
76
|
+
font-size: 18px;
|
|
77
|
+
font-weight: 800;
|
|
78
|
+
padding: 8px 14px;
|
|
79
|
+
line-height: 1.4;
|
|
77
80
|
/*24 / 21*/
|
|
78
81
|
margin-top: 1.85em;
|
|
79
82
|
/*48 / 21*/
|
|
80
83
|
margin-bottom: 1.15em;
|
|
81
84
|
/*24 / 21*/
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
margin-left: 0;
|
|
86
|
+
border-bottom: none;
|
|
87
|
+
box-sizing: border-box;
|
|
88
|
+
background:#2891DB;
|
|
89
|
+
color:#fff;
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
h3 {
|
|
87
|
-
font-size:
|
|
93
|
+
font-size: 16px;
|
|
88
94
|
/*21 / 16*/
|
|
89
95
|
line-height: 1.15;
|
|
90
96
|
/*24 / 21*/
|
package/styles/brown.css
CHANGED
|
@@ -70,17 +70,23 @@ h1 {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
h2{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
display: block;
|
|
74
|
+
width: 100%;
|
|
75
|
+
font-size: 18px;
|
|
76
|
+
font-weight: 800;
|
|
77
|
+
padding: 8px 14px;
|
|
78
|
+
line-height: 1.4;
|
|
76
79
|
margin-top: 1.85em;
|
|
77
80
|
margin-bottom: 1.15em;
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
margin-left: 0;
|
|
82
|
+
border-bottom: none;
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
background:#D27D2D;
|
|
85
|
+
color:#fff;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
h3 {
|
|
83
|
-
font-size:
|
|
89
|
+
font-size: 16px;
|
|
84
90
|
line-height: 1.15;
|
|
85
91
|
margin-top: 2.285714em;
|
|
86
92
|
margin-bottom: 1.15em;
|
package/styles/default.css
CHANGED
|
@@ -69,17 +69,23 @@ h1 {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
h2{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
display: block;
|
|
73
|
+
width: 100%;
|
|
74
|
+
font-size: 18px;
|
|
75
|
+
font-weight: 800;
|
|
76
|
+
padding: 8px 14px;
|
|
77
|
+
line-height: 1.4;
|
|
75
78
|
margin-top: 1.85em;
|
|
76
79
|
margin-bottom: 1.15em;
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
margin-left: 0;
|
|
81
|
+
border-bottom: none;
|
|
82
|
+
box-sizing: border-box;
|
|
83
|
+
background:#349971;
|
|
84
|
+
color:#fff;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
h3 {
|
|
82
|
-
font-size:
|
|
88
|
+
font-size: 16px;
|
|
83
89
|
line-height: 1.15;
|
|
84
90
|
margin-top: 2.285714em;
|
|
85
91
|
margin-bottom: 1.15em;
|
package/styles/green.css
CHANGED
|
@@ -72,20 +72,26 @@ h1 {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
h2{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
display: block;
|
|
76
|
+
width: 100%;
|
|
77
|
+
font-size: 18px;
|
|
78
|
+
font-weight: 800;
|
|
79
|
+
padding: 8px 14px;
|
|
80
|
+
line-height: 1.4;
|
|
78
81
|
/*24 / 21*/
|
|
79
82
|
margin-top: 1.85em;
|
|
80
83
|
/*48 / 21*/
|
|
81
84
|
margin-bottom: 1.15em;
|
|
82
85
|
/*24 / 21*/
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
margin-left: 0;
|
|
87
|
+
border-bottom: none;
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
background:#7FFF06;
|
|
90
|
+
color:#fff;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
h3 {
|
|
88
|
-
font-size:
|
|
94
|
+
font-size: 16px;
|
|
89
95
|
/*21 / 16*/
|
|
90
96
|
line-height: 1.15;
|
|
91
97
|
/*24 / 21*/
|
package/styles/orange.css
CHANGED
|
@@ -72,20 +72,26 @@ h1 {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
h2{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
display: block;
|
|
76
|
+
width: 100%;
|
|
77
|
+
font-size: 18px;
|
|
78
|
+
font-weight: 800;
|
|
79
|
+
padding: 8px 14px;
|
|
80
|
+
line-height: 1.4;
|
|
78
81
|
/*24 / 21*/
|
|
79
82
|
margin-top: 1.85em;
|
|
80
83
|
/*48 / 21*/
|
|
81
84
|
margin-bottom: 1.15em;
|
|
82
85
|
/*24 / 21*/
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
margin-left: 0;
|
|
87
|
+
border-bottom: none;
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
background:#F7BC0A;
|
|
90
|
+
color:#fff;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
h3 {
|
|
88
|
-
font-size:
|
|
94
|
+
font-size: 16px;
|
|
89
95
|
/*21 / 16*/
|
|
90
96
|
line-height: 1.15;
|
|
91
97
|
/*24 / 21*/
|
package/styles/red.css
CHANGED
|
@@ -72,20 +72,26 @@ h1 {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
h2{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
display: block;
|
|
76
|
+
width: 100%;
|
|
77
|
+
font-size: 18px;
|
|
78
|
+
font-weight: 800;
|
|
79
|
+
padding: 8px 14px;
|
|
80
|
+
line-height: 1.4;
|
|
78
81
|
/*24 / 21*/
|
|
79
82
|
margin-top: 1.85em;
|
|
80
83
|
/*48 / 21*/
|
|
81
84
|
margin-bottom: 1.15em;
|
|
82
85
|
/*24 / 21*/
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
margin-left: 0;
|
|
87
|
+
border-bottom: none;
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
background:#DC143C;
|
|
90
|
+
color:#fff;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
h3 {
|
|
88
|
-
font-size:
|
|
94
|
+
font-size: 16px;
|
|
89
95
|
/*21 / 16*/
|
|
90
96
|
line-height: 1.15;
|
|
91
97
|
/*24 / 21*/
|
package/styles/yellow.css
CHANGED
|
@@ -72,20 +72,26 @@ h1 {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
h2{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
display: block;
|
|
76
|
+
width: 100%;
|
|
77
|
+
font-size: 18px;
|
|
78
|
+
font-weight: 800;
|
|
79
|
+
padding: 8px 14px;
|
|
80
|
+
line-height: 1.4;
|
|
78
81
|
/*24 / 21*/
|
|
79
82
|
margin-top: 1.85em;
|
|
80
83
|
/*48 / 21*/
|
|
81
84
|
margin-bottom: 1.15em;
|
|
82
85
|
/*24 / 21*/
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
margin-left: 0;
|
|
87
|
+
border-bottom: none;
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
background:#FFD139;
|
|
90
|
+
color:#fff;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
h3 {
|
|
88
|
-
font-size:
|
|
94
|
+
font-size: 16px;
|
|
89
95
|
/*21 / 16*/
|
|
90
96
|
line-height: 1.15;
|
|
91
97
|
/*24 / 21*/
|