Automatically execute code blocks within a Markdown file and update the output in-place
Project description
:rocket: Markdown Code Runner
markdown-code-runner
is a Python package that automatically executes code blocks within a Markdown file and updates the output in-place. This package is particularly useful for maintaining Markdown files with embedded code snippets, ensuring that the output displayed is up-to-date and accurate.
The package is hosted on GitHub: https://github.com/basnijholt/markdown-code-runner
:question: Problem Statement
When creating Markdown files with code examples, it's essential to keep the output of these code snippets accurate and up-to-date. Manually updating the output can be time-consuming and error-prone, especially when working with large files or multiple collaborators.
markdown-code-runner
solves this problem by automatically executing the code blocks within a Markdown file and updating the output in-place. This ensures that the displayed output is always in sync with the code.
:books: Table of Contents
- :computer: Installation
- :rocket: Quick Start
- Usage
- :book: Examples
- :bulb: Usage Ideas
- :page_with_curl: License
- :handshake: Contributing
:computer: Installation
Install markdown-code-runner
via pip:
pip install markdown-code-runner
:rocket: Quick Start
To get started with markdown-code-runner
, follow these steps:
- Add code blocks to your Markdown file between
<!-- START_CODE -->
and<!-- END_CODE -->
markers. - Place the output of the code blocks between
<!-- START_OUTPUT -->
and<!-- END_OUTPUT -->
markers.
Example:
This is an example code block:
<!-- START_CODE -->
<!-- print('Hello, world!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
This content will be replaced by the output of the code block above.
<!-- END_OUTPUT -->
- Run
markdown-code-runner
on your Markdown file:
markdown-code-runner /path/to/your/markdown_file.md
- The output of the code block will be automatically executed and inserted between the output markers.
Usage
To use markdown-code-runner
, simply import the update_markdown_file
function from the package and call it with the path to your Markdown file:
from markdown_code_runner import update_markdown_file
from pathlib import Path
update_markdown_file(Path("path/to/your/markdown_file.md"))
:book: Examples
Here are a few examples demonstrating the usage of markdown-code-runner
:
:star: Example 1: Simple code block
This is an example of a simple code block:
<!-- START_CODE -->
<!-- print('Hello, world!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
This content will be replaced by the output of the code block above.
<!-- END_OUTPUT -->
After running markdown-code-runner
:
This is an example of a simple code block:
<!-- START_CODE -->
<!-- print('Hello, world!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
<!-- THIS CONTENT IS AUTOMATICALLY GENERATED -->
Hello, world!
<!-- END_OUTPUT -->
:star: Example 2: Multiple code blocks
Here are two code blocks:
First code block:
<!-- START_CODE -->
<!-- print('Hello, world!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
This content will be replaced by the output of the first code block.
<!-- END_OUTPUT -->
Second code block:
<!-- START_CODE -->
<!-- print('Hello again!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
This content will be replaced by the output of the second code block.
<!-- END_OUTPUT -->
After running markdown-code-runner
:
Here are two code blocks:
First code block:
<!-- START_CODE -->
<!-- print('Hello, world!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
<!-- THIS CONTENT IS AUTOMATICALLY GENERATED -->
Hello, world!
<!-- END_OUTPUT -->
Second code block:
<!-- START_CODE -->
<!-- print('Hello again!') -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
<!-- THIS CONTENT IS AUTOMATICALLY GENERATED -->
Hello again!
<!-- END_OUTPUT -->
:bulb: Usage Ideas
Markdown Code Runner can be used for various purposes, such as creating Markdown tables, generating visualizations, and showcasing code examples with live outputs. Here are some usage ideas to get you started:
:gear: Idea 1: Continuous Integration with GitHub Actions
You can use markdown-code-runner
to automatically update your Markdown files in a CI environment.
The following example demonstrates how to configure a GitHub Actions workflow that updates your README.md
whenever changes are pushed to the main
branch.
-
Create a new workflow file in your repository at
.github/workflows/markdown-code-runner.yml
. -
Add the following content to the workflow file:
name: Update README.md
on:
push:
branches:
- main
jobs:
update_readme:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
persist-credentials: false
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install markdown-code-runner
run: |
python -m pip install --upgrade pip
pip install markdown-code-runner
# Install dependencies you're using in your README.md
- name: Install other Python dependencies
run: |
pip install pandas tabulate pytest matplotlib requests
- name: Run update-readme.py
run: markdown-code-runner README.md
- name: Commit updated README.md
run: |
git add README.md
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git diff --quiet && git diff --staged --quiet || git commit -m "Update README.md"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
- Commit and push the workflow file to your repository. The workflow will now automatically run whenever you push changes to the
main
branch, updating yourREADME.md
with the latest outputs from your code blocks.
For more information on configuring GitHub Actions, check out the official documentation.
:computer: Idea 1: Show command-line output
Use markdown-code-runner
to display the output of a command-line program. For example, the following Markdown file shows the helper options of this package:
<!-- START_CODE -->
<!-- import subprocess -->
<!-- out = subprocess.run(["markdown-code-runner", "--help"], capture_output=True, text=True) -->
<!-- print(f"```bash\n{out.stdout}\n```") -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
<!-- END_OUTPUT -->
Which is rendered as:
usage: markdown-code-runner [-h] [-o OUTPUT] [-d] input
Automatically update Markdown files with code block output.
positional arguments:
input Path to the input Markdown file.
options:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Path to the output Markdown file. (default: overwrite
input file)
-d, --debug Enable debugging mode (default: False)
:bar_chart: Idea 2: Generating Markdown Tables
Use the pandas
library to create a Markdown table from a DataFrame. The following example demonstrates how to create a table with random data:
import pandas as pd
import numpy as np
# Generate random data
np.random.seed(42)
data = np.random.randint(1, 101, size=(5, 3))
# Create a DataFrame and column names
df = pd.DataFrame(data, columns=["Column A", "Column B", "Column C"])
# Convert the DataFrame to a Markdown table
print(df.to_markdown(index=False))
Which is rendered as:
Column A | Column B | Column C |
---|---|---|
52 | 93 | 15 |
72 | 61 | 21 |
83 | 87 | 75 |
75 | 88 | 100 |
24 | 3 | 22 |
:art: Idea 3: Generating Visualizations
Create a visualization using the matplotlib
library and save it as an image. Then, reference the image in your Markdown file. The following example demonstrates how to create a bar chart:
import matplotlib.pyplot as plt
import io
import base64
from urllib.parse import quote
# Example data for the plot
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
# Create a simple line plot
plt.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.title("Sample Line Plot")
# Save the plot to a BytesIO buffer
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close()
# Encode the buffer as a base64 string
data = base64.b64encode(buf.getvalue()).decode('utf-8')
# Create an inline HTML img tag with the base64 string
from urllib.parse import quote
img_html = f'<img src="data:image/png;base64,{quote(data)}" alt="Sample Line Plot"/>'
print(img_html)
:star: Idea 4: Generating a table from CSV data
Suppose you have a CSV file containing data that you want to display as a table in your Markdown file.
You can use pandas
to read the CSV file, convert it to a DataFrame, and then output it as a Markdown table.
<!-- START_CODE -->
<!-- import pandas as pd -->
<!-- csv_data = "Name,Age,Score\nAlice,30,90\nBob,25,85\nCharlie,22,95" -->
<!-- with open("sample_data.csv", "w") as f: -->
<!-- f.write(csv_data) -->
<!-- df = pd.read_csv("sample_data.csv") -->
<!-- print(df.to_markdown(index=False)) --> -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
Output will appear here.
<!-- END_OUTPUT -->
Which is rendered as:
Name | Age | Score |
---|---|---|
Alice | 30 | 90 |
Bob | 25 | 85 |
Charlie | 22 | 95 |
:star: Idea 5: Displaying API data as a list
You can use markdown-code-runner
to make API calls and display the data as a list in your Markdown file.
In this example, we'll use the requests
library to fetch data from an API and display the results as a list.
<!-- START_CODE -->
<!-- import requests -->
<!-- response = requests.get("https://jsonplaceholder.typicode.com/todos?_limit=5") -->
<!-- todos = response.json() -->
<!-- for todo in todos: -->
<!-- print(f"- {todo['title']} (User ID: {todo['userId']}, Completed: {todo['completed']})") -->
<!-- END_CODE -->
<!-- START_OUTPUT -->
Output will appear here.
<!-- END_OUTPUT -->
Which is rendered as:
- delectus aut autem (User ID: 1, Completed: False)
- quis ut nam facilis et officia qui (User ID: 1, Completed: False)
- fugiat veniam minus (User ID: 1, Completed: False)
- et porro tempora (User ID: 1, Completed: True)
- laboriosam mollitia et enim quasi adipisci quia provident illum (User ID: 1, Completed: False)
These are just a few examples of how you can use Markdown Code Runner to enhance your Markdown documents with dynamic content. The possibilities are endless!
:page_with_curl: License
markdown-code-runner
is released under the MIT License. Please include the LICENSE file when using this package in your project, and cite the original source.
:handshake: Contributing
Contributions are welcome! To contribute, please follow these steps:
- Fork the repository on GitHub: https://github.com/basnijholt/markdown-code-runner
- Create a new branch for your changes.
- Make your changes, ensuring that they adhere to the code style and guidelines.
- Submit a pull request with a description of your changes.
Please report any issues or bugs on the GitHub issue tracker: https://github.com/basnijholt/markdown-code-runner/issues
Thank you for your interest in markdown-code-runner
!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file markdown-code-runner-1.0.0.tar.gz
.
File metadata
- Download URL: markdown-code-runner-1.0.0.tar.gz
- Upload date:
- Size: 11.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 70c7a5c8156b0b66ba60478323dd984ea1ea90dd6fe05100bc7a6b1ed8759527 |
|
MD5 | 95015c22d4d4608d1dde01a71036af37 |
|
BLAKE2b-256 | 16a5236418596820b537b04d86262a2169ad7db36bd75970352881b26c08e3f1 |
File details
Details for the file markdown_code_runner-1.0.0-py3-none-any.whl
.
File metadata
- Download URL: markdown_code_runner-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6601a695a3ed3920615bd73aa62f5ce39ea446eea9ef2939bb920fea0d209560 |
|
MD5 | b341cf1c98be5a0da5bc8bb50a5791d4 |
|
BLAKE2b-256 | 2fcaa9cab228a634ddfe5a1ac9a5677805387b31ba6630795134552ca3467f53 |