On Sun, 18 Jan 2009, Tim Woodall wrote:
Surely the octaves can change? (I'm a very new lilypond user but a fairly confident sed user so I might be completely misunderstanding something)
Well it was an interesting exercise. I believe that the following bash script does what is required. It works correctly on the following input: staff \relative c { <ces ces' ces'>4 <ces ces' ces'>4 <ces ces' ces'>4 <fis fis' fis'>8 <c' c' c'>8~ <c c'~ c'>4 <d c' d'> \times 2/3 { <c c' c'>8 <c c' c'><c c' c'>} <ces ces' ces'>4 <fis fis' fis'>8 <c' c' c'>8~ <c c'~ c'>4 <d c' d'> \times 2/3 { <c c' c'>8 <c c' c'><c c' c'>} } (The script might fail if there are any notes not in chords. I think all that will be required is that the octave might need correcting in one or more parts at the note which will be cloned in all three parts. I'm also not sure what might happen if there are chords missing notes. It might not work at all. The first is hard to fix, the second shouldn't be too difficult.) #!/bin/bash cat test.ly | sed 's/<[^>a-g]*\([a-g][a-g]*[^a-g>]*\)[^>]*>\([^<]*\)/\n<\1>\n\2/g' >part1.ly cat test.ly | sed 's/<[^>a-g]*[a-g][a-g]*[^>a-g]*\([a-g][a-g]*[^a-g>]*\)[^>]*>\([^<]*\)/\n<\1>\n\2/g' >part2.ly cat test.ly | sed 's/<[^>a-g]*[a-g][a-g]*[^>a-g]*[a-g][a-g]*[^>a-g]*\([a-g][a-g]*[^a-g>]*\)[^>]*>\([^<]*\)/\n<\1>\n\2/g' >part3.ly c=0 while read -r line; do line1[$c]="$line" echo "${line1[$c]}" "$line" c=$(($c+1)) done <<EOF $( < part1.ly ) EOF c=0 while read -r line; do line2[$c]="$line" c=$(($c+1)) done <<EOF $( < part2.ly ) EOF c=0 while read -r line; do line3[$c]="$line" c=$(($c+1)) done <<EOF $( < part3.ly ) EOF c=0 note_cannonical() { local note local val=0 local accidental="" local octave=0 note=$( echo $1 | sed "s/[^a-gis',]//g" ) case $note in a*) val=0 ;; b*) val=1 ;; c*) val=2 ;; d*) val=3 ;; e*) val=4 ;; f*) val=5 ;; g*) val=6 ;; *) echo "Error bad note $note"; exit 1 ;; esac note=${note#?} while [[ "$note" != "" ]]; do case $note in es*) accidental="${accidental}es"; note=${note#es} ;; is*) accidental="${accidental}is"; note=${note#is} ;; \'*) octave=$(($octave+1)); note=${note#?} ;; ,*) octave=$(($octave-1)); note=${note#?} ;; *) echo "Error bad adjust $note"; exit 1 ;; esac done echo "$val:$accidental:$octave" } calc_delta() { local p1=${1%%:*} local p2=${2%%:*} local o2=${2##*:} local dn if [[ $p2 -gt $p1 ]]; then if [[ $(($p2-$p1)) -le 3 ]]; then dn=$(($p2-$p1)) else dn=$(($p1-7-$p2)) fi else if [[ $(($p2-$p1)) -ge -3 ]]; then dn=$(($p2-$p1)) else dn=$((7-$p1+$p2)) fi fi dn=$(($o2*7+$dn)) echo $dn } calcoctave() { local off=$(($1+$2)) local n="" while [[ $off -ge 7 ]]; do n="${n}'" off=$(($off-7)) done while [[ $off -lt 0 ]]; do n="${n}," off=$(($off+7)) done echo $n } note() { local p=${1%%:*} local a=${1#*:} local n=("a" "b" "c" "d" "e" "f" "g") echo "${n[$p]}${a%:*}" } replace_note() { local from="$1" local r=$2 local innote=0 local d local ret="" while [[ "$from" != "" ]]; do d=$( echo "$from" | sed "s/\(.\).*/\1/" ) from="${from#?}" case $d in [a-g]) if [[ $innote == 0 ]]; then ret="$ret$r" innote=1 elif [[ $innote != 1 ]]; then ret="$ret$d" fi ;; [is\',]) if [[ $innote != 1 ]]; then ret="$ret$d" fi ;; \ ) ret="$ret$d" ;; *) if [[ $innote == 1 ]]; then innote=2 fi ret="$ret$d" ;; esac done echo $ret } n1="2" n2="2" n3="2" od2=0 od3=0 while [[ $c -lt ${#line1[*]} ]]; do if [[ ! -z "${line1[$c]}" && "${line1[$c]%<*}" = "" ]]; then nc1=$( note_cannonical "${line1[$c]}" ) nc2=$( note_cannonical "${line2[$c]}" ) nc3=$( note_cannonical "${line3[$c]}" ) echo $nc1 $nc2 $nc3 d1=$( calc_delta $n1 $nc1 ) d2=$(($d1 + $( calc_delta $nc1 $nc2 ) )) d3=$(($d2 + $( calc_delta $nc2 $nc3 ) )) echo $d1 $d2 $d3 out1="$(note $nc1)$( calcoctave $n1 $d1 )" out2="$(note $nc2)$( calcoctave $n2 $(($d2-$od2)) )" out3="$(note $nc3)$( calcoctave $n3 $(($d3-$od3)) )" od2=$( calc_delta $nc1 $nc2 ) od3=$(($od2 + $( calc_delta $nc2 $nc3 ) )) echo $od2 $od3 line1[$c]=$( replace_note "${line1[$c]}" $out1 ) line2[$c]=$( replace_note "${line2[$c]}" $out2 ) line3[$c]=$( replace_note "${line3[$c]}" $out3 ) n1=${nc1%%:*} n2=${nc1%%:*} n3=${nc1%%:*} fi c=$(($c+1)) done c=0; while [[ $c -lt ${#line1[*]} ]]; do echo ${line1[$c]}; c=$(($c+1)); done >part1.ly c=0; while [[ $c -lt ${#line2[*]} ]]; do echo ${line2[$c]}; c=$(($c+1)); done >part2.ly c=0; while [[ $c -lt ${#line3[*]} ]]; do echo ${line3[$c]}; c=$(($c+1)); done >part3.ly exit 0 -- God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t," and there was light. http://www.woodall.me.uk/ _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user