Re: #(define (bookGenerator please))

2016-06-28 Thread David Kastrup
Simon Albrecht  writes:

> On 28.06.2016 00:52, Thomas Morley wrote:
>>> How can I make my function be more "indentable" by using, for
>>> example, curly braces e.g. \bookGenerator { stuff } ?
>> No idea what you mean.
>
> The point is, with the current coding you write
>
> \bookGenerator
> \scores
> "violinI"
> %\header {instrument = "Violin I"}
> \paper {}
> \layout {}
>
> and it’s hard to discern that the five following lines are arguments
> to the function in the first line, since Lilypond syntax doesn’t
> enclose the arguments of a function and no editor will indent them.

Well, that means that we should think about how to teach this to editors
best...

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: #(define (bookGenerator please))

2016-06-28 Thread Simon Albrecht

On 28.06.2016 00:52, Thomas Morley wrote:

How can I make my function be more "indentable" by using, for
example, curly braces e.g. \bookGenerator { stuff } ?

No idea what you mean.


The point is, with the current coding you write

\bookGenerator
\scores
"violinI"
%\header {instrument = "Violin I"}
\paper {}
\layout {}

and it’s hard to discern that the five following lines are arguments to 
the function in the first line, since Lilypond syntax doesn’t enclose 
the arguments of a function and no editor will indent them.
But the only solution I’d see for this problem is switching to Scheme 
syntax, and that’s not quite desirable.


Best, Simon

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: #(define (bookGenerator please))

