Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/tool-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ MCP imports. Examples below show Python arguments; MCP uses the same parameter n

`analyze_text("Hi hi!")` returns `characters=6`, `words=2`, `lines=1`,
`sentences=1`, and `frequent_words=[{"word": "hi", "count": 2}]`.
Characters include whitespace. Words are Unicode letter/digit sequences with
Characters include
whitespace; `characters_without_whitespace` counts every character for which
`str.isspace()` is false, so punctuation and digits still count. Words are Unicode letter/digit
sequences with
optional internal apostrophes; underscores separate words. Frequency is case-insensitive,
with ties ordered by first appearance. Lines follow `str.splitlines()`:
empty input has zero lines and a final newline does not add an extra line.
Expand Down
5 changes: 5 additions & 0 deletions src/mcp_tools_lab/tools/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ def analyze_text(text: str) -> dict:

Words are letter/digit sequences (apostrophes within words are kept).
Sentences are nonempty pieces separated by '.', '!', or '?'.
Characters exclude anything str.isspace() recognizes when counting
characters_without_whitespace.
This is a simple heuristic, not linguistic analysis.
"""
words = re.findall(r"[^\W_]+(?:['’][^\W_]+)*", text.lower())
return {
"characters": len(text),
"characters_without_whitespace": sum(
not character.isspace() for character in text
),
"words": len(words),
"lines": len(text.splitlines()),
"sentences": sum(bool(part.strip()) for part in re.split(r"[.!?]+", text)),
Expand Down
23 changes: 22 additions & 1 deletion tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@


def test_empty_text():
assert analyze_text("") == {"characters": 0, "words": 0, "lines": 0,
assert analyze_text("") == {"characters": 0,
"characters_without_whitespace": 0,
"words": 0, "lines": 0,
"sentences": 0, "frequent_words": []}


Expand All @@ -18,3 +20,22 @@ def test_unicode_and_trailing_newline():
result = analyze_text("café café\n")
assert result["words"] == 2
assert result["lines"] == 1


def test_characters_without_whitespace():
result = analyze_text("Hi there!\n")
assert result["characters"] == 10
assert result["characters_without_whitespace"] == 8


def test_characters_without_whitespace_keeps_punctuation_and_digits():
result = analyze_text("a, 1\tb")
assert result["characters"] == 6
assert result["characters_without_whitespace"] == 4


def test_characters_without_whitespace_whitespace_only():
result = analyze_text(" \t\r\n\u00a0")
assert result["characters"] == 5
assert result["characters_without_whitespace"] == 0
assert result["words"] == 0
Loading