Skip to content

Instantly share code, notes, and snippets.

@KoStard
Created September 24, 2024 11:03
Show Gist options
  • Save KoStard/e6ae4d3f27e55bdcac0641e00f94b7e5 to your computer and use it in GitHub Desktop.
Save KoStard/e6ae4d3f27e55bdcac0641e00f94b7e5 to your computer and use it in GitHub Desktop.
A demo script, showing how to print markdown text into terminal with syntax highlighting without rendering it with tools like rich. This way it still remains the markdown text which you can copy/paste from terminal, but with nice readable colors.
import mistune
from mistune.renderers.markdown import MarkdownRenderer
from pygments import highlight
from pygments.lexers import get_lexer_by_name, MarkdownLexer
from pygments.formatters import Terminal256Formatter
def markdown_stream_generator():
text = """
# Main Heading
## Sub-heading
### Third-level heading
#### Fourth-level heading
This is a paragraph with **bold text**, *italicized text*, and `inline code`.
Here's a [link to Google](https://www.google.com).
![Alt text for an image](https://example.com/image.jpg)
- Unordered list item 1
- Unordered list item 2
- Nested item 2.1
- Nested item 2.2
- Unordered list item 3
1. Ordered list item 1
2. Ordered list item 2
1. Nested ordered item 2.1
2. `Nested ordered` item 2.2
3. Ordered list item 3
> This is a blockquote.
> It can span multiple lines.
---
Here's a table:
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Row 1, Col 1 | Row 1, Col 2 | Row 1, Col 3 |
| Row 2, Col 1 | Row 2, Col 2 | Row 2, Col 3 |
Here's a code block:
```python
def hello_world():
print("Hello, world!")
hello_world()
```
```javascript
function factorial(n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
console.log(factorial(5));
```
```ruby
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("Alice", 30)
puts "#{person.name} is #{person.age} years old."
```
```java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
```cpp
#include <iostream>
using namespace std;
int main() {
int nums[] = {1, 2, 3, 4, 5};
for (int num : nums) {
cout << num << " ";
}
return 0;
}
```
```sql
SELECT customers.name, orders.order_date
FROM customers
JOIN orders ON customers.id = orders.customer_id
WHERE orders.total > 100;
```
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample Page</title>
</head>
<body>
<h1>Welcome to my website!</h1>
<p>This is a paragraph.</p>
</body>
</html>
```
And here's a task list:
- [x] Completed task
- [ ] Incomplete task
- [ ] Another incomplete task
Here's some ~~strikethrough text~~.
You can also use inline HTML: <span style="color: red;">This text is red</span>
Here's a footnote reference[^1].
[^1]: This is the footnote content.
"""
for index in range(0, len(text), 3):
yield text[index : index + 3]
def line_aggregator(generator):
buffer = ""
for chunk in generator:
buffer += chunk
while "\n" in buffer:
line, buffer = buffer.split("\n", 1)
yield line + "\n"
if buffer:
yield buffer
renderer = MarkdownRenderer()
state = mistune.BlockState()
def render_to_markdown(element):
rendered = renderer([element], state)
return rendered
def get_lexer(element):
info = element.get("attrs", {}).get("info", "")
if info:
return get_lexer_by_name(info)
else:
return MarkdownLexer()
def print_markdown(text, lexer):
highlighted = highlight(text, lexer, Terminal256Formatter())
print(highlighted, end="")
def process_markdown_stream():
ast = mistune.create_markdown(renderer="ast")
buffer = ""
old_parsed = []
for line in line_aggregator(markdown_stream_generator()):
buffer += line
parsed = ast(buffer)
if len(parsed) == len(old_parsed):
continue
old_parsed = parsed
buffer = line
while len(parsed) > 1:
element = parsed.pop(0)
print_markdown(render_to_markdown(element), get_lexer(element))
if buffer:
parsed = ast(buffer)
for element in parsed:
print_markdown(render_to_markdown(element), get_lexer(element))
process_markdown_stream()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment