better-markdown
v1.0.0
Published
Extended markdown-it plugins for Obsidian-style wikilinks, checkboxes, callouts, and more
Maintainers
Readme
Better Markdown
Extended markdown-it plugins for Obsidian-style wikilinks, interactive checkboxes, callouts, footnotes, and more.
Features
- 🔗 Wikilinks - Obsidian-style
[[note]]linking with heading and block support - ✅ Interactive Checkboxes -
[ ],[x],[-]with click-to-toggle - 📻 Radio Buttons -
( )and(x)for single-choice options - 📢 Callouts - Beautiful alert boxes
(:warning: text :) - 📝 Footnotes - Auto-numbered references
[^1] - 🎨 Custom Syntax - Simplified formatting (
/italic/,*bold*,=highlight=, etc.) - 🔖 Block IDs - Direct linking to paragraphs
^block-id - 🎭 And more - Toggles, buttons, auto-linking for emails/phones/hashtags
Installation
npm install better-markdown markdown-itQuick Start
import MarkdownIt from 'markdown-it';
import { applyAllPlugins } from 'better-markdown';
const md = new MarkdownIt();
applyAllPlugins(md);
const html = md.render('[[My Note]] with a [[wikilink]]!');Individual Plugin Usage
Import only the plugins you need:
import MarkdownIt from 'markdown-it';
import { markdownWikilinks, markdownCheckboxes } from 'better-markdown';
const md = new MarkdownIt();
md.use(markdownWikilinks);
md.use(markdownCheckboxes);Available Plugins
Wikilinks
Obsidian-style note linking:
[[Note Name]] # Basic wikilink
[[Note#Heading]] # Link to heading
[[Note^block-id]] # Link to block
[[Long Note Name|Display Text]] # Custom displayRendering: Creates <a class="wikilink"> with data attributes (data-target, data-heading, data-block)
Checkboxes
Interactive task lists:
[ ] Unchecked task
[x] Completed task
[-] Indeterminate/in-progressRadio Buttons
Single-choice lists:
( ) Option A
(x) Option B (selected)
( ) Option CCallouts
Color-coded alert boxes:
(:warning: This is important :)
(:info: Helpful information :)
(:question: Why does this happen? :)
(:custom-color: Custom styled :)Footnotes
Auto-numbered references:
This is a citation[^1].
[*1] Footnote definition appears at bottomCustom Syntax
Simplified text formatting:
*bold* or ** bold text **
/italic/ or // italic text //
_underline_ or __ underline text __
=highlight= or == highlight text ==
-strike- or -- strike text --
^superscript^
~subscript~Block IDs
Direct paragraph linking:
This paragraph has an ID. ^my-block
Link to it: [[#^my-block]]Integration Examples
CodeMirror 6
import { EditorView } from '@codemirror/view';
import { markdown } from '@codemirror/lang-markdown';
import MarkdownIt from 'markdown-it';
import { applyAllPlugins } from 'better-markdown';
const md = new MarkdownIt();
applyAllPlugins(md);
new EditorView({
extensions: [
markdown({
base: markdownLanguage,
codeLanguages: languages
})
],
parent: document.body
});
// Render preview
const html = md.render(editorContent);React
import { useState } from 'react';
import MarkdownIt from 'markdown-it';
import { applyAllPlugins } from 'better-markdown';
const md = new MarkdownIt();
applyAllPlugins(md);
function MarkdownEditor() {
const [text, setText] = useState('');
return (
<div>
<textarea value={text} onChange={e => setText(e.target.value)} />
<div dangerouslySetInnerHTML={{ __html: md.render(text) }} />
</div>
);
}Handling Wikilink Clicks
document.addEventListener('click', (e) => {
if (e.target.classList.contains('wikilink')) {
e.preventDefault();
const target = e.target.dataset.target;
const heading = e.target.dataset.heading;
const blockId = e.target.dataset.block;
// Implement your navigation logic
navigateToNote(target, heading, blockId);
}
});Utility Functions
import { wikilinkUtils } from 'better-markdown';
// Extract all wikilinks from text
const links = wikilinkUtils.extractWikilinks(markdown);
// Returns: [{ target, heading, blockId, display, raw }]
// Extract all block IDs
const blockIds = wikilinkUtils.extractBlockIds(markdown);
// Returns: ['block-1', 'block-2', ...]
// Generate unique block ID
const id = wikilinkUtils.generateBlockId();
// Returns: 'block-abc123xyz'API Reference
applyAllPlugins(md)
Convenience function that applies all plugins to a markdown-it instance.
Parameters:
md(MarkdownIt): The markdown-it instance
Returns: The same markdown-it instance with all plugins applied
Individual Plugins
All plugins follow the standard markdown-it plugin signature:
function plugin(md, options) { ... }customSyntaxPlugin- Custom text formattingmarkdownCheckboxes- Interactive checkboxesmarkdownRadios- Radio button listsmarkdownCallouts- Alert boxesmarkdownToggles- Collapsible listsmarkdownWikilinks- Note linkingmarkdownBlockIds- Block identifiers
Styling
Better-markdown generates semantic HTML with appropriate classes. You'll need to add CSS for styling. See the demo app for example styles.
Example CSS for wikilinks:
.wikilink {
color: #7c3aed;
background-color: rgba(124, 58, 237, 0.08);
padding: 0.1em 0.3em;
border-radius: 3px;
text-decoration: none;
}Browser Compatibility
Works in all modern browsers and Node.js environments that support ES6+.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT © Better Markdown Contributors
Roadmap
- [ ] TypeScript definitions
- [ ] React hooks package
- [ ] CSS stylesheet package
- [ ] Interactive playground
- [ ] Comprehensive test suite
