Skip to content

Commit

Permalink
Scaladoc: better support for inner classes (#397)
Browse files Browse the repository at this point in the history
* Scaladoc: better support for inner classes

* Review fix
  • Loading branch information
ennru authored and raboof committed Dec 3, 2019
1 parent 6288ac0 commit 1ba42c4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
21 changes: 17 additions & 4 deletions core/src/main/scala/com/lightbend/paradox/markdown/Directive.scala
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ abstract class ApiDocDirective(name: String)
if (path.endsWith("$")) path.substring(0, path.length - 1)
else if (path.endsWith(".package")) path.substring(0, path.length - ".package".length)
else if (path.endsWith(".index")) path.substring(0, path.length - ".index".length)
else path
// for inner-class notation with $$
else path.replaceAll("\\$\\$", ".")
} catch {
case e @ Url.Error(reason) =>
ctx.logger.debug(e)
Expand All @@ -308,16 +309,27 @@ abstract class ApiDocDirective(name: String)

}

object ApiDocDirective {
/** This relies on the naming convention of packages being all-lowercase (which is rarely broken). */
def packageDotsToSlash(s: String) = s.replaceAll("(\\b[a-z]+)\\.", "$1/")
}

case class ScaladocDirective(ctx: Writer.Context)
extends ApiDocDirective("scaladoc") {

protected def resolveApiLink(link: String): Url = {
val levels = link.split("[.]")
val packages = (1 to levels.init.size).map(levels.take(_).mkString("."))
val baseUrl = packages.reverse.collectFirst(baseUrls).getOrElse(defaultBaseUrl).resolve()
url(link, baseUrl)
}

private def classDotsToDollarDollar(s: String) = s.replaceAll("(\\b[A-Z].+)\\.", "$1\\$\\$")

private def url(link: String, baseUrl: Url): Url = {
val url = Url(link).base
val path = url.getPath.replace('.', '/') + ".html"
(baseUrl / path) withFragment (url.getFragment)
val path = classDotsToDollarDollar(ApiDocDirective.packageDotsToSlash(url.getPath)) + ".html"
(baseUrl / path).withFragment(url.getFragment)
}

}
Expand All @@ -337,7 +349,7 @@ object JavadocDirective {

private[markdown] def url(link: String, baseUrl: Url, linkStyle: LinkStyle): Url = {
val url = Url(link).base
val path = url.getPath.replaceAll("(\\b[a-z]+)\\.", "$1/") + ".html"
val path = ApiDocDirective.packageDotsToSlash(url.getPath) + ".html"
linkStyle match {
case LinkStyleFrames => baseUrl.withEndingSlash.withQuery(path).withFragment(url.getFragment)
case LinkStyleDirect => (baseUrl / path).withFragment(url.getFragment)
Expand Down Expand Up @@ -702,6 +714,7 @@ case class DependencyDirective(ctx: Writer.Context) extends LeafBlockDirective("

val startDelimiter = node.attributes.value("start-delimiter", "$")
val stopDelimiter = node.attributes.value("stop-delimiter", "$")

def coordinate(name: String): Option[String] =
Option(node.attributes.value(name)).map { value =>
variables.foldLeft(value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ScaladocDirectiveSpec extends MarkdownBaseSpec {
"scaladoc.scala.base_url" -> "http://www.scala-lang.org/api/2.11.12/",
"scaladoc.akka.base_url" -> "http://doc.akka.io/api/akka/2.4.10",
"scaladoc.akka.http.base_url" -> "http://doc.akka.io/api/akka-http/10.0.0",
"scaladoc.akka.kafka.base_url" -> "https://doc.akka.io/api/alpakka-kafka/current",
"scaladoc.root.relative.base_url" -> ".../scaladoc/api/",
"scaladoc.broken.base_url" -> "https://c|"
)
Expand Down Expand Up @@ -62,6 +63,16 @@ class ScaladocDirectiveSpec extends MarkdownBaseSpec {
html("""<p><a href="http://doc.akka.io/api/akka/2.4.10/akka/actor/Actor.html" title="akka.actor.Actor"><code>Actor</code></a></p>""")
}

it should "handle inner classes correctly" in {
markdown("@scaladoc[Consumer.Control](akka.kafka.scaladsl.Consumer.Control)") shouldEqual
html("""<p><a href="https://doc.akka.io/api/alpakka-kafka/current/akka/kafka/scaladsl/Consumer$$Control.html" title="akka.kafka.scaladsl.Consumer.Control"><code>Consumer.Control</code></a></p>""")
}

it should "handle inner classes in $$ notation" in {
markdown("@scaladoc[Consumer.Control](akka.kafka.scaladsl.Consumer$$Control)") shouldEqual
html("""<p><a href="https://doc.akka.io/api/alpakka-kafka/current/akka/kafka/scaladsl/Consumer$$Control.html" title="akka.kafka.scaladsl.Consumer.Control"><code>Consumer.Control</code></a></p>""")
}

it should "retain whitespace before or after" in {
markdown("The @scaladoc:[Model](org.example.Model) class") shouldEqual
html("""<p>The <a href="http://example.org/api/0.1.2/org/example/Model.html" title="org.example.Model"><code>Model</code></a> class</p>""")
Expand Down

0 comments on commit 1ba42c4

Please sign in to comment.