36.8 分类

分类(Categories)为字符提供了另一种语法分类方式。你可以根据需要定义多个分类,然后独立地将每个字符分配到一个或多个分类中。与语法类不同,分类并非互斥;一个字符属于多个分类是常见情况。

每个缓冲区都拥有一个分类表(category table),用于记录已定义的分类以及每个字符所属的分类。每个分类表都会定义自身的分类,但通常会通过复制标准分类表完成初始化,确保所有模式中都能使用标准分类。

每个分类都有一个名称,该名称是范围为 ‘  至 ‘~’ 的ASCII可打印字符。使用define-category定义分类时,需要指定分类名称。

分类表本质上是一个字符表(see 字符表)。分类表中索引为c的元素是一个分类集(category set)(布尔向量),用于标识字符c所属的分类。在该分类集中,若索引cat对应的元素为t,则表示分类cat是该集合的成员,即字符c属于分类cat

对于接下来的三个函数,可选参数table默认使用当前缓冲区的分类表。

Function: define-category char docstring &optional table

该函数为分类表table定义一个新分类,名称为char,文档字符串为docstring

以下示例演示如何为具有强从右到左书写方向的字符定义新分类(see 双向显示),并在专用分类表中使用该分类。示例代码通过‘bidi-class’ Unicode 属性获取字符的书写方向信息(see bidi-class)。

(defvar special-category-table-for-bidi
  ;;     创建一个空的分类表。
  (let ((category-table (make-category-table))
        ;; 创建一个字符表,用于存储每个字符的 'bidi-class' Unicode
        ;; 属性。
        (uniprop-table
         (unicode-property-table-internal 'bidi-class)))
    (define-category ?R "属于 bidi-class R、AL 或 RLO 的字符"
                     category-table)
    ;; 修改所有 'bidi-class' Unicode 属性为 R、AL 或 RLO 的字符
    ;; 的分类条目——这类字符具有从右到左的书写方向。
    (map-char-table
     (lambda (key val)
       (if (memq val '(R AL RLO))
           (modify-category-entry key ?R category-table)))
     uniprop-table)
    category-table))
Function: category-docstring category &optional table

该函数返回分类表table中分类category的文档字符串。

(category-docstring ?a)
     ⇒ "ASCII"
(category-docstring ?l)
     ⇒ "Latin"
Function: get-unused-category &optional table

该函数返回一个当前未在table中定义的分类名称(字符类型)。若table中所有可用分类均已被占用,则返回nil

Function: category-table

该函数返回当前缓冲区的分类表。

Function: category-table-p object

object是分类表,该函数返回t,否则返回nil

Function: standard-category-table

该函数返回标准分类表。

Function: copy-category-table &optional table

该函数创建并返回table的副本。若未提供table(或为nil),则返回标准分类表的副本。若table不是分类表,则抛出错误。

Function: set-category-table table

该函数将table设置为当前缓冲区的分类表,并返回table

Function: make-category-table

该函数创建并返回一个空分类表。空分类表中未分配任何分类,也没有字符归属任何分类。

Function: make-category-set categories

该函数返回一个新的分类集(布尔向量),初始内容为字符串categories中列出的分类。categories的元素应为分类名称;新分类集中对应这些分类的元素为t,其余分类为nil

(make-category-set "al")
     ⇒ #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
Function: char-category-set char

该函数返回当前缓冲区的分类表中,字符 char 对应的分类集。这是一个布尔向量,用于记录字符 char 所属的全部分类。函数 char-category-set 不会分配新的存储空间,因为它直接返回分类表中已存在的布尔向量。

(char-category-set ?a)
     ⇒ #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
Function: category-set-mnemonics category-set

该函数将分类集 category-set 转换为字符串,字符串中的字符用于标识属于该集合的分类。

(category-set-mnemonics (char-category-set ?a))
     ⇒ "al"
Function: modify-category-entry char category &optional table reset

该函数修改分类表 table 中字符 char 的分类集(table 默认为当前缓冲区的分类表)。char 可以是单个字符,也可以是格式为 (min . max) 的 cons 单元;在后一种情况下,函数会修改 minmax 范围内(包含首尾)所有字符的分类集。

默认情况下,该函数会将分类 category 添加到分类集中。但如果 reset 为非 nil 值,则会从分类集中删除分类 category

Command: describe-categories &optional buffer-or-name

该函数描述当前分类表中的分类规范。它会将描述信息插入到一个缓冲区,然后显示该缓冲区。如果 buffer-or-name 为非 nil 值,则改为描述指定缓冲区的分类表。