CBD // ARCHIVE

Coffee Byte Dev

43 DOCS ยท 200K WORDS ยท IDX 2026.09
Flavors

Brewdown

โ˜• Brewdown

Brewdown is the Markdown-flavored converter used across Coffee Byte Dev. It's plain Markdown with the extensions this site kept needing โ€” media embedding, spoilers, click-to-copy, collapsible sections, and a table of contents.

This page is the reference. It's written as static HTML rather than as a Brewdown paper, because a Brewdown paper cannot document Brewdown โ€” showing raw syntax would trigger the converter. So this page shows the syntax in code blocks and describes what each one does.


How It Works

Every paper is a markdown file in papers/. The page fetches the file, hands the text to Brewdown.brewdown(), and inserts the resulting HTML into the paper sheet. brewdown.js itself does no fetching โ€” the caller owns that.

If a highlight.js build is on the page, Brewdown calls hljs.highlightElement() on each fenced block after rendering so code picks up syntax colors. highlight.min.js must load before brewdown.js, or the check fails and code blocks render plain.


Text Formatting

**bold**
*italic*
~~strikethrough~~
__underline__
`inline code`
!!spoiler, click to reveal!!
^^click to copy^^

Headings

# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6

H1 through H3 auto-collect into the table of contents. Every heading gets an id auto-slugified from its text, so links can scroll to it.


[Link Text](https://example.com)

External links (http/https, or any URL ending in .pdf) open in a new tab and get a ๐Ÿ”— indicator prepended. Links whose URL ends in .zip get a ๐Ÿ’พ indicator, whether or not they're external.

Internal links stay in the same tab and carry no indicator. Bare URLs are not auto-linked โ€” if you want a link, write one.


Media Embedding

Use the image syntax for everything โ€” Brewdown reads the file extension and picks the right HTML element.

![alt text](photo.jpg)        -> <img>
![alt text](video.mp4)        -> <video controls>
![alt text](song.mp3)         -> <audio controls>
![alt text](document.pdf)     -> opens in new tab

Image: jpg, jpeg, png, gif, webp, svg, bmp, ico, avif

Video: mp4, webm, ogg, mov

Audio: mp3, wav, flac, aac, m4a

Anything else: opens in a new tab.

Consecutive media-only lines are gathered into a flex gallery.


Code Blocks

function hello() {
    console.log("Hello, world!");
}

The language tag drives highlight.js. Without one, the block renders plain.

To color the changelog, fence the block as changelog and prefix lines with #, @, +, -, >, or $. Each prefix gets its own color, injected at load by scripts.js.


Blockquotes

> This is a blockquote.
> It can span multiple lines.

Tables

| Name   | Role   |
|--------|--------|
| Alice  | Admin  |
| Bob    | User   |

A first column header of # makes that column a narrow index column.


Checkboxes

[ ] Unchecked
[x] Checked

Horizontal Rules

---

Spoilers

Click-to-reveal hidden text.

!!This text is hidden until clicked.!!

Renders as <span class="spoiler"> with a click handler that toggles the revealed class.


Click-to-Copy

Click the rendered text to copy its content to the clipboard.

^^npm install foo^^

Renders as <span class="copy"> with a click handler that writes data-copy to the clipboard via navigator.clipboard.writeText.


Collapsible Sections

Wraps content in a <details>/<summary> pair. The <details> gets an id auto-slugified from its title, so links can scroll to it โ€” but collapsibles are not auto-listed in the TOC.

>>> Click to expand
Content goes here.
More content.
<<<

Nesting works:

>>> Outer
>>> Inner
Nested content.
<<<
<<<

Table of Contents

Write ::toc:: on its own line to place a table of contents. H1 through H3 auto-collect as sections are scanned.

::toc::

## First Section
Content here.

## Second Section
More content.

Renders as <pre class="brewdown-toc"> with a bold TABLE OF CONTENTS header. Indentation follows heading depth. Clicking a link scrolls via native browser behavior.

When a paper includes other markdown via <script data-brewdown>, the TOC is rebuilt after those includes land, so their headings appear too.


API

The global Brewdown object exposes:

// Convert a markdown string to HTML
const html = Brewdown.brewdown(markdownText);

// With options
const html = Brewdown.brewdown(markdownText, {
    wrapInContainer: true,
    containerClass: 'my-class'
});

// Process <script data-brewdown> tags already in the DOM
Brewdown.processScriptTags();

// Process <div class="brewdown"> blocks
Brewdown.processBrewdownDivs();

// Rebuild any ::toc:: after late includes land
Brewdown.rebuildToc();

Brewdown is a custom Markdown variant built for Coffee Byte Dev. It is not a standard and not compatible with CommonMark. The syntax above is what this site actually uses.