Skip to content

Instantly share code, notes, and snippets.

@carlosdelfino
Forked from m93a/README.md
Created September 19, 2022 16:49
Show Gist options
  • Save carlosdelfino/cc148d24209c7fb2fada666fd730fb2f to your computer and use it in GitHub Desktop.
Save carlosdelfino/cc148d24209c7fb2fada666fd730fb2f to your computer and use it in GitHub Desktop.
Example of a markdown-it extension written in TypeScript

Mark Plugin for markdown-it

This is a sample implementation of a basic extension. It uses the @types/markdown-it package from NPM which contains the documentation for markdown-it. The code here is mostly copied from the backtick rule implementation you can find in the original markdown-it repository.

Keywords

Plugin example for markdown-it, extension tutorial, markdown-it extension API, TypeScript, jsDoc, documentation for extensions, specification of plugin API, how to write an extension for markdown-it.

import { MarkdownIt, RuleInline } from 'markdown-it';
const delimiter = '=';
export default function insertPlugin(md: MarkdownIt)
{
const tokenize: RuleInline = (state, silent) =>
{
let pos = state.pos;
const ch = state.src[pos];
if (ch !== delimiter) { return false; }
const start = pos;
pos++;
const max = state.posMax;
while (pos < max && state.src[pos] === delimiter) { pos++; }
const marker = state.src.slice(start, pos);
let matchEnd = pos;
let matchStart = state.src.indexOf('=', matchEnd);
while (matchStart !== -1)
{
matchEnd = matchStart + 1;
while (matchEnd < max && state.src[matchEnd] === delimiter) { matchEnd++; }
if (matchEnd - matchStart === marker.length)
{
if (!silent)
{
let token = state.push('mark_begin', 'mark', 1);
token.markup = marker;
token.attrSet('class', 'bass');
token = state.push('text', '', 0);
token.content = state.src.slice(pos, matchStart)
.replace(/[ \n]+/g, ' ')
.trim();
token = state.push('mark_end', 'mark', -1);
console.log('token: ', state.tokens);
}
state.pos = matchEnd;
return true;
}
matchStart = state.src.indexOf(delimiter, matchEnd);
}
if (!silent) { state.pending += marker; }
state.pos += marker.length;
return true;
};
md.inline.ruler.before('emphasis', 'mark', tokenize);
};
@carlosdelfino
Copy link
Author

I'm studying a way to make a similar but very simplified replacement process for the Liquid used in Jekyll, where when finding a declaration {{variable}} it is consulted in the application's database, so I would have {{doc.variable} } for database variables, and {{sys.variable}} for internal system variables.

In your case you used a single character delimiter, could you help me with an example for a two character delimiter? or if there is already something ready that I can replicate?

I'm using NativeScript and I don't know yet if it will be possible to use Markdown-it with it, but I'll try.

Grateful.

@carlosdelfino
Copy link
Author

I'm trying to use your example, but the "RuleInline" is not found, I was forced to activate the "esModuleInterop" flag, but it still doesn't find it, would you have any suggestions?

I'm using Nativescript 8.3.3 with the following dependencies:

"dependencies": {
"@angular/animations": "~13.2.0",
"@angular/common": "~13.2.0",
"@angular/compiler": "~13.2.0",
"@angular/core": "~13.2.0",
"@angular/forms": "~13.2.0",
"@angular/platform-browser": "~13.2.0",
"@angular/platform-browser-dynamic": "~13.2.0",
"@angular/router": "~13.2.0",
"@nativescript/angular": "^13.0.0",
"@nativescript/core": "~8.3.4",
"@nativescript/firebase-core": "^2.3.4",
"@nativescript/firebase-database": "^2.3.4",
"@nativescript/firebase-firestore": "^2.3.4",
"@nativescript/firebase-installations": "^2.3.4",
"@nativescript/firebase-remote-config": "^2.3.4",
"@nativescript/theme": "~3.0.2",
"@types/markdown-it": "^12.2.3",
"rxjs": "~7.5.0",
"zone.js": "~0.11.5"
},
"devDependencies": {
"@angular-devkit/build-angular": "~13.2.0",
"@angular/compiler-cli": "~13.2.0",
"@nativescript/android": "8.3.1",
"@nativescript/types": "~8.3.1",
"@nativescript/webpack": "~5.0.6",
"@ngtools/webpack": "~13.2.0",
"typescript": "~4.5.5"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment