Hallo Forum,
ich habe mich inzwischen durch die Details von Harm's Code durchgearbeitet und denke, ich habe ihn jetzt verstanden. Darüber hinaus habe ich mich in die regular expressions eingelesen und denke ich habe eine funktionsidentische Version zu der von Harm, jedoch mit regulären Ausdrücken. In einer Guile Kommandozeilenumgebung tun die auch, was ich von ihnen möchte. Aber in lilypond bekomme ich eine Fehlermeldung.
Hier der Code:
\version "2.18.2"
#(define-markup-command (underdot layout props arg)
(markup?)
"Place a dot below @var{arg} using @code{\\center.column}"
(interpret-markup layout props
(markup #:override '(baseline-skip . 0.5) #:center-column (arg "."))))
#(define-markup-command (emphasize layout props strg)(string?)
#:properties ((func make-underdot-markup)
(indicator "*"))
"Applies @code{func} to substrings of @var{strg}. Those substrings have to be
marked with @code{indicator}, which defaults to @code{"*"}
@lilypond[verbatim,quote]
\\markup \\column {
\\emphasize #"a*ä**ö*de*f**ü*"
\\override #'(indicator . "_") \\emphasize #"a_ä__ö_de_f__ü_"
\\override #`(func . ,make-underline-markup) \\emphasize #"a*ä**ö*de*f**ü*"
}
@end lilypond
"
(let* ((indicator-char
(let ((ls (string->list indicator)))
(if (not (= (length ls) 1))
(ly:error
"indicator needs to be (= (string-length indicator) 1)")
(car ls))))
(sub-strings
(map match:substring
(list-matches
(string-concatenate
(list (regexp-quote indicator-char) "([^" (regexp-quote indicator-char) "]+)" (regexp-quote indicator-char)))
strg)))
;; der folgende refuläre Ausdruck sollte das gleiche Ergebnis liefern
;; und zudem effizienter sein. zumindest auf der Kommandozeile habe ich
;; jedoch keine non-greedy regexp zum Laufen bekommen :(
; (sub-strings
; (map match:substring
; (list-matches
; (string-concatenate
; (list (regexp-quote indicator-char) "(.+?)" (regexp-quote indicator-char)))
; strg))
(strg-ls (string-split strg indicator-char))
(mrkp
(make-concat-markup
(map
(lambda (x)
(if (member x sub-strings)
(func x)
x))
strg-ls))))
; (ly:warning (string-concatenate (list "indicator='" indicator "', strg='" strg "'" )))
; (ly:warning (string-concatenate (list "indicator-char='" (string indicator-char) "'")))
; (ly:warning (string-concatenate (list "sub-strings=(" (string-concatenate (map (lambda (x) (string-concatenate (list "'" x "',"))) sub-strings)) ")" )))
; (ly:warning (string-concatenate (list "strg-ls=(" (string-concatenate (map (lambda (x) (string-concatenate (list "'" x "',"))) strg-ls)) ")" )))
; (ly:warning " ")
(interpret-markup layout props mrkp)))
%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%
\markup
\rounded-box
\emphasize #"a*ä**ö*de*f**ü*"
\markup
\rounded-box
\emphasize #"a*äö*de*frü*"
\markup
\rounded-box
\emphasize #"aäödefü"
% generate warning-located "number of indicators not even, last indicator will be ignored"
\markup
\rounded-box
\emphasize #"a*ä*ö*de*fü*"
\markup
\rounded-box
\emphasize #"aä**öde*f****ü*"
\markup
\rounded-box
\override #'(indicator . "_")
\emphasize #"a_ä__ö_de_f__ü_"
\markup
\rounded-box
\override #`(func . ,make-underline-markup)
\emphasize #"a*ä**ö*de*f**ü*"
\markup
\rounded-box
\override #`(func . ,make-underline-markup)
\emphasize #"a*äö*de*fü*"
\markup
\rounded-box
\override #`(func . ,(lambda (s) (make-with-color-markup red s)))
\emphasize #"a*ä**ö*de*f**ü*"
\markup
\rounded-box
\override #`(func
.
,(lambda (s)
#{
\markup
\override #'(baseline-skip . 0)
\center-column {
$s
\tied-lyric #"~"
}
#}))
\emphasize #"a*äö*de*fü*"
\markup \rounded-box \emphasize #"l*e*t th*e* c*o*ngr*e*-"
Und dies ist die Fehlermeldung:
.../underdot-emphasize2.ly:30:12: Unbound variable: match:substring
Muss ich noch irgendetwas includen, damit match:substring erkannt wird ?
In obigem Code sind kommentiert noch meine debugging Loganweisungen zu sehen.
Ferner ist der verwendete reguläre Ausdruck eigentlich eine ineffiziente Krücke, aber die non-greedy regexp haben bei mir nicht funktioniert.
Wie immer für sachdienliche und sonstige Hinweise dankbar,
Michael