This post explains how to use the python, typescript, rust, cpp, sql, and mermaid shortcodes to create interactive, runnable code snippets and diagrams in your blog posts.
Introduction#
Interactive code snippets allow readers to run and experiment with code directly in their browsers without setting up a development environment. Our website now supports this feature for Python (using Pyodide, a port of CPython to WebAssembly), TypeScript (using the TypeScript compiler in the browser), Rust (using compilation services), and C++ (using WebAssembly).
Python Shortcode#
Basic Usage#
To add a runnable Python code snippet to your post, use the python shortcode like this:
{{</* python */>}}
# Your Python code here
print("Hello, world!")
{{</* /python */>}}
This will create a code block with a "Run" button. When clicked, the code will execute and the output will be displayed below the code.
Here's a live example:
# A simple Python example
for i in range(5):
print(f"The square of {i} is {i*i}")
apple = 50 # Apple variable is shared across multiple code editors.
Using Python Libraries#
Pyodide includes many standard library modules and popular packages like NumPy, Pandas, Matplotlib, and more. When you import these libraries in your code, Pyodide will automatically load them.
Here's an example using NumPy:
%% numpy
import numpy as np
from functools import wraps
# Create a random array
data = np.random.rand(5, 5)
print("Random 5x5 matrix:")
print(data)
# Calculate statistics
print(f"Mean: {np.mean(data):.4f}")
print(f"Max: {np.max(data):.4f}")
print(f"Min: {np.min(data):.4f}")
print("apple: ", apple) # Apple variable is shared across multiple code editors.
Creating Visualizations#
You can even create visualizations using Matplotlib:
%% numpy, matplotlib
import numpy as np
import matplotlib.pyplot as plt
from io import BytesIO
import base64
# Create data
x = np.linspace(0, 2*np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# Create plot
plt.figure(figsize=(8, 4))
plt.plot(x, y1, label='sin(x)')
plt.plot(x, y2, label='cos(x)')
plt.title('Sine and Cosine Waves')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
# Convert plot to image and display
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
img_str = base64.b64encode(buf.read()).decode('utf-8')
print(f'<img src="data:image/png;base64,{img_str}" />')
Interactive Examples#
You can create more complex examples that demonstrate algorithms or concepts:
TypeScript Shortcode#
Basic Usage#
To add a runnable TypeScript code snippet to your post, use the typescript shortcode like this:
{{</* typescript */>}}
// Your TypeScript code here
console.log("Hello from TypeScript!");
{{</* /typescript */>}}
This creates an interactive code block with syntax highlighting and a "Run" button. When clicked, the TypeScript code is compiled to JavaScript and executed, with the output displayed below.
Here's a live example:
// A simple TypeScript example
// Type annotations
const message: string = "TypeScript is awesome";
const year: number = 2023;
const isEnabled: boolean = true;
console.log(`${message} in ${year}!`);
console.log(`Feature enabled: ${isEnabled}`);
Using TypeScript Features#
There is type-checking too (Work-in-process)!
const message: number = "TypeScript is awesome";
const year: number = 2023;
console.log(`${message} in ${year}!`);
The above should not compile (The above example is still compiling - need to incorporate type checking into the shortcodes, still a work in progress).
The TypeScript shortcode supports all standard TypeScript features, including interfaces, types, classes, and more:
// Define an interface
interface Person {
name: string;
age: number;
greet(): void;
}
// Implement the interface
class Employee implements Person {
constructor(public name: string, public age: number, private role: string) {}
}
// Create an instance
const employee = new Employee("Alice", 30, "Developer");
employee.greet();
employee.introduce();
Working with Arrays and Objects#
TypeScript provides excellent type safety for working with collections:
// Type-safe arrays and objects
const numbers: number[] = [1, 2, 3, 4, 5];
const fruits: Array<string> = ["apple", "banana", "orange"];
// Array operations with TypeScript
const doubled = numbers.map((n: number): number => n * 2);
console.log("Doubled numbers:", doubled);
const filteredFruits = fruits.filter((fruit: string): boolean => fruit.length > 5);
console.log("Fruits with more than 5 characters:", filteredFruits);
// Type-safe object
const products: Product[] = [
{ id: 1, name: "Laptop", price: 1200 },
{ id: 2, name: "Phone", price: 800 },
{ id: 3, name: "Tablet", price: 400 }
];
// Calculate total price
const totalPrice = products.reduce((sum, product) => sum + product.price, 0);
console.log(`Total price: $${totalPrice}`);
Async Operations#
TypeScript handles async operations elegantly with type safety:
// Async function example
async function fetchData<T>(delay: number, data: T): Promise<T> {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Data fetched!");
resolve(data);
}, delay);
});
}
// Using async/await
async function processData() {
console.log("Fetching data...");
try {
const result = await fetchData(1000, { id: 123, name: "Sample Data" });
console.log("Result:", result);
const numbers = await fetchData(500, [1, 2, 3, 4, 5]);
const sum = numbers.reduce((a, b) => a + b, 0);
console.log("Sum:", sum);
} catch (error) {
console.error("Error:", error);
}
}
// Run the async function
processData();
Rust Shortcode#
Basic Usage#
To add a runnable Rust code snippet to your post, use the rust shortcode like this:
{{</* rust */>}}
// Your Rust code here
fn main() {
println!("Hello from Rust!");
}
{{</* /rust */>}}
This creates an interactive code block with syntax highlighting and a "Run" button. When clicked, the Rust code is compiled and executed remotely, with the output displayed below.
Here's a live example:
fn main() {
// A simple Rust example
// Display some numbers
for i in 0..5 {
println!("The square of {} is {}", i, i * i);
}
}
Using Rust Features#
The Rust shortcode supports many standard Rust features, including structs, enums, traits, and more:
// Define a struct
// Implement methods for the struct
impl Person {
fn new(name: &str, age: u32) -> Self {
Person {
name: String::from(name),
age,
}
}
fn greet(&self) {
println!("Hello, my name is {} and I'm {} years old.", self.name, self.age);
}
}
fn main() {
// Create an instance of Person
let person = Person::new("Alice", 30);
person.greet();
}
Working with Collections#
Rust provides powerful, safe ways to work with collections:
fn main() {
// Working with vectors
let mut numbers = vec![1, 2, 3, 4, 5];
// Map operation (similar to other languages)
let doubled: Vec<i32> = numbers.iter().map(|&n| n * 2).collect();
println!("Doubled numbers: {:?}", doubled);
// Filter operation
let even_numbers: Vec<i32> = numbers.iter().filter(|&&n| n % 2 == 0).cloned().collect();
println!("Even numbers: {:?}", even_numbers);
// Push and modify
numbers.push(6);
numbers.push(7);
println!("Updated vector: {:?}", numbers);
// Using a HashMap
use std::collections::HashMap;
println!("Scores: {:?}", scores);
// Access and update
if let Some(score) = scores.get_mut("Blue") {
*score += 5;
}
println!("Updated Blue score: {:?}", scores.get("Blue"));
}
Error Handling and Result Type#
Rust's approach to error handling is both powerful and expressive:
fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
return Err(String::from("Cannot divide by zero"));
}
Ok(a / b)
}
fn main() {
// Using the Result type for error handling
let results = vec![
divide(10, 2),
divide(5, 0),
divide(8, 4)
];
for (i, result) in results.iter().enumerate() {
match result {
Ok(value) => println!("Result {}: {}", i, value),
Err(error) => println!("Error in result {}: {}", i, error)
}
}
// Using the ? operator for error propagation
fn process_division() -> Result<(), String> {
let result1 = divide(10, 2)?;
println!("First division result: {}", result1);
let result2 = divide(result1, 0)?; // This will return early with an Err
println!("This line won't be reached!");
Ok(())
}
println!("\nAttempting process_division:");
match process_division() {
Ok(_) => println!("All operations succeeded"),
Err(e) => println!("An error occurred: {}", e)
}
}
Ownership and Borrowing#
Demonstrate Rust's unique ownership system with this example:
fn main() {
// Ownership example
let s1 = String::from("hello");
// s1 is moved into the function
let (s2, len) = calculate_length_with_ownership(s1);
// s1 is no longer valid here!
// println!("s1: {}", s1); // This would cause a compilation error
println!("s2: {}, length: {}", s2, len);
// Borrowing example
let s3 = String::from("world");
// s3 is borrowed by the function
let len = calculate_length_with_borrowing(&s3);
// s3 is still valid here
println!("s3: {}, length: {}", s3, len);
// Mutable borrowing
let mut s4 = String::from("hello");
println!("Before: {}", s4);
append_world(&mut s4);
println!("After: {}", s4);
}
// Function that takes ownership
fn calculate_length_with_ownership(s: String) -> (String, usize) {
let length = s.len();
(s, length) // Return the string and its length
}
// Function that borrows its parameter
fn calculate_length_with_borrowing(s: &String) -> usize {
s.len() // Return the length of the borrowed string
}
// Function that mutably borrows its parameter
fn append_world(s: &mut String) {
s.push_str(" world");
}
C++ Shortcode#
Basic Usage#
To add a runnable C++ code snippet to your post, use the cpp shortcode like this:
{{</* cpp */>}}
// Your C++ code here
#include <iostream>
int main() {
std::cout << "Hello from C++!" << std::endl;
return 0;
}
{{</* /cpp */>}}
This creates an interactive code block with syntax highlighting and a "Run" button. When clicked, the C++ code is compiled and executed using WebAssembly, with the output displayed below.
Here's a live example:
#include <iostream>
int main() {
}
Using C++ Features#
The C++ shortcode supports many standard C++ features, including classes, templates, and more:
#include <iostream>
#include <string>
// Define a class
class Person {
private:
std::string name;
int age;
public:
};
int main() {
// Create an instance of Person
Person person("Alice", 30);
person.greet();
return 0;
}
Working with STL Containers#
C++ provides powerful containers and algorithms through the Standard Template Library (STL):
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
int main() {
// Working with vectors
std::vector<int> numbers = {1, 2, 3, 4, 5};
// Map operation (similar to other languages)
std::vector<int> doubled;
std::transform(numbers.begin(), numbers.end(), std::back_inserter(doubled),
[](int n) { return n * 2; });
std::cout << "Doubled numbers: ";
for (int n : doubled) {
std::cout << n << " ";
}
std::cout << std::endl;
// Filter operation
std::vector<int> even_numbers;
std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(even_numbers),
[](int n) { return n % 2 == 0; });
std::cout << "Even numbers: ";
for (int n : even_numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
// Push and modify
numbers.push_back(6);
numbers.push_back(7);
std::cout << "Updated vector: ";
for (int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
// Using a map (similar to HashMap in other languages)
std::map<std::string, int> scores;
scores["Blue"] = 10;
scores["Red"] = 25;
scores["Green"] = 15;
std::cout << "Scores: ";
for (const auto& pair : scores) {
std::cout << pair.first << "=" << pair.second << " ";
}
std::cout << std::endl;
// Access and update
scores["Blue"] += 5;
std::cout << "Updated Blue score: " << scores["Blue"] << std::endl;
return 0;
}
Templates and Generic Programming#
C++ templates enable powerful generic programming:
#include <iostream>
#include <string>
#include <vector>
// Generic function template
// Generic class template
template<typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
T pop() {
if (elements.empty()) {
throw std::out_of_range("Stack is empty");
}
T top = elements.back();
elements.pop_back();
return top;
}
bool isEmpty() const {
return elements.empty();
}
size_t size() const {
return elements.size();
}
};
int main() {
// Using the function template
std::cout << "Adding integers: " << add(5, 3) << std::endl;
std::cout << "Adding doubles: " << add(3.14, 2.71) << std::endl;
std::cout << "Concatenating strings: " << add(std::string("Hello, "), std::string("C++!")) << std::endl;
// Using the class template
Stack<int> intStack;
intStack.push(1);
intStack.push(2);
intStack.push(3);
std::cout << "Integer stack size: " << intStack.size() << std::endl;
std::cout << "Popping from integer stack: " << intStack.pop() << std::endl;
std::cout << "New stack size: " << intStack.size() << std::endl;
Stack<std::string> stringStack;
stringStack.push("Hello");
stringStack.push("World");
std::cout << "String stack size: " << stringStack.size() << std::endl;
std::cout << "Popping from string stack: " << stringStack.pop() << std::endl;
return 0;
}
Memory Management and Smart Pointers#
Demonstrate C++'s modern memory management with smart pointers:
#include <iostream>
#include <memory>
#include <vector>
#include <string>
public:
Resource(const std::string& n) : name(n) {
std::cout << "Resource '" << name << "' created." << std::endl;
}
~Resource() {
std::cout << "Resource '" << name << "' destroyed." << std::endl;
}
void use() const {
std::cout << "Using resource '" << name << "'." << std::endl;
}
};
int main() {
// Scope-based resource management
{
std::cout << "=== Entering inner scope ===" << std::endl;
// Unique pointer - exclusive ownership
std::unique_ptr<Resource> uniqueRes = std::make_unique<Resource>("Unique");
uniqueRes->use();
// Shared pointer - shared ownership
std::shared_ptr<Resource> sharedRes1 = std::make_shared<Resource>("Shared");
{
std::cout << "Reference count: " << sharedRes1.use_count() << std::endl;
auto sharedRes2 = sharedRes1; // Create another reference
std::cout << "Reference count after sharing: " << sharedRes1.use_count() << std::endl;
sharedRes2->use();
} // sharedRes2 goes out of scope here
std::cout << "Reference count after inner scope: " << sharedRes1.use_count() << std::endl;
sharedRes1->use();
// Weak pointer - non-owning reference
std::shared_ptr<Resource> sharedRes3 = std::make_shared<Resource>("Weak Reference Target");
std::weak_ptr<Resource> weakRes = sharedRes3;
std::cout << "Weak pointer expired? " << weakRes.expired() << std::endl;
if (auto res = weakRes.lock()) {
res->use();
} else {
std::cout << "Failed to lock weak pointer." << std::endl;
}
// Reset the shared pointer, releasing the resource
sharedRes3.reset();
std::cout << "After resetting shared pointer, weak pointer expired? " << weakRes.expired() << std::endl;
std::cout << "=== Exiting inner scope ===" << std::endl;
} // All resources are automatically cleaned up here
std::cout << "Back in main scope." << std::endl;
return 0;
}
C++ Examples#
Let's explore some C++ code examples that you can run directly in the browser.
Simple Calculator in C++#
#include <iostream>
int main() {
double num1, num2;
char operation;
std::cout << "Simple Calculator\n";
std::cout << "Enter first number: 5\n";
std::cout << "Enter operation (+, -, *, /): +\n";
std::cout << "Enter second number: 3\n";
num1 = 5;
operation = '+';
num2 = 3;
double result;
switch(operation) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if(num2 != 0)
result = num1 / num2;
else {
std::cout << "Error: Division by zero" << std::endl;
return 1;
}
break;
default:
std::cout << "Error: Invalid operation" << std::endl;
return 1;
}
std::cout << "Result: " << num1 << " " << operation << " " << num2 << " = " << result << std::endl;
return 0;
}
Fibonacci Sequence in C++#
#include <iostream>
#include <vector>
// Function to generate Fibonacci sequence up to n terms
std::vector<int> generateFibonacci(int n) {
std::vector<int> fib;
if (n <= 0) return fib;
fib.push_back(0);
if (n == 1) return fib;
fib.push_back(1);
}
return fib;
}
int main() {
int n = 10;
std::cout << "Generating first " << n << " Fibonacci numbers:" << std::endl;
std::vector<int> fibSequence = generateFibonacci(n);
for (int i = 0; i < fibSequence.size(); ++i) {
std::cout << fibSequence[i];
}
std::cout << std::endl;
return 0;
}
Object-Oriented Programming in C++#
#include <iostream>
#include <string>
#include <vector>
class Shape {
protected:
std::string name;
public:
Shape(const std::string& n) : name(n) {}
virtual double area() const = 0;
virtual void display() const {
std::cout << "Shape: " << name << std::endl;
}
virtual ~Shape() {}
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : Shape("Circle"), radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
void display() const override {
Shape::display();
std::cout << "Radius: " << radius << std::endl;
std::cout << "Area: " << area() << std::endl;
}
};
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double w, double h) : Shape("Rectangle"), width(w), height(h) {}
double area() const override {
return width * height;
}
void display() const override {
Shape::display();
std::cout << "Width: " << width << std::endl;
std::cout << "Height: " << height << std::endl;
std::cout << "Area: " << area() << std::endl;
}
};
int main() {
std::vector<Shape*> shapes;
shapes.push_back(new Circle(5.0));
shapes.push_back(new Rectangle(4.0, 6.0));
std::cout << "Displaying shape information:" << std::endl;
for (const auto& shape : shapes) {
shape->display();
std::cout << "-------------------" << std::endl;
}
// Clean up
for (auto& shape : shapes) {
delete shape;
}
return 0;
}
Important Considerations#
When using these interactive code shortcodes, keep these things in mind:
For Python:#
-
Loading Time: Pyodide may take a moment to load on the first execution, especially on slower connections.
-
Package Availability: While many packages are available, not all Python packages can be used with Pyodide.
-
Performance: Complex computations may run slower in the browser than they would in a native Python environment.
-
Memory Limitations: Browser environments have memory limitations, so very large datasets may cause problems.
For TypeScript:#
-
Browser API Limitations: The TypeScript code runs in a sandboxed environment, so some browser APIs may not be available.
-
No External Imports: You cannot import external modules or packages in the TypeScript snippets.
-
Compilation Errors: TypeScript errors are displayed in the output area, making it easy to debug code.
-
No Persistent State: Each execution starts with a fresh environment; state is not maintained between runs.
For Rust:#
-
Remote Execution: Rust code is compiled and executed on remote servers, which may have usage limitations or occasional downtime.
-
Compilation Time: Rust compilation may take a few seconds, especially for larger code examples.
-
Standard Library: Most standard library features are available, but some platform-specific functionality may be restricted.
-
Memory and Time Limits: There are memory and execution time limits for the compiled code.
For C++:#
-
WebAssembly Limitations: The C++ code is compiled to WebAssembly, which has some limitations compared to native C++.
-
Standard Library Support: Most of the C++ standard library is available, but some features may be restricted.
-
Compilation Time: Complex C++ code may take longer to compile in the browser environment.
-
Memory Management: While the examples demonstrate memory management, the actual behavior in the WebAssembly environment might differ slightly from native C++.
General Considerations:#
-
Security: Code runs either in the user's browser or on remote servers, so avoid including sensitive information or operations.
-
Mobile Compatibility: The interactive code blocks work on mobile devices but may have limited screen space.
Conclusion#
The python, typescript, rust, cpp, and sql shortcodes make your blog posts more interactive and engaging by allowing readers to experiment with code directly. This is particularly useful for tutorials, educational content, or demonstrating programming concepts.
Experiment with Python, TypeScript, Rust, C++, and SQL in your posts and let us know how they work for you!
SQL Shortcode#
Basic Usage#
To add a runnable SQL code snippet to your post, use the sql shortcode like this:
{{</* sql */>}}
-- Your SQL code here
SELECT * FROM example_users;
{{</* /sql */>}}
This creates an interactive code block with syntax highlighting and a "Run" button. When clicked, the SQL query is executed against an in-memory PGlite database, with the results displayed as a formatted table below.
Here's a live example:
-- A simple SQL example
WHERE id <= 3
ORDER BY id;
Creating and Manipulating Tables#
You can also create and manipulate tables in the database:
-- Create a new table
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(10,2) NOT NULL,
category TEXT
);
-- Insert some data
INSERT INTO products (name, price, category)
VALUES
('Laptop', 1200.00, 'Electronics'),
('Smartphone', 800.00, 'Electronics'),
('Coffee Maker', 99.99, 'Kitchen'),
('Headphones', 149.99, 'Electronics'),
('Blender', 79.99, 'Kitchen');
-- Query the data
SELECT * FROM products
ORDER BY price DESC;
Performing JOINS#
SQL joins allow you to combine data from multiple tables:
-- Create a table for categories
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT
);
-- Insert category data
INSERT INTO categories (name, description)
VALUES
('Electronics', 'Electronic devices and accessories'),
('Kitchen', 'Kitchen appliances and tools');
-- Query with JOIN
SELECT
p.id,
p.name,
p.price,
c.name as category_name,
c.description
FROM products p
JOIN categories c ON p.category = c.name
ORDER BY p.price DESC;
Using Aggregate Functions#
SQL's aggregate functions allow you to perform calculations on data:
-- Aggregate queries
SELECT
category,
COUNT(*) as item_count,
ROUND(AVG(price), 2) as avg_price,
MIN(price) as min_price,
MAX(price) as max_price,
SUM(price) as total_value
FROM products
GROUP BY category
ORDER BY total_value DESC;
Complex SQL Queries#
You can run more complex queries to filter and transform data:
-- Create a sales table
CREATE TABLE sales (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES products(id),
quantity INTEGER NOT NULL,
sale_date DATE NOT NULL
);
-- Insert some sales data
INSERT INTO sales (product_id, quantity, sale_date)
VALUES
(1, 2, '2023-01-15'),
(2, 5, '2023-01-20'),
(3, 3, '2023-01-25'),
(4, 2, '2023-02-05'),
(5, 1, '2023-02-10'),
(1, 1, '2023-02-15'),
(2, 3, '2023-02-20');
-- Complex query with JOIN, GROUP BY, and HAVING
SELECT
p.name as product_name,
p.category,
SUM(s.quantity) as units_sold,
SUM(s.quantity * p.price) as revenue
FROM products p
JOIN sales s ON p.id = s.product_id
GROUP BY p.id, p.name, p.category
HAVING SUM(s.quantity) > 2
ORDER BY revenue DESC;
Mermaid Diagrams#
Basic Usage#
Mermaid is a JavaScript-based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. To add a Mermaid diagram to your post, use the mermaid shortcode like this:
{{</* mermaid */>}}
flowchart TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
C --> D[Rethink]
D --> B
B -->|No| E[End]
{{</* /mermaid */>}}
This will create an interactive diagram with controls for zooming, editing, copying the diagram code, and downloading the diagram as an SVG. Here's a live example:
flowchart TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
C --> D[Rethink]
D --> B
B -->|No| E[End]
Important Syntax Notes for Mermaid 11.6.0#
- Use
flowchartinstead ofgraphfor all flowchart diagrams - Ensure node IDs with spaces are quoted:
"Node Name" - Each statement should be on a separate line or use semicolons to separate them
Flowcharts#
Mermaid makes it easy to create flowcharts with different orientations:
flowchart LR
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
Sequence Diagrams#
Sequence diagrams show the sequence of messages/calls between different participants:
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts <br/>prevail!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
Class Diagrams#
Visualize class relationships with class diagrams:
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
State Diagrams#
Represent state machines and transitions:
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
Entity Relationship Diagrams#
Visualize relationships between entities in a database:
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
Gantt Charts#
Create project schedules and timelines:
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2023-01-01, 30d
Another task :after a1, 20d
section Another
Task in sec :2023-01-12, 12d
another task :24d
Pie Charts#
Display data in a simple pie chart:
pie title Pets Adopted by Species
"Dogs" : 386
"Cats" : 265
"Rabbits" : 85
"Guinea Pigs" : 15
Git Graph#
Visualize Git workflows:
gitGraph
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
branch feature
checkout feature
commit
checkout main
commit
merge feature
commit
Conclusion#
The python, typescript, rust, cpp, sql, and mermaid shortcodes make your blog posts more interactive and engaging by allowing readers to experiment with code and visualize concepts directly. This is particularly useful for tutorials, educational content, or demonstrating programming and architectural concepts.
Experiment with these interactive elements in your posts and let us know how they work for you!

Discussion
Join the conversation.
Questions, corrections, and thoughtful detours are welcome.