First off, further apologies for accidentally posting a follow-up
via an second email address.
Aaron, thanks for all of this. Helpful to have the demonstration
of column-formatted note names from pitches, along with evidence
of something called "note-name->markup"; maybe that's all I
need if I stick with ordinary letter note names.
And thanks especially for the crucial info that pitch-notename
returns a number, despite its name. Makes sense from a coding
standpoint but the name threw me, what with NoteNames seeming
string-y. (Is there a list of data types for parameters and
returned values for the internal functions?)
Anyway with that in mind and with your helper functions added in, I
have my function working (here, it returns vanilla note name forms
for LilyPond notename numbers, but custom forms are now easy). Next
I'll try adding a loop to process the entire input, discarding
non-pitch, non-chord events and building up a corresponding string
of note names. Sticking with the way this function has been
designed, getting note names for transposed music would require
first transposing the input within the function or via another
helper one, I guess, and then processing the transposed music.
David's displayLilyMusic-based function would make unnecessary any
code to handle transposition, but weeding out all the non-notename
characters from the string it produces would take some work.
#(define (pitch->name pitch)
(vector-ref '#("C" "D" "E" "F" "G" "A" "B")
(ly:pitch-notename pitch)))
#(define (pitch->alteration pitch)
(assoc-get (ly:pitch-alteration pitch)
'((-1/2 . "b") (1/2 . "#") (-1 . "-double-flat") (1 . "-double-sharp")) ""))
notenamer =
#(define-scheme-function (pitchin)
(ly:music?)
(let* (
(note-datum (car (ly:music-property pitchin 'elements)))
(pitch-datum (ly:music-property note-datum 'pitch))
(out-notename (pitch->name pitch-datum))
(out-acc (pitch->alteration pitch-datum)))
#{\markup
\bold
\concat {$out-notename $out-acc }
#}
)
)
\notenamer {ees d b c g}
From: Aaron Hill
Subject: Re: Scheme function to return pitchnames as markup/text
Date: Tue, 19 Nov 2019 09:19:26 -0800
On 2019-11-19 6:05 am, Stephen Cummings wrote:
Am I missing a basic LilyPond command/directive--something built-in
that takes music as input and returns note names as text?
There is the NoteNames context, but its functionality is wrapped up in C++ code and is not easily customizable.
%%%%
\version "2.19.83"
melody = \fixed c' { e8 fis g4 <f bes>2 }
<< \new NoteNames \melody \new Staff \melody >>
%%%%
Next, the logic behind ChordNames has a number of helper functions that are used to compose the final markup for a given chord.
%%%%
\version "2.19.83"
\markup \column \override #'(word-space . 0.1) { #@(map
(lambda (pitch) (note-name->markup pitch #f))
(list #{ d, #} #{ ees #} #{ fisis' #})) }
%%%%
Finally, you can do it manually when you need to fully customize naming:
%%%%
\version "2.19.83"
#(define (pitch->name pitch)
(vector-ref '#("Do" "Re" "Mi" "Fa" "So" "La" "Ti")
(ly:pitch-notename pitch)))
#(define (pitch->alteration pitch)
(assoc-get (ly:pitch-alteration pitch)
'((-1/2 . "-flat") (1 . "-double-sharp")) ""))
\markup \column { #@(map
(lambda (pitch) #{ \markup \concat {
$(object->string pitch) ": "
$(pitch->name pitch) $(pitch->alteration pitch) } #})
(list #{ d, #} #{ ees #} #{ fisis' #})) }
%%%%
What is important to note is that ly:pitch-notename returns a number, not a string. It is up to the caller to map that number into a suitable value within the desired naming system.
-- Aaron Hill