% Akkorde können auch geklammert sein
#(define (parenthesis-ignatzek-chord-names in-pitches bass inversion context)
(markup #:line ( "(" (ignatzek-chord-names in-pitches bass inversion context) ")" )))
klamm = #(define-music-function (parser location chords) (ly:music?)
#{
	\set chordNameFunction = #parenthesis-ignatzek-chord-names
	$chords
	\set chordNameFunction = #ignatzek-chord-names
#})

repeats-around-chords =
#(define-music-function (parser location chords) (ly:music?)
#{
  \once \set noChordSymbol = \markup { \normal-text \repStart }
  r4
	$chords
  \once \set noChordSymbol = \markup { \normal-text \repStop }
  r4
#})

bchord =
#(define-music-function (parser location chords) (ly:music?)
#{
	\override ChordName.font-series = #'bold
	$chords
	\revert ChordName.font-series
#})

shiftChord = #(define-music-function (parser location xshift chord) (number? ly:music?)
#{
	\once \override ChordName.extra-offset = #`(,xshift . 0)
	$chord
#})

shiftChords = #(define-music-function (parser location xshift chords) (number? ly:music?)
#{
	\override ChordName.extra-offset = #`(,xshift . 0)
	$chords
#})

altChord =
#(define-music-function (parser location mainchord altchord) (ly:music? ly:music?)
  (let* ((remove-point-and-click
           (lambda (grob)
             (ly:grob-set-property! grob 'cause #f)
             (ly:text-interface::print grob)))
         (chord-name (lambda (in-pitches bass inversion context) #{
           \markup {
             \translate #'(-0.5 . 0)
             \score {
               \chords { \transposable #TRANSPOSITION { #(music-clone mainchord) \klamm #(music-clone altchord) } }
               \layout {
                 \LAYOUT
                 \context {
                   \ChordNames
                   \override ChordName.extra-spacing-width = #'(0 . 0.3)
                   \override ChordName.stencil = #remove-point-and-click
                 }
                 \context {
                   \Score
                   \override SpacingSpanner.spacing-increment = 0
                 }
               }
             }
           }#})))
    #{
      \once \set chordNameFunction = #chord-name
      #mainchord
    #}))

% kleine Mollakkorde und Alteration ausgeschrieben
#(define (note-name->german-markup-nosym pitch lowercase?)
   (define (pitch-alteration-semitones pitch) (inexact->exact (round (* (ly:pitch-alteration pitch) 2))))
   (define (accidental->markup alteration name)
     (if (= alteration 0)
         (make-line-markup (list empty-markup))
          (if (= alteration FLAT)
              (if (equal? name "B")
                  ""
              ;   (make-line-markup (list (make-hspace-markup 0.2)
              ;     (make-tiny-markup (make-raise-markup 1.2
              ;     (make-musicglyph-markup (assoc-get alteration standard-alteration-glyph-name-alist ""))))
              ;   ))
              (if (or (equal? name "E") (equal? name "A")) "s" "es"))
              "is")
         ))
   (define (conditional-string-downcase str condition)
     (if condition (string-downcase str) str))

   (let* ((name (ly:pitch-notename pitch))
         (alt-semitones  (pitch-alteration-semitones pitch))
	 (n-a (if (member (cons name alt-semitones) `((6 . -1) (6 . -2)))
		  (cons 7 (+ 0 alt-semitones))
		  (cons name alt-semitones))))
    (make-line-markup
     (list
      (make-simple-markup
       (conditional-string-downcase
		(vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
		lowercase?))
       (accidental->markup (/ (cdr n-a) 2) (vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a)) ))))
)

% additional bass notes should get uppercased
#(define (bassnote-name->german-markup-nosym pitch lowercase?)(note-name->german-markup-nosym pitch #f))


#(define chordNameExceptions
  (if (defined? 'customChordPrintings)
  (sequential-music-to-chord-exceptions customChordPrintings #t)
  '()))

generalLayout = \layout {
  \generalLayout
  \context {
    \ChordNames
    \semiGermanChords
    \override ChordName.font-size = \songScoreChordFontSize
    \override ChordName.font-series = \songChordFontSeries
    \override ChordName.font-family = #'serif
    chordNameLowercaseMinor = ##t
    chordChanges = ##t
    % eigenen chordRootNamer damit F# = Fis und Gb = Ges (also alteration ausgeschrieben)
    chordRootNamer = #note-name->german-markup-nosym
    chordNoteNamer = #bassnote-name->german-markup-nosym
    majorSevenSymbol = "maj7"
    chordNameExceptions = \chordNameExceptions
  }
}

% Akkord mit Bunddiagramm anzeigen
#(define-markup-command (fret-chord layout props fret chord) (string? string?)
   (interpret-markup layout props
     #{ \markup { \override #'(baseline-skip . 2)
          \center-column {
            \score { \new ChordNames {
              #(ly:parser-include-string (string-append "\\chordmode { s4 " chord " }"))
            } \layout { \generalLayout } }
            \override #'(fret-diagram-details . ((barre-type . straight))) {
              \fret-diagram-terse #fret
            }
          }
        }
     #}))

% If you add this engraver to ChordNames Context chords get only printed on chordchanges and if its the first chord after line break.
Ensure_first_chord_after_line_break_printed_engraver =
  #(lambda (ctx)
     (define last-system-column-rank 0)
     (make-engraver
      (acknowledgers
       ((chord-name-interface this-engraver grob source-engraver)
          (ly:grob-set-property! grob 'after-line-breaking
            (lambda (grob)
              (let ((current-system-column-rank (car (ly:grob-spanned-column-rank-interval (ly:grob-system grob)))))
                (if (and
                       (ly:context-property ctx 'chordChanges #f)
                       (ly:grob-property grob 'begin-of-line-visible #f)
                       (not (= last-system-column-rank current-system-column-rank)))
                  ; the current chord handling implementation in lilypond uses 'begin-of-line-visible to mark repeated chords
                  (ly:grob-set-property! grob 'begin-of-line-visible #f))
                (set! last-system-column-rank current-system-column-rank)
                (ly:chord-name::after-line-breaking grob)
                )))))))

% If you add this engraver to ChordNames Context chords get only printed on chordchanges and not at newline.
Ignoring_newline_chord_changes_engraver =
  #(lambda (ctx)
     (make-engraver
      (acknowledgers
       ((chord-name-interface this-engraver grob source-engraver)
         (when (and (ly:context-property ctx 'chordChanges #f) (ly:grob-property grob 'begin-of-line-visible #f))
                  (ly:grob-suicide! grob)
                )))))