mdsyntax 0.1.0__py3-none-any.whl

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.
mdsyntax/__init__.py ADDED
@@ -0,0 +1,26 @@
1
+ """
2
+ mdsyntax: Render markdown with syntax highlighting in the terminal.
3
+
4
+ Usage:
5
+ >>> from mdsyntax import md_print, md_render
6
+ >>> md_print("# Hello **world**")
7
+ >>> output = md_render("Some `code` here")
8
+ """
9
+
10
+ from mdsyntax.renderer import (
11
+ LANG_ALIASES,
12
+ MarkdownRenderer,
13
+ SyntaxHighlighter,
14
+ md_print,
15
+ md_render,
16
+ )
17
+
18
+ __version__ = "0.1.0"
19
+ __all__ = [
20
+ "md_print",
21
+ "md_render",
22
+ "MarkdownRenderer",
23
+ "SyntaxHighlighter",
24
+ "LANG_ALIASES",
25
+ "__version__",
26
+ ]
mdsyntax/cli.py ADDED
@@ -0,0 +1,82 @@
1
+ """Command-line interface for md-print."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+
8
+ from mdsyntax import __version__, md_print
9
+ from mdsyntax.renderer import SyntaxHighlighter
10
+
11
+
12
+ def main(argv: list[str] | None = None) -> int:
13
+ """Main CLI entry point."""
14
+ parser = argparse.ArgumentParser(
15
+ prog="mdsyntax",
16
+ description="Render markdown with syntax highlighting in the terminal.",
17
+ )
18
+ parser.add_argument(
19
+ "file",
20
+ nargs="?",
21
+ type=argparse.FileType("r"),
22
+ default=sys.stdin,
23
+ help="Markdown file to render (default: stdin)",
24
+ )
25
+ parser.add_argument(
26
+ "-s",
27
+ "--style",
28
+ default="monokai",
29
+ metavar="STYLE",
30
+ help="Pygments style for code blocks (default: monokai)",
31
+ )
32
+ parser.add_argument(
33
+ "-w",
34
+ "--width",
35
+ type=int,
36
+ default=None,
37
+ metavar="N",
38
+ help="Width for code blocks (default: terminal width)",
39
+ )
40
+ parser.add_argument(
41
+ "--no-true-color",
42
+ action="store_true",
43
+ help="Disable 24-bit true color (use 256 colors)",
44
+ )
45
+ parser.add_argument(
46
+ "--list-styles",
47
+ action="store_true",
48
+ help="List available syntax highlighting styles and exit",
49
+ )
50
+ parser.add_argument(
51
+ "-V",
52
+ "--version",
53
+ action="version",
54
+ version=f"%(prog)s {__version__}",
55
+ )
56
+
57
+ args = parser.parse_args(argv)
58
+
59
+ if args.list_styles:
60
+ print("Available styles:")
61
+ for style in sorted(SyntaxHighlighter.available_styles()):
62
+ print(f" {style}")
63
+ return 0
64
+
65
+ text = args.file.read()
66
+ if args.file is not sys.stdin:
67
+ args.file.close()
68
+
69
+ true_color = None if not args.no_true_color else False
70
+
71
+ md_print(
72
+ text,
73
+ code_style=args.style,
74
+ code_width=args.width,
75
+ true_color=true_color,
76
+ )
77
+
78
+ return 0
79
+
80
+
81
+ if __name__ == "__main__":
82
+ sys.exit(main())
mdsyntax/py.typed ADDED
File without changes
mdsyntax/renderer.py ADDED
@@ -0,0 +1,368 @@
1
+ """
2
+ Terminal markdown renderer with syntax highlighting.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import os
8
+ import re
9
+ import shutil
10
+ from collections.abc import Iterator
11
+ from dataclasses import dataclass, field
12
+
13
+ from colorama import Back, Fore, Style, init
14
+ from pygments import highlight
15
+ from pygments.formatters import Terminal256Formatter, TerminalTrueColorFormatter
16
+ from pygments.lexers import TextLexer, get_lexer_by_name, guess_lexer
17
+ from pygments.styles import get_all_styles, get_style_by_name
18
+
19
+ init(autoreset=True)
20
+
21
+
22
+ class Ansi:
23
+ """ANSI escape codes not exposed by colorama."""
24
+
25
+ ITALIC = "\033[3m"
26
+ ITALIC_OFF = "\033[23m"
27
+ UNDERLINE = "\033[4m"
28
+ UNDERLINE_OFF = "\033[24m"
29
+ DIM = "\033[2m"
30
+ DIM_OFF = "\033[22m"
31
+ STRIKETHROUGH = "\033[9m"
32
+ STRIKETHROUGH_OFF = "\033[29m"
33
+
34
+
35
+ LANG_ALIASES: dict[str, str] = {
36
+ "py": "python",
37
+ "js": "javascript",
38
+ "ts": "typescript",
39
+ "sh": "bash",
40
+ "shell": "bash",
41
+ "yml": "yaml",
42
+ "md": "markdown",
43
+ "c++": "cpp",
44
+ "c#": "csharp",
45
+ }
46
+
47
+
48
+ def _detect_true_color() -> bool:
49
+ """Check if terminal supports 24-bit color."""
50
+ colorterm = os.environ.get("COLORTERM", "")
51
+ return colorterm in ("truecolor", "24bit")
52
+
53
+
54
+ def _get_style_bg(style_name: str) -> str:
55
+ """Extract background color from pygments style as ANSI escape."""
56
+ try:
57
+ style = get_style_by_name(style_name)
58
+ bg = style.background_color
59
+ if bg and bg.startswith("#") and len(bg) == 7:
60
+ r, g, b = int(bg[1:3], 16), int(bg[3:5], 16), int(bg[5:7], 16)
61
+ return f"\033[48;2;{r};{g};{b}m"
62
+ except Exception:
63
+ pass
64
+ return "\033[48;5;236m" # fallback gray
65
+
66
+
67
+ def _visible_len(s: str) -> int:
68
+ """Length of string excluding ANSI escape sequences."""
69
+ return len(re.sub(r"\033\[[0-9;]*m", "", s))
70
+
71
+
72
+ def _pad_to_width(text: str, width: int) -> str:
73
+ """Pad string to width, accounting for ANSI codes."""
74
+ padding = width - _visible_len(text)
75
+ return text + " " * max(0, padding)
76
+
77
+
78
+ class SyntaxHighlighter:
79
+ """Syntax highlighter using pygments."""
80
+
81
+ def __init__(self, style: str = "monokai", true_color: bool | None = None):
82
+ """
83
+ Args:
84
+ style: Pygments style name (monokai, dracula, gruvbox-dark, one-dark, etc.)
85
+ true_color: Use 24-bit color. None = auto-detect from COLORTERM env var.
86
+ """
87
+ if true_color is None:
88
+ true_color = _detect_true_color()
89
+
90
+ formatter_cls = (
91
+ TerminalTrueColorFormatter if true_color else Terminal256Formatter
92
+ )
93
+ self.formatter = formatter_cls(style=style)
94
+ self.style = style
95
+
96
+ def highlight(self, code: str, language: str = "") -> str:
97
+ """Highlight code and return ANSI-formatted string."""
98
+ lexer = self._get_lexer(code, language)
99
+ return highlight(code, lexer, self.formatter).rstrip("\n")
100
+
101
+ def _get_lexer(self, code: str, language: str):
102
+ language = LANG_ALIASES.get(language.lower(), language.lower())
103
+
104
+ if language:
105
+ try:
106
+ return get_lexer_by_name(language)
107
+ except Exception:
108
+ pass
109
+
110
+ try:
111
+ return guess_lexer(code)
112
+ except Exception:
113
+ return TextLexer()
114
+
115
+ @staticmethod
116
+ def available_styles() -> list[str]:
117
+ """Return list of available pygments style names."""
118
+ return list(get_all_styles())
119
+
120
+
121
+ @dataclass
122
+ class MarkdownRenderer:
123
+ """Renders markdown to ANSI-formatted terminal output."""
124
+
125
+ code_style: str = "monokai"
126
+ code_width: int | None = None # None = terminal width
127
+ true_color: bool | None = None # None = auto-detect
128
+
129
+ _highlighter: SyntaxHighlighter = field(init=False, repr=False)
130
+ _code_bg: str = field(init=False, repr=False)
131
+
132
+ def __post_init__(self):
133
+ self._highlighter = SyntaxHighlighter(
134
+ style=self.code_style, true_color=self.true_color
135
+ )
136
+ self._code_bg = _get_style_bg(self.code_style)
137
+
138
+ def render(self, text: str) -> str:
139
+ """Render markdown text to ANSI-formatted string."""
140
+ # Normalize line endings
141
+ text = text.replace("\r\n", "\n").replace("\r", "\n")
142
+ return "\n".join(self._render_blocks(text))
143
+
144
+ def _render_blocks(self, text: str) -> Iterator[str]:
145
+ """Process block-level elements."""
146
+ lines = text.split("\n")
147
+ i = 0
148
+
149
+ while i < len(lines):
150
+ line = lines[i]
151
+ stripped = line.strip()
152
+
153
+ # Code block
154
+ if stripped.startswith("```"):
155
+ lang = stripped[3:].strip()
156
+ code_lines = []
157
+ i += 1
158
+
159
+ while i < len(lines) and not lines[i].strip().startswith("```"):
160
+ code_lines.append(lines[i])
161
+ i += 1
162
+
163
+ yield from self._render_code_block(code_lines, lang)
164
+ i += 1 # skip closing ```
165
+ continue
166
+
167
+ yield self._render_line(line)
168
+ i += 1
169
+
170
+ def _get_code_width(self) -> int:
171
+ if self.code_width:
172
+ return self.code_width
173
+ return shutil.get_terminal_size().columns
174
+
175
+ def _render_code_block(self, code_lines: list[str], language: str) -> Iterator[str]:
176
+ """Render a fenced code block with syntax highlighting."""
177
+ width = self._get_code_width()
178
+ bg = self._code_bg
179
+ reset = Style.RESET_ALL
180
+
181
+ # Header with language label
182
+ label = f"{language}" if language else ""
183
+ if label:
184
+ yield f"{bg}{Fore.LIGHTBLACK_EX}{_pad_to_width(label, width)}{reset}"
185
+
186
+ # Highlighted code
187
+ if code_lines:
188
+ code = "\n".join(code_lines)
189
+ highlighted = self._highlighter.highlight(code, language)
190
+
191
+ for hl_line in highlighted.split("\n"):
192
+ yield f"{bg}{_pad_to_width(hl_line, width)}{reset}"
193
+
194
+ def _render_line(self, line: str) -> str:
195
+ """Render a single line of markdown."""
196
+ stripped = line.strip()
197
+
198
+ if not stripped:
199
+ return ""
200
+
201
+ # Horizontal rule
202
+ if re.match(r"^[-*_]{3,}$", stripped):
203
+ return f"{Ansi.DIM}{Fore.WHITE}{'─' * 50}{Style.RESET_ALL}"
204
+
205
+ # Headers
206
+ if m := re.match(r"^(#{1,6})\s+(.+)$", stripped):
207
+ return self._render_header(len(m.group(1)), m.group(2))
208
+
209
+ # Blockquotes
210
+ if stripped.startswith(">"):
211
+ content = stripped.lstrip(">").strip()
212
+ rendered = self._render_inline(content)
213
+ return f"{Fore.MAGENTA}│ {Ansi.ITALIC}{rendered}{Ansi.ITALIC_OFF}{Style.RESET_ALL}"
214
+
215
+ # Task lists
216
+ if m := re.match(r"^[-*]\s+\[([ xX])\]\s+(.+)$", stripped):
217
+ checked = m.group(1).lower() == "x"
218
+ marker = f"{Fore.GREEN}✓" if checked else f"{Fore.RED}○"
219
+ return f" {marker} {self._render_inline(m.group(2))}{Style.RESET_ALL}"
220
+
221
+ # Unordered lists
222
+ if m := re.match(r"^[-*+]\s+(.+)$", stripped):
223
+ indent = len(line) - len(line.lstrip())
224
+ return f"{' ' * indent}{Fore.GREEN}• {Style.RESET_ALL}{self._render_inline(m.group(1))}"
225
+
226
+ # Ordered lists
227
+ if m := re.match(r"^(\d+)\.\s+(.+)$", stripped):
228
+ indent = len(line) - len(line.lstrip())
229
+ return f"{' ' * indent}{Fore.GREEN}{m.group(1)}. {Style.RESET_ALL}{self._render_inline(m.group(2))}"
230
+
231
+ return self._render_inline(line)
232
+
233
+ def _render_header(self, level: int, text: str) -> str:
234
+ """Render a header with level-appropriate styling."""
235
+ colors = [
236
+ Fore.CYAN,
237
+ Fore.BLUE,
238
+ Fore.MAGENTA,
239
+ Fore.GREEN,
240
+ Fore.YELLOW,
241
+ Fore.WHITE,
242
+ ]
243
+ color = colors[min(level, 6) - 1]
244
+
245
+ # Visual prefix for h1-h3
246
+ prefix = "█" * (4 - level) + " " if level <= 3 else ""
247
+
248
+ rendered_text = self._render_inline(text)
249
+ return f"{color}{Style.BRIGHT}{prefix}{rendered_text}{Style.RESET_ALL}"
250
+
251
+ def _render_inline(self, text: str) -> str:
252
+ """Render inline markdown elements."""
253
+ # Order matters: process from most specific to least specific
254
+
255
+ # Inline code first (protects contents from further processing)
256
+ code_spans: list[str] = []
257
+
258
+ def extract_code(m):
259
+ code_spans.append(
260
+ f"{Back.BLACK}{Fore.YELLOW} {m.group(1)} {Style.RESET_ALL}"
261
+ )
262
+ return f"\x00CODE{len(code_spans) - 1}\x00"
263
+
264
+ text = re.sub(r"`([^`]+)`", extract_code, text)
265
+
266
+ # Bold + italic (must come before bold and italic)
267
+ text = re.sub(
268
+ r"\*\*\*(.+?)\*\*\*",
269
+ lambda m: f"{Style.BRIGHT}{Ansi.ITALIC}{m.group(1)}{Ansi.ITALIC_OFF}{Style.NORMAL}",
270
+ text,
271
+ )
272
+
273
+ # Bold
274
+ text = re.sub(
275
+ r"\*\*(.+?)\*\*",
276
+ lambda m: f"{Style.BRIGHT}{m.group(1)}{Style.NORMAL}",
277
+ text,
278
+ )
279
+ text = re.sub(
280
+ r"__(.+?)__",
281
+ lambda m: f"{Style.BRIGHT}{m.group(1)}{Style.NORMAL}",
282
+ text,
283
+ )
284
+
285
+ # Italic with asterisks (works anywhere)
286
+ text = re.sub(
287
+ r"(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)",
288
+ lambda m: f"{Ansi.ITALIC}{m.group(1)}{Ansi.ITALIC_OFF}",
289
+ text,
290
+ )
291
+
292
+ # Italic with underscores (only at word boundaries)
293
+ text = re.sub(
294
+ r"(?<!\w)_(?!_)(.+?)(?<!_)_(?!\w)",
295
+ lambda m: f"{Ansi.ITALIC}{m.group(1)}{Ansi.ITALIC_OFF}",
296
+ text,
297
+ )
298
+
299
+ # Strikethrough
300
+ text = re.sub(
301
+ r"~~(.+?)~~",
302
+ lambda m: f"{Ansi.STRIKETHROUGH}{m.group(1)}{Ansi.STRIKETHROUGH_OFF}",
303
+ text,
304
+ )
305
+
306
+ # Links
307
+ text = re.sub(
308
+ r"\[([^\]]+)\]\(([^)]+)\)",
309
+ lambda m: f"{Ansi.UNDERLINE}{Fore.BLUE}{m.group(1)}{Ansi.UNDERLINE_OFF}{Style.RESET_ALL}{Ansi.DIM} ({m.group(2)}){Ansi.DIM_OFF}",
310
+ text,
311
+ )
312
+
313
+ # Restore code spans
314
+ for i, code in enumerate(code_spans):
315
+ text = text.replace(f"\x00CODE{i}\x00", code)
316
+
317
+ return text
318
+
319
+
320
+ def md_print(
321
+ text: str,
322
+ *,
323
+ code_style: str = "monokai",
324
+ code_width: int | None = None,
325
+ true_color: bool | None = None,
326
+ ) -> None:
327
+ """
328
+ Print markdown-formatted text to the terminal.
329
+
330
+ Args:
331
+ text: Markdown text to render.
332
+ code_style: Pygments style for code blocks.
333
+ code_width: Width for code blocks (None = terminal width).
334
+ true_color: Use 24-bit color (None = auto-detect).
335
+ """
336
+ renderer = MarkdownRenderer(
337
+ code_style=code_style,
338
+ code_width=code_width,
339
+ true_color=true_color,
340
+ )
341
+ print(renderer.render(text))
342
+
343
+
344
+ def md_render(
345
+ text: str,
346
+ *,
347
+ code_style: str = "monokai",
348
+ code_width: int | None = None,
349
+ true_color: bool | None = None,
350
+ ) -> str:
351
+ """
352
+ Render markdown text to ANSI-formatted string.
353
+
354
+ Args:
355
+ text: Markdown text to render.
356
+ code_style: Pygments style for code blocks.
357
+ code_width: Width for code blocks (None = terminal width).
358
+ true_color: Use 24-bit color (None = auto-detect).
359
+
360
+ Returns:
361
+ ANSI-formatted string ready for terminal output.
362
+ """
363
+ renderer = MarkdownRenderer(
364
+ code_style=code_style,
365
+ code_width=code_width,
366
+ true_color=true_color,
367
+ )
368
+ return renderer.render(text)
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdsyntax
3
+ Version: 0.1.0
4
+ Summary: Render markdown with syntax highlighting in the terminal
5
+ Project-URL: Homepage, https://github.com/Azaias/mdsyntax
6
+ Project-URL: Repository, https://github.com/Azaias/mdsyntax
7
+ Project-URL: Issues, https://github.com/Azaias/mdsyntax/issues
8
+ Author-email: Izaiah Meyer <lolduderlly@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ansi,cli,console,markdown,syntax-highlighting,terminal
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Terminals
23
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: colorama>=0.4.6
27
+ Requires-Dist: pygments>=2.17.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: build; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.4; extra == 'dev'
32
+ Requires-Dist: twine; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # mdsyntax
36
+
37
+ [![PyPI version](https://img.shields.io/pypi/v/mdsyntax.svg)](https://pypi.org/project/mdsyntax/)
38
+ [![Python versions](https://img.shields.io/pypi/pyversions/mdsyntax.svg)](https://pypi.org/project/mdsyntax/)
39
+ [![CI](https://github.com/Azaias/mdsyntax/actions/workflows/ci.yml/badge.svg)](https://github.com/Azaias/mdsyntax/actions/workflows/ci.yml)
40
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
41
+
42
+ Render markdown with syntax highlighting in the terminal.
43
+
44
+ ## Installation
45
+
46
+ ```bash
47
+ pip install mdsyntax
48
+ ```
49
+
50
+ ## Usage
51
+
52
+ ### Python API
53
+
54
+ ```python
55
+ from mdsyntax import md_print, md_render
56
+
57
+ # Print directly to terminal
58
+ md_print("""
59
+ # Hello World
60
+
61
+ This is **bold** and *italic* text.
62
+
63
+ ```python
64
+ def greet(name):
65
+ return f"Hello, {name}!"
66
+ ```
67
+ """)
68
+
69
+ # Get ANSI string for further processing
70
+ output = md_render("Some `inline code` here")
71
+ ```
72
+
73
+ ### Command Line
74
+
75
+ ```bash
76
+ # Render a file
77
+ mdsyntax README.md
78
+
79
+ # Pipe from stdin
80
+ echo "# Hello" | mdsyntax
81
+
82
+ # Use a different syntax theme
83
+ mdsyntax --style dracula document.md
84
+
85
+ # List available themes
86
+ mdsyntax --list-styles
87
+ ```
88
+
89
+ ## Features
90
+
91
+ - Headers (h1-h6) with color coding
92
+ - **Bold**, *italic*, ***bold italic***
93
+ - ~~Strikethrough~~
94
+ - `Inline code`
95
+ - Fenced code blocks with syntax highlighting
96
+ - [Links](https://example.com)
97
+ - Unordered and ordered lists
98
+ - Task lists
99
+ - Blockquotes
100
+ - Horizontal rules
101
+
102
+ ## Configuration
103
+
104
+ ### Code Styles
105
+
106
+ Any [Pygments style](https://pygments.org/styles/) is supported. Popular options:
107
+
108
+ - `monokai` (default)
109
+ - `dracula`
110
+ - `one-dark`
111
+ - `gruvbox-dark`
112
+ - `nord`
113
+ - `github-dark`
114
+
115
+ ### True Color
116
+
117
+ By default, md-print auto-detects 24-bit color support via the `COLORTERM` environment variable. You can override this:
118
+
119
+ ```python
120
+ # Force 256-color mode
121
+ md_print(text, true_color=False)
122
+
123
+ # Force true color
124
+ md_print(text, true_color=True)
125
+ ```
126
+
127
+ ## API Reference
128
+
129
+ ### `md_print(text, *, code_style="monokai", code_width=None, true_color=None)`
130
+
131
+ Print markdown to terminal.
132
+
133
+ - `text`: Markdown string to render
134
+ - `code_style`: Pygments style name for code blocks
135
+ - `code_width`: Fixed width for code blocks (default: terminal width)
136
+ - `true_color`: Use 24-bit color (default: auto-detect)
137
+
138
+ ### `md_render(...) -> str`
139
+
140
+ Same arguments as `md_print`, but returns the ANSI-formatted string instead of printing.
141
+
142
+ ### `MarkdownRenderer`
143
+
144
+ Dataclass for more control:
145
+
146
+ ```python
147
+ from mdsyntax import MarkdownRenderer
148
+
149
+ renderer = MarkdownRenderer(
150
+ code_style="dracula",
151
+ code_width=80,
152
+ true_color=True,
153
+ )
154
+ output = renderer.render(markdown_text)
155
+ ```
156
+
157
+ ### `SyntaxHighlighter`
158
+
159
+ Standalone code highlighter:
160
+
161
+ ```python
162
+ from mdsyntax import SyntaxHighlighter
163
+
164
+ hl = SyntaxHighlighter(style="monokai")
165
+ print(hl.highlight("print('hello')", "python"))
166
+ print(SyntaxHighlighter.available_styles())
167
+ ```
168
+
169
+ ## License
170
+
171
+ MIT
172
+
173
+
174
+ ## Contributing
175
+
176
+ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
@@ -0,0 +1,9 @@
1
+ mdsyntax/__init__.py,sha256=UyRtUQZPOR9Ju9jQXYM1o98yToDCv4FGes3Ug0TYXlU,503
2
+ mdsyntax/cli.py,sha256=tGXBjAeibKwphdHi5saSWuNV3mAKee-82koUC6uxeMo,1977
3
+ mdsyntax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ mdsyntax/renderer.py,sha256=WInbdSCepcWw7l_ziuG13ncfGM17Xf4P0-haxe-lmwg,11434
5
+ mdsyntax-0.1.0.dist-info/METADATA,sha256=0ktiKUppK9eYCLZhLye8GML4REg09-8r5CIkwGcVATY,4306
6
+ mdsyntax-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
7
+ mdsyntax-0.1.0.dist-info/entry_points.txt,sha256=X3XBqbjP3t5OnEsK5RniLQZNpK3_Z1Q5nQnYQbeXxcE,47
8
+ mdsyntax-0.1.0.dist-info/licenses/LICENSE,sha256=KAch0UTtju_-x0eNps82_go4gq-FssWkDk-eJlNkKMU,1069
9
+ mdsyntax-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mdsyntax = mdsyntax.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Izaiah Meyer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.