or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mddata-access.mdformat-conversion.mdindex.mdloading-config.mdrendering.md

advanced.mddocs/

0

# Advanced Features

1

2

This document covers advanced functionality including experimental editor features, layout manipulation, locale management, runtime measurement, and other specialized capabilities.

3

4

## Capabilities

5

6

### Experimental Editor Functions

7

8

Experimental editing capabilities for modifying loaded MEI documents.

9

10

**Warning**: These functions are experimental and should not be relied upon for production use. The API may change in future versions.

11

12

```python { .api }

13

class toolkit:

14

def edit(self, editor_action: dict) -> bool:

15

"""

16

Edit the MEI data (experimental).

17

18

This is experimental code not to rely on. The API and

19

behavior may change in future versions.

20

21

Args:

22

editor_action: Dictionary with editor action specifications

23

24

Returns:

25

True if edit action was successfully applied, False otherwise

26

"""

27

28

def editInfo(self) -> dict:

29

"""

30

Get editor status (experimental).

31

32

This is experimental code not to rely on. Returns information

33

about the current editor state.

34

35

Returns:

36

Dictionary with editor status information

37

"""

38

```

39

40

### Layout Manipulation

41

42

Redo layout calculations with updated options or after modifications.

43

44

```python { .api }

45

class toolkit:

46

def redoLayout(self, options: dict | None = None) -> None:

47

"""

48

Redo the layout of the loaded data.

49

50

Call this after changing rendering options (e.g., page size,

51

zoom level) to recalculate the layout without reloading data.

52

53

Args:

54

options: Dictionary with action options:

55

- resetCache: bool, true to reset cache (default: True)

56

"""

57

58

def redoPagePitchPosLayout(self) -> None:

59

"""

60

Redo pitch position layout for the current page.

61

62

Only recalculates vertical positions of notes. For full

63

recalculation, use redoLayout() instead.

64

"""

65

```

66

67

### Locale Management

68

69

Control locale settings for the toolkit instance.

70

71

```python { .api }

72

class toolkit:

73

def setLocale(self) -> None:

74

"""

75

Set the global locale for the toolkit instance.

76

"""

77

78

def resetLocale(self) -> None:

79

"""

80

Reset the global locale to the previous value.

81

"""

82

```

83

84

### Runtime Measurement

85

86

Measure and log execution time for performance analysis.

87

88

```python { .api }

89

class toolkit:

90

def initClock(self) -> None:

91

"""

92

Initialize the runtime clock.

93

94

Start timing for performance measurement.

95

"""

96

97

def resetClock(self) -> None:

98

"""

99

Reset the runtime clock.

100

101

Reset timing measurements to zero.

102

"""

103

104

def getRuntimeInSeconds(self) -> float:

105

"""

106

Get the elapsed runtime in seconds.

107

108

Returns:

109

Runtime in seconds as float

110

"""

111

112

def logRuntime(self) -> None:

113

"""

114

Log runtime information.

115

116

Write runtime information to the log.

117

"""

118

```

119

120

## Usage Examples

121

122

### Performance Measurement

123

124

```python

125

import verovio

126

127

tk = verovio.toolkit()

128

129

# Initialize timing

130

tk.initClock()

131

132

# Load and render

133

tk.loadFile("large_score.mei")

134

page_count = tk.getPageCount()

135

136

for page in range(1, page_count + 1):

137

svg = tk.renderToSVG(pageNo=page)

138

139

# Get elapsed time

140

elapsed = tk.getRuntimeInSeconds()

141

print(f"Rendered {page_count} pages in {elapsed:.2f} seconds")

142

print(f"Average: {elapsed/page_count:.3f} seconds per page")

143

144

# Log to Verovio's internal log

145

tk.logRuntime()

146

```

147

148

### Benchmarking Different Options

149

150

```python

151

import verovio

152

153

def benchmark_rendering(filename, options_list):

154

"""Benchmark rendering with different option sets."""

155

tk = verovio.toolkit()

156

tk.loadFile(filename)

157

158

results = []

159

160

for idx, options in enumerate(options_list):

161

# Reset and start timing

162

tk.resetClock()

163

tk.initClock()

164

165

# Apply options and redo layout

166

tk.setOptions(options)

167

tk.redoLayout()

168

169

# Render all pages

170

page_count = tk.getPageCount()

171

for page in range(1, page_count + 1):

172

svg = tk.renderToSVG(pageNo=page)

173

174

# Record time

175

elapsed = tk.getRuntimeInSeconds()

176

results.append({

177

'options': options,

178

'time': elapsed,

179

'pages': page_count

180

})

181

182

print(f"Config {idx+1}: {elapsed:.2f}s for {page_count} pages")

183

184

return results

185

186

# Test different scales

187

options_to_test = [

188

{'scale': 40},

189

{'scale': 60},

190

{'scale': 80},

191

{'scale': 100}

192

]

193

194

results = benchmark_rendering("score.mei", options_to_test)

195

```

