This is an automated email from the ASF dual-hosted git repository. spmallette pushed a commit to branch afd in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 54471af798322317dfd3a5a29a90d2f4d36ee263 Author: Stephen Mallette <[email protected]> AuthorDate: Sat Jul 25 13:01:23 2026 +0000 Split the traversal step catalog into one Markdown page per step The size-driven splitter packed the ~117-step traversal reference into 7 arbitrarily-named grab-bag pages (combine-step.md held 26 steps, etc.), so an agent scanning llms.txt for a step like fold() found no entry and no way to guess which file held it. The page names and llms.txt descriptions effectively lied about their contents. Add an [llms-explode] section attribute that marks a catalog section whose direct subsections should each become their own page. The Markdown converter emits it as a hidden <!-- llms-explode --> marker (never rendered into HTML or the page body); MarkdownSplitter gives each direct child of a marked section its own anchor-named page regardless of size. Applied to "Graph Traversal Steps", this yields one page per step (fold-step.md, group-step.md, ...), each with its own llms.txt entry. Also add a curated [llms-summary] to every step in the catalog (first-sentence extraction, with ~18 hand-written where the opening prose was not self-describing) so each step's llms.txt line is a clean one-liner. Result: reference grows from 24 to 140 pages, llms.txt from ~71 to 187 entries (30.8KB, under the 50KB cap), every page under budget, 408 cross-page links resolve, no marker leakage into HTML. 172 extension tests pass. Assisted-by: Claude Code:claude-opus-4-8 --- docs/src/reference/the-traversal.asciidoc | 116 ++++++++++++++++++++- .../tinkerpop/tinkeradoc/MarkdownConverter.java | 23 ++++ .../tinkerpop/tinkeradoc/MarkdownSplitter.java | 30 ++++++ .../tinkeradoc/MarkdownConverterProbeTest.java | 15 +++ .../tinkerpop/tinkeradoc/MarkdownSplitterTest.java | 29 ++++++ 5 files changed, 212 insertions(+), 1 deletion(-) diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc index 101a60f9c9..6d12ab989d 100644 --- a/docs/src/reference/the-traversal.asciidoc +++ b/docs/src/reference/the-traversal.asciidoc @@ -390,7 +390,7 @@ Spawn steps, which actually yield a traversal, typically match the names of exis * `V()` - Reads vertices from the graph to start the traversal (<<graph-step, example>>). [[graph-traversal-steps]] -[llms-summary="Reference catalog of the individual Gremlin steps (map, filter, sideEffect, branch, and more) with syntax and examples for each."] +[llms-summary="Reference catalog of the individual Gremlin steps (map, filter, sideEffect, branch, and more) with syntax and examples for each.",llms-explode=""] == Graph Traversal Steps Gremlin steps are chained together to produce the actual traversal and are triggered by way of <<start-steps,start steps>> @@ -399,6 +399,7 @@ on the `GraphTraversalSource`. IMPORTANT: More details about the Gremlin language can be found in the Provider Documentation within the link:https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#gremlin-semantics[Gremlin Semantics Section]. +[llms-summary="The five general steps (map, flatMap, filter, sideEffect, branch) from which all other Gremlin steps are derived."] [[general-steps]] === General Steps @@ -483,6 +484,7 @@ g.V().choose(has('name','marko'), <2> The same operation, but using the traversal representing of `branch()`. <3> The more specific boolean-based `choose()`-step is implemented as a `branch()`. +[llms-summary="Terminal steps (e.g. next(), toList(), iterate(), hasNext()) that execute a traversal and return concrete results rather than another traversal."] [[terminal-steps]] === Terminal Steps @@ -523,6 +525,7 @@ on the current `Traversal` that will be completed in the future. Finally, <<explain-step,`explain()`>>-step is also a terminal step and is described in its own section. +[llms-summary="The addE()-step (map/sideEffect) adds an edge between vertices in the graph."] [[addedge-step]] === AddE Step @@ -573,6 +576,7 @@ supports user provided ids. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#addE(java.lang.String)++[`addE(String)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#addE(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`addE(Traversal)`] +[llms-summary="The addV()-step is used to add vertices to the graph (map/sideEffect)."] [[addvertex-step]] === AddV Step @@ -594,6 +598,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#addV(java.lang.String)++[`addV(String)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#addV(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`addV(Traversal)`] +[llms-summary="The aggregate()-step (sideEffect) is used to aggregate all the objects at a particular point of traversal into a Collection."] [[aggregate-step]] === [[store-step]]Aggregate Step @@ -665,6 +670,7 @@ g.E().aggregate(local,'x').by('weight').cap('x') link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#aggregate(java.lang.String)++[`aggregate(String)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#aggregate(org.apache.tinkerpop.gremlin.process.traversal.Scope,java.lang.String)++[`aggregate(Scope,String)`] +[llms-summary="It is possible to filter list traversers using all()-step (filter)."] [[all-step]] === All Step @@ -689,6 +695,7 @@ g.V().values('age').fold().all(gt(25)) <1> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#all(org.apache.tinkerpop.gremlin.process.traversal.P)++[`all(P)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`] +[llms-summary="The and()-step ensures that all provided traversals yield a result (filter)."] [[and-step]] === And Step @@ -721,6 +728,7 @@ g.V().where(outE('created').and().outE('knows')).values('name') link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#and(org.apache.tinkerpop.gremlin.process.traversal.Traversal...)++[`and(Traversal...)`] +[llms-summary="It is possible to filter list traversers using any()-step (filter)."] [[any-step]] === Any Step @@ -745,6 +753,7 @@ g.V().values('age').fold().any(gt(25)) <1> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#any(org.apache.tinkerpop.gremlin.process.traversal.P)++[`any(P)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`] +[llms-summary="The as()-step is not a real step, but a \"step modulator\" similar to by() and option()."] [[as-step]] === As Step @@ -787,6 +796,7 @@ g.V().hasLabel('software').as('a','b','c'). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#as(java.lang.String,java.lang.String...)++[`as(String,String...)`] +[llms-summary="The asString()-step (map) returns the value of incoming traverser as strings."] [[asString-step]] === AsString Step @@ -808,6 +818,7 @@ g.V().hasLabel('person').values('age').fold().asString(local) <3> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#asString()++[`asString()`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#asString(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`asString(Scope)`] +[llms-summary="The asDate()-step (map) converts string or numeric input to Date."] [[asDate-step]] === AsDate Step @@ -833,6 +844,7 @@ g.inject(datetime("2023-08-24T00:00:00Z")).asDate() <3> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#asDate()++[`asDate()`] +[llms-summary="The barrier()-step (barrier) turns the lazy traversal pipeline into a bulk-synchronous pipeline."] [[barrier-step]] === Barrier Step @@ -894,6 +906,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#barrier(java.util.function.Consumer)++[`barrier(Consumer)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#barrier(int)++[`barrier(int)`] +[llms-summary="The branch() step splits the traverser to all the child traversals provided to it."] [[branch-step]] === Branch Step @@ -905,6 +918,7 @@ robust steps like <<choose-step, choose()>> and <<union-step,union()>>. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#branch(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`branch(Traversal)`] +[llms-summary="The by()-step is not an actual step, but instead is a \"step-modulator\" similar to as() and option()."] [[by-step]] === By Step @@ -974,6 +988,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Order.html++[`Order`], <<a-note-on-maps>> +[llms-summary="The call() step allows for custom, provider-specific service calls either at the start of a traversal or mid-traversal."] [[call-step]] === Call Step @@ -1035,6 +1050,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#call(java.lang.String,org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`call(String, Traversal)`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#call(java.lang.String,java.util.Map,org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`call(String, Map, Traversal)`] +[llms-summary="The cap()-step (barrier) iterates the traversal up to itself and emits the sideEffect referenced by the provided key."] [[cap-step]] === Cap Step @@ -1054,6 +1070,7 @@ g.V().groupCount('a').by(label).groupCount('b').by(outE().count()).cap('a','b') link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#cap(java.lang.String,java.lang.String...)++[`cap(String,String...)`] +[llms-summary="The choose()-step (branch) routes the current traverser to a particular traversal branch option."] [[choose-step]] === Choose Step @@ -1119,6 +1136,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#choose(org.apache.tinkerpop.gremlin.process.traversal.Traversal,org.apache.tinkerpop.gremlin.process.traversal.Traversal,org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`choose(Traversal,Traversal,Traversal)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#choose(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`choose(Traversal)`] +[llms-summary="The coalesce()-step evaluates the provided traversals in order and returns the first traversal that emits at least one element."] [[coalesce-step]] === Coalesce Step @@ -1137,6 +1155,7 @@ g.V().hasLabel('person').coalesce(values('nickname'), values('name')) link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#coalesce(org.apache.tinkerpop.gremlin.process.traversal.Traversal...)++[`coalesce(Traversal...)`] +[llms-summary="To randomly filter out a traverser, use the coin()-step (filter)."] [[coin-step]] === Coin Step @@ -1173,6 +1192,7 @@ g.V().values("name").fold().combine(__.constant("stephen").fold()) link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#combine(java.lang.Object)++[`combine(Object)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#combine-step++[`Semantics`] +[llms-summary="The concat()-step (map) concatenates one or more String values together to the incoming String traverser."] [[concat-step]] === Concat Step @@ -1220,6 +1240,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#concat(org.apache.tinkerpop.gremlin.process.traversal.Traversal,org.apache.tinkerpop.gremlin.process.traversal.Traversal...)++[`concat(Taversal, Traversal...)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#concat-step++[`Semantics`] +[llms-summary="The conjoin()-step (map) joins together the elements in the incoming list traverser together with the provided argument as a delimiter."] [[conjoin-step]] === Conjoin Step @@ -1238,6 +1259,7 @@ g.V().values("name").fold().conjoin("+") link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#conjoin(java.lang.String)++[`conjoin(String)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#conjoin-step++[`Semantics`] +[llms-summary="The connectedComponent() step performs a computation to identify Connected Component instances in a graph."] [[connectedcomponent-step]] === ConnectedComponent Step @@ -1273,6 +1295,7 @@ configuration keys from the `ConnectedComponent` class and is automatically impo link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#connectedComponent()++[`connectedComponent()`] +[llms-summary="To specify a constant value for a traverser, use the constant()-step (map)."] [[constant-step]] === Constant Step @@ -1296,6 +1319,7 @@ g.V().coalesce( link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#constant(E2)++[`constant(Object)`] +[llms-summary="The count()-step (map) counts the total number of represented traversers in the streams (i.e. the bulk count)."] [[count-step]] === Count Step @@ -1323,6 +1347,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#count(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`count(Scope)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The cyclicPath()-step (filter) retains only traversers whose path contains a cycle (a repeated element)."] [[cyclicpath-step]] === CyclicPath Step @@ -1355,6 +1380,7 @@ g.V(1).as('a').out('created').as('b'). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#cyclicPath()++[`cyclicPath()`] +[llms-summary="The dateAdd()-step (map) returns the value with the addition of the value number of units as specified by the DateToken."] [[dateAdd-step]] === DateAdd Step @@ -1374,6 +1400,7 @@ g.inject(["2023-08-02T00:00:00Z", "2023-08-03T00:00:00Z"]).unfold().asDate().dat link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#dateAdd(org.apache.tinkerpop.gremlin.process.traversal.DT,int)++[`dateAdd(DT,int)`] +[llms-summary="The dateDiff()-step (map) returns the difference between two Dates in epoch time."] [[dateDiff-step]] === DateDiff Step @@ -1396,6 +1423,7 @@ g.inject("2023-08-02T00:00:00Z").asDate().dateDiff(constant("2023-08-03T00:00:00 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#dateDiff(java.util.Date)++[`dateDiff(Date)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#dateDiff(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`dateDiff(Traversal)`] +[llms-summary="With dedup()-step (filter), repeatedly seen objects are removed from the traversal stream."] [[dedup-step]] === Dedup Step @@ -1476,6 +1504,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`], link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#dedup-step++[`Semantics`] +[llms-summary="The difference()-step (map) calculates the difference between the incoming list traverser and the provided list argument."] [[difference-step]] === Difference Step @@ -1495,6 +1524,7 @@ g.V().values("name").fold().difference(__.V().limit(2).values("name").fold()) link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#difference(java.lang.Object)++[`difference(Object)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#difference-step++[`Semantics`] +[llms-summary="The disjunct()-step (map) calculates the disjunct set between the incoming list traverser and the provided list argument."] [[disjunct-step]] === Disjunct Step @@ -1515,6 +1545,7 @@ g.V().values("name").fold().disjunct(__.V().limit(3).values("name").fold()) link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#disjunct(java.lang.Object)++[`disjunct(Object)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#disjunct-step++[`Semantics`] +[llms-summary="The drop()-step (filter/sideEffect) is used to remove element and properties from the graph (i.e. remove)."] [[drop-step]] === Drop Step @@ -1535,6 +1566,7 @@ g.V() * link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#drop()++[`drop()`] +[llms-summary="The E()-step is meant to read edges from the graph and is usually used to start a GraphTraversal, but can also be used mid-traversal."] [[e-step]] === E Step @@ -1555,6 +1587,7 @@ g.inject(1).coalesce(E().hasLabel("knows"), addE("knows").from(V().has("name","j link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#E(java.lang.Object...)++[`E(Object...)`] +[llms-summary="The element() step is a no-argument step that traverses from a Property to the Element that owns it."] [[element-step]] === Element Step @@ -1575,6 +1608,7 @@ g.V().properties().properties().element() <3> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#element()++[`element()`] +[llms-summary="The elementMap()-step yields a Map representation of the structure of an element."] [[elementmap-step]] === ElementMap Step @@ -1606,6 +1640,7 @@ as the `id` is the only available data to the star graph. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#elementMap(java.lang.String...)++[`elementMap(String...)`] +[llms-summary="The emit-step is not an actual step, but is instead a step modulator for repeat() (find more documentation on the emit() there)."] [[emit-step]] === Emit Step @@ -1618,6 +1653,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#emit(java.util.function.Predicate)++[`emit(Predicate)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#emit(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`emit(Traversal)`] +[llms-summary="The explain()-step (terminal) will return a TraversalExplanation."] [[explain-step]] === Explain Step @@ -1635,6 +1671,7 @@ g.V().hasLabel('person').outE().identity().inV().count().is(gt(5)).explain() For traversal profiling information, please see <<profile-step,`profile()`>>-step. +[llms-summary="The fail()-step provides a way to force a traversal to immediately fail with an exception."] [[fail-step]] === Fail Step @@ -1693,6 +1730,7 @@ continue to surface this condition as their standard remote exception type. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#fail()++[`fail()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#fail(java.lang.String)++[`fail(String)`] +[llms-summary="The filter() step maps the traverser from the current object to either true or false where the latter will not pass the traverser to the next step in the proces"] [[filter-step]] === Filter Step @@ -1704,6 +1742,7 @@ information. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#filter(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`filter(Traversal)`] +[llms-summary="The flatMap() step maps the traverser from the current object to an Iterator of objects for the next step in the process."] [[flatmap-step]] === FlatMap Step @@ -1714,6 +1753,7 @@ process. Please see the <<general-steps, General Steps>> section for more inform link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#flatMap(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`flatMap(Traversal)`] +[llms-summary="The format()-step (map) builds a string from a template with placeholders filled by traverser values and properties."] [[format-step]] === Format Step @@ -1737,6 +1777,7 @@ g.V().project("name","count").by(values("name")).by(bothE().count()).format("%{n link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#format(java.lang.String)++[`format(String)`], +[llms-summary="The fold()-step (map) aggregates all objects in the stream into a single list (or reduces them with a supplied seed and function)."] [[fold-step]] === Fold Step @@ -1769,6 +1810,7 @@ g.inject(["a":1],["b":2]).fold([], addAll) <7> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#fold()++[`fold()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#fold(E2,java.util.function.BiFunction)++[`fold(Object,BiFunction)`] +[llms-summary="The from()-step is not an actual step, but instead is a \"step-modulator\" similar to as() and by()."] [[from-step]] === From Step @@ -1795,6 +1837,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#from(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`from(Traversal)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#from(org.apache.tinkerpop.gremlin.structure.Vertex)++[`from(Vertex)`] +[llms-summary="The group()-step (map/sideEffect) organizes objects into a Map by a key, optionally folding each group's values."] [[group-step]] === Group Step @@ -1835,6 +1878,7 @@ g.V().group().by('name').by('age') <2> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#group()++[`group()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#group(java.lang.String)++[`group(String)`] +[llms-summary="When it is important to know how many times a particular object has been at a particular part of a traversal, groupCount()-step (map/sideEffect) is used."] [[groupcount-step]] === GroupCount Step @@ -1959,6 +2003,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/structure/T.html++[`T`], link:++https://tinkerpop.apache.org/docs/x.y.z/recipes/#has-traversal++[Recipes - Anti-pattern] +[llms-summary="The id()-step (map) takes an Element and extracts its identifier from it."] [[id-step]] === Id Step @@ -1976,6 +2021,7 @@ g.V(1).properties().id() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#id()++[`id()`] +[llms-summary="The identity()-step (map) is an identity function which maps the current object to itself."] [[identity-step]] === Identity Step @@ -1991,6 +2037,7 @@ g.V().identity() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#identity()++[`identity()`] +[llms-summary="The index()-step (map) indexes each element in the current collection."] [[index-step]] === Index Step @@ -2029,6 +2076,7 @@ g.V().hasLabel("person").values("name").fold(). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#index()++[`index()`] +[llms-summary="The inject()-step inserts arbitrary objects into the traversal stream."] [[inject-step]] === Inject Step @@ -2059,6 +2107,7 @@ inject(1,2).map {it.get() + 1}.map {g.V(it.get()).next()}.values('name') link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#inject(E...)++[`inject(Object)`] +[llms-summary="The intersect()-step (map) calculates the intersection between the incoming list traverser and the provided list argument."] [[intersect-step]] === Intersect Step @@ -2078,6 +2127,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#intersect-step++[`Semantics`] anchor:_gremlin_i_o[] +[llms-summary="The task of importing and exporting the data of Graph instances is the job of the io()-step."] [[io-step]] === IO Step @@ -2265,6 +2315,7 @@ g.io("graph.kryo").write().iterate() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.html#io(java.lang.String)++[`io(String)`] +[llms-summary="It is possible to filter scalar values using is()-step (filter)."] [[is-step]] === Is Step @@ -2296,6 +2347,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#is(org.apache.tinkerpop.gremlin.process.traversal.P)++[`is(P)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`] +[llms-summary="The key()-step (map) takes a Property and extracts the key from it."] [[key-step]] === Key Step @@ -2311,6 +2363,7 @@ g.V(1).properties().properties().key() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#key()++[`key()`] +[llms-summary="The label()-step (map) takes an Element and extracts its label from it."] [[label-step]] === Label Step @@ -2327,6 +2380,7 @@ g.V(1).properties().label() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#label()++[`label()`] +[llms-summary="The length()-step (map) returns the length incoming string or list of string traverser."] [[length-step]] === Length Step @@ -2347,6 +2401,7 @@ g.V().values('name').fold().length(local) <2> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#length()++[`length()`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#length(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`length(Scope)`] +[llms-summary="The limit()-step is analogous to range()-step save that the lower end range is set to 0."] [[limit-step]] === Limit Step @@ -2376,6 +2431,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#limit(org.apache.tinkerpop.gremlin.process.traversal.Scope,long)++[`limit(Scope,long)`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The local()-step (branch) runs a child traversal locally on each single input object rather than the whole stream."] [[local-step]] === Local Step @@ -2435,6 +2491,7 @@ the confines of the vertex's star graph. In other words, it can not traverse to link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#local(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`local(Traversal)`] +[llms-summary="The loops()-step (map) extracts the number of times the Traverser has gone through the current loop."] [[loops-step]] === Loops Step @@ -2450,6 +2507,7 @@ g.V().emit(__.has("name", "marko").or().loops().is(2)).repeat(__.out()).values(" link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#loops()++[`loops()`], link:++https://tinkerpop.apache.org/docs/x.y.z/recipes/#looping++[`Looping Recipes`] +[llms-summary="The lTrim()-step (map) returns a string with leading whitespace removed."] [[lTrim-step]] === LTrim Step @@ -2467,6 +2525,7 @@ g.inject([" hello ", " world ", null]).lTrim(local) <1> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#lTrim()++[`lTrim()`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#lTrim(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`lTrim(Scope)`] +[llms-summary="The map() step maps the traverser from the current object to the next step in the process."] [[map-step]] === Map Step @@ -2704,6 +2763,7 @@ path of the traverser in `match()`. As such, `where()`-steps in `match()` are us link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#match(org.apache.tinkerpop.gremlin.process.traversal.Traversal...)++[`match(Traversal...)`] +[llms-summary="The math()-step (math) enables scientific calculator functionality within Gremlin."] [[math-step]] === Math Step @@ -2755,6 +2815,7 @@ functions are provided: link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#math(java.lang.String)++[`math(String)`] +[llms-summary="The max()-step (map) operates on a stream of comparable objects and determines which is the last object according to its natural order in the stream."] [[max-step]] === Max Step @@ -2791,6 +2852,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#max(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`max(Scope)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The mean()-step (map) operates on a stream of numbers and determines the average of those numbers."] [[mean-step]] === Mean Step @@ -2829,6 +2891,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#mean(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`mean(Scope)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The merge()-step (map) combines collections like lists and maps."] [[merge-step]] === Merge Step @@ -2850,6 +2913,7 @@ g.V().hasLabel('software').elementMap().merge([year:2009]) link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#merge(java.lang.Object)++[`merge(Object)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#merge-step++[`Semantics`] +[llms-summary="The mergeE() step is used to add edges and their properties to a graph in a \"create if not exist\" fashion."] [[mergeedge-step]] === MergeEdge Step @@ -2988,6 +3052,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Merge.html++[`Merge`], link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#_mergee++[Semantics] +[llms-summary="The mergeV() -step is used to add vertices and their properties to a graph in a \"create if not exist\" fashion."] [[mergevertex-step]] === MergeVertex Step @@ -3196,6 +3261,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Merge.html++[`Merge`], link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#_mergee++[Semantics] +[llms-summary="The min()-step (map) operates on a stream of comparable objects and determines which is the first object according to its natural order in the stream."] [[min-step]] === Min Step @@ -3232,6 +3298,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#min(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`min(Scope)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The none()-step (filter) filters all objects from a traversal stream."] [[none-step]] === None Step @@ -3280,6 +3347,7 @@ g.V().hasLabel('person'). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#not(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`not(Traversal)`] +[llms-summary="The option()-step is a modulator that supplies branch choices to choose(), branch(), and mergeV()/mergeE()."] [[option-step]] === Option Step @@ -3290,6 +3358,7 @@ An option to a <<general-steps,`branch()`>> or <<choose-step,`choose()`>>. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#option(M,org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`option(Object,Traversal)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#option(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`option(Traversal)`] +[llms-summary="The optional()-step (branch/flatMap) returns the result of the specified traversal if it yields a result else it returns the calling element, i.e. the identity("] [[optional-step]] === Optional Step @@ -3318,6 +3387,7 @@ g.V().hasLabel('person').optional(out('knows').optional(out('created'))).path() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#optional(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`optional(Traversal)`] +[llms-summary="The or()-step ensures that at least one of the provided traversals yield a result (filter)."] [[or-step]] === Or Step @@ -3351,6 +3421,7 @@ g.V().where(outE('created').or().outE('knows')).values('name') link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#or(org.apache.tinkerpop.gremlin.process.traversal.Traversal...)++[`or(Traversal...)`] +[llms-summary="When the objects of the traversal stream need to be sorted, order()-step (map) can be leveraged."] [[order-step]] === Order Step @@ -3422,6 +3493,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Order.html++[`Order`] +[llms-summary="The pageRank()-step (map/sideEffect) calculates PageRank using PageRankVertexProgram."] [[pagerank-step]] === PageRank Step @@ -3465,6 +3537,7 @@ g.V().hasLabel('person'). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#pageRank()++[`pageRank()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#pageRank(double)++[`pageRank(double)`] +[llms-summary="The path()-step (map) returns the full history (path) of each traverser through the traversal."] [[path-step]] === Path Step @@ -3563,6 +3636,7 @@ path.d == path.e link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#path()++[`path()`] +[llms-summary="The peerPressure()-step (map/sideEffect) clusters vertices using PeerPressureVertexProgram."] [[peerpressure-step]] === PeerPressure Step @@ -3589,6 +3663,7 @@ configuration keys from the `PeerPressure` class and is automatically imported t link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#peerPressure()++[`peerPressure()`] +[llms-summary="The product()-step (map) calculates the cartesian product between the incoming list traverser and the provided list argument."] [[product-step]] === Product Step @@ -3607,6 +3682,7 @@ g.V().values("name").fold().product(__.V().has("age").limit(1).values("age").fol link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#product(java.lang.Object)++[`product(Object)`] link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#product-step++[`Semantics`] +[llms-summary="The profile()-step (sideEffect) exists to allow developers to profile their traversals to determine statistical information like step runtime, counts, etc."] [[profile-step]] === Profile Step @@ -3642,6 +3718,7 @@ For traversal compilation information, please see <<explain-step,`explain()`>>-s link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#profile()++[`profile()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#profile(java.lang.String)++[`profile(String)`] +[llms-summary="The project()-step (map) projects the current object into a Map<String,Object> keyed by provided labels."] [[project-step]] === Project Step @@ -3676,6 +3753,7 @@ g.V().project('n','a').by('name').by('age') <1> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#project(java.lang.String,java.lang.String...)++[`project(String,String...)`] +[llms-summary="The program()-step (map/sideEffect) is the \"lambda\" step for GraphComputer jobs."] [[program-step]] === Program Step @@ -3771,6 +3849,7 @@ g.V().hasLabel('person'). elementMap('name', 'rank') ---- +[llms-summary="The properties()-step (map) extracts properties from an Element in the traversal stream."] [[properties-step]] === Properties Step @@ -3788,6 +3867,7 @@ g.V(1).properties('location').has('endTime').valueMap() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#properties(java.lang.String...)++[`properties(String...)`] anchor:addproperty-step[] +[llms-summary="The property()-step is used to add properties to the elements of the graph (sideEffect)."] [[property-step]] === Property Step @@ -3828,6 +3908,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#property(org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality,java.lang.Object,java.lang.Object,java.lang.Object...)++[`property(Cardinality, Object, Object, Object...)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/structure/VertexProperty.Cardinality.html++[`Cardinality`] +[llms-summary="The propertiesMap()-step yields a Map representation of the properties of an element."] [[propertymap-step]] === PropertyMap Step @@ -3845,6 +3926,7 @@ g.E().propertyMap() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#propertyMap(java.lang.String...)++[`propertyMap(String...)`] +[llms-summary="As traversers propagate through the traversal, it is possible to only allow a certain number of them to pass through with range()-step (filter)."] [[range-step]] === Range Step @@ -3885,6 +3967,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#range(org.apache.tinkerpop.gremlin.process.traversal.Scope,long,long)++[`range(Scope,long,long)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The read()-step is not really a \"step\" but a step modulator in that it modifies the functionality of the io()-step."] [[read-step]] === Read Step @@ -3896,6 +3979,7 @@ location. Please see the <<io-step,documentation>> for `io()`-step for more comp link:++https://tinkerpop.apache.org/javadocs/x.y.z/full/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#read()++[`read()`] +[llms-summary="The repeat()-step (branch) is used for looping over a traversal given some break predicate."] [[repeat-step]] === Repeat Step @@ -3996,6 +4080,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre <<emit-step, emit>>, <<times-step, times()>>, <<until-step,until()>>, link:++https://tinkerpop.apache.org/docs/x.y.z/recipes/#looping++[`Looping Recipes`] +[llms-summary="The replace()-step (map) returns a string with the specified characters in the original string replaced with the new characters."] [[replace-step]] === Replace Step The `replace()`-step (*map*) returns a string with the specified characters in the original string replaced with the new @@ -4019,6 +4104,7 @@ g.V().hasLabel("software").values("name").fold().replace(local, "p", "g") <4> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#replace(java.lang.String,java.lang.String)++[`replace(String,String)`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#replace(org.apache.tinkerpop.gremlin.process.traversal.Scope,java.lang.String,java.lang.String)++[`replace(Scope,String,String)`] +[llms-summary="The reverse()-step (map) returns the reverse of the incoming list traverser."] [[reverse-step]] === Reverse Step @@ -4036,6 +4122,7 @@ g.V().values("name").order().fold().reverse() <2> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#reverse()++[`reverse()`] +[llms-summary="The rTrim()-step (map) returns a string with trailing whitespace removed."] [[rTrim-step]] === RTrim Step @@ -4141,6 +4228,7 @@ g.withBulk(false).withSack(1.0f).V(1).local(outE('knows').barrier(normSack).inV( link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#sack()++[`sack()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#sack(java.util.function.BiFunction)++[`sack(BiFunction)`] +[llms-summary="The sample()-step is useful for sampling some number of traversers previous in the traversal."] [[sample-step]] === Sample Step @@ -4202,6 +4290,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#sample(org.apache.tinkerpop.gremlin.process.traversal.Scope,int)++[`sample(Scope,int)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The select()-step (map) selects labeled steps, side-effects, columns, or map entries from the traverser."] [[select-step]] === Select Step @@ -4342,6 +4431,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Pop.html++[`Pop`], <<a-note-on-maps>> +[llms-summary="The shortestPath()-step provides an easy way to find shortest non-cyclic paths in a graph."] [[shortestpath-step]] === ShortestPath step @@ -4406,6 +4496,7 @@ g.inject(g.withComputer().V().shortestPath(). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#shortestPath()++[`shortestPath()`] +[llms-summary="The sideEffect() step performs some operation on the traverser and passes it to the next step in the process."] [[sideeffect-step]] === SideEffect Step @@ -4416,6 +4507,7 @@ see the <<general-steps, General Steps>> section for more information. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#sideEffect(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`sideEffect(Traversal)`] +[llms-summary="When it is important that a traverser not repeat its path through the graph, simplePath()-step should be used (filter)."] [[simplepath-step]] === SimplePath Step @@ -4472,6 +4564,7 @@ cross the vertices from the first path. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#simplePath()++[`simplePath()`] +[llms-summary="The skip()-step is analogous to range()-step save that the higher end range is set to -1."] [[skip-step]] === Skip Step @@ -4506,6 +4599,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#skip(org.apache.tinkerpop.gremlin.process.traversal.Scope,long)++[`skip(Scope,long)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The split()-step (map) returns a list of strings created by splitting the incoming string traverser around the matches of the given separator."] [[split-step]] === Split Step The `split()`-step (*map*) returns a list of strings created by splitting the incoming string traverser around the @@ -4529,6 +4623,7 @@ g.V().hasLabel("person").values("name").fold().split(local, "a") <4> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#split(java.lang.String)++[`split(String)`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#split(org.apache.tinkerpop.gremlin.process.traversal.Scope,java.lang.String)++[`split(Scope, String)`] +[llms-summary="The subgraph()-step (sideEffect) extracts a portion of the graph into a new edge-induced subgraph."] [[subgraph-step]] === Subgraph Step @@ -4643,6 +4738,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#substring(int,int)++[`substring(int,int)`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#substring(org.apache.tinkerpop.gremlin.process.traversal.Scope,int,int)++[`substring(Scope,int,int)`] +[llms-summary="The sum()-step (map) operates on a stream of numbers and sums the numbers together to yield a result."] [[sum-step]] === Sum Step @@ -4679,6 +4775,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#sum(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`sum(Scope)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The tail()-step is analogous to limit()-step, except that it emits the last n-objects instead of the first n-objects."] [[tail-step]] === Tail Step @@ -4722,6 +4819,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#tail(org.apache.tinkerpop.gremlin.process.traversal.Scope,long)++[`tail(Scope,long)`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`] +[llms-summary="The timeLimit()-step (filter) halts a traversal branch after a specified time has elapsed."] [[timelimit-step]] === TimeLimit Step @@ -4753,6 +4851,7 @@ yield `false`. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#timeLimit(long)++[`timeLimit(long)`] +[llms-summary="The times-step is not an actual step, but is instead a step modulator for repeat() (find more documentation on the times() there)."] [[times-step]] === Times Step @@ -4785,6 +4884,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#toV(org.apache.tinkerpop.gremlin.structure.Direction)++[`toV(Direction)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/structure/Direction.html++[`Direction`] +[llms-summary="The toLower()-step (map) returns the lowercase representation of incoming string or list of string traverser."] [[toLower-step]] === ToLower Step @@ -4804,6 +4904,7 @@ g.inject(["HELLO", "wORlD", null]).toLower(Scope.local) <1> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#toLower()++[`toLower()`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#toLower(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`toLower(Scope)`] +[llms-summary="The toUpper()-step (map) returns the uppercase representation of incoming string or list of string traverser."] [[toUpper-step]] === ToUpper Step @@ -4825,6 +4926,7 @@ g.V().values("name").fold().toUpper(local) <2> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#toUpper()++[`toUpper()`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#toUpper(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`toUpper(Scope)`] +[llms-summary="The tree()-step (sideEffect) aggregates the paths emanating from elements into a tree structure."] [[tree-step]] === Tree Step @@ -4887,6 +4989,7 @@ g.V().has('name','josh').out('created').values('name').tree('x').cap('x') link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#tree()++[`tree()`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#tree(java.lang.String)++[`tree(String)`] +[llms-summary="The trim()-step (map) returns a string with leading and leading whitespace removed."] [[trim-step]] === Trim Step @@ -4904,6 +5007,7 @@ g.inject([" hello ", " world ", null]).trim(Scope.local) <1> link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#trim()++[`trim()`] link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#trim(org.apache.tinkerpop.gremlin.process.traversal.Scope)++[`trim(Scope)`] +[llms-summary="The unfold()-step (flatMap) unrolls an iterator, iterable, or map in the stream into a linear sequence of objects."] [[unfold-step]] === Unfold Step @@ -4929,6 +5033,7 @@ inject(1,[2,3,[4,5,[6]]]).repeat(unfold()).until(count(local).is(1)).unfold() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#unfold()++[`unfold()`] +[llms-summary="The union()-step (branch) supports the merging of the results of an arbitrary number of traversals."] [[union-step]] === Union Step @@ -4954,6 +5059,7 @@ g.union(V().has('person','name','vadas'), link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#union(org.apache.tinkerpop.gremlin.process.traversal.Traversal...)++[`union(Traversal...)`] +[llms-summary="The until-step is not an actual step, but is instead a step modulator for repeat() (find more documentation on the until() there)."] [[until-step]] === Until Step @@ -4966,6 +5072,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#until(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`until(Traversal)`] anchor:graph-step[] +[llms-summary="The V()-step is meant to read vertices from the graph and is usually used to start a GraphTraversal, but can also be used mid-traversal."] [[v-step]] === V Step @@ -5000,6 +5107,7 @@ g.V().has('name', within('marko', 'vadas', 'josh')).as('person'). link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#V(java.lang.Object...)++[`V(Object...)`] +[llms-summary="The value()-step (map) takes a Property and extracts the value from it."] [[value-step]] === Value Step @@ -5015,6 +5123,7 @@ g.V(1).properties().properties().value() link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#value()++[`value()`] +[llms-summary="The valueMap()-step yields a Map representation of the properties of an element."] [[valuemap-step]] === ValueMap Step @@ -5066,6 +5175,7 @@ g.V().hasLabel('person').properties('location').valueMap().with(WithOptions.toke link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#valueMap(java.lang.String...)++[`valueMap(String...)`] +[llms-summary="The values()-step (map) extracts the values of properties from an Element in the traversal stream."] [[values-step]] === Values Step @@ -5098,6 +5208,7 @@ The order in which property values are returned is not guaranteed. link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#values(java.lang.String...)++[`values(String...)`] +[llms-summary="The vertex steps (out(), in(), both(), outE(), V(), etc.) move between vertices and edges and are fundamental to graph navigation."] [[vertex-steps]] === Vertex Steps @@ -5167,6 +5278,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#outE(java.lang.String...)++[`outE(String...)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#outV()++[`outV()`] +[llms-summary="The where()-step filters the current object based on either the object itself (Scope.local) or the path history of the object (Scope.global) (filter)."] [[where-step]] === Where Step @@ -5236,6 +5348,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#where(org.apache.tinkerpop.gremlin.process.traversal.Traversal)++[`where(Traversal)`], link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`] +[llms-summary="The with()-step is not an actual step, but is instead a \"step modulator\" which modifies the behavior of the step prior to it."] [[with-step]] === With Step @@ -5253,6 +5366,7 @@ The term `with` is a reserved word in Javascript, and therefore must be referred The term `with` is a reserved word in Python, and therefore must be referred to in Gremlin with `with_()`. ==== +[llms-summary="The write()-step is not really a \"step\" but a step modulator in that it modifies the functionality of the io()-step."] [[write-step]] === Write Step diff --git a/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverter.java b/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverter.java index 3d9dae7fb3..82ca4c6fc5 100644 --- a/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverter.java +++ b/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverter.java @@ -54,6 +54,13 @@ public class MarkdownConverter extends StringConverter { */ static final String LLMS_SUMMARY_ATTR = "llms-summary"; + /** + * Section attribute ({@code [llms-explode]}) marking a catalog section whose direct subsections + * should each become their own split page. Emitted as a hidden {@code <!-- llms-explode -->} + * marker for {@link MarkdownSplitter}; never rendered into the page body. + */ + static final String LLMS_EXPLODE_ATTR = "llms-explode"; + public MarkdownConverter(final String backend, final Map<String, Object> opts) { super(backend, opts); } @@ -200,10 +207,26 @@ public class MarkdownConverter extends StringConverter { appendAnchor(sb, section.getId()); sb.append(hashes).append(' ').append(section.getTitle()).append("\n\n"); appendLlmsSummary(sb, section.getAttribute(LLMS_SUMMARY_ATTR)); + appendExplodeMarker(sb, section.getAttribute(LLMS_EXPLODE_ATTR)); sb.append(section.getContent()); return sb.toString(); } + /** + * Emits a hidden {@code <!-- llms-explode -->} marker when a section carries the + * {@code [llms-explode]} attribute. The marker tells {@link MarkdownSplitter} to give each direct + * subsection of this section its own page (rather than size-packing them), which is what turns a + * flat catalog such as the traversal step reference into one page per step. Invisible in rendered + * output, like the summary comment. + */ + private static void appendExplodeMarker(final StringBuilder sb, final Object explode) { + if (explode == null) return; + // Any non-empty/non-"false" value enables it; the bare [llms-explode] form yields "". + final String v = explode.toString().trim(); + if (v.equalsIgnoreCase("false")) return; + sb.append("<!-- llms-explode -->\n\n"); + } + /** Emits {@code <a id="..."></a>} on its own line when the node has a non-empty id. */ private static void appendAnchor(final StringBuilder sb, final String id) { if (id != null && !id.isEmpty()) { diff --git a/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitter.java b/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitter.java index f00f3b94da..4e4e460935 100644 --- a/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitter.java +++ b/docs/tinkeradoc-extension/src/main/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitter.java @@ -59,6 +59,8 @@ class MarkdownSplitter { private static final Pattern HEADING = Pattern.compile("^(#{1,6}) +(.*)$"); // Intra-document links: [label](#anchor). Capture label and anchor separately. private static final Pattern INTRA_LINK = Pattern.compile("\\]\\(#([^)]+)\\)"); + // Marker MarkdownConverter emits from [llms-explode]: split this section's children per-page. + private static final String EXPLODE_MARKER = "<!-- llms-explode -->"; private static final Logger LOG = Logger.getLogger(MarkdownSplitter.class.getName()); @@ -357,6 +359,21 @@ class MarkdownSplitter { private void planChildren(final Node parent, final PageCursor cursor, final List<PagePlan> plans, final Map<String, String> anchorToFile) { for (final Node child : parent.children) { + if (isExplode(child)) { + // Catalog section (e.g. the traversal step reference): give the section's own + // heading/preamble its own page, then put EACH direct subsection on its own page so + // every entry (each step) is individually named and addressable in llms.txt. + final PagePlan page = newPage(child, plans); + page.nodes.add(headOnly(child, page, anchorToFile)); + for (final Node grandchild : child.children) { + final PagePlan gcPage = newPage(grandchild, plans); + placeWhole(grandchild, gcPage, anchorToFile); + } + // Resume packing subsequent siblings on a fresh cursor (the catalog pages are done). + cursor.page = page; + cursor.used = packBudget; // force the next sibling onto its own page/flow + continue; + } if (cursor.used + child.byteSize <= packBudget) { placeWhole(child, cursor.page, anchorToFile); cursor.used += child.byteSize; @@ -388,6 +405,19 @@ class MarkdownSplitter { return page; } + /** + * Whether a node is a catalog section marked for per-child explosion (its own lines contain the + * {@code <!-- llms-explode -->} marker emitted from the {@code [llms-explode]} attribute) and it + * actually has children to explode. + */ + private static boolean isExplode(final Node node) { + if (node.children.isEmpty()) return false; + for (final String line : node.lines) { + if (line.trim().equals(EXPLODE_MARKER)) return true; + } + return false; + } + /** Places a node (and its whole subtree) onto a page, recording all its anchors' home. */ private void placeWhole(final Node node, final PagePlan page, final Map<String, String> anchorToFile) { page.nodes.add(node); diff --git a/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverterProbeTest.java b/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverterProbeTest.java index 0eaf4ce214..1350ab1788 100644 --- a/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverterProbeTest.java +++ b/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownConverterProbeTest.java @@ -107,6 +107,21 @@ public class MarkdownConverterProbeTest { assertThat(md, not(containsString("llms-summary"))); } + @Test + public void llmsExplodeAttributeBecomesHiddenMarkerNotBodyText() { + // [llms-explode] on a catalog section emits a hidden <!-- llms-explode --> marker for the + // splitter, and must not appear as visible body text. + final String md = toMarkdown("= T\n\n[llms-explode=\"\"]\n== Steps\n\nCatalog intro.\n\n=== A Step\n\nBody.\n"); + assertThat(md, containsString("<!-- llms-explode -->")); + assertThat(md, containsString("Catalog intro.")); + } + + @Test + public void noLlmsExplodeMarkerWhenAttributeAbsent() { + final String md = toMarkdown("= T\n\n== Steps\n\nCatalog intro.\n"); + assertThat(md, not(containsString("llms-explode"))); + } + @Test public void emitsExplicitAnchorFromSectionId() { // An explicit AsciiDoc id must surface as an HTML anchor immediately before the heading so diff --git a/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitterTest.java b/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitterTest.java index 0476726672..f5fff5a6f2 100644 --- a/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitterTest.java +++ b/docs/tinkeradoc-extension/src/test/java/org/apache/tinkerpop/tinkeradoc/MarkdownSplitterTest.java @@ -173,6 +173,35 @@ public class MarkdownSplitterTest { assertThat(graphson.getContent(), containsString("[GraphML](index.md#graphml)")); } + @Test + public void explodeMarkerGivesEachChildItsOwnPage() { + // A catalog section marked with <!-- llms-explode --> must split each direct child onto its + // own page (named from the child anchor), regardless of size — even though all children are + // tiny and would otherwise pack onto one page. + final String md = heading("book", 1, "Book") + "\nintro\n\n" + + heading("graph-traversal-steps", 1, "Graph Traversal Steps") + "\n<!-- llms-explode -->\n\ncatalog intro\n\n" + + heading("fold-step", 2, "Fold Step") + "\nThe fold() step.\n\n" + + heading("group-step", 2, "Group Step") + "\nThe group() step.\n\n" + + heading("count-step", 2, "Count Step") + "\nThe count() step.\n"; + final List<MarkdownSplitter.Page> pages = new MarkdownSplitter(50_000).split(md, "index.md"); + final List<String> names = fileNames(pages); + // Each step is its own page, plus the catalog head page. + assertThat(names, hasItem("graph-traversal-steps.md")); + assertThat(names, hasItem("fold-step.md")); + assertThat(names, hasItem("group-step.md")); + assertThat(names, hasItem("count-step.md")); + // The fold page contains only fold, not the others. + final MarkdownSplitter.Page fold = pages.stream() + .filter(p -> p.getFileName().equals("fold-step.md")).findFirst().orElseThrow(AssertionError::new); + assertThat(fold.getContent(), containsString("The fold() step.")); + assertThat(fold.getContent(), not(containsString("The group() step."))); + // The catalog head page keeps its intro but not the steps. + final MarkdownSplitter.Page cat = pages.stream() + .filter(p -> p.getFileName().equals("graph-traversal-steps.md")).findFirst().orElseThrow(AssertionError::new); + assertThat(cat.getContent(), containsString("catalog intro")); + assertThat(cat.getContent(), not(containsString("The fold() step."))); + } + @Test public void hashCommentsInsideCodeFenceAreNotTreatedAsHeadings() { // A code fence containing shell/properties comment lines that begin with '#' must NOT be
