7.3 表示结构化文档

728 篇文章 1 订阅
349 篇文章 0 订阅

7.3 表示结构化文档

 

在这一节我们所设计的数据结构,灵感来自 HTML 格式,这是我们熟悉的,成功创建文档的语言。就像 HTML 一样,我们表示的内容有几种类型,并且有些部分可能以适当的方法嵌套。图 7.3 显示了带注释的示例文档,它能给你格式包括哪些内容的概念。

有两种不同的部分。简单的部分,如 TextPart 和 ImagePart,包含内容,但不包含嵌套的部分;在另一侧,TitledPart 包含了嵌套部分,还有标题,而 SplitPart 包含一个或多个嵌套的部分和方向的规范。你可能已经猜到,我们将使用差别联合来表示不同的部分;有两个部分可以包含嵌套的部分,因此,类型将是递归的。清单 7.9 显示了类型声明,给我们更具体的内容,需要详细讨论。


图 7.3 文档格式有四种不同部分:TitledPart 标题加其他部分;使用 SplitPart,可以创建列和行;TextPart 和 ImagePart 指定实际内容。

 

清单 7.9 分层次的文档表示 (F#)

type Orientation =   [1]

  |Vertical 

  |Horizontal 

 

type DocumentPart =   [2]

  |SplitPart of Orientation * list<DocumentPart>  <-- 行或列中包含其他部分

  |TitledPart of TextContent * DocumentPart  <-- 表示有标题的部分

  |TextPart of TextContent   | 保存基本内容

  |ImagePart of string      |

 

把前面一段中非正式的规范翻译成 F# 代码非常简单,这绝对是一个最标准的 F# 类型声明。我们首先声明一个简单的差别联合,有两个选项,表示拆分部分的方向[1],然后,再声明DocumentPart 类型[2],有四个可选的选项。

两个选项递归地包含了其他文档部分。SplitPart 包含了列表中的几个其他部分,和确定区域应如何划分的方向信息;TitledPart 包含了一个其他部分,和装饰用的标题。保存文本,使用上一节的 TextContent 类型,它是记录类型,包含了字符串和使用的字体。

DocumentPart 类型表示整个文档。因为,类型是递归的,我们可以在一个文档部分中,嵌套任意数量的内容部分。这不同于以前的做法,那时,我们为元素创建类型,然后,用元素列表表示文档;在那种表示形式中,列表成为数据结构的“根”,元素没有进一步地嵌套;使用新的数据类型,我们可以像这样来写 7.2 节的文档:

 

let doc = 

  TitledPart({Text = "Functional Programming for the Real World"; 

           Font = fntHead }, 

  SplitPart(Vertical, 

    [ImagePart("cover.jpg"); 

     TextPart({Text = "..."; Font = fntText }) ] 

  ) 

)

 

我们省略了位于图像下面的TextPart 的内容,但仍可以看到,表示方法很简洁,因为不需要自己计算矩形的边框。然而,我们没有实现绘制数据类型。我们不打算写,或者说,什么时候,我们已经为早先的表示方法,有了很好的绘制函数,为什么还要写呢?我们所要做的就是提供转换,从“构造设计”的形式到“绘制设计”。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值