markrender 1.0.6__tar.gz → 1.0.7__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.
Files changed (38) hide show
  1. {markrender-1.0.6/markrender.egg-info → markrender-1.0.7}/PKG-INFO +6 -2
  2. {markrender-1.0.6 → markrender-1.0.7}/README.md +5 -1
  3. {markrender-1.0.6 → markrender-1.0.7}/markrender/cli.py +25 -9
  4. {markrender-1.0.6 → markrender-1.0.7}/markrender/colors.py +36 -0
  5. {markrender-1.0.6 → markrender-1.0.7}/markrender/config.py +33 -0
  6. {markrender-1.0.6 → markrender-1.0.7}/markrender/formatters.py +314 -95
  7. {markrender-1.0.6 → markrender-1.0.7}/markrender/parser.py +10 -9
  8. {markrender-1.0.6 → markrender-1.0.7}/markrender/renderer.py +106 -76
  9. {markrender-1.0.6 → markrender-1.0.7/markrender.egg-info}/PKG-INFO +6 -2
  10. {markrender-1.0.6 → markrender-1.0.7}/markrender.egg-info/SOURCES.txt +1 -11
  11. {markrender-1.0.6 → markrender-1.0.7}/pyproject.toml +1 -1
  12. {markrender-1.0.6 → markrender-1.0.7}/tests/test_enhancements.py +6 -10
  13. {markrender-1.0.6 → markrender-1.0.7}/tests/test_parser.py +3 -3
  14. markrender-1.0.6/.gitignore +0 -66
  15. markrender-1.0.6/check_truecolor.py +0 -30
  16. markrender-1.0.6/examples/basic_usage.py +0 -76
  17. markrender-1.0.6/examples/streaming_demo.py +0 -134
  18. markrender-1.0.6/examples/theme_showcase.py +0 -60
  19. markrender-1.0.6/tests/__init__.py +0 -1
  20. markrender-1.0.6/tests/reproduce_code_block_colors.py +0 -73
  21. markrender-1.0.6/tests/reproduce_colors.py +0 -130
  22. markrender-1.0.6/tests/reproduce_failures.py +0 -40
  23. markrender-1.0.6/tests/verify_fixes.py +0 -69
  24. {markrender-1.0.6 → markrender-1.0.7}/LICENSE +0 -0
  25. {markrender-1.0.6 → markrender-1.0.7}/markrender/__init__.py +0 -0
  26. {markrender-1.0.6 → markrender-1.0.7}/markrender/themes.py +0 -0
  27. {markrender-1.0.6 → markrender-1.0.7}/markrender.egg-info/dependency_links.txt +0 -0
  28. {markrender-1.0.6 → markrender-1.0.7}/markrender.egg-info/entry_points.txt +0 -0
  29. {markrender-1.0.6 → markrender-1.0.7}/markrender.egg-info/requires.txt +0 -0
  30. {markrender-1.0.6 → markrender-1.0.7}/markrender.egg-info/top_level.txt +0 -0
  31. {markrender-1.0.6 → markrender-1.0.7}/setup.cfg +0 -0
  32. {markrender-1.0.6 → markrender-1.0.7}/tests/test_emoji_note.py +0 -0
  33. {markrender-1.0.6 → markrender-1.0.7}/tests/test_formatters.py +0 -0
  34. {markrender-1.0.6 → markrender-1.0.7}/tests/test_inline_formatting_contexts.py +0 -0
  35. {markrender-1.0.6 → markrender-1.0.7}/tests/test_new_features.py +0 -0
  36. {markrender-1.0.6 → markrender-1.0.7}/tests/test_renderer.py +0 -0
  37. {markrender-1.0.6 → markrender-1.0.7}/tests/test_renderer_edge_cases.py +0 -0
  38. {markrender-1.0.6 → markrender-1.0.7}/tests/test_v1_0_5_features.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markrender
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Professional terminal markdown renderer for streaming LLM responses
5
5
  Author: Praneeth Gandodi
6
6
  License-Expression: MIT
@@ -40,8 +40,12 @@ MarkRender is a Python library for rendering Markdown in the terminal. It is des
40
40
  - **Streaming Support**: MarkRender can process and render Markdown content as it arrives, providing a smooth and responsive experience for dynamic content.
