repl-toolkit 1.0.0__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of repl-toolkit might be problematic. Click here for more details.
- {repl_toolkit-1.0.0/repl_toolkit.egg-info → repl_toolkit-1.1.0}/PKG-INFO +107 -1
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/README.md +106 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/pyproject.toml +2 -2
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/__init__.py +21 -8
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/actions/registry.py +1 -1
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/async_repl.py +7 -3
- repl_toolkit-1.1.0/repl_toolkit/formatting.py +151 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/ptypes.py +3 -2
- repl_toolkit-1.1.0/repl_toolkit/tests/test_formatting.py +232 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0/repl_toolkit.egg-info}/PKG-INFO +107 -1
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit.egg-info/SOURCES.txt +2 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/LICENSE +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/actions/__init__.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/actions/action.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/actions/shell.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/headless_repl.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/tests/__init__.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/tests/test_actions.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/tests/test_async_repl.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/tests/test_headless.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit/tests/test_types.py +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit.egg-info/dependency_links.txt +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit.egg-info/requires.txt +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/repl_toolkit.egg-info/top_level.txt +0 -0
- {repl_toolkit-1.0.0 → repl_toolkit-1.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repl-toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: A Python toolkit for building interactive REPL and headless interfaces with action support
|
|
5
5
|
Author-email: REPL Toolkit Contributors <martin.j.bartlett@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -639,3 +639,109 @@ See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
|
|
639
639
|
- Built on [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) for terminal handling
|
|
640
640
|
- Logging by [loguru](https://github.com/Delgan/loguru) for structured logs
|
|
641
641
|
- Inspired by modern CLI tools and REPL interfaces
|
|
642
|
+
|
|
643
|
+
## Formatting Utilities
|
|
644
|
+
|
|
645
|
+
REPL Toolkit includes utilities for automatically detecting and applying formatted text (HTML or ANSI) without needing to explicitly wrap text in format types.
|
|
646
|
+
|
|
647
|
+
### Auto-Format Detection
|
|
648
|
+
|
|
649
|
+
The formatting utilities can automatically detect whether text contains HTML tags, ANSI escape codes, or is plain text:
|
|
650
|
+
|
|
651
|
+
```python
|
|
652
|
+
from repl_toolkit import detect_format_type, auto_format, print_auto_formatted
|
|
653
|
+
|
|
654
|
+
# Detect format type
|
|
655
|
+
detect_format_type("<b>Bold</b>") # Returns: 'html'
|
|
656
|
+
detect_format_type("\x1b[1mBold\x1b[0m") # Returns: 'ansi'
|
|
657
|
+
detect_format_type("Plain text") # Returns: 'plain'
|
|
658
|
+
|
|
659
|
+
# Auto-format and print
|
|
660
|
+
print_auto_formatted("<b>Bold HTML</b>") # Automatically applies HTML formatting
|
|
661
|
+
print_auto_formatted("\x1b[1mBold ANSI\x1b[0m") # Automatically applies ANSI formatting
|
|
662
|
+
print_auto_formatted("Plain text") # Prints as-is
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### Creating Auto-Printers
|
|
666
|
+
|
|
667
|
+
The `create_auto_printer()` function creates a printer that can be used as a drop-in replacement for `print()` with automatic format detection:
|
|
668
|
+
|
|
669
|
+
```python
|
|
670
|
+
from repl_toolkit import create_auto_printer
|
|
671
|
+
|
|
672
|
+
# Create a printer
|
|
673
|
+
printer = create_auto_printer()
|
|
674
|
+
|
|
675
|
+
# Use it like print()
|
|
676
|
+
printer("<b>Bold text</b>") # HTML formatting applied
|
|
677
|
+
printer("\x1b[1mANSI bold\x1b[0m") # ANSI formatting applied
|
|
678
|
+
printer("Plain text") # No formatting
|
|
679
|
+
|
|
680
|
+
# Works with all print() parameters
|
|
681
|
+
printer("<b>Prefix:</b> ", end="", flush=True)
|
|
682
|
+
printer("Hello world\n")
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
### Integration with Callback Handlers
|
|
686
|
+
|
|
687
|
+
The auto-printer is particularly useful for integrating with callback handlers from other libraries:
|
|
688
|
+
|
|
689
|
+
```python
|
|
690
|
+
from repl_toolkit import create_auto_printer
|
|
691
|
+
from some_library import CallbackHandler
|
|
692
|
+
|
|
693
|
+
# Create handler with auto-formatting printer
|
|
694
|
+
handler = CallbackHandler(
|
|
695
|
+
response_prefix="<b><darkcyan>🤖 Assistant:</darkcyan></b> ",
|
|
696
|
+
printer=create_auto_printer() # Automatically formats HTML tags
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
# The response_prefix will be properly formatted without needing
|
|
700
|
+
# to explicitly wrap it in HTML() or ANSI()
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
### Format Detection Rules
|
|
704
|
+
|
|
705
|
+
The auto-detection uses the following rules:
|
|
706
|
+
|
|
707
|
+
1. **ANSI Detection**: Looks for ANSI escape codes (`\x1b[...m`)
|
|
708
|
+
- Pattern: `\x1b\[[0-9;]*m`
|
|
709
|
+
- Examples: `\x1b[1m`, `\x1b[31;1m`
|
|
710
|
+
|
|
711
|
+
2. **HTML Detection**: Looks for HTML-like tags
|
|
712
|
+
- Pattern: `</?[a-zA-Z][a-zA-Z0-9]*\s*/?>`
|
|
713
|
+
- Examples: `<b>`, `</b>`, `<darkcyan>`, `<tag/>`
|
|
714
|
+
- Avoids false positives: `a < b`, `<123>`, `<_tag>`
|
|
715
|
+
|
|
716
|
+
3. **Plain Text**: Everything else
|
|
717
|
+
|
|
718
|
+
### API Reference
|
|
719
|
+
|
|
720
|
+
#### `detect_format_type(text: str) -> str`
|
|
721
|
+
Detect the format type of a text string.
|
|
722
|
+
|
|
723
|
+
**Returns**: `'ansi'`, `'html'`, or `'plain'`
|
|
724
|
+
|
|
725
|
+
#### `auto_format(text: str)`
|
|
726
|
+
Auto-detect format type and return appropriate formatted text object.
|
|
727
|
+
|
|
728
|
+
**Returns**: `HTML`, `ANSI`, or `str` object
|
|
729
|
+
|
|
730
|
+
#### `print_auto_formatted(text: str, **kwargs) -> None`
|
|
731
|
+
Print text with auto-detected formatting.
|
|
732
|
+
|
|
733
|
+
**Parameters**: Same as `print_formatted_text()` from prompt_toolkit
|
|
734
|
+
|
|
735
|
+
#### `create_auto_printer() -> Callable`
|
|
736
|
+
Create a printer function with auto-format detection.
|
|
737
|
+
|
|
738
|
+
**Returns**: Callable with signature `printer(text: str, **kwargs)`
|
|
739
|
+
|
|
740
|
+
### Example
|
|
741
|
+
|
|
742
|
+
See `examples/formatting_demo.py` for a complete demonstration of the formatting utilities.
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
python examples/formatting_demo.py
|
|
746
|
+
```
|
|
747
|
+
|
|
@@ -598,3 +598,109 @@ See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
|
|
598
598
|
- Built on [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) for terminal handling
|
|
599
599
|
- Logging by [loguru](https://github.com/Delgan/loguru) for structured logs
|
|
600
600
|
- Inspired by modern CLI tools and REPL interfaces
|
|
601
|
+
|
|
602
|
+
## Formatting Utilities
|
|
603
|
+
|
|
604
|
+
REPL Toolkit includes utilities for automatically detecting and applying formatted text (HTML or ANSI) without needing to explicitly wrap text in format types.
|
|
605
|
+
|
|
606
|
+
### Auto-Format Detection
|
|
607
|
+
|
|
608
|
+
The formatting utilities can automatically detect whether text contains HTML tags, ANSI escape codes, or is plain text:
|
|
609
|
+
|
|
610
|
+
```python
|
|
611
|
+
from repl_toolkit import detect_format_type, auto_format, print_auto_formatted
|
|
612
|
+
|
|
613
|
+
# Detect format type
|
|
614
|
+
detect_format_type("<b>Bold</b>") # Returns: 'html'
|
|
615
|
+
detect_format_type("\x1b[1mBold\x1b[0m") # Returns: 'ansi'
|
|
616
|
+
detect_format_type("Plain text") # Returns: 'plain'
|
|
617
|
+
|
|
618
|
+
# Auto-format and print
|
|
619
|
+
print_auto_formatted("<b>Bold HTML</b>") # Automatically applies HTML formatting
|
|
620
|
+
print_auto_formatted("\x1b[1mBold ANSI\x1b[0m") # Automatically applies ANSI formatting
|
|
621
|
+
print_auto_formatted("Plain text") # Prints as-is
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Creating Auto-Printers
|
|
625
|
+
|
|
626
|
+
The `create_auto_printer()` function creates a printer that can be used as a drop-in replacement for `print()` with automatic format detection:
|
|
627
|
+
|
|
628
|
+
```python
|
|
629
|
+
from repl_toolkit import create_auto_printer
|
|
630
|
+
|
|
631
|
+
# Create a printer
|
|
632
|
+
printer = create_auto_printer()
|
|
633
|
+
|
|
634
|
+
# Use it like print()
|
|
635
|
+
printer("<b>Bold text</b>") # HTML formatting applied
|
|
636
|
+
printer("\x1b[1mANSI bold\x1b[0m") # ANSI formatting applied
|
|
637
|
+
printer("Plain text") # No formatting
|
|
638
|
+
|
|
639
|
+
# Works with all print() parameters
|
|
640
|
+
printer("<b>Prefix:</b> ", end="", flush=True)
|
|
641
|
+
printer("Hello world\n")
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### Integration with Callback Handlers
|
|
645
|
+
|
|
646
|
+
The auto-printer is particularly useful for integrating with callback handlers from other libraries:
|
|
647
|
+
|
|
648
|
+
```python
|
|
649
|
+
from repl_toolkit import create_auto_printer
|
|
650
|
+
from some_library import CallbackHandler
|
|
651
|
+
|
|
652
|
+
# Create handler with auto-formatting printer
|
|
653
|
+
handler = CallbackHandler(
|
|
654
|
+
response_prefix="<b><darkcyan>🤖 Assistant:</darkcyan></b> ",
|
|
655
|
+
printer=create_auto_printer() # Automatically formats HTML tags
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
# The response_prefix will be properly formatted without needing
|
|
659
|
+
# to explicitly wrap it in HTML() or ANSI()
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Format Detection Rules
|
|
663
|
+
|
|
664
|
+
The auto-detection uses the following rules:
|
|
665
|
+
|
|
666
|
+
1. **ANSI Detection**: Looks for ANSI escape codes (`\x1b[...m`)
|
|
667
|
+
- Pattern: `\x1b\[[0-9;]*m`
|
|
668
|
+
- Examples: `\x1b[1m`, `\x1b[31;1m`
|
|
669
|
+
|
|
670
|
+
2. **HTML Detection**: Looks for HTML-like tags
|
|
671
|
+
- Pattern: `</?[a-zA-Z][a-zA-Z0-9]*\s*/?>`
|
|
672
|
+
- Examples: `<b>`, `</b>`, `<darkcyan>`, `<tag/>`
|
|
673
|
+
- Avoids false positives: `a < b`, `<123>`, `<_tag>`
|
|
674
|
+
|
|
675
|
+
3. **Plain Text**: Everything else
|
|
676
|
+
|
|
677
|
+
### API Reference
|
|
678
|
+
|
|
679
|
+
#### `detect_format_type(text: str) -> str`
|
|
680
|
+
Detect the format type of a text string.
|
|
681
|
+
|
|
682
|
+
**Returns**: `'ansi'`, `'html'`, or `'plain'`
|
|
683
|
+
|
|
684
|
+
#### `auto_format(text: str)`
|
|
685
|
+
Auto-detect format type and return appropriate formatted text object.
|
|
686
|
+
|
|
687
|
+
**Returns**: `HTML`, `ANSI`, or `str` object
|
|
688
|
+
|
|
689
|
+
#### `print_auto_formatted(text: str, **kwargs) -> None`
|
|
690
|
+
Print text with auto-detected formatting.
|
|
691
|
+
|
|
692
|
+
**Parameters**: Same as `print_formatted_text()` from prompt_toolkit
|
|
693
|
+
|
|
694
|
+
#### `create_auto_printer() -> Callable`
|
|
695
|
+
Create a printer function with auto-format detection.
|
|
696
|
+
|
|
697
|
+
**Returns**: Callable with signature `printer(text: str, **kwargs)`
|
|
698
|
+
|
|
699
|
+
### Example
|
|
700
|
+
|
|
701
|
+
See `examples/formatting_demo.py` for a complete demonstration of the formatting utilities.
|
|
702
|
+
|
|
703
|
+
```bash
|
|
704
|
+
python examples/formatting_demo.py
|
|
705
|
+
```
|
|
706
|
+
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "repl-toolkit"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.1.0"
|
|
8
8
|
description = "A Python toolkit for building interactive REPL and headless interfaces with action support"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -100,4 +100,4 @@ warn_redundant_casts = true
|
|
|
100
100
|
warn_unused_ignores = true
|
|
101
101
|
warn_no_return = true
|
|
102
102
|
warn_unreachable = true
|
|
103
|
-
strict_equality = true
|
|
103
|
+
strict_equality = true
|
|
@@ -11,24 +11,25 @@ Key Features:
|
|
|
11
11
|
- Protocol-based architecture for type safety
|
|
12
12
|
- Comprehensive test coverage
|
|
13
13
|
- Async-native design
|
|
14
|
+
- Auto-formatting utilities for HTML and ANSI text
|
|
14
15
|
|
|
15
16
|
Example:
|
|
16
17
|
>>> import asyncio
|
|
17
18
|
>>> from repl_toolkit import run_async_repl, ActionRegistry
|
|
18
|
-
>>>
|
|
19
|
+
>>>
|
|
19
20
|
>>> class MyBackend:
|
|
20
21
|
... async def handle_input(self, user_input: str) -> bool:
|
|
21
22
|
... print(f"You said: {user_input}")
|
|
22
23
|
... return True
|
|
23
|
-
>>>
|
|
24
|
+
>>>
|
|
24
25
|
>>> async def main():
|
|
25
26
|
... backend = MyBackend()
|
|
26
27
|
... await run_async_repl(backend=backend)
|
|
27
|
-
>>>
|
|
28
|
+
>>>
|
|
28
29
|
>>> # asyncio.run(main())
|
|
29
30
|
"""
|
|
30
31
|
|
|
31
|
-
__version__ = "1.
|
|
32
|
+
__version__ = "1.1.0"
|
|
32
33
|
__author__ = "REPL Toolkit Contributors"
|
|
33
34
|
__license__ = "MIT"
|
|
34
35
|
|
|
@@ -37,22 +38,34 @@ from .async_repl import AsyncREPL, run_async_repl
|
|
|
37
38
|
from .headless_repl import run_headless_mode, HeadlessREPL
|
|
38
39
|
from .actions import ActionRegistry, Action, ActionContext, ActionError
|
|
39
40
|
from .ptypes import AsyncBackend, ActionHandler, Completer
|
|
41
|
+
from .formatting import (
|
|
42
|
+
detect_format_type,
|
|
43
|
+
auto_format,
|
|
44
|
+
print_auto_formatted,
|
|
45
|
+
create_auto_printer,
|
|
46
|
+
)
|
|
40
47
|
|
|
41
48
|
__all__ = [
|
|
42
49
|
# Core classes
|
|
43
50
|
"AsyncREPL",
|
|
44
51
|
"HeadlessREPL",
|
|
45
|
-
"ActionRegistry",
|
|
52
|
+
"ActionRegistry",
|
|
46
53
|
"Action",
|
|
47
54
|
"ActionContext",
|
|
48
55
|
"ActionError",
|
|
49
|
-
|
|
56
|
+
|
|
50
57
|
# Convenience functions
|
|
51
58
|
"run_async_repl",
|
|
52
59
|
"run_headless_mode",
|
|
53
|
-
|
|
60
|
+
|
|
54
61
|
# Protocols/Types
|
|
55
62
|
"AsyncBackend",
|
|
56
63
|
"ActionHandler",
|
|
57
64
|
"Completer",
|
|
58
|
-
|
|
65
|
+
|
|
66
|
+
# Formatting utilities
|
|
67
|
+
"detect_format_type",
|
|
68
|
+
"auto_format",
|
|
69
|
+
"print_auto_formatted",
|
|
70
|
+
"create_auto_printer",
|
|
71
|
+
]
|
|
@@ -6,7 +6,7 @@ executing actions that can be triggered through multiple interaction methods.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import importlib
|
|
9
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
9
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
10
10
|
from loguru import logger
|
|
11
11
|
|
|
12
12
|
from .shell import shell_command
|
|
@@ -44,7 +44,8 @@ class AsyncREPL:
|
|
|
44
44
|
action_registry: Optional[ActionHandler] = None,
|
|
45
45
|
completer: Optional[Completer] = None,
|
|
46
46
|
prompt_string: Optional[str] = None,
|
|
47
|
-
history_path: Optional[Path] = None
|
|
47
|
+
history_path: Optional[Path] = None,
|
|
48
|
+
**kwargs,
|
|
48
49
|
):
|
|
49
50
|
"""
|
|
50
51
|
Initialize the async REPL interface.
|
|
@@ -64,10 +65,12 @@ class AsyncREPL:
|
|
|
64
65
|
self.prompt_string = HTML(prompt_string or "User: ")
|
|
65
66
|
self.action_registry = action_registry or ActionRegistry()
|
|
66
67
|
self.session = PromptSession(
|
|
68
|
+
message=self.prompt_string,
|
|
67
69
|
history=self._create_history(history_path),
|
|
68
70
|
key_bindings=self._create_key_bindings(),
|
|
69
71
|
multiline=True,
|
|
70
72
|
completer=completer,
|
|
73
|
+
**kwargs,
|
|
71
74
|
)
|
|
72
75
|
self.main_app = self.session.app
|
|
73
76
|
|
|
@@ -246,7 +249,7 @@ class AsyncREPL:
|
|
|
246
249
|
|
|
247
250
|
while True:
|
|
248
251
|
try:
|
|
249
|
-
user_input = await self.session.prompt_async(
|
|
252
|
+
user_input = await self.session.prompt_async()
|
|
250
253
|
if self._should_exit(user_input):
|
|
251
254
|
break
|
|
252
255
|
if not user_input.strip():
|
|
@@ -344,6 +347,7 @@ async def run_async_repl( # pragma: no cover
|
|
|
344
347
|
initial_message: Optional[str] = None,
|
|
345
348
|
prompt_string: Optional[str] = None,
|
|
346
349
|
history_path: Optional[Path] = None,
|
|
350
|
+
**kwargs,
|
|
347
351
|
):
|
|
348
352
|
"""
|
|
349
353
|
Convenience function to create and run an AsyncREPL with action support.
|
|
@@ -361,7 +365,7 @@ async def run_async_repl( # pragma: no cover
|
|
|
361
365
|
"""
|
|
362
366
|
logger.trace("run_async_repl() entry")
|
|
363
367
|
|
|
364
|
-
repl = AsyncREPL(action_registry, completer, prompt_string, history_path)
|
|
368
|
+
repl = AsyncREPL(action_registry, completer, prompt_string, history_path, **kwargs)
|
|
365
369
|
await repl.run(backend, initial_message)
|
|
366
370
|
|
|
367
371
|
logger.trace("run_async_repl() exit")
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Formatted text utilities for repl_toolkit.
|
|
3
|
+
|
|
4
|
+
This module provides utilities for working with formatted text in prompt_toolkit,
|
|
5
|
+
including auto-detection of format types and smart printing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
from typing import Callable
|
|
10
|
+
from prompt_toolkit import print_formatted_text
|
|
11
|
+
from prompt_toolkit.formatted_text import HTML, ANSI
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Pre-compile regex patterns for performance
|
|
15
|
+
_ANSI_PATTERN = re.compile(r'\x1b\[[0-9;]*m')
|
|
16
|
+
_HTML_PATTERN = re.compile(r'</?[a-zA-Z][a-zA-Z0-9]*\s*/?>')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def detect_format_type(text: str) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Detect the format type of a text string.
|
|
22
|
+
|
|
23
|
+
Detects three format types:
|
|
24
|
+
- 'ansi': Text contains ANSI escape codes (e.g., \\x1b[1m)
|
|
25
|
+
- 'html': Text contains HTML-like tags (e.g., <b>, <darkcyan>)
|
|
26
|
+
- 'plain': Plain text with no special formatting
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
text: Text string to analyze
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Format type: 'ansi', 'html', or 'plain'
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
>>> detect_format_type("<b>Bold</b>")
|
|
36
|
+
'html'
|
|
37
|
+
>>> detect_format_type("\\x1b[1mBold\\x1b[0m")
|
|
38
|
+
'ansi'
|
|
39
|
+
>>> detect_format_type("Plain text")
|
|
40
|
+
'plain'
|
|
41
|
+
>>> detect_format_type("a < b and c > d")
|
|
42
|
+
'plain'
|
|
43
|
+
"""
|
|
44
|
+
# Check for ANSI escape codes (most specific)
|
|
45
|
+
if _ANSI_PATTERN.search(text):
|
|
46
|
+
return 'ansi'
|
|
47
|
+
|
|
48
|
+
# Check for HTML tags
|
|
49
|
+
# Valid HTML tag names: start with letter, contain letters/numbers
|
|
50
|
+
if _HTML_PATTERN.search(text):
|
|
51
|
+
return 'html'
|
|
52
|
+
|
|
53
|
+
# Plain text
|
|
54
|
+
return 'plain'
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def auto_format(text: str):
|
|
58
|
+
"""
|
|
59
|
+
Auto-detect format type and return appropriate formatted text object.
|
|
60
|
+
|
|
61
|
+
This function analyzes the input text and wraps it in the appropriate
|
|
62
|
+
prompt_toolkit formatted text type (HTML, ANSI, or plain string).
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
text: Text string to format
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Formatted text object (HTML, ANSI, or str)
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
>>> auto_format("<b>Bold</b>")
|
|
72
|
+
HTML('<b>Bold</b>')
|
|
73
|
+
>>> auto_format("\\x1b[1mBold\\x1b[0m")
|
|
74
|
+
ANSI('\\x1b[1mBold\\x1b[0m')
|
|
75
|
+
>>> auto_format("Plain text")
|
|
76
|
+
'Plain text'
|
|
77
|
+
"""
|
|
78
|
+
format_type = detect_format_type(text)
|
|
79
|
+
|
|
80
|
+
if format_type == 'ansi':
|
|
81
|
+
return ANSI(text)
|
|
82
|
+
elif format_type == 'html':
|
|
83
|
+
return HTML(text)
|
|
84
|
+
else:
|
|
85
|
+
return text
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def print_auto_formatted(text: str, **kwargs) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Print text with auto-detected formatting.
|
|
91
|
+
|
|
92
|
+
This function automatically detects the format type (HTML, ANSI, or plain)
|
|
93
|
+
and prints the text with appropriate formatting applied.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
text: Text to print (may contain HTML tags, ANSI codes, or be plain)
|
|
97
|
+
**kwargs: Additional arguments passed to print_formatted_text
|
|
98
|
+
(e.g., end, flush, style, output)
|
|
99
|
+
|
|
100
|
+
Examples:
|
|
101
|
+
>>> print_auto_formatted("<b>Bold</b> text")
|
|
102
|
+
Bold text
|
|
103
|
+
>>> print_auto_formatted("\\x1b[1mBold\\x1b[0m text")
|
|
104
|
+
Bold text
|
|
105
|
+
>>> print_auto_formatted("Plain text")
|
|
106
|
+
Plain text
|
|
107
|
+
"""
|
|
108
|
+
formatted = auto_format(text)
|
|
109
|
+
print_formatted_text(formatted, **kwargs)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def create_auto_printer() -> Callable:
|
|
113
|
+
"""
|
|
114
|
+
Create a printer function with auto-format detection.
|
|
115
|
+
|
|
116
|
+
Returns a callable that can be used as a drop-in replacement for print(),
|
|
117
|
+
with automatic detection and application of formatting (HTML or ANSI).
|
|
118
|
+
|
|
119
|
+
This is particularly useful for injecting into callback handlers or other
|
|
120
|
+
components that accept a custom printer function.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Callable printer function with signature: printer(text, **kwargs)
|
|
124
|
+
|
|
125
|
+
Examples:
|
|
126
|
+
>>> printer = create_auto_printer()
|
|
127
|
+
>>> printer("<b>Bold</b>", end="", flush=True)
|
|
128
|
+
Bold
|
|
129
|
+
>>> printer(" text\\n")
|
|
130
|
+
text
|
|
131
|
+
|
|
132
|
+
Usage with callback handlers:
|
|
133
|
+
>>> from some_library import CallbackHandler
|
|
134
|
+
>>> handler = CallbackHandler(
|
|
135
|
+
... response_prefix="<b>Bot:</b> ",
|
|
136
|
+
... printer=create_auto_printer()
|
|
137
|
+
... )
|
|
138
|
+
"""
|
|
139
|
+
def printer(text: str, **kwargs):
|
|
140
|
+
"""Auto-format and print text."""
|
|
141
|
+
print_auto_formatted(text, **kwargs)
|
|
142
|
+
|
|
143
|
+
return printer
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
__all__ = [
|
|
147
|
+
'detect_format_type',
|
|
148
|
+
'auto_format',
|
|
149
|
+
'print_auto_formatted',
|
|
150
|
+
'create_auto_printer',
|
|
151
|
+
]
|
|
@@ -5,9 +5,10 @@ Defines the interface contracts that backends and handlers must implement
|
|
|
5
5
|
for compatibility with the REPL toolkit.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Protocol, runtime_checkable,
|
|
9
|
-
from pathlib import Path
|
|
8
|
+
from typing import Protocol, runtime_checkable, List, TYPE_CHECKING
|
|
10
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .actions.action import ActionContext # Avoid circular import
|
|
11
12
|
|
|
12
13
|
@runtime_checkable
|
|
13
14
|
class AsyncBackend(Protocol):
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for formatting utilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from prompt_toolkit.formatted_text import HTML, ANSI
|
|
7
|
+
|
|
8
|
+
from repl_toolkit.formatting import (
|
|
9
|
+
detect_format_type,
|
|
10
|
+
auto_format,
|
|
11
|
+
print_auto_formatted,
|
|
12
|
+
create_auto_printer,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestDetectFormatType:
|
|
17
|
+
"""Tests for detect_format_type function."""
|
|
18
|
+
|
|
19
|
+
def test_detect_html(self):
|
|
20
|
+
"""Test HTML tag detection."""
|
|
21
|
+
assert detect_format_type("<b>Bold</b>") == "html"
|
|
22
|
+
assert detect_format_type("<darkcyan>Colored</darkcyan>") == "html"
|
|
23
|
+
assert detect_format_type("<b><darkcyan>Nested</darkcyan></b>") == "html"
|
|
24
|
+
assert detect_format_type("<i>Italic</i>") == "html"
|
|
25
|
+
assert detect_format_type("<u>Underline</u>") == "html"
|
|
26
|
+
|
|
27
|
+
def test_detect_html_uppercase(self):
|
|
28
|
+
"""Test HTML detection with uppercase tags."""
|
|
29
|
+
assert detect_format_type("<B>Bold</B>") == "html"
|
|
30
|
+
assert detect_format_type("<TAG>content</TAG>") == "html"
|
|
31
|
+
|
|
32
|
+
def test_detect_html_self_closing(self):
|
|
33
|
+
"""Test HTML self-closing tag detection."""
|
|
34
|
+
assert detect_format_type("<br/>") == "html"
|
|
35
|
+
assert detect_format_type("<tag />") == "html"
|
|
36
|
+
|
|
37
|
+
def test_detect_ansi(self):
|
|
38
|
+
"""Test ANSI escape code detection."""
|
|
39
|
+
assert detect_format_type("\x1b[1mBold\x1b[0m") == "ansi"
|
|
40
|
+
assert detect_format_type("\x1b[31mRed\x1b[0m") == "ansi"
|
|
41
|
+
assert detect_format_type("\x1b[1;32mBold Green\x1b[0m") == "ansi"
|
|
42
|
+
assert detect_format_type("\033[1mBold\033[0m") == "ansi"
|
|
43
|
+
|
|
44
|
+
def test_detect_plain(self):
|
|
45
|
+
"""Test plain text detection."""
|
|
46
|
+
assert detect_format_type("Plain text") == "plain"
|
|
47
|
+
assert detect_format_type("No formatting here") == "plain"
|
|
48
|
+
assert detect_format_type("") == "plain"
|
|
49
|
+
|
|
50
|
+
def test_edge_cases(self):
|
|
51
|
+
"""Test edge cases that should not be detected as HTML."""
|
|
52
|
+
# Comparison operators
|
|
53
|
+
assert detect_format_type("a < b and c > d") == "plain"
|
|
54
|
+
|
|
55
|
+
# Numbers in tag names (invalid HTML)
|
|
56
|
+
assert detect_format_type("<123>content</123>") == "plain"
|
|
57
|
+
|
|
58
|
+
# Hyphens in tag names (invalid HTML)
|
|
59
|
+
assert detect_format_type("<a-b>content</a-b>") == "plain"
|
|
60
|
+
|
|
61
|
+
# Underscore start (invalid HTML)
|
|
62
|
+
assert detect_format_type("<_tag>content</_tag>") == "plain"
|
|
63
|
+
|
|
64
|
+
# Angle brackets but not tags
|
|
65
|
+
assert detect_format_type("Text with <angle brackets> but not tags") == "plain"
|
|
66
|
+
|
|
67
|
+
def test_mixed_content(self):
|
|
68
|
+
"""Test that ANSI takes precedence over HTML."""
|
|
69
|
+
# If text has both ANSI and HTML-like content, ANSI is detected first
|
|
70
|
+
mixed = "\x1b[1m<b>Bold</b>\x1b[0m"
|
|
71
|
+
assert detect_format_type(mixed) == "ansi"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class TestAutoFormat:
|
|
75
|
+
"""Tests for auto_format function."""
|
|
76
|
+
|
|
77
|
+
def test_auto_format_html(self):
|
|
78
|
+
"""Test auto-formatting HTML text."""
|
|
79
|
+
result = auto_format("<b>Bold</b>")
|
|
80
|
+
assert isinstance(result, HTML)
|
|
81
|
+
# HTML objects have the text accessible via their value attribute
|
|
82
|
+
assert result.value == "<b>Bold</b>"
|
|
83
|
+
|
|
84
|
+
def test_auto_format_ansi(self):
|
|
85
|
+
"""Test auto-formatting ANSI text."""
|
|
86
|
+
result = auto_format("\x1b[1mBold\x1b[0m")
|
|
87
|
+
assert isinstance(result, ANSI)
|
|
88
|
+
# ANSI objects have the text accessible via their value attribute
|
|
89
|
+
assert result.value == "\x1b[1mBold\x1b[0m"
|
|
90
|
+
|
|
91
|
+
def test_auto_format_plain(self):
|
|
92
|
+
"""Test auto-formatting plain text."""
|
|
93
|
+
result = auto_format("Plain text")
|
|
94
|
+
assert isinstance(result, str)
|
|
95
|
+
assert result == "Plain text"
|
|
96
|
+
|
|
97
|
+
def test_auto_format_empty(self):
|
|
98
|
+
"""Test auto-formatting empty string."""
|
|
99
|
+
result = auto_format("")
|
|
100
|
+
assert isinstance(result, str)
|
|
101
|
+
assert result == ""
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class TestPrintAutoFormatted:
|
|
105
|
+
"""Tests for print_auto_formatted function."""
|
|
106
|
+
|
|
107
|
+
def test_print_html(self):
|
|
108
|
+
"""Test printing HTML formatted text."""
|
|
109
|
+
# Just verify it doesn't raise an exception
|
|
110
|
+
# We can't easily test the actual output in pytest
|
|
111
|
+
try:
|
|
112
|
+
print_auto_formatted("<b>Bold</b>")
|
|
113
|
+
except Exception as e:
|
|
114
|
+
pytest.fail(f"print_auto_formatted raised {e}")
|
|
115
|
+
|
|
116
|
+
def test_print_plain(self):
|
|
117
|
+
"""Test printing plain text."""
|
|
118
|
+
try:
|
|
119
|
+
print_auto_formatted("Plain text")
|
|
120
|
+
except Exception as e:
|
|
121
|
+
pytest.fail(f"print_auto_formatted raised {e}")
|
|
122
|
+
|
|
123
|
+
def test_print_with_kwargs(self):
|
|
124
|
+
"""Test printing with additional kwargs."""
|
|
125
|
+
try:
|
|
126
|
+
print_auto_formatted("Test", end="", flush=True)
|
|
127
|
+
except Exception as e:
|
|
128
|
+
pytest.fail(f"print_auto_formatted raised {e}")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class TestCreateAutoPrinter:
|
|
132
|
+
"""Tests for create_auto_printer function."""
|
|
133
|
+
|
|
134
|
+
def test_create_printer(self):
|
|
135
|
+
"""Test creating an auto printer."""
|
|
136
|
+
printer = create_auto_printer()
|
|
137
|
+
assert callable(printer)
|
|
138
|
+
|
|
139
|
+
def test_printer_html(self):
|
|
140
|
+
"""Test printer with HTML text."""
|
|
141
|
+
printer = create_auto_printer()
|
|
142
|
+
try:
|
|
143
|
+
printer("<b>Bold</b>")
|
|
144
|
+
except Exception as e:
|
|
145
|
+
pytest.fail(f"printer raised {e}")
|
|
146
|
+
|
|
147
|
+
def test_printer_plain(self):
|
|
148
|
+
"""Test printer with plain text."""
|
|
149
|
+
printer = create_auto_printer()
|
|
150
|
+
try:
|
|
151
|
+
printer("Plain text")
|
|
152
|
+
except Exception as e:
|
|
153
|
+
pytest.fail(f"printer raised {e}")
|
|
154
|
+
|
|
155
|
+
def test_printer_with_kwargs(self):
|
|
156
|
+
"""Test printer with kwargs."""
|
|
157
|
+
printer = create_auto_printer()
|
|
158
|
+
try:
|
|
159
|
+
printer("Test", end="", flush=True)
|
|
160
|
+
except Exception as e:
|
|
161
|
+
pytest.fail(f"printer raised {e}")
|
|
162
|
+
|
|
163
|
+
def test_printer_multiple_calls(self):
|
|
164
|
+
"""Test printer with multiple calls."""
|
|
165
|
+
printer = create_auto_printer()
|
|
166
|
+
try:
|
|
167
|
+
printer("<b>Prefix:</b> ", end="", flush=True)
|
|
168
|
+
printer("Hello", end="", flush=True)
|
|
169
|
+
printer(" world\n")
|
|
170
|
+
except Exception as e:
|
|
171
|
+
pytest.fail(f"printer raised {e}")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class TestIntegration:
|
|
175
|
+
"""Integration tests for formatting utilities."""
|
|
176
|
+
|
|
177
|
+
def test_callback_handler_simulation(self):
|
|
178
|
+
"""Test simulating a callback handler usage."""
|
|
179
|
+
# Simulate ConfigurableCallbackHandler behavior
|
|
180
|
+
printer = create_auto_printer()
|
|
181
|
+
response_prefix = "<b><darkcyan>🤖 Assistant:</darkcyan></b> "
|
|
182
|
+
|
|
183
|
+
try:
|
|
184
|
+
# Print prefix
|
|
185
|
+
printer(response_prefix, end="", flush=True)
|
|
186
|
+
|
|
187
|
+
# Print message parts
|
|
188
|
+
printer("Hello", end="", flush=True)
|
|
189
|
+
printer(" world", end="", flush=True)
|
|
190
|
+
printer("\n")
|
|
191
|
+
except Exception as e:
|
|
192
|
+
pytest.fail(f"callback simulation raised {e}")
|
|
193
|
+
|
|
194
|
+
def test_different_format_types(self):
|
|
195
|
+
"""Test handling different format types in sequence."""
|
|
196
|
+
printer = create_auto_printer()
|
|
197
|
+
|
|
198
|
+
try:
|
|
199
|
+
# HTML
|
|
200
|
+
printer("<b>HTML</b>")
|
|
201
|
+
|
|
202
|
+
# ANSI
|
|
203
|
+
printer("\x1b[1mANSI\x1b[0m")
|
|
204
|
+
|
|
205
|
+
# Plain
|
|
206
|
+
printer("Plain")
|
|
207
|
+
except Exception as e:
|
|
208
|
+
pytest.fail(f"different format types raised {e}")
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class TestDocstrings:
|
|
212
|
+
"""Test that docstrings are present and informative."""
|
|
213
|
+
|
|
214
|
+
def test_detect_format_type_docstring(self):
|
|
215
|
+
"""Test detect_format_type has docstring."""
|
|
216
|
+
assert detect_format_type.__doc__ is not None
|
|
217
|
+
assert "Detect the format type" in detect_format_type.__doc__
|
|
218
|
+
|
|
219
|
+
def test_auto_format_docstring(self):
|
|
220
|
+
"""Test auto_format has docstring."""
|
|
221
|
+
assert auto_format.__doc__ is not None
|
|
222
|
+
assert "Auto-detect format type" in auto_format.__doc__
|
|
223
|
+
|
|
224
|
+
def test_print_auto_formatted_docstring(self):
|
|
225
|
+
"""Test print_auto_formatted has docstring."""
|
|
226
|
+
assert print_auto_formatted.__doc__ is not None
|
|
227
|
+
assert "Print text with auto-detected formatting" in print_auto_formatted.__doc__
|
|
228
|
+
|
|
229
|
+
def test_create_auto_printer_docstring(self):
|
|
230
|
+
"""Test create_auto_printer has docstring."""
|
|
231
|
+
assert create_auto_printer.__doc__ is not None
|
|
232
|
+
assert "Create a printer function" in create_auto_printer.__doc__
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repl-toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: A Python toolkit for building interactive REPL and headless interfaces with action support
|
|
5
5
|
Author-email: REPL Toolkit Contributors <martin.j.bartlett@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -639,3 +639,109 @@ See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
|
|
639
639
|
- Built on [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) for terminal handling
|
|
640
640
|
- Logging by [loguru](https://github.com/Delgan/loguru) for structured logs
|
|
641
641
|
- Inspired by modern CLI tools and REPL interfaces
|
|
642
|
+
|
|
643
|
+
## Formatting Utilities
|
|
644
|
+
|
|
645
|
+
REPL Toolkit includes utilities for automatically detecting and applying formatted text (HTML or ANSI) without needing to explicitly wrap text in format types.
|
|
646
|
+
|
|
647
|
+
### Auto-Format Detection
|
|
648
|
+
|
|
649
|
+
The formatting utilities can automatically detect whether text contains HTML tags, ANSI escape codes, or is plain text:
|
|
650
|
+
|
|
651
|
+
```python
|
|
652
|
+
from repl_toolkit import detect_format_type, auto_format, print_auto_formatted
|
|
653
|
+
|
|
654
|
+
# Detect format type
|
|
655
|
+
detect_format_type("<b>Bold</b>") # Returns: 'html'
|
|
656
|
+
detect_format_type("\x1b[1mBold\x1b[0m") # Returns: 'ansi'
|
|
657
|
+
detect_format_type("Plain text") # Returns: 'plain'
|
|
658
|
+
|
|
659
|
+
# Auto-format and print
|
|
660
|
+
print_auto_formatted("<b>Bold HTML</b>") # Automatically applies HTML formatting
|
|
661
|
+
print_auto_formatted("\x1b[1mBold ANSI\x1b[0m") # Automatically applies ANSI formatting
|
|
662
|
+
print_auto_formatted("Plain text") # Prints as-is
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### Creating Auto-Printers
|
|
666
|
+
|
|
667
|
+
The `create_auto_printer()` function creates a printer that can be used as a drop-in replacement for `print()` with automatic format detection:
|
|
668
|
+
|
|
669
|
+
```python
|
|
670
|
+
from repl_toolkit import create_auto_printer
|
|
671
|
+
|
|
672
|
+
# Create a printer
|
|
673
|
+
printer = create_auto_printer()
|
|
674
|
+
|
|
675
|
+
# Use it like print()
|
|
676
|
+
printer("<b>Bold text</b>") # HTML formatting applied
|
|
677
|
+
printer("\x1b[1mANSI bold\x1b[0m") # ANSI formatting applied
|
|
678
|
+
printer("Plain text") # No formatting
|
|
679
|
+
|
|
680
|
+
# Works with all print() parameters
|
|
681
|
+
printer("<b>Prefix:</b> ", end="", flush=True)
|
|
682
|
+
printer("Hello world\n")
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
### Integration with Callback Handlers
|
|
686
|
+
|
|
687
|
+
The auto-printer is particularly useful for integrating with callback handlers from other libraries:
|
|
688
|
+
|
|
689
|
+
```python
|
|
690
|
+
from repl_toolkit import create_auto_printer
|
|
691
|
+
from some_library import CallbackHandler
|
|
692
|
+
|
|
693
|
+
# Create handler with auto-formatting printer
|
|
694
|
+
handler = CallbackHandler(
|
|
695
|
+
response_prefix="<b><darkcyan>🤖 Assistant:</darkcyan></b> ",
|
|
696
|
+
printer=create_auto_printer() # Automatically formats HTML tags
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
# The response_prefix will be properly formatted without needing
|
|
700
|
+
# to explicitly wrap it in HTML() or ANSI()
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
### Format Detection Rules
|
|
704
|
+
|
|
705
|
+
The auto-detection uses the following rules:
|
|
706
|
+
|
|
707
|
+
1. **ANSI Detection**: Looks for ANSI escape codes (`\x1b[...m`)
|
|
708
|
+
- Pattern: `\x1b\[[0-9;]*m`
|
|
709
|
+
- Examples: `\x1b[1m`, `\x1b[31;1m`
|
|
710
|
+
|
|
711
|
+
2. **HTML Detection**: Looks for HTML-like tags
|
|
712
|
+
- Pattern: `</?[a-zA-Z][a-zA-Z0-9]*\s*/?>`
|
|
713
|
+
- Examples: `<b>`, `</b>`, `<darkcyan>`, `<tag/>`
|
|
714
|
+
- Avoids false positives: `a < b`, `<123>`, `<_tag>`
|
|
715
|
+
|
|
716
|
+
3. **Plain Text**: Everything else
|
|
717
|
+
|
|
718
|
+
### API Reference
|
|
719
|
+
|
|
720
|
+
#### `detect_format_type(text: str) -> str`
|
|
721
|
+
Detect the format type of a text string.
|
|
722
|
+
|
|
723
|
+
**Returns**: `'ansi'`, `'html'`, or `'plain'`
|
|
724
|
+
|
|
725
|
+
#### `auto_format(text: str)`
|
|
726
|
+
Auto-detect format type and return appropriate formatted text object.
|
|
727
|
+
|
|
728
|
+
**Returns**: `HTML`, `ANSI`, or `str` object
|
|
729
|
+
|
|
730
|
+
#### `print_auto_formatted(text: str, **kwargs) -> None`
|
|
731
|
+
Print text with auto-detected formatting.
|
|
732
|
+
|
|
733
|
+
**Parameters**: Same as `print_formatted_text()` from prompt_toolkit
|
|
734
|
+
|
|
735
|
+
#### `create_auto_printer() -> Callable`
|
|
736
|
+
Create a printer function with auto-format detection.
|
|
737
|
+
|
|
738
|
+
**Returns**: Callable with signature `printer(text: str, **kwargs)`
|
|
739
|
+
|
|
740
|
+
### Example
|
|
741
|
+
|
|
742
|
+
See `examples/formatting_demo.py` for a complete demonstration of the formatting utilities.
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
python examples/formatting_demo.py
|
|
746
|
+
```
|
|
747
|
+
|
|
@@ -3,6 +3,7 @@ README.md
|
|
|
3
3
|
pyproject.toml
|
|
4
4
|
repl_toolkit/__init__.py
|
|
5
5
|
repl_toolkit/async_repl.py
|
|
6
|
+
repl_toolkit/formatting.py
|
|
6
7
|
repl_toolkit/headless_repl.py
|
|
7
8
|
repl_toolkit/ptypes.py
|
|
8
9
|
repl_toolkit.egg-info/PKG-INFO
|
|
@@ -17,5 +18,6 @@ repl_toolkit/actions/shell.py
|
|
|
17
18
|
repl_toolkit/tests/__init__.py
|
|
18
19
|
repl_toolkit/tests/test_actions.py
|
|
19
20
|
repl_toolkit/tests/test_async_repl.py
|
|
21
|
+
repl_toolkit/tests/test_formatting.py
|
|
20
22
|
repl_toolkit/tests/test_headless.py
|
|
21
23
|
repl_toolkit/tests/test_types.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|