lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: notes regex expression


From: Jim Tisdall
Subject: Re: notes regex expression
Date: Tue, 12 Sep 2017 14:05:45 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.3.0

I have been using a perl regular expression to parse lilypond notes for my own 
application,
which handles guitar notes with possible right hand, left hand, plectrum, 
string, glissando markings.
Thus it only includes some of the features of lilypond notes.  It assumes 
english note names
(easily modified).


$noteRE = '
(?<original>
        (
                (
                        (<      # lilypond grouping
(?<pitch>                               # $-{pitch}[0]
                                        (?<name> [a-g](ss*|ff*)?\b)     # 
$-{name}[0]
                                        (?<octave> (,,*|\'\'*)?)        # 
$-{octave}[0]
                                )
                                (?<duration> (\d+\.*)?)                 # 
$-{duration}[0]
                                (
                                        ((\\\(?<string> [1-6]))?)       # 
$-{string}[0]
                                        |
                                        (((-(?<LH> [0-4])) | none )?)           
# $-{LH}[0]
                                        |
                                        (?<plectrum> \\\downbow|\\\upbow)       
# $-{plectrum}[0]
                                        |
                                        (?<PIMA> -?\\\(RH|rightHandFinger)\ 
\#[0-4]\ )  # $-{PIMA}[0]
                                )*
                        >)      # lilypond grouping
                        (

                                ((\\\(?<glissando> glissando))?)        # 
$-{glissando}[0]
                                |
                                (?<duration> (\d+\.*)?)         # 
$-{duration}[1]
                                |
                                (?<other> ([\\^_\-]"\S")?  | \S*) # other 
arbitrary constructs
                        )*
                )
                |
                (
                        (       # without lilypond grouping
(?<pitch>                               # $-{pitch}[1]
                                        (?<name> [a-g](ss*|ff*)?\b)     # 
$-{name}[1]
                                        (?<octave> (,,*|\'\'*)?)        # 
$-{octave}[1]
                                )
                                (?<duration> (\d+\.*)?)                 # 
$-{duration}[2]
                                (
                                        ((\\\(?<string> [1-6]))?)       # 
$-{string}[1]
                                        |
                                        (((-(?<LH> [0-4])) | none )?)           
# $-{LH}[1]
                                        |
                                        (?<plectrum> \\\downbow|\\\upbow)       
# $-{plectrum}[1]
                                        |
                                        (?<PIMA> -?\\\(RH|rightHandFinger)\ 
\#[0-4]\ )  # $-{PIMA}[1]
                                )*
                        )       # without lilypond grouping
                        (
                                (?<duration> (\d+\.*)?)         # 
$-{duration}[3]
                                |
                                ((\\\(?<glissando> glissando))?)        # 
$-{glissando}[1]
                                |
                                (?<other> ([\\^_\-]"\S")?  | \S*) # other 
arbitrary constructs
                        )*
                )
        )
        |
        (
                (?<pitch>                               # $-{pitch}[2]
                        (?<name> [rR])                  # $-{name}[2]
                )
                (?<duration> (\d+\.*)?)                 # $-{duration}[4]
        )
)
';



I use the regular expression $noteRE in the following parse function which 
creates a note object:

sub parsenote {
        my($self, $lilynote) = @_;

        # best used on new note: may reset e.g. duration
        # if called on pitch of existing note

        unless((defined $lilynote) and $lilynote) {
                Error(Trace("Cannot parse note: input lilynote is not 
defined"));
                return 0;
        }

        # simple case of name and octave
        if($lilynote =~ /^([ra-gA-G][sf]*)([,']*)$/) {
                $self->set_type('note');
                $self->set_pitch($lilynote);
                $self->set_name($1);
                $self->set_octave($2);
                return(1);
        }

        $lilynote =~ /$noteRE/x or return 0;

        $self->set_type('note');
        if(defined $-{pitch}[0]) {
                $self->set_pitch($-{pitch}[0]);
        }elsif(defined $-{pitch}[1]) {
                $self->set_pitch($-{pitch}[1]);
        }elsif(defined $-{pitch}[2]) {
                $self->set_pitch($-{pitch}[2]);
        }
        if(defined $-{name}[0]) {
                $self->set_name($-{name}[0]);
        }elsif(defined $-{name}[1]) {
                $self->set_name($-{name}[1]);
        }elsif(defined $-{name}[2]) {
                $self->set_name($-{name}[2]);
        }
        if(defined $-{octave}[0]) {
                $self->set_octave($-{octave}[0]);
        }elsif(defined $-{octave}[1]) {
                $self->set_octave($-{octave}[1]);
        }
        if(defined $-{duration}[0]) {
                $self->set_duration($-{duration}[0]);
        }elsif(defined $-{duration}[1]) {
                $self->set_duration($-{duration}[1]);
        }elsif(defined $-{duration}[2]) {
                $self->set_duration($-{duration}[2]);
        }elsif(defined $-{duration}[3]) {
                $self->set_duration($-{duration}[3]);
        }elsif(defined $-{duration}[4]) {
                $self->set_duration($-{duration}[4]);
        }
        if(defined $-{string}[0]) {
                $self->set_string($-{string}[0]);
        }elsif(defined $-{string}[1]) {
                $self->set_string($-{string}[1]);
        }
        if(defined $-{LH}[0]) {
                $self->set_LH($-{LH}[0]);
        }elsif(defined $-{LH}[1]) {
                $self->set_LH($-{LH}[1]);
        }
        if(defined $-{PIMA}[0]) {
                $self->set_PIMA($-{PIMA}[0]);
        }elsif(defined $-{PIMA}[1]) {
                $self->set_PIMA($-{PIMA}[1]);
        }
        if(defined $-{plectrum}[0]) {
                $self->set_plectrum($-{plectrum}[0]);
        }elsif(defined $-{plectrum}[1]) {
                $self->set_plectrum($-{plectrum}[1]);
        }
        if((defined $-{glissando}[0]) and $-{glissando}[0]) {
                my $j = "\\" . $-{glissando}[0];
                $self->set_glissando( $j );
        }elsif((defined $-{glissando}[1]) and $-{glissando}[1]) {
                my $j = "\\" . $-{glissando}[1];
                $self->set_glissando( $j );
        }

        if($lilynote eq $-{original}[0]) {
                # do not actually reset original, so you can use this parse
                # function to e.g. change the octave, without changing, say, 
gliss
                # $self->set_original($lilynote);
        }else{
                #die "parsenote: input $lilynote output ",$-{original}[0];
                Error(Trace("Cannot parse input $lilynote : only found 
",$-{original}[0]));
                return 0;
        }

        # fret is used in computation but not present in note format
        if( defined $self->get_string and $self->get_string and defined 
$self->get_pitch and $self->get_pitch ) {
                $self->set_fret( 
$stringAndPitch2Fret[$self->get_string]{$self->get_pitch} );
        }

        return 1;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]