lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Use markup in \replace when lilypond is expecting a string?


From: P J
Subject: Re: Use markup in \replace when lilypond is expecting a string?
Date: Fri, 17 Jun 2022 16:41:59 +0100

Many thanks for your help!

On Thu, 16 Jun 2022 at 08:16, Jean Abou Samra <jean@abou-samra.fr> wrote:


Le 16/06/2022 à 02:36, Valentin Petzel a écrit :
> Of course it would
> theoretically be possible to define a custom replace command that allows for
> this.


Let me throw in a possible solution:

\version "2.22.2" %% Also tested on 2.23.9

#(use-modules (ice-9 regex))

#(define cache (make-hash-table))

#(define (interpret-string-allowing-markup-replacements layout props str)
    (let* ((props-norepl `(((replacement-alist . ())) . ,props))
           (repl (chain-assoc-get 'replacement-alist props '())))
      ;; This needs to be special-cased since we'd otherwise get an
      ;; empty regex, which matches an empty substring anywhere, unlike
      ;; a true empty alternative matching nothing.  It also provides
      ;; the base case for the recursion with \concat.
      (if (null? repl)
          (ly:text-interface::interpret-string layout props-norepl str)
          (let* ((pat (or (hashq-ref cache repl)
                          (let ((p (make-regexp (string-join (map
regexp-quote (map car repl))
"|"))))
                            (hashq-set! cache repl p)
                            p))))
            (let loop ((pos 0)
                       (acc '()))
              (let ((match (regexp-exec pat str pos)))
                (if match
                    (let* ((start (match:start match))
                           (end (match:end match))
                           (before (substring str pos start))
                           (replacement (assoc-get (match:substring match)
                                                   repl)))
                      (loop end (cons* replacement before acc)))
                    (let* ((last-part (substring str pos))
                           (final-acc (reverse! (cons last-part acc))))
(interpret-markup-allowing-markup-replacements
                       layout
                       props-norepl
                       (make-concat-markup final-acc))))))))))

#(define (interpret-markup-allowing-markup-replacements layout props mkup)
    (if (string? mkup)
        (interpret-string-allowing-markup-replacements layout props mkup)
        (apply (car mkup)
               layout
               props
               (cdr mkup))))

#(set! interpret-markup interpret-markup-allowing-markup-replacements)


\markup \column {
   "100"
   \bold \italic "abc"
   \replace #`(("100" . ,#{ \markup \with-color "red" "100" #}))
     { \box "A 100 dpi" }
}


Cheers,
Jean


reply via email to

[Prev in Thread] Current Thread [Next in Thread]