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

text-rendering.mddocs/

0

# Text Content Rendering

1

2

Plain text rendering system for converting CommonMark documents back to text format with optional newline stripping and custom formatting. The text renderer extracts textual content from AST nodes while preserving document structure and readability.

3

4

## Capabilities

5

6

### Text Content Renderer

7

8

Main rendering class that converts AST nodes to plain text output.

9

10

```java { .api }

11

/**

12

* Renders a tree of nodes to plain text.

13

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

14

*/

15

public class TextContentRenderer implements Renderer {

16

/**

17

* Create a new builder for configuring a TextContentRenderer

18

* @return a builder instance

19

*/

20

public static Builder builder();

21

22

/**

23

* Render the node to text and return as string

24

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

25

* @return the rendered text as a string

26

*/

27

public String render(Node node);

28

29

/**

30

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

31

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

32

* @param output the appendable to write text 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.text.TextContentRenderer;

43

import org.commonmark.node.Node;

44

45

// Basic text rendering

46

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

47

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

48

49

Node document = parser.parse("# Hello\n\nThis is **bold** text with a [link](url).");

50

String text = renderer.render(document);

51

// Result: "Hello\n\nThis is bold text with a link."

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.txt")) {

59

renderer.render(document, writer);

60

}

61

```

62

63

### Text Content Renderer Builder

64

65

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

66

67

```java { .api }

68

/**

69

* Builder for configuring a TextContentRenderer

70

*/

71

public static class TextContentRenderer.Builder {

72

/**

73

* Build the configured TextContentRenderer instance

74

* @return the configured TextContentRenderer

75

*/

76

public TextContentRenderer build();

77

78

/**

79

* Whether to strip newlines and render everything on one line, defaults to false

80

* @param stripNewlines true to strip newlines, false to preserve line structure

81

* @return this builder

82

*/

83

public Builder stripNewlines(boolean stripNewlines);

84

85

/**

86

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

87

* @param nodeRendererFactory the factory for creating a node renderer

88

* @return this builder

89

*/

90

public Builder nodeRendererFactory(TextContentNodeRendererFactory nodeRendererFactory);

91

92

/**

93

* Add extensions to use on this text renderer

94

* @param extensions extensions to use on this text renderer

95

* @return this builder

96

*/

97

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

98

}

99

```

100

101

**Usage Examples:**

102

103

```java

104

import org.commonmark.renderer.text.TextContentRenderer;

105

106

// Strip newlines for single-line output

107

TextContentRenderer singleLineRenderer = TextContentRenderer.builder()

108

.stripNewlines(true)

109

.build();

110

111

Node document = parser.parse("# Title\n\nParagraph one.\n\nParagraph two.");

112

String singleLine = singleLineRenderer.render(document);

113

// Result: "Title Paragraph one. Paragraph two."

114

115

// Preserve line structure (default)

116

TextContentRenderer structuredRenderer = TextContentRenderer.builder()

117

.stripNewlines(false)

118

.build();

119

120

String structured = structuredRenderer.render(document);

121

// Result: "Title\n\nParagraph one.\n\nParagraph two."

122

```

123

124

### Text Content Renderer Extension System

125

126

Extension interfaces and classes for customizing text rendering behavior.

127

128

```java { .api }

129

/**

130

* Extension interface for text content renderer

131

*/

132

public interface TextContentRenderer.TextContentRendererExtension extends Extension {

133

/**

134

* Extend the text content renderer builder with custom functionality

135

* @param rendererBuilder the builder to extend

136

*/

137

void extend(TextContentRenderer.Builder rendererBuilder);

138

}

139

140

/**

141

* Factory for text content node renderers

142

*/

143

public interface TextContentNodeRendererFactory {

144

/**

145

* Create a node renderer with the given context

146

* @param context the rendering context

147

* @return a node renderer instance

148

*/

149

NodeRenderer create(TextContentNodeRendererContext context);

150

}

151

152

/**

153

* Context for text content node rendering

154

*/

155

public interface TextContentNodeRendererContext {

156

/**

157

* Whether newlines should be stripped

158

* @return true if newlines should be stripped

159

*/

160

boolean stripNewlines();

161

162

/**

163

* Get the text content writer

164

* @return the text content writer

165

*/

166

TextContentWriter getWriter();

167

168

/**

169

* Render a child node

170

* @param node the node to render

171

*/

172

void render(Node node);

173

}

174

```

175

176

### Text Content Writer

177

178

Low-level text writing utility used by node renderers.

179

180

```java { .api }

181

/**

182

* Helper for writing text content

183

*/

184

public class TextContentWriter {

185

/**

186

* Create a text content writer that writes to the given appendable

187

* @param out the appendable to write to

188

*/

189

public TextContentWriter(Appendable out);

190

191

/**

192

* Write whitespace (space character)

193

*/

194

public void whitespace();

195

196

/**

197

* Write a colon character

198

*/

199

public void colon();

200

201

/**

202

* Write a line break

203

*/

204

public void line();

205

206

/**

207

* Write text content, stripping newlines if configured

208

* @param s the text to write

209

*/

210

public void writeStripped(String s);

211

212

/**

213

* Write text content as-is

214

* @param s the text to write

215

*/

216

public void write(String s);

217

218

/**

219

* Write a single character

220

* @param c the character to write

221

*/

222

public void write(char c);

223

}

224

```

