or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-marked-highlight

Syntax highlighting extension for the marked markdown parser

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/marked-highlight@2.2.x

To install, run

npx @tessl/cli install tessl/npm-marked-highlight@2.2.0

0

# marked-highlight

1

2

marked-highlight is a syntax highlighting extension for the marked markdown parser. It provides a flexible API that accepts custom highlight functions (synchronous or asynchronous) and integrates seamlessly with popular syntax highlighting libraries like highlight.js and pygmentize.

3

4

## Package Information

5

6

- **Package Name**: marked-highlight

7

- **Package Type**: npm

8

- **Language**: JavaScript with TypeScript definitions

9

- **Installation**: `npm install marked-highlight`

10

11

## Core Imports

12

13

```javascript

14

import { markedHighlight } from "marked-highlight";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { markedHighlight } = require("marked-highlight");

21

```

22

23

UMD (browser):

24

25

```html

26

<script src="https://cdn.jsdelivr.net/npm/marked-highlight/lib/index.umd.js"></script>

27

<script>

28

const { markedHighlight } = globalThis.markedHighlight;

29

</script>

30

```

31

32

## Architecture

33

34

marked-highlight integrates with the marked parser using the extension system:

35

36

- **Extension Integration**: The `markedHighlight` function returns a `MarkedExtension` object that plugs into marked's parsing pipeline

37

- **Token Processing**: Uses `walkTokens` to identify and process code block tokens during parsing

38

- **Renderer Override**: Provides a custom `code` renderer that applies CSS classes and processes highlighted content

39

- **Async Support**: Handles both synchronous and asynchronous highlighting functions through Promise-based processing

40

- **Lazy Processing**: Code highlighting occurs during the rendering phase, allowing for efficient token processing

41

42

This architecture allows marked-highlight to integrate seamlessly with any marked instance while maintaining compatibility with other extensions.

43

44

## Basic Usage

45

46

### With highlight.js (synchronous)

47

48

```javascript

49

import { Marked } from "marked";

50

import { markedHighlight } from "marked-highlight";

51

import hljs from 'highlight.js';

52

53

const marked = new Marked(

54

markedHighlight({

55

emptyLangClass: 'hljs',

56

langPrefix: 'hljs language-',

57

highlight(code, lang, info) {

58

const language = hljs.getLanguage(lang) ? lang : 'plaintext';

59

return hljs.highlight(code, { language }).value;

60

}

61

})

62

);

63

64

const html = marked.parse(`

65

\`\`\`javascript

66

const highlight = "code";

67

\`\`\`

68

`);

69

// Output: <pre><code class="hljs language-javascript">

70

// <span class="hljs-keyword">const</span> highlight = <span class="hljs-string">"code"</span>;

71

// </code></pre>

72

```

73

74

### With pygmentize (asynchronous)

75

76

```javascript

77

import { Marked } from "marked";

78

import { markedHighlight } from "marked-highlight";

79

import pygmentize from 'pygmentize-bundled';

80

81

const marked = new Marked(

82

markedHighlight({

83

async: true,

84

highlight(code, lang, info) {

85

return new Promise((resolve, reject) => {

86

pygmentize({ lang, format: 'html' }, code, function (err, result) {

87

if (err) {

88

reject(err);

89

return;

90

}

91

resolve(result.toString());

92

});

93

});

94

}

95

})

96

);

97

98

const html = await marked.parse(`

99

\`\`\`javascript

100

const highlight = "code";

101

\`\`\`

102

`);

103

```

104

105

## Capabilities

106

107

### markedHighlight Function

108

109

Creates a marked extension for syntax highlighting code blocks with three different calling patterns.

110

111

```typescript { .api }

112

/**

113

* Creates a marked extension for syntax highlighting with synchronous highlighting function

114

* @param options - Configuration options with synchronous highlight function

115

* @returns MarkedExtension to be passed to marked.use()

116

*/