196

197

### Dynamic Layout Adjustments

198

199

```python

200

import verovio

201

202

tk = verovio.toolkit()

203

tk.loadFile("score.mei")

204

205

# Initial render

206

initial_options = {

207

'pageHeight': 2970,

208

'pageWidth': 2100,

209

'scale': 40

210

}

211

tk.setOptions(initial_options)

212

svg1 = tk.renderToSVG()

213

214

# Change options and redo layout

215

new_options = {

216

'pageHeight': 3960,

217

'pageWidth': 2800,

218

'scale': 60

219

}

220

tk.setOptions(new_options)

221

tk.redoLayout()

222

223

# Render with new layout

224

svg2 = tk.renderToSVG()

225

print(f"Pages after resize: {tk.getPageCount()}")

226

```

227

228

### Incremental Layout Updates

229

230

```python

231

import verovio

232

233

tk = verovio.toolkit()

234

tk.loadFile("score.mei")

235

236

# Full layout

237

tk.redoLayout()

238

svg = tk.renderToSVG(pageNo=1)

239

240

# Make a small pitch adjustment (if needed)

241

# Then do quick pitch position recalculation

242

tk.redoPagePitchPosLayout()

243

244

# Render updated page

245

svg_updated = tk.renderToSVG(pageNo=1)

246

```

247

248

### Responsive Score Viewer

249

250

```python

251

import verovio

252

253

class ResponsiveScoreViewer:

254

def __init__(self, filename):

255

self.tk = verovio.toolkit()

256

self.tk.loadFile(filename)

257

self.current_page = 1

258

259

def resize_viewport(self, width, height):

260

"""Adjust score layout for new viewport size."""

261

self.tk.resetClock()

262

self.tk.initClock()

263

264

# Update page dimensions

265

options = {

266

'pageWidth': width,

267

'pageHeight': height,

268

'adjustPageHeight': True

269

}

270

self.tk.setOptions(options)

271

272

# Redo layout

273

self.tk.redoLayout()

274

275

elapsed = self.tk.getRuntimeInSeconds()

276

print(f"Layout recalculated in {elapsed:.3f}s")

277

278

return self.tk.getPageCount()

279

280

def set_zoom(self, scale):

281

"""Change zoom level."""

282

self.tk.setScale(scale)

283

self.tk.redoLayout()

284

285

def render_current_page(self):

286

"""Render the current page."""

287

return self.tk.renderToSVG(pageNo=self.current_page)

288

289

# Usage

290

viewer = ResponsiveScoreViewer("score.mei")

291

292

# Simulate window resize

293

new_page_count = viewer.resize_viewport(2400, 3200)

294

print(f"Document now has {new_page_count} pages")

295

296

# Change zoom

297

viewer.set_zoom(60)

298

299

# Render

300

svg = viewer.render_current_page()

301

```

302

303

### Layout Optimization

304

305

```python

306

import verovio

307

308

def find_optimal_scale(filename, target_pages):

309

"""Find scale that produces target number of pages."""

310

tk = verovio.toolkit()

311

tk.loadFile(filename)

312

313

# Binary search for optimal scale

314

min_scale = 10

315

max_scale = 150

316

tolerance = 2 # pages

317

318

while max_scale - min_scale > 5:

319

test_scale = (min_scale + max_scale) // 2

320

321

tk.setScale(test_scale)

322

tk.redoLayout()

323

pages = tk.getPageCount()

324

325

print(f"Scale {test_scale}: {pages} pages")

326

327

if abs(pages - target_pages) <= tolerance:

328

print(f"Found optimal scale: {test_scale} ({pages} pages)")

329

return test_scale

330

331

if pages > target_pages:

332

# Need larger scale to fit more on each page

333

min_scale = test_scale

334

else:

335

# Need smaller scale

336

max_scale = test_scale

337

338

final_scale = (min_scale + max_scale) // 2

339

tk.setScale(final_scale)

340

tk.redoLayout()

341

print(f"Best scale: {final_scale} ({tk.getPageCount()} pages)")

342

return final_scale

343

344

# Find scale for ~10 pages

345

optimal = find_optimal_scale("score.mei", target_pages=10)

346

```

347

348

### Locale-Aware Processing

349

350

