summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2010-02-24 15:51:10 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2010-02-24 15:51:10 +0000
commitf84684ee02a8990726fcb62a454b3788d5fe5f16 (patch)
treec1e6e31302f06932ff2596e0395406d14fbdcc32
parentf270f7ecfb30c331aa650d7b75fdbabc78be006b (diff)
downloadscala-f84684ee02a8990726fcb62a454b3788d5fe5f16.tar.gz
scala-f84684ee02a8990726fcb62a454b3788d5fe5f16.tar.bz2
scala-f84684ee02a8990726fcb62a454b3788d5fe5f16.zip
[scaladoc] Preliminary support for links and li...
[scaladoc] Preliminary support for links and lists in wiki syntax, as well as printing of lists. Fix to display of "inherits" classes. Contributed by Pedro Furlanetto, no review. Member names in signature are more contrasted and are aligned.
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala18
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css29
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala15
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/Body.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala98
5 files changed, 142 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index ee2f491e9e..520bcb9a36 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -132,15 +132,27 @@ abstract class HtmlPage { thisPage =>
case Paragraph(in) => <p>{ inlineToHtml(in) }</p>
case Code(data) => <pre>{ Unparsed(data) }</pre>
case UnorderedList(items) =>
- <ul>{items map { i => <li>{ blockToHtml(i) }</li>}}</ul>
+ <ul>{ listItemsToHtml(items) }</ul>
case OrderedList(items) =>
- <ol>{items map { i => <li>{ blockToHtml(i) }</li>}}</ol>
+ <ol>{ listItemsToHtml(items) }</ol>
case DefinitionList(items) =>
<dl>{items map { case (t, d) => <dt>{ inlineToHtml(t) }</dt><dd>{ blockToHtml(d) }</dd> } }</dl>
case HorizontalRule() =>
<hr/>
}
+ def listItemsToHtml(items: Seq[Block]) =
+ items.foldLeft(xml.NodeSeq.Empty){ (xmlList, item) =>
+ item match {
+ case OrderedList(_) | UnorderedList(_) => // html requires sub ULs to be put into the last LI
+ xmlList.init ++ <li>{ xmlList.last.child ++ blockToHtml(item) }</li>
+ case Paragraph(inline) =>
+ xmlList :+ <li>{ inlineToHtml(inline) }</li> // LIs are blocks, no need to use Ps
+ case block =>
+ xmlList :+ <li>{ blockToHtml(block) }</li>
+ }
+ }
+
def inlineToHtml(inl: Inline): NodeSeq = inl match {
//case URLLink(url, text) => <a href={url}>{if(text.isEmpty)url else inlineSeqsToXml(text)}</a>
case Chain(items) => items flatMap (inlineToHtml(_))
@@ -149,7 +161,7 @@ abstract class HtmlPage { thisPage =>
case Underline(in) => <u>{ inlineToHtml(in) }</u>
case Superscript(in) => <sup>{ inlineToHtml(in) }</sup>
case Subscript(in) => <sub>{ inlineToHtml(in) }</sub>
- case Link(raw) => Unparsed(raw)//error("link not supported") // TODO
+ case Link(raw,title) => <a href={ raw }>{ title.getOrElse(raw) }</a> // TODO link to target
case Monospace(text) => <code>{ Unparsed(text) }</code>
case Text(text) => Unparsed(text)
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
index 5114ebe957..64c3e0ad8a 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -122,8 +122,8 @@ div.members > ol > li {
.signature .kind {
text-align: right;
float: left;
- display: inline;
- padding-left: 72px;
+ display: inline-block;
+ width: 72px;
}
.signature .symbol {
@@ -149,11 +149,11 @@ div.members > ol > li {
}
#values .signature .name {
- color: #142556;
+ color: blue;
}
#types .signature .name {
- color: #561414;
+ color: red;
}
/* Comments text formating */
@@ -176,6 +176,20 @@ div.members > ol > li {
margin: 2px 0 2px 0;
}
+.cmt ul, .cmt ol {
+ display: block;
+ list-style: circle;
+ padding-left:20px;
+}
+
+.cmt li {
+ display:list-item;
+}
+
+.cmt a {
+ text-decoration: underline;
+}
+
/* Comments structured layout */
p.comment {
@@ -263,6 +277,11 @@ div.fullcomment dl.paramcmts > dd + dt + dd {
}
#mbrsel > div > ol {
+ display: inline-block;
+ background-color: white;
+}
+
+#mbrsel > div > ol#linearization {
display: inline;
}
@@ -270,7 +289,7 @@ div.fullcomment dl.paramcmts > dd + dt + dd {
padding: 4px 8px 4px 8px;
font-weight: bold;
background-color: white;
- display: inline;
+ display: inline-block;
cursor: crosshair;
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index 7be902cd5f..2362016152 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -72,6 +72,21 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
def abstractTypes: List[AbstractType]
def aliasTypes: List[AliasType]
def companion: Option[DocTemplateEntity]
+ // temporary implementation: to be removed
+ def findMember(str: String): Option[DocTemplateEntity] = {
+ val root = toRoot.last
+ val path = if (str.length > 0) str.split("\\.") else Array[String]()
+ var i = 0;
+ var found: DocTemplateEntity = root
+ while(i < path.length && found != null) {
+ found = found.members.find(_.name == path(i)) match {
+ case Some(doc:DocTemplateEntity) => doc
+ case _ => null
+ }
+ i += 1
+ }
+ Option(found)
+ }
}
/** A ''documentable'' trait. */
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
index 28359104e0..c87ecb7d4d 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
@@ -32,6 +32,6 @@ final case class Bold(text: Inline) extends Inline
final case class Underline(text: Inline) extends Inline
final case class Superscript(text: Inline) extends Inline
final case class Subscript(text: Inline) extends Inline
-final case class Link(raw: String) extends Inline // TODO
+final case class Link(target: String, title: Option[String]) extends Inline
final case class Monospace(text: String) extends Inline
final case class Text(text: String) extends Inline
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index 05064d362a..a04e98ddc5 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -21,8 +21,8 @@ import scala.annotation.switch
* @author Gilles Dubochet */
final class CommentFactory(val reporter: Reporter) { parser =>
- final val endOfText = '\u0003'
- final val endOfLine = '\u000A'
+ val endOfText = '\u0003'
+ val endOfLine = '\u000A'
/** Something that should not have happened, happened, and Scaladoc should exit. */
protected def oops(msg: String): Nothing =
@@ -248,12 +248,46 @@ final class CommentFactory(val reporter: Reporter) { parser =>
title()
else if (check("----"))
hrule()
- // TODO: Lists
+ else if (check(" - "))
+ listBlock(countWhitespace, '-', UnorderedList)
+ else if (check(" 1 "))
+ listBlock(countWhitespace, '1', OrderedList)
else {
para()
}
}
+ /**
+ * {{{
+ * nListBlock ::= nLine { mListBlock }
+ * nLine ::= nSpc '*' para '\n'
+ * }}}
+ * Where n and m stand for the number of spaces. When m > n, a new list is nested. */
+ def listBlock(indentation: Int, marker: Char, constructor: (Seq[Block] => Block)): Block = {
+ var count = indentation
+ val start = " " * count + marker + " "
+ var chk = check(start)
+ var line = listLine(indentation, marker)
+ val blocks = mutable.ListBuffer.empty[Block]
+ while (chk) {
+ blocks += line
+ count = countWhitespace
+ if (count > indentation) { // nesting-in
+ blocks += listBlock(count, marker, constructor) // TODO is tailrec really needed here?
+ }
+ chk = check(start)
+ if (chk) { line = listLine(indentation, marker) }
+ }
+ constructor(blocks)
+ }
+
+ def listLine(indentation: Int, marker: Char): Block = {
+ jump(" " * indentation + marker + " ")
+ val p = Paragraph(inline(check(Array(endOfLine))))
+ blockEnded("end of list line ")
+ p
+ }
+
/** {{{ code ::= "{{{" { char } '}' "}}" '\n' }}} */
def code(): Block = {
jump("{{{")
@@ -288,8 +322,9 @@ final class CommentFactory(val reporter: Reporter) { parser =>
def para(): Block = {
def checkParaEnd(): Boolean = {
check(Array(endOfLine, endOfLine)) ||
- check(Array(endOfLine, '='))
- check(Array(endOfLine, '{', '{', '{'))
+ check(Array(endOfLine, '=')) ||
+ check(Array(endOfLine, '{', '{', '{')) ||
+ check(Array(endOfLine, ' ', '-', ' '))
}
val p = Paragraph(inline(checkParaEnd()))
while (char == endOfLine && char != endOfText)
@@ -390,7 +425,16 @@ final class CommentFactory(val reporter: Reporter) { parser =>
jump("[[")
readUntil { check("]]") }
jump("]]")
- Link(getRead())
+ val read = getRead()
+ val (target, title) = {
+ val index = read.indexOf(' ');
+ val split = read.splitAt( if (index > -1) index else 0 )
+ if (split._1 == "")
+ (split._2, None)
+ else
+ (split._1, Some(split._2.trim))
+ }
+ Link(target, title)
}
/* UTILITY */
@@ -446,6 +490,30 @@ final class CommentFactory(val reporter: Reporter) { parser =>
ok
}
+ def checkSkipWhitespace(chars: Array[Char]): Boolean = {
+ assert(chars.head!=' ') // or it makes no sense
+ val poff = offset
+ val pc = char
+ jumpWhitespace
+ val ok = jump(chars)
+ offset = poff
+ char = pc
+ ok
+ }
+
+ def countWhitespace:Int = {
+ var count = 0
+ val poff = offset
+ val pc = char
+ while (isWhitespace(char) && char!=endOfText) {
+ nextChar()
+ count += 1
+ }
+ offset = poff
+ char = pc
+ count
+ }
+
/* JUMPERS */
final def jump(chars: Array[Char]): Boolean = {
@@ -474,7 +542,8 @@ final class CommentFactory(val reporter: Reporter) { parser =>
while (more && count < max) {
if (!checkedJump(chars))
more = false
- count += 1
+ else
+ count += 1
}
count
}
@@ -485,15 +554,18 @@ final class CommentFactory(val reporter: Reporter) { parser =>
while (more) {
if (!checkedJump(chars))
more = false
- count += 1
+ else
+ count += 1
}
count
}
final def jumpUntil(ch: Char): Int = {
var count = 0
- while(char != ch && char != endOfText)
+ while(char != ch && char != endOfText) {
nextChar()
+ count=count+1
+ }
count
}
@@ -503,16 +575,20 @@ final class CommentFactory(val reporter: Reporter) { parser =>
val c = chars(0)
while(!check(chars) && char != endOfText) {
nextChar()
- while (char != c && char != endOfText)
+ while (char != c && char != endOfText) {
nextChar()
+ count += 1
+ }
}
count
}
final def jumpUntil(pred: => Boolean): Int = {
var count = 0
- while (!pred && char != endOfText)
+ while (!pred && char != endOfText) {
nextChar()
+ count += 1
+ }
count
}