2016-06-27 Thread Thomas Morley
2016-06-28 0:52 GMT+02:00 Thomas Morley :
> 2016-06-27 18:56 GMT+02:00 Pierre-Luc Gauthier :
>> Greetings,
>>
>> Sorry about the late follow up (about 7 months later).
>>
>> The orchestra I work with came down to a halt for the summer and I now
>> have some time to set stuff up for the next season.
>>
>> Many thanks to you Urs and David; your explanations certainly helped
>> me understand more of what was going on especially about quasi-quotes.
>>
>> Here is what I got so far.
>>
>> %
>>
>> \version "2.19.44"
>>
>> \language "english"
>>
>> \header {title = "Such title."}
>>
>> scoreA = \score {\header {piece = "Piece A"} a'4}
>>
>> scoreB = \score {\header {piece = "Piece B"} b'4}
>>
>> scores = #(list scoreA scoreB)
>>
>> #(define bookGenerator
>>(define-void-function
>> (
>>   scoreList
>>   bookSuffix
>>   ;; header
>>   paperBlock
>>   layoutBlock
>>   )
>> (list? string? scheme? scheme?) ;; add scheme? here
>> (let* (
>> (book (apply ly:make-book
>> paperBlock
>> #f ;; header
>> (reverse scoreList)))
>> )
>>   (ly:book-process book paperBlock layoutBlock bookSuffix))
>> ))
>>
>> \bookGenerator
>> \scores
>> "violinI"
>> %\header {instrument = "Violin I"}
>> \paper {}
>> \layout {}
>>
>> %
>>
>> It works fine and I am pretty excited about this
>> ¡¡¡So long, 500+ lines of inflexible and unmaintainable book definitions!!!
>> Well, my problem is with the header.
>> I have not found a way to pass a header to the function ly:make-book.
>> I found #f to make the function compile... which obviously is not much
>> of a suitable header.
>>
>> How can I pass a header (and the global header) to ly:make-book?
>
>
> Below two different codings which you may find helpful
>
> (1) %
>
> \version "2.19.44"
>
> \language "english"
>
> bookGenerator =
> #(define-void-function (scoreList bookSuffix) (list? string?)
>   (let* ((book (apply ly:make-book
>   $defaultpaper
>   $defaultheader
>   (reverse scoreList
> (ly:book-process book $defaultpaper $defaultlayout bookSuffix)))
>
>  book-header
> %% referenced as $defaultheader
> %% needs to be defined before new settings are done
> \header { title = "Such title." }
>
> %% header-settings added via scheme:
> %% settings stored in an alist:
> my-header-entries =
> #'((subtitle . "SUBTITLE")
>(dedication . "DEDICATION")
>(composer . "MYSELF"))
>
> %% apply them:
> #(for-each
>   (lambda (e) (module-define! $defaultheader (car e) (cdr e)))
>   my-header-entries)
>
> %% print header-settings to terminal
> %#(pretty-print (ly:module->alist $defaultheader))
>
>  book-layout
> %% referenced as $defaultlayout
> \layout {
>   \context {
>   \Staff
>   \override TimeSignature.color = #green
>   }
> }
>
>  book-paper
> %% referenced as $defaultpaper
> \paper { ragged-right = ##f }
>
> %% score-definitions with scoreheader-settings
> scoreA = \score { \header { piece = "Piece A" } a'4 }
> scoreB = \score { \header { piece = "Piece B" } b'4 }
>
> scores = #(list scoreA scoreB)
>
> %% print the book:
> \bookGenerator
>   \scores
>   "violinI"
>
> (2) %
>
> %% you can do a lot with those powerful functions, here another method
> %% `add-score` is a nice function as well
>
> \version "2.19.44"
>
> \language "english"
>
> scoreA = \score { \header { piece = "Piece A" } a'4 }
> scoreB = \score { \header { piece = "Piece B" } b'4 }
>
> \paper { ragged-right = ##f }
>
> \header { title = "Such title two." }
>
> \layout {
>   \context {
>   \Staff
>   \override TimeSignature.color = #green
>   }
> }
>
> bk = \book {}
>
> %% not really needed in this situation :
> #(ly:book-set-header! bk $defaultheader)
>
> %% you could use this in a book-generating function:
> #(for-each
>   add-score
>   (list scoreA scoreB))
>
> \bookOutputName "violinI"

or
(3) %%%


my-other-header-entries =
#'((title . "title")
   (subtitle . "subtitlw")
   (dedication . "dedication")
   (composer . "myself"))

#(define my-defaultheader (make-module))

#(for-each
  (lambda (e)
(module-define! my-defaultheader (car e) (cdr e)))
  my-other-header-entries)

bookGeneratorTwo =
#(define-void-function (scoreList custom-header bookSuffix)
  (list? module? string?)
  (let* ((book (apply ly:make-book
  $defaultpaper
  custom-header
  (reverse scoreList
(ly:book-process book $defaultpaper $defaultlayout bookSuffix)))

scoreA = \score { \header { piece = "Piece A-bis" } ais'4 }
scoreB = \score { \header { piece = "Piece B-bis" } bis'4 }

scores = #(list scoreA scoreB)

\bookGeneratorTwo
  \scores
  #my-defaultheader
  "violinI-bis"



A plethora of possibilities ...


Re: #(define (bookGenerator please))

2016-06-27 Thread Thomas Morley
2016-06-27 18:56 GMT+02:00 Pierre-Luc Gauthier :
> Greetings,
>
> Sorry about the late follow up (about 7 months later).
>
> The orchestra I work with came down to a halt for the summer and I now
> have some time to set stuff up for the next season.
>
> Many thanks to you Urs and David; your explanations certainly helped
> me understand more of what was going on especially about quasi-quotes.
>
> Here is what I got so far.
>
> %
>
> \version "2.19.44"
>
> \language "english"
>
> \header {title = "Such title."}
>
> scoreA = \score {\header {piece = "Piece A"} a'4}
>
> scoreB = \score {\header {piece = "Piece B"} b'4}
>
> scores = #(list scoreA scoreB)
>
> #(define bookGenerator
>(define-void-function
> (
>   scoreList
>   bookSuffix
>   ;; header
>   paperBlock
>   layoutBlock
>   )
> (list? string? scheme? scheme?) ;; add scheme? here
> (let* (
> (book (apply ly:make-book
> paperBlock
> #f ;; header
> (reverse scoreList)))
> )
>   (ly:book-process book paperBlock layoutBlock bookSuffix))
> ))
>
> \bookGenerator
> \scores
> "violinI"
> %\header {instrument = "Violin I"}
> \paper {}
> \layout {}
>
> %
>
> It works fine and I am pretty excited about this
> ¡¡¡So long, 500+ lines of inflexible and unmaintainable book definitions!!!
> Well, my problem is with the header.
> I have not found a way to pass a header to the function ly:make-book.
> I found #f to make the function compile... which obviously is not much
> of a suitable header.
>
> How can I pass a header (and the global header) to ly:make-book?


Below two different codings which you may find helpful

(1) %

\version "2.19.44"

\language "english"

bookGenerator =
#(define-void-function (scoreList bookSuffix) (list? string?)
  (let* ((book (apply ly:make-book
  $defaultpaper
  $defaultheader
  (reverse scoreList
(ly:book-process book $defaultpaper $defaultlayout bookSuffix)))

 book-header
%% referenced as $defaultheader
%% needs to be defined before new settings are done
\header { title = "Such title." }

%% header-settings added via scheme:
%% settings stored in an alist:
my-header-entries =
#'((subtitle . "SUBTITLE")
   (dedication . "DEDICATION")
   (composer . "MYSELF"))

%% apply them:
#(for-each
  (lambda (e) (module-define! $defaultheader (car e) (cdr e)))
  my-header-entries)

%% print header-settings to terminal
%#(pretty-print (ly:module->alist $defaultheader))

 book-layout
%% referenced as $defaultlayout
\layout {
  \context {
  \Staff
  \override TimeSignature.color = #green
  }
}

 book-paper
%% referenced as $defaultpaper
\paper { ragged-right = ##f }

%% score-definitions with scoreheader-settings
scoreA = \score { \header { piece = "Piece A" } a'4 }
scoreB = \score { \header { piece = "Piece B" } b'4 }

scores = #(list scoreA scoreB)

%% print the book:
\bookGenerator
  \scores
  "violinI"

(2) %

%% you can do a lot with those powerful functions, here another method
%% `add-score` is a nice function as well

\version "2.19.44"

\language "english"

scoreA = \score { \header { piece = "Piece A" } a'4 }
scoreB = \score { \header { piece = "Piece B" } b'4 }

\paper { ragged-right = ##f }

\header { title = "Such title two." }

\layout {
  \context {
  \Staff
  \override TimeSignature.color = #green
  }
}

bk = \book {}

%% not really needed in this situation :
#(ly:book-set-header! bk $defaultheader)

%% you could use this in a book-generating function:
#(for-each
  add-score
  (list scoreA scoreB))

\bookOutputName "violinI"

> %
>
> A few side questions,
>
> Also, How can I make my function be more "indentable" by using, for
> example, curly braces e.g. \bookGenerator { stuff } ?

No idea what you mean.

>
> Why do I have to pass a paperBlock to ly:make-book AND to ly:book-process ?
> Is there a way to only have one?
> Doesn't the ly:make-book already contains the paperBlock ?

ly:make-book creates the book. Now you could add this and that ...
After you finished your work on the probably modified book you need to
print it with ly:book-process

> OT discussion; Frescobaldi can not, currently, get a hold of those PDF
> generated with lower level commands
> As this [1] comment stated, the LilyPond output could be a fail-safe
> way to track down every generated PDFs instead of reverse engineering
> the generated filenames as it is (I think) currently the case.

Can't say anything here, I don't use Frescobaldi

>
> [1] https://github.com/wbsoft/frescobaldi/issues/546#issuecomment-155148714
>
>
> --
> Pierre-Luc Gauthier
>
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> 

Re: #(define (bookGenerator please))

2016-06-27 Thread Pierre-Luc Gauthier
Greetings,

Sorry about the late follow up (about 7 months later).

The orchestra I work with came down to a halt for the summer and I now
have some time to set stuff up for the next season.

Many thanks to you Urs and David; your explanations certainly helped
me understand more of what was going on especially about quasi-quotes.

Here is what I got so far.

%

\version "2.19.44"

\language "english"

\header {title = "Such title."}

scoreA = \score {\header {piece = "Piece A"} a'4}

scoreB = \score {\header {piece = "Piece B"} b'4}

scores = #(list scoreA scoreB)

#(define bookGenerator
   (define-void-function
(
  scoreList
  bookSuffix
  ;; header
  paperBlock
  layoutBlock
  )
(list? string? scheme? scheme?) ;; add scheme? here
(let* (
(book (apply ly:make-book
paperBlock
#f ;; header
(reverse scoreList)))
)
  (ly:book-process book paperBlock layoutBlock bookSuffix))
))

\bookGenerator
\scores
"violinI"
%\header {instrument = "Violin I"}
\paper {}
\layout {}

%

It works fine and I am pretty excited about this
¡¡¡So long, 500+ lines of inflexible and unmaintainable book definitions!!!
Well, my problem is with the header.
I have not found a way to pass a header to the function ly:make-book.
I found #f to make the function compile... which obviously is not much
of a suitable header.

How can I pass a header (and the global header) to ly:make-book?

%

A few side questions,

Also, How can I make my function be more "indentable" by using, for
example, curly braces e.g. \bookGenerator { stuff } ?

Why do I have to pass a paperBlock to ly:make-book AND to ly:book-process ?
Is there a way to only have one?
Doesn't the ly:make-book already contains the paperBlock ?

OT discussion; Frescobaldi can not, currently, get a hold of those PDF
generated with lower level commands
As this [1] comment stated, the LilyPond output could be a fail-safe
way to track down every generated PDFs instead of reverse engineering
the generated filenames as it is (I think) currently the case.

[1] https://github.com/wbsoft/frescobaldi/issues/546#issuecomment-155148714


-- 
Pierre-Luc Gauthier
\version "2.19.44"

\language "english"

\header {title = "Such title."}

scoreA = \score {\header {piece = "Piece A"} a'4}

scoreB = \score {\header {piece = "Piece B"} b'4}

scores = #(list scoreA scoreB)

#(define bookGenerator
   (define-void-function
(
  scoreList
  bookSuffix
  ;; header
  paperBlock
  layoutBlock
  )
(list? string? scheme? scheme?) ;; add scheme? here
(let* (
(book (apply ly:make-book
paperBlock
#f ;; header
(reverse scoreList)))
)
  (ly:book-process book paperBlock layoutBlock bookSuffix))
))

\bookGenerator
\scores
"violinI"
%\header {instrument = "Violin I"}
\paper {}
\layout {}___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: #(define (bookGenerator please))

2015-11-17 Thread David Kastrup
Pierre-Luc Gauthier  writes:

> So, after reading the "Automated processing of multiple books" thread
> and few hours trying to figure this out, I am still not able to make
> it work.
> The higher order function "for-each" somehow cannot call the
> "compilePart" function and Lilyponds GUILE interpreter returns "Wrong
> type to apply".
>
> Why?

Apart from the quoting problem mentioned by Urs, because you are using
version 2.18.2; a function defined with "define-void-function" cannot be
called as if were a native Scheme function before version 2.19.22
(issue 4421).

> Simple tests allowed me to prove that "for-each" *can* call functions
> like "display" but not my "compilePart".

Yup.  For 2.18.2, you can call (ly:music-function-extract compilePart)
instead but it will expect you to supply processed versions of all
optional arguments.  Also, the calling convention as of 2.19.22 no
longer includes "parser" and "location" arguments, so if you are working
with ly:music-function-extract, your code will not work under newer
versions without change.

It's more portable to define a Scheme function using named compile-part
or compile-part-internal using "define" and call that from inside of
your compilePart definition as well as from your for-each loop.

Or just upgrade to version 2.19.22 or later and stuff will just work the
way you tried.  But as of version 2.19.22, you can just leave off the
"parser location" arguments anyway.

> I am very very new to scheme and let alone scheme inside the pond and
> I really got a kick out of this journey finally understanding why
> those #, #', #{, #}, $, parser, location, etc were there in the first
> place.
>
> It's really satisfying.

Too bad I removed "parser" and "location" arguments by now.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: #(define (bookGenerator please))

2015-11-17 Thread Urs Liska


Am 17.11.2015 um 03:12 schrieb Pierre-Luc Gauthier:
> So, after reading the "Automated processing of multiple books" thread
> and few hours trying to figure this out, I am still not able to make
> it work.
> The higher order function "for-each" somehow cannot call the
> "compilePart" function and Lilyponds GUILE interpreter returns "Wrong
> type to apply".
>
> Why?

This is because you did not pass a music expression but a symbol.
The problem is in the definition of the "parts" variable. This is
defined to be a list of pairs (which is right) but in

' ("piccolo" . piccoloPart)

the leading quotation mark makes the elements of the following pair or
list "quoted" as well. So it's basically the same as

(list "piccolo" 'piccoloPart)

If you want to use the "quote" style definition but need some of the
elements to be treated as their actual value instead of simply names we
have the "quasiquote" style where you precede the parenthesis with a
backtick:

`(item1 . item2)

`("piccolo" . piccoloPart)

however would result in the same error. But if you have "quasiquoted" an
expression you can "unquote" individual elements using the comma:

`("piccolo" . ,piccoloPart)

finally works.

So

parts = #(list
  ;; This is a list of pairs containing parts informations
  `("piccolo" . ,piccoloPart)
  `("bass" . ,bassPart))

will make your file compile and produce two parts

HTH
Urs


>
> Simple tests allowed me to prove that "for-each" *can* call functions
> like "display" but not my "compilePart".
>
> I am very very new to scheme and let alone scheme inside the pond and
> I really got a kick out of this journey finally understanding why
> those #, #', #{, #}, $, parser, location, etc were there in the first
> place.
> It's really satisfying.
>
> Here is the code for my MWE.
>
> 
> \version "2.18.2"
>
> \language "english"
>
> piccoloPart = \new Staff {
>   \new Voice {
> \relative c' {
>   d4 e fs g |
>   a1\fermata |
> }
>   }
> }
>
> bassPart = \new Staff {
>   \new Voice {
> \relative c {
>   \clef bass
>   c4 d e f |
>   g1\fermata |
> }
>   }
> }
>
> compilePart = #(define-void-function ( parser location music name)
>  ;; This function is used to do and engrave a book
>  ;; $music should be a musical expression
>  ;; $name should be a string for the book output suffix
>  (ly:music? string?)
>  (let ((paper #{ \paper {} #})
>(layout #{ \layout {} #})
>(book #{ \book { \score { $music } } #}))
>(ly:book-process book paper layout name)))
>
> % _This_ is to test the compilePart function
> %\compilePart \piccoloPart #"piccolo"
> % \compilePart \bassPart #"bass"
>
> parts = #(list
>   ;; This is a list of pairs containing parts informations
>   '("piccolo" . piccoloPart)
>   '("bass" . bassPart))
>
> % _This_ is to test that the data can be extracted succesfully from the list
> %\compilePart #(cdr (car parts)) #(car (car parts)) % First entry
> %\compilePart #(cdr (car (cdr parts))) #(car (car (cdr parts))) % Second entry
>
> % Somehow _this_ does not work.
> %{#(for-each
>   (lambda (p)
> (let ((name (car p))
>   (music (cdr p)))
> (compilePart music name )
> ))
>   parts)%}
> 
>
> 2015-11-16 14:55 GMT-05:00 Pierre-Luc Gauthier :
>> Possible duplicate!
>>
>> It appears I have missed the very similar thread "Automated processing
>> of multiple books"
>>
>> I'll digest that first ;-)
>>
>> --
>> Pierre-Luc Gauthier
>
>
>
>
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: #(define (bookGenerator please))

2015-11-16 Thread Pierre-Luc Gauthier
Possible duplicate!

It appears I have missed the very similar thread "Automated processing
of multiple books"

I'll digest that first ;-)

-- 
Pierre-Luc Gauthier

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: #(define (bookGenerator please))

2015-11-16 Thread Pierre-Luc Gauthier
So, after reading the "Automated processing of multiple books" thread
and few hours trying to figure this out, I am still not able to make
it work.
The higher order function "for-each" somehow cannot call the
"compilePart" function and Lilyponds GUILE interpreter returns "Wrong
type to apply".

Why?

Simple tests allowed me to prove that "for-each" *can* call functions
like "display" but not my "compilePart".

I am very very new to scheme and let alone scheme inside the pond and
I really got a kick out of this journey finally understanding why
those #, #', #{, #}, $, parser, location, etc were there in the first
place.
It's really satisfying.

Here is the code for my MWE.


\version "2.18.2"

\language "english"

piccoloPart = \new Staff {
  \new Voice {
\relative c' {
  d4 e fs g |
  a1\fermata |
}
  }
}

bassPart = \new Staff {
  \new Voice {
\relative c {
  \clef bass
  c4 d e f |
  g1\fermata |
}
  }
}

compilePart = #(define-void-function ( parser location music name)
 ;; This function is used to do and engrave a book
 ;; $music should be a musical expression
 ;; $name should be a string for the book output suffix
 (ly:music? string?)
 (let ((paper #{ \paper {} #})
   (layout #{ \layout {} #})
   (book #{ \book { \score { $music } } #}))
   (ly:book-process book paper layout name)))

% _This_ is to test the compilePart function
%\compilePart \piccoloPart #"piccolo"
% \compilePart \bassPart #"bass"

parts = #(list
  ;; This is a list of pairs containing parts informations
  '("piccolo" . piccoloPart)
  '("bass" . bassPart))

% _This_ is to test that the data can be extracted succesfully from the list
%\compilePart #(cdr (car parts)) #(car (car parts)) % First entry
%\compilePart #(cdr (car (cdr parts))) #(car (car (cdr parts))) % Second entry

% Somehow _this_ does not work.
%{#(for-each
  (lambda (p)
(let ((name (car p))
  (music (cdr p)))
(compilePart music name )
))
  parts)%}


2015-11-16 14:55 GMT-05:00 Pierre-Luc Gauthier :
> Possible duplicate!
>
> It appears I have missed the very similar thread "Automated processing
> of multiple books"
>
> I'll digest that first ;-)
>
> --
> Pierre-Luc Gauthier



-- 
Pierre-Luc Gauthier
\version "2.18.2"

\language "english"

piccoloPart = \new Staff {
  \new Voice {
\relative c' {
  d4 e fs g |
  a1\fermata |
}
  }
}

bassPart = \new Staff {
  \new Voice {
\relative c {
  \clef bass
  c4 d e f |
  g1\fermata |
}
  }
}

compilePart = #(define-void-function ( parser location music name)
 ;; This function is used to do and engrave a book
 ;; $music should be a musical expression
 ;; $name should be a string for the book output suffix
 (ly:music? string?)
 (let ((paper #{ \paper {} #})
   (layout #{ \layout {} #})
   (book #{ \book { \score { $music } } #}))
   (ly:book-process book paper layout name)))

% _This_ is to test the compilePart function
%\compilePart \piccoloPart #"piccolo"
% \compilePart \bassPart #"bass"

parts = #(list
  ;; This is a list of pairs containing parts informations
  '("piccolo" . piccoloPart)
  '("bass" . bassPart))

% _This_ is to test that the data can be extracted succesfully from the list
%\compilePart #(cdr (car parts)) #(car (car parts)) % First entry
%\compilePart #(cdr (car (cdr parts))) #(car (car (cdr parts))) % Second entry

% Somehow _this_ does not work.
%{#(for-each
  (lambda (p)
(let ((name (car p))
	   (music (cdr p)))
(compilePart music name )
))
  parts)%}___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user