ChordNames in a ChordMarkup-context
Appearance
Sometimes the possibility to enter chords not using the default ChordNames-context, but as text only is requested.
This snippets provides some code to do so.
Obvious disadvantages are missing midi and it's not transposable.
\version "2.24.0"
#(define (markup-concat-join markups sep)
"Return concat-markup of @var{markups}, joining them with markup @var{sep}"
(if (pair? markups)
(make-concat-markup (list-insert-separator markups sep))
empty-markup))
#(define (pitch-accidental-markuplist pitch-strg context)
(let* ((minor-chord-modifier
(ly:context-property context 'minorChordModifier))
(minor?
(and (not (string-null? pitch-strg))
(string=? "m" (string-take-right pitch-strg 1))))
(pitch-markup
(lambda (strg)
(if minor?
(make-concat-markup
(list (string-drop-right strg 1) minor-chord-modifier))
strg))))
(cond
((string-null? pitch-strg) '())
((string-contains pitch-strg "is")
(list (string-take pitch-strg 1)
(make-smaller-markup
(make-raise-markup 0.6
(make-musicglyph-markup "accidentals.sharp")))
(if minor? minor-chord-modifier "")))
((or (string-contains pitch-strg "s")
(string-ci=? (string-take pitch-strg 1) "B"))
(list (string-take pitch-strg 1)
(make-smaller-markup
(make-raise-markup 0.3
(make-musicglyph-markup "accidentals.flat")))
(if minor? minor-chord-modifier "")))
(else (list (pitch-markup pitch-strg))))))
#(define chords->lyrics
(lambda (text context)
(if (not (string? text))
text
(let* ((slash-chord-separator
(ly:context-property context 'slashChordSeparator "/"))
(chord-name-separator
(ly:context-property context 'chordNameSeparator ""))
(major-seven-symbol
(ly:context-property context 'majorSevenSymbol #f))
(chord-root-namer
(ly:context-property context 'chordRootNamer))
(chord-note-namer
(ly:context-property context 'chordNoteNamer))
(chrd&bass (string-split text #\/))
(chrd (car chrd&bass))
(root&adds (string-split chrd #\:))
(bass
(if (pair? (cdr chrd&bass))
(cadr chrd&bass)
""))
(slash-bass
(if (string-null? bass)
""
(make-concat-markup
(cons
slash-chord-separator
(if (and (procedure? chord-note-namer)
(eq? (procedure-name chord-note-namer)
'identity))
(list bass)
(pitch-accidental-markuplist bass context))))))
(root (car root&adds))
(root
(make-concat-markup
(if (eq? (procedure-name chord-root-namer) 'identity)
(list root)
(pitch-accidental-markuplist root context))))
(adds
(if (null? (cdr root&adds))
""
(cadr root&adds)))
(adds-list
(string-split adds #\.))
(adds&alts
(map
(lambda (add)
(cond
((and (string=? add "7+") major-seven-symbol)
major-seven-symbol)
((string-contains add "+")
(make-concat-markup
(list
(make-raise-markup 0.6
(make-musicglyph-markup "accidentals.sharp"))
(string-delete #\+ add))))
((string-contains add "-")
(make-concat-markup
(list
(make-raise-markup 0.3
(make-musicglyph-markup "accidentals.flat"))
(string-delete #\- add))))
(else add)))
adds-list)))
(make-concat-markup
(list
root
(make-super-markup
(markup-concat-join adds&alts chord-name-separator))
slash-bass))))))
#(define (Chords_lyrics_engraver context)
(make-engraver
(acknowledgers
((lyric-syllable-interface engraver grob source-engraver)
(ly:grob-set-property! grob 'text
(chords->lyrics (ly:grob-property grob 'text) context))))))
\layout {
\context {
\Lyrics
\name "ChordMarkup"
\consists \Chords_lyrics_engraver
\override LyricText.font-family = #'sans
\override LyricText.self-alignment-X = #LEFT
%% some defaults:
%slashChordSeparator = #"/"
%majorSevenSymbol = #whiteTriangleMarkup
%chordNameSeparator = #(make-hspace-markup 0.5)
%minorChordModifier = #"m"
}
\context {
\Score
\accepts "ChordMarkup"
}
\context {
\StaffGroup
\accepts "ChordMarkup"
}
\context {
\ChoirStaff
\accepts "ChordMarkup"
}
%% others?
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markup \bold \rounded-box \rounded-box \fill-line {
\column {
"Generals for entering ChordNames in ChordMarkup-context:"
"- Root is not capitalized, it's taken as entered!"
"- Double-alteration (ases etc) as root is not supported"
"- Input should be entered as string, otherwise numbers are taken as
duration"
\line {
"- Durations are entered as usual for LyricText, i.e"
\typewriter "\lyricmode { \"c:sus4\"2 }"
"is of duration 2"
}
}
\null
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% CHORD-EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\header { tagline = ##f }
%% 1
simple-chrds =
<<
\new ChordMarkup
\lyricmode {
C Cis D Dis E Eis F Fis G Gis A Ais B H h b
cism cesm hm "B:sus4"
}
\new ChordNames
\chordmode {
c cis d dis e eis f fis g gis a ais bes b b bes
cis:m ces:m b:m bes:sus4
}
\new Staff
\chordmode {
c cis d dis e eis f fis g gis a ais bes b b bes
cis:m ces:m b:m bes:sus4
}
>>
\score {
\simple-chrds
\header {
piece = \markup \rounded-box \fill-line {
\column {
"In ChordMarkup minor-chords have to be entered like: cism"
"Note the absence of \":\" here."
}
\null
}
}
\layout { indent = 0 }
}
%% 2
keep-entered-root-chrds =
<<
\new ChordMarkup
\lyricmode {
\set chordRootNamer = #identity
C Cis cism "Cis:7.5-" "Cis:5-.7" "Es:7+.(13)/fis"
\set chordNoteNamer = #identity
"Es:7+.add13/Fis"
G /e /es /d /F /E /Es /D
}
\new ChordNames
\chordmode {
c cis cis:m cis:7.5- cis:5-.7 ees:7+.13/fis
ees:7+.13/fis g \repeat unfold 7 q
}
\new Staff
\chordmode {
c cis cis:m cis:7.5- cis:5-.7 ees:7+.13/fis
ees:7+.13/fis g \repeat unfold 7 q
}
>>
\score {
\keep-entered-root-chrds
\header {
piece = \markup \rounded-box \fill-line {
\column {
"To insist on the root as entered, set 'chordRootNamer' to 'identity'"
"Rootless basses are possible"
"To insist on the bass as entered, set 'chordNoteNamer' to 'identity'"
}
\null
}
}
\layout { indent = 0 }
}
%% 3
change-defaults-chrds =
<<
\new ChordMarkup
\lyricmode {
"C/E" \once \set slashChordSeparator = " with bass:" "C/E"
"C:7+" \once \set majorSevenSymbol = "7<" "C:7+"
"C:7.13" \once \set chordNameSeparator = "," "C:7.13"
"cm:7.alt"
\once \set minorChordModifier =
#(markup #:fontsize -4 #:smallCaps "minor")
"cm:7.alt"
}
\new ChordNames
\chordmode {
c:7+ c:7+
}
\new Staff
\chordmode {
c/+e c/+e c:7+ c:7+ c:7.13 c:7.13 c:m7 c:m7
}
>>
\score {
\change-defaults-chrds
\header {
piece = \markup \rounded-box \fill-line {
\column {
"It's possible to change"
"- slashChordSeparator"
"- majorSevenSymbol"
"- chordNameSeparator"
"- minorChordModifier"
}
\null
}
}
\layout { indent = 0 }
}
%% 4
other-example-chrds =
\new ChordMarkup
\lyricmode {
"C:13" C:alt "C:7.alt" "Gm:7.(b5)/F"
}
\score {
\other-example-chrds
\header { piece = \markup \rounded-box \fill-line { "Other examples" \null } }
\layout { indent = 0 }
}