Browse Source

Support depthOffset in MD docs headings for nesting functions (#126984)

While this change appears subtle at this point, I am using this in a later PR that adds a lot more spatial functions, where nesting them in related groups like this looks much better.

The main impact of this is that the On this page navigator on the right panel of the docs will show the nesting

Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com>
Craig Taverner 5 months ago
parent
commit
f6a05c6a7c

+ 1 - 1
docs/reference/query-languages/esql/_snippets/functions/layout/st_xmax.md

@@ -1,6 +1,6 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
 
-## `ST_XMAX` [esql-st_xmax]
+### `ST_XMAX` [esql-st_xmax]
 
 **Syntax**
 

+ 1 - 1
docs/reference/query-languages/esql/_snippets/functions/layout/st_xmin.md

@@ -1,6 +1,6 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
 
-## `ST_XMIN` [esql-st_xmin]
+### `ST_XMIN` [esql-st_xmin]
 
 **Syntax**
 

+ 1 - 1
docs/reference/query-languages/esql/_snippets/functions/layout/st_ymax.md

@@ -1,6 +1,6 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
 
-## `ST_YMAX` [esql-st_ymax]
+### `ST_YMAX` [esql-st_ymax]
 
 **Syntax**
 

+ 1 - 1
docs/reference/query-languages/esql/_snippets/functions/layout/st_ymin.md

@@ -1,6 +1,6 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
 
-## `ST_YMIN` [esql-st_ymin]
+### `ST_YMIN` [esql-st_ymin]
 
 **Syntax**
 

+ 4 - 4
docs/reference/query-languages/esql/_snippets/lists/spatial-functions.md

@@ -6,7 +6,7 @@
 * [`ST_X`](../../functions-operators/spatial-functions.md#esql-st_x)
 * [`ST_Y`](../../functions-operators/spatial-functions.md#esql-st_y)
 * [preview] [`ST_ENVELOPE`](../../functions-operators/spatial-functions.md#esql-st_envelope)
-* [preview] [`ST_XMAX`](../../functions-operators/spatial-functions.md#esql-st_xmax)
-* [preview] [`ST_XMIN`](../../functions-operators/spatial-functions.md#esql-st_xmin)
-* [preview] [`ST_YMAX`](../../functions-operators/spatial-functions.md#esql-st_ymax)
-* [preview] [`ST_YMIN`](../../functions-operators/spatial-functions.md#esql-st_ymin)
+  * [preview] [`ST_XMAX`](../../functions-operators/spatial-functions.md#esql-st_xmax)
+  * [preview] [`ST_XMIN`](../../functions-operators/spatial-functions.md#esql-st_xmin)
+  * [preview] [`ST_YMAX`](../../functions-operators/spatial-functions.md#esql-st_ymax)
+  * [preview] [`ST_YMIN`](../../functions-operators/spatial-functions.md#esql-st_ymin)

+ 6 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/FunctionInfo.java

@@ -70,6 +70,12 @@ public @interface FunctionInfo {
      */
     String appendix() default "";
 
+    /**
+     * Adjusts documentation heading level (0=standard, 1=subheading, etc).
+     * Used to create logical nesting between related functions.
+     */
+    int depthOffset() default 0;
+
     /**
      * The position the function can appear in the language.
      */

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StXMax.java

@@ -45,7 +45,8 @@ public class StXMax extends UnaryScalarFunction {
         returnType = "double",
         description = "Extracts the maximum value of the `x` coordinates from the supplied geometry.\n"
             + "If the geometry is of type `geo_point` or `geo_shape` this is equivalent to extracting the maximum `longitude` value.",
-        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max")
+        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max"),
+        depthOffset = 1  // So this appears as a subsection of ST_ENVELOPE
     )
     public StXMax(
         Source source,

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StXMin.java

@@ -45,7 +45,8 @@ public class StXMin extends UnaryScalarFunction {
         returnType = "double",
         description = "Extracts the minimum value of the `x` coordinates from the supplied geometry.\n"
             + "If the geometry is of type `geo_point` or `geo_shape` this is equivalent to extracting the minimum `longitude` value.",
-        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max")
+        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max"),
+        depthOffset = 1  // So this appears as a subsection of ST_ENVELOPE
     )
     public StXMin(
         Source source,

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StYMax.java

@@ -45,7 +45,8 @@ public class StYMax extends UnaryScalarFunction {
         returnType = "double",
         description = "Extracts the maximum value of the `y` coordinates from the supplied geometry.\n"
             + "If the geometry is of type `geo_point` or `geo_shape` this is equivalent to extracting the maximum `latitude` value.",
-        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max")
+        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max"),
+        depthOffset = 1  // So this appears as a subsection of ST_ENVELOPE
     )
     public StYMax(
         Source source,

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StYMin.java

@@ -45,7 +45,8 @@ public class StYMin extends UnaryScalarFunction {
         returnType = "double",
         description = "Extracts the minimum value of the `y` coordinates from the supplied geometry.\n"
             + "If the geometry is of type `geo_point` or `geo_shape` this is equivalent to extracting the minimum `latitude` value.",
-        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max")
+        examples = @Example(file = "spatial_shapes", tag = "st_x_y_min_max"),
+        depthOffset = 1  // So this appears as a subsection of ST_ENVELOPE
     )
     public StYMin(
         Source source,

+ 13 - 11
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java

@@ -536,7 +536,7 @@ public abstract class DocsV3Support {
             }
             boolean hasExamples = renderExamples(info);
             boolean hasAppendix = renderAppendix(info.appendix());
-            renderFullLayout(info.preview(), info.appliesTo(), hasExamples, hasAppendix, hasFunctionOptions);
+            renderFullLayout(info, hasExamples, hasAppendix, hasFunctionOptions);
             renderKibanaInlineDocs(name, null, info);
             renderKibanaFunctionDefinition(name, null, info, description.args(), description.variadic());
         }
@@ -627,16 +627,12 @@ public abstract class DocsV3Support {
             }
         }
 
-        private void renderFullLayout(
-            boolean preview,
-            FunctionAppliesTo[] functionAppliesTos,
-            boolean hasExamples,
-            boolean hasAppendix,
-            boolean hasFunctionOptions
-        ) throws IOException {
+        private void renderFullLayout(FunctionInfo info, boolean hasExamples, boolean hasAppendix, boolean hasFunctionOptions)
+            throws IOException {
+            String headingMarkdown = "#".repeat(2 + info.depthOffset());
             StringBuilder rendered = new StringBuilder(
                 DOCS_WARNING + """
-                    ## `$UPPER_NAME$` [esql-$NAME$]
+                    $HEAD$ `$UPPER_NAME$` [esql-$NAME$]
                     $PREVIEW_CALLOUT$
                     **Syntax**
 
@@ -645,10 +641,11 @@ public abstract class DocsV3Support {
                     :class: text-center
                     :::
 
-                    """.replace("$NAME$", name)
+                    """.replace("$HEAD$", headingMarkdown)
+                    .replace("$NAME$", name)
                     .replace("$CATEGORY$", category)
                     .replace("$UPPER_NAME$", name.toUpperCase(Locale.ROOT))
-                    .replace("$PREVIEW_CALLOUT$", makePreviewText(preview, functionAppliesTos))
+                    .replace("$PREVIEW_CALLOUT$", makePreviewText(info.preview(), info.appliesTo()))
             );
             for (String section : new String[] { "parameters", "description", "types" }) {
                 rendered.append(addInclude(section));
@@ -777,6 +774,11 @@ public abstract class DocsV3Support {
                     return orig.appendix().replace(baseName, name);
                 }
 
+                @Override
+                public int depthOffset() {
+                    return orig.depthOffset();
+                }
+
                 @Override
                 public FunctionType type() {
                     return orig.type();