Hi David,

2012/2/20 David Kastrup <d...@gnu.org>:

>> Furthermore, I realized, that there seems to be no conversion rule for
>> the following 2.12.3-definitions:
>>
>> From 2.12.3:  \scm\lily-library.scm
>>
>>    (define (interval-translate iv amount)
>>      (cons (+ amount (car iv))
>>       (+ amount (cdr iv))))
>
> It's used in snippets?  Ugh.

http://lsr.dsi.unimi.it/LSR/Item?id=700 by Neil Puttock

< Probably easiest to put that back in and
> document it, then.

I reintegrated the interval-translate-definition into the file
->attached my manual update

> Is there a known replacement?

Don't know.

>
>> From 2.12.3:  \ly\markup-init.ly
>>
>> #(define-public toplevel-module-define-public! #f)
>> #(define-public toplevel-module-ref #f)
>
> Those can be replaced by their straightforward counterpart.  Where are
> they used?

http://lsr.dsi.unimi.it/LSR/Item?id=657
I reintegrated the old definitions, too.  ->attached my manual update
I don't know about their counterpart.

>
>> And of course any 2.14.2-chordRootNamer-definition expects two
>> arguments now. I've no idea how that could be covered by converting
>> rules.
>
> Give a before/after example.  It might be more reliable to actually just
> let the function deal with it via an optional argument,

In http://lsr.dsi.unimi.it/LSR/Search?q=chordRootNamer I simple added
the non-functional argument lowercase? to the definition. -> attached
my manual update
Or should I try to competely rewrite this snippet due to the new possibillities?

< but it is not
> inconceivable to write conversion rules either.  If you take a look at
> convertrules.py, you'll see that I did some rather heavy lifting inside
> of Scheme constructs for dealing with ly:export.  It is not the same as
> doing compatibility in Scheme itself, but it was sufficient for the
> LilyPond repository.

Will have a look at it.


Cheers,
  Harm
\version "2.14.0"

