= Pkldoc
include::ROOT:partial$component-attributes.adoc[]
:uri-pkl-doc-maven: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-doc
:uri-DocsiteInfo: {uri-pkl-stdlib-docs}/DocsiteInfo/
:uri-DocPackageInfo: {uri-pkl-stdlib-docs}/DocPackageInfo/
:uri-CliDocGenerator: {uri-pkl-doc-main-sources}/CliDocGenerator.kt
:uri-DocGenerator: {uri-pkl-doc-main-sources}/DocGenerator.kt
:uri-pkldoc-macos-aarch64-download: {uri-sonatype-snapshot-download}&a=pkldoc-macos-aarch64&e=bin
:uri-pkldoc-linux-amd64-download: {uri-sonatype-snapshot-download}&a=pkldoc-linux-amd64&e=bin
:uri-pkldoc-linux-aarch64-download: {uri-sonatype-snapshot-download}&a=pkldoc-linux-aarch64&e=bin
:uri-pkldoc-alpine-download: {uri-sonatype-snapshot-download}&a=pkldoc-alpine-linux-amd64&e=bin
:uri-pkldoc-windows-download: {uri-sonatype-snapshot-download}&a=pkldoc-windows-amd64&e=exe
:uri-pkldoc-java-download: {uri-sonatype-snapshot-download}&a=pkldoc-java&e=jar

ifdef::is-release-version[]
:uri-pkldoc-macos-aarch64-download: {github-releases}/pkldoc-macos-aarch64
:uri-pkldoc-linux-amd64-download: {github-releases}/pkldoc-linux-amd64
:uri-pkldoc-linux-aarch64-download: {github-releases}/pkldoc-linux-aarch64
:uri-pkldoc-alpine-download: {github-releases}/pkldoc-alpine-linux-amd64
:uri-pkldoc-windows-download: {github-releases}/pkldoc-windows-amd64.exe
:uri-pkldoc-java-download: {github-releases}/jpkldoc
endif::[]

_Pkldoc_ is a documentation website generator that produces navigable and searchable API documentation for Pkl modules.

Pkldoc's look and feel is inspired by Scaladoc.
To get a first impression, browse the link:{uri-pkl-stdlib-docs-index}[Standard Library API Docs].

== Features

Pkldoc offers the following features:

Code navigation::
Easily navigate between hyperlinked modules, classes, functions, and properties.
Member search::
Search the entire documentation by member name.
See the next section for details.
Comment folding::
Expand and collapse multi-paragraph doc comments.
Markdown support::
Write doc comments in Markdown.
See xref:language-reference:index.adoc#doc-comments[Doc Comments] for details.
Member links::
Link to other members from your doc comments.
See xref:language-reference:index.adoc#member-links[Member Links] for details.
Member anchors::
Get a member's deep link by clicking its anchor symbol and copying the URL in the address bar.
Cross-site links::
Enable cross-site member links simply by providing the URLs of other Pkldoc websites such as the standard library docs.

[[member-search]]
=== Member Search

To get a first impression of Pkldoc's member search, let's try and find property `MinFiniteFloat` in the link:{uri-pkl-stdlib-docs-index}[standard library docs]:

image::pkldoc-search.gif[title="Searching the standard library docs."]

To start a search, press kbd:[s]. Search results are displayed as you type.

To limit the search to a particular kind of member, prefix the search term with _m:_ for modules, _c:_ for classes, _f:_ for functions, or _p:_ for properties.
For example, search term _p:min_ finds property `MinFiniteFloat` but not function `min()`.

Camel case matching is always enabled and does not require capitalizing the search term.
For example, search term _mff_ matches properties `MinFiniteFloat` and `MaxFiniteFloat`.

Both search terms and member names may contain non-ASCII Unicode characters.
As characters are normalized to their base form, search term _res_ matches `Réseau`.

The `@AlsoKnownAs` annotation, defined and used throughout the _pkl.base_ module, documents alternative names for a member used in other programming languages or earlier versions of a module.
Pkldoc's search takes these alternative names into account.
For example, searching the standard library docs for _count_ or _size_ finds property `String.length`.
Feel free to use `@AlsoKnownAs` in your own modules.

Search results are categorized into _exact_ and _other_ (partial) matches.
On module and class pages, additional categories show matches in the same module and class.
Within a category, results are ranked by similarity with the search term.

To navigate to a search result, either click the result or select it with the up/down arrow keys and press kbd:[Enter].

== Installation

Pkldoc is offered as Gradle plugin, Java library, and CLI.

=== Gradle Plugin

See xref:pkl-gradle:index.adoc#installation[Installation] in the _Gradle Plugin_ chapter.

[[install-library]]
=== Java Library

The `pkl-doc` library is available {uri-pkl-doc-maven}[from Maven Central].
It requires Java 17 or higher.

ifndef::is-release-version[]
NOTE: Snapshots are published to repository `{uri-snapshot-repo}`.
endif::[]

==== Gradle

To use the library in a Gradle project, declare the following dependency:

[tabs]
====
Kotlin::
+
.build.gradle.kts
[source,kotlin,subs="+attributes"]
----
dependencies {
  implementation("org.pkl-lang:pkl-doc:{pkl-artifact-version}")
}

repositories {
ifdef::is-release-version[]
  mavenCentral()
endif::[]
ifndef::is-release-version[]
  maven(url = "{uri-snapshot-repo}")
endif::[]
}
----

Groovy::
+
.build.gradle
[source,groovy,subs="+attributes"]
----
dependencies {
  implementation "org.pkl-lang:pkl-doc:{pkl-artifact-version}"
}

