@wenyan-md/core 3.0.4 → 3.0.6

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/dist/core.js CHANGED
@@ -194,9 +194,9 @@ function renderListStyleFootnotes(footnotes) {
194
194
  }
195
195
  async function handleFrontMatter(markdown) {
196
196
  const { attributes, body } = fm(markdown);
197
- const result = { body: body || "" };
197
+ const result = { content: body || "" };
198
198
  let head = "";
199
- const { title, description, cover, author, source_url } = attributes;
199
+ const { title, description, cover, author, source_url, need_open_comment, only_fans_can_comment, image_list } = attributes;
200
200
  if (title) {
201
201
  result.title = title;
202
202
  }
@@ -208,7 +208,7 @@ async function handleFrontMatter(markdown) {
208
208
  result.cover = cover;
209
209
  }
210
210
  if (head) {
211
- result.body = head + result.body;
211
+ result.content = head + result.content;
212
212
  }
213
213
  if (author) {
214
214
  result.author = author;
@@ -216,6 +216,15 @@ async function handleFrontMatter(markdown) {
216
216
  if (source_url) {
217
217
  result.source_url = source_url;
218
218
  }
219
+ if (need_open_comment !== void 0) {
220
+ result.need_open_comment = need_open_comment;
221
+ }
222
+ if (only_fans_can_comment !== void 0) {
223
+ result.only_fans_can_comment = only_fans_can_comment;
224
+ }
225
+ if (image_list) {
226
+ result.image_list = image_list;
227
+ }
219
228
  return result;
220
229
  }
221
230
  const parseOptions = {
@@ -524,9 +533,9 @@ function createMathJaxParser(options = {}) {
524
533
  fontCache: options.fontCache ?? "none"
525
534
  });
526
535
  function addContainer(math, doc) {
536
+ const container = math.typesetRoot;
527
537
  const tag = math.display ? "section" : "span";
528
538
  const cls = math.display ? "block-equation" : "inline-equation";
529
- const container = math.typesetRoot;
530
539
  if (math.math) {
531
540
  doc.adaptor.setAttribute(container, "math", math.math);
532
541
  }
package/dist/publish.js CHANGED
@@ -185,12 +185,13 @@ class WechatPublisher {
185
185
  await this.tokenStore.setToken(appId, result.access_token, result.expires_in);
186
186
  return result.access_token;
187
187
  }
188
- async uploadImage(file, filename, accessToken) {
188
+ async uploadImage(file, filename, accessToken, appId) {
189
189
  let hash;
190
190
  if (this.uploadCacheStore) {
191
191
  const arrayBuffer = await file.arrayBuffer();
192
192
  hash = await this.uploadCacheStore.calcHash(arrayBuffer);
193
- const cached = await this.uploadCacheStore.get(hash);
193
+ const cacheKey = appId ? `${hash}:${appId}` : hash;
194
+ const cached = await this.uploadCacheStore.get(cacheKey);
194
195
  if (cached) {
195
196
  return {
196
197
  media_id: cached.media_id,
@@ -200,7 +201,8 @@ class WechatPublisher {
200
201
  }
201
202
  const data = await this.uploadMaterial("image", file, filename, accessToken);
202
203
  if (this.uploadCacheStore && hash) {
203
- await this.uploadCacheStore.set(hash, data.media_id, data.url);
204
+ const cacheKey = appId ? `${hash}:${appId}` : hash;
205
+ await this.uploadCacheStore.set(cacheKey, data.media_id, data.url);
204
206
  }
205
207
  return data;
206
208
  }
@@ -1,4 +1,4 @@
1
- import { FrontMatterResult } from "./parser/frontMatterParser.js";
1
+ import { StyledContent } from "../node/types.js";
2
2
  export interface WenyanOptions {
3
3
  isConvertMathJax?: boolean;
4
4
  isWechat?: boolean;
@@ -12,7 +12,7 @@ export interface ApplyStylesOptions {
12
12
  isAddFootnote?: boolean;
13
13
  }
14
14
  export declare function createWenyanCore(options?: WenyanOptions): Promise<{
15
- handleFrontMatter(markdown: string): Promise<FrontMatterResult>;
15
+ handleFrontMatter(markdown: string): Promise<StyledContent>;
16
16
  renderMarkdown(markdown: string): Promise<string>;
17
17
  applyStylesWithTheme(wenyanElement: HTMLElement, options?: ApplyStylesOptions): Promise<string>;
18
18
  applyStylesWithResolvedCss(wenyanElement: HTMLElement, options: {
@@ -1,9 +1,12 @@
1
1
  export interface FrontMatterResult {
2
- body: string;
2
+ content: string;
3
3
  title?: string;
4
- cover?: string;
5
4
  description?: string;
5
+ cover?: string;
6
6
  author?: string;
7
7
  source_url?: string;
8
+ need_open_comment?: boolean;
9
+ only_fans_can_comment?: boolean;
10
+ image_list?: string[];
8
11
  }
9
12
  export declare function handleFrontMatter(markdown: string): Promise<FrontMatterResult>;
@@ -13,3 +13,4 @@ export declare function uploadStyledContent(gzhContent: StyledContent, serverUrl
13
13
  export declare function requestServerPublish(mdFileId: string, serverUrl: string, headers: Record<string, string>, options: ClientPublishOptions): Promise<string>;
14
14
  export declare function uploadLocalImages(content: string, serverUrl: string, headers: Record<string, string>, relativePath?: string): Promise<string>;
15
15
  export declare function uploadCover(serverUrl: string, headers: Record<string, string>, cover?: string, relativePath?: string): Promise<string | undefined>;
16
+ export declare function uploadImageList(serverUrl: string, headers: Record<string, string>, imageList?: string[], relativePath?: string): Promise<string[]>;
@@ -1,5 +1,5 @@
1
- import { WechatPublishResponse } from "../wechat.js";
2
- import { ArticleOptions, WechatPublisher } from "../publish.js";
1
+ import type { WechatPublishResponse } from "../wechat.js";
2
+ import { ArticleOptions, ImageTextArticleOptions, WechatPublisher } from "../publish.js";
3
3
  import { CredentialStore } from "../credentialStore.js";
4
4
  export declare const wechatPublisher: WechatPublisher;
5
5
  export declare const credentialStore: CredentialStore;
@@ -9,5 +9,9 @@ interface PublishOptions {
9
9
  relativePath?: string;
10
10
  }
11
11
  export declare function publishToWechatDraft(articleOptions: ArticleOptions, publishOptions?: PublishOptions): Promise<WechatPublishResponse>;
12
+ /**
13
+ * @deprecated use publishToWechatDraft instead
14
+ */
12
15
  export declare function publishToDraft(title: string, content: string, cover?: string, options?: PublishOptions): Promise<WechatPublishResponse>;
16
+ export declare function publishImageTextToWechatDraft(articleOptions: ImageTextArticleOptions, publishOptions?: PublishOptions): Promise<WechatPublishResponse>;
13
17
  export {};
@@ -1,5 +1,4 @@
1
1
  import { ApplyStylesOptions } from "../core/index.js";
2
- import { GetInputContentFn, RenderContext, RenderOptions, StyledContent } from "./types.js";
3
- export declare function renderWithTheme(markdownContent: string, options: RenderOptions): Promise<StyledContent>;
4
- export declare function renderStyledContent(content: string, options?: ApplyStylesOptions): Promise<StyledContent>;
2
+ import { GetInputContentFn, RenderContext, RenderOptions } from "./types.js";
3
+ export declare function renderStyledContent(content: string, options?: ApplyStylesOptions): Promise<string>;
5
4
  export declare function prepareRenderContext(inputContent: string | undefined, options: RenderOptions, getInputContent: GetInputContentFn): Promise<RenderContext>;
@@ -21,10 +21,13 @@ export interface RenderContext {
21
21
  export interface StyledContent {
22
22
  content: string;
23
23
  title?: string;
24
- cover?: string;
25
24
  description?: string;
25
+ cover?: string;
26
26
  author?: string;
27
27
  source_url?: string;
28
+ need_open_comment?: boolean;
29
+ only_fans_can_comment?: boolean;
30
+ image_list?: string[];
28
31
  }
29
32
  export type GetInputContentFn = (inputContent?: string, filePath?: string) => Promise<{
30
33
  content: string;
@@ -1,5 +1,4 @@
1
- import { ClientPublishOptions, GetInputContentFn, PublishOptions, StyledContent } from "./types.js";
2
- export declare function getGzhContent(content: string, themeId: string, hlThemeId: string, isMacStyle?: boolean, isAddFootnote?: boolean): Promise<StyledContent>;
1
+ import { ClientPublishOptions, GetInputContentFn, PublishOptions } from "./types.js";
3
2
  export declare function renderAndPublish(inputContent: string | undefined, options: PublishOptions, getInputContent: GetInputContentFn): Promise<string>;
4
3
  export declare function renderAndPublishToServer(inputContent: string | undefined, options: ClientPublishOptions, getInputContent: GetInputContentFn): Promise<string>;
5
4
  export * from "./configStore.js";
@@ -8,6 +8,11 @@ export interface ArticleOptions {
8
8
  cover?: string;
9
9
  author?: string;
10
10
  source_url?: string;
11
+ need_open_comment?: boolean;
12
+ only_fans_can_comment?: boolean;
13
+ }
14
+ export interface ImageTextArticleOptions extends ArticleOptions {
15
+ images: string[];
11
16
  }
12
17
  export declare class WechatPublisher {
13
18
  private tokenStore;
@@ -17,7 +22,7 @@ export declare class WechatPublisher {
17
22
  private fetchAccessToken;
18
23
  constructor(httpAdapter: HttpAdapter, tokenStoreAdapter?: TokenStorageAdapter, uploadCacheStoreAdapter?: UploadCacheStorageAdapter);
19
24
  getAccessTokenWithCache(appId: string, appSecret: string): Promise<string>;
20
- uploadImage(file: Blob, filename: string, accessToken: string): Promise<WechatUploadResponse>;
25
+ uploadImage(file: Blob, filename: string, accessToken: string, appId?: string): Promise<WechatUploadResponse>;
21
26
  publishToDraft(accessToken: string, options: WechatPublishOptions): Promise<WechatPublishResponse>;
22
27
  clearCache(): Promise<void>;
23
28
  }
@@ -1,10 +1,28 @@
1
1
  import type { HttpAdapter } from "./http.js";
2
+ export interface ImageCropPercent {
3
+ ratio: string;
4
+ x1: number;
5
+ y1: number;
6
+ x2: number;
7
+ y2: number;
8
+ }
9
+ export interface ImageListItem {
10
+ image_media_id: string;
11
+ crop_percent_list?: ImageCropPercent[];
12
+ }
13
+ export interface ImageInfo {
14
+ image_list: ImageListItem[];
15
+ }
2
16
  export interface WechatPublishOptions {
3
17
  title: string;
4
18
  author?: string;
5
19
  content: string;
6
20
  thumb_media_id: string;
7
21
  content_source_url?: string;
22
+ article_type?: "news" | "newspic";
23
+ image_info?: ImageInfo;
24
+ need_open_comment?: 0 | 1;
25
+ only_fans_can_comment?: 0 | 1;
8
26
  }
9
27
  export interface WechatErrorResponse {
10
28
  errcode: number;
package/dist/wrapper.js CHANGED
@@ -327,6 +327,19 @@ async function uploadCover(serverUrl, headers, cover, relativePath) {
327
327
  }
328
328
  return cover;
329
329
  }
330
+ async function uploadImageList(serverUrl, headers, imageList, relativePath) {
331
+ if (imageList && imageList.length > 0) {
332
+ const uploadPromises = imageList.map(async (image) => {
333
+ if (needUpload(image)) {
334
+ const newImageUrl = await uploadLocalImage(image, serverUrl, headers, relativePath);
335
+ return newImageUrl || image;
336
+ }
337
+ return image;
338
+ });
339
+ return await Promise.all(uploadPromises);
340
+ }
341
+ return imageList || [];
342
+ }
330
343
  const nodeHttpAdapter = {
331
344
  fetch,
332
345
  createMultipart(field, file, filename) {
@@ -404,7 +417,7 @@ const wechatPublisher = new WechatPublisher(
404
417
  new NodeUploadCacheAdapter()
405
418
  );
406
419
  const credentialStore = new CredentialStore(new NodeCredentialStorageAdapter());
407
- async function uploadImage(imageUrl, accessToken, fileName, relativePath) {
420
+ async function uploadImage(imageUrl, accessToken, fileName, relativePath, appId) {
408
421
  let fileData;
409
422
  let finalName;
410
423
  if (imageUrl.startsWith("http")) {
@@ -433,11 +446,11 @@ async function uploadImage(imageUrl, accessToken, fileName, relativePath) {
433
446
  const fileFromPathResult = await fileFromPath(resolvedPath);
434
447
  fileData = new Blob([await fileFromPathResult.arrayBuffer()], { type: fileFromPathResult.type });
435
448
  }
436
- const data = await wechatPublisher.uploadImage(fileData, finalName, accessToken);
449
+ const data = await wechatPublisher.uploadImage(fileData, finalName, accessToken, appId);
437
450
  mediaIdMapping.set(data.url, data.media_id);
438
451
  return data;
439
452
  }
440
- async function uploadImages(content, accessToken, relativePath) {
453
+ async function uploadImages(content, accessToken, relativePath, appId) {
441
454
  if (!content.includes("<img")) {
442
455
  return { html: content, firstImageId: "" };
443
456
  }
@@ -448,7 +461,7 @@ async function uploadImages(content, accessToken, relativePath) {
448
461
  const dataSrc = element.getAttribute("src");
449
462
  if (dataSrc) {
450
463
  if (!dataSrc.startsWith("https://mmbiz.qpic.cn")) {
451
- const resp = await uploadImage(dataSrc, accessToken, void 0, relativePath);
464
+ const resp = await uploadImage(dataSrc, accessToken, void 0, relativePath, appId);
452
465
  element.setAttribute("src", resp.url);
453
466
  return resp.media_id;
454
467
  } else {
@@ -463,18 +476,18 @@ async function uploadImages(content, accessToken, relativePath) {
463
476
  return { html: updatedHtml, firstImageId };
464
477
  }
465
478
  async function publishToWechatDraft(articleOptions, publishOptions = {}) {
466
- const { title, content, cover, author, source_url } = articleOptions;
479
+ const { title, content, cover, author, source_url, need_open_comment, only_fans_can_comment } = articleOptions;
467
480
  const { appId, appSecret, relativePath } = publishOptions;
468
481
  const { appId: appIdFinal, appSecret: appSecretFinal } = await getAppIdAndSecret(appId, appSecret);
469
482
  const accessToken = await wechatPublisher.getAccessTokenWithCache(appIdFinal, appSecretFinal);
470
- const { html, firstImageId } = await uploadImages(content, accessToken, relativePath);
483
+ const { html, firstImageId } = await uploadImages(content, accessToken, relativePath, appIdFinal);
471
484
  let thumbMediaId;
472
485
  if (cover) {
473
486
  const cachedThumbMediaId = mediaIdMapping.get(cover);
474
487
  if (cachedThumbMediaId) {
475
488
  thumbMediaId = cachedThumbMediaId;
476
489
  } else {
477
- const resp = await uploadImage(cover, accessToken, "cover.jpg", relativePath);
490
+ const resp = await uploadImage(cover, accessToken, "cover.jpg", relativePath, appIdFinal);
478
491
  thumbMediaId = resp.media_id;
479
492
  }
480
493
  } else {
@@ -483,7 +496,7 @@ async function publishToWechatDraft(articleOptions, publishOptions = {}) {
483
496
  if (cachedThumbMediaId) {
484
497
  thumbMediaId = cachedThumbMediaId;
485
498
  } else {
486
- const resp = await uploadImage(firstImageId, accessToken, "cover.jpg", relativePath);
499
+ const resp = await uploadImage(firstImageId, accessToken, "cover.jpg", relativePath, appIdFinal);
487
500
  thumbMediaId = resp.media_id;
488
501
  }
489
502
  } else {
@@ -498,7 +511,9 @@ async function publishToWechatDraft(articleOptions, publishOptions = {}) {
498
511
  content: html,
499
512
  thumb_media_id: thumbMediaId,
500
513
  author,
501
- content_source_url: source_url
514
+ content_source_url: source_url,
515
+ need_open_comment: need_open_comment ? 1 : 0,
516
+ only_fans_can_comment: only_fans_can_comment ? 1 : 0
502
517
  });
503
518
  if (data.media_id) {
504
519
  return data;
@@ -526,6 +541,52 @@ async function getAppIdAndSecret(appId, appSecret) {
526
541
  }
527
542
  throw new Error(`未能找到 AppID 为 "${appId}" 的公众号凭据,请检查配置文件。`);
528
543
  }
544
+ async function publishImageTextToWechatDraft(articleOptions, publishOptions = {}) {
545
+ const { title, content, images, cover, author, need_open_comment, only_fans_can_comment } = articleOptions;
546
+ const { appId, appSecret, relativePath } = publishOptions;
547
+ const { appId: appIdFinal, appSecret: appSecretFinal } = await getAppIdAndSecret(appId, appSecret);
548
+ if (!images || images.length === 0) {
549
+ throw new Error("图片消息至少需要一张图片");
550
+ }
551
+ const accessToken = await wechatPublisher.getAccessTokenWithCache(appIdFinal, appSecretFinal);
552
+ const imageInfoList = [];
553
+ for (const img of images) {
554
+ const resp = await uploadImage(img, accessToken, void 0, relativePath);
555
+ imageInfoList.push({ image_media_id: resp.media_id });
556
+ }
557
+ let thumbMediaId = "";
558
+ if (cover) {
559
+ const cachedThumbMediaId = mediaIdMapping.get(cover);
560
+ if (cachedThumbMediaId) {
561
+ thumbMediaId = cachedThumbMediaId;
562
+ } else {
563
+ const resp = await uploadImage(cover, accessToken, "cover.jpg", relativePath);
564
+ thumbMediaId = resp.media_id;
565
+ }
566
+ } else {
567
+ thumbMediaId = imageInfoList[0].image_media_id;
568
+ }
569
+ if (!thumbMediaId) {
570
+ throw new Error("未能获取封面图的 media_id");
571
+ }
572
+ const data = await wechatPublisher.publishToDraft(
573
+ accessToken,
574
+ {
575
+ title,
576
+ content,
577
+ thumb_media_id: thumbMediaId,
578
+ author,
579
+ article_type: "newspic",
580
+ image_info: { image_list: imageInfoList },
581
+ need_open_comment: need_open_comment ? 1 : 0,
582
+ only_fans_can_comment: only_fans_can_comment ? 1 : 0
583
+ }
584
+ );
585
+ if (data.media_id) {
586
+ return data;
587
+ }
588
+ throw new Error(`上传图片消息到公众号草稿失败: ${JSON.stringify(data)}`);
589
+ }
529
590
  const defaultConfig = {};
530
591
  const configPath = path.join(configDir, "config.json");
531
592
  class ConfigStore {
@@ -625,25 +686,22 @@ async function renderWithTheme(markdownContent, options) {
625
686
  return gzhContent;
626
687
  }
627
688
  async function renderStyledContent(content, options = {}) {
628
- const preHandlerContent = await wenyanCoreInstance.handleFrontMatter(content);
629
- const html = await wenyanCoreInstance.renderMarkdown(preHandlerContent.body);
689
+ const html = await wenyanCoreInstance.renderMarkdown(content);
630
690
  const dom = new JSDOM(`<body><section id="wenyan">${html}</section></body>`);
631
691
  const document = dom.window.document;
632
692
  const wenyan = document.getElementById("wenyan");
633
693
  const result = await wenyanCoreInstance.applyStylesWithTheme(wenyan, options);
634
- return {
635
- content: result,
636
- title: preHandlerContent.title,
637
- cover: preHandlerContent.cover,
638
- description: preHandlerContent.description,
639
- author: preHandlerContent.author,
640
- source_url: preHandlerContent.source_url
641
- };
694
+ return result;
642
695
  }
643
696
  async function prepareRenderContext(inputContent, options, getInputContent) {
644
697
  const { content, absoluteDirPath } = await getInputContent(inputContent, options.file);
645
- const gzhContent = await renderWithTheme(content, options);
646
- return { gzhContent, absoluteDirPath };
698
+ const preHandlerContent = await wenyanCoreInstance.handleFrontMatter(content);
699
+ if (preHandlerContent.image_list && preHandlerContent.image_list.length > 0) {
700
+ return { gzhContent: preHandlerContent, absoluteDirPath };
701
+ }
702
+ const styledContent = await renderWithTheme(preHandlerContent.content, options);
703
+ preHandlerContent.content = styledContent;
704
+ return { gzhContent: preHandlerContent, absoluteDirPath };
647
705
  }
648
706
  async function listThemes() {
649
707
  const themes = getAllGzhThemes();
@@ -705,30 +763,34 @@ async function checkCustomThemeExists(themeId) {
705
763
  const customThemes = await configStore.getThemes();
706
764
  return customThemes.some((theme) => theme.id === themeId);
707
765
  }
708
- async function getGzhContent(content, themeId, hlThemeId, isMacStyle = true, isAddFootnote = true) {
709
- return await renderStyledContent(content, {
710
- themeId,
711
- hlThemeId,
712
- isMacStyle,
713
- isAddFootnote
714
- });
715
- }
716
766
  async function renderAndPublish(inputContent, options, getInputContent) {
717
767
  const { gzhContent, absoluteDirPath } = await prepareRenderContext(inputContent, options, getInputContent);
718
768
  if (!gzhContent.title) throw new Error("未能找到文章标题");
719
- const data = await publishToWechatDraft(
720
- {
721
- title: gzhContent.title,
722
- content: gzhContent.content,
723
- cover: gzhContent.cover,
724
- author: gzhContent.author,
725
- source_url: gzhContent.source_url
726
- },
727
- {
728
- appId: options.appId,
729
- relativePath: absoluteDirPath
730
- }
731
- );
769
+ let data;
770
+ if (gzhContent.image_list && gzhContent.image_list.length > 0) {
771
+ data = await publishImageTextToWechatDraft(
772
+ {
773
+ ...gzhContent,
774
+ title: gzhContent.title,
775
+ images: gzhContent.image_list
776
+ },
777
+ {
778
+ appId: options.appId,
779
+ relativePath: absoluteDirPath
780
+ }
781
+ );
782
+ } else {
783
+ data = await publishToWechatDraft(
784
+ {
785
+ ...gzhContent,
786
+ title: gzhContent.title
787
+ },
788
+ {
789
+ appId: options.appId,
790
+ relativePath: absoluteDirPath
791
+ }
792
+ );
793
+ }
732
794
  if (data.media_id) {
733
795
  return data.media_id;
734
796
  } else {
@@ -743,7 +805,11 @@ async function renderAndPublishToServer(inputContent, options, getInputContent)
743
805
  await verifyAuth(serverUrl, headers);
744
806
  const { gzhContent, absoluteDirPath } = await prepareRenderContext(inputContent, options, getInputContent);
745
807
  if (!gzhContent.title) throw new Error("未能找到文章标题");
746
- gzhContent.content = await uploadLocalImages(gzhContent.content, serverUrl, headers, absoluteDirPath);
808
+ if (gzhContent.image_list && gzhContent.image_list.length > 0) {
809
+ gzhContent.image_list = await uploadImageList(serverUrl, headers, gzhContent.image_list, absoluteDirPath);
810
+ } else {
811
+ gzhContent.content = await uploadLocalImages(gzhContent.content, serverUrl, headers, absoluteDirPath);
812
+ }
747
813
  gzhContent.cover = await uploadCover(serverUrl, headers, gzhContent.cover, absoluteDirPath);
748
814
  const mdFileId = await uploadStyledContent(gzhContent, serverUrl, headers);
749
815
  return await requestServerPublish(mdFileId, serverUrl, headers, options);
@@ -755,7 +821,6 @@ export {
755
821
  configStore,
756
822
  credentialStore,
757
823
  ensureDir,
758
- getGzhContent,
759
824
  getNormalizeFilePath,
760
825
  isAbsolutePath,
761
826
  listThemes,
@@ -763,6 +828,7 @@ export {
763
828
  md5FromFile,
764
829
  normalizePath,
765
830
  prepareRenderContext,
831
+ publishImageTextToWechatDraft,
766
832
  publishToDraft,
767
833
  publishToWechatDraft,
768
834
  readBinaryFile,
@@ -771,7 +837,6 @@ export {
771
837
  renderAndPublish,
772
838
  renderAndPublishToServer,
773
839
  renderStyledContent,
774
- renderWithTheme,
775
840
  safeReadJson,
776
841
  safeWriteJson,
777
842
  wechatPublisher
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wenyan-md/core",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "Core library for Wenyan markdown rendering & publishing",
5
5
  "author": "Lei <caol64@gmail.com> (https://github.com/caol64)",
6
6
  "license": "Apache-2.0",