summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/doc/DocUtil.scala
blob: 34844c1367db6d97925d97e7a2d7d1ecd727678c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* NSC -- new Scala compiler
 * Copyright 2005-2007 LAMP/EPFL
 * @author  Sean McDirmid
 */
// $Id$

package scala.tools.nsc.doc

import java.io.StringReader
import org.xml.sax.InputSource

import scala.collection.immutable._
import scala.xml._

object DocUtil {

  //def dquote(str: String): NodeSeq =
  //  DQUOTE :: Text(str) :: DQUOTE :: Nil

  def load(str: String): NodeSeq = {
    val xmlSrc =
      if (str.matches("^(<!--.*-->)*<[^>]+>.*<[^>]+>(<!--.*-->)*$")) str
      else "<span>" + str + "</span>"
    XML.load(new StringReader(xmlSrc))
  }

  //object DQUOTE extends SpecialNode {
   // def toString(sb: StringBuffer) = {
   //   sb.append("\""); sb
   // }
   // def label = "#PCDATA"
  //}

  def br(nodes: NodeSeq): NodeSeq = nodes ++ <br/>
  def hr(nodes: NodeSeq): NodeSeq = nodes ++ <hr/>

  trait UrlContext {
    def relative: String

    def aref(href0: String, target: String, text: String): NodeSeq = {
      if (href0 == null) return Text(text);

      val href = {
        if (href0.startsWith("http:") || href0.startsWith("file:")) "";
        else relative
      } + Utility.escape(href0)
      if ((target ne null) && target.indexOf('<') != -1) throw new Error(target)

      val t0 = Text(text)
      if (target ne null)
        <a href={href} target={target}>{t0}</a>;
      else
        <a href={href}>{t0}</a>;
    }

    val encoding = Properties.encodingString
    val header =
      <meta http-equiv="content-type"
            content={"text/html; charset=" + encoding}/>
      <meta name="generator"
            content={"scaladoc (" + Properties.versionString +")"}/>
      <link rel="stylesheet" type="text/css" href={ relative + "style.css"}/>
      <script type="text/javascript" src={relative + "script.js"}></script>;

    def body0(hasBody: Boolean, nodes: NodeSeq): NodeSeq =
      if (!hasBody) nodes else <body onload="init()">{nodes}</body>;

    val dtype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"

    def page(title: String, body: NodeSeq, hasBody: Boolean): NodeSeq =
      <html>
        <head><title>{Text(title)}</title>
        {header}
        </head>
        {body0(hasBody, body)}
      </html>
  } // UrlContext

  def div0(title: String): NodeSeq =
    <div class="doctitle-larger">{Text(title)}</div>;

  def merge[T](ts0: TreeSet[T], ts1: TreeSet[T]): TreeSet[T] = {
    var ts = ts0
    for (val t <- ts1.toList) ts = ts + t
    ts
  }

  def merge[T,S <: Ordered[S]](ts0: ListMap[T,TreeSet[S]],
                               ts1: ListMap[T,TreeSet[S]]): ListMap[T,TreeSet[S]] = {
    var ts = ts0
    for (val t <- ts1.elements) {
      if (!ts.contains(t._1))
        ts = ts.update(t._1, new TreeSet[S]);
      ts = ts.update(t._1, merge(ts(t._1), t._2))
    }
    ts
  }
  implicit def coerceIterable[T](list : Iterable[T]) = NodeWrapper(list.elements);
  implicit def coerceIterator[T](list : Iterator[T]) = NodeWrapper(list);
  case class NodeWrapper[T](list : Iterator[T]) {
    def mkXML(begin : NodeSeq, separator : NodeSeq, end : NodeSeq)(f : T => NodeSeq) : NodeSeq = {
      var seq : NodeSeq = begin;
      val i = list;
      while (i.hasNext) {
        seq = seq ++ f(i.next);
        if (i.hasNext) seq = seq ++ separator;
      }
      seq ++ end;
    }


    def mkXML(begin : String, separator : String, end : String)(f : T => NodeSeq) : NodeSeq = {
      this.mkXML(Text(begin),Text(separator),Text(end))(f);
    }
    def surround(open : String, close : String)(f : T => NodeSeq) = {
      if (list.hasNext) mkXML(open, ", ", close)(f);
      else NodeSeq.Empty;
    }
  }
}