repositories {
ifdef::is-release-version[]
  mavenCentral()
endif::[]
ifndef::is-release-version[]
  maven { url "{uri-snapshot-repo}" }
endif::[]
}
----
====

==== Maven

To use the library in a Maven project, declare the following dependency:

.pom.xml
[source,xml,subs="+attributes"]
----
<project>
  <dependency>
    <groupId>org.pkl-lang</groupId>
    <artifactId>pkl-doc</artifactId>
    <version>{pkl-artifact-version}</version>
  </dependency>
ifndef::is-release-version[]
  <repositories>
    <repository>
      <id>sonatype-s01</id>
      <name>Sonatype S01</name>
      <url>{uri-snapshot-repo}</url>
    </repository>
  </repositories>
endif::[]
</project>
----

[[install-cli]]
=== CLI

The CLI comes in multiple flavors:

* Native macOS executable for aarch64 (tested on macOS 10.15)
* Native Linux executable for amd64
* Native Linux executable for aarch64
* Native Alpine Linux executable for amd64 (cross-compiled and tested on Oracle Linux 8)
* Native Windows executable for amd64 (tested on Windows Server 2022)
* Java executable (tested with Java 17/21 on macOS and Oracle Linux)

.What is the Difference Between the Linux and Alpine Linux Executables?
[NOTE]
====
The Linux executable is dynamically linked against _glibc_ and _libstdc{plus}{plus}_,
whereas, the Alpine Linux executable is statically linked against _musl libc_ and _libstdc{plus}{plus}_.
====

The Java executable works on multiple platforms and has a smaller binary size than the native executables.
However, it requires a Java 17 (or higher) runtime on the system path, and has a noticeable startup delay.

Download links:

* macOS aarch64: {uri-pkldoc-macos-aarch64-download}
* Linux aarch64: {uri-pkldoc-linux-aarch64-download}
* Linux amd64: {uri-pkldoc-linux-amd64-download}
* Alpine Linux amd64: {uri-pkldoc-alpine-download}
* Windows amd64: {uri-pkldoc-windows-download}

[[usage]]
== Usage

The Pkldoc tool is offered as Gradle plugin, Java library, and CLI.
It can generate documentation either for modules directly, or generate documentation for _package uris_.

The tool accepts an optional argument of a module named _docsite-info.pkl_, that amends link:{uri-DocsiteInfo}[pkl.DocsiteInfo].

[discrete]
==== Generating documentation for modules directly

Modules can be passed directly to Pkldoc for documentation generation.
When generating documentation for these modules, there must also be a module named _doc-package-info.pkl_ that amends link:{uri-DocPackageInfo}[pkl.DocPackageInfo].

The _doc-package-info.pkl_ module defines a _doc package_, which describes how modules are grouped and versioned together. 

When generating documentation for modules, each such module must declare a module name that starts with a package name declared in a _doc-package-info.pkl_ module.
For example, the following are valid module declarations for package _com.example_:

* `module com.example.Birds`
* `module com.example.Birds.Parrot`

The part of the module name that comes after the package name
must match the module's relative path in its source code repository.
For example, module _com.example.Bird.Parrot_ is expected to be found at _$sourceCode/Bird/Parrot.pkl_,
where _sourceCode_ is configured in _doc-package-info.pkl_.

[discrete]
==== Generating documentation for a _package_

Pkldoc can alternatively generate documentation for a _package_.
When generating documentation for a package, the URI of the package must be passed as an argument to Pkldoc.
These packages must already be published and downloadable.

When generating documentation for packages, modules within a package must declare a module name that is prefixed by the package's name declared in the `Package.name` property of its `PklProject` file.
For example, the following are valid module declarations for package `com.example`:

* `module com.example.Birds`
* `module com.example.Birds.Parrot`

The part of the module name that comes after the package name
must match the module's relative path in its source code repository.
For example, module _com.example.Bird.Parrot_ is expected to be found at _$sourceCode/Bird/Parrot.pkl_,
where _sourceCode_ is configured in the `Package.sourceCode` property of its `PklProject` file.

=== Gradle Plugin

See xref:pkl-gradle:index.adoc#pkldoc-generation[Pkldoc Generation] in the _Gradle Plugin_ chapter.

=== Java Library

The Java library offers two APIs:

* A high-level link:{uri-CliDocGenerator}[CliDocGenerator] API whose feature set corresponds to the CLI.
* A low-level link:{uri-DocGenerator}[DocGenerator] API that offers additional features and control.

For more information, refer to the Javadoc documentation.

=== CLI

*Synopsis:* `pkldoc [<options>] <modules>`

`<modules>`::
The absolute or relative URIs of docsite descriptors, package descriptors, and the modules for which to generate documentation.

Relative URIs are resolved against the working directory.

==== Options

.-o, --output-dir
[%collapsible]
====
Default: (none) +
Example: `pkldoc` +
The directory where generated documentation is placed.
====

.--no-symlinks
[%collapsible]
====
Create copies of files and directories instead of symbolic links.
In particular, this affects how the "current" directories containing documentation content for the last generated version should be created.
By default, a symbolic link is created pointing to the last generated version. If symlinks are disabled, a full copy of the last generated version is created.
====

Common CLI options:

include::../../pkl-cli/partials/cli-common-options.adoc[]

[[full-example]]
== Full Example

For a ready-to-go example with full source code and detailed walkthrough,
see link:{uri-pkldoc-example}[pkldoc] in the _pkl-jvm-examples_ repository.
