Skip to main content

Publish to PyPI

md2bbcode logo, original image 'A Specious Origin' by Jerry LoFaro.

md2bbcode

Converts most GitHub-flavored Markdown and HTML to XenForo-flavored BB code. It uses Mistune. You can also configure it to work with your favorite ancient community.

Installation

pipx install md2bbcode

Usage

md2bbcode README.md

Output prints to stdout as UTF-8. To write straight to a file (recommended on Windows, where shell > redirection can mangle the encoding), use -o:

md2bbcode README.md -o output.bbcode

Relative paths

Use --domain to turn relative links and image paths, such as guide.md and images/logo.png, into full URLs:

md2bbcode README.md --domain https://example.com/docs/

For GitHub, use the repo URL. This assumes you use the default branch:

md2bbcode README.md --domain https://github.com/RedGuides/md2bbcode
Advanced URL options

For a different GitHub branch, or a Markdown file that lives in a subfolder of the repo, pass that folder's GitHub URL to --domain, for example https://github.com/RedGuides/md2bbcode/tree/dev/docs.

For other sites, --domain uses the same base URL for links and images. To set separate base URLs, use --link-base and --image-base:

md2bbcode README.md --link-base https://github.com/RedGuides/md2bbcode/blob/main/ --image-base https://raw.githubusercontent.com/RedGuides/md2bbcode/main/

Full URLs and URLs starting with //host/path are left unchanged.

Your board's custom BB codes

XenForo has no built-in tag for highlights, superscript, subscript, abbreviations, anchors, and others, so md2bbcode writes those with custom BB codes. By default it assumes your board has the RedGuides set of custom BB codes.

If your board has its own custom BB codes, export them at admin.php?bb-codes in XenForo and use them:

md2bbcode README.md --bb-codes bb_codes.xml

md2bbcode checks the HTML each BB code produces to find the right tag for your board. For example, if [highlight] produces <mark>{text}</mark>, then ==text== becomes [HIGHLIGHT]text[/HIGHLIGHT].

If your board has no matching BB code, md2bbcode uses a simpler alternative, such as plain text, inline code, or a quote.

Use --no-custom-bbcode if your board has only default XenForo BB code.

Changing a tag

Put the settings you want to change in a TOML file, such as myboard.toml. This example changes inline code to [CODE] and turns off highlighting:

[tags]
codespan = "[CODE]{text}[/CODE]"
mark = "{text}"

{text} keeps the content. Using it alone removes the surrounding tag, so ==highlighted text== becomes plain text. These settings apply to HTML in your Markdown too.

Apply your config with --config:

md2bbcode README.md --config myboard.toml

To find other tag names and see their current settings, use --dump-config:

md2bbcode --dump-config
More config options

Your config only needs the settings you want to override. Add -o myboard.toml to the dump command to start from a full config, or --bb-codes bb_codes.xml to inspect the tags detected from your board's export.

To remove unsupported HTML tags instead of keeping them, add this above [tags]. Their content is kept:

unknown_html = "strip"

A config can also name your board's export, so you don't need --bb-codes each time. The path is relative to the config file:

bb_codes = "bb_codes.xml"

You can use the environment variables MD2BBCODE_CONFIG and MD2BBCODE_BB_CODES instead of --config and --bb-codes.

HTML files

md2bbcode also installs html2bbcode, which converts an HTML file the same way md2bbcode converts the HTML inside Markdown. It takes the same -o, --domain, --config and --bb-codes options:

html2bbcode page.html -o output.bbcode

Use in Python

from md2bbcode import convert

bbcode = convert("# Hell World")
print(bbcode)

Use domain for relative links and images, with the same automatic GitHub handling as the CLI:

bbcode = convert(
    markdown_text,
    domain="https://github.com/yourusername/yourrepo",
)
Custom BB code in Python

Use Dialect to apply a TOML config:

from md2bbcode import Dialect, convert

bbcode = convert(markdown_text, dialect=Dialect.load("myboard.toml"))

Or just your board's BB code export (bb_codes=False for a board with none):

bbcode = convert(markdown_text, dialect=Dialect.defaults(bb_codes="bb_codes.xml"))

Development

You need Hatch, which you can install with pipx install hatch. Then clone the repository and run the tests:

git clone https://github.com/RedGuides/md2bbcode.git
cd md2bbcode
hatch test
How the code fits together
  • main.py has the commands and convert().
  • plugins.py and html_tokens.py turn the HTML inside Markdown into tokens, because Mistune does not.
  • renderer.py is the Mistune renderer that turns the tokens into BB code.
  • dialect.py holds the tag settings, which start from dialects/xenforo.toml. bb_codes.py reads a board's BB code export.
  • image_rewrite.py points SVG images at a service that serves them as PNG, which XenForo can show.

Each Markdown file in tests/fixtures has its expected BB code saved beside it. After a change that is meant to alter the output, update the saved files and check the diff:

hatch test -- --update-goldens

To see how your Markdown and HTML were read, print the tokens the renderer works from. md2ast input.md output.json does the same:

md2bbcode README.md --ast

Metadata

Release files for md2bbcode 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for md2bbcode 2.1.0
File Size Uploaded
md2bbcode-2.1.0.tar.gz 47.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for md2bbcode 2.1.0
File Interpreter ABI Platform
md2bbcode-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 99.4 kB

Release files / md2bbcode-2.1.0.tar.gz

Download URL md2bbcode-2.1.0.tar.gz
Size 47.2 kB
Tags Source
SHA-256 checksum
How to use checksums
82c7e9b49a14514ddffec387d849031ede7fa6a0cab76b7abfee9efa2339fae8
BLAKE2b-256 checksum
How to use checksums
50aa0d86b364ffa0b5bdc06599f2041cc08953620bae846575fb1d0b73a3758f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / md2bbcode-2.1.0-py3-none-any.whl

Download URL md2bbcode-2.1.0-py3-none-any.whl
Size 52.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6c774097ba8e3bc7abacbfeb2dc7aae78c92e5fd663eafe749b154f9b4d7779b
BLAKE2b-256 checksum
How to use checksums
89bad77cb0db0067142d16f42984eed55212d946e73d16e9dc2ac7074920130f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files

2.0.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.4

2 release files

1.0.3

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page