lilypond-devel
[Top][All Lists]
Advanced

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

Setting arbitrary pdf-metadata from inside .ly-file


From: Thomas Morley
Subject: Setting arbitrary pdf-metadata from inside .ly-file
Date: Sat, 9 Jul 2016 13:08:54 +0200

Out off
https://lists.gnu.org/archive/html/lilypond-user/2016-07/msg00166.html
where Andrew wrote: "On this topic, can we add ‘engraver’ as
pdfengraver to have it in the custom PDF fields?" I tried to set
arbitrary pdf-meta-data from inside the .ly-file.

The code below is _not_ ready to use, just to test whether it's possible at all.
It is - at least for the minimal code-example. I did no further testing.
Thus posting on -devel, cc-ing Andrew and Federico.

Though, I've not a good idea how to transform it into something which
a user could safely deal with.

Here the code:

\version "2.19.44"

%% c/p from framework-ps.scm
#(define (ps-quote str)
  (fold
   (lambda (replacement-list result)
     (string-join
      (string-split
       result
       (car replacement-list))
      (cadr replacement-list)))
   str
   '((#\\ "\\\\") (#\( "\\(") (#\) "\\)"))))

%% jEdit's highlighting gets confused by all the (un-)escaped "-signs :(
%% Thus this comment, now jEdit is on track again

%% Extended %% c/p from framework-ps.scm
#(define (handle-metadatas header port)
  (define (metadata-encode val)
    ;; First, call ly:encode-string-for-pdf to encode the string (latin1 or
    ;; utf-16be), then escape all parentheses and backslashes
    ;; FIXME guile-2.0: use (string->utf16 str 'big) instead

    (ps-quote (ly:encode-string-for-pdf val)))
  (define (metadata-lookup-output overridevar fallbackvar field)
    (let* ((overrideval (ly:modules-lookup (list header) overridevar))
           (fallbackval (ly:modules-lookup (list header) fallbackvar))
           (val (if overrideval overrideval fallbackval)))
      (if val
          (format port "/~a (~a)\n"
            field (metadata-encode (markup->string val (list header)))))))

  (if (module? header)
      (begin
       (display "mark " port)
       (metadata-lookup-output 'pdfauthor 'author "Author")
       (format port "/Creator (LilyPond ~a)\n" (lilypond-version))
       (metadata-lookup-output 'pdftitle 'title "Title")
       (metadata-lookup-output 'pdfsubject 'subject "Subject")
       (metadata-lookup-output 'pdfkeywords 'keywords "Keywords")
       (metadata-lookup-output 'pdfmodDate 'modDate "ModDate")
       (metadata-lookup-output 'pdfsubtitle 'subtitle "Subtitle")
       (metadata-lookup-output 'pdfcomposer 'composer "Composer")
       (metadata-lookup-output 'pdfarranger 'arranger "Arranger")
       (metadata-lookup-output 'pdfpoet 'poet "Poet")
   ;;;; added:
       (metadata-lookup-output 'pdfengraver 'engraver "Engraver")
       (metadata-lookup-output 'pdffoo 'foo "Foo")
   ;;;; end additions
       (metadata-lookup-output 'pdfcopyright 'copyright "Copyright")
       (display "/DOCINFO pdfmark\n\n" port)))

  (if (ly:get-option 'embed-source-code)
      (let ((source-list (delete-duplicates
                          (remove (lambda (str)
                                    (or
                                     (string-contains str
                                       (ly:get-option 'datadir))
                                     (string=? str
                                       "<included string>")))
                            (ly:source-files)))))
         (display "\n/pdfmark where
{pop} {userdict /pdfmark /cleartomark load put} ifelse" port)
         (for-each (lambda (fname idx)
                     (format port "\n
mark /_objdef {ly~a_stream} /type /stream   /OBJ pdfmark
mark {ly~a_stream} << /Type /EmbeddedFile>> /PUT pdfmark
mark {ly~a_stream} (~a) /PUT pdfmark
mark /Name (LilyPond source file ~a)
/FS << /Type /Filespec /F (~a) /EF << /F {ly~a_stream} >> >> /EMBED pdfmark
mark {ly~a_stream} /CLOSE pdfmark
\n"
                idx idx idx
                (ps-quote (ly:gulp-file fname))
                  idx fname idx idx))
          source-list (iota (length source-list))))))

%% put `handle-metadatas' in the relevant module
#(module-set!
  (@@ (scm framework-ps) framework-ps-module)
  'handle-metadata
  (ly:parser-lookup 'handle-metadatas))


\book {
  \header {
    title = "TITLE with Engraver and buzz in meta"
    engraver = "Engraver"
    foo = "buzz"
  }
  \score { { r1 \pageBreak r } }
}


$ exiftool <file.ly>
[...]
Title                           : TITLE with Engraver and buzz in meta
Creator                         : LilyPond 2.19.45
Engraver                        : Engraver
Foo                             : buzz


Cheers,
  Harm



reply via email to

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