117

function markedHighlight(options: SynchronousOptions): MarkedExtension;

118

119

/**

120

* Creates a marked extension for syntax highlighting with asynchronous highlighting function

121

* @param options - Configuration options with asynchronous highlight function

122

* @returns MarkedExtension to be passed to marked.use()

123

*/

124

function markedHighlight(options: AsynchronousOptions): MarkedExtension;

125

126

/**

127

* Creates a marked extension for syntax highlighting with a direct function

128

* @param highlightFunction - A synchronous function to apply syntax highlighting

129

* @returns MarkedExtension to be passed to marked.use()

130

*/

131

function markedHighlight(highlightFunction: SyncHighlightFunction): MarkedExtension;

132

```

133

134

**Usage Examples:**

135

136

```javascript

137

// Direct function approach

138

markedHighlight((code, lang) => {

139

return hljs.highlight(code, { language: lang }).value;

140

});

141

142

// Synchronous options approach

143

markedHighlight({

144

highlight: (code, lang) => hljs.highlight(code, { language: lang }).value,

145

langPrefix: 'hljs language-',

146

emptyLangClass: 'hljs'

147

});

148

149

// Asynchronous options approach

150

markedHighlight({

151

async: true,

152

highlight: async (code, lang) => {

153

return await someAsyncHighlighter(code, lang);

154

}

155

});

156

```

157

158

## Types

159

160

```typescript { .api }

161

/**

162

* A synchronous function to highlight code

163

*/

164

type SyncHighlightFunction = (

165

code: string,

166

language: string,

167

info: string

168

) => string;

169

170

/**

171

* An asynchronous function to highlight code

172

*/

173

type AsyncHighlightFunction = (

174

code: string,

175

language: string,

176

info: string

177

) => Promise<string>;

178

179

/**

180

* Options for configuring the marked-highlight extension using a synchronous

181

* highlighting function.

182

*/

183

interface SynchronousOptions {

184

/** Function to highlight code with */

185

highlight: SyncHighlightFunction;

186

/**

187

* Not necessary when using a synchronous highlighting function, but can be

188

* set without harm (it will make marked.parse() return a promise if true)

189

*/

190

async?: boolean;

191

/**

192

* The language tag found immediately after the code block opening marker is

193

* appended to this to form the class attribute added to the <code> element.

194

* @default 'language-'

195

*/

196

langPrefix?: string;

197

/**

198

* The class attribute added to the <code> element if the language tag is

199

* empty.

200

* @default ''

201

*/

202

emptyLangClass?: string;

203

}

204

205

/**

206

* Options for configuring the marked-highlight extension using an

207

* asynchronous highlighting function.

208

*/

209

interface AsynchronousOptions {

210

/** Function to highlight code with */

211

highlight: AsyncHighlightFunction;

212

/** Must be set to true when using an asynchronous highlight function */

213

async: true;

214

/**

215

* The language tag found immediately after the code block opening marker is

216

* appended to this to form the class attribute added to the <code> element.

217

* @default 'language-'

218

*/

219

langPrefix?: string;

220

/**

221

* The class attribute added to the <code> element if the language tag is

222

* empty.

223

* @default ''

224

*/

225

emptyLangClass?: string;

226

}

227

228

/**

229

* MarkedExtension interface from marked library

230

* This is the return type of markedHighlight() function

231

*/

232

interface MarkedExtension {

233

/** Whether the extension requires async processing */

234

async: boolean;

235

/** Token processing function for code blocks */

236

walkTokens: (token: any) => void | Promise<void>;

237

/** Indicates use of the new renderer system */

238

useNewRenderer: boolean;

239

/** Custom renderer for code blocks */

240

renderer: {

241

code: (code: string, infoString: string, escaped: boolean) => string;

242

};

243

}

244

