diff --git a/README.md b/README.md index 0108faa..de52853 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ import hljs from 'highlight.js'; const marked = new Marked( markedHighlight({ langPrefix: 'hljs language-', - highlight(code, lang) { + highlight(code, lang, info) { const language = hljs.getLanguage(lang) ? lang : 'plaintext'; return hljs.highlight(code, { language }).value; } @@ -46,7 +46,7 @@ import pygmentize from 'pygmentize-bundled'; const marked = new Marked( markedHighlight({ async: true, - highlight(code, lang) { + highlight(code, lang, info) { return new Promise((resolve, reject) => { pygmentize({ lang, format: 'html' }, code, function (err, result) { if (err) { diff --git a/spec/index.test.js b/spec/index.test.js index a3deef3..27b21c6 100644 --- a/spec/index.test.js +++ b/spec/index.test.js @@ -174,4 +174,71 @@ no need to escape chars expect(() => marked(markdown)).toThrow(/set the async option to true/i); }); + + const markdownWithSpaceInLang = ` +\`\`\`ts twoslash +let a = 1 +\`\`\``; + + test('uses infostring', () => { + marked.use(markedHighlight({ + highlight(code, lang, info) { + return info; + } + })); + + expect(marked(markdownWithSpaceInLang)).toMatchInlineSnapshot(` +"
ts twoslash
+
" +`); + }); + + test('async uses infostring', async() => { + marked.use(markedHighlight({ + async: true, + highlight(code, lang, info) { + return new Promise((resolve, reject) => { + resolve(info); + }); + } + })); + + expect(await marked(markdownWithSpaceInLang)).toMatchInlineSnapshot(` +"
ts twoslash
+
" +`); + }); + + const markdownWithoutLang = ` +\`\`\` +no language provided +\`\`\` +`; + + test('nullish infostring is cast to empty string', () => { + marked.use(markedHighlight({ + highlight(code, lang, info) { + expect(info).toBe(''); + return info; + } + })); + expect(marked(markdownWithoutLang)).toMatchInlineSnapshot(` +"

+
" +`); + }); + + test('async nullish infostring is cast to empty string', async() => { + marked.use(markedHighlight({ + async: true, + highlight(code, lang, info) { + expect(info).toBe(''); + return Promise.resolve(info); + } + })); + expect(await marked(markdownWithoutLang)).toMatchInlineSnapshot(` +"

+
" +`); + }); }); diff --git a/src/index.d.ts b/src/index.d.ts index 0162a9c..6a0a366 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -5,9 +5,11 @@ declare module 'marked-highlight' { * @param code The raw code to be highlighted * @param language The language tag found immediately after the code block * opening marker (e.g. ```typescript -> language='typescript') + * @param info The full string after the code block opening marker + * (e.g. ```ts twoslash -> info='ts twoslash') * @return The highlighted code as a HTML string */ - type SyncHighlightFunction = (code: string, language: string) => string; + type SyncHighlightFunction = (code: string, language: string, info: string) => string; /** * An asynchronous function to highlight code @@ -15,9 +17,11 @@ declare module 'marked-highlight' { * @param code The raw code to be highlighted * @param language The language tag found immediately after the code block * opening marker (e.g. ```typescript -> language='typescript') + * @param info The full string after the code block opening marker + * (e.g. ```ts twoslash -> info='ts twoslash') * @return A Promise for the highlighted code as a HTML string */ - type AsyncHighlightFunction = (code: string, language: string) => Promise; + type AsyncHighlightFunction = (code: string, language: string, info: string) => Promise; /** * Options for configuring the marked-highlight extension using a synchronous diff --git a/src/index.js b/src/index.js index b267e4d..95afb42 100644 --- a/src/index.js +++ b/src/index.js @@ -23,10 +23,10 @@ export function markedHighlight(options) { const lang = getLang(token); if (options.async) { - return Promise.resolve(options.highlight(token.text, lang)).then(updateToken(token)); + return Promise.resolve(options.highlight(token.text, lang, token.lang || '')).then(updateToken(token)); } - const code = options.highlight(token.text, lang); + const code = options.highlight(token.text, lang, token.lang || ''); if (code instanceof Promise) { throw new Error('markedHighlight is not set to async but the highlight function is async. Set the async option to true on markedHighlight to await the async highlight function.'); } diff --git a/types_test/index.test-d.ts b/types_test/index.test-d.ts index acb6a0c..cfd9b7a 100644 --- a/types_test/index.test-d.ts +++ b/types_test/index.test-d.ts @@ -3,6 +3,7 @@ import {expectError} from 'tsd'; // Single function argument markedHighlight((code: string, language: string) => code+language); +markedHighlight((code: string, language: string, info: string) => code+language+info); // Invalid asynchronous function argument - missing async: true expectError(markedHighlight(async (code: string, language: string) => code+language)); @@ -37,6 +38,10 @@ markedHighlight({ highlight: async (code: string, language: string) => code+language, async: true, }) +markedHighlight({ + highlight: async (code: string, language: string, info: string) => code+language+info, + async: true, +}) // Full asynchronous options argument markedHighlight({