NAME
Music::NWC2MusicXML::Parser - NWCTXT text parser producing an internal score representation.
VERSION
0.001.1
SYNOPSIS
use Music::NWC2MusicXML::Parser;
my $parser = Music::NWC2MusicXML::Parser->new;
my $score = $parser->parse($nwctxt);
DESCRIPTION
Music::NWC2MusicXML::Parser accepts the NWCTXT string produced by Music::NWC2MusicXML::NWC and returns a Music::NWC2MusicXML::Score object.
The internal representation is completely independent of MusicXML so that parsing and MusicXML generation can be tested separately.
NWCTXT record structure
Each record occupies one line and begins with |:
|RecordType|Field1:Value1|Field2:Value2|...
Fields are pipe-delimited. Values may be:
unquoted single tokens
double-quoted strings (which may contain
|and:)comma-separated lists
The parser does not use split(/[|]/) because quoted values and escape sequences require a proper tokeniser.
new
Construct a parser.
Arguments
Named parameters:
Returns
Blessed Music::NWC2MusicXML::Parser object.
API SPECIFICATION
Input
diagnostics : Music::NWC2MusicXML::Diagnostics (optional)
Output
Music::NWC2MusicXML::Parser object
FORMAL SPECIFICATION
[ParserInit]
diagnostics : Diagnostics
(placeholder -- populate with Z calculus as implementation matures)
parse
Parse a complete NWCTXT string and return the corresponding Music::NWC2MusicXML::Score.
Purpose
This is the primary entry point. It iterates over each line of the NWCTXT, dispatches to a type-specific handler, and accumulates the results into a Score object.
Arguments
Returns
A Music::NWC2MusicXML::Score object.
Side Effects
Croaks on fatal structural errors (e.g. missing header). Issues warnings via diagnostics for non-fatal issues (e.g. unknown records).
Usage Example
my $score = Music::NWC2MusicXML::Parser->new->parse($nwctxt);
API SPECIFICATION
Input
$nwctxt : SCALAR (UTF-8, required)
-- Valid domain: non-empty string beginning with the line
-- '!NoteWorthyComposer(<version>)' followed by pipe-delimited records
-- Invalid partitions:
-- undef or '' -> croaks error_empty_input
-- non-empty but missing header -> croaks error_no_header
-- Boundary: MAX_RECORDS = 1,000,000 pipe-delimited records
-- At exactly 1,000,000 records: accepted
-- At 1,000,001+ records: croaks error_too_many_records
Output
Music::NWC2MusicXML::Score
MESSAGES
| Code | Meaning | Resolution | |-----------------------|------------------------------------------|-------------------------------| | error_empty_input | Input is undef or zero-length | Check NWC decoder output | | error_no_header | Header line not found | Verify NWC binary decoder | | error_too_many_records| Record count exceeds MAX_RECORDS | Input may be malicious/corrupt| | error_bad_record | Record cannot be tokenised | File may be corrupt | | error_no_staff | Event seen before first AddStaff | NWCTXT may be truncated | | warn_unknown_record | Unknown record type stored as Unsupported| New NWC version may add types |
FORMAL SPECIFICATION
[Parse]
nwctxt? : NWCTXT
----------
score! : Score
(placeholder)
DIAGNOSTICS
MESSAGES
| Code | Meaning | Resolution | |------------------------|------------------------------------------|-----------------------------------| | error_empty_input | NWCTXT string is empty or undef | Check NWC decoder | | error_no_header | Header line absent | Verify NWCTXT output from decoder | | error_too_many_records | Record count exceeds MAX_RECORDS (1M) | Probable corrupt input | | error_bad_record | Record fails tokenisation | File may be corrupt | | error_no_staff | Musical event before any AddStaff | NWCTXT may be truncated | | warn_unknown_record | Unknown record type | New NWC version; file as UnsupportedEvent | | warn_bad_value | Field value not in recognised set | NWC file may use newer syntax |
LIMITATIONS
Note and Rest pitch/duration sub-field parsing is stubbed (Phase 2).
Tuplet time-modification is not yet applied to affected events (Phase 4).
The parser does not yet validate measure duration totals (Phase 3 / --validate).
Multi-voice detection within a single staff is deferred to the MusicXML generator.
AUTHOR
Nigel Horne <njh@nigelhorne.com>
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.