or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching.mdconfiguration.mdenvironment-cli.mdindex.mdpackage-management.mdpresets.mdstory-processing.mdtext-processing.md

text-processing.mddocs/

0

# Text Processing & Formatting

1

2

Template interpolation, code formatting, and logging utilities for development tools and code generation. These utilities provide consistent text processing capabilities across Storybook tooling.

3

4

## Capabilities

5

6

### Template Interpolation

7

8

String template interpolation with variable substitution using `{{key}}` syntax.

9

10

```typescript { .api }

11

/**

12

* Template string interpolation with variable substitution

13

* @param template - Template string with {{key}} placeholders

14

* @param bindings - Object with key-value pairs for substitution

15

* @returns Interpolated string with variables replaced

16

*/

17

function interpolate(template: string, bindings: Record<string, any>): string;

18

```

19

20

**Usage Examples:**

21

22

```typescript

23

import { interpolate } from "@storybook/core-common";

24

25

// Basic interpolation

26

const template = 'Hello {{name}}, welcome to {{app}}!';

27

const result = interpolate(template, {

28

name: 'Alice',

29

app: 'Storybook'

30

});

31

console.log(result); // 'Hello Alice, welcome to Storybook!'

32

33

// HTML template interpolation

34

const htmlTemplate = `

35

<div class="{{className}}">

36

<h1>{{title}}</h1>

37

<p>Version: {{version}}</p>

38

</div>

39

`;

40

41

const html = interpolate(htmlTemplate, {

42

className: 'story-container',

43

title: 'My Component',

44

version: '1.2.0'

45

});

46

```

47

48

### Code Formatting

49

50

Format code content using Prettier with intelligent fallbacks and error handling.

51

52

```typescript { .api }

53

/**

54

* Format code using Prettier with fallbacks for different file types

55

* @param filePath - File path for parser detection

56

* @param content - Code content to format

57

* @returns Promise resolving to formatted code content

58

*/

59

function formatFileContent(filePath: string, content: string): Promise<string>;

60

```

61

62

**Usage Examples:**

63

64

```typescript

65

import { formatFileContent } from "@storybook/core-common";

66

67

// Format JavaScript code

68

const jsCode = `

69

const component={props}=><div className="test">{props.children}</div>;

70

export default component;

71

`;

72

73

const formattedJs = await formatFileContent('Component.js', jsCode);

74

console.log(formattedJs);

75

// const component = ({ props }) => (

76

// <div className="test">{props.children}</div>

77

// );

78

// export default component;

79

80

// Format TypeScript

81

const tsCode = `interface Props{title:string;onClick:()=>void;}`;

82

const formattedTs = await formatFileContent('types.ts', tsCode);

83

84

// Format JSON

85

const jsonCode = `{"name":"my-app","version":"1.0.0"}`;

86

const formattedJson = await formatFileContent('package.json', jsonCode);

87

```

88

89

### Logging Utilities

90

91

Styled logging functions for command-line interfaces and development tools.

92

93

```typescript { .api }

94

/**

95

* Styled command logging with success/error callbacks

96

* @param message - Base log message

97

* @returns Object with success and error logging methods

98

*/

99

function commandLog(message: string): {

100

success: (message: string) => void;

101

error: (message: string) => void;

102

};

103

104

/**

105

* Indented logging with consistent padding

106

* @param message - Message to log with padding

107

*/

108

function paddedLog(message: string): void;

109

110

/**

111

* Format code blocks for display with syntax highlighting hints

112

* @param codeLines - Array of code lines or single code string

113

* @param leftPadAmount - Left padding amount in spaces

114

*/

115

function codeLog(codeLines: string[] | string, leftPadAmount?: number): void;

116

117

/**

118

* Generate repeated character strings for formatting

119

* @param char - Character to repeat

120

* @param amount - Number of repetitions

121

* @returns String with repeated characters

122

*/

123

function getChars(char: string, amount: number): string;

124

```

