From: Valentin Villenave Date: Mon, 7 Mar 2016 09:06:52 +0000 (+0100) Subject: (Optionally) embed ly source files inside generated PDF X-Git-Tag: release/2.19.38-1~6^2~7 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=0fa6f042cccacb643d46781dde23617c71a9753e;p=lilypond.git (Optionally) embed ly source files inside generated PDF By using the new -dembed-source-code command line switch, users may now include their LilyPond source code in the generated PDF (using the pdfmark EMBED feature); although the PDF is not modified in any visible way, embedded .ly files should appear in viewers that support this feature (other viewers should degrade gracefully). This patch adds a new ly:source-files function (with an optional parser arg) that allows to retrieve the list of (non distribution-provided) ly files involved in making the current score. --- diff --git a/Documentation/changes.tely b/Documentation/changes.tely index 21e06b9ed9..647bdb8177 100644 --- a/Documentation/changes.tely +++ b/Documentation/changes.tely @@ -61,6 +61,14 @@ which scares away people. @end ignore +@item +LilyPond source files may now be embedded inside the generated PDF files. +This experimental feature is disabled by default and may be regarded as unsafe, +as PDF documents with hidden content tend to present a security risk. +Please note that not all PDF viewers have the ability to handle embedded +documents (if not, the PDF output will appear normally and source files +will remain invisible). This feature only works with the PDF backend. + @item French note names are now defined specifically instead of being aliased to Italian note names: in addition to the diff --git a/Documentation/usage/running.itely b/Documentation/usage/running.itely index 9801cfc207..995119e57b 100644 --- a/Documentation/usage/running.itely +++ b/Documentation/usage/running.itely @@ -580,6 +580,10 @@ compilation. @tab @code{#f} @tab Dump output signatures of each system. Used for regression testing. +@item @code{embed-source-code} +@tab @code{#f} +@tab Embed the LilyPond source files inside the generated PDF document. + @item @code{eps-box-padding} @tab @code{#f} @tab Pad left edge of the output EPS bounding box by the given amount diff --git a/lily/sources.cc b/lily/sources.cc index b42300f47a..5d865fe706 100644 --- a/lily/sources.cc +++ b/lily/sources.cc @@ -86,3 +86,28 @@ Sources::~Sources () } } +#include "lily-parser.hh" +#include "lily-lexer.hh" +#include "lily-imports.hh" +#include "fluid.hh" + +LY_DEFINE (ly_source_files, "ly:source-files", 0, 1, 0, + (SCM parser_smob), + "A list of LilyPond files being processed;" + "a PARSER may optionally be specified.") +{ + + if (SCM_UNBNDP (parser_smob)) + parser_smob = scm_fluid_ref (Lily::f_parser); + Lily_parser *parser = LY_ASSERT_SMOB (Lily_parser, parser_smob, 1); + Includable_lexer *lex = parser->lexer_; + + SCM lst = SCM_EOL; + for (vector::const_iterator + i = lex->file_name_strings_.begin(); + i != lex->file_name_strings_.end(); ++i) + { + lst = scm_cons (ly_string2scm (*i), lst); + } + return scm_reverse_x (lst, SCM_EOL); +} diff --git a/scm/framework-ps.scm b/scm/framework-ps.scm index f6d1700f42..d3234b3329 100644 --- a/scm/framework-ps.scm +++ b/scm/framework-ps.scm @@ -463,20 +463,44 @@ (val (if overrideval overrideval fallbackval))) (if val (format port "/~a (~a)\n" field (metadata-encode (markup->string val (list header))))))) - (display "[ " 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 (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) + (string-contains str + (ly:get-option 'datadir))) + (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)))))) (define-public (output-framework basename book scopes fields) (let* ((port-tmp (make-tmpfile)) @@ -501,8 +525,7 @@ ;; don't do BeginDefaults PageMedia: A4 ;; not necessary and wrong (write-preamble paper #t port) - (if (module? header) - (handle-metadata header port)) + (handle-metadata header port) (for-each (lambda (page) (set! page-number (1+ page-number)) @@ -730,7 +753,7 @@ system-by-system output. For that, use the EPS backend instead, lilypond -dbackend=eps FILE -If have cut & pasted a lilypond fragment from a webpage, be sure +If you have cut & pasted a lilypond fragment from a webpage, be sure to only remove anything before %% **************************************************************** diff --git a/scm/lily.scm b/scm/lily.scm index eb487d33e9..3d7a326c64 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -245,6 +245,9 @@ configurations.") #f "Dump output signatures of each system. Used for regression testing.") + (embed-source-code + #f + "Embed the source files inside the generated PDF document.") (eps-box-padding #f "Pad left edge of the output EPS bounding box by