Chordpro export

This commit is contained in:
2026-04-06 13:14:58 +02:00
parent 71c8c0385c
commit 603b25831a
8 changed files with 1101 additions and 26 deletions

2
.gitignore vendored
View File

@@ -1,8 +1,8 @@
# ---> Lilypond # ---> Lilypond
*.pdf *.pdf
*.cho
*.ps *.ps
*.midi *.midi
*.mid *.mid
*.log *.log
*~ *~

View File

@@ -38,6 +38,7 @@
\include "eps_file_from_song_dir.ily" \include "eps_file_from_song_dir.ily"
\include "title_with_category_images.ily" \include "title_with_category_images.ily"
\include "chord_settings.ily" \include "chord_settings.ily"
\include "chordpro.ily"
\include "transposition.ily" \include "transposition.ily"
\include "verses_with_chords.ily" \include "verses_with_chords.ily"
\include "arrows_in_scores.ily" \include "arrows_in_scores.ily"

View File

@@ -158,6 +158,8 @@ override-stanza =
#(define (stanza . stanzanumbers) #(define (stanza . stanzanumbers)
#{ #{
\once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs \once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs
\once \override StanzaNumber.details.custom-stanza-type = #'verse
\once \override StanzaNumber.details.custom-stanza-numbers = #stanzanumbers
\applyContext \applyContext
#(lambda (context) #(lambda (context)
(handle-stanza-numbers context stanzanumbers (handle-stanza-numbers context stanzanumbers
@@ -169,6 +171,8 @@ ref =
#(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?) #(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?)
#{ \lyricmode { #{ \lyricmode {
\once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs \once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs
\once \override StanzaNumber.details.custom-stanza-type = #'ref
\once \override StanzaNumber.details.custom-stanza-numbers = #stanzanumbers
\applyContext \applyContext
#(lambda (context) #(lambda (context)
(handle-stanza-numbers context stanzanumbers (handle-stanza-numbers context stanzanumbers
@@ -186,6 +190,8 @@ bridge =
#(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?) #(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?)
#{ \lyricmode { #{ \lyricmode {
\once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs \once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs
\once \override StanzaNumber.details.custom-stanza-type = #'bridge
\once \override StanzaNumber.details.custom-stanza-numbers = #stanzanumbers
\applyContext \applyContext
#(lambda (context) #(lambda (context)
(handle-stanza-numbers context stanzanumbers (handle-stanza-numbers context stanzanumbers
@@ -201,8 +207,11 @@ bridge =
% prints a repStart Sign as stanza if the tag 'repeats is kept. % prints a repStart Sign as stanza if the tag 'repeats is kept.
% if there was a stanza already set by the stanza function with StanzaNumber.details.custom-realstanza = ##t we set that also as stanza. % if there was a stanza already set by the stanza function with StanzaNumber.details.custom-realstanza = ##t we set that also as stanza.
% Sets custom-inline-text for ChordPro export so it can collect the repeat sign separately
repStartWithTag = \lyricmode { repStartWithTag = \lyricmode {
\tag #'repeats { \tag #'repeats {
\once \override StanzaNumber.details.custom-inline-text = \repStart
\once \override StanzaNumber.details.custom-inline-direction = #LEFT
\applyContext \applyContext
#(lambda (context) #(lambda (context)
(let ((lastStanza (ly:context-property context 'stanza)) (let ((lastStanza (ly:context-property context 'stanza))
@@ -220,6 +229,8 @@ repStartWithTag = \lyricmode {
repStopWithTag = \lyricmode { repStopWithTag = \lyricmode {
\tag #'repeats { \tag #'repeats {
\once \override StanzaNumber.details.custom-inline-text = \repStop
\once \override StanzaNumber.details.custom-inline-direction = #RIGHT
\once \override StanzaNumber.font-series = #'normal \once \override StanzaNumber.font-series = #'normal
\once \override StanzaNumber.direction = 1 \once \override StanzaNumber.direction = 1
\set stanza = \markup { \pad-x-right #1 \repStop } \set stanza = \markup { \pad-x-right #1 \repStop }

View File

@@ -40,34 +40,19 @@ shiftChords = #(define-music-function (parser location xshift chords) (number? l
altChord = altChord =
#(define-music-function (parser location mainchord altchord) (ly:music? ly:music?) #(define-music-function (parser location mainchord altchord) (ly:music? ly:music?)
(let* ((remove-point-and-click (let* ((chord-name (lambda (in-pitches bass inversion context)
(lambda (grob) (make-line-markup (list
(ly:grob-set-property! grob 'cause #f) (ignatzek-chord-names in-pitches bass inversion context)
(ly:text-interface::print grob))) (make-hspace-markup 0.3)
(chord-name (lambda (in-pitches bass inversion context) #{ (parenthesis-ignatzek-chord-names (music-pitches (transposable (cons (car (music-pitches mainchord)) (car in-pitches)) (music-clone altchord))) '() '() context)
\markup { ))
\translate #'(-0.5 . 0) )))
\score {
\chords { \transposable #(cons (car (music-pitches mainchord)) (car in-pitches)) { #(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 \once \set chordNameFunction = #chord-name
#mainchord #mainchord
#})) #}))
% Akkorde werden so transponiert, dass sie passen, wenn man mit Kapo im angegebenen Bund spielt % Akkorde werden so transponiert, dass sie passen, wenn man mit Kapo im angegebenen Bund spielt
capoTranspose = capoTranspose =
#(define-music-function (fret chords) (number? ly:music?) #(define-music-function (fret chords) (number? ly:music?)

File diff suppressed because it is too large Load Diff

View File

@@ -379,6 +379,8 @@ Chord_lyrics_spacing_engraver =
\override SpacingSpanner.spacing-increment = 0 \override SpacingSpanner.spacing-increment = 0
% \override SpacingSpanner.packed-spacing = ##t % \override SpacingSpanner.packed-spacing = ##t
\consists \Chord_lyrics_spacing_engraver \consists \Chord_lyrics_spacing_engraver
% ChordPro engraver in Score context to collect all data
\consists \ChordPro_score_collector
\remove Bar_number_engraver \remove Bar_number_engraver
\remove Mark_engraver \remove Mark_engraver
\remove Jump_engraver \remove Jump_engraver

View File

@@ -39,6 +39,20 @@ TEXT = \markuplist {
TEXT_PAGES TEXT_PAGES
(list TEXT)))) (list TEXT))))
%% Add invisible ChordPro write trigger to last TEXT_PAGES markuplist
#(when (and (defined? 'chordpro-export-enabled) chordpro-export-enabled (pair? TEXT_PAGES))
(let* ((last-index (- (length TEXT_PAGES) 1))
(last-page (list-ref TEXT_PAGES last-index))
(modified-last-page #{
\markuplist {
#last-page
\chordpro-delayed-write
}
#}))
(set! TEXT_PAGES
(append (list-head TEXT_PAGES last-index)
(list modified-last-page)))))
#(define (add-text-pages text-pages) #(define (add-text-pages text-pages)
(if (pair? text-pages) (if (pair? text-pages)
(begin (begin
@@ -55,12 +69,34 @@ TEXT = \markuplist {
(if header (set! $defaultheader header)) (if header (set! $defaultheader header))
(if paper (set! $defaultpaper paper)) (if paper (set! $defaultpaper paper))
) )
;; ChordPro export: Store filename and extract metadata from basicSongInfo FIRST
(when (and (defined? 'chordpro-export-enabled) chordpro-export-enabled)
;; Use ly:parser-output-name which returns the output basename
;; This will write relative to current working directory (same as PDF)
(let ((output-name (ly:parser-output-name)))
(set! chordpro-current-filename output-name))
;; Try to extract metadata from basicSongInfo \header block
(when (defined? 'basicSongInfo)
(let* ((header-alist (ly:module->alist basicSongInfo))
(title (assoc-ref header-alist 'title))
(authors (assoc-ref header-alist 'authors)))
(when title
(set! chordpro-header-title
(if (markup? title)
(markup->string title)
(if (string? title) title "Untitled"))))
(when authors
(set! chordpro-header-authors authors)))))
(add-score #{ (add-score #{
\score { \score {
\MUSIC \MUSIC
\layout { \LAYOUT } \layout { \LAYOUT }
}#}) }#})
(add-text-pages TEXT_PAGES) (add-text-pages TEXT_PAGES)
(add-score #{ (add-score #{
\score { \score {
\unfoldRepeats { \MUSIC \INLINESCOREMUSIC } \unfoldRepeats { \MUSIC \INLINESCOREMUSIC }
@@ -75,4 +111,4 @@ TEXT = \markuplist {
} }
} }
}#}) }#})
)) ))

View File

@@ -4,4 +4,4 @@ HEADER = \bookpart {
\basicSongInfo \basicSongInfo
} }
} }
\include #(if noDefaultOutput "../private_includes/void.ily" "layout_bottom.ily") \include #(if noDefaultOutput "../private_includes/void.ily" "layout_bottom.ily")