\header {
  texidoc = "
Staff lines can be colored independently by overriding the default
stencil for @code{StaffSymbol}.

The @code{StaffSymbol} callback @code{color-staff-lines} takes a set of
colors (using LilyPond's predefined colors or the functions
@code{x11-color} and @code{rgb-color}) which are applied to each staff
line in turn starting with the fifth line (for a standard staff), or
each item in the list for custom staves defined with
@code{line-positions}.  To signal that a particular line between
colored lines should remain black, use @code{#f}. 

"
  doctitle = "Coloring individual staff lines"
}
%LSR This snippet was contributed by Neil Puttock

#(define-public ((color-staff-lines . rest) grob)

   (define (index-cell cell dir)
     (if (equal? dir RIGHT)
         (cdr cell)
         (car cell)))

   (define (index-set-cell! x dir val)
     (case dir
       ((-1) (set-car! x val))
       ((1) (set-cdr! x val))))
   
;;;; Definition added!
   (define (interval-translate iv amount)
     (cons (+ amount (car iv))
     	(+ amount (cdr iv))))

   (let* ((common (ly:grob-system grob))
          (span-points '(0 . 0))
          (thickness (* (ly:grob-property grob 'thickness 1.0)
                        (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness)))
          (width (ly:grob-property grob 'width))
          (line-positions (ly:grob-property grob 'line-positions))
          (staff-space (ly:grob-property grob 'staff-space 1))
          (line-stencil #f)
          (total-lines empty-stencil)
          ;; use a local copy of colors list, since
          ;; stencil creation mutates list
          (colors rest))

     (for-each
      (lambda (dir)
        (if (and (= dir RIGHT)
                 (number? width))
            (set-cdr! span-points width)
            (let* ((bound (ly:spanner-bound grob dir))
                   (bound-ext (ly:grob-extent bound bound X)))
              
              (index-set-cell! span-points dir
                               (ly:grob-relative-coordinate bound common X))
              (if (and (not (ly:item-break-dir bound))
                       (not (interval-empty? bound-ext)))
                  (index-set-cell! span-points dir 
                                   (+ (index-cell span-points dir)
                                      (index-cell bound-ext dir))))))
        (index-set-cell! span-points dir (- (index-cell span-points dir)
                                            (* dir thickness 0.5))))
      (list LEFT RIGHT))

     (set! span-points
           (interval-translate span-points
                            (- (ly:grob-relative-coordinate grob common X))))
     (set! line-stencil
           (make-line-stencil thickness (car span-points) 0 (cdr span-points) 0))

     (if (pair? line-positions)
         (for-each (lambda (position)
                     (let ((color (if (pair? colors)
                                      (car colors)
                                      #f)))
                       (set! total-lines
                             (ly:stencil-add
                              total-lines
                              (ly:stencil-translate-axis
                               (if (color? color)
                                   (ly:stencil-in-color line-stencil
                                                        (first color)
                                                        (second color)
                                                        (third color))
                                   line-stencil)
                               (* position staff-space 0.5) Y)))
                       (and (pair? colors)
                            (set! colors (cdr colors)))))
                   line-positions)       
         (let* ((line-count (ly:grob-property grob 'line-count 5))
                (height (* (1- line-count) (/ staff-space 2))))
           (do ((i 0 (1+ i)))                      
               ((= i line-count))
             (let ((color (if (and (pair? colors)
                                   (> (length colors) i))
                              (list-ref colors i)
                              #f)))
               (set! total-lines (ly:stencil-add
                                  total-lines
                                  (ly:stencil-translate-axis
                                   (if (color? color)
                                       (ly:stencil-in-color line-stencil
                                                            (first color)
                                                            (second color)
                                                            (third color))
                                       line-stencil)
                                   (- height (* i staff-space)) Y)))))))
     total-lines))

\relative c' {
  % color all lines in a standard five-line staff
  \override Staff.StaffSymbol #'stencil = #(color-staff-lines red green yellow blue cyan)
  c1 \stopStaff
  \revert Staff.StaffSymbol #'stencil

  \startStaff
  % color the fifth, third and second lines only
  \override Staff.StaffSymbol #'stencil = #(color-staff-lines (rgb-color 0 0.3 0.8) #f grey (x11-color 'LightGreen))
  c1 \stopStaff
  \revert Staff.StaffSymbol #'stencil

  \startStaff
  % color an individual line in a custom staff
  \override Staff.StaffSymbol #'line-positions = #'(-4 0 4)
  \override Staff.StaffSymbol #'stencil = #(color-staff-lines #f red)
  c1 
}

\version "2.14.0"

\header {
  texidoc = "
Some files of definitions should be included only once in a project,
but they need to be mentioned by all of the files that require them.

I defined \\includeIfAbsent to include a file if and only if it has not
already been included by \\includeIfAbsent. It works in a different
scope from \\include, so definitions in the included file need to be
made global with define-public-toplevel in order to be effective.

"
  doctitle = "Including a file only once"
}
% Will not work in 2.13 or later since define-public-toplevel has been removed

% Include a file unless it has already been included.  This executes
% in a cloned parser, so all definitions in the included file need to
% be made global with define-public-toplevel.  Include seems to be
% implemented in the lexical analyzer, and I don't see how to do it
% properly at a higher level.  Executing in the main parser appears to
% have the right effect, and produce all desired output, but LilyPond
% ends with a segmentation fault.

%
% In the included file, do lilypond variable defintion
%
%      var = <stuff>
% as
%      #(define-public-toplevel var #{ <stuff> #} )
%
% music function definition
%
%      fname = #(define-music-function <stuff>)
% as
%      #(define-public-toplevel fname (define-music-function <stuff>))
%
% markup definition
%
%      var = \markup { <stuff> }
% as
%      #(define-public-toplevel var (markup <translated-stuff>))
%
% Using the translation described in the LilyPond Notation Manual
% section Markup-construction-in-Scheme
%

%%%% fixed reimplementing the relevant definitions from "2.12.3"
%%%% TODO ask Devs

#(define-public toplevel-module-define-public! #f)
#(define-public toplevel-module-ref #f)
#(let ((toplevel-module (current-module)))
   (set! toplevel-module-define-public!
         (lambda (symbol value)
           (module-define! toplevel-module symbol value)
           (module-export! toplevel-module (list symbol))))
   (set! toplevel-module-ref
         (lambda (symbol)
           (module-ref toplevel-module symbol))))

#(defmacro-public define-public-toplevel
   (first-arg . rest)
  "Define a public variable or function in the toplevel module:
  (define-public-toplevel variable-name value)
or:
  (define-public-toplevel (function-name . args)
    ..body..)"
  (if (symbol? first-arg)
      ;; (define-public-toplevel symbol value)
      (let ((symbol first-arg)
            (value (car rest)))
        `(toplevel-module-define-public! ',symbol ,value))
      ;; (define-public-toplevel (function-name . args) . body)
      (let ((function-name (car first-arg))
            (arg-list (cdr first-arg))
            (body rest))
        `(toplevel-module-define-public!
          ',function-name
          (let ((proc (lambda ,arg-list
                        ,@body)))
            (set-procedure-property! proc
                                     'name
                                     ',function-name)
            proc)))))

#(if (not (defined? 'includeIfAbsent))
          (define-public-toplevel includeIfAbsent(define-music-function (parser location fileName) (string?)

    (let ((guardName (string-append "Already Got " fileName)))

      (if (not (defined? (string->symbol guardName)))
        (begin

          (primitive-eval (list 'define (string->symbol guardName) #t))

          (ly:parser-parse-string (ly:parser-clone parser) (string-concatenate (list "\\include \"" fileName "\"")))

          (make-music 'SequentialMusic 'void #t))

        (make-music 'SequentialMusic 'void #t))))))

\markup {
  Pointless markup to avoid LSR rejecting the snippet for lack of output
}

\version "2.14.0"

\header {
  texidoc = "
For typesetting chords, LilyPond uses its internal accidentals (i.e. it
uses glyphs from the Feta font). This example shows how you can change
LilyPond's behaviour to use the accidentals \"#\" and \"b\" from the
currently selected font. This is useful if you'd like to use a font for
setting jazz chords in RealBook style.
"
  doctitle = "Use custom font's flat (b) and sharp (#) symbols for chords"
  
}

% correct markup for "b" and "#" (use symbols from current font...)
chordFlat = \markup { \hspace #0.2 \fontsize #-1 \raise #0.3 "b" }
chordSharp = \markup { \hspace #0.1 \fontsize #-1 \raise #0.3 "#" }

% define custom chords
myPopChordsMusic =
{
    <c es ges bes>-\markup { "m" \super { "7/" \chordFlat "5" } }
    <c e g bes dis'>-\markup { \super { "7/" \chordSharp "9" } }
    % ... define all other possible chords here...
}

% Add to existing exceptions
myPopChordsAdd = #(append (sequential-music-to-chord-exceptions myPopChordsMusic #t) ignatzekExceptions)

%% Ugly fix by simply adding lowercase? to the definition-args

% fix accidentals with some Scheme (using the current font's symbols)
#(define (my-chord-name->pop-markup pitch lowercase?)
  (let* ((alt (ly:pitch-alteration pitch)))
  (make-line-markup
    (list
      (make-simple-markup (vector-ref #("C" "D" "E" "F" "G" "A" "B") (ly:pitch-notename pitch)))
      ;; If it's natural, do nothing
      (if (= alt 0)
        (make-line-markup (list empty-markup))
        (if (= alt FLAT)
          ;; Otherwise, handle adding the flat symbol
          (make-line-markup
            (list
              (make-hspace-markup 0.3)
              (make-small-markup (make-raise-markup 0.7
                (make-text-markup "b")))
            ))
          ;; or handle adding the sharp symbol
          (make-line-markup
            (list
              (make-hspace-markup 0.1)
              (make-small-markup (make-raise-markup 0.7
                (make-text-markup "#")))
            ))
        )))))
)

\new Score
{
    \new ChordNames
    {
        % for demonstration purposes, use Arial as font
        % this does not look very nice, but shows the functionality

        \override ChordNames . ChordName  #'font-name = #"Arial"

        % use our new chord definitions (including the new accidentals)

        \set chordNameExceptions = #myPopChordsAdd

        % use our new markup chord naming functions to get the new accidentals

        \set chordRootNamer = #my-chord-name->pop-markup

        \chordmode { cis1:m7.5-  des1:7.9+ }
    }
}


% % use like this:
%
% {
%     popChords =
%     {
%         \set chordNameExceptions = #myPopChordsAdd
%         \set chordRootNamer = #my-chord-name->pop-markup
%     }
% }
% 
% % or like this:
%
% \layout
% {
%     \context
%     {
%         \Score
%         chordNameExceptions = #myPopChordsAdd
%         chordRootNamer = #my-chord-name->pop-markup
%     }
% }
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to