```

245

246

## Configuration Options

247

248

### highlight (required)

249

250

The function that transforms raw code into highlighted HTML.

251

252

**Parameters:**

253

- `code` (string): The raw code to be highlighted

254

- `language` (string): The language tag found immediately after the code block opening marker (e.g., `javascript` from \`\`\`javascript). Only the first word is used if multiple words are present.

255

- `info` (string): The full string after the code block opening marker (e.g., `ts twoslash` from \`\`\`ts twoslash). Empty string for code blocks without language tags.

256

257

**Returns:** Highlighted code as HTML string (or Promise for async functions). Returning `null` will skip highlighting and render the original code with HTML escaping.

258

259

**Edge Case Behaviors:**

260

- **Multiple words in language**: Only the first word is used (e.g., `ts twoslash` becomes language `ts`)

261

- **Special characters in language**: HTML entities are escaped in CSS class names

262

- **Null return**: When the highlight function returns `null`, the original code is rendered with proper HTML escaping

263

- **Empty language**: When no language is specified, `language` parameter is empty string and `emptyLangClass` is applied

264

265

### async (optional)

266

267

Set to `true` when using an asynchronous highlight function. When `true`, `marked.parse()` will return a Promise.

268

269

**Default:** `false`

270

271

### langPrefix (optional)

272

273

A prefix added to the CSS class on the `<code>` element. The language tag is appended to this prefix.

274

275

**Default:** `'language-'`

276

277

**Example:** With `langPrefix: 'hljs language-'` and language `javascript`, the resulting class will be `hljs language-javascript`

278

279

### emptyLangClass (optional)

280

281

The CSS class added to the `<code>` element when the language tag is empty or not specified.

282

283

**Default:** `''` (empty string)

284

285

**Example:** With `emptyLangClass: 'hljs'`, code blocks without language tags will have `class="hljs"`

286

287

## Error Handling

288

289

The library throws specific errors for common configuration mistakes:

290

291

1. **Missing highlight function:**

292

```

293

"Must provide highlight function"

294

```

295

Thrown when options object is provided without a highlight function.

296

297

2. **Async configuration mismatch:**

298

```

299

"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."

300

```

301

Thrown when an async highlight function is used but `async: true` is not set in options.

302

303

## Integration Examples

304

305

### With highlight.js

306

307

```javascript

308

import { markedHighlight } from "marked-highlight";

309

import hljs from 'highlight.js';

310

311

const extension = markedHighlight({

312

langPrefix: 'hljs language-',

313

highlight(code, lang) {

314

const language = hljs.getLanguage(lang) ? lang : 'plaintext';

315

return hljs.highlight(code, { language }).value;

316

}

317

});

318

```

319

320

### With Prism.js

321

322

```javascript

323

import { markedHighlight } from "marked-highlight";

324

import Prism from 'prismjs';

325

326

const extension = markedHighlight({

327

langPrefix: 'language-',

328

highlight(code, lang) {

329

if (Prism.languages[lang]) {

330

return Prism.highlight(code, Prism.languages[lang], lang);

331

}

332

return code;

333

}

334

});

335

```

336

337

### With custom async highlighter

338

339

```javascript

340

import { markedHighlight } from "marked-highlight";

341

342

const extension = markedHighlight({

343

async: true,

344

highlight: async (code, lang) => {

345

const response = await fetch('/api/highlight', {

346

method: 'POST',

347

headers: { 'Content-Type': 'application/json' },

348

body: JSON.stringify({ code, language: lang })

349

});

350

const result = await response.json();

351

return result.highlighted;

352

}

353

});

354

```

355

356

## Requirements

357

358

### Peer Dependencies

359

360

- **marked**: `>=4 <17` (required)

361

362

The extension is compatible with marked versions 4 through 16 and integrates using marked's extension system.

363

364

### Environment Support

365

366

- **Node.js**: CommonJS and ES modules

367

- **Browser**: UMD build available

368

- **TypeScript**: Full type definitions included