or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-parser.mdindex.mdlinkify.mdrendering.mdrule-system.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

The utils module provides helper functions for custom rule development, text processing, and HTML manipulation. These utilities are exposed to enable consistent behavior in custom rendering rules and plugins.

3

4

## Capabilities

5

6

### Type Checking Utilities

7

8

Functions for runtime type checking and validation.

9

10

```javascript { .api }

11

/**

12

* Check if value is a string

13

* @param obj - Value to check

14

* @returns True if value is a string

15

*/

16

function isString(obj: any): boolean;

17

```

18

19

**Usage Examples:**

20

21

```javascript

22

import { utils } from "remarkable";

23

24

// Type checking in custom rules

25

function customRule(state, start, end, silent) {

26

const line = state.getLines(start, start + 1, 0, false);

27

28

if (!utils.isString(line)) {

29

return false;

30

}

31

32

// Process string content

33

return processLine(line);

34

}

35

36

// Validating plugin options

37

function myPlugin(md, options) {

38

if (options.template && !utils.isString(options.template)) {

39

throw new Error('Template option must be a string');

40

}

41

}

42

```

43

44

### Object Utilities

45

46

Functions for object property checking and manipulation.

47

48

```javascript { .api }

49

/**

50

* Check if object has own property

51

* @param object - Object to check

52

* @param key - Property key to look for

53

* @returns True if object has the property

54

*/

55

function has(object: object, key: string): boolean;

56

57

/**

58

* Merge multiple objects into target object (Object.assign polyfill)

59

* @param target - Target object to merge into

60

* @param sources - Source objects to merge from

61

* @returns Modified target object

62

*/

63

function assign(target: object, ...sources: object[]): object;

64

```

65

66

**Usage Examples:**

67

68

```javascript

69

import { utils } from "remarkable";

70

71

// Property checking in custom rules

72

function processToken(token, options) {

73

if (utils.has(token, 'attrs') && token.attrs) {

74

// Process attributes

75

token.attrs.forEach(([name, value]) => {

76

console.log(`${name}: ${value}`);

77

});

78

}

79

80

if (utils.has(options, 'customClass')) {

81

token.attrSet('class', options.customClass);

82

}

83

}

84

85

// Object merging for plugin options

86

function configurePlugin(defaultOptions, userOptions) {

87

return utils.assign({}, defaultOptions, userOptions);

88

}

89

90

// Example usage

91

const defaultOpts = { theme: 'default', showNumbers: false };

92

const userOpts = { showNumbers: true, highlighter: 'prism' };

93

const finalOpts = utils.assign({}, defaultOpts, userOpts);

94

// Result: { theme: 'default', showNumbers: true, highlighter: 'prism' }

95

```

96

97

### String Processing Utilities

98

99

Functions for processing and escaping text content.

100

101

```javascript { .api }

102

/**

103

* Unescape markdown escape sequences

104

* @param str - String with markdown escapes

105

* @returns String with escapes resolved

106

*/

107

function unescapeMd(str: string): string;

108

109

/**

110

* Replace HTML entities with their character equivalents

111

* @param str - String containing HTML entities

112

* @returns String with entities replaced

113

*/

114

function replaceEntities(str: string): string;

115

116

/**

117

* Escape HTML special characters

118

* @param str - String to escape

119

* @returns HTML-safe string

120

*/

121

function escapeHtml(str: string): string;

122

```

123

124

**Usage Examples:**

125

126

```javascript

127

import { utils } from "remarkable";

128

129

// Unescaping markdown in custom rules

130

function processMarkdown(content) {

131

// Handle escaped characters like \* \_ \#

132

const unescaped = utils.unescapeMd(content);

133

return unescaped;

134

}

135

136

// Entity replacement in text processing

137

function processEntities(text) {

138

// Convert & < > " ' etc. to actual characters

139

const withEntities = utils.replaceEntities(text);

140

return withEntities;

141

}

142

143

// HTML escaping for safe output

144

function customTextRule(tokens, idx, options, env, renderer) {

145

const token = tokens[idx];

146

const safeContent = utils.escapeHtml(token.content);

147

return safeContent;

148

}

149

150

// Example transformations

151

console.log(utils.unescapeMd('\\*not italic\\*')); // β†’ *not italic*

152

console.log(utils.replaceEntities('&lt;p&gt;')); // β†’ <p>

153

console.log(utils.escapeHtml('<script>alert(1)</script>')); // β†’ &lt;script&gt;alert(1)&lt;/script&gt;

154

```

155

156

### Entity Processing Utilities

157

158

Advanced utilities for Unicode and HTML entity processing.

159

160

```javascript { .api }

161

/**

162

* Check if Unicode code point is valid

163

* @param code - Unicode code point to validate

164

* @returns True if code point is valid

165

*/

166

function isValidEntityCode(code: number): boolean;

167

168

/**

169

* Convert Unicode code point to string character

170

* @param code - Unicode code point

171

* @returns String character for the code point

172

*/

173

function fromCodePoint(code: number): string;

174

```

175

176

**Usage Examples:**

177

178

```javascript

179

import { utils } from "remarkable";

180

181

// Unicode validation

182

const validCode = 0x1F600; // πŸ˜€ emoji

183

console.log(utils.isValidEntityCode(validCode)); // β†’ true

184

185

const invalidCode = 0xD800; // Surrogate pair range

186

console.log(utils.isValidEntityCode(invalidCode)); // β†’ false

187

188

// Code point conversion

189

console.log(utils.fromCodePoint(0x1F600)); // β†’ πŸ˜€

190

console.log(utils.fromCodePoint(0x41)); // β†’ A

191

console.log(utils.fromCodePoint(0x20AC)); // β†’ €

192

193

// Custom entity processing

194

function processCustomEntities(text) {

195

return text.replace(/&#(\d+);/g, (match, code) => {

196

const codeNum = parseInt(code, 10);

197

return utils.isValidEntityCode(codeNum)

198

? utils.fromCodePoint(codeNum)

199

: match; // Keep original if invalid

200

});

201

}

202

```

203

204

### Practical Usage Patterns

205

206

Common patterns for using utilities in custom rules and plugins.

207

208

**Custom Renderer Rules:**

209

210

```javascript

211

import { Remarkable, utils } from "remarkable";

212

213

const md = new Remarkable();

214

215

// Safe text rendering with escaping

216

md.renderer.rules.text = function(tokens, idx, options, env, renderer) {

217

const token = tokens[idx];

218

return utils.escapeHtml(token.content);

219

};

220

221

// Custom code block with entity handling

222

md.renderer.rules.code = function(tokens, idx, options, env, renderer) {

223

const token = tokens[idx];

224

const content = utils.replaceEntities(token.content);

225

const escaped = utils.escapeHtml(content);

226

227

if (token.block) {

228

return `<pre><code>${escaped}</code></pre>\n`;

229

}

230

return `<code>${escaped}</code>`;

231

};

232

233

// Link processing with validation

234

md.renderer.rules.link_open = function(tokens, idx, options, env, renderer) {

235

const token = tokens[idx];

236

const href = token.attrGet('href');

237

238

if (utils.isString(href)) {

239

const safeHref = utils.escapeHtml(href);

240

token.attrSet('href', safeHref);

241

}

242

243

return '<a' + renderer.renderAttrs(token) + '>';

244

};

245

```

246

247

**Plugin Development:**

248

249

```javascript

250

function safeContentPlugin(md, options) {

251

const defaultOptions = {

252

escapeLevel: 'basic',

253

preserveEntities: false

254

};

255

256

// Merge options safely

257

const opts = utils.assign({}, defaultOptions, options);

258

259

// Custom rule for safe content processing

260

md.core.ruler.push('safe_content', function(state) {

261

state.tokens.forEach(token => {

262

if (token.type === 'inline' && token.children) {

263

token.children.forEach(child => {

264

if (child.type === 'text' && utils.isString(child.content)) {

265

// Process text content safely

266

if (!opts.preserveEntities) {

267

child.content = utils.replaceEntities(child.content);

268

}

269

if (opts.escapeLevel === 'full') {

270

child.content = utils.escapeHtml(child.content);

271

}

272

}

273

});

274

}

275

});

276

});

277

}

278

279

// Usage

280

const md = new Remarkable().use(safeContentPlugin, {

281

escapeLevel: 'full',

282

preserveEntities: true

283

});

284

```

285

286

**Token Processing:**

287

288

```javascript

289

function processTokens(tokens) {

290

return tokens.map(token => {

291

// Check for required properties

292

if (!utils.has(token, 'type')) {

293

throw new Error('Token missing required type property');

294

}

295

296

// Process text tokens

297

if (token.type === 'text' && utils.isString(token.content)) {

298

const processed = utils.assign({}, token);

299

processed.content = utils.unescapeMd(token.content);

300

return processed;

301

}

302

303

// Process container tokens

304

if (utils.has(token, 'children') && Array.isArray(token.children)) {

305

const processed = utils.assign({}, token);

306

processed.children = processTokens(token.children);

307

return processed;

308

}

309

310

return token;

311

});

312

}

313

```

314

315

### Utility Function Reference

316

317

Complete reference of all available utility functions with their signatures.

318

319

```javascript { .api }

320

interface Utils {

321

/** Type checking */

322

isString(obj: any): boolean;

323

324

/** Object utilities */

325

has(object: object, key: string): boolean;

326

assign(target: object, ...sources: object[]): object;

327

328

/** String processing */

329

unescapeMd(str: string): string;

330

replaceEntities(str: string): string;

331

escapeHtml(str: string): string;

332

333

/** Entity processing (advanced utilities) */

334

isValidEntityCode(code: number): boolean;

335

fromCodePoint(code: number): string;

336

}

337

338

// Import patterns

339

import { utils } from "remarkable";

340

const { utils } = require("remarkable");

341

342

// Individual function imports (not available - import from utils object)

343

// import { escapeHtml } from "remarkable"; // ❌ Not available

344

// const { escapeHtml } = utils; // βœ… Correct way

345

```