@cliven/mddocx 1.0.2 → 1.0.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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "mddocx",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Markdown 转学术格式 Word 文档 (DOCX)。支持三线表、图题/表题自动编号、页码、页眉等学术论文排版规范。",
5
- "author": "Quan Guanyu",
5
+ "author": { "name": "Quan Guanyu" },
6
6
  "keywords": ["markdown", "docx", "word", "academic", "论文", "学术", "转换"],
7
7
  "skills": "./skills/"
8
8
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mddocx",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Markdown 转学术格式 Word 文档 (DOCX)。支持三线表、图题/表题自动编号、页码、页眉等学术论文排版规范。",
5
5
  "author": "Quan Guanyu",
6
6
  "homepage": "https://github.com/Trisia/mddocx",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mddocx",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Markdown 转学术格式 Word 文档 (DOCX)。支持三线表、图题/表题自动编号、页码、页眉等学术论文排版规范。",
5
5
  "author": "Quan Guanyu",
6
6
  "homepage": "https://github.com/Trisia/mddocx",
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # mddocx — Markdown 转学术格式 DOCX
2
2
 
3
- [![Claude Code](https://img.shields.io/badge/Agent-Claude%20Code-orange?logo=claude)](https://claude.com/code)
3
+ [![Claude Code](https://img.shields.io/badge/Agent-Claude%20Code-orange?logo=claude)](https://www.claudepluginhub.com/plugins/trisia-mddocx)
4
4
  [![Codex](https://img.shields.io/badge/Agent-Codex-blue?logo=openai)](https://github.com/openai/codex)
5
5
  [![Cursor](https://img.shields.io/badge/Agent-Cursor-6c47ff?logo=cursor)](https://cursor.com)
6
6
  [![OpenCode](https://img.shields.io/badge/Agent-OpenCode-teal)](https://opencode.ai)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cliven/mddocx",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Markdown 转学术格式 DOCX",
5
5
  "type": "module",
6
6
  "main": ".opencode/plugins/mddocx.js",
@@ -213,7 +213,7 @@ p.add_run().add_picture(img_path, width=img_width(img_path))
213
213
 
214
214
  ### 图题
215
215
 
216
- 图片下方(不空行)、小五(9pt)宋体加粗居中、格式 `图<章>-<序号> <alt>`、逐章编号。
216
+ 图片下方(不空行)、小五(9pt)宋体加粗居中、逐章编号。有章标题时格式 `图<章>-<序号> <alt>`,无章标题时格式 `图<序号> <alt>`。若 alt 为空,自动使用图片文件名(不含扩展名)作为图题。
217
217
 
218
218
  ```python
219
219
  p = doc.add_paragraph()
@@ -225,7 +225,7 @@ add_empty(doc) # 图题下方空一行
225
225
 
226
226
  ### 表格 + 表题
227
227
 
228
- **三线表**(顶线1.5pt/表头底线0.75pt/底线1.5pt粗,无竖线)。表题在上方(不空行)、五号(10.5pt)宋体加粗居中、格式`表<章>-<序号> <描述>`。
228
+ **三线表**(顶线1.5pt/表头底线0.75pt/底线1.5pt粗,无竖线)。表题在上方(不空行)、五号(10.5pt)宋体加粗居中。有章标题时格式`表<章>-<序号> <描述>`,无章标题时格式`表<序号> <描述>`。
229
229
 
230
230
  ```python
231
231
  # 表题
@@ -566,8 +566,40 @@ def add_empty_para(doc):
566
566
  # ============================================================
567
567
 
568
568
  def download_image(url):
569
- """下载图片到临时文件,返回路径。失败返回 None"""
569
+ """下载或复制图片到临时文件,返回路径。失败返回 None
570
+
571
+ 支持:
572
+ - HTTP/HTTPS URL:requests 下载
573
+ - 本地文件路径:直接复制到临时文件
574
+ - base64 data URI:解码保存
575
+ """
570
576
  import requests
577
+ import shutil
578
+
579
+ # 1. 本地文件路径(相对于工作目录的路径)
580
+ if os.path.exists(url):
581
+ suffix = os.path.splitext(url)[1] or '.png'
582
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
583
+ shutil.copy2(url, tmp.name)
584
+ tmp.close()
585
+ return tmp.name
586
+
587
+ # 2. base64 data URI
588
+ if url.startswith('data:'):
589
+ import base64
590
+ # 格式: data:image/png;base64,xxxx 或 data:image/png,xxxx
591
+ header, data = url.split(',', 1)
592
+ is_base64 = ';base64' in header
593
+ suffix = '.png'
594
+ mime_match = re.match(r'data:image/(\w+)', header)
595
+ if mime_match:
596
+ suffix = '.' + mime_match.group(1)
597
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
598
+ tmp.write(base64.b64decode(data) if is_base64 else data.encode())
599
+ tmp.close()
600
+ return tmp.name
601
+
602
+ # 3. HTTP/HTTPS URL
571
603
  headers = {'User-Agent': 'Mozilla/5.0 (compatible; mddoc-converter/1.0)'}
572
604
  try:
573
605
  resp = requests.get(url, headers=headers, timeout=30)
@@ -906,6 +938,7 @@ def generate_docx(nodes, output_path, title_text=None):
906
938
 
907
939
  # --- 计数器 ---
908
940
  chapter_path = [1] # 一级标题序号
941
+ has_chapter = False # 是否遇到章标题(# 一级标题)
909
942
  fig_counter = {} # key: chapter index tuple, value: counter
910
943
  tab_counter = {}
911
944
  eq_counter = {}
@@ -929,10 +962,14 @@ def generate_docx(nodes, output_path, title_text=None):
929
962
  return eq_counter[key]
930
963
 
931
964
  def make_fig_label():
932
- return f"图{chapter_path[0]}-{incr_fig()}"
965
+ if has_chapter:
966
+ return f"图{chapter_path[0]}-{incr_fig()}"
967
+ return f"图{incr_fig()}"
933
968
 
934
969
  def make_tab_label():
935
- return f"表{chapter_path[0]}-{incr_tab()}"
970
+ if has_chapter:
971
+ return f"表{chapter_path[0]}-{incr_tab()}"
972
+ return f"表{incr_tab()}"
936
973
 
937
974
  # --- 遍历节点生成内容 ---
938
975
  for node in nodes:
@@ -950,6 +987,7 @@ def generate_docx(nodes, output_path, title_text=None):
950
987
  lv = node['level']
951
988
  if lv == 1:
952
989
  # 一级标题:新页 + 三号黑体居中
990
+ has_chapter = True
953
991
  chapter_path[0] += 1
954
992
  chapter_path[1:] = [0] # reset sub-levels
955
993
 
@@ -1017,6 +1055,9 @@ def generate_docx(nodes, output_path, title_text=None):
1017
1055
  run_img.add_picture(img_path, width=w)
1018
1056
 
1019
1057
  # 图题:小五宋体加粗居中
1058
+ # alt 为空时,使用图片文件名(不含扩展名)作为默认图题
1059
+ if not alt:
1060
+ alt = os.path.splitext(os.path.basename(url))[0]
1020
1061
  p_cap = doc.add_paragraph()
1021
1062
  p_cap.alignment = WD_ALIGN_PARAGRAPH.CENTER
1022
1063
  run_cap = p_cap.add_run(f'{make_fig_label()} {alt}')