TabNav
Sublime Text 字表插件,用于在文本文件中的表格进行键盘导航。支持:Markdown、Org 模式、Textile、CSV。
详细信息
安装
- 总计 472
- Win 250
- Mac 143
- Linux 79
8 月 6 日 | 8 月 5 日 | 8 月 4 日 | 8 月 3 日 | 8 月 2 日 | 8 月 1 日 | 7 月 31 日 | 7 月 30 日 | 7 月 29 日 | 7 月 28 日 | 7 月 27 日 | 7 月 26 日 | 7 月 25 日 | 7 月 24 日 | 7 月 23 日 | 7 月 22 日 | 7 月 21 日 | 7 月 20 日 | 7 月 19 日 | 7 月 18 日 | 7 月 17 日 | 7 月 16 日 | 7 月 15 日 | 7 月 14 日 | 7 月 13 日 | 7 月 12 日 | 7 月 11 日 | 7 月 10 日 | 7 月 9 日 | 7 月 8 日 | 7 月 7 日 | 7 月 6 日 | 7 月 5 日 | 7 月 4 日 | 7 月 3 日 | 7 月 2 日 | 7 月 1 日 | 6 月 30 日 | 6 月 29 日 | 6 月 28 日 | 6 月 27 日 | 6 月 26 日 | 6 月 25 日 | 6 月 24 日 | 6 月 23 日 | 6 月 22 日 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Windows | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 1 |
Mac | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Linux | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
README
TabNav - 表格数据的键盘导航
TabNav 是一个 Sublime Text 插件,用于在表格文本数据进行键盘导航。在不离开键盘的情况下,快速移动和选择以下格式的“单元格”,如下:
- Markdown 管道表格
- Org 模式表格
- Textile 表格
- CSV 文件
TabNav 还提供了复制表格内容的功能,不包括标记,以便能够直接粘贴到其他程序中,例如 Excel。
目录
安装说明
包控制
- 如果尚未安装,请安装 Package Control。
- 在 Sublime Text 命令面板中,运行命令:
Package Control: Install Package
。 - 从可用包列表中选择
TabNav
。
Git 克隆
- 将此存储库克隆到本地计算机:
git clone https://github.com/mitchvm/tabnav.git
- 如果您没有直接克隆到 Sublime Text 包夹目录,请在本地 Sublime Text 包夹目录中创建指向仓库的符号链接。
手册
- 下载最新版本的 TabNav 发布 并将其解压缩到本地包夹目录。
- 要查找本地包目录,请打开Sublime Text首选项,然后选择“浏览包…
- 注意:所有TabNav文件应直接位于“Packages”目录下的一个
tabnav
目录中。如果文件进一步嵌套,Sublime Text将无法找到它们。
推荐键盘快捷键
:warning: TabNav在初始安装时没有启用的快捷键。
类似于TabNav的包显然需要很多快捷键。为了不覆盖默认的Sublime Text快捷键或您可能已安装的其他包的快捷键,同时允许您根据个人喜好和键盘布局自定义快捷键以获得最大灵活性,默认情况下不配置任何快捷键。
包中提供了推荐的关键绑定集,但它们都被注释掉了。推荐的关键绑定基于美式英语QWERTY键盘。它们在Enter键左侧的四键簇上使用得很频繁。
键盘快捷键设置
- 从Sublime Text主菜单中选择首选项 ❯ 包设置 ❯ TabNav ❯ 快捷键
- 这将在新窗口中打开TabNav快捷键包的快捷键文件(在左侧)以及您的用户快捷键文件(在右侧)。请注意,所有默认快捷键都已使用
//
在每个行首进行注释。
- 这将在新窗口中打开TabNav快捷键包的快捷键文件(在左侧)以及您的用户快捷键文件(在右侧)。请注意,所有默认快捷键都已使用
- 将注释掉的TabNav快捷键复制到您的用户快捷键数组中。
- 必须将快捷键粘贴到您的用户快捷键文件的外部数组括号内。
选择并保持复制的快捷键(仍然注释掉),取消整个选择的注释。(主菜单:编辑 ❯ 注释 ❯ 取消注释)
- 如果您没有其他自定义快捷键,您的用户快捷键文件应如下所示。注意首尾行的括号:
[
和]
,以及除了注释行之外每行的起始处没有//
。
[ // =================== TabNav Key Bindings ========================= // #### TabNav: Non-navigation keybindings #### { // Enable TabNav on current view // Note: this keybinding gets clobbered by the "select cell on right" keybindings // once TabNav is enabled. In a CSV file, what this means is that the first press // of this keybinding enables TabNav, and the next press selects the current cell. "keys": ["ctrl+'"], "command": "enable_tabnav" }, ... (a lot more key bindings here) // =================== End: TabNav Key Bindings ===================== ]
- 如果您没有其他自定义快捷键,您的用户快捷键文件应如下所示。注意首尾行的括号:
有关推荐快捷键的更多信息以及如何使用自定义快捷键,请参阅快捷键部分。
命令
TabNav向Sublime Text添加以下命令。它们都可通过选择菜单下的TabNav子菜单访问。
注意:如果您在packagecontrol.io上阅读此内容,则表格在GitHub上渲染得更加清晰。
表格导航命令
下面的表格导航命令仅在该上下文中有效。所有表格命令都与多光标兼容,甚至可以在多个、不连续的表格中有多个光标。
如上所述,TabNav默认没有启用的快捷键。下面显示的快捷键是推荐的快捷键。核心移动和选择快捷键组合了四种基本修改键组合之一与四个方向键之一
名称 | Windows/Linux | macOS | 描述 |
---|---|---|---|
移动光标到单元格… | Alt | 将所有光标移动到下一个所需的单元格。 | |
选择下一个单元格… | Ctrl | ⌘ | 将所有选择移动到相邻单元格。 |
选择最后一行/列中的单元格… | CtrlAlt | ⌘ | 将所有选择移动到行/列的最远单元格。 |
扩展选择… | CtrlShift | ⌘⇧ | 将所选方向上的下一个单元格添加到当前选择中。 |
扩展选择到行/列末尾… | CtrlAltShift | ⌘⇧ | 选择从当前选择的单元格到行/列末尾的方向上的所有单元格。 |
减小选择… | AltShift | ⇧ | 当连续选择了两个或更多单元格时,从所选方向上的单元格中移除选择。 |
添加光标到单元格… | 对于每个活动光标,在所需的方位的单元格中添加一个额外光标。推荐的键绑定不包括这些命令。 | ||
从单元格中删除光标... | 当序列中的两个或更多单元格包含光标时,在所需的方位的单元格中删除光标。推荐的键绑定不包括这些命令。 |
方向键 |
---|
上 [ |
左 ; | ' 右 |
/ 下 |
除了核心导航命令之外,还提供了这些额外的移动和选择命令。与大多数核心命令不同,所有这些命令都是幂等的 - 也就是说,无论它们被调用多少次,都会生成相同的Sublime Text选择器/光标,即使当前的选择器/光标已经与表格单元格对齐。这可能在记录宏时非常有用。
名称 | Windows/Linux 键绑定 | macOS 键绑定 |
---|---|---|
将光标移至当前单元格的起始位置1 | ||
将光标移至当前单元格的结尾位置1 | ||
选择从当前单元格的起始位置开始的部分 | ||
选择从当前单元格的结尾位置到结束的部分 | ||
选择当前单元格2 | ||
选择行单元格 | CtrlShift+L | ⌘⇧+L |
选择列单元格 | CtrlShift+C | ⌘⇧+C |
选择所有表格单元格 | CtrlAltShift+C | ⌘⇧+C |
1 在初始调用时,核心左右光标移动命令也会将光标分别移动到当前单元格的开始/结尾位置,如果不是所有选择都已经处于那个位置。
2 在初始调用时,核心下一个和扩展选择命令也会选择当前单元格,如果所有现有选择没有与表格单元格对齐。
其他命令
这些命令即使在表格外部的情况下也能运行。它们可以通过命令面板访问。
名称 | Windows/Linux 键绑定 | macOS 键绑定 | 描述 |
---|---|---|---|
在当前视图中启用 | Ctrl+' | ⌘+' | 在当前视图中启用TabNav。注意,一旦启用,键绑定会被诸如“将光标移到右侧的单元格”的命令(如果使用推荐的键绑定)覆盖。 |
在当前视图中禁用 | 禁用当前视图中TabNav | ||
设置捕获级别 | 配置当前视图中使用的选择 捕获级别。 | ||
将捕获级别重置为上一个 | 重置到之前配置的捕获级别。对录制宏很有用(例如,更改捕获级别,执行操作,重置捕获级别)。 | ||
设置CSV分隔符 | 设置用于CSV文件的分隔符。更多信息请参阅CSV上下文部分。 | ||
从选择中删除空白字符 | 删除所有当前选择两端的空白字符。 | ||
合并相邻的选择 | 合并共享相同起点/终点的选择区域。如果想要剪切/复制多个相邻列很有用。与cell 捕获级别一起使用。 |
||
将选择作为TSV复制 | 将所有当前选择作为制表符分隔数据复制,同一行的所有选择在文本中用制表符分隔,并在选择行之间有一个换行符。例如,这是一个有用的功能,用于将数据从文本表复制到Excel中。 | ||
带有分隔符的复制选择 | 与“将选择复制为TSV”命令相同,但提示用户输入要使用的分隔符。 |
上下文
TabNav基于“上下文”的概念运行,这定义了它如何在一个文档中识别表格数据。默认情况下,它包括Markdown、Org Mode、Textile和CSV文档的上下文定义。
Markdown
TabNav默认在Markdown文档中启用。仅支持“管道”样式的表格。其他Markdown表格样式目前不受支持。
一些Markdown支持“无边框”表格,其中表格外围不需要管道。例如,这是一个有效的表格
| Heading 1 | Heading 2 | Heading 3 |
|:----------|:----------|----------:|
| 1.1 | 1.2 | 1.3 |
| 2.1 | 2.2 | 2.3 |
或者,“加边框”的表格看起来像这样
| Heading 1 | Heading 2 | Heading 3 |
|:----------|:----------|----------:|
| 1.1 | 1.2 | 1.3 |
| 2.1 | 2.2 | 2.3 |
默认情况下,TabNav 支持无边框和加边框的表格。但是,为了能够支持无边框表格,任何包含管道字符的(非纯文本)文本行都被视为表格的一部分。
由于这是一个 Markdown 文件,如果我在这里放一个管道符号 |,那么这一行的文本就会被视为包含两个单元格的表格。
如果您只使用加边框的 Markdown 表格,您可以配置 TabNav,使其对视为表格的内容更加严格。请参阅 上下文配置。
Org 模式
TabNav 默认在 Org Mode 文档中启用,使用由 orgmode 或 orgextended 包定义的作用域。在“原始”作用域中的表格将被忽略。
TabNav 认识 Org Mode 表格中三种类型的标记行
Textile
TabNav 默认在 Textile 文档中启用。与大多数其他支持的标记语言相比,Textile 表格有两个不同之处
- 单元格和行可以包含内联表格标记,以及内容。
- 标记行可能不包含与表格单元格对齐的标记“单元格”。
单元格中的内联标记直接遵守当前的 捕获级别 - 当设置为 trimmed
或 content
时,标记将从选择中省略;当设置为 markup
或 cell
时,标记将包含在选择中。但是,行标记(即,在第一个管道之前分配给行的大小写和类)以及没有在行尾放置管道的独立标记行总是被忽略,不论捕获级别如何。标题和页脚行被视为普通内容行。
Textile 也支持跨越多个行和/或列的单元格,尽管 TabNav 没有特别努力来支持行和列的跨越。当移动单个光标/选择时,其行为基本上是您预期的,或者至少是可预测的,但当涉及到选择表格区域的区域内时,跨越多个行或列的单元格往往会给出非常奇怪的结果。
目前没有打算在 Textile 表格中添加对多个行或列跨越单元格的“正确”支持。
CSV
CSV 需要特殊处理,特别是因为“分隔值”文件有如此多的排列组合。没有针对 CSV 文档的具体 Sublime Text 作用域。相反,如果未确定其他上下文,TabNav 将 CSV 作为后备上下文处理 - 在 CSV 上下文中,TabNav 默认禁用 - 使用““在当前视图中启用” 命令来启用它。
TabNav 与 Advanced CSV 和 Rainbow CSV3 包件集成。如果当前视图中使用的语法来自这两个包中的任何一个,它们使用的分隔符也将自动由 TabNav 使用。
如果这两个包提供的语法在当前视图中未使用,那么 TabNav 将尝试通过检查文件的第一行来确定要使用的分隔符。如果文件的第一行只包含以下字符之一,那么该字符被认为是要用的分隔符
- 逗号:
,
- 分号:
;
- 管道:
|
- 制表符
您还可以使用““设置 CSV 分隔符” 命令指定要使用的特定分隔符(当不在高级 CSV 或 Rainbow CSV 语法中时)。请注意,无法将空格用作内置 CSV 上下文的分隔符。
最后,如果所有其他确定分隔符的方法都失败,则 TabNav 使用逗号作为默认分隔符。
3 TabNav 仅部分支持 Rainbow CSV 语法。两个限制是:只支持单字符分隔符,以及所有 CSV 文件都视为引用文件,不论是否使用 Rainbow CSV 的“简单”语法。
捕获级别
TabNav上下文提供多个“捕获级别”,这些级别定义了在单元格内选择多少文本。以下列出可用的捕获级别。每个级别都捕获比上一级别更多的所有文本。
- 修剪:仅包含单元格内的文本,排除任何两边的空白。只包含标记的单元格将从选中项中排除。
- 内容:单元格中的文本以及围绕文本的任何空白。只包含标记的单元格将从选中项中排除。
- 标记:单元格内容,以及单元格中的任何标记,但排除分隔符。所有表格单元格,包括没有任何标记的单元格,都包含在选中项中。
- 单元格:所有表格单元格都包含在选中项中,包括每个单元格前面(如有)的分隔符。
请注意,并非所有捕获级别都适用于所有上下文 - 例如,CSV不包含单元格分隔符之外的任何标记。此外,在大多数情况下,上下文不会在相同单元格内混合标记和内容。
默认捕获级别是content
。可以在特定视图中更改当前使用的捕获级别,使用“设置捕获级别”命令。默认捕获级别可以是全局配置或按上下文配置。
键盘快捷键
仅仅是由于包的性质,TabNav需要许多键绑定。建议的键绑定包括一些覆盖内置Sublime Text键绑定的键绑定。通过仅在非常具体的情况下激活TabNav键绑定,已尽最大努力减少对默认Sublime Text键绑定的影响。只有当以下所有条件都满足时,TabNave键绑定才会覆盖内置键绑定。
- 有一个TabNav 上下文配置与当前视图相匹配。
- TabNav在当前视图中已启用 - 在大多数上下文中默认启用。
- 第一个选区起点在表格内。
以下内置Sublime Text键绑定被建议的TabNav键绑定覆盖
操作系统 | 键绑定 | Sublime Text命令 | TabNav命令 |
---|---|---|---|
Windows, Linux | Ctrl+; | 打开“转到单词”覆盖层 | 选择左侧单元格 |
Windows, Linux | Ctrl+[ | 取消缩进行 | 选择上方单元格 |
Windows, Linux | Ctrl+/ | 注释行 | 选择下方单元格 |
Windows, Linux | CtrlShift+[ | 折叠选区 | 扩展选区向上 |
Windows, Linux | CtrlShift+/ | 插入注释 | 扩展选区向下 |
Windows, Linux | CtrlShift+L | 按行选择单元格 | Select cells in table row(s) |
macOS | ⌘+[ | 取消缩进行 | 选择上方单元格 |
macOS | ⌘⇧+[ | 折叠选区 | 扩展选区向上 |
macOS | ⌘⇧+L | 按行选择单元格 | Select cells in table row(s) |
要临时禁用大多数建议的TabNav键绑定,只需在当前视图中禁用TabNav即可。通过这样做,唯一(建议)不会被禁用的键绑定是启用视图TabNav的键绑定。
自定义键盘快捷键
当然,忽略建议的键绑定并使用自己的自定义键绑定,或者为建议绑定未涵盖的命令添加更多键绑定是完全有效的。
所有可用命令及其参数在CommandListing
文件中进行了列举。
对于每个导航键绑定,建议添加is_tabnav_context
键绑定上下文,以限制键绑定将生效的作用域,如上所述。
自定义
TabNav提供了相当多的配置选项,甚至可以自定义修改默认上下文的行为或添加新的上下文。
配置选项
选择首选项 ❯ 包设置 ❯ TabNav ❯ 设置 - TabNav菜单项可打开TabNav默认设置文件,以及您的本地TabNav设置文件。通过将参数放入本地设置文件中,覆盖默认配置。以下为可用全局配置参数
capture_level
:使用的初始 捕获级别。捕获级别也可以按上下文配置,或者使用 “设置捕获级别”命令 在活动视图中更改。选项:trimmed
、content
、markup
、cell
。默认:content
。trim_on_copy
:当为 true 时,在将选定的文本区域放入剪贴板之前,使用 “复制选择”命令 删除选定的区域文本的前后空白。视图中的选择本身不受影响。默认:true
。enable_explicitly
:当为 false 时,如果上下文与文件匹配成功,则假定 TabNav 已启用。当为 true 时,必须在每个视图中显式启用 TabNav。此设置也可以按上下文配置。默认:false
。log_level
:设置为INFO
或DEBUG
以在 Sublime Text 控制台中查看 TabNav 日志消息。默认WARNING
。
上下文配置
要修改默认上下文的行为或添加新上下文,请使用您本地的 TabNav 设置文件中的 user_contexts
4 元素。
要覆盖默认上下文的设置,只需在 user_contexts
元素中提供该设置的路径即可;您不需要复制完整的上下文定义。例如,要将 Markdown 上下文配置为仅支持带边框的表格,请在您的用户配置中添加此内容
{
"user_contexts":
{
"markdown":
{
"patterns": [
{
"line": "^(?P<table>(\\|\\s*[:-]+\\s*(?=\\|))+\\|)$",
"cell": "(?P<cell>\\|(?P<markup>\\s*[:-]+\\s*))(?=\\|)"
},
{
"line": "^(?P<table>\\|.*\\|)$",
"cell": "(?P<cell>\\|(?P<content>\\s*(?P<trimmed>.*?)\\s*))(?=\\|)"
}
]
}
}
}
有关标准上下文参数的描述,请参阅下面的 自定义上下文 部分。
4 默认设置文件有一个 contexts
元素。TabNav 会合并来自 user_contexts
和 contexts
设置的设置。如果您想完全覆盖默认上下文,您可以在本地设置文件中使用 contexts
元素,但这不推荐。
CSV 上下文配置
具有几个自定义参数的 auto_csv
上下文是特殊情况,除了标准上下文参数之外。
auto_delimiters
:TabNav 将尝试从文件的第一行推断 CSV 分隔符时检查的分隔符列表。default_delimiter
:如果所有其他确定分隔符的方法都失败,则用于 CSV 上下文的最后手段分隔符。
自定义上下文
还可以在 user_contexts
元素中定义附加上下文。有关示例,请参阅 tabnav.sublime-settings
文件(首选项 ❯ 包设置 ❯ TabNav ❯ 设置 - TabNav),以查看带有详细注释的默认上下文。
以下参数用于定义 TabNav 上下文
selector
:必需。一个 Sublime Text 选择器,用于标识上下文操作的范围。如果当前活动多个选择,则仅检查第一个选择的范围。如果多个 TabNav 上下文的选择器与当前范围匹配,则使用具有最高选择器“得分”(由 Sublime Text API 返回)的上下文。except_selector
:可选。一个 Sublime Text 选择器,用于覆盖基本selector
。如果第一个选择与此选择器匹配,则上下文不匹配。patterns
:必需。一个或多个用于识别和解析表格内容行的 模式定义。如果只提供了一个模式,则它不需要放在 JSON 数组中。如果提供了多个模式,则按顺序应用,直到找到第一个匹配项。通常,标记行模式应放在内容行模式的上方。enable_explicitly
:可选。一个布尔值,指示是否必须显式启用 TabNav 才能匹配此上下文。覆盖全局enable_explicitly
设置。默认false
。capture_level
:可选。与该上下文一起使用的默认 捕获级别。覆盖全局capture_level
设置。可能的值:trimmed
、content
、markup
、cell
。
模式定义
patterns
上下文参数 的每个元素都定义了如何
- 识别文本行是否属于表格,并
- 解析该文本行中表格单元格的内容。
每个模式包含两个元素,以下将更详细地解释。
line
捕获组
可选的 line
表达式用于确定模式是否适用于文本行,如果是,则构成表格的文本行部分。如果使用,则 line
表达式必须返回一个命名的 table
分组,用于使用 cell
表达式匹配表格内容。如果没有提供与模式一起的 line
表达式,则使用 cell
表达式解析整行文本。
有一种情况下,line
元素是必需的,而 cell
元素可以省略:要捕获表格的行,但不解析该行中的任何单元格,包含一个没有 table
捕获组的 line
元素。
cell
捕获组
cell
表达式中的每个元素可以包含最多四个 嵌套 的命名捕获组
(cell (markup (content (trimmed))))
这对应于四个 TabNav 捕获级别。如果使用内部组,则必须定义所有外部组,无论外部组是否捕获比内部组更多的额外内容。例如,大多数表格格式不包含内容单元格内的标记,但是必须包含 markup
组以能够捕获 content
组。
为了定义仅包含标记不应在 content
或 trimmed
级别中包含的选择的单元格,省略 content
和 trimmed
捕获组。
cell
捕获组应该捕获单元格内容之前的 前置 分隔符(如果适用)。在“无边框”环境中,例如 CSV 和无边框 Markdown 表格,行中第一个单元格不捕获分隔符。
数组中每个表达式的每次匹配都应该返回单个单元格的内容。每个表达式还可以(可选地)返回一个在最后一个匹配分隔符之前的零宽匹配。此匹配将被忽略。
如果在一个 JSON 数组中提供了多个表达式,则它们将逐个顺序处理,直到它们的匹配用尽。可以使用此功能,例如,一个表达式用于捕获行的第一个单元格,另一个表达式用于捕获行的中间单元格,第三个表达式用于捕获最后一个单元格。如果只提供了一个表达式,则不必将其放置在 JSON 数组中。
例如
一种在表格单元格中混合标记和内容的表格格式是Textile。以下是 Textile 表格定义标题的示例行。单元格由竖线分隔,单元格开头的 _.
是标记,表示该单元格是标题单元格。
|_. First Header |_. Second Header |
以下是该行四个 TabNav 捕获组应捕获的视觉表示
|_. First Header |_. Second Header |
↑↑ ↑↑ ↑ ↑↑↑ ↑↑ ↑↑
|| |└ trimmed ─┘ ||| |└ trimmed ──┘|
|| └─ content ───┤|| └─ content ───┤
|└─── markup ────┤|└─── markup ────┤
└──── cell ──────┘└──── cell ──────┘
或者,以表格形式呈现(多么元啊)
捕获组 | 第一个单元格选择 | 第二个单元格选择 |
---|---|---|
cell |
|_. 第一个标题 |
|_. 第二个标题 |
markup |
_. 第一个标题 |
_. 第二个标题 |
content |
第一个标题 |
第二个标题 |
trimmed |
First Header |
Second Header |
请注意,最后的 |
没有作为任何单元格的一部分被捕获 - 每个单元格只捕获前置分隔符。