#(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 } }