bananamark

中文文档
0.2.1发布于 2026/11/03MITES Module

A Markdown dialect for mathematical writing: formulas, numbered sections and theorems, cross-references, bibliographies, wiki links and Chinese typography, rendered to HTML

原始使用文档
文档目录8 节
  1. Install
  2. From the command line
  3. In a program
  4. Syntax
  5. Packages
  6. Documentation
  7. Status
  8. Contributing

bananamark

bananamark is a Markdown dialect for mathematical writing. It adds TeX formulas, numbered sections and theorems, and cross-references to Markdown, and renders documents to HTML.

## Groups

::: definition [Group] {@def:group}
A **group** is a set with an associative operation, an identity $e$ and inverses.
:::

By @def:group, every group has an identity.

Here the section is numbered 1, the definition is titled "Definition 1.1 (Group)", and the reference becomes a link reading "Definition 1.1".

It also supports bibliographies, footnotes, TikZ diagrams and Chinese typography. It can be used as a command or as a library, and it renders the pages of 香蕉空间, a Chinese mathematics wiki.

Install

npm install bananamark       # in a project
npm install -g bananamark    # for the command, anywhere

Or without installing: npx bananamark file.md. Node 22 or later.

From the command line

bananamark file.md

writes file.html beside the file: a whole page holding its stylesheets and fonts, which opens by itself and works offline. An error names its line (file.md:5: unknown theorem environment: nope), and the command exits with status 1.

OptionMeaning
-o, --output <file>Where the HTML goes; - for standard output
--fragmentOnly the body's HTML, to put in a page of your own (style it with bananamark/style.css and bananamark/katex.css)
--css <file or URL>A stylesheet added after the others, so that it takes priority: a file is embedded, a URL linked. Can be given several times
--no-default-styleLeaves out bananamark's look and the page's layout, keeping only what formulas need
--lang <code>The page's language: zh-cn gives Chinese typography and 定理, 证明…; over the front matter's; default en
--locale <code>The language of errors, en or zh-cn; default en
--dialect <file>A module holding the dialect (below)
--tikzCompile TikZ diagrams (below)
-h, --help; -v, --version

With - as the file, it reads standard input and writes standard output.

Stylesheets. A page holds KaTeX's stylesheet and fonts, bananamark's stylesheet and a few lines of layout. A file given with --css comes after these, so a few rules are enough to change the look. The colours of environments are custom properties:

/* mine.css, for bananamark file.md --css mine.css */
:root { --bm-accent-theorem: crimson; }
a { color: teal; }
body { font-family: sans-serif; }

To start from nothing, add --no-default-style. The addresses in an embedded file start from the page, not from the file.

Front matter. A YAML block at the start of the file, between lines of ---, is optional. The command reads title (shown as the page's heading, and it may hold formulas), lang, numbering and typography (see Numbering and Typography), and ignores other fields.

---
title: Groups and $\mathbb{Z}$
lang: en
---

## Definition {@sec:def}
…

Without a title, the page's title is its first heading's text or, failing that, the file's name. Relative image addresses are written as they are, so they hold from where the HTML is.

What it reads. Bibliographies are on and every code language is highlighted; wiki links are off, since a single file has no site for them to go to, so [[…]] stays text. To change this, or add macros, give --dialect a module exporting the dialect's settings. It needs no import, so it works wherever the command is installed:

// dialect.mjs
export default { wikiLinks: true, katex: { macros: { '\\RR': '\\mathbb{R}' } } };

A module may instead export what defineDialect returned (as its default, or as dialect), which is then used as it is. That needs the same copy of bananamark as the command, so install both in the project.

TikZ. Diagrams need the separate package bananamark-tikz, installed beside bananamark. With --tikz (or a dialect with tikz: true) they are compiled to SVG, and their fonts are put in the page too; without it, ```tikz blocks are ordinary code blocks. To try it without installing: npx -p bananamark -p bananamark-tikz bananamark file.md --tikz.

In a program

import { renderDocument } from 'bananamark';
import 'bananamark/katex.css';   // with a bundler; or serve katex/dist/ of the same KaTeX version, 0.18.4
import 'bananamark/style.css';   // a plain look, to start from

const source = '## Groups {@sec:groups}\n\n::: definition [Group] {@def:group}\nA set with an operation…\n:::\n\nBy @def:group, $e$ is unique.';
const result = renderDocument(source, { file: 'groups.md' });
result.html;       // the body's HTML: "Definition 1.1 (Group)", "By Definition 1.1, …"
result.headings;   // [{ level: 2, id: 'groups', number: '1', title: 'Groups' }]

To render many pages, make a processor once:

import { createProcessor, defineDialect } from 'bananamark';

const dialect = defineDialect({ wikiLinks: true, bibliography: true });
const processor = createProcessor({
  dialect,
  resolveWikiLink: target => articles.has(target) ? { url: `/wiki/${encodeURIComponent(target)}/` } : undefined,
});
for (const [file, source] of pages) output.set(file, processor.render(source, { file }).html);

A page's front matter is the caller's: remove it before rendering, and give lineOffset (the number of lines before the body) so that errors point at the file's own lines.

Syntax

CommonMark with GFM tables, strikethrough and footnotes, and:

FeatureWritten
Formulas$…$, \(…\); display $$…$$, \[…\]; numbered: a ```math {@eq:label} block
Sections## headings are numbered; ## Title* is not; {@sec:label} at the end declares a label
Theorem-like environments::: theorem [Title] {@thm:label} … :::; ::: definition (Name) gives the environment its own name, remark* is unnumbered; ::: proof (kinds: see Default environments)
Cross-references@label, {@label}, @-label (the number alone), [text](@label)
Labelled list items(a), iv), (A1) and the like as list markers; (a) {@it:label} text can be referred to
Data blocksfenced blocks the caller names, holding data about the page, not shown (see Data blocks)
HTML-style tags<lang de>…</lang>; the caller may add its own, and bananamark's ready-made <align right>…</align> and <spoiler title="…">…</spoiler> (see HTML-style tags)
Image width![caption](image.png){width=200}: width (whole pixels) becomes <img width>
TypographyChinese typography (see Typography); straight quotation marks become curly ones (see Quotation marks), --, --- and ... become –, —, …
Bare addresseshttps://…, http://…, www.… and e-mail addresses become links, also right after Han characters. An address is in ASCII and ends at the first character that is not; ?!.,:;*_~ and unbalanced ) at its end are not part of it. Write others as [text](…) or <…>
Wiki links (wikiLinks)[[Target]], [[Target|text]]; the target may hold formulas
Bibliographies (bibliography)a ```bibliography block (YAML; fields: see Bibliography fields); @key in the text cites an entry
TikZ (tikz)a ```tikz block ({caption="…"} after tikz gives it a caption), tikzcd and tikzpicture environments in formulas (compiled by bananamark-tikz)