225

226

**Usage Examples:**

227

228

```java

229

import org.commonmark.renderer.text.TextContentWriter;

230

231

// Custom text writer usage

232

StringBuilder output = new StringBuilder();

233

TextContentWriter writer = new TextContentWriter(output);

234

235

writer.write("Hello");

236

writer.whitespace();

237

writer.write("world");

238

writer.line();

239

writer.writeStripped("Text with\nnewlines"); // May strip newlines based on configuration

240

```

241

242

### Core Text Content Node Renderer

243

244

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

245

246

```java { .api }

247

/**

248

* Core text content renderer for built-in nodes

249

*/

250

public class CoreTextContentNodeRenderer extends AbstractVisitor implements NodeRenderer {

251

/**

252

* Create a core text content node renderer with the given context

253

* @param context the rendering context

254

*/

255

public CoreTextContentNodeRenderer(TextContentNodeRendererContext context);

256

257

/**

258

* Get the node types this renderer handles

259

* @return set of node types

260

*/

261

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

262

263

/**

264

* Render the specified node

265

* @param node the node to render

266

*/

267

public void render(Node node);

268

269

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

270

}

271

```

272

273

## Text Rendering Behavior

274

275

The text content renderer handles different node types with specific text extraction logic:

276

277

### Block Elements

278

- **Document**: Renders all child blocks with appropriate spacing

279

- **Heading**: Renders heading text followed by double newline

280

- **Paragraph**: Renders paragraph text followed by double newline

281

- **BlockQuote**: Renders quoted text with standard spacing

282

- **Code Blocks**: Renders code content with appropriate line breaks

283

- **Lists**: Renders list items with appropriate spacing and structure

284

- **Thematic Break**: Renders as empty (no text content)

285

- **HTML Blocks**: Renders as empty (HTML content stripped)

286

287

### Inline Elements

288

- **Text**: Renders literal text content

289

- **Code**: Renders code content without backticks

290

- **Emphasis/Strong**: Renders emphasized text without formatting markers

291

- **Link**: Renders link text content (URL is ignored)

292

- **Image**: Renders alt text content

293

- **Line Breaks**: Renders as space or newline depending on type

294

- **HTML Inline**: Renders as empty (HTML content stripped)

295

296

**Usage Examples:**

297

298

```java

299

import org.commonmark.renderer.text.TextContentRenderer;

300

import org.commonmark.renderer.text.TextContentNodeRendererFactory;

301

import org.commonmark.renderer.text.TextContentNodeRendererContext;

302

import org.commonmark.renderer.NodeRenderer;

303

import org.commonmark.node.CustomNode;

304

305

// Custom text node renderer

306

public class CustomTextRenderer implements NodeRenderer {

307

private final TextContentNodeRendererContext context;

308

private final TextContentWriter writer;

309

310

public CustomTextRenderer(TextContentNodeRendererContext context) {

311

this.context = context;

312

this.writer = context.getWriter();

313

}

314

315

@Override

316

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

317

return Collections.singleton(CustomNode.class);

318

}

319

320

@Override

321

public void render(Node node) {

322

CustomNode customNode = (CustomNode) node;

323

324

writer.write("[CUSTOM: ");

325

renderChildren(customNode);

326

writer.write("]");

327

}

328

329

private void renderChildren(Node parent) {

330

Node child = parent.getFirstChild();

331

while (child != null) {

332

context.render(child);

333

child = child.getNext();

334

}

335

}

336

}

337

338

// Register custom text renderer

339

TextContentRenderer renderer = TextContentRenderer.builder()

340

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

341

.build();

342

343

// Demonstrate different rendering modes

344

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

345

Node document = parser.parse(

346

"# Title\n\n" +

347

"This is a paragraph with **bold** text and a [link](url).\n\n" +

348

"- List item 1\n" +

349

"- List item 2\n\n" +

350

"```java\n" +

351

"System.out.println(\"code\");\n" +

352

"```"

353

);

354

355

// Default text rendering (preserves structure)

356

TextContentRenderer defaultRenderer = TextContentRenderer.builder().build();

357

String structured = defaultRenderer.render(document);

358

System.out.println("Structured:\n" + structured);

359

360

// Single-line text rendering

361

TextContentRenderer singleLineRenderer = TextContentRenderer.builder()

362

.stripNewlines(true)

363

.build();

364

String singleLine = singleLineRenderer.render(document);

365

System.out.println("Single line: " + singleLine);

366

```

367

368

## Common Use Cases

369

370

### Extract Plain Text from Markdown

371

```java

372

// Convert Markdown to plain text for search indexing

373

String markdown = "# Article Title\n\nThis **article** discusses [CommonMark](url).";

374

Node document = parser.parse(markdown);

375

String plainText = textRenderer.render(document);

376

// Use plainText for full-text search, previews, etc.

377

```

378

379

### Generate Text Summaries

380

```java

381

// Generate single-line summary

382

TextContentRenderer summaryRenderer = TextContentRenderer.builder()

383

.stripNewlines(true)

384

.build();

385

String summary = summaryRenderer.render(document);

386

// Use summary for meta descriptions, previews, etc.

387

```

388

389

### Extract Headings for Table of Contents

390

```java

391

// Custom renderer to extract only headings

392

public class HeadingExtractor implements NodeRenderer {

393

// Implementation that only renders heading text

394

}

395

```