or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

editor-commands.mdeditor-core.mdeditor-factory.mdextension-system.mdindex.mdlanguage-support.mdmime-type-service.mdsearch-replace.mdspecial-extensions.mdtheme-system.md
tile.json

mime-type-service.mddocs/

0

# MIME Type Service

1

2

Service for resolving MIME types based on file extensions, language metadata, and content analysis for proper syntax highlighting.

3

4

## Capabilities

5

6

### CodeMirrorMimeTypeService

7

8

Main service class for MIME type resolution and language detection.

9

10

```typescript { .api }

11

/**

12

* The MIME type service for CodeMirror

13

* Resolves MIME types from file paths and language metadata

14

*/

15

class CodeMirrorMimeTypeService implements IEditorMimeTypeService {

16

constructor(languages: IEditorLanguageRegistry);

17

18

/**

19

* Returns a MIME type for the given language info

20

* Used with Jupyter notebook language metadata

21

*/

22

getMimeTypeByLanguage(info: nbformat.ILanguageInfoMetadata): string;

23

24

/**

25

* Returns a MIME type for the given file path

26

* Analyzes file extension and filename patterns

27

*/

28

getMimeTypeByFilePath(path: string): string;

29

}

30

31

interface IEditorMimeTypeService {

32

getMimeTypeByLanguage(info: nbformat.ILanguageInfoMetadata): string;

33

getMimeTypeByFilePath(path: string): string;

34

}

35

```

36

37

**Usage Examples:**

38

39

```typescript

40

import {

41

CodeMirrorMimeTypeService,

42

EditorLanguageRegistry

43

} from "@jupyterlab/codemirror";

44

45

// Create service with language registry

46

const languages = new EditorLanguageRegistry();

47

const mimeService = new CodeMirrorMimeTypeService(languages);

48

49

// Get MIME type from file path

50

const pythonMime = mimeService.getMimeTypeByFilePath('script.py');

51

console.log(pythonMime); // "text/x-python"

52

53

const jsMime = mimeService.getMimeTypeByFilePath('app.js');

54

console.log(jsMime); // "text/javascript"

55

56

const tsMime = mimeService.getMimeTypeByFilePath('component.tsx');

57

console.log(tsMime); // "text/typescript-jsx"

58

59

// Get MIME type from language metadata

60

const languageInfo = {

61

name: 'python',

62

version: '3.9.0',

63

mimetype: 'text/x-python',

64

file_extension: '.py'

65

};

66

67

const mimeType = mimeService.getMimeTypeByLanguage(languageInfo);

68

console.log(mimeType); // "text/x-python"

69

```

70

71

### File Extension Resolution

72

73

MIME type detection based on file extensions and filename patterns.

74

75

```typescript

76

// File extension to MIME type mapping examples

77

const extensionExamples = {

78

'.py': 'text/x-python',

79

'.js': 'text/javascript',

80

'.ts': 'text/typescript',

81

'.tsx': 'text/typescript-jsx',

82

'.jsx': 'text/jsx',

83

'.html': 'text/html',

84

'.css': 'text/css',

85

'.json': 'application/json',

86

'.md': 'text/markdown',

87

'.yml': 'text/yaml',

88

'.yaml': 'text/yaml',

89

'.xml': 'text/xml',

90

'.sql': 'text/sql',

91

'.sh': 'text/x-sh',

92

'.dockerfile': 'text/x-dockerfile',

93

'.java': 'text/x-java',

94

'.c': 'text/x-csrc',

95

'.cpp': 'text/x-c++src',

96

'.h': 'text/x-chdr',

97

'.php': 'text/x-php',

98

'.rb': 'text/x-ruby',

99

'.go': 'text/x-go',

100

'.rs': 'text/x-rustsrc',

101

'.swift': 'text/x-swift',

102

'.kt': 'text/x-kotlin'

103

};

104

105

// Special filename patterns

106

const filenamePatterns = {

107

'Dockerfile': 'text/x-dockerfile',

108

'Makefile': 'text/x-makefile',

109

'CMakeLists.txt': 'text/x-cmake',

110

'.gitignore': 'text/plain',

111

'.env': 'text/plain',

112

'requirements.txt': 'text/plain',

113

'package.json': 'application/json',

114

'tsconfig.json': 'application/json',

115

'.eslintrc.json': 'application/json'

116

};

117

118

// Usage in service

119

function detectMimeType(filePath: string): string {

120

const service = new CodeMirrorMimeTypeService(languages);

121

return service.getMimeTypeByFilePath(filePath);

122

}

123

124

// Examples

125

console.log(detectMimeType('script.py')); // "text/x-python"

126

console.log(detectMimeType('Dockerfile')); // "text/x-dockerfile"

127

console.log(detectMimeType('component.vue')); // Detected based on registry

128

```

129

130

### Language Metadata Resolution

131

132

Integration with Jupyter notebook language metadata format.

133

134