125

126

**Usage Examples:**

127

128

```typescript

129

import {

130

commandLog,

131

paddedLog,

132

codeLog,

133

getChars

134

} from "@storybook/core-common";

135

136

// Command logging with status

137

const buildLog = commandLog('Building Storybook');

138

buildLog.success('Build completed successfully!');

139

buildLog.error('Build failed with errors');

140

141

// Padded logging for hierarchical output

142

console.log('Starting process...');

143

paddedLog('Loading configuration');

144

paddedLog('Processing stories');

145

paddedLog('Generating output');

146

147

// Code block logging

148

codeLog([

149

'import { Meta, StoryObj } from "@storybook/react";',

150

'import { Button } from "./Button";',

151

'',

152

'const meta: Meta<typeof Button> = {',

153

' title: "Example/Button",',

154

' component: Button,',

155

'};'

156

], 2);

157

158

// Character repetition for separators

159

const separator = getChars('=', 50);

160

console.log(separator);

161

console.log('Section Title');

162

console.log(separator);

163

```

164

165

### Template Generation

166

167

Generate HTML templates for Storybook preview with variable interpolation.

168

169

```typescript { .api }

170

/**

171

* Generate preview body HTML template with interpolations

172

* @param configDir - Storybook configuration directory

173

* @param interpolations - Variables for template interpolation

174

* @returns Generated HTML body content

175

*/

176

function getPreviewBodyTemplate(

177

configDir: string,

178

interpolations?: Record<string, any>

179

): Promise<string>;

180

181

/**

182

* Generate preview head HTML template with interpolations

183

* @param configDir - Storybook configuration directory

184

* @param interpolations - Variables for template interpolation

185

* @returns Generated HTML head content

186

*/

187

function getPreviewHeadTemplate(

188

configDir: string,

189

interpolations?: Record<string, any>

190

): Promise<string>;

191

```

192

193

**Usage Examples:**

194

195

```typescript

196

import {

197

getPreviewBodyTemplate,

198

getPreviewHeadTemplate

199

} from "@storybook/core-common";

200

201

// Generate preview templates

202

const bodyHtml = await getPreviewBodyTemplate('.storybook', {

203

theme: 'dark',

204

customStyles: '/assets/custom.css'

205

});

206

207

const headHtml = await getPreviewHeadTemplate('.storybook', {

208

title: 'My Storybook',

209

favicon: '/assets/favicon.ico'

210

});

211

212

// Use in HTML generation

213

const fullHtml = `

214

<!DOCTYPE html>

215

<html>

216

<head>

217

${headHtml}

218

</head>

219

<body>

220

${bodyHtml}

221

</body>

222

</html>

223

`;

224

```

225

226

### File Template Reading

227

228

Read template files with fallback handling and error recovery.

229

230

```typescript { .api }

231

/**

232

* Read template file with fallbacks and error handling

233

* @param filePath - Path to template file

234

* @returns Promise resolving to template content

235

*/

236

function readTemplate(filePath: string): Promise<string>;

237

```

238

239

**Usage Example:**

240

241

```typescript

242

import { readTemplate, interpolate } from "@storybook/core-common";

243

244

// Read and process template

245

const templateContent = await readTemplate('./templates/component.template');

246

const processedTemplate = interpolate(templateContent, {

247

componentName: 'MyButton',

248

props: 'title: string; onClick: () => void'

249

});

250

251

console.log(processedTemplate);

252

```

253

254

## Advanced Text Processing Patterns

255

256

### Dynamic Template Processing

257

258

