Files
oldboy/scripts/csound-parser/README.md
2025-10-15 15:05:23 +02:00

278 lines
6.7 KiB
Markdown

# Csound Manual Parser
A robust parser that converts the Csound reference manual into TypeScript reference files for use in code editors with hover tooltips and searchable documentation.
## Features
- Downloads markdown files directly from GitHub
- Parses 1000+ Csound opcodes
- Extracts structured data (syntax, parameters, examples)
- Generates organized TypeScript files by category
- Creates a main aggregator file with lookup functions
- Handles edge cases and provides detailed error reporting
## Installation
```bash
cd scripts/csound-parser
pnpm install
```
## Usage
### Option 1: Download and Parse (Recommended)
Download fresh markdown files from GitHub and parse them:
```bash
pnpm run download
```
This will:
1. Download all opcode markdown files from the Csound manual repository
2. Parse them into structured data
3. Generate TypeScript reference files in `src/lib/csound-reference/`
### Option 2: Parse Local Files
If you already have the Csound manual cloned locally:
```bash
pnpm run parse -- --input=/path/to/csound-manual/docs/opcodes
```
### Custom Output Directory
```bash
pnpm run parse -- --output=/custom/output/path
```
## Output Structure
The parser generates:
```
src/lib/csound-reference/
├── types.ts # Type definitions
├── csoundReference.ts # Main aggregator
├── signal-generators-basic-oscillators.ts
├── signal-modifiers-standard-filters.ts
├── mathematical-operations-trigonometric-functions.ts
└── ... (100+ category files)
```
Each category file contains an array of `CsoundReference` objects:
```typescript
export const signalGeneratorsBasicOscillators: CsoundReference[] = [
{
name: 'oscil',
type: 'opcode',
category: 'Signal Generators:Basic Oscillators',
description: 'A simple oscillator without any interpolation.',
syntax: 'ares = oscil(xamp, xcps [, ifn, iphs])\nkres = oscil(kamp, kcps [, ifn, iphs])',
rates: ['a-rate', 'k-rate', 'i-rate'],
parameters: [
{
name: 'ifn',
description: 'function table number. Requires a wrap-around guard point.',
type: 'initialization'
},
// ...
],
seeAlso: ['oscili', 'poscil']
},
// ...
]
```
## Integration
Import in your application:
```typescript
import {
allCsoundReferences,
getCsoundReference,
getCsoundReferencesByCategory
} from './lib/csound-reference/csoundReference'
// Get a specific opcode
const oscil = getCsoundReference('oscil')
// Get all oscillators
const oscillators = getCsoundReferencesByCategory('Signal Generators:Basic Oscillators')
// Search all references
const filtered = allCsoundReferences.filter(ref =>
ref.description.includes('filter')
)
```
## Use Cases
### 1. Hover Tooltips in CodeMirror
Create a tooltip extension similar to the GLSL tooltips:
```typescript
import { hoverTooltip } from '@codemirror/view'
import { getCsoundReference } from './lib/csound-reference/csoundReference'
export const csoundTooltip = hoverTooltip((view, pos) => {
const word = getWordAt(view, pos)
if (!word) return null
const reference = getCsoundReference(word.text)
if (!reference) return null
return {
pos: word.from,
end: word.to,
above: true,
create() {
const dom = document.createElement('div')
dom.innerHTML = `
<div class="tooltip-header">
<strong>${reference.name}</strong>
<span>${reference.type}</span>
</div>
<div class="tooltip-description">${reference.description}</div>
${reference.syntax ? `<pre>${reference.syntax}</pre>` : ''}
`
return { dom }
}
}
})
```
### 2. Searchable Help Panel
Create a reference panel with fuzzy search:
```typescript
import { allCsoundReferences } from './lib/csound-reference/csoundReference'
import Fuse from 'fuse.js'
const fuse = new Fuse(allCsoundReferences, {
keys: ['name', 'description', 'category'],
threshold: 0.4
})
const results = fuse.search('oscillator')
```
### 3. Autocomplete
Use the reference data for intelligent autocomplete:
```typescript
import { allCsoundReferences } from './lib/csound-reference/csoundReference'
const completions = allCsoundReferences.map(ref => ({
label: ref.name,
type: ref.type,
info: ref.description,
detail: ref.syntax
}))
```
## Data Structure
### CsoundReference Interface
```typescript
interface CsoundReference {
name: string // Opcode name (e.g., "oscil")
type: 'opcode' | 'keyword' | 'header' | 'constant'
category: string // Full category path
description: string // Brief description
syntax?: string // Syntax examples
example?: string // Code example
rates?: string[] // ['a-rate', 'k-rate', 'i-rate']
parameters?: {
name: string
description: string
type: 'initialization' | 'performance'
}[]
seeAlso?: string[] // Related opcodes
}
```
## Parser Architecture
### 1. Downloader (`downloader.ts`)
- Fetches markdown files from GitHub API
- Handles rate limiting and retries
- Downloads to `downloaded-opcodes/` directory
### 2. Parser (`parser.ts`)
- Parses markdown frontmatter (id, category)
- Extracts sections using regex
- Extracts parameters from initialization/performance sections
- Handles modern and classic syntax variants
- Detects rate types (a-rate, k-rate, i-rate)
### 3. Generator (`generator.ts`)
- Groups opcodes by category
- Sanitizes category names for file names
- Generates TypeScript files with proper escaping
- Creates main aggregator with imports
- Provides lookup functions
## Troubleshooting
### Download Fails
If the GitHub download fails, manually clone the repository:
```bash
git clone https://github.com/csound/manual.git
cd manual
git checkout develop
```
Then run the parser with the local path:
```bash
pnpm run parse -- --input=../manual/docs/opcodes
```
### Missing Categories
Some opcodes may not have categories defined. The parser will skip these and log warnings.
### Parse Errors
The parser is robust and will continue parsing even if individual files fail. Check the console output for warnings about skipped files.
## Extending the Parser
### Adding New Extraction
To extract additional information from the markdown files, modify `parser.ts`:
```typescript
extractNewField(content: string): string {
const section = this.extractSection(content, 'NewSection')
// Parse the section content
return parsed
}
```
Then add the field to the `CsoundReference` interface in `types.ts`.
### Custom Categories
To reorganize categories, modify the `category` field in the parser or create a mapping function in the generator.
## Performance
- Parsing 1000+ opcodes: ~2-5 seconds
- Generating TypeScript files: ~1-2 seconds
- Download from GitHub: ~30-60 seconds (network dependent)
## License
MIT