Bloops is an AoPS-like BBCode to HTML transpiler written in Python, with live-preview and support for Asymptote geometry diagrams.
- AoPS-Inspired Syntax: Transpiles mathematical environments
(
[theorem],[lemma],[example],[soln]), code blocks, lists, quotes, and formatted text directly into clean and SEO-friendly HTML. - Asymptote Integration: Automatically extracts, caches, and
compiles
[asy]blocks into SVG vector graphics using Asymptote. - Live Preview and Server: Built in real-time preview web-server
powered by
livereloadandwatchdogto preview changes instantly into the browser. - Math & Syntax Highlighthing: Pre-configured with MathJax v4 for TeX rendering and Highlight.js (Tokyo Night Dark) for code syntax highlighting.
Writing a document block by block with bloops -pc running:
every save rebuilds index.html and the browser reloads instantly.
bloops-live-preview.mp4
- Python >= 3.12
- Asymptote (
asyexecutable available in your systemPATH) for vector diagram rendering
Install bloops from PyPI. Here is the
PyPI listing.
- I suggest using
uv:- Run
uv tool install bloopsif you'd like to usebloopsjust as a CLI tool. - Run
uv add bloopsif you you'd like to importbloopsas a package in your project.
- Run
- Or, if you want to use
pip: runpip install bloops. - AUR entry is yet to be added.
bloops is executed via the CLI module syntax.
| Flag | Long Flag | Description |
|---|---|---|
-h |
--help |
Show help message for usage of bloops. |
-V |
--version |
Show the version of bloops. |
-c |
--build-cont |
Watch content.bbcode for changes and continuously rebuild index.html. |
-p |
--preview |
Launch a local web live-server to preview index.html. |
-i |
--input |
(Required) Input directory containing content.bbcode. |
-o |
--output |
Output directory for generated assets (defaults to in_dir/static/). |
Tip
The most useful way to use bloops is to simultaneously
run a live-preview alongside continuous compilation: to do this, use the -pc flag
while calling bloops.
Help Summary
usage: bloops [-h] [-v] [-c] [-p] -i INDIR [-o OUTDIR]
An AoPS-like BBCode to HTML transpiler written in Python, featuring live-preview support and dynamic Asymptote geometry diagram compilation.
options:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-c, --build-cont convert BBCode to HTML and continuously write to index.html on change
-p, --preview run a preview of index.html on the web-browser
-i, --input INDIR directory path which contains the BBCode file
-o, --output OUTDIR optional directory path where generated Asymptote diagrams are to be savedmy_document/
├── content.bbcode # Your source BBCode document
├── index.html # Generated HTML page
├── build/ # Asymptote build cache and temporary .asy files
└── static/
├── style.css # Stylesheet for rendered document
└── diagram1.svg # Compiled Asymptote vector diagramsBloops uses BBCode syntax inspired by AoPS. Here are reference tables for each BBCode tag bloops uses:
[asy]
| Option | Mandatory | Description |
|---|---|---|
src |
YES | Path to the saved image (relative to content.bbcode). |
label |
YES | Label of the diagram which will be used as the filename (must be unique). |
width |
- | Width in percentage (without % symbol) relative to the body width. |
alt |
- | Alternate text to be shown if the image fails to load. |
caption |
- | Caption for the diagram. |
[code]
| Option | Mandatory | Description |
|---|---|---|
lang |
- | Language used in the code block (tries to detect the language if argument is not provided). |
mode |
- | inline or block (default: block) |
[color]
| Option | Mandatory | Description |
|---|---|---|
hex |
YES | Color code in hex (with the leading #). |
[img]
| Option | Mandatory | Description |
|---|---|---|
src |
YES | Path to the saved image (relative to content.bbcode). |
width |
- | Width in percentage (without % symbol) relative to the body width. |
alt |
- | Alternate text to be shown if the image fails to load. |
caption |
- | Caption for the image. |
[url]
| Option | Mandatory | Description |
|---|---|---|
link |
YES | URL link. |
target |
- | Target for opening the URL: [self, blank] (defaults to blank). |
self: opens the URL in the current page.
blank: opens the URL in a new page.
[list]
| Option | Mandatory | Description |
|---|---|---|
type |
- | Type of the list: [ul, ol] (defaults to ul). |
style |
- | Style of the list marker. |
Google “list styles in css” for valid styles.
[quote]
| Option | Mandatory | Description |
|---|---|---|
author |
- | Name of the author. |
link |
- | Link to the quote for citation (will not be visible in page, used for SEO). |
[hide]
| Option | Mandatory | Description |
|---|---|---|
label |
YES | Label to be used as the summary for hidden details. |
math environments
Currently, the following math box tags are supported:
[theorem], [lemma], [proposition], [corollary],
[example], [claim], [problem], and [exercise].
There is only one option for each math box: title.
| Option | Mandatory | Description |
|---|---|---|
title |
- | An optional title for math boxes to be put within parentheses in the heading. |
Apart from these, bloops also provides [proof] and [soln] for
proof and solutions.
tags without any options
| Tag | Purpose |
|---|---|
[sidemark][/sidemark] |
To put a number in the subscript for a sidenote. |
[sidenote]<your-note>[/sidenote] |
To write a note to be put aside. |
| Tag | HTML Counterpart |
|---|---|
[b] |
<strong> |
[i] |
<em> |
[u] |
<u> |
[s] |
<s> |
[*] |
<li> |
[sub] |
<sub> |
[sup] |
<sup> |
[h1] |
<h1> |
[h2] |
<h2> |
[h3] |
<h3> |
[h4] |
<h4> |
[h5] |
<h5> |
[h6] |
<h6> |
An example showcasing the use of tags mentioned above has been provided in example/content.bbcode and the corresponding generated HTML file is present in example/index.html.
Bloops provides the following public modules and functions:
| Module | Functions |
|---|---|
validator |
validate_bbcode & compile_asy_diagrams |
bloopser |
convert_bbcode_to_html |
bracer |
gobble_inside_delim, gobble_around_delim, & get_close_delim_end_index |
If you want to convert a BBCode text into HTML using bloops,
first run validate_bbcode, then compile_asy_diagrams, and
finally convert_bbcode_to_html on the text.
Bloops also provides the BBCODE_TAGS global constant
under the vars module.
A detailed documentation of these API endpoints can be found in docs/api.md.
Q: Why are my images not loading even though the src path is valid?
Answer.
Make sure that the image can be reached without leaving
the directory in which index.html and content.bbcode reside.
The suggested place for images to reside is at static/ as shown
in the example under Directory Structure.
In general, the image should be reachable starting from
my_document/, as in the example.
This is due to a caveat of
python-livereload. The directories that are being used to serve static files need to be registered before the server is launched. Hence, it is not possible to add random directories dynamically into the live-server.
Q: How do I use my own stylesheet?
Answer.
Bloops creates a stylesheet at static/style.css given that the file doesn't
already exist; otherwise, it does nothing.
So, there are two ways you could use a custom stylesheet:
- Create/Edit the stylesheet at
static/style.cssand put your custom style in it. - Import a style sheet into
static/style.cssby adding@import url("<path-to-your-stylesheet>")tostatic/style.css.
Q: How do I use my own javascript code?
Answer.
Same as the previous FAQ. Use static/script.js.
Contributions are very welcome! Please read CONTRIBUTING.md for a guide on how to contribute. I'm against the idea of using AI for writing hobby projects; however, I have no problem if someone else uses them. If you're using AI assistance for contributing, please mention so in your PR. (No AI has been used in this project except for generating docstrings, the TokyoNight-Night based CSS stylesheet, and the preview demos/banner.)
- Implement a post-processor which adds paragraph tags around every disjoint block of HTML code.
- Shift avatar to integration server.
- Handle
[or]inside arguments of BBCode tags. (I'll be very glad if someone suggests me a solution for this; I've thought about it myself, but couldn't really come up with anything.) - Switch lists to sets to optimize speed.
- Currently, using BBCODE content inside
[code]is broken, since bloops eagerly formats the BBCODE inside[code]too.