```typescript

135

import { nbformat } from "@jupyterlab/nbformat";

136

137

// Language metadata examples

138

const pythonLanguageInfo: nbformat.ILanguageInfoMetadata = {

139

name: 'python',

140

version: '3.9.0',

141

mimetype: 'text/x-python',

142

file_extension: '.py',

143

pygments_lexer: 'ipython3',

144

codemirror_mode: 'python'

145

};

146

147

const javascriptLanguageInfo: nbformat.ILanguageInfoMetadata = {

148

name: 'javascript',

149

version: 'ES2020',

150

mimetype: 'text/javascript',

151

file_extension: '.js'

152

};

153

154

const rLanguageInfo: nbformat.ILanguageInfoMetadata = {

155

name: 'R',

156

version: '4.1.0',

157

mimetype: 'text/x-rsrc',

158

file_extension: '.r'

159

};

160

161

// Resolve MIME types from metadata

162

function resolveMimeFromMetadata(info: nbformat.ILanguageInfoMetadata): string {

163

const service = new CodeMirrorMimeTypeService(languages);

164

return service.getMimeTypeByLanguage(info);

165

}

166

167

// Priority order for resolution:

168

// 1. Explicit mimetype in metadata

169

// 2. Language name lookup in registry

170

// 3. File extension lookup

171

// 4. Fallback to 'text/plain'

172

173

const resolvedMime = resolveMimeFromMetadata(pythonLanguageInfo);

174

console.log(resolvedMime); // "text/x-python"

175

```

176

177

### Custom MIME Type Registration

178

179

Extending the service with custom MIME type mappings.

180

181

```typescript

182

// Custom language registration affects MIME type resolution

183

const customLanguage: IEditorLanguage = {

184

name: 'mylang',

185

displayName: 'My Custom Language',

186

mime: ['text/x-mylang', 'application/x-mylang'],

187

extensions: ['.ml', '.mylang'],

188

filename: /^\.mylangrc$/

189

};

190

191

// Register custom language

192

languages.addLanguage(customLanguage);

193

194

// Now MIME service can resolve custom types

195

const customMime = mimeService.getMimeTypeByFilePath('script.ml');

196

console.log(customMime); // "text/x-mylang"

197

198

// Custom MIME type mapping function

199

function createCustomMimeService(

200

languages: IEditorLanguageRegistry,

201

customMappings: Record<string, string>

202

): CodeMirrorMimeTypeService {

203

204

class CustomMimeTypeService extends CodeMirrorMimeTypeService {

205

getMimeTypeByFilePath(path: string): string {

206

// Check custom mappings first

207

const extension = path.toLowerCase().split('.').pop();

208

if (extension && customMappings[`.${extension}`]) {

209

return customMappings[`.${extension}`];

210

}

211

212

// Check filename patterns

213

const filename = path.split('/').pop() || '';

214

if (customMappings[filename]) {

215

return customMappings[filename];

216

}

217

218

// Fall back to default behavior

219

return super.getMimeTypeByFilePath(path);

220

}

221

}

222

223

return new CustomMimeTypeService(languages);

224

}

225

226

// Use custom service

227

const customService = createCustomMimeService(languages, {

228

'.vue': 'text/x-vue',

229

'.svelte': 'text/x-svelte',

230

'.astro': 'text/x-astro',

231

'BUILD': 'text/x-bazel',

232

'WORKSPACE': 'text/x-bazel'

233

});

234

```

235

236

### Integration with Editor

237

238

Using the MIME type service to configure editor language support.

239

240

```typescript

241

import {

242

CodeMirrorEditor,

243

CodeMirrorMimeTypeService,

244

EditorLanguageRegistry

245

} from "@jupyterlab/codemirror";

246

import { CodeEditor } from "@jupyterlab/codeeditor";

247

248

// Create integrated editor factory with MIME type service

249

class IntegratedEditorFactory {

250

private mimeService: CodeMirrorMimeTypeService;

251

private languages: EditorLanguageRegistry;

252

253

constructor() {

254

this.languages = new EditorLanguageRegistry();

255

this.mimeService = new CodeMirrorMimeTypeService(this.languages);

256

}

257

258

// Create editor with automatic language detection

259

createEditorForFile(filePath: string, content: string): CodeMirrorEditor {

260

const model = new CodeEditor.Model();

261

const host = document.createElement('div');

262

263

// Auto-detect MIME type

264

const mimeType = this.mimeService.getMimeTypeByFilePath(filePath);

265

266

// Create editor

267

const editor = new CodeMirrorEditor({

268

model,

269

host,

270

languages: this.languages

271

});

272

273

// Configure editor

274

model.sharedModel.setSource(content);

275

model.mimeType = mimeType;

276

277

return editor;

278

}

279

280

// Create editor from notebook language metadata

281

createEditorFromLanguageInfo(

282

info: nbformat.ILanguageInfoMetadata,

283

content: string

284

): CodeMirrorEditor {

285

const model = new CodeEditor.Model();

286

const host = document.createElement('div');

287

288

// Resolve MIME type from metadata

289

const mimeType = this.mimeService.getMimeTypeByLanguage(info);

290

291

const editor = new CodeMirrorEditor({

292

model,

293

host,

294

languages: this.languages

295

});

296

297

model.sharedModel.setSource(content);

298

model.mimeType = mimeType;

299

300

return editor;

301

}

302

}

303

304

// Usage

305

const factory = new IntegratedEditorFactory();

306

307

// Create editor for Python file

308

const pythonEditor = factory.createEditorForFile(

309

'analysis.py',

310

'import pandas as pd\ndf = pd.read_csv("data.csv")'

311

);

312

313

// Create editor from notebook metadata

314

const notebookEditor = factory.createEditorFromLanguageInfo(

315

{

316

name: 'python',

317

version: '3.9.0',

318

mimetype: 'text/x-python',

319

file_extension: '.py'

320

},

321

'print("Hello from notebook!")'

322

);

323

```

