Skip to content

快捷语法 3.x

快捷语法 :xxx 提供了一种简洁的格式化方式,自动补全格式化指令前缀。

概述

快捷语法是一种"无头补全"机制:当你写 :单位 时,系统会自动补全为 _shortcut_prefix:单位

核心概念:$ 缺少头部 !u,自动补全为 !u:$

配置

_shortcut_prefix

  • 类型: string
  • 默认值: '!u'
  • 说明: 快捷语法的前缀,:xxx 会被展开为 _shortcut_prefix:xxx
  • 有效值: '!u', '!t', '!c', '!n', '!e', '!i', '!g', '!ua', '!ub', '!um', '!uh'

容错处理:配置时可以带或不带末尾的冒号,系统会自动标准化

javascript
// 以下两种配置完全等价
set_config({ _shortcut_prefix: '!u' });   // 推荐
set_config({ _shortcut_prefix: '!u:' });  // 也可以,会自动标准化为 '!u'

基础用法

默认行为(单位格式化)

javascript
import { calc, set_config } from 'a-calc'

// 配置单位转换
set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } },
  _unit_default_out: '$',
  _shortcut_prefix: '!u'  // 默认值
})

// :$ 等同于 !u:$
calc('10000 | =2 :$')   // '100.00$'
calc('10000 | =2 !u:$') // '100.00$' - 完全相同
Ctrl+D 选择词, Ctrl+/ 注释

没有默认单位时

javascript
// 没有配置 _unit_default_out 时,:$ 会去除单位
set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } }
  // 没有 _unit_default_out
})

calc('100$ | :$')  // '100' - 去除单位

!u 智能单位处理

!u 是一个智能单位处理指令,根据配置自动决定行为:

行为规则

  1. _unit_default_out 配置

    • 使用默认输出单位进行转换
    • 显示单位
    • 位置由 _unit_default_position 决定(默认 'after'
  2. _unit_default_out 配置

    • 去除单位
    • 不进行单位转换

示例

javascript
// 场景1:有默认单位配置
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元'
})

calc('10000 | !u')      // '100元' - 转换并显示
calc('10000 | =2 !u')   // '100.00元'
calc('10000 | !uh')     // '100' - 转换但不显示

// 场景2:无默认单位配置
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } }
  // 没有 _unit_default_out
})

calc('100元 | !u')      // '100' - 去除单位
calc('100元 | !uh')     // '100' - 去除单位

单位位置

javascript
set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } },
  _unit_default_out: '$',
  _unit_default_position: 'before'  // 单位在前
})

calc('10000 | =2 !u')   // '$100.00'

// 未配置时默认 'after'
set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } },
  _unit_default_out: '$'
  // _unit_default_position 未配置,默认 'after'
})

calc('10000 | =2 !u')   // '100.00$'

配置其他前缀

千分位快捷语法

javascript
set_config({
  _shortcut_prefix: '!t',
  _thousands: {
    'en': { sep: ',', point: '.', grouping: [3] },
    'eu': { sep: '.', point: ',', grouping: [3] }
  }
})

// :en 等同于 !t:en
calc('1234567.89 | =2 :en')  // '1,234,567.89'
calc('1234567.89 | =2 :eu')  // '1.234.567,89'

紧凑格式快捷语法

javascript
set_config({
  _shortcut_prefix: '!c',
  _compact: {
    'default': { symbols: ['', 'K', 'M', 'B', 'T'], step: 1000 },
    'cn': { symbols: ['', '千', '百万', '十亿'], step: 1000 }
  }
})

// :cn 等同于 !c:cn
calc('1234567 | =2 :cn')  // '123.46百万'

与其他语法对比

!u vs :单位

javascript
set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } },
  _unit_default_out: '$',
  _shortcut_prefix: '!u'
})

// 以下三种写法完全等价
calc('10000 | =2 :$')      // '100.00$'
calc('10000 | =2 !u:$')    // '100.00$'
calc('10000 | =2 !ua:$')   // '100.00$' - 显式指定位置

// !u 单独使用(智能处理)
calc('10000 | =2 !u')      // '100.00$' - 使用默认单位

!uh vs !u

javascript
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元'
})

calc('10000 | !u')   // '100元' - 转换并显示
calc('10000 | !uh')  // '100' - 转换但不显示

优先级

快捷语法的优先级与其展开后的指令相同:

javascript
// :$ 展开为 !u:$
// 优先级:显式语法 > position_map > _unit_default_position > 内置默认

set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } },
  _unit_default_out: '$',
  _unit_position_map: { '$': 'before' },
  _unit_default_position: 'after'
})

calc('10000 | =2 :$')      // '$100.00' - 使用 position_map
calc('10000 | =2 !ua:$')   // '100.00$' - 显式语法优先级最高

实现原理

快捷语法使用状态机实现:

  1. 遇到 : 字符时进入 state_shortcut 状态
  2. 收集 : 后面的内容直到空格或结束
  3. 获取 _shortcut_prefix 配置(默认 '!u'
  4. 构造完整指令:_shortcut_prefix:内容
  5. 递归调用 fmt_tokenizer 解析完整指令
  6. 将解析后的 tokens 添加到当前 tokens 列表

注意事项

  1. 前缀验证_shortcut_prefix 必须是有效的格式化指令前缀
  2. 递归解析:快捷语法会递归调用分词器,支持复杂的格式化指令
  3. 变量支持:如果递归解析的 tokens 包含变量,会正确标记
  4. 空格分隔: 后面的内容以空格或字符串结束为界

最佳实践

  1. 保持默认:大多数情况下使用默认的 !u 前缀即可
  2. 语义清晰:选择与使用场景匹配的前缀
  3. 配置一致:确保 _shortcut_prefix 与实际使用的格式化指令一致
  4. 智能单位:利用 !u 的智能处理特性,减少重复配置

配置项速查

配置项类型默认值说明
_shortcut_prefixstring'!u'快捷语法前缀
语法展开为说明
:xxx_shortcut_prefix:xxx自动补全前缀
!u-智能单位处理
!uh-转换但不显示单位

完整示例

电商价格显示

javascript
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元',
  _shortcut_prefix: '!u'
})

// 使用快捷语法
calc('9999 | =2 :元')     // '99.99元'
calc('9999 | =2,:元')     // '99.99元' (带千分位)

// 等同于完整语法
calc('9999 | =2 !u:元')   // '99.99元'
calc('9999 | =2,!u:元')   // '99.99元'

多货币系统

javascript
set_config({
  _unit_convert_out: {
    '元': { '分': 0.01 },
    '$': { '¢': 0.01 }
  },
  _unit_default_out: '元',
  _unit_position_map: {
    '$': 'before',
    '元': 'after'
  }
})

calc('10000 | =2 :元')    // '100.00元'
calc('10000 | =2 :$')     // '$100.00'

数据报表

javascript
set_config({
  _shortcut_prefix: '!c',
  _compact: {
    'default': { symbols: ['', 'K', 'M', 'B'], step: 1000 }
  }
})

calc('1234567 | =2 :default')  // '1.23M'

基于 MIT 许可发布