[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Use markup in \replace when lilypond is expecting a string?
From: |
Jean Abou Samra |
Subject: |
Re: Use markup in \replace when lilypond is expecting a string? |
Date: |
Thu, 16 Jun 2022 09:16:21 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1 |
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