or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-nodes.mdcore-parsing.mdextensions.mdhtml-rendering.mdindex.mdtext-rendering.md

html-rendering.mddocs/

0

# HTML Rendering

1

2

High-performance HTML rendering system with extensive customization options including URL sanitization, attribute providers, custom node renderers, and output formatting controls. The HTML renderer converts CommonMark AST nodes into clean, standards-compliant HTML output.

3

4

## Capabilities

5

6

### HTML Renderer

7

8

Main rendering class that converts AST nodes to HTML output.

9

10

```java { .api }

11

/**

12

* Renders a tree of nodes to HTML.

13

* Thread-safe renderer that can be reused across multiple rendering operations.

14

*/

15

public class HtmlRenderer implements Renderer {

16

/**

17

* Create a new builder for configuring an HtmlRenderer

18

* @return a builder instance

19

*/

20

public static Builder builder();

21

22

/**

23

* Render the node to HTML and return as string

24

* @param node the node to render - must not be null

25

* @return the rendered HTML as a string

26

*/

27

public String render(Node node);

28

29

/**

30

* Render the node to HTML and append to the given output

31

* @param node the node to render - must not be null

32

* @param output the appendable to write HTML to

33

*/

34

public void render(Node node, Appendable output);

35

}

36

```

37

38

**Usage Examples:**

39

40

```java

41

import org.commonmark.parser.Parser;

42

import org.commonmark.renderer.html.HtmlRenderer;

43

import org.commonmark.node.Node;

44

45

// Basic HTML rendering

46

Parser parser = Parser.builder().build();

47

HtmlRenderer renderer = HtmlRenderer.builder().build();

48

49

Node document = parser.parse("# Hello\n\nThis is **bold** text.");

50

String html = renderer.render(document);

51

// Result: <h1>Hello</h1>\n<p>This is <strong>bold</strong> text.</p>\n

52

53

// Render to StringBuilder

54

StringBuilder sb = new StringBuilder();

55

renderer.render(document, sb);

56

57

// Render to file

58

try (FileWriter writer = new FileWriter("output.html")) {

59

renderer.render(document, writer);

60

}

61

```

62

63

### HTML Renderer Builder

64

65

Builder class for configuring HTML renderer instances with custom options and extensions.

66

67

```java { .api }

68

/**

69

* Builder for configuring an HtmlRenderer

70

*/

71

public static class HtmlRenderer.Builder {

72

/**

73

* Build the configured HtmlRenderer instance

74

* @return the configured HtmlRenderer

75

*/

76

public HtmlRenderer build();

77

78

/**

79

* The HTML to use for rendering a softbreak, defaults to "\n"

80

* Set it to "<br>" to make them hard breaks

81

* Set it to " " to ignore line wrapping in the source

82

* @param softbreak HTML for softbreak

83

* @return this builder

84

*/

85

public Builder softbreak(String softbreak);

86

87

/**

88

* Whether HtmlInline and HtmlBlock should be escaped, defaults to false

89

* @param escapeHtml true for escaping, false for preserving raw HTML

90

* @return this builder

91

*/

92

public Builder escapeHtml(boolean escapeHtml);

93

94

/**

95

* Whether Image src and Link href should be sanitized, defaults to false

96

* @param sanitizeUrls true for sanitization, false for preserving raw attribute

97

* @return this builder

98

*/

99

public Builder sanitizeUrls(boolean sanitizeUrls);

100

101

/**

102

* UrlSanitizer used to filter URLs if sanitizeUrls is true

103

* @param urlSanitizer Filterer used to filter Image src and Link href

104

* @return this builder

105

*/

106

public Builder urlSanitizer(UrlSanitizer urlSanitizer);

107

108

/**

109

* Whether URLs of link or images should be percent-encoded, defaults to false

110

* @param percentEncodeUrls true to percent-encode, false for leaving as-is

111

* @return this builder

112

*/

113

public Builder percentEncodeUrls(boolean percentEncodeUrls);

114

115

/**

116

* Add a factory for an attribute provider for adding/changing HTML attributes to the rendered tags

117

* @param attributeProviderFactory the attribute provider factory to add

118

* @return this builder

119

*/

120

public Builder attributeProviderFactory(AttributeProviderFactory attributeProviderFactory);

121

122

/**

123

* Add a factory for instantiating a node renderer (done when rendering)

124

* @param nodeRendererFactory the factory for creating a node renderer

125

* @return this builder

126

*/

127

public Builder nodeRendererFactory(HtmlNodeRendererFactory nodeRendererFactory);

128

129

/**

130

* Add extensions to use on this HTML renderer

131

* @param extensions extensions to use on this HTML renderer

132

* @return this builder

133

*/

134

public Builder extensions(Iterable<? extends Extension> extensions);

135

}

136

```

