-(define-public (output-framework basename book scopes fields)
- (let* ((filename (format "~a.ps" basename))
- (outputter (ly:make-paper-outputter
- ;; FIXME: better wrap open/open-file,
- ;; content-mangling is always bad.
- ;; MINGW hack: need to have "b"inary for embedding CFFs
- (open-file filename "wb")
- 'ps))
- (paper (ly:paper-book-paper book))
- (systems (ly:paper-book-systems book))
- (page-stencils (map page-stencil (ly:paper-book-pages book)))
-
- (landscape? (eq? (ly:output-def-lookup paper 'landscape) #t))
- (page-number (1- (ly:output-def-lookup paper 'first-page-number)))
- (page-count (length page-stencils))
- (port (ly:outputter-port outputter)))
-
+(define (ps-quote str)
+ (fold
+ (lambda (replacement-list result)
+ (string-join
+ (string-split
+ result
+ (car replacement-list))
+ (cadr replacement-list)))
+ str
+ '((#\\ "\\\\") (#\( "\\(") (#\) "\\)"))))
+
+;;; Create DOCINFO pdfmark containing metadata
+;;; header fields with pdf prefix override those without the prefix
+(define (handle-metadata 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")
+ (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))))))