2013-06-05 3 views
18

Ich versuche, Klassen aus dem JDK in das Scaladoc-generierte Dokument zu verknüpfen. Ich habe die -doc-external-doc Option von Scaladoc 2.10.1 aber ohne Erfolg verwendet.Wie Klassen von JDK in scaladoc-generated doc?

Ich benutze -doc-external-doc:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar#http://docs.oracle.com/javase/7/docs/api/, aber ich bekomme Links wie index.html#java.io.File statt index.html?java/io/File.html. Scheint, dass diese Option nur für scaladoc-generierte Dokumente funktioniert.

Habe ich eine Option in scaladoc oder sollte ich eine Feature-Anfrage füllen?

ich konfiguriert haben SBT wie folgt:

scalacOptions in (Compile,doc) += "-doc-external-doc:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar#http://docs.oracle.com/javase/7/docs/api" 

Hinweis: Ich habe die Opts.doc.externalAPI gesehen util in der kommenden sbt 0,13. Ich denke eine nette Ergänzung (nicht sicher, ob es möglich ist) wäre, eine ModuleID statt einer File zu übergeben. Das util würde herausfinden, welche Datei der ModuleID entspricht.

+1

Sie sollten zu scaladoc berichten. – jsuereth

+0

Gibt es eine Befehlszeile für diese externe sbt? Nach @ jsuereths Antwort übergibt sbt die Optionen einfach an scaladoc, und wenn es die Funktion nicht unterstützt, tut sbt das auch nicht. –

Antwort

7

Ich benutze sbt 0.13.5.

Es gibt keine out-of-the-Box-Art und Weise die Funktion des mit Javadoc Links innerhalb scaladoc zu haben. Und so wie ich es verstehe, ist es nicht schuld, sondern wie Scaladoc funktioniert. Als JoshYou should report to scaladoc. in seinem Kommentar darauf hingewiesen

Es gibt jedoch eine Abhilfe, die ich kam mit - nachbearbeiten dem doc -Generated scaladoc so dem Java-URLs richtigen Javadoc Link zu bilden ersetzt bekommen.

Die Datei scaladoc.sbt sollte in einem sbt Projekt und wann immer doc Aufgabe.

HINWEIS Es gibt viele Wege, so hartkodierte es, die Nachbearbeitung über fixJavaLinksTask Aufgabe Kicks wird ausgeführt platziert werden verwenden, um mit Vorsicht (aka machen Sie das Polieren, wie Sie es für richtig halten).

import scala.util.matching.Regex.Match 

autoAPIMappings := true 

// builds -doc-external-doc 
apiMappings += (
    file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") -> 
    url("http://docs.oracle.com/javase/8/docs/api") 
) 

lazy val fixJavaLinksTask = taskKey[Unit](
    "Fix Java links - replace #java.io.File with ?java/io/File.html" 
) 

fixJavaLinksTask := { 
    println("Fixing Java links") 
    val t = (target in (Compile, doc)).value 
    (t ** "*.html").get.filter(hasJavadocApiLink).foreach { f => 
    println("fixing " + f) 
    val newContent = javadocApiLink.replaceAllIn(IO.read(f), fixJavaLinks) 
    IO.write(f, newContent) 
    } 
} 

val fixJavaLinks: Match => String = m => 
    m.group(1) + "?" + m.group(2).replace(".", "/") + ".html" 

val javadocApiLink = """\"(http://docs\.oracle\.com/javase/8/docs/api/index\.html)#([^"]*)\"""".r 

def hasJavadocApiLink(f: File): Boolean = (javadocApiLink findFirstIn IO.read(f)).nonEmpty 

fixJavaLinksTask <<= fixJavaLinksTask triggeredBy (doc in Compile) 
6

Ich habe die Antwort von @ jacek-Laskowski und modifiziert, so dass es hartcodierte Zeichenfolgen zu vermeiden und für eine beliebige Anzahl von Java-Bibliotheken verwendet werden könnten, nicht nur der Standard.