41
41
  - **Syntax Highlighting**: Code blocks are highlighted using the powerful Pygments library, supporting a wide range of languages.
42
42
  - **Theming**: Choose from a variety of built-in themes to customize the appearance of your rendered output.
43
- - **Table Rendering**: Tables are rendered with proper formatting and alignment, powered by the `rich` library.
43
+ - **Table Rendering**: Tables are rendered with proper formatting, automatic alignment, and terminal-width awareness, powered by the `rich` library.
44
44
  - **Advanced Markdown Support**: Highlights, footnotes, definition lists, progress bars, nested lists, and image placeholders.
45
+ - **Terminal Capabilities Detection**: Automatic detection of TrueColor support with graceful fallback for older terminals.
46
+ - **Dim Mode (Thinking Mode)**: A specialized mode for rendering background thoughts or LLM processes with reduced visual prominence.
47
+ - **File Tree Rendering**: Visualize directory structures with the `tree` or `file-tree` code blocks.
48
+ - **OSC 8 Hyperlinks**: Clickable hyperlinks in supported modern terminals.
45
49
  - **CLI Interface**: Render markdown files directly from the command line.
46
50
  - **Configuration**: Support for TOML configuration files.
47
51
  - **Cross-Platform**: Works on Windows, macOS, and Linux.
@@ -7,8 +7,12 @@ MarkRender is a Python library for rendering Markdown in the terminal. It is des
7
7
  - **Streaming Support**: MarkRender can process and render Markdown content as it arrives, providing a smooth and responsive experience for dynamic content.
8
8
  - **Syntax Highlighting**: Code blocks are highlighted using the powerful Pygments library, supporting a wide range of languages.
9
9
  - **Theming**: Choose from a variety of built-in themes to customize the appearance of your rendered output.
10
- - **Table Rendering**: Tables are rendered with proper formatting and alignment, powered by the `rich` library.
10
+ - **Table Rendering**: Tables are rendered with proper formatting, automatic alignment, and terminal-width awareness, powered by the `rich` library.
11
11
  - **Advanced Markdown Support**: Highlights, footnotes, definition lists, progress bars, nested lists, and image placeholders.
12
+ - **Terminal Capabilities Detection**: Automatic detection of TrueColor support with graceful fallback for older terminals.
13
+ - **Dim Mode (Thinking Mode)**: A specialized mode for rendering background thoughts or LLM processes with reduced visual prominence.
14
+ - **File Tree Rendering**: Visualize directory structures with the `tree` or `file-tree` code blocks.
15
+ - **OSC 8 Hyperlinks**: Clickable hyperlinks in supported modern terminals.
12
16
  - **CLI Interface**: Render markdown files directly from the command line.
13
17
  - **Configuration**: Support for TOML configuration files.
14
18
  - **Cross-Platform**: Works on Windows, macOS, and Linux.
@@ -78,8 +78,7 @@ Examples:
78
78
  parser.add_argument(
79
79
  'file',
80
80
  nargs='?',
81
- type=argparse.FileType('r', encoding='utf-8'),
82
- default=sys.stdin,
81
+ default=None,
83
82
  help='Markdown file to render (default: stdin)'
84
83
  )
85
84
 
@@ -136,7 +135,7 @@ Examples:
136
135
  parser.add_argument(
137
136
  '-v', '--version',
138
137
  action='version',
139
- version='%(prog)s 1.0.6'
138
+ version='%(prog)s 1.0.7'
140
139
  )
141
140
 
142
141
  args = parser.parse_args()
@@ -164,8 +163,27 @@ Examples:
164
163
  stream_code=not args.no_stream_code
165
164
  )
166
165
 