324

325

### Advanced MIME Type Detection

326

327

Complex scenarios for MIME type detection and content analysis.

328

329

```typescript

330

// Content-based MIME type detection

331

function detectMimeFromContent(content: string, filePath?: string): string {

332

const mimeService = new CodeMirrorMimeTypeService(languages);

333

334

// Start with file path if available

335

let detectedMime = filePath ? mimeService.getMimeTypeByFilePath(filePath) : 'text/plain';

336

337

// Override based on content patterns

338

if (content.startsWith('#!/usr/bin/env python') || content.startsWith('#!/usr/bin/python')) {

339

return 'text/x-python';

340

}

341

342

if (content.startsWith('#!/bin/bash') || content.startsWith('#!/usr/bin/bash')) {

343

return 'text/x-sh';

344

}

345

346

if (content.startsWith('#!/usr/bin/env node') || content.startsWith('#!/usr/bin/node')) {

347

return 'text/javascript';

348

}

349

350

if (content.includes('<!DOCTYPE html>')) {

351

return 'text/html';

352

}

353

354

if (content.trim().startsWith('{') || content.trim().startsWith('[')) {

355

try {

356

JSON.parse(content);

357

return 'application/json';

358

} catch {

359

// Not valid JSON, keep original detection

360

}

361

}

362

363

return detectedMime;

364

}

365

366

// Multi-language file detection (e.g., Vue, Svelte)

367

function detectMultiLanguageFile(filePath: string): string[] {

368

const extension = filePath.toLowerCase().split('.').pop();

369

370

switch (extension) {

371

case 'vue':

372

return ['text/html', 'text/javascript', 'text/css']; // Template, script, style

373

case 'svelte':

374

return ['text/html', 'text/javascript', 'text/css'];

375

case 'astro':

376

return ['text/html', 'text/javascript', 'text/css', 'text/markdown'];

377

case 'md':

378

case 'markdown':

379

return ['text/markdown', 'text/javascript', 'text/css']; // With code blocks

380

default:

381

return [new CodeMirrorMimeTypeService(languages).getMimeTypeByFilePath(filePath)];

382

}

383

}

384

385

// Context-aware MIME type service

386

class ContextAwareMimeTypeService extends CodeMirrorMimeTypeService {

387

private context: 'notebook' | 'file-editor' | 'console';

388

389

constructor(languages: IEditorLanguageRegistry, context: string) {

390

super(languages);

391

this.context = context as any;

392

}

393

394

getMimeTypeByFilePath(path: string): string {

395

const baseMime = super.getMimeTypeByFilePath(path);

396

397

// Adjust based on context

398

if (this.context === 'notebook') {

399

// In notebooks, prefer IPython for Python

400

if (baseMime === 'text/x-python') {

401

return 'text/x-ipython';

402

}

403

}

404

405

if (this.context === 'console') {

406

// In console, prefer REPL-friendly modes

407

if (baseMime === 'text/javascript') {

408

return 'text/javascript-repl';

409

}

410

}

411

412

return baseMime;

413

}

414

}

415

```

416

417

## Types

418

419

```typescript { .api }

420

interface IEditorMimeTypeService {

421

getMimeTypeByLanguage(info: nbformat.ILanguageInfoMetadata): string;

422

getMimeTypeByFilePath(path: string): string;

423

}

424

425

namespace nbformat {

426

interface ILanguageInfoMetadata {

427

name: string;

428

version?: string;

429

mimetype?: string;

430

file_extension?: string;

431

pygments_lexer?: string;

432

codemirror_mode?: string | Record<string, any>;

433

}

434

}

435

436

class CodeMirrorMimeTypeService implements IEditorMimeTypeService {

437

constructor(languages: IEditorLanguageRegistry);

438

getMimeTypeByLanguage(info: nbformat.ILanguageInfoMetadata): string;

439

getMimeTypeByFilePath(path: string): string;

440

}

441

```