```typescript

259

import { interpolate, formatFileContent } from "@storybook/core-common";

260

261

async function generateComponentCode(config: {

262

name: string;

263

props: Record<string, string>;

264

framework: 'react' | 'vue' | 'angular';

265

}) {

266

// Load framework-specific template

267

const templateMap = {

268

react: 'export interface {{name}}Props {\n{{propTypes}}\n}\n\nexport const {{name}} = (props: {{name}}Props) => {\n return <div>{{name}}</div>;\n};',

269

vue: '<template>\n <div>{{name}}</div>\n</template>\n\n<script>\nexport default {\n name: "{{name}}",\n props: {\n{{propTypes}}\n }\n};\n</script>',

270

angular: '@Component({\n selector: "app-{{kebabName}}",\n template: "<div>{{name}}</div>"\n})\nexport class {{name}}Component {\n{{propTypes}}\n}'

271

};

272

273

// Process prop types

274

const propTypes = Object.entries(config.props)

275

.map(([key, type]) => ` ${key}: ${type};`)

276

.join('\n');

277

278

// Interpolate template

279

const code = interpolate(templateMap[config.framework], {

280

name: config.name,

281

kebabName: config.name.replace(/([A-Z])/g, '-$1').toLowerCase(),

282

propTypes

283

});

284

285

// Format the generated code

286

const extension = config.framework === 'react' ? '.tsx' :

287

config.framework === 'vue' ? '.vue' : '.ts';

288

289

return await formatFileContent(`${config.name}${extension}`, code);

290

}

291

```

292

293

### Structured Logging System

294

295

```typescript

296

import { commandLog, paddedLog, codeLog } from "@storybook/core-common";

297

298

class StorybookLogger {

299

private level: number = 0;

300

301

startSection(title: string) {

302

const log = commandLog(title);

303

this.level++;

304

return {

305

info: (msg: string) => paddedLog(`${' '.repeat(this.level)}${msg}`),

306

success: (msg: string) => {

307

log.success(msg);

308

this.level--;

309

},

310

error: (msg: string) => {

311

log.error(msg);

312

this.level--;

313

},

314

code: (code: string[] | string) => codeLog(code, this.level * 2)

315

};

316

}

317

}

318

319

// Usage

320

const logger = new StorybookLogger();

321

322

const buildSection = logger.startSection('Building Storybook');

323

buildSection.info('Loading configuration...');

324

buildSection.info('Processing stories...');

325

buildSection.code([

326

'Found 25 stories in:',

327

' - src/components/*.stories.tsx',

328

' - src/pages/*.stories.tsx'

329

]);

330

buildSection.success('Build completed successfully!');

331

```

332

333

### Template Caching System

334

335

```typescript

336

import { readTemplate, interpolate, cache } from "@storybook/core-common";

337

338

class TemplateCache {

339

private templateCache = new Map<string, string>();

340

341

async getTemplate(templatePath: string): Promise<string> {

342

// Check memory cache first

343

if (this.templateCache.has(templatePath)) {

344

return this.templateCache.get(templatePath)!;

345

}

346

347

// Check file system cache

348

const cacheKey = `template-${templatePath}`;

349

let template = await cache.get<string>(cacheKey);

350

351

if (!template) {

352

// Read from disk and cache

353

template = await readTemplate(templatePath);

354

await cache.set(cacheKey, template);

355

}

356

357

// Store in memory for immediate reuse

358

this.templateCache.set(templatePath, template);

359

return template;

360

}

361

362

async processTemplate(

363

templatePath: string,

364

bindings: Record<string, any>

365

): Promise<string> {

366

const template = await this.getTemplate(templatePath);

367

return interpolate(template, bindings);

368

}

369

}

370

371

// Usage

372

const templates = new TemplateCache();

373

const processed = await templates.processTemplate('./templates/story.template', {

374

componentName: 'Button',

375

storyName: 'Primary'

376

});

377

```

378

379

## Supporting Types

380

381

```typescript { .api }

382

interface InterpolationBindings {

383

[key: string]: string | number | boolean | null | undefined;

384

}

385

386

interface LogMethods {

387

success: (message: string) => void;

388

error: (message: string) => void;

389

}

390

391

interface TemplateOptions {

392

configDir: string;

393

interpolations?: Record<string, any>;

394

}

395

```