167
- # Read and render input
168
- content = args.file.read()
166
+ # Read input content
167
+ if args.file is None:
168
+ content = sys.stdin.read()
169
+ else:
170
+ file_path = Path(args.file)
171
+ if not file_path.exists():
172
+ print(f"Error: File not found: {file_path}", file=sys.stderr)
173
+ return 1
174
+
175
+ try:
176
+ # Try reading as UTF-8
177
+ content = file_path.read_text(encoding='utf-8')
178
+ except UnicodeDecodeError:
179
+ # Try reading with latin-1 as fallback if it's not binary
180
+ try:
181
+ content = file_path.read_text(encoding='latin-1')
182
+ print(f"Warning: File {file_path} is not UTF-8 encoded. Using latin-1 fallback.", file=sys.stderr)
183
+ except Exception:
184
+ print(f"Error: Could not read file {file_path}. It might be a binary file.", file=sys.stderr)
185
+ return 1
186
+
169
187
  renderer.render(content)
170
188
  renderer.finalize()
171
189
 
@@ -181,12 +199,10 @@ Examples:
181
199
  print("\nInterrupted", file=sys.stderr)
182
200
  return 130
183
201
  except Exception as e:
202
+ import traceback
203
+ # print(traceback.format_exc()) # For debugging
184
204
  print(f"Error: {e}", file=sys.stderr)
185
205
  return 1
186
- finally:
187
- # Close file if not stdin
188
- if args.file is not sys.stdin:
189
- args.file.close()
190
206
 
191
207
 
192
208
  if __name__ == '__main__':
@@ -9,6 +9,42 @@ import colorama
9
9
 
10
10
  colorama.init()
11
11
 
12
+ def supports_truecolor():
13
+ """
14
+ Check if the terminal supports TrueColor (24-bit).
15
+ """
16
+ if os.environ.get('COLORTERM') in ('truecolor', '24bit'):
17
+ return True
18
+
19
+ # Check TERM for common truecolor terminals
20
+ term = os.environ.get('TERM', '')
21
+ if any(x in term for x in ('iterm', 'iterm2', 'alacritty', 'kitty', 'konsole')):
22
+ return True
23
+
24
+ # VS Code terminal
25
+ if os.environ.get('TERM_PROGRAM') == 'vscode':
26
+ return True
27
+
28
+ return False
29
+
30
+ def get_color_system():
31
+ """
32
+ Determine the supported color system.
33
+ Returns: "truecolor", "256", "standard" (16), or None (no color)
34
+ """
35
+ if not sys.stdout.isatty() and not os.environ.get('FORCE_COLOR'):
36
+ return None
37
+
38
+ if supports_truecolor():
39
+ return "truecolor"
40
+
41
+ # Check for 256 color support
42
+ term = os.environ.get('TERM', '')
43
+ if '256color' in term:
44
+ return "256"
45
+
46
+ return "standard"
47
+
12
48
  # Define common rich styles based on ANSI codes
13
49
  # Rich understands these string representations directly
14
50
  RICH_STYLES = {
@@ -25,9 +25,42 @@ DEFAULT_CONFIG = {
25
25
  'width': None,
26
26
  'force_color': False,
27
27
  'stream_code': True,
28
+ 'inline_code_color': None,
29
+ 'dim_mode': False,
28
30
  }
29
31
 
30
32
 
33
+ class RendererConfig:
34
+ """
35
+ Configuration for MarkdownRenderer.
36
+ Encapsulates all rendering settings.
37
+ """
38
+ def __init__(self, **kwargs):
39
+ # Start with defaults
40
+ self.config = DEFAULT_CONFIG.copy()
41
+
42
+ # Merge with provided kwargs
43
+ for key, value in kwargs.items():
44
+ if key in self.config:
45
+ self.config[key] = value
46
+ elif hasattr(self, key):
47
+ setattr(self, key, value)
48
+
49
+ @classmethod
50
+ def from_file(cls, config_path: Optional[Path] = None):
51
+ """Create config from a file"""
52
+ file_config = load_config(config_path)
53
+ return cls(**file_config)
54
+
55
+ def get(self, key, default=None):
56
+ return self.config.get(key, default)
57
+
58
+ def __getattr__(self, name):
59
+ if name in self.config:
60
+ return self.config[name]
61
+ raise AttributeError(f"'RendererConfig' object has no attribute '{name}'")
62
+
63
+
31
64
  def find_config_file() -> Optional[Path]:
32
65
  """
33
66
  Find configuration file in standard locations.