级别: 中级 马 若劼 (maruojie@cn.ibm.com), 软件工程师, IBM 中国软件开发中心
2008 年 5 月 15 日 Text Formatting(文本格式化)是 JTF 提供的自动排版技术,可以快速的将源代码按照预定的规则排版,极大的方便了浏览一些格式混乱的源代码。本文介绍文本格式化的相关概念并实现简单的文本格式化功能。
Text Formatting
Text Formatting(文本格式化)可以快速的将源代码按照预定的规则排版,JTF 只是定义了这个框架,将其发挥到极致的是 JDT。打开 Eclipse 的设置页,找到 General->Java->Code Style->Formatter,你会发现在这里可以编辑名目繁多的格式化选项。JDT 提供的代码格式化功能强大的令人眩目,但本文的目的是介绍这个强大功能下的基础设施。
IFormattingStrategy
IFormattingStrategy(格式化策略)是格式化真正完成的地方,它代表一种格式化的方式。格式化策略是和文本类型相关联的,所以可以为每一种文本类型创建一个格式化策略,这是 JTF 的一个基本做法,你还能回忆起还有哪些功能是和文本类型绑定在一起的吗?这个接口有一个扩展接口 IFormattingStrategyExtension,它引入了 Formatting Context(格式化上下文)的概念,下面会有介绍。
IContentFormatter
IContentFormatter 是最基本的接口,它代表了一个格式化器。既然实际的格式化工作应该放到 IFormattingStrategy 中,那 IContentFormatter 做什么呢?可以说,它基本上相当于一个调度器,它会决定要格式化的内容具有什么样的文本类型,然后调用不同的 IFormattingStrategy 实现。不过,这只是推荐行为,你可以在 IContentFormatter 的实现里做任何事,但是不推荐刻意超越这个架构的约束。JTF有这个接口的缺省实现:ContentFormatter,一般我们直接使用它就可以了。
IFormattingContext
IFormattingContext 为格式化提供附加信息,它采用键值对的方式保存信息,所以你可以存任何格式化需要知道的东西。不过这是一个相对较新的接口,从 Eclipse 3.0 开始才出现,你实现了 IFormattingStrategyExtension 才需要用到它。记住,不要忘了查查是否每个接口都有扩展接口,也许你会有很多新的发现,因为 JTF 中到处都是,或者说 Eclipse 中到处都是扩展接口。
实现文本格式化
实现 IFormattingStrategy
首先我使用 ExprFormattingStrategy 实现 IFormattingStrategy 接口,我没有实现 IFormattingStrategyExtension,因为例子中的语言太简单了,我不需要多少上下文信息就可以做格式化工作。另外一个原因是:文本格式化的算法因不同的情况而已,且和和 JTF 的架构关系不大,没有必要进行详细的演示。我的格式化方式很简单:每个符号之间会有空格分隔(除了分号),且每行只允许写一条语句。
配置
修改 ExprConfiguration,覆盖 getContentFormatter 方法。我使用缺省实现,并用 setFormattingStrategy 方法注册 ExprFormattingStrategy。出于简单至上的原则,我没有实现 IContentFormatter,如果你的软件需求必须要实现 IContentFormatter,请不要犹豫。
快捷键处理
和内容提示,快速帮助一样,需要一个快捷键来触发文本格式化。普通的文本编辑器并没有格式化的功能,如果我需要使用格式化的命令ID,需要依赖 org.eclipse.jdt.ui 插件,我不太想这样做。当然对我这个例子来说,这无所谓,但如果是正在开发一个真正的产品,我想你也不希望为了使用一个常量就把整个 JDT 都包含进来,所以我通过扩展定义了一个格式化命令,并绑定到 Ctrl+Shift+F。然后,仿照快速帮助时的做法,在 ExprViewer 的 createHandlers 方法中添加一个 handler。
效果
尝试输入一些混乱的代码,全选后然后按下 Ctrl+Shift+F,你会得到如下的对比:
图1. 格式化之前
图2. 格式化之后
结束语
本文介绍的是JTF中文本格式化的基本概念和实现方式,下面是对这一章内容的进一步思考:
- ExprFormattingStrategy 太简单了,format 方法的后面三个参数都没怎么用到。看看它们到底是什么意思,想想如何使用它们
- 我没有实现 IFormattingStrategyExtension,这样得不到很多信息。IFormattingStrategy 的 format 方法参数虽然不少,但是携带的信息还是太有限了。因此在实际的应用中,推荐实现 IFormattingStrategyExtension 以便能使用 IFormattingContext。
- 格式化会牵涉到很多的文本操作,不妨尝试使用 Eclipse 自带的一些工具。在 org.eclipse.text 插件中,封装了不少类型的文本操作,看看 TextEdit 和它的子类,相信你会有收获。不光是格式化,任何需要操作文档的功能都可以使用。
- 格式化的重头戏是格式化算法,但是它不在本系列的范畴之内。不过我要再提醒你,要把格式化做到 JDT 那样的水准,重要的是需要一个强大的解析器支持。
这些不足的地方留给有兴趣的读者。
声明
本文仅代表作者的个人观点,不代表IBM的立场。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| 第十小节示例代码 | jtf.tutorial.part10.zip | 1140KB | HTTP |
|---|
参考资料
关于作者  | |  | 马若劼是 Lotus Forms 部门的一位软件工程师,主要从事电子表单技术的研发工作。他在 Eclipse 和 Java 方面有多年研发经验,同时也是国内著名开源项目 LumaQQ 的创立者 |
对本文的评价
|