Skip to content

Commit 9b15696

Browse files
authored
[201_64] 支持 Around 多种括号类型的切换 (#2646)
1 parent 261d6fa commit 9b15696

File tree

4 files changed

+189
-5
lines changed

4 files changed

+189
-5
lines changed

TeXmacs/plugins/lang/dic/en_US/zh_CN.scm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,28 @@
33
("Advanced header" "高级页眉")
44
("Advanced page numbering" "高级页码")
55
("Allow multiple spaces" "允许多个空格")
6+
("Angle brackets ⟨ ⟩" "尖括号 ⟨ ⟩")
67
("Applying from" "起始于")
78
("Applying to" "结束于")
89
("As" "作为")
10+
("Backslash \\ /" "反斜线 \\ /")
911
("BibTeX command" "BibTeX命令")
1012
("Bitmap export resolution (dpi):" "Bitmap 导出分辨率(dpi):")
13+
("Braces { }" "大括号 { }")
14+
("Brackets [ ]" "中括号 [ ]")
1115
("Buy Now!" "现在购买!")
16+
("Ceiling brackets ⌈ ⌉" "上取整括号 ⌈ ⌉")
1217
("CJK" "中日韩")
1318
("CSS stylesheet:" "CSS 样式表:")
1419
("Clipboard image format:" "剪贴板图片格式:")
1520
("Conservative conversion options" "保守的转换选项")
1621
("Correction" "纠正")
1722
("Default document style" "默认文档样式")
1823
("Delete::keyboard" "Delete")
24+
("Double brackets ⟦ ⟧" "双括号 ⟦ ⟧")
25+
("Double vertical bars ‖ ‖" "双竖线 ‖ ‖")
1926
("Documents in separate windows" "单个文档独立窗口")
27+
("Empty brackets . ." "空括号 . .")
2028
("End::keyboard" "End")
2129
("Expand TeXmacs macros with no LaTeX equivalents" "展开没有 LaTeX 等价项的 TeXmacs 宏")
2230
("Experimental features (to be used with care)" "实验性功能(请谨慎使用)")
@@ -26,6 +34,7 @@
2634
("Export mathematical formulas as MathML" "将数学公式导出为MathML")
2735
("Exporting" "导出中")
2836
("Failed to save" "无法保存")
37+
("Floor brackets ⌊ ⌋" "下取整括号 ⌊ ⌋")
2938
("GNU FDL" "GNU自由文档许可证")
3039
("GNU TeXmacs comes without any form of legal warranty" "GNU TeXmacs 无任何形式的法律保证")
3140
("GNU TeXmacs falls under the GNU general public license" "GNU TeXmacs 使用 GNU 通用公共许可授权")
@@ -44,6 +53,7 @@
4453
("Open Pdf?" "打开 Pdf?")
4554
("PageDown::keyboard" "PageDown")
4655
("PageUp::keyboard" "PageUp")
56+
("Parentheses ( )" "小括号 ( )")
4757
("Pause" "暂停")
4858
("Plain::theme" "浅色")
4959
("Play" "播放")
@@ -67,6 +77,7 @@
6777
("SimHei" "黑体")
6878
("SimKai" "楷体")
6979
("SimSun" "宋体")
80+
("Slash / \\" "斜线 / \\")
7081
("Slovak" "斯洛伐克语")
7182
("Slovenian" "斯洛维尼亚语")
7283
("Space::format" "空白")
@@ -99,6 +110,7 @@
99110
("Windows Bitmap" "Windows位图")
100111
("You do not have read access to" "你没有权限读取")
101112
("You can save the document using Save as." "可通过另存为保存文档。")
113+
("Vertical bars | |" "竖线 | |")
102114
("a series" "A系列")
103115
("abbreviation" "缩写")
104116
("about menu" "关于菜单")

TeXmacs/progs/math/math-edit.scm

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,13 @@
437437
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
438438

439439
(define lbrackets
440-
'("(" "[" "{" "<langle>" "|" "<||>" "<lfloor>" "<lceil>" "<llbracket>"))
440+
'("(" "[" "{" "<langle>" "<llbracket>" "<lfloor>" "<lceil>" "|" "<||>" "/" "\\" "<nobracket>"))
441441

442442
(define mbrackets
443443
'("|" "<||>" "/" "\\"))
444444

445445
(define rbrackets
446-
'(")" "]" "}" "<rangle>" "|" "<||>" "<rfloor>" "<rceil>" "<rrbracket>"))
446+
'(")" "]" "}" "<rangle>" "<rrbracket>" "<rfloor>" "<rceil>" "|" "<||>" "\\" "/" "<nobracket>"))
447447

448448
(define (bracket-circulate t forward? brackets)
449449
(cond ((and (tree-in? t '(around around*))
@@ -1039,6 +1039,137 @@ list
10391039
(noop))
10401040
(noop))
10411041

1042+
(define bracket-variant-alist
1043+
;; 括号变体统一映射表和辅助函数
1044+
;; 定义统一的变体映射表:每个变体对应左右括号符号
1045+
'((parentheses "(" ")")
1046+
(brackets "[" "]")
1047+
(braces "{" "}")
1048+
(angle "<langle>" "<rangle>")
1049+
(double "<llbracket>" "<rrbracket>")
1050+
(floor "<lfloor>" "<rfloor>")
1051+
(ceiling "<lceil>" "<rceil>")
1052+
(vertical "|" "|")
1053+
(double-vertical "<||>" "<||>")
1054+
(slash "/" "\\")
1055+
(backslash "\\" "/")
1056+
(empty "<nobracket>" "<nobracket>")))
1057+
1058+
(define (get-bracket-node child)
1059+
;; 获取括号节点中的实际符号节点
1060+
(cond ((tree-atomic? child) child)
1061+
((and (tree-in? child '(left right))
1062+
(> (tree-arity child) 1))
1063+
(tree-ref child 0))
1064+
(else #f)))
1065+
1066+
;; 辅助函数:
1067+
(define (set-bracket-node! child sym)
1068+
;; 设置括号节点中的符号
1069+
(with node (get-bracket-node child)
1070+
(when node (tree-assign node sym))))
1071+
1072+
(define (bracket-set-pair t lb rb)
1073+
;; 括号设置函数
1074+
;; 实际修改 around/around* 节点的左右括号符号
1075+
(when (== (tree-arity t) 3)
1076+
(set-bracket-node! (tree-ref t 0) lb)
1077+
(set-bracket-node! (tree-ref t 2) rb)))
1078+
1079+
(define (get-bracket-symbol child)
1080+
;; 括号符号提取器
1081+
;; 从子节点中提取括号符号字符串
1082+
(with node (get-bracket-node child)
1083+
(if node (tree->string node) "")))
1084+
1085+
(define (bracket-pair->variant lb rb)
1086+
;; 符号到标识的映射器
1087+
;; 将具体的括号符号对映射到伪变体标识符
1088+
(let loop ((alist bracket-variant-alist))
1089+
(cond ((null? alist) #f)
1090+
((and (== lb (cadar alist))
1091+
(== rb (caddar alist)))
1092+
(caar alist))
1093+
(else (loop (cdr alist))))))
1094+
1095+
#|
1096+
get-bracket-variant
1097+
从 around/around* 节点检测当前括号类型,返回伪变体标识
1098+
1099+
语法
1100+
----
1101+
(get-bracket-variant t)
1102+
1103+
参数
1104+
----
1105+
t : tree
1106+
必须是 around 或 around* 节点,表示一个括号结构
1107+
1108+
返回值
1109+
----
1110+
symbol | boolean
1111+
- 成功时:返回对应的变体标识符(如 parentheses, brackets, braces 等)
1112+
- 失败时:返回 #f(当 t 不是 around/around* 节点或 arity 不为 3 时)
1113+
1114+
逻辑
1115+
----
1116+
1. 检查 t 是否为 around 或 around* 节点(通过 :require 条件)
1117+
2. 验证节点的 arity 是否为 3(左括号、内容、右括号)
1118+
3. 通过 get-bracket-symbol 提取左右括号的实际符号字符串
1119+
4. 调用 bracket-pair->variant 将符号对映射到预定义的变体标识
1120+
1121+
注意
1122+
----
1123+
此函数是括号变体系统的一部分,用于检测当前括号的显示样式。
1124+
变体标识定义在 bracket-variant-alist 中,如 parentheses, brackets, braces 等
1125+
|#
1126+
(tm-define (get-bracket-variant t)
1127+
;; 当前括号类型检测器
1128+
;; 从 around 节点检测当前括号类型,返回伪变体标识
1129+
(:require (tree-in? t '(around around*)))
1130+
(if (== (tree-arity t) 3)
1131+
(with lb (get-bracket-symbol (tree-ref t 0))
1132+
(with rb (get-bracket-symbol (tree-ref t 2))
1133+
(bracket-pair->variant lb rb)))
1134+
#f))
1135+
1136+
#|
1137+
variant-set
1138+
变体切换系统的重载函数,将伪变体标识映射到具体的括号符号对
1139+
1140+
语法
1141+
----
1142+
(variant-set t v)
1143+
1144+
参数
1145+
----
1146+
t : tree
1147+
必须是 around 或 around* 节点,表示一个括号结构
1148+
v : symbol
1149+
变体标识符,如 parentheses, brackets, braces 等(定义在 bracket-variant-alist 中)
1150+
1151+
返回值
1152+
----
1153+
不返回
1154+
1155+
逻辑
1156+
----
1157+
1. 在 bracket-variant-alist 中查找变体标识 v
1158+
2. 如果找到对应的括号符号对,调用 bracket-set-pair 设置节点的左右括号
1159+
1160+
注意
1161+
----
1162+
此函数是括号变体系统的一部分,用于切换括号的显示样式。
1163+
是通用变体系统 variant-set 针对 around/around* 节点的重载实现
1164+
|#
1165+
(tm-define (variant-set t v)
1166+
;; 变体切换系统的重载函数
1167+
;; 将伪变体标识映射到具体的括号符号对,调用 bracket-set-pair
1168+
(:require (tree-in? t '(around around*)))
1169+
(let ((pair (assoc v bracket-variant-alist)))
1170+
(when pair
1171+
(bracket-set-pair t (cadr pair) (caddr pair)))))
1172+
10421173
(tm-define (kbd-paste)
10431174
(:require (in-math?))
10441175
;; 在数学模式下粘贴

TeXmacs/progs/math/math-menu.scm

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1313

1414
(texmacs-module (math math-menu)
15-
(:use (table table-edit)))
15+
(:use (table table-edit)
16+
(math math-edit)))
1617

1718
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1819
;; Inserting mathematical markup
@@ -1465,12 +1466,35 @@
14651466
(list "math-brackets"))
14661467

14671468
(tm-define (focus-tag-name l)
1469+
;; 在 around 环境中时
1470+
;; get-bracket-variant 如果能获取到伪变体则走伪变体 focus-tag-name
1471+
;; 否则返回默认的 "Around"
14681472
(:require (in? l '(around around*)))
1469-
"Around")
1473+
(with t (focus-tree)
1474+
(if (and t (tree-in? t '(around around*)))
1475+
(with v (get-bracket-variant t)
1476+
(if v (focus-tag-name v) "Around"))
1477+
"Around")))
1478+
1479+
(tm-define (focus-tag-name l)
1480+
;; 具体括号类型伪变体表
1481+
(:require (in? l '(parentheses brackets braces angle double floor ceiling vertical double-vertical slash backslash empty)))
1482+
(cond ((== l 'parentheses) "Parentheses ( )")
1483+
((== l 'brackets) "Brackets [ ]")
1484+
((== l 'braces) "Braces { }")
1485+
((== l 'angle) "Angle brackets ⟨ ⟩")
1486+
((== l 'double) "Double brackets ⟦ ⟧")
1487+
((== l 'floor) "Floor brackets ⌊ ⌋")
1488+
((== l 'ceiling) "Ceiling brackets ⌈ ⌉")
1489+
((== l 'vertical) "Vertical bars | |")
1490+
((== l 'double-vertical) "Double vertical bars ‖ ‖")
1491+
((== l 'slash) "Slash / \\")
1492+
((== l 'backslash) "Backslash \\ /")
1493+
((== l 'empty) "Empty brackets . .")))
14701494

14711495
(tm-define (focus-variants-of t)
14721496
(:require (tree-in? t '(around around*)))
1473-
'(around))
1497+
'(parentheses brackets braces angle double floor ceiling vertical double-vertical slash backslash empty))
14741498

14751499
(tm-menu (focus-toggle-menu t)
14761500
(:require (tree-in? t '(around around*)))

devel/201_64.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# [201_64] 支持 Around 多种括号类型的切换
2+
3+
## 如何测试
4+
1. 进入数学模式,输入括号(如 `(``[`)进入 around 环境
5+
2. 观察顶部菜单栏,原来显示是 `Around` 标签且不可点击,现在是具体括号类型名且可以点击进去
6+
3. 点击这个括号类型标签,会出现 12 种括号类型,应该可正常选择与切换
7+
4. 使用 `Shift+Alt+上下键` 循环切换括号类型,确认切换顺序与菜单列表一致
8+
9+
## 2026/1/22
10+
### What
11+
为 around 环境实现完整的括号类型切换功能,支持通过菜单选择和 `Shift+Alt+上下键` 快捷键循环 切换 12 种常见括号类型
12+
13+
### How
14+
1. 扩展 `lbrackets``rbrackets` 列表,补全斜线、反斜线和空括号类型,使 `Shift+Alt+上下键` 支持全部 12 种括号循环
15+
2. 定义伪变体系统:`focus-variants-of` 返回 12 个伪变体标识,使 around 菜单标签自动显示为可点击的下拉箭头并生成变体选择菜单
16+
3. 实现 `variant-set` 函数重载,将伪变体标识映射到具体的括号符号对,并处理括号尺寸信息的保留
17+
4. **实现动态标签显示**:修改 `focus-tag-name` 函数,根据当前括号符号动态显示具体括号类型名称(如 "Parentheses ( )"、"Brackets [ ]" 等)

0 commit comments

Comments
 (0)