The last three are off unless the dialect turns them on (see The dialect): otherwise [[…]] is text, and ```bibliography and ```tikz blocks are ordinary code blocks.

In these docs a label is the target of a reference ({@thm:a}); <lang> and the like are HTML-style tags. The reference describes each feature in full, and the spec files show every one with examples.

Packages

PackageWhat for
bananamark (this one)Rendering pages to HTML, in Node or in a browser
bananamark-tikzTikZ diagrams (```tikz blocks, tikzcd in formulas) compiled to SVG; Node only
bananamark-codemirrorEditing the dialect in CodeMirror 6: highlighting, completion, checking as you type

A site renders with bananamark (plus bananamark-tikz for diagrams); an editor in the browser adds bananamark-codemirror. Describe the site's dialect once with defineDialect, in a module of its own, and give it to each, so that the editor reads pages as the renderer does:

// dialect.js, imported by the site's build and by its editor
import { alignTag, defineDialect } from 'bananamark';
export const dialect = defineDialect({ wikiLinks: true, tags: { align: alignTag } });

// the build
createProcessor({ dialect, resolveWikiLink });
// the editor
new EditorView({ extensions: [basicSetup, bananamark({ dialect })] });   // bananamark-codemirror

Documentation

  • REFERENCE.md: everything in detail: the syntax, options, hooks, the result and its errors, messages, extending, books, the HTML, typography, KaTeX, highlighting and the API.
  • test/spec/: the conformance examples, which are the dialect's specification, kept in the repository (not in the npm package).
  • CHANGELOG.md: what changed in each version.

Status

  • Version 0.2. Until 1.0, a minor version (0.3) may change the interface and the HTML the spec describes; a patch version (0.2.1) does not. The three packages are released together with the same version; bananamark-codemirror and bananamark-tikz take bananamark as a peer dependency of the same minor version.
  • Node 22 and later; browsers from 2023 on (the stylesheet needs :has()).
  • ES modules only. No TypeScript types yet.
  • MIT licence.

Contributing

Tests, the spec's examples and how to update them: see CONTRIBUTING.md.

版本与发布记录

bananamark 共发布 4 个版本,首次发布于 2026/10/28;过去 12 个月发布了 4 个版本。

版本发布日期距今
0.2.1latest2026/11/03今天
0.2.02026/11/012 天前
0.1.02026/10/286 天前
0.0.0-stage2026/10/286 天前

关于 bananamark 的常见问题

bananamark 是什么?

用于数学写作的Markdown方言:公式,编号章节和定理,交叉引用,参考书目,维基链接和中文排版,呈现为HTML

如何安装 bananamark?

在项目目录运行 npm install bananamark,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@lezer/common(^1.5.3)、@lezer/markdown(^1.8.0)、@lezer/highlight(^1.2.5)、@codemirror/language(^6.13.1)、@codemirror/lang-yaml(^6.1.3)、@codemirror/lang-markdown(^6.5.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 bananamark,可以用 npx bananamark 直接运行。

bananamark 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/bananamark 是否存在。

bananamark 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

bananamark 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

bananamark 可以商用吗?

bananamark 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

bananamark 还在维护吗?

最新版本 0.2.1 发布于 2026/11/03(今天);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/10/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。