Edit: die Lage von rt.jar wird nun von der Laufzeit bestimmt sun.boot.class.path verwenden und nicht hart codiert.

Das einzige, was Sie ändern müssen, ist die Karte, die ich externalJavadocMap im folgenden genannt haben:

import scala.util.matching.Regex 
import scala.util.matching.Regex.Match 

val externalJavadocMap = Map(
    "owlapi" -> "http://owlcs.github.io/owlapi/apidocs_4_0_2/index.html" 
) 

/* 
* The rt.jar file is located in the path stored in the sun.boot.class.path system property. 
* See the Oracle documentation at http://docs.oracle.com/javase/6/docs/technotes/tools/findingclasses.html. 
*/ 
val rtJar: String = System.getProperty("sun.boot.class.path").split(java.io.File.pathSeparator).collectFirst { 
    case str: String if str.endsWith(java.io.File.separator + "rt.jar") => str 
}.get // fail hard if not found 

val javaApiUrl: String = "http://docs.oracle.com/javase/8/docs/api/index.html" 

val allExternalJavadocLinks: Seq[String] = javaApiUrl +: externalJavadocMap.values.toSeq 

def javadocLinkRegex(javadocURL: String): Regex = ("""\"(\Q""" + javadocURL + """\E)#([^"]*)\"""").r 

def hasJavadocLink(f: File): Boolean = allExternalJavadocLinks exists { 
    javadocURL: String => 
    (javadocLinkRegex(javadocURL) findFirstIn IO.read(f)).nonEmpty 
} 

val fixJavaLinks: Match => String = m => 
    m.group(1) + "?" + m.group(2).replace(".", "/") + ".html" 

/* You can print the classpath with `show compile:fullClasspath` in the SBT REPL. 
* From that list you can find the name of the jar for the managed dependency. 
*/ 
lazy val documentationSettings = Seq(
    apiMappings ++= { 
    // Lookup the path to jar from the classpath 
    val classpath = (fullClasspath in Compile).value 
    def findJar(nameBeginsWith: String): File = { 
     classpath.find { attributed: Attributed[File] => (attributed.data ** s"$nameBeginsWith*.jar").get.nonEmpty }.get.data // fail hard if not found 
    } 
    // Define external documentation paths 
    (externalJavadocMap map { 
     case (name, javadocURL) => findJar(name) -> url(javadocURL) 
    }) + (file(rtJar) -> url(javaApiUrl)) 
    }, 
    // Override the task to fix the links to JavaDoc 
    doc in Compile <<= (doc in Compile) map { 
    target: File => 
     (target ** "*.html").get.filter(hasJavadocLink).foreach { f => 
     //println(s"Fixing $f.") 
     val newContent: String = allExternalJavadocLinks.foldLeft(IO.read(f)) { 
      case (oldContent: String, javadocURL: String) => 
      javadocLinkRegex(javadocURL).replaceAllIn(oldContent, fixJavaLinks) 
     } 
     IO.write(f, newContent) 
     } 
     target 
    } 
) 

ich verwende 0.13.8 SBT.

+0

Ich habe versucht, Ihren Code zu meiner SBT-Build-Datei hinzuzufügen, aber ScalaDoc scheint immer noch keine JDK-Klassen zu finden. Ich habe wahrscheinlich etwas Dummes gemacht - das sollte zu build.sbt hinzugefügt werden, oder? –

+1

Ja, es sollte zu 'build.sbt' hinzugefügt werden. Was ist der Wert von 'System.getProperty (" sun.boot.class.path ")'?Sie können dies überprüfen, indem Sie "console" von der SBT REPL eingeben, um in die Scala REPL zu gelangen. Laufen unter Windows oder Linux oder Mac? Erhalten Sie irgendwelche Warnungen, wenn Sie die 'doc' Aufgabe ausführen? –

+1

@Hawk Vielleicht am wichtigsten, hast du 'documentationSettings' zu den Projekteinstellungen hinzugefügt? Zum Beispiel etwas wie 'lazy val myProject = (Projekt in Datei (" myProject ")). Settings (documentationSettings: _ *)' in 'build.sbt'. –