diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt b/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt
index 1dcb94e71dfd87..356016f5b5b3d2 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt
@@ -103,6 +103,47 @@ Use literally anything but this function.
+
+
+## param_doc_multiline
+
+
+param_doc_multiline(complex)
+
+
+Has a complex parameter.
+
+### Parameters
+
+
+
+
+
+
+
+
+ complex |
+
+ required.
+
+ A parameter with some non-obvious behavior.
+
+ For example, it does things that require **multiple paragraphs** to explain.
+
+Note: we should preserve the nested indent in the following code:
+
+```json
+{
+ "key": "value"
+}
+```
+
+ |
+
+
+
+
+
## returns_a_thing
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/input.bzl b/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/input.bzl
index d00f29353f33ba..53af2dae446ab7 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/input.bzl
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/input.bzl
@@ -54,3 +54,21 @@ def deprecated_do_not_use():
def undocumented_function(a, b, c):
pass
+
+def param_doc_multiline(complex):
+ """Has a complex parameter.
+
+ Args:
+ complex: A parameter with some non-obvious behavior.
+
+ For example, it does things that require **multiple paragraphs** to explain.
+
+ Note: we should preserve the nested indent in the following code:
+
+ ```json
+ {
+ "key": "value"
+ }
+ ```
+ """
+ pass
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt b/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt
index f6add6b4702165..140fa022b992c6 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt
@@ -56,7 +56,7 @@ Small example of function using a markdown template.
| Name | Description | Default Value |
| :-------------: | :-------------: | :-------------: |
| foo | This parameter does foo related things. | none |
-| bar | This parameter does bar related things. | "bar"
|
+| bar | This parameter does bar related things.
For example, it does things that require **multiple paragraphs** to explain.
Note: we should preserve the nested indent in the following code:
json { "key": "value" }
| "bar"
|
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/input.bzl b/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/input.bzl
index 23f3379a09acbc..e84caab422ba8a 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/input.bzl
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/input.bzl
@@ -6,6 +6,16 @@ def example_function(foo, bar = "bar"):
Args:
foo: This parameter does foo related things.
bar: This parameter does bar related things.
+
+ For example, it does things that require **multiple paragraphs** to explain.
+
+ Note: we should preserve the nested indent in the following code:
+
+ ```json
+ {
+ "key": "value"
+ }
+ ```
"""
pass
diff --git a/src/tools/starlark/java/com/google/devtools/starlark/common/DocstringUtils.java b/src/tools/starlark/java/com/google/devtools/starlark/common/DocstringUtils.java
index 7a3cba063fa310..222276ad929945 100644
--- a/src/tools/starlark/java/com/google/devtools/starlark/common/DocstringUtils.java
+++ b/src/tools/starlark/java/com/google/devtools/starlark/common/DocstringUtils.java
@@ -479,17 +479,25 @@ private List parseParameters() {
/** Parses additional lines that can come after "param: foo" in an 'Args' section. */
private void parseContinuedParamDescription(
int baselineIndentation, StringBuilder description) {
+ // Two iterations: first buffer lines and find the minimal indent, then trim to the min
+ List buffer = new ArrayList<>();
+ int continuationIndentation = Integer.MAX_VALUE;
while (nextLine()) {
- if (line.isEmpty()) {
- description.append('\n');
- continue;
- }
- if (getIndentation(line) <= baselineIndentation) {
- break;
+ if (!line.isEmpty()) {
+ if (getIndentation(line) <= baselineIndentation) {
+ break;
+ }
+ continuationIndentation = Math.min(getIndentation(line), continuationIndentation);
}
- String trimmedLine = line.substring(baselineIndentation);
+ buffer.add(line);
+ }
+
+ for (String bufLine : buffer) {
description.append('\n');
- description.append(trimmedLine);
+ if (!bufLine.isEmpty()) {
+ String trimmedLine = bufLine.substring(continuationIndentation);
+ description.append(trimmedLine);
+ }
}
}