From 3a47c6f31f2b978f5eaa537a062e44f2dda537c3 Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Fri, 16 Jul 2010 17:29:07 +0200
Subject: [PATCH] Handle all clef types

-) For mensural clefs, write out a warning that MusicXML does not support them
-) Move all clef-generation to a dedicated clef (..) function
-) Also implement g-2 clef (tenor clef)
---
 pae2xml.pl             | 58 +++++++++++++++++++++++-------------------
 sample_files/Clefs.pae |  7 +++++
 2 files changed, 39 insertions(+), 26 deletions(-)
 create mode 100644 sample_files/Clefs.pae

diff --git a/pae2xml.pl b/pae2xml.pl
index 67332f0..5ea6a60 100755
--- a/pae2xml.pl
+++ b/pae2xml.pl
@@ -160,20 +160,12 @@ sub parse_pe {
   $pe =~ s/@�/@0�/gs; # make missing time signature explicit
   while ($pe =~ s/([^\-])(\d+)(\'|\,)(A|B|C|D|E|F|G)/$1$3$2$4/gs) {};  # octave first, then duration. Truly global.
 
-  if ($pe =~ /\s*(%([\w\-\d]+))?(@([\d\w\/]+))?\s*&?\s*(\$([^�]+))?�(.*)$/gs) {
+  if ($pe =~ /\s*(%([\w\-\+\d]+))?(@([\d\w\/]+))?\s*&?\s*(\$([^�]+))?�(.*)$/gs) {
     my ($clef, $timesig, $keysig, $rest) = ($2, $4, $6, $7);
 
     print "Writing $filename...\n";
     open(OUT, ">$filename");
 
-    if ($clef =~ /^(\w)\-(\d)$/) {
-      ($clefsign, $clefline) = ($1, $2);
-    } else {
-      ($clefsign, $clefline) = ("G", 2);
-    }
-
-    $timesig = timesignature($timesig);
-
     my %fif=("", 0, "xF", 1, "xFC", 2, "xFCG",3, "xFCGD",4, "xFCGDA",5, "xFCGDAE",6, "xFCGDAEB",7, "bB",-1, "bBE",-2, "bBEA",-3, "bBEAD",-4, "bBEADG",-5, "bBEADGC",-6, "bBEADGCF",-7);
     $keysig =~ s/(\s+)|&//gs;  # it is unclear what the & means, so we'll ignore it for now.
     $keysig =~ s/\[|\]//gs; # IGNORING brackets around a key sig.
@@ -214,12 +206,9 @@ sub parse_pe {
 				<key>
 					<fifths>'.$fifths.'</fifths>
 				</key>
-'.$timesig
-.'				<clef>
-					<sign>'.$clefsign.'</sign>
-					<line>'.$clefline.'</line>
-				</clef>
-			</attributes>
+'.timesignature($timesig)
+.clef ($clef)
+.'			</attributes>
 ';
 
 
@@ -371,17 +360,12 @@ sub parse_notes {
 					<actual-notes>'.$act_notes.'</actual-notes>
 					<normal-notes>1</normal-notes>
 				</time-modification>', $qq);
-    } elsif ($notes =~ /^(%\w-\d)(.*)$/) {  # Clef change
-      ($clef,$notes) = ($1,$2);
-      $clef =~ /^%(\w)\-(\d)$/;
-      ($clefsign, $clefline) = ($1, $2);
-      print OUT '			<attributes>
-				<clef>
-					<sign>'.$clefsign.'</sign>
-					<line>'.$clefline.'</line>
-				</clef>
-			</attributes>
-';
+    } elsif ($notes =~ /^(%(\w(-|\+)\d))(.*)$/) {  # Clef change
+      ($clef,$notes) = ($2,$4);
+      $clef = clef ($clef);
+      print OUT "			<attributes>\n";
+      print OUT $clef;
+      print OUT "			</attributes>\n";
     } elsif ($notes =~ /^@(\d\/\d|c\/?)\s*(.*)$/) {  # time signatue change
       #	print "$notes\n";
       ($timesig,$notes) = ($1,$2);
@@ -618,6 +602,28 @@ sub octave {
   return $old_octave;
 }
 
+sub clef {
+  my ($clef) = @_;
+  my $clefoctave = '';
+  if ($clef =~ /^(\w)(\-|\+)(\d)$/) {
+    ($clefsign, $clefline) = ($1, $3);
+    if ($2 =~ /^\+$/) {
+      print "Warning: Mensural clefs are not supported by MusicXML, using modern clef (input: $clef)\n";
+    }
+    if ($clefsign eq 'g') {
+      $clefsign = "G";
+      $clefoctave = "					<clef-octave-change>-1</clef-octave-change>\n";
+    }
+  } else {
+    ($clefsign, $clefline) = ("G", 2);
+  }
+  return '				<clef>
+					<sign>'.$clefsign.'</sign>
+					<line>'.$clefline.'</line>
+'.$clefoctave.'				</clef>
+';
+}
+
 sub timesignature {
   my ($timesig) = @_;
 
diff --git a/sample_files/Clefs.pae b/sample_files/Clefs.pae
new file mode 100644
index 0000000..daad4a1
--- /dev/null
+++ b/sample_files/Clefs.pae
@@ -0,0 +1,7 @@
+Test Composer
+Test case for clefs
+1.1.1: S Clefs
+plain&easy: %G-2@c$bB� '1C/%G-4 1C/2D%C-1 2E/%F-4 1C/%g-21 C/%C+3 1C/
+
+Test Library
+00000000
\ No newline at end of file
-- 
GitLab