Trouble defining markup functiion

2019-01-17 Thread Carl Sorensen


I'm trying to define a markup function for establishing a common set of 
formatting for a number of text markups.

%%% beginning of sample code

\version "2.19.82"

\displayScheme
\markup{\sans{\fontsize #10 "C"}}  % Just used to show the scheme markup 
command -- this is what I'm trying

#(define-markup-command  (chord-name-markup layout props chord-name) (markup?)
   "Display a chord name in the desired formatting"
   (interpret-markup layout props 
 (make-line-markup (#:sans (#:fontsize 10 chord-name)


\markup \chord-name-markup "E"

%%% end of code

I've used displayScheme to get the representation of the markup function.  I've 
found that is uses #:line so that I have to use make-line-markup.  

When I run this code, I get

Processing 
`/var/folders/q5/88k2s1717qv1v7rq4tqz53k8gn/T/frescobaldi-fmnvoopw/tmpc0ltmn4y/document.ly'
Parsing.../var/folders/q5/88k2s1717qv1v7rq4tqz53k8gn/T/frescobaldi-fmnvoopw/tmpc0ltmn4y/document.ly:9:32:
 In expression (#:fontsize 10 chord-name):
/var/folders/q5/88k2s1717qv1v7rq4tqz53k8gn/T/frescobaldi-fmnvoopw/tmpc0ltmn4y/document.ly:9:32:
 Wrong type to apply: #:fontsize

Apparently, in the context of make-line-markup I can't use #:fontsize as the 
first element in a list, because it's not applyable.

How can I do this properly?

Thanks,

Carl



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


Re: Trouble defining markup functiion

2019-01-17 Thread David Kastrup
Carl Sorensen  writes:

> I'm trying to define a markup function for establishing a common set of 
> formatting for a number of text markups.
>
> %%% beginning of sample code
>
> \version "2.19.82"
>
> \displayScheme
> \markup{\sans{\fontsize #10 "C"}}  % Just used to show the scheme markup 
> command -- this is what I'm trying
>
> #(define-markup-command  (chord-name-markup layout props chord-name) (markup?)
>"Display a chord name in the desired formatting"
>(interpret-markup layout props 
>  (make-line-markup (#:sans (#:fontsize 10 chord-name)
>
>
> \markup \chord-name-markup "E"
>
> %%% end of code
>
> I've used displayScheme to get the representation of the markup
> function.  I've found that is uses #:line so that I have to use
> make-line-markup.

#:sans is garbage outside of the markup macro.  Also make-line-markup
requires a list as its argument.

Your original
\markup{\sans{\fontsize #10 "C"}}

contains two levels of spurious braces.  Those generate spurious markup
lists causing LilyPond to intersperse a \line call for converting back
to a single markup.

Any reason you don't use #{ \markup ... #} for constructing your markup?
That way you don't need to replace LilyPond's expertise for constructing
markups with your own.

-- 
David Kastrup

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


Re: Trouble defining markup functiion

2019-01-17 Thread Aaron Hill

On 2019-01-17 6:27 am, Carl Sorensen wrote:

I'm trying to define a markup function for establishing a common set
of formatting for a number of text markups.

%%% beginning of sample code

\version "2.19.82"

\displayScheme
\markup{\sans{\fontsize #10 "C"}}  % Just used to show the scheme
markup command -- this is what I'm trying

#(define-markup-command  (chord-name-markup layout props chord-name) 
(markup?)

   "Display a chord name in the desired formatting"
   (interpret-markup layout props
 (make-line-markup (#:sans (#:fontsize 10 chord-name)


\markup \chord-name-markup "E"

%%% end of code

I've used displayScheme to get the representation of the markup
function.  I've found that is uses #:line so that I have to use
make-line-markup.

When I run this code, I get

Processing
`/var/folders/q5/88k2s1717qv1v7rq4tqz53k8gn/T/frescobaldi-fmnvoopw/tmpc0ltmn4y/document.ly'
Parsing.../var/folders/q5/88k2s1717qv1v7rq4tqz53k8gn/T/frescobaldi-fmnvoopw/tmpc0ltmn4y/document.ly:9:32:
In expression (#:fontsize 10 chord-name):
/var/folders/q5/88k2s1717qv1v7rq4tqz53k8gn/T/frescobaldi-fmnvoopw/tmpc0ltmn4y/document.ly:9:32:
Wrong type to apply: #:fontsize

Apparently, in the context of make-line-markup I can't use #:fontsize
as the first element in a list, because it's not applyable.

How can I do this properly?


I would sidestep trying to do the markup in pure Scheme and use #{ #} 
instead:



#(define-markup-command  (chord-name-markup layout props chord-name) 
(markup?)

   "Display a chord name in the desired formatting"
   (interpret-markup layout props
 #{ \markup \sans \fontsize #10 $chord-name #}))


NOTE: I omitted some of the curly braces, since they were not needed.


-- Aaron Hill

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


Getting spanner length

2019-01-17 Thread Leo Correia de Verdier
Dear list!

I’m all new to lily pond and trying to create a custom spanner (a couple of
parallel lines connecting some of the holes of two fingering charts). To
hack this together I would need the length of the spanner I’m modifying or
replacing. I’ve put this piece of code together to extract it and can’t
understand what mistake I’ve made:

\version "2.18.2"
\relative c'' {
  \once \override TextSpanner.stencil =
  #(lambda (grob)
 (let (grob-X (interval-length (ly:stencil-extent (ly:grob-property
grob 'stencil) X)))
   (make-line-stencil .2 1 1 grob-X 4)
   )
 )
  d \startTextSpan
  c b
  a \stopTextSpan
}


I attempted to abstract it from this piece of code
https://www.mail-archive.com/lilypond-user@gnu.org/msg81685.html

Do you have any other sources or better suggestions for custom spanners?
This doesn’t have to be very complex or be able to cover line breaks.

Thanks a lot!

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


Re: Getting spanner length

2019-01-17 Thread Aaron Hill

On 2019-01-17 6:43 am, Leo Correia de Verdier wrote:

Dear list!

I’m all new to lily pond and trying to create a custom spanner (a 
couple of
parallel lines connecting some of the holes of two fingering charts). 
To
hack this together I would need the length of the spanner I’m modifying 
or

replacing. I’ve put this piece of code together to extract it and can’t
understand what mistake I’ve made:

\version "2.18.2"
\relative c'' {
  \once \override TextSpanner.stencil =
  #(lambda (grob)
 (let (grob-X (interval-length (ly:stencil-extent (ly:grob-property
grob 'stencil) X)))
   (make-line-stencil .2 1 1 grob-X 4)
   )
 )
  d \startTextSpan
  c b
  a \stopTextSpan
}


I attempted to abstract it from this piece of code
https://www.mail-archive.com/lilypond-user@gnu.org/msg81685.html

Do you have any other sources or better suggestions for custom 
spanners?

This doesn’t have to be very complex or be able to cover line breaks.


Two issues:

- You are missing a set of parentheses for the let statement.
- You are attempting to query a grob property from within the property.

Try this:


\version "2.18.2"
\relative c'' {
  \once \override TextSpanner.stencil =
  #(lambda (grob)
 (let ((grob-X (interval-length
(ly:stencil-extent (ly:line-spanner::print grob) X
   (make-line-stencil .2 1 1 grob-X 4)))
  d \startTextSpan
  c b
  a \stopTextSpan
}



-- Aaron Hill

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


Re: System spacing for Certain

2019-01-17 Thread Reggie
Aaron Hill wrote
> On 2019-01-16 5:24 pm, Reggie wrote:
>> First, are you saying that every time I want to manually adjust one 
>> staff in
>> a system in one instance I must create a new voice just to hack this? 
>> Like
>> you did? What about my original code itself used?
> 
> You do not need the extra voice.  I did that simply because the advice 
> in the notation reference is sound to follow.  One should try to keep 
> matters of presentation (such as spacing) completely separate from the 
> musical content.  It can muddy a score to have things like that messy 
> \overrideProperty stuck in the middle of notes.  Additionally, it makes 
> it much harder to reuse musical content in different contexts without 
> resorting to tags.
> 
> That all said, you can easily apply the \verticalSpacer to a musical 
> note in your staff rather than on a spacer in a separate voice.
> 
>> Second, you mention that
>> it's relative from PRIOR staff right? What if I want to move the top 
>> staff
>> of a system up or down only for example as such?
> 
> Technically, alignment-distances specifies the values *between* the 
> staves, so it doesn't affect space before the first or after the last.  
> In that case, you'd probably have to use something like extra-offset to 
> shift the entire system upwards or downwards, which is basically what 
> shifting the first staff would mean.
> 
> If we're talking about the placeholder markup, simply use 
> ^\verticalSpacer so the markup appears above the staff in question.  
> This would work on a first staff of a system and force it to appear 
> further down on the paper.
> 
> 
> -- Aaron Hill
> 
> ___
> lilypond-user mailing list

> lilypond-user@

> https://lists.gnu.org/mailman/listinfo/lilypond-user

Thank you Aaron. However I also meant asking about the top staff of a system
moving UP as well. So imagine you want to bump up a top staff of a system
without moving other staffs in system. How so accomplish?




--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

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


Re: select a note in a chord

2019-01-17 Thread Davide Bonetti

I worked on your example, and here is the result.

The "\drop n" function drop the nth note from above, an can be nested 
(to do drop 2 drop 4)


The funcion "\rise n" function rise the nth note from below, an can be 
nested too


The "\inversion n" function do the inversions of the chord.

I'm sure there is a better way to write the inversion function, but I 
haven't find a way to program the repetition of a function in scheme.


%


#(define (move-a-note n direction)
   (lambda (music)
 (let* ((elts (ly:music-property music 'elements))
    (l (length elts))
    ;; if the direction is up, we count from the bottom note 
upward,
    ;; if the direction is down, we count from the top note 
downward

    (count-from (cond ((= direction up) (- n 1))
  ((= direction down) (- l n
    ;; The user may not have entered the notes
    ;; from the lowest to the uppermost;
    ;; let’s extract the pitches…
    (pitches (map (lambda (x) (ly:music-property x 'pitch))
   (filter
    (lambda (y)
  (music-is-of-type? y 'note-event))
    elts)))
    ;; … and put them in order.
    (sorted (sort pitches ly:pitch= l n))
   (begin
    ;; first apply the sorted pitches
    ;; to the actual notes.
    (map
 (lambda (e p)
   (ly:music-set-property! e 'pitch p))
 elts sorted)
    ;; then transpose the specified note
    (list-set! elts count-from
  (ly:music-transpose
   (list-ref elts count-from)
   (ly:make-pitch (cond
   ;; transpose the note up or down,
   ;;depending on direction
   ((= direction up) +1)
   ((= direction down) -1)) 0)
   music)))

%% drop a note of a chord, in num position from above
drop =
#(define-music-function (parser location num music) (integer? ly:music?)
   #{ \musicMap #(move-a-note num down) $music #})

%% rise a note of a chord, in num position from below
rise =
#(define-music-function (parser location num music) (integer? ly:music?)
   #{ \musicMap #(move-a-note num up) $music #})

inversion =
#(define-music-function (parser location num music) (integer? ly:music?)
   (cond ((= num 1) #{ \rise 1 $music #})
 ((= num 2) #{ \rise 1 \rise 1 $music #})
 ((= num 3) #{ \rise 1 \rise 1 \rise 1 $music #})
 ((= num 4) #{ \rise 1 \rise 1 \rise 1 \rise 1 $music #})
 ((= num 5) #{ \rise 1 \rise 1 \rise 1 \rise 1 \rise 1 $music #})
 ((= num 6) #{ \rise 1 \rise 1 \rise 1 \rise 1 \rise 1 \rise 1 
$music #})

 ((= num -1) #{ \drop 1 $music #})
 ((= num -2) #{ \drop 1 \drop 1 $music #})
 ((= num -3) #{ \drop 1 \drop 1 \drop 1 $music #})
 ((= num -4) #{ \drop 1 \drop 1 \drop 1 \drop 1 $music #})
 ((= num -5) #{ \drop 1 \drop 1 \drop 1 \drop 1 \drop 1 $music #})
 ((= num -6) #{ \drop 1 \drop 1 \drop 1 \drop 1 \drop 1 \drop 1 
$music #})

 (else #{ $music #})
 ))


ac = \relative c' {2  \chordmode {c:maj es:6}}

{
  <>^\markup "chords"
  \ac
  \bar "||"
  <>^\markup "drop 2"
  \drop 2 \ac
  \bar "||"
  <>^\markup "drop 4"
  \drop 4 \ac
  \bar "||"
  <>^\markup "drop 2 and 4"
  \drop 2 \drop 4 \ac
  \bar "||"
  <>^\markup "rise 1"
  \rise 1 \ac
  \bar "||"
  <>^\markup "rise 3"
  \rise 3 \ac
  \bar "||"
  <>^\markup "2nd inversion"
  \inversion 2 \ac
  \bar "||"
  <>^\markup "\"down\" inversion"
  \inversion -1 \ac
  \bar "||"
}

%

Cheers.
Davide

Il 16/01/2019 00:15, David Kastrup ha scritto:

Valentin Villenave  writes:


On 1/15/19, Davide Bonetti  wrote:

I modified
 (if (and (music-is-of-type? music 'event-chord)
  (> l n))
with
 (if (and (music-is-of-type? music 'event-chord)
  (>= l n))

Nice catch! I’ve updated the snippet as well.

Additionally, beware that the LSR version uses
#(define-music-function (parser location music)
whereas the syntax for LilyPond 2.19 would be
#(define-music-function (music)

Not much to beware here since convert-ly knows its way around this and
2.19 will do argument counting in order to provide backwards
compatibility.




---
Questa e-mail è stata controllata per individuare virus con Avast antivirus.
https://www.avast.com/antivirus

#(define (move-a-note n direction)
   (lambda (music)
 (let* ((elts (ly:music-property music 'elements))
(l (length elts))
;; if the direction is up, we count from the bottom note upward,
;; if the direction is down, we count from the top note downward
;; (strangely, jazzmen tend to
;; count from the top note downward).
(count-from (cond ((= direction up) (- n 1))
  ((

Re: setting fretboard diagrams at the top of the page

2019-01-17 Thread Carl Sorensen
Hi Evan,

Welcome to LilyPond!

On 1/15/19, 11:10 AM, "Evan Levine"  wrote:

Good afternoon! I've got a few things I'm brewing right now, but the 
most pressing is that I'm looking to set all of the chord diagrams for a 
lead sheet at the top of the page under the title, and modify the 
spacing of the diagrams to be centered on the page and have padding 
between each diagram.

The key here, in my opinion, is to set the fret diagrams as markups, rather 
than as music.   

Thanks so much! Here's my code:

Great job on providing a small example!  That was helpful to see what you 
intended.

The only problem with the example is that it wouldn't completely compile, 
because the music and lyrics were missing.  It's much easier if you provide 
those.


Please forgive me for any oversight of the protocol here, as this is my 
first interaction with the mailing list.

The only oversight I see is that you put your mail at the top of another 
unrelated post.  Please don't post your reply to the top of a full post, and 
when you start a new thread, don't do it by replying to a previous post.  

With that said, here's how I'd attack your problem.  I've created some markup 
functions to allow you to have control over size, spacing, etc.

 Beginning of sample code

\version "2.19.82"

\header {
  title = "Steven Universe Theme"
  composer = "Rebecca Sugar, Aivi & Surasshu"
  tagline = ##t
}

#(define chord-name-fontsize 6)
#(define name-fretboard-separation .75)
#(define different-separation 8)
#(define same-separation 2)
#(define or-vspace 1.75)

#(define fret-formatting "s:2.2;w:4;h:3;d:0.37;f:1;")

#(define c-fret "4-x;3-4-2;2-3-2;1-x;")
#(define e-one-fret "c:4-2-4;4-4-3;3-4-3;2-4-3;1-x;")
#(define e-two-fret "4-x;3-4-2;2-4-3;1-2-1;")
#(define f-fret "4-x;3-5-2;2-5-3;1-3-1;")
#(define fm-fret "4-x;3-5-2;2-4-3;1-3-1;")

#(define-markup-command  (chord-name-markup layout props chord-name) 
   (markup?)
   "Display a chord name in the desired formatting"
   (interpret-markup layout props 
#{ \markup \sans \fontsize #chord-name-fontsize $chord-name #} ))

#(define-markup-command (name-and-fret-markup layout props chord-name 
fret-diagram)
   (markup? markup?)
   "Display a chord name and fretboard as stacked markups separated by 
name-fretboard-separation"
   (interpret-markup layout props
 #{ \markup \center-column {
  \chord-name-markup $chord-name
  \vspace #name-fretboard-separation
  $fret-diagram
}
 #}))
  
 #(define-markup-command (or-markup layout props or-text)
   (markup?)
   "Display a separator between alternative fretboards"
   (interpret-markup layout props
 #{ \markup \center-column {
  \vspace #or-vspace
  \chord-name-markup $or-text
}
 #}))
  
\markup \line {
  \name-and-fret-markup "C"  \fret-diagram #(string-append fret-formatting 
c-fret)
  \hspace #different-separation
  \center-column {
\name-and-fret-markup "E" \line {
  \fret-diagram #(string-append fret-formatting e-one-fret)
  \hspace #same-separation
  \or-markup "or"
  \hspace #same-separation
  \fret-diagram#(string-append fret-formatting e-two-fret)
  \hspace #same-separation
  \or-markup "or"
  \hspace #same-separation
  \fret-diagram#(string-append fret-formatting e-two-fret)
}
  }
  \hspace #different-separation
  \name-and-fret-markup "F"  \fret-diagram #(string-append fret-formatting 
f-fret)
  \hspace #different-separation
  \center-column {
\name-and-fret-markup "Fm"  \fret-diagram #(string-append fret-formatting 
fm-fret)
  } 

}


\score {
  <<
\new ChordNames {
  c1 e f c f
}
  \new Staff {
\new Voice = "melody" {
\repeat unfold 5 {c'4 d' e' f'}
}
  }
\new Lyrics {
  \lyricsto "melody" {
  \repeat unfold 5 {tra la la la }
  }
}
  >>
}

 end of sample code 

HTH,

Carl


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


Re: Trouble defining markup functiion

2019-01-17 Thread Carl Sorensen
On 1/17/19, 8:02 AM, "David Kastrup"  wrote:

>
> I've used displayScheme to get the representation of the markup
> function.  I've found that is uses #:line so that I have to use
> make-line-markup.

#:sans is garbage outside of the markup macro.  Also make-line-markup
requires a list as its argument.

That's what I thought, but I couldn't find it documented.

Your original
\markup{\sans{\fontsize #10 "C"}}

contains two levels of spurious braces.  Those generate spurious markup
lists causing LilyPond to intersperse a \line call for converting back
to a single markup.

I thought I copied that code from the NR, but I can't find it, so I must not 
have.

Any reason you don't use #{ \markup ... #} for constructing your markup?
That way you don't need to replace LilyPond's expertise for constructing
markups with your own.

Only because of ignorance.  The last time I spent serious time writing markup 
functions, #{ ... #} wasn't available.  Thanks for pointing it out to me, and 
again reminding me how much your work has improved the usability of LilyPond!

On 1/17/19, 8:05 AM, "Aaron Hill"  wrote:


I would sidestep trying to do the markup in pure Scheme and use #{ #} 
instead:


#(define-markup-command  (chord-name-markup layout props chord-name) 
(markup?)
"Display a chord name in the desired formatting"
(interpret-markup layout props
  #{ \markup \sans \fontsize #10 $chord-name #}))


Thanks for the help, Aaron.  As both you and David mentioned, that was the 
right way to go about it.

Thanks,

Carl


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


Re: Trouble defining markup functiion

2019-01-17 Thread David Kastrup
Carl Sorensen  writes:

> On 1/17/19, 8:02 AM, "David Kastrup"  wrote:
>
> >
> > I've used displayScheme to get the representation of the markup
> > function.  I've found that is uses #:line so that I have to use
> > make-line-markup.
> 
> #:sans is garbage outside of the markup macro.  Also make-line-markup
> requires a list as its argument.
>
> That's what I thought, but I couldn't find it documented.

It's probably more implied than documented.

> Your original
> \markup{\sans{\fontsize #10 "C"}}
> 
> contains two levels of spurious braces.  Those generate spurious markup
> lists causing LilyPond to intersperse a \line call for converting back
> to a single markup.
>
> I thought I copied that code from the NR, but I can't find it, so I
> must not have.

Or it has been simplified in the mean time.

> Any reason you don't use #{ \markup ... #} for constructing your markup?
> That way you don't need to replace LilyPond's expertise for constructing
> markups with your own.
> 
> Only because of ignorance.  The last time I spent serious time writing
> markup functions, #{ ... #} wasn't available.

For markups.

> Thanks for pointing it out to me, and again reminding me how much your
> work has improved the usability of LilyPond!

Well, this approach calls the parser at runtime.  Certainly less
efficient than calling a macro (which usually is already called at
compile time anyway).

This does not really increase usability (you cannot actually do more
than you could do without) but it does lower the barrier of entry and
gives more experienced developers a chance to "solve" other people's
problems in a manner where they don't need to frequently visit the
mailing lists for what amounts to elaboration on the same kind of
question.  Which does improve the usability of the mailing lists.

Basically it's flush mounting of LilyPond's wiring.  More complex than
on-wall mounting, worse when maintenance is needed, but users don't keep
stumbling over and tearing stuff.  Until they try hanging up pictures,
of course.

-- 
David Kastrup

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


Re: select a note in a chord

2019-01-17 Thread Valentin Villenave
On 1/17/19, Davide Bonetti  wrote:
> I worked on your example, and here is the result.

Nice!

> I'm sure there is a better way to write the inversion function, but I
> haven't find a way to program the repetition of a function in scheme.

This is certainly not the most elegant way, but it seems to work:

inversion =
#(define-music-function (num music) (integer? ly:music?)
   (let ((str "")
 (up? (> num 0)))
 (map (lambda (x)
(set! str
  (string-append str
(if up? "\\rise 1 " "\\drop 1 ")))
str)
   (iota (abs num)))
 #{ $(ly:parser-include-string str) $music #}))

Can you verify that it works as you intended? (If you’re running 2.18,
you’ll need to add "parser" after ly:parser-include-string.)

Cheers,
V.

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


Re: select a note in a chord

2019-01-17 Thread David Kastrup
Valentin Villenave  writes:

> On 1/17/19, Davide Bonetti  wrote:
>> I worked on your example, and here is the result.
>
> Nice!
>
>> I'm sure there is a better way to write the inversion function, but I
>> haven't find a way to program the repetition of a function in scheme.
>
> This is certainly not the most elegant way, but it seems to work:
>
> inversion =
> #(define-music-function (num music) (integer? ly:music?)
>(let ((str "")
>  (up? (> num 0)))
>  (map (lambda (x)
> (set! str
>   (string-append str
> (if up? "\\rise 1 " "\\drop 1 ")))
> str)
>(iota (abs num)))

There is append-map but seriously?

  (string-concatenate (make-list (abs num)
 (if (negative? num) "\\drop 1 " "\\rise 1 ")))


>  #{ $(ly:parser-include-string str) $music #}))

This is not really an issue for string-manipulation.

> Can you verify that it works as you intended? (If you’re running 2.18,
> you’ll need to add "parser" after ly:parser-include-string.)

And parser location before num in (num music).

Let's rather do this in a sane manner:

inversion =
#(define-music-function (num music) (integer? ly:music?)
  (let loop ((num num) (music music))
 (cond ((zero? num) music)
   ((negative? num) (loop (1+ num) (drop 1 music))
   (else (loop (1- num) (rise 1 music)))

Assuming 2.18, music functions are not directly callable from Scheme
which would render this as

inversion =
#(define-music-function (parser location num music) (integer? ly:music?)
  (let loop ((num num) (music music))
 (cond ((zero? num) music)
   ((negative? num) (loop (1+ num) #{ \drop 1 #music #}))
   (else (loop (1- num) #{ \rise 1 #music #})

This does not mess with internal parsers.  And the 2.19 version does not
even engage the parser for the looping.

-- 
David Kastrup

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


Re: select a note in a chord

2019-01-17 Thread Valentin Villenave
On 1/18/19, David Kastrup  wrote:
> This is not really an issue for string-manipulation.

Agreed. Nevertheless, I was pleasantly surprised to see that
ly:parser-include-string could accept an incomplete expression.
(Previously, ly:parser-parse-string would have been much less flexible
here.)

> Let's rather do this in a sane manner:

Indeed, a named "let" loop is clearly the preferred way to go!

That being said, I still wonder if there’d be any way of making it
work with either iota or make-list without having to go through string
manipulations. (It would remove the need for a loop with an
incremented counter.)

And btw, why does mapping onto (iota num) require a lambda (x)
function even though that x argument does absolutely nothing? My
instinct would be to use lambda (), but that throws an error.

>((negative? num) (loop (1+ num) #{ \drop 1 #music #}))
>(else (loop (1- num) #{ \rise 1 #music #})

Why #music and not $music inside the #{ #}? (I suspect there’s no
difference in this case, but $music is the more familiar syntax
inherited from before your parser/lexer improvements.)

V.

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


Re: select a note in a chord

2019-01-17 Thread David Kastrup
Valentin Villenave  writes:

> On 1/18/19, David Kastrup  wrote:
>> This is not really an issue for string-manipulation.
>
> Agreed. Nevertheless, I was pleasantly surprised to see that
> ly:parser-include-string could accept an incomplete expression.
> (Previously, ly:parser-parse-string would have been much less flexible
> here.)
>
>> Let's rather do this in a sane manner:
>
> Indeed, a named "let" loop is clearly the preferred way to go!
>
> That being said, I still wonder if there’d be any way of making it
> work with either iota or make-list without having to go through string
> manipulations. (It would remove the need for a loop with an
> incremented counter.)

You can use something like
(fold (if (negative? num) drop rise)
  music
  (make-list (abs num) 1))

but I don't like creating lists for the sake of controlling loop size.

> And btw, why does mapping onto (iota num) require a lambda (x)
> function even though that x argument does absolutely nothing? My
> instinct would be to use lambda (), but that throws an error.

You cannot call functions with a different number of arguments than they
are defined.  A map is a _map_.  Of course it takes an argument.  If you
want to express "this function ignores whatever arguments it may
receives" you can write (lambda _ ... ) and the whole argument list
would be assigned to _ (by convention a subsequently ignored binding).

>>((negative? num) (loop (1+ num) #{ \drop 1 #music #}))
>>(else (loop (1- num) #{ \rise 1 #music #})
>
> Why #music and not $music inside the #{ #}? (I suspect there’s no
> difference in this case, but $music is the more familiar syntax
> inherited from before your parser/lexer improvements.)

#music is an as-is Scheme expression, $music is evaluated and copied
before assigning a syntactical category.  If you aren't using the
expression elsewhere, those copies are unnecessary.

I mean, it's documented.  The "Extending LilyPond Guide" has this to
say:


1.2.1 LilyPond Scheme syntax


The Guile interpreter is part of LilyPond, which means that Scheme can
be included in LilyPond input files.  There are several methods for
including Scheme in LilyPond.

   The simplest way is to use a hash mark ‘#’ before a Scheme
expression.

   Now LilyPond’s input is structured into tokens and expressions, much
like human language is structured into words and sentences.  LilyPond
has a lexer that recognizes tokens (literal numbers, strings, Scheme
elements, pitches and so on), and a parser that understands the syntax,
*note (lilypond-contributor)LilyPond grammar::.  Once it knows that a
particular syntax rule applies, it executes actions associated with it.

   The hash mark ‘#’ method of embedding Scheme is a natural fit for
this system.  Once the lexer sees a hash mark, it calls the Scheme
reader to read one full Scheme expression (this can be an identifier, an
expression enclosed in parentheses, or several other things).  After the
Scheme expression is read, it is stored away as the value for an
‘SCM_TOKEN’ in the grammar.  Once the parser knows how to make use of
this token, it calls Guile for evaluating the Scheme expression.  Since
the parser usually requires a bit of lookahead from the lexer to make
its parsing decisions, this separation of reading and evaluation between
lexer and parser is exactly what is needed to keep the execution of
LilyPond and Scheme expressions in sync.  For this reason, you should
use the hash mark ‘#’ for calling Scheme whenever this is feasible.

   Another way to call the Scheme interpreter from LilyPond is the use
of dollar ‘$’ instead of a hash mark for introducing Scheme expressions.
In this case, LilyPond evaluates the code right after the lexer has read
it.  It checks the resulting type of the Scheme expression and then
picks a token type (one of several ‘xxx_IDENTIFIER’ in the syntax) for
it.  It creates a _copy_ of the value and uses that for the value of the
token.  If the value of the expression is void (Guile’s value of
‘*unspecified*’), nothing at all is passed to the parser.

   This is, in fact, exactly the same mechanism that LilyPond employs
when you call any variable or music function by name, as ‘\name’, with
the only difference that the name is determined by the LilyPond lexer
without consulting the Scheme reader, and thus only variable names
consistent with the current LilyPond mode are accepted.

   The immediate action of ‘$’ can lead to surprises, see *note
Importing Scheme in LilyPond::.  Using ‘#’ where the parser supports it
is usually preferable.  Inside of music expressions, expressions created
using ‘#’ _are_ interpreted as music.  However, they are _not_ copied
before use.  If they are part of some structure that might still get
used, you may need to use ‘ly:music-deep-copy’ explicitly.


-- 
David Kastrup

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

Re: select a note in a chord

2019-01-17 Thread David Kastrup
David Kastrup  writes:

> Valentin Villenave  writes:
>
>> On 1/18/19, David Kastrup  wrote:
>>> This is not really an issue for string-manipulation.
>>
>> Agreed. Nevertheless, I was pleasantly surprised to see that
>> ly:parser-include-string could accept an incomplete expression.
>> (Previously, ly:parser-parse-string would have been much less flexible
>> here.)
>>
>>> Let's rather do this in a sane manner:
>>
>> Indeed, a named "let" loop is clearly the preferred way to go!
>>
>> That being said, I still wonder if there’d be any way of making it
>> work with either iota or make-list without having to go through string
>> manipulations. (It would remove the need for a loop with an
>> incremented counter.)
>
> You can use something like
> (fold (if (negative? num) drop rise)
>   music
>   (make-list (abs num) 1))
>
> but I don't like creating lists for the sake of controlling loop size.

By the way: `drop' is a function imported from (slri slri-1) and it's
probably not a good idea to redefine it.

-- 
David Kastrup

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


Springs and rods

2019-01-17 Thread Andrew Bernard
Yet another annoying question about documentation from me.

After figuring out how to make a glissando longer, and discovering this in
the NR under the spanner interface:

minimum-length (dimension, in staff space)
Try to make a spanner at least this long, normally in the horizontal
direction. This requires an appropriate callback for the springs-and-rods
property. If added to a Tie, this sets the minimum distance between
noteheads.

I can only ask and I think reasonably where is this mystical
springs-and-rods mechanism explained? Why does one need to do this:

  \override Glissando #'minimum-length = #4
  \override Glissando #'springs-and-rods = #ly:spanner::set-spacing-rods

How is one meant to know what an 'appropriate callback is'? What other
callback would one use? And what for?

I have to honestly say that if I could ever understand the lilypond
internals I would readily volunteer to rewrite these sections in the NR,
which occur far too often I am afraid. I've been using lilypond heavily for
years, and sections like this simply make me feel dumb. Perhaps I missed
something fundamental along the learning curve.

None of this criticism is aimed at any person. I am well aware this sort of
manual is reference and not tutorial. There used to be a series of computer
publications called [X]: The Missing Manual. I feel we need the missing
manual for lilypond. I don't know enough to write it.

All help most appreciated.

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