pub fn split_text_chunks(text: &str, max_chars: usize) -> Vec<String>Expand description
Splits text into chunks of at most max_chars chars, on paragraph
boundaries wherever packing allows, and never inside a fenced code
block.
The contract, in the order it matters:
- Round trip. The concatenation of the returned chunks is
textbyte-for-byte, always. Separators travel with blocks: a paragraph or fenced block keeps the blank-line run that follows it, and a blank run at the very start of the document rides in front of the first chunk’s content whenever the two fit one chunk together (a run that cannot stands alone as a whitespace-only chunk —TextModelChunkedExt::complete_chunkednever asks the model about one).\r\ninput round-trips too — the split works on byte offsets, and a\r\nblank line counts as blank. - The bound. Every chunk is at most
max_charschars (characters, not bytes), with exactly one exception: a single fenced code block longer thanmax_charsis one oversized chunk, because chunks are never split inside a fence. - Paragraph preference. Boundaries fall on blank-line runs whenever packing allows, so a chunk is a whole number of paragraphs and blocks. (The blank-line runs themselves are packing items: a run that no longer fits a chunk starts the next one, still never inside a paragraph.)
- Fences. A line whose leading-whitespace-stripped form starts with three or more backticks or tildes opens a fence; it closes at a line whose trimmed form is a run of the same marker at least as long, with no info string. A blank line inside a fence stays inside it, an unclosed fence runs to the end of the input as one (possibly oversized) chunk, and a four-backtick fence does not close at an inner three-backtick line. Indented (four-space) code blocks are not fence-tracked: they are ordinary lines and may split at line boundaries.
- Fallbacks. A plain block longer than
max_charssplits at line boundaries, greedily packing whole lines; a single line longer than the bound is hard-cut everymax_charschars, always on a char boundary — multibyte input never splits mid-character.
Empty input returns an empty Vec; whitespace-only input is a single
chunk holding it, however long — there is nothing in it to model.
§Panics
Panics if max_chars is zero: a zero-char chunk cannot hold anything.
§Examples
use cratefield_core::{reassemble_text_chunks, split_text_chunks};
let text = "first paragraph\n\nsecond paragraph";
let chunks = split_text_chunks(text, 20);
assert_eq!(chunks, vec!["first paragraph\n\n", "second paragraph"]);
assert_eq!(reassemble_text_chunks(&chunks), text);