streamdown 0.24.0__tar.gz → 0.26.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.
- {streamdown-0.24.0 → streamdown-0.26.0}/PKG-INFO +1 -5
- {streamdown-0.24.0 → streamdown-0.26.0}/README.md +0 -4
- {streamdown-0.24.0 → streamdown-0.26.0}/pyproject.toml +1 -1
- {streamdown-0.24.0 → streamdown-0.26.0}/streamdown/sd.py +54 -25
- streamdown-0.26.0/tests/blankie.md +6 -0
- streamdown-0.26.0/tests/rerun.zsh +3 -0
- streamdown-0.26.0/tools/deploy.sh +16 -0
- streamdown-0.24.0/tests/rerun.zsh +0 -3
- streamdown-0.24.0/tools/deploy.sh +0 -7
- {streamdown-0.24.0 → streamdown-0.26.0}/.gitignore +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/LICENSE.MIT +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/requirements.txt +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/streamdown/__init__.py +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/streamdown/plugins/README.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/streamdown/plugins/latex.py +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/README.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/backtick-with-post-spaces.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/block.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/bold_reset_with_link.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/broken-code.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/broken-example.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/chunk-buffer.sh +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/cjk-table.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/cjk-wrap.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/code.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/example.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/fizzbuzz.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/inline.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/jimmy_webb.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/line-buffer.sh +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/line-wrap.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/links.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/managerie.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/mandlebrot.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/markdown.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/nested-example.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/outline.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/pvgo_512.jpg +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/pythonvgo.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/qwen3.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/slash.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/strip-chunks.sh +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/table-break.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/table_test.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/test.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/test_input.md +0 -0
- {streamdown-0.24.0 → streamdown-0.26.0}/tests/wm.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamdown
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: A streaming markdown renderer for modern terminals with syntax highlighting
|
|
5
5
|
Project-URL: Homepage, https://github.com/kristopolous/Streamdown
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/kristopolous/Streamdown/issues
|
|
@@ -188,7 +188,3 @@ After the git clone least one of these should work, hopefully. it's using the mo
|
|
|
188
188
|
$ pip install -e .
|
|
189
189
|
$ uv pip install -e .
|
|
190
190
|
|
|
191
|
-
### Future work
|
|
192
|
-
|
|
193
|
-
#### Glow styles
|
|
194
|
-
I'm going to try to be compatible with other popular markdown styles to help for a smoother transition. Glow compatible json sheets is on my radar. There's also mdless and frogmouth. Might be others
|
|
@@ -159,7 +159,3 @@ After the git clone least one of these should work, hopefully. it's using the mo
|
|
|
159
159
|
$ pip install -e .
|
|
160
160
|
$ uv pip install -e .
|
|
161
161
|
|
|
162
|
-
### Future work
|
|
163
|
-
|
|
164
|
-
#### Glow styles
|
|
165
|
-
I'm going to try to be compatible with other popular markdown styles to help for a smoother transition. Glow compatible json sheets is on my radar. There's also mdless and frogmouth. Might be others
|
|
@@ -104,19 +104,22 @@ visible_length = lambda x: len(visible(x)) + dbl_count(x)
|
|
|
104
104
|
extract_ansi_codes = lambda text: re.findall(ESCAPE, text)
|
|
105
105
|
remove_ansi = lambda line, codeList: reduce(lambda line, code: line.replace(code, ''), codeList, line)
|
|
106
106
|
|
|
107
|
+
def gettmpdir():
|
|
108
|
+
tmp_dir_all = os.path.join(tempfile.gettempdir(), "sd")
|
|
109
|
+
os.makedirs(tmp_dir_all, mode=0o777, exist_ok=True)
|
|
110
|
+
tmp_dir = os.path.join(tmp_dir_all, str(os.getuid()))
|
|
111
|
+
os.makedirs(tmp_dir, exist_ok=True)
|
|
112
|
+
return tmp_dir
|
|
113
|
+
|
|
107
114
|
def debug_write(text):
|
|
108
115
|
if state.Logging:
|
|
109
116
|
if state.Logging == True:
|
|
110
|
-
|
|
111
|
-
os.makedirs(tmp_dir, exist_ok=True)
|
|
112
|
-
state.Logging = tempfile.NamedTemporaryFile(dir=tmp_dir, prefix="dbg", delete=False, mode="wb")
|
|
117
|
+
state.Logging = tempfile.NamedTemporaryFile(dir=gettmpdir(), prefix="dbg", delete=False, mode="wb")
|
|
113
118
|
state.Logging.write(text)
|
|
114
119
|
|
|
115
120
|
def savebrace():
|
|
116
121
|
if state.Savebrace and state.code_buffer_raw:
|
|
117
|
-
|
|
118
|
-
os.makedirs(tmp_dir, exist_ok=True)
|
|
119
|
-
path = os.path.join(tempfile.gettempdir(), "sd", 'savebrace')
|
|
122
|
+
path = os.path.join(gettmpdir(), 'savebrace')
|
|
120
123
|
with open(path, "a") as f:
|
|
121
124
|
f.write(state.code_buffer_raw + "\x00")
|
|
122
125
|
f.flush()
|
|
@@ -282,17 +285,23 @@ def format_table(rowList):
|
|
|
282
285
|
|
|
283
286
|
def emit_h(level, text):
|
|
284
287
|
text = line_format(text)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
288
|
+
lineList = text_wrap(text)
|
|
289
|
+
res = []
|
|
290
|
+
for text in lineList:
|
|
291
|
+
spaces_to_center = (state.current_width() - visible_length(text)) / 2
|
|
292
|
+
if level == 1: #
|
|
293
|
+
res.append(f"{state.space_left()}\n{state.space_left()}{BOLD[1]}{' ' * math.floor(spaces_to_center)}{text}{BOLD[1]}")
|
|
294
|
+
elif level == 2: ##
|
|
295
|
+
res.append(f"{state.space_left()}\n{state.space_left()}{BOLD[0]}{FG}{Style.Bright}{' ' * math.floor(spaces_to_center)}{text}{' ' * math.ceil(spaces_to_center)}{BOLD[1]}{FGRESET}")
|
|
296
|
+
elif level == 3: ###
|
|
297
|
+
res.append(f"{state.space_left()}{FG}{Style.Head}{BOLD[0]}{text}{RESET}")
|
|
298
|
+
elif level == 4: ####
|
|
299
|
+
res.append(f"{state.space_left()}{FG}{Style.Symbol}{text}{RESET}")
|
|
300
|
+
elif level == 5: #####
|
|
301
|
+
res.append(f"{state.space_left()}{text}{RESET}")
|
|
302
|
+
else:
|
|
303
|
+
res.append(f"{state.space_left()}{FG}{Style.Grey}{text}{RESET}")
|
|
304
|
+
return "\n".join(res)
|
|
296
305
|
|
|
297
306
|
def code_wrap(text_in):
|
|
298
307
|
if not Style.PrettyBroken and state.WidthWrap and len(text_in) > state.full_width():
|
|
@@ -453,7 +462,7 @@ def cjk_count(s):
|
|
|
453
462
|
return len(cjk_re.findall(visible(s)))
|
|
454
463
|
|
|
455
464
|
def line_format(line):
|
|
456
|
-
not_text = lambda token: not (token.isalnum() or token
|
|
465
|
+
not_text = lambda token: not (token.isalnum() or token in ['\\','"']) or cjk_count(token)
|
|
457
466
|
footnotes = lambda match: ''.join([chr(SUPER[int(i)]) for i in match.group(1)])
|
|
458
467
|
|
|
459
468
|
def process_images(match):
|
|
@@ -514,7 +523,6 @@ def line_format(line):
|
|
|
514
523
|
state.code_buffer_raw += token
|
|
515
524
|
|
|
516
525
|
elif token == '~~' and (state.in_strikeout or not_text(prev_token)):
|
|
517
|
-
print("in strike")
|
|
518
526
|
state.in_strikeout = not state.in_strikeout
|
|
519
527
|
result += STRIKEOUT[0] if state.in_strikeout else STRIKEOUT[1]
|
|
520
528
|
|
|
@@ -718,10 +726,8 @@ def parse(stream):
|
|
|
718
726
|
if state.in_code:
|
|
719
727
|
try:
|
|
720
728
|
# This is turning it OFF
|
|
721
|
-
if
|
|
722
|
-
|
|
723
|
-
(state.CodeSpaces and state.in_code == Code.Spaces and not line.startswith(' '))
|
|
724
|
-
):
|
|
729
|
+
if ( ( state.in_code == Code.Backtick and line.strip() == "```" ) or
|
|
730
|
+
(state.CodeSpaces and state.in_code == Code.Spaces and not line.startswith(' ')) ):
|
|
725
731
|
if state.scrape:
|
|
726
732
|
ext = "sh"
|
|
727
733
|
try:
|
|
@@ -944,6 +950,11 @@ def parse(stream):
|
|
|
944
950
|
continue
|
|
945
951
|
|
|
946
952
|
state.where_from = "emit_normal"
|
|
953
|
+
|
|
954
|
+
# if we've gotten to an emit normal then we can assert that our list stack should
|
|
955
|
+
# be empty. This is a hack.
|
|
956
|
+
state.list_item_stack = []
|
|
957
|
+
|
|
947
958
|
if len(line) == 0: yield ""
|
|
948
959
|
if len(line) < state.Width:
|
|
949
960
|
# we want to prevent word wrap
|
|
@@ -1010,7 +1021,7 @@ def apply_multipliers(style, name, H, S, V):
|
|
|
1010
1021
|
def width_calc():
|
|
1011
1022
|
if not state.WidthFull or not state.WidthArg:
|
|
1012
1023
|
if state.WidthArg:
|
|
1013
|
-
|
|
1024
|
+
width = state.WidthArg
|
|
1014
1025
|
else:
|
|
1015
1026
|
width = 80
|
|
1016
1027
|
|
|
@@ -1020,7 +1031,13 @@ def width_calc():
|
|
|
1020
1031
|
except (AttributeError, OSError):
|
|
1021
1032
|
pass
|
|
1022
1033
|
|
|
1023
|
-
|
|
1034
|
+
|
|
1035
|
+
# This can't be done because our list item stack can change as well so
|
|
1036
|
+
# unless we want to track that too, we're SOL
|
|
1037
|
+
#if state.WidthFull == width:
|
|
1038
|
+
# return
|
|
1039
|
+
|
|
1040
|
+
state.WidthFull = width
|
|
1024
1041
|
|
|
1025
1042
|
state.Width = state.WidthFull - 2 * Style.Margin
|
|
1026
1043
|
pre = state.space_left(listwidth=True) if Style.PrettyBroken else ''
|
|
@@ -1039,8 +1056,20 @@ def main():
|
|
|
1039
1056
|
parser.add_argument("-w", "--width", default="0", help="Set the width WIDTH")
|
|
1040
1057
|
parser.add_argument("-e", "--exec", help="Wrap a program EXEC for more 'proper' i/o handling")
|
|
1041
1058
|
parser.add_argument("-s", "--scrape", help="Scrape code snippets to a directory SCRAPE")
|
|
1059
|
+
parser.add_argument("-v", "--version", action="store_true", help="Show version information")
|
|
1042
1060
|
args = parser.parse_args()
|
|
1043
1061
|
|
|
1062
|
+
if args.version:
|
|
1063
|
+
import importlib.metadata
|
|
1064
|
+
|
|
1065
|
+
try:
|
|
1066
|
+
version = importlib.metadata.version("streamdown")
|
|
1067
|
+
except importlib.metadata.PackageNotFoundError:
|
|
1068
|
+
version = "Unknown"
|
|
1069
|
+
|
|
1070
|
+
print(f"Streamdown - {version}")
|
|
1071
|
+
sys.exit(0)
|
|
1072
|
+
|
|
1044
1073
|
config_toml_path, config_toml_content = ensure_config_file(args.config)
|
|
1045
1074
|
config = toml.loads(config_toml_content)
|
|
1046
1075
|
style = toml.loads(default_toml).get('style') | config.get("style", {})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
version=$(grep version pyproject.toml | cut -d '"' -f 2)
|
|
3
|
+
tag_update() {
|
|
4
|
+
git tag -m $version $version
|
|
5
|
+
git push --tags
|
|
6
|
+
}
|
|
7
|
+
pipy() {
|
|
8
|
+
source .venv/bin/activate
|
|
9
|
+
for i in pip hatch build; do
|
|
10
|
+
pip install --upgrade $i
|
|
11
|
+
done
|
|
12
|
+
python3 -m build .
|
|
13
|
+
twine upload dists/*$version*
|
|
14
|
+
}
|
|
15
|
+
tag_update
|
|
16
|
+
pipy
|
|
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
|
|
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
|
|
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
|