lilypond-devel
[Top][All Lists]
Advanced

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

Re: "include" music-function


From: Jan-Peter Voigt
Subject: Re: "include" music-function
Date: Mon, 09 Jan 2012 11:35:44 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.24) Gecko/20111108 Lightning/1.0b2 Thunderbird/3.1.16

Hello again,

Am 07.01.2012 09:42, schrieb David Kastrup:
Actually, this is quite too complicated...

(ly:parser-include-string parser
   (format #f "\\include ~S" file))

should likely be all that is needed here.

Sorry for thinking too complicated.

so its just:
--snip--
#(define-public includeLocal (define-music-function (parser location file)(string?)
    (let ((outname (format "~A.ly" (ly:parser-output-name parser)))
          (locname (car (ly:input-file-line-char-column location))))
; condition when to include
(if (or (string=? outname locname) (string-suffix? outname locname)) (ly:parser-include-string parser (format "\\include \"~A\"\n" file)))
         (make-music 'SequentialMusic 'void #t))))
--snip--

So another solution to issue 1096, Carl mentioned, could be:
--snip--
#(define-public includeIf (define-music-function (parser location pred file)(procedure? string?)
         (if (pred parser location)
(ly:parser-include-string parser (format "\\include \"~A\"\n" file)))
         (make-music 'SequentialMusic 'void #t)))

\includeIf #(lambda (parser location) (not (defined? 'defs))) "defs.ly"
--snip--
where in "defs.ly" somewhere defs is defined. Or the given lambda looks into a singleton containing all filenames already included or ...
Of course one could use just
--snip--
#(define-public includeIfNotDef (define-music-function (parser location sym file)(symbol? string?)
         (if (not (defined? sym))
(ly:parser-include-string parser (format "\\include \"~A\"\n" file)))
         (make-music 'SequentialMusic 'void #t)))

\includeIfNotDef #'defs "defs.ly"
--snip--
Conclusion: To write a different include music-function, use (ly:parser-include-string parser (format "\\include \"~A\"\n" file)) so that this can be done in global context.

The other function I implemented is also only changing the parser-include-string and removes ly:gulp-file. This is working for me and I am sharing it here, but I don't want to bother anyone to look thru this code. The only thing I'd like to know is: In %load-path the scheme search-path is stored ... where is the lilypond-search-path stored? I propably just didn't saw in the docs?

To explain the other include function a little bit (see below): The directory containing the file named in location is reference point for the directory search. Because ly:find-file doesn't find directories, I cannot refer to that. (It would be nice, but I'd call it a special thing and not an issue ;) ). One could use a reference file and include all siblings matching the pattern or ... or ...
This fits for me:
If I have a collection of files to include "part-<nn>.ly" in a directory called "parts" I can place a file "parts.ly" in the upper directory containing
--snip--
\includePattern "parts" "part-[0-9][0-9].ly"
--snip--
Parameters:
1 - string? directory to search
2 - string? regular expression to match filenames

The include order is not predictable, so the include files should contain variable definitions and not typeset by themself. Of course one could first collect all filenames in a list, sort it and then do the inclusion with for-each over that list.
But there might be many other ideas, how to search and include part-files.

Cheers,
Jan-Peter

--snip--
#(use-modules (ice-9 regex))
#(define-public includePattern (define-music-function (parser location idir pattern)(string? string?)
    (let* ((normalize-list (lambda (path)
                     (let ((ret '()))
                          (for-each (lambda (e)
(set! ret (cond ((equal? e "..")(if (> (length ret) 1) (cdr ret) '())) ((equal? e ".") ret) (else `(,e ,@ret))))) path)
                          (reverse ret))))
(normalize-path (lambda (s) (string-join (normalize-list (string-split s #\/)) "/" 'infix)))
           (extract-path (lambda (location)
(let* ((loc (car (ly:input-file-line-char-column location)))
                            (dirmatch (string-match "(.*/).*" loc))
(dirname (if (regexp-match? dirmatch) (normalize-path (match:substring dirmatch 1)) "./")))
                           dirname
           )))

           (dirname (string-append (extract-path location) idir)))

(if (not (eq? #\. (string-ref dirname 0))) (set! dirname (normalize-path dirname)))
          (if (or (= (string-length dirname) 0)
(not (eq? #\/ (string-ref dirname (- (string-length dirname) 1)))))
              (set! dirname (string-append dirname "/")))
(if (or (not (file-exists? dirname)) (not (eq? 'directory (stat:type (stat dirname)))))
              (set! dirname #f))

          (if dirname (let* ((dir (opendir dirname))
                   (entry (readdir dir)))
                  (while (not (eof-object? entry))
                         (if (regexp-match? (string-match pattern entry))
                             (let ((file (string-append dirname entry)))
;(ly:input-message location "\\include \"~A\"\n" file)
                                  (ly:parser-include-string parser
                                    (format "\\include \"~A\"\n" file))))
                         (set! entry (readdir dir))
                  )
                  (closedir dir)
          ))
    )
    (make-music 'SequentialMusic 'void #t)))
--snip--




reply via email to

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