feat(indexing): parse Markdown front matter with SnakeYAML, split multi-record files, and accept documents array - #207
Open
adityamparikh wants to merge 3 commits into
Conversation
adityamparikh
force-pushed
the
feat/markdown-multi-record
branch
2 times, most recently
from
September 14, 2026 19:36
3c4f880 to
ea17141
Compare
adityamparikh
force-pushed
the
feat/markdown-multi-record
branch
from
September 16, 2026 16:36
ea17141 to
ea392ec
Compare
This was referenced Sep 23, 2026
The front matter is YAML, but its values came from the commonmark extension's line-by-line reader plus a hand-rolled splitter for flow sequences, so a quoted title containing a comma or a colon, a quoted list element, or a nested mapping came out wrong. The block is now sliced out verbatim via commonmark's source spans and handed to SnakeYAML, which is already on the classpath through Spring Boot. Implicit type resolution is switched off so every scalar stays the text as written, exactly as before; Solr's schema guessing types it. The flow-sequence splitter is gone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CiUHyyXLTo9ATdgg8eRFZJ Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
Markdown had no way to carry a dataset: create() always returned a single document, so a 61-show sample dataset would have needed 61 files. A file may now hold several records, each its own YAML front matter block followed by its body, and the dataset ships as one shows-markdown.md. Markdown has no record separator of its own, and `---` already means two other things -- a thematic break and a setext heading underline. Naive concatenation fails twice over: commonmark only recognises front matter at position 0, so later blocks become body text, and a mid-file `---` promotes the preceding paragraph into a heading. Splitting is therefore narrow: the file must itself open with front matter, a boundary is a `---` line preceded by a blank line and followed by a YAML key, and that block must be closed by a later `---`. Anything that is not unambiguously several records still yields exactly one document, so the eleven MarkdownIndexingTest cases asserting hasSize(1) pass unedited. ShowsSampleDataTest checks the 61 documents parsed from that one file against shows.json, field for field. The -H:IncludeResources arg sits on the nativeTest binary, which is the one that reads the fixture; nativeImageBuildArgs feeds the shipped binary and the published images, which never load a test resource. Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com> Co-authored-by: Junie <junie@jetbrains.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019qWfXJUJ7TU3HJgtNZZq2E
Accept documents as an array of Markdown strings (one per document) instead of a single Markdown string, avoiding multiple tool-call round trips from LLM clients and aligning with index-json-documents. Each array element is parsed for YAML front matter metadata, title, headings, and body content. Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com> Co-authored-by: Junie <junie@jetbrains.com>
adityamparikh
force-pushed
the
feat/markdown-multi-record
branch
from
September 24, 2026 14:43
ea392ec to
2f81f66
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three changes to Markdown indexing. Supersedes #203 and #206.
Front matter is parsed by a YAML parser. Front matter is YAML, but its values did not come from a YAML parser: the commonmark front-matter extension reads the block line by line, and
MarkdownDocumentCreatoradded a hand-rolled splitter for flow sequences ([a, b]). A quoted title containing a comma or a colon, a quoted list element, or a nested mapping came out wrong or was lost. The block is now sliced out verbatim using commonmark's source spans and handed to SnakeYAML, which Spring Boot already ships. Implicit type resolution is switched off, so every scalar stays the text as written (2026-01-01is not turned into a Date,8.4not into a Double); Solr's schema guessing types it. Sequences become multi-valued fields, nested mappings flatten with underscores (ratings_imdb), nulls are skipped. The flow-sequence splitter is deleted.One file can hold many documents.
create()always returned a single document, so a 61-show sample dataset would have needed 61 separate files. A file may now hold several records, each its own front matter block followed by its body, and the dataset ships as oneshows-markdown.md.Batching via documents array parameter. Incorporates #203 to align with
index-json-documents(#202).index-markdown-documentsacceptsdocuments: List<String>, allowing clients to pass multiple documents in a single tool call rather than initiating dozens of separate tool-call round trips.Why the split rule is narrow
Markdown has no record separator of its own, and
---already means two other things — a thematic break, and a setext heading underline. Naive concatenation fails twice over: commonmark only recognises front matter at position 0, so later blocks become body text, and a mid-file---promotes the preceding paragraph into a heading.Splitting therefore engages only when all of the following hold:
---line preceded by a blank line and followed by a YAML key — a rule followed by prose is not a boundary;---— an unterminated block is not a boundary.Anything that is not unambiguously several records still yields exactly one document. The residual ambiguity is documented on
splitRecords: a document that both opens with front matter and uses a thematic break immediately followed by akey: valueline will split when it should not.What changed
MarkdownDocumentCreator: parser built withincludeSourceSpans(BLOCKS);addFrontMatterFieldsloads the block with SnakeYAML'sSafeConstructorand a resolver with no implicit tags.create()splits into records and maps each through the existing per-document logic, extracted ascreateOne(); addssplitRecords()/isRecordStart().IndexingService:indexMarkdownDocumentssignature acceptsList<String> documentsand indexes all documents in one call.build.gradle.kts:-H:IncludeResourcesforshows-markdown.mdon thenativeTestbinary, which is the one that reads the fixture. It is deliberately not innativeImageBuildArgs, which feeds the shipped binary and the published*-native-*images — those never load a test resource.README.md& tests: updated tool description and tests for the array parameter.Tests
New
MarkdownDocumentCreatorTestcovers the YAML cases (quoted scalars with delimiters, flow and block sequences, nested mappings, typed-looking scalars kept as text, invalid YAML) and the split cases;ShowsSampleDataTestparsesshows-markdown.mdand checks its 61 documents againstshows.jsonfield for field.IndexingServiceTestcovers theList<String> documentsarray input and null handling. The regression guard on the split rule is that the elevenMarkdownIndexingTestcases assertinghasSize(1)pass unedited — if the rule were even slightly too eager, several would go red../gradlew spotlessApply buildon Java 25 passes.