Add support for wysiwyg markdown preview
This commit is contained in:
@@ -1,44 +1,97 @@
|
||||
# ribbit
|
||||
|
||||
Zero-dependency WYSIWYG markdown editor
|
||||
Zero-dependency WYSIWYG markdown editor for the browser.
|
||||
|
||||
## Files
|
||||
## Source Layout
|
||||
|
||||
- `src/hopdown.js` — Markdown ↔ HTML converter (`HopDown.toHTML()`, `HopDown.toMarkdown()`)
|
||||
- `src/ribbit.js` — Base viewer class (`Ribbit`), plugin base class (`RibbitPlugin`), utilities
|
||||
- `src/ribbit-editor.js` — Editor class (`RibbitEditor`) with VIEW/EDIT/WYSIWYG modes
|
||||
- `src/ribbit.css` — Editor and content styles
|
||||
- `src/ts/` — TypeScript source files
|
||||
- `types.ts` — shared interfaces (Tag, SourceToken, Converter, etc.)
|
||||
- `tags.ts` — tag definitions and `inlineTag()` factory
|
||||
- `hopdown.ts` — configurable markdown↔HTML converter (HopDown class)
|
||||
- `macros.ts` — macro parsing and Tag generation
|
||||
- `ribbit.ts` — Ribbit viewer, RibbitPlugin, utilities
|
||||
- `ribbit-editor.ts` — RibbitEditor with WYSIWYG support, public API exports
|
||||
- `default-theme.ts` — built-in theme definition
|
||||
- `theme-manager.ts` — theme registration and switching
|
||||
- `events.ts` — typed event emitter
|
||||
- `src/static/` — CSS and static assets
|
||||
- `ribbit-core.css` — functional editor styles (always load)
|
||||
- `themes/ribbit-default/theme.css` — default theme
|
||||
|
||||
## Build Output
|
||||
|
||||
```
|
||||
dist/ribbit/
|
||||
├── ribbit.js # readable IIFE bundle + source map
|
||||
├── ribbit.min.js # minified bundle
|
||||
├── ribbit-core.css # functional styles
|
||||
└── themes/
|
||||
└── ribbit-default/
|
||||
└── theme.css # default theme (imports ribbit-core.css)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="ribbit/src/ribbit.css">
|
||||
<link rel="stylesheet" href="ribbit/themes/ribbit-default/theme.css">
|
||||
<article id="ribbit">your markdown here</article>
|
||||
|
||||
<script src="ribbit/src/hopdown.js"></script>
|
||||
<script src="ribbit/src/ribbit.js"></script>
|
||||
<script src="ribbit/src/ribbit-editor.js"></script>
|
||||
<script src="ribbit/ribbit.js"></script>
|
||||
<script>
|
||||
const editor = new RibbitEditor({ plugins: [] });
|
||||
const editor = new ribbit.Editor({
|
||||
on: {
|
||||
save: ({ markdown }) => {
|
||||
fetch('/api/save', { method: 'POST', body: markdown });
|
||||
},
|
||||
},
|
||||
macros: [
|
||||
{
|
||||
name: 'npc',
|
||||
toHTML: ({ keywords }) => {
|
||||
const name = keywords.join(' ');
|
||||
return `<a href="/NPC/${name}">${name}</a>`;
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
editor.run();
|
||||
|
||||
// Switch modes
|
||||
editor.wysiwyg(); // WYSIWYG editing
|
||||
editor.edit(); // Source editing
|
||||
editor.view(); // Read-only view
|
||||
|
||||
// Get content
|
||||
editor.getMarkdown();
|
||||
editor.getHTML();
|
||||
editor.wysiwyg();
|
||||
</script>
|
||||
```
|
||||
|
||||
## Custom Block Tags
|
||||
|
||||
```javascript
|
||||
const spoiler = {
|
||||
name: 'spoiler',
|
||||
match: (context) => {
|
||||
if (!/^\|{3,}/.test(context.lines[context.index])) return null;
|
||||
const content = [];
|
||||
let i = context.index + 1;
|
||||
while (i < context.lines.length && !/^\|{3,}/.test(context.lines[i]))
|
||||
content.push(context.lines[i++]);
|
||||
return { content: content.join('\n'), raw: '', consumed: i + 1 - context.index };
|
||||
},
|
||||
toHTML: (token, convert) =>
|
||||
'<details><summary>Spoiler</summary>' + convert.block(token.content) + '</details>',
|
||||
selector: 'DETAILS',
|
||||
toMarkdown: (element, convert) =>
|
||||
'\n\n|||\n' + convert.children(element).trim() + '\n|||\n\n',
|
||||
};
|
||||
|
||||
const converter = new ribbit.HopDown({
|
||||
tags: { ...ribbit.defaultTags, 'DETAILS': spoiler },
|
||||
});
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
```
|
||||
npm test
|
||||
```
|
||||
|
||||
## Supported Markdown
|
||||
|
||||
Bold, italic, inline code, links, headings (h1-h6), unordered/ordered/nested lists,
|
||||
blockquotes, fenced code blocks with language, horizontal rules, GFM tables with
|
||||
column alignment, and paragraphs. Arbitrary nesting of all inline formatting.
|
||||
|
||||
## Tests
|
||||
|
||||
Open `test/test_ribbit-down.html` in a browser.
|
||||
column alignment, paragraphs, and macros (@name syntax).
|
||||
|
||||
Reference in New Issue
Block a user