1
/* NSC -- new Scala compiler
2
* Copyright 2007-2013 LAMP/EPFL
3
* @author Manohar Jonnalagedda
6
package scala.tools.nsc
11
import scala.collection._
15
/** A body of text. A comment has a single body, which is composed of
16
* at least one block. Inside every body is exactly one summary (see
17
* [[scala.tools.nsc.doc.model.comment.Summary]]). */
18
final case class Body(blocks: Seq[Block]) {
20
/** The summary text of the comment body. */
21
lazy val summary: Option[Inline] = {
22
def summaryInBlock(block: Block): Seq[Inline] = block match {
23
case Title(text, _) => summaryInInline(text)
24
case Paragraph(text) => summaryInInline(text)
25
case UnorderedList(items) => items flatMap summaryInBlock
26
case OrderedList(items, _) => items flatMap summaryInBlock
27
case DefinitionList(items) => items.values.toSeq flatMap summaryInBlock
30
def summaryInInline(text: Inline): Seq[Inline] = text match {
31
case Summary(text) => List(text)
32
case Chain(items) => items flatMap summaryInInline
33
case Italic(text) => summaryInInline(text)
34
case Bold(text) => summaryInInline(text)
35
case Underline(text) => summaryInInline(text)
36
case Superscript(text) => summaryInInline(text)
37
case Subscript(text) => summaryInInline(text)
38
case Link(_, title) => summaryInInline(title)
41
(blocks flatMap { summaryInBlock(_) }).toList match {
43
case inline :: Nil => Some(inline)
44
case inlines => Some(Chain(inlines))
49
/** A block-level element of text, such as a paragraph or code block. */
50
sealed abstract class Block
52
final case class Title(text: Inline, level: Int) extends Block
53
final case class Paragraph(text: Inline) extends Block
54
final case class Code(data: String) extends Block
55
final case class UnorderedList(items: Seq[Block]) extends Block
56
final case class OrderedList(items: Seq[Block], style: String) extends Block
57
final case class DefinitionList(items: SortedMap[Inline, Block]) extends Block
58
final case class HorizontalRule() extends Block
60
/** An section of text inside a block, possibly with formatting. */
61
sealed abstract class Inline
63
final case class Chain(items: Seq[Inline]) extends Inline
64
final case class Italic(text: Inline) extends Inline
65
final case class Bold(text: Inline) extends Inline
66
final case class Underline(text: Inline) extends Inline
67
final case class Superscript(text: Inline) extends Inline
68
final case class Subscript(text: Inline) extends Inline
69
final case class Link(target: String, title: Inline) extends Inline
70
final case class Monospace(text: Inline) extends Inline
71
final case class Text(text: String) extends Inline
72
abstract class EntityLink(val title: Inline) extends Inline { def link: LinkTo }
74
def apply(title: Inline, linkTo: LinkTo) = new EntityLink(title) { def link: LinkTo = linkTo }
75
def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link))
77
final case class HtmlTag(data: String) extends Inline {
78
private val Pattern = """(?ms)\A<(/?)(.*?)[\s>].*\z""".r
79
private val (isEnd, tagName) = data match {
80
case Pattern(s1, s2) =>
81
(! s1.isEmpty, Some(s2.toLowerCase))
86
def canClose(open: HtmlTag) = {
87
isEnd && tagName == open.tagName
90
private val TagsNotToClose = Set("br", "img")
91
def close = tagName collect { case name if !TagsNotToClose(name) => HtmlTag(s"</$name>") }
94
/** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */
95
final case class Summary(text: Inline) extends Inline