```python

351

import verovio

352

353

tk = verovio.toolkit()

354

355

# Set locale for proper text rendering

356

tk.setLocale()

357

358

# Load and process

359

tk.loadFile("score_with_text.mei")

360

svg = tk.renderToSVG()

361

362

# Reset locale when done

363

tk.resetLocale()

364

```

365

366

### Performance Profiling Suite

367

368

```python

369

import verovio

370

import statistics

371

372

class PerformanceProfiler:

373

def __init__(self):

374

self.tk = verovio.toolkit()

375

self.measurements = []

376

377

def profile_operation(self, operation_name, operation_func):

378

"""Profile a single operation."""

379

self.tk.resetClock()

380

self.tk.initClock()

381

382

result = operation_func()

383

384

elapsed = self.tk.getRuntimeInSeconds()

385

self.measurements.append({

386

'operation': operation_name,

387

'time': elapsed

388

})

389

390

print(f"{operation_name}: {elapsed:.4f}s")

391

return result

392

393

def profile_file(self, filename):

394

"""Profile all major operations on a file."""

395

print(f"\nProfiling: {filename}")

396

397

# Load

398

self.profile_operation(

399

"Load",

400

lambda: self.tk.loadFile(filename)

401

)

402

403

# Get page count

404

page_count = self.profile_operation(

405

"Get page count",

406

lambda: self.tk.getPageCount()

407

)

408

409

# Render SVG

410

self.profile_operation(

411

"Render to SVG",

412

lambda: self.tk.renderToSVG()

413

)

414

415

# Render MIDI

416

self.profile_operation(

417

"Render to MIDI",

418

lambda: self.tk.renderToMIDI()

419

)

420

421

# Get MEI

422

self.profile_operation(

423

"Export MEI",

424

lambda: self.tk.getMEI()

425

)

426

427

# Generate timemap

428

self.profile_operation(

429

"Generate timemap",

430

lambda: self.tk.renderToTimemap()

431

)

432

433

def print_summary(self):

434

"""Print performance summary."""

435

print("\n=== Performance Summary ===")

436

total_time = sum(m['time'] for m in self.measurements)

437

print(f"Total time: {total_time:.4f}s")

438

439

times = [m['time'] for m in self.measurements]

440

print(f"Mean operation time: {statistics.mean(times):.4f}s")

441

print(f"Median operation time: {statistics.median(times):.4f}s")

442

443

print("\nSlowest operations:")

444

sorted_ops = sorted(self.measurements, key=lambda x: x['time'], reverse=True)

445

for op in sorted_ops[:3]:

446

print(f" {op['operation']}: {op['time']:.4f}s")

447

448

# Usage

449

profiler = PerformanceProfiler()

450

profiler.profile_file("score.mei")

451

profiler.print_summary()

452

```

453

454

### Cache Management

455

456

```python

457

import verovio

458

459

tk = verovio.toolkit()

460

tk.loadFile("score.mei")

461

462

# Initial layout with cache

463

tk.redoLayout()

464

465

# Change options

466

tk.setScale(60)

467

468

# Redo with cache reset (full recalculation)

469

tk.redoLayout(options={'resetCache': True})

470

471

# Redo without cache reset (may use cached data)

472

tk.setScale(80)

473

tk.redoLayout(options={'resetCache': False})

474

```

475

476

### Debug Timing for Operations

477

478

```python

479

import verovio

480

481

def timed_render_pipeline(filename):

482

"""Time each step of the rendering pipeline."""

483

tk = verovio.toolkit()

484

485

# Time loading

486

tk.initClock()

487

tk.loadFile(filename)

488

load_time = tk.getRuntimeInSeconds()

489

print(f"Load time: {load_time:.4f}s")

490

491

# Time layout

492

tk.resetClock()

493

tk.initClock()

494

tk.redoLayout()

495

layout_time = tk.getRuntimeInSeconds()

496

print(f"Layout time: {layout_time:.4f}s")

497

498

# Time first page render

499

tk.resetClock()

500

tk.initClock()

501

svg = tk.renderToSVG(pageNo=1)

502

render_time = tk.getRuntimeInSeconds()

503

print(f"First page render: {render_time:.4f}s")

504

505

# Time MIDI generation

506

tk.resetClock()

507

tk.initClock()

508

midi = tk.renderToMIDI()

509

midi_time = tk.getRuntimeInSeconds()

510

print(f"MIDI generation: {midi_time:.4f}s")

511

512

total = load_time + layout_time + render_time + midi_time

513

print(f"\nTotal pipeline time: {total:.4f}s")

514

515

return {

516

'load': load_time,

517

'layout': layout_time,

518

'render': render_time,

519

'midi': midi_time,

520

'total': total

521

}

522

523

# Profile a file

524

timings = timed_render_pipeline("score.mei")

525

```

526