137

138

**Usage Examples:**

139

140

```java

141

import org.commonmark.renderer.html.HtmlRenderer;

142

import org.commonmark.renderer.html.AttributeProvider;

143

144

// Custom softbreak handling

145

HtmlRenderer brRenderer = HtmlRenderer.builder()

146

.softbreak("<br>\n")

147

.build();

148

149

// Escape HTML content

150

HtmlRenderer safeRenderer = HtmlRenderer.builder()

151

.escapeHtml(true)

152

.build();

153

154

// URL sanitization

155

HtmlRenderer sanitizedRenderer = HtmlRenderer.builder()

156

.sanitizeUrls(true)

157

.percentEncodeUrls(true)

158

.build();

159

160

// Custom attribute provider

161

HtmlRenderer customRenderer = HtmlRenderer.builder()

162

.attributeProviderFactory(context -> new AttributeProvider() {

163

@Override

164

public void setAttributes(Node node, String tagName, Map<String, String> attributes) {

165

if (node instanceof Heading) {

166

attributes.put("class", "heading-" + ((Heading) node).getLevel());

167

}

168

}

169

})

170

.build();

171

```

172

173

### HTML Renderer Extension System

174

175

Extension interfaces and classes for customizing HTML rendering behavior.

176

177

```java { .api }

178

/**

179

* Extension interface for HTML renderer

180

*/

181

public interface HtmlRenderer.HtmlRendererExtension extends Extension {

182

/**

183

* Extend the HTML renderer builder with custom functionality

184

* @param rendererBuilder the builder to extend

185

*/

186

void extend(HtmlRenderer.Builder rendererBuilder);

187

}

188

189

/**

190

* Factory for HTML node renderers

191

*/

192

public interface HtmlNodeRendererFactory {

193

/**

194

* Create a node renderer with the given context

195

* @param context the rendering context

196

* @return a node renderer instance

197

*/

198

NodeRenderer create(HtmlNodeRendererContext context);

199

}

200

201

/**

202

* Context for HTML node rendering

203

*/

204

public interface HtmlNodeRendererContext {

205

/**

206

* Whether HTML should be escaped

207

* @return true if HTML should be escaped

208

*/

209

boolean shouldEscapeHtml();

210

211

/**

212

* Whether URLs should be sanitized

213

* @return true if URLs should be sanitized

214

*/

215

boolean shouldSanitizeUrls();

216

217

/**

218

* Get the URL sanitizer

219

* @return the URL sanitizer

220

*/

221

UrlSanitizer urlSanitizer();

222

223

/**

224

* Encode a URL if percent encoding is enabled

225

* @param url the URL to encode

226

* @return the encoded URL

227

*/

228

String encodeUrl(String url);

229

230

/**

231

* Extend attributes for a node and tag

232

* @param node the node being rendered

233

* @param tagName the HTML tag name

234

* @param attributes the current attributes

235

* @return the extended attributes

236

*/

237

Map<String, String> extendAttributes(Node node, String tagName, Map<String, String> attributes);

238

239

/**

240

* Get the HTML writer

241

* @return the HTML writer

242

*/

243

HtmlWriter getWriter();

244

245

/**

246

* Get the softbreak string

247

* @return the softbreak HTML

248

*/

249

String getSoftbreak();

250

251

/**

252

* Render a child node

253

* @param node the node to render

254

*/

255

void render(Node node);

256

}

257

```

258

259

### Attribute Provider System

260

261

System for adding custom HTML attributes to rendered elements.

262

263

```java { .api }

264

/**

265

* Provides attributes for HTML elements

266

*/

267

public interface AttributeProvider {

268

/**

269

* Set attributes for the specified node and tag

270

* @param node the node being rendered

271

* @param tagName the HTML tag name

272

* @param attributes the attributes map to modify

273

*/

274

void setAttributes(Node node, String tagName, Map<String, String> attributes);

275

}

276

277

/**

278

* Factory for attribute providers

279

*/

280

public interface AttributeProviderFactory {

281

/**

282

* Create an attribute provider with the given context

283

* @param context the attribute provider context

284

* @return an attribute provider instance

285

*/

286

AttributeProvider create(AttributeProviderContext context);

287

}

288

289

/**

290

* Context for attribute providers

291

*/

292

public interface AttributeProviderContext {

293

// Context methods for attribute provision

294

}

295

```

296

297

**Usage Examples:**

298

299

```java

300

import org.commonmark.renderer.html.AttributeProvider;

301

import org.commonmark.node.*;

302

303

// Add CSS classes to headings

304

AttributeProvider headingClassProvider = new AttributeProvider() {

305

@Override

306

public void setAttributes(Node node, String tagName, Map<String, String> attributes) {

307

if (node instanceof Heading) {

308

Heading heading = (Heading) node;

309

attributes.put("class", "heading heading-" + heading.getLevel());

310

}

311

}

312

};

313

314

// Add target="_blank" to external links

315

AttributeProvider externalLinkProvider = new AttributeProvider() {

316

@Override

317

public void setAttributes(Node node, String tagName, Map<String, String> attributes) {

318

if (node instanceof Link && tagName.equals("a")) {

319

Link link = (Link) node;

320

if (link.getDestination().startsWith("http")) {

321

attributes.put("target", "_blank");

322

attributes.put("rel", "noopener");

323

}

324

}

325

}

326

};

327

328

// Use providers

329

HtmlRenderer renderer = HtmlRenderer.builder()

330

.attributeProviderFactory(context -> headingClassProvider)

331

.attributeProviderFactory(context -> externalLinkProvider)

332

.build();

333

```

334

335

### URL Sanitization

336

337

System for sanitizing URLs in links and images for security.

338

339

```java { .api }

340

/**

341

* Sanitizes URLs in links and images

342

*/

343

public interface UrlSanitizer {

344

/**

345

* Sanitize a link URL

346

* @param url the URL to sanitize

347

* @return the sanitized URL, or null to remove the URL

348

*/

349

String sanitizeLinkUrl(String url);

350

351

/**

352

* Sanitize an image URL

353

* @param url the URL to sanitize

354

* @return the sanitized URL, or null to remove the URL

355

*/

356

String sanitizeImageUrl(String url);

357

}

358

359

/**

360

* Default URL sanitizer implementation

361

*/

362

public class DefaultUrlSanitizer implements UrlSanitizer {

363

/**

364

* Sanitize a link URL - allows http, https, ftp, mailto

365

* @param url the URL to sanitize

366

* @return the sanitized URL, or null if not allowed

367

*/

368

public String sanitizeLinkUrl(String url);

369

370

/**

371

* Sanitize an image URL - allows http, https, data

372

* @param url the URL to sanitize

373

* @return the sanitized URL, or null if not allowed

374

*/

375

public String sanitizeImageUrl(String url);

376

}

377

```

378

379

**Usage Examples:**

380

381

```java

382

import org.commonmark.renderer.html.UrlSanitizer;

383

import org.commonmark.renderer.html.DefaultUrlSanitizer;

384

385

// Custom URL sanitizer

386

UrlSanitizer strictSanitizer = new UrlSanitizer() {

387

@Override

388

public String sanitizeLinkUrl(String url) {

389

// Only allow https URLs

390

if (url.startsWith("https://")) {

391

return url;

392

}

393

return null; // Remove unsafe URLs

394

}

395

396

@Override

397

public String sanitizeImageUrl(String url) {

398

// Only allow https images or data URLs

399

if (url.startsWith("https://") || url.startsWith("data:image/")) {

400

return url;

401

}

402

return null;

403

}

404

};

405

406

HtmlRenderer renderer = HtmlRenderer.builder()

407

.sanitizeUrls(true)

408

.urlSanitizer(strictSanitizer)

409

.build();

410

```

411

412

### HTML Writer

413

414

Low-level HTML writing utility used by node renderers.

415

416

```java { .api }

417

/**

418

* Helper for writing HTML output

419

*/

420

public class HtmlWriter {

421

/**

422

* Create an HTML writer that writes to the given appendable

423

* @param out the appendable to write to

424

*/

425

public HtmlWriter(Appendable out);

426

427

/**

428

* Write raw HTML content (not escaped)

429

* @param s the raw HTML to write

430

*/

431

public void raw(String s);

432

433

/**

434

* Write text content (HTML-escaped)

435

* @param text the text to write

436

*/

437

public void text(String text);

438

439

/**

440

* Write an HTML tag with no attributes

441

* @param name the tag name

442

*/

443

public void tag(String name);

444

445

/**

446

* Write an HTML tag with attributes

447

* @param name the tag name

448

* @param attrs the attributes map

449

*/

450

public void tag(String name, Map<String, String> attrs);

451

452

/**

453

* Write an HTML tag with attributes, specifying if it's a void element

454

* @param name the tag name

455

* @param attrs the attributes map

456

* @param voidElement true if this is a void element (like <br>)

457

*/

458

public void tag(String name, Map<String, String> attrs, boolean voidElement);

459

460

/**

461

* Write a line break

462

*/

463

public void line();

464

}

465

```

466

467

### Core HTML Node Renderer

468

469

The built-in renderer that handles all core CommonMark nodes.

470

471

```java { .api }

472

/**

473

* Core HTML renderer for built-in nodes

474

*/

475

public class CoreHtmlNodeRenderer extends AbstractVisitor implements NodeRenderer {

476

/**

477

* Create a core HTML node renderer with the given context

478

* @param context the rendering context

479

*/

480

public CoreHtmlNodeRenderer(HtmlNodeRendererContext context);

481

482

/**

483

* Get the node types this renderer handles

484

* @return set of node types

485

*/

486

public Set<Class<? extends Node>> getNodeTypes();

487

488

/**

489

* Render the specified node

490

* @param node the node to render

491

*/

492

public void render(Node node);

493

494

// Visit methods for all core node types (inherited from AbstractVisitor)

495

}

496

```

497

498

**Usage Examples:**

499

500

```java

501

import org.commonmark.renderer.html.HtmlWriter;

502

import org.commonmark.renderer.html.HtmlNodeRendererContext;

503

import org.commonmark.renderer.NodeRenderer;

504

import org.commonmark.node.CustomBlock;

505

506

// Custom node renderer example

507

public class CustomBlockRenderer implements NodeRenderer {

508

private final HtmlNodeRendererContext context;

509

private final HtmlWriter html;

510

511

public CustomBlockRenderer(HtmlNodeRendererContext context) {

512

this.context = context;

513

this.html = context.getWriter();

514

}

515

516

@Override

517

public Set<Class<? extends Node>> getNodeTypes() {

518

return Collections.singleton(CustomBlock.class);

519

}

520

521

@Override

522

public void render(Node node) {

523

CustomBlock customBlock = (CustomBlock) node;

524

525

Map<String, String> attrs = new HashMap<>();

526

attrs.put("class", "custom-block");

527

528

html.tag("div", context.extendAttributes(node, "div", attrs));

529

renderChildren(customBlock);

530

html.tag("/div");

531

}

532

533

private void renderChildren(Node parent) {

534

Node child = parent.getFirstChild();

535

while (child != null) {

536

context.render(child);

537

child = child.getNext();

538

}

539

}

540

}

541

542

// Register custom renderer

543

HtmlRenderer renderer = HtmlRenderer.builder()

544

.nodeRendererFactory(context -> new CustomBlockRenderer(context))

545

.build();

546

```