Skip to content

Commit 13e762d

Browse files
da-liiiclaude
andauthored
[1293] 草稿文件放开 .stem 后缀支持并导出样式包为 .stem 草稿 (#4533)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 699052c commit 13e762d

13 files changed

Lines changed: 328 additions & 37 deletions

File tree

TeXmacs/progs/kernel/boot/abbrevs.scm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,19 @@
222222
(when (null? (cdr opts))
223223
;; Issue #327: Use last file dialog directory if current buffer is scratch
224224
(let* ((master (buffer-get-master (current-buffer)))
225+
(style-target (and (defined? 'style-package-target-url)
226+
(style-package-target-url (current-buffer))
227+
) ;and
228+
) ;style-target
225229
(last-dir (and (url-scratch? master)
230+
(not style-target)
226231
(defined? 'get-last-file-dialog-directory)
227232
(get-last-file-dialog-directory)
228233
) ;and
229234
) ;last-dir
230235
) ;
231-
(cond ((and last-dir (string? last-dir) (not (string-null? last-dir)))
236+
(cond (style-target (set! opts (list (car opts) style-target)))
237+
((and last-dir (string? last-dir) (not (string-null? last-dir)))
232238
(set! opts (list (car opts) (system->url last-dir)))
233239
) ;
234240
((url-scratch? master)

TeXmacs/progs/source/source-edit.scm

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,24 @@
192192
) ;with
193193
) ;define
194194

195-
(tm-define (extract-style-file style?)
196-
(let* ((tit (extract-source-title style?))
197-
(packs (extract-use-package style?))
195+
(define style-package-targets (make-ahash-table))
196+
197+
(tm-define (style-package-target-url buf) (ahash-ref style-package-targets buf))
198+
199+
(define (style-package-compute-target orig)
200+
(cond ((or (url-scratch? orig) (url-rooted-tmfs? orig))
201+
(url-append (get-documents-path)
202+
(string-append "LiiiSTEM/" (url-basename orig) ".stem")
203+
) ;url-append
204+
) ;
205+
(else (url-append (url-head orig) (string-append (url-basename orig) ".stem")))
206+
) ;cond
207+
) ;define
208+
209+
(tm-define (extract-style-package)
210+
(let* ((orig (current-buffer))
211+
(tit (extract-source-title #f))
212+
(packs (extract-use-package #f))
198213
(inits (extract-style-parameters))
199214
(defs (extract-macro-definitions))
200215
(body `(document ,tit ,@packs ,@inits ,@defs))
@@ -203,7 +218,11 @@
203218
(body ,body))
204219
) ;doc
205220
) ;
206-
(new-buffer)
221+
(new-buffer ".stem")
222+
(ahash-set! style-package-targets
223+
(current-buffer)
224+
(style-package-compute-target orig)
225+
) ;ahash-set!
207226
(delayed (:idle 1) (buffer-set (current-buffer) doc))
208227
) ;let*
209228
) ;tm-define

TeXmacs/progs/source/source-menu.scm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,7 @@
175175
("Edit macros" (open-macros-editor :global))
176176
("Edit preamble" (toggle-preamble-mode))
177177
---
178-
("Extract style file" (extract-style-file #t))
179-
("Extract style package" (extract-style-file #f))
178+
("Extract style package" (extract-style-package))
180179
) ;menu-bind
181180

182181
(menu-bind source-menu
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2+
;;
3+
;; MODULE : extract-style-package-test.scm
4+
;; DESCRIPTION : 单元测试:导出样式包生成 .stem 草稿文件及宏菜单结构验证
5+
;; COPYRIGHT : (C) 2026 Mogan STEM
6+
;;
7+
;; USAGE
8+
;; xmake b stem
9+
;; xmake r extract-style-package-test
10+
;;
11+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12+
13+
(import (liii check))
14+
15+
(check-set-mode! 'report-failed)
16+
17+
(load "./TeXmacs/progs/source/source-menu.scm")
18+
(load "./TeXmacs/progs/source/source-edit.scm")
19+
20+
(define (menu-contains-label? m label)
21+
(cond ((null? m) #f)
22+
((pair? m)
23+
(or (menu-contains-label? (car m) label) (menu-contains-label? (cdr m) label))
24+
) ;
25+
((string? m) (string=? m label))
26+
(else #f)
27+
) ;cond
28+
) ;define
29+
30+
(define (test-source-macros-menu-items)
31+
(let ((menu (source-macros-menu)))
32+
;; 验证已移除 "Extract style file",仅保留 "Extract style package"
33+
(check (menu-contains-label? menu "Extract style file") => #f)
34+
(check (menu-contains-label? menu "Extract style package") => #t)
35+
) ;let
36+
) ;define
37+
38+
(define (test-extract-style-package-stem-buffer)
39+
(let ((orig-buf (current-buffer)))
40+
(extract-style-package)
41+
(let* ((new-buf (current-buffer)) (name (url->string (url-tail new-buf))))
42+
;; 验证新创建的 buffer 是 .stem 后缀的草稿文件
43+
(check (string-starts? name "draft_") => #t)
44+
(check (string-ends? name ".stem") => #t)
45+
(check (url-scratch? new-buf) => #t)
46+
;; 验证记录了目标保存路径
47+
(check (url? (style-package-target-url new-buf)) => #t)
48+
) ;let*
49+
;; 切回原 buffer 并关闭测试草稿 buffer
50+
(buffer-close (current-buffer))
51+
(switch-to-buffer orig-buf)
52+
) ;let
53+
) ;define
54+
55+
(define (test-style-package-compute-target)
56+
(for-each (lambda (case
57+
) ;case
58+
(check (url->system (style-package-compute-target (system->url (car case))))
59+
=>
60+
(cdr case)
61+
) ;check
62+
) ;lambda
63+
'(("/home/da/docs/paper.tmu" . "/home/da/docs/paper.stem")
64+
("/home/da/projects/report.tm" . "/home/da/projects/report.stem")
65+
("/home/da/文档/测试.tmu" . "/home/da/文档/测试.stem")
66+
("/tmp/my_paper.tmu" . "/tmp/my_paper.stem"))
67+
) ;for-each
68+
) ;define
69+
70+
(tm-define (regtest-extract-style-package)
71+
(test-source-macros-menu-items)
72+
(test-extract-style-package-stem-buffer)
73+
(test-style-package-compute-target)
74+
(check-report)
75+
) ;tm-define

TeXmacs/progs/texmacs/texmacs/tm-files-test.scm

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,16 @@
6060
) ;define
6161

6262
(define (draft-name-stamp-part name)
63-
(let* ((body (substring name 6 (- (string-length name) 4)))
63+
(let* ((dot (string-rindex name #\.))
64+
(body (substring name 6 dot))
6465
(cut (or (string-index body #\-) (string-length body)))
6566
) ;
6667
(substring body 0 cut)
6768
) ;let*
6869
) ;define
6970

7071
(define (test-scratch-buffer-name-has-date-time-underscore)
71-
(let* ((path (scratch-buffer-name))
72+
(let* ((path (scratch-buffer-name ".tmu"))
7273
(name (url->string (url-tail (system->url path))))
7374
(stamp (draft-name-stamp-part name))
7475
) ;
@@ -80,6 +81,30 @@
8081
) ;let*
8182
) ;define
8283

84+
(define (test-scratch-buffer-name-stem)
85+
(let* ((path (scratch-buffer-name ".stem"))
86+
(name (url->string (url-tail (system->url path))))
87+
(stamp (draft-name-stamp-part name))
88+
) ;
89+
(check (string-starts? name "draft_") => #t)
90+
(check (string-ends? name ".stem") => #t)
91+
(check (string-length stamp) => 15)
92+
(check (substring stamp 8 9) => "_")
93+
) ;let*
94+
) ;define
95+
96+
(define (test-scratch-buffer-title-stem)
97+
(let ((tmu-title (scratch-buffer-title (draft-test-url "draft_20250802_153000.tmu")))
98+
(stem-title (scratch-buffer-title (draft-test-url "draft_20250802_153000.stem"))
99+
) ;stem-title
100+
(stem-n-title (scratch-buffer-title (draft-test-url "draft_20250802_153000-1.stem"))
101+
) ;stem-n-title
102+
) ;
103+
(check stem-title => tmu-title)
104+
(check stem-n-title => tmu-title)
105+
) ;let
106+
) ;define
107+
83108
(define (test-scratch-buffer-title-old-and-new-stamp)
84109
;; 往年草稿不显示时刻,新旧文件名必须得到同一标题
85110
(let ((old (scratch-buffer-title (draft-test-url "draft_20250802153000.tmu")))
@@ -122,6 +147,8 @@
122147
(test-auto-backup-official-url)
123148
(test-auto-backup-texmacs-path-buffer?)
124149
(test-scratch-buffer-name-has-date-time-underscore)
150+
(test-scratch-buffer-name-stem)
151+
(test-scratch-buffer-title-stem)
125152
(test-scratch-buffer-title-old-and-new-stamp)
126153
(test-scratch-buffer-title-legacy-one-underscore-this-week)
127154
(check-report)

TeXmacs/progs/texmacs/texmacs/tm-files.scm

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@
573573
(save-buffer-check-faithful name opts)
574574
(choose-file (lambda (x) (apply save-buffer-as-main (cons x opts)))
575575
"Save TeXmacs file"
576-
"tmu"
576+
"action_save_as"
577577
) ;choose-file
578578
) ;if
579579
) ;
@@ -1201,57 +1201,70 @@
12011201
(and (not (buffer-exists? u)) (not (url-exists? u)))
12021202
) ;define
12031203

1204-
(define (scratch-candidate dir stamp)
1205-
(url-append dir (string-append "draft_" stamp ".tmu"))
1204+
(define (normalize-draft-ext ext)
1205+
(if (equal? ext ".stem") ".stem" ".tmu")
1206+
) ;define
1207+
1208+
(define (scratch-candidate dir stamp ext)
1209+
(url-append dir (string-append "draft_" stamp ext))
12061210
) ;define
12071211

12081212
;; 秒级名字仍冲突时,追加 -2、-3 …… 保证唯一
12091213

1210-
(define (scratch-unique-name dir stamp i)
1214+
(define (scratch-unique-name dir stamp i ext)
12111215
(let ((u (scratch-candidate dir
12121216
(if (= i 0) stamp (string-append stamp "-" (number->string i)))
1217+
ext
12131218
) ;scratch-candidate
12141219
) ;u
12151220
) ;
1216-
(if (scratch-name-free? u) u (scratch-unique-name dir stamp (+ i 1)))
1221+
(if (scratch-name-free? u) u (scratch-unique-name dir stamp (+ i 1) ext))
12171222
) ;let
12181223
) ;define
12191224

12201225
;; 新 scratch buffer 的名字:日期与时刻用 _ 分开,精确到秒,冲突加 -N
1221-
;; 例: draft_20260901_194700.tmu / draft_20260901_194700-1.tmu
1226+
;; 例: draft_20260901_194700.tmu / draft_20260901_194700-1.tmu / .stem
12221227
;; 返回系统路径字符串(供 C++ make_new_buffer 使用)
1223-
(tm-define (scratch-buffer-name)
1228+
(tm-define (scratch-buffer-name ext)
12241229
(with dir
12251230
(scratch-buffer-dir)
12261231
(when (not (url-exists? dir))
12271232
(system-mkdir dir)
12281233
) ;when
12291234
(with full
12301235
(date->string (current-date) "~Y~m~d_~H~M~S")
1231-
(url->system (scratch-unique-name dir full 0))
1236+
(url->system (scratch-unique-name dir full 0 (normalize-draft-ext ext)))
12321237
) ;with
12331238
) ;with
12341239
) ;tm-define
12351240

1241+
(tm-define (new-buffer . opt-ext)
1242+
(cpp-new-buffer-with-ext (if (null? opt-ext) ".tmu" (normalize-draft-ext (car opt-ext)))
1243+
) ;cpp-new-buffer-with-ext
1244+
) ;tm-define
1245+
12361246
;; draft 文件名 → 纯数字时间戳,供标题按位切分(YYYYMMDDHH[MM][SS])。
12371247
;; 新格式 "draft_20260901_194700.tmu" → "20260901194700";
1248+
;; ".stem" 格式 "draft_20260901_194700.stem" → "20260901194700";
12381249
;; 旧格式 "draft_202608242127-2.tmu" → "202608242127";
12391250
;; 非 draft 名返回 #f
12401251

12411252
(define (draft-stamp u)
12421253
(with name
12431254
(url->string (url-tail u))
1244-
(and (string-starts? name "draft_")
1245-
(string-ends? name ".tmu")
1246-
(let* ((body (substring name 6 (- (string-length name) 4)))
1247-
(cut (or (string-index body #\-) (string-length body)))
1248-
(raw (substring body 0 cut))
1249-
;; 去掉日期与时刻之间的 _,标题逻辑仍按连续数字下标切
1250-
(digits (string-join (string-split raw "_") ""))
1251-
) ;
1252-
(and (>= (string-length digits) 12) digits)
1253-
) ;let*
1254-
) ;and
1255+
(let ((ext (url-suffix u)))
1256+
(and (in? ext '("tmu" "stem"))
1257+
(string-starts? name "draft_")
1258+
(let* ((body (substring name 6 (- (string-length name) (string-length ext) 1)))
1259+
(cut (or (string-index body #\-) (string-length body)))
1260+
(raw (substring body 0 cut))
1261+
;; 去掉日期与时刻之间的 _,标题逻辑仍按连续数字下标切
1262+
(digits (string-join (string-split raw "_") ""))
1263+
) ;
1264+
(and (>= (string-length digits) 12) digits)
1265+
) ;let*
1266+
) ;and
1267+
) ;let
12551268
) ;with
12561269
) ;define
12571270

0 commit comments

Comments
 (0)