X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Fharp-pedals.scm;h=30fd1bf94361cf4cd9627f14e4d79574a0ba43c4;hb=42ae342ba877dc8f26cabb5cc3937a6d3cdb4066;hp=8f7756acbafb3e7b34e6e6038a951c66c9ed379d;hpb=338ddfdb1451f099f60b8da97a957c99696eb71c;p=lilypond.git diff --git a/scm/harp-pedals.scm b/scm/harp-pedals.scm index 8f7756acba..30fd1bf943 100644 --- a/scm/harp-pedals.scm +++ b/scm/harp-pedals.scm @@ -1,16 +1,27 @@ -;;;; harp-pedals.scm -- +;;;; This file is part of LilyPond, the GNU music typesetter. ;;;; -;;;; source file of the GNU LilyPond music typesetter +;;;; Copyright (C) 2008--2011 Reinhold Kainhofer ;;;; -;;;; (c) 2008 Reinhold Kainhofer +;;;; LilyPond is free software: you can redistribute it and/or modify +;;;; it under the terms of the GNU General Public License as published by +;;;; the Free Software Foundation, either version 3 of the License, or +;;;; (at your option) any later version. +;;;; +;;;; LilyPond is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with LilyPond. If not, see . -(define-builtin-markup-command (harp-pedal layout props definition-string) (string?) - instrument-specific-markup ; markup type for the documentation! - ((size 1.0) - (harp-pedal-details) - (thickness 0.5)) +(define-markup-command (harp-pedal layout props definition-string) (string?) + #:category instrument-specific-markup ; markup type for the documentation! + #:properties ((size 1.2) + (harp-pedal-details '()) + (thickness 0.5)) "Make a harp pedal diagram. Possible elements in @var{definition-string}: @@ -50,78 +61,8 @@ divider) and @code{space-after-divider} (box spacing after the divider). \\markup \\harp-pedal #\"^-v|--ov^\" @end lilypond " - (make-harp-pedal layout props (harp-pedals-parse-string definition-string))) - - -;; There is also a \harp-pedal-verbose version, which takes a list of -1/0/1 -;; directions, o and a possible |. It's commented out, because it has some -;; issues (see below) and does not add any new functionality over \harp-pedal -;; The caveats: -;; 1) the | cannot be given as a string "|" but as a character #\| and -;; the "o" has to be given as #\o. -;; 2) if one wants to use directions like UP, CENTER or DOWN, one cannot use -;; '(UP DOWN CENTER #\| ....), because the contents of that list are -;; never evaluated to -1/0/1. Instead one has to explicitly create a -;; list like (list UP DOWN CENTER #\| ....) -;; -;; (define-builtin-markup-command (harp-pedal-verbose layout props pedal-list) (list?) -;; instrument-specific-markup ; markup type -;; ((size 1.0) -;; (harp-pedal-details) -;; (thickness 0.5)) -;; "Make a harp pedal diagram containing the directions indicated in @var{pedal-list}." -;; (make-harp-pedal layout props pedal-list)) - - - -;; Parse the harp pedal definition string into list of directions (-1/0/1), #\o and #\| -(define (harp-pedals-parse-string definition-string) - "Parse a harp pedals diagram string and return a list containing 1, 0, -1, #\\o or #\\|" - (map (lambda (c) - (case c - ((#\^) 1) - ((#\v) -1) - ((#\-) 0) - ((#\| #\o) c) - (else c))) - (string->list definition-string))) - - -;; Analyze the pedal-list: Return (pedalcount . (divider positions)) -(define (harp-pedal-info pedal-list) - (let check ((pedals pedal-list) - (pedalcount 0) - (dividerpositions '())) - (if (null? pedals) - (cons pedalcount (reverse dividerpositions)) - - (case (car pedals) - ((-1 0 1) (check (cdr pedals) (+ pedalcount 1) dividerpositions)) - ((#\|) (check (cdr pedals) pedalcount (cons pedalcount dividerpositions))) - (else (check (cdr pedals) pedalcount dividerpositions)))))) - - -;; Sanity checks, spit out warning if pedal-list violates the conventions -(define (harp-pedal-check pedal-list) - "Perform some sanity checks for harp pedals (7 pedals, divider after third)" - (let ((info (harp-pedal-info pedal-list))) - ; 7 pedals: - (if (not (equal? (car info) 7)) - (ly:warning "Harp pedal diagram contains ~a pedals rather than the usual 7." (car info))) - ; One divider after third pedal: - (if (null? (cdr info)) - (ly:warning "Harp pedal diagram does not contain a divider (usually after third pedal).") - (if (not (equal? (cdr info) '(3))) - (ly:warning "Harp pedal diagram contains dividers at positions ~a. Normally, there is only one divider after the third pedal." (cdr info)))))) - - -(define (make-harp-pedal layout props pedal-list) - "Make a harp pedals diagram markup" - - (harp-pedal-check pedal-list) - - (let* ((size (chain-assoc-get 'size props 1.2)) - (details (chain-assoc-get 'harp-pedal-details props '())) + (let* ((pedal-list (harp-pedals-parse-string definition-string)) + (details (begin (harp-pedal-check pedal-list) harp-pedal-details)) (dy (* size (assoc-get 'box-offset details 0.8))) ; offset of the box center from the line (line-width (* (ly:output-def-lookup layout 'line-thickness) (chain-assoc-get 'thickness props 0.5))) @@ -129,12 +70,17 @@ divider) and @code{space-after-divider} (box spacing after the divider). (box-hheight (* size (/ (assoc-get 'box-height details 1.0) 2))) ; half the box-height, saves some divisions by 2 (spacebeforedivider (* size (assoc-get 'space-before-divider details 0.8))) ; full space between boxes before the first divider (spaceafterdivider (* size (assoc-get 'space-after-divider details 0.8))) ; full space between boxes - ;(spacebeforedivider (/ (+ box-width (* 8 spaceafterdivider)) 8)) + (circle-thickness (* (ly:output-def-lookup layout 'line-thickness) + (assoc-get 'circle-thickness details 0.5))) + (circle-x-padding (* size (assoc-get 'circle-x-padding details 0.15))) + (circle-y-padding (* size (assoc-get 'circle-y-padding details 0.2))) (box-x-dimensions (lambda (prev-x p space) (cons (+ prev-x space) (+ prev-x space box-width)))) (box-y-dimensions (lambda (prev-x p space) (cons (- (* p dy) box-hheight) (+ (* p dy) box-hheight)))) - (divider-stencil (lambda (xpos) (make-line-stencil line-width xpos (- 0 dy box-hheight) xpos (+ dy box-hheight)))) + (divider-stencil (lambda (xpos) (make-line-stencil line-width + xpos (- 0 dy box-hheight) + xpos (+ dy box-hheight)))) (result (let process-pedal ((remaining pedal-list) (prev-x 0) (stencils '()) @@ -150,20 +96,28 @@ divider) and @code{space-after-divider} (box spacing after the divider). (stencil (make-filled-box-stencil (box-x-dimensions prev-x p space) (box-y-dimensions prev-x p space))) - ;(circle-stencil (if circled (rounded-box-stencil stencil 0.05 0.3 0.1 ) stencil)) - (circle-stencil (if circled (circle-stencil stencil 0.05 0.2 ) stencil)) + (pedal-stencil + (if circled + (oval-stencil stencil circle-thickness + circle-x-padding circle-y-padding) + stencil)) (new-prev-x (+ prev-x space box-width))) - (process-pedal (cdr remaining) new-prev-x (cons circle-stencil stencils) #f space))) + (process-pedal (cdr remaining) new-prev-x + (cons pedal-stencil stencils) #f space))) ((#\|) ; Divider line (let* ((xpos (+ prev-x space)) (stencil (divider-stencil xpos)) (new-prev-x (+ prev-x space))) - (process-pedal (cdr remaining) new-prev-x (cons stencil stencils) circled spaceafterdivider))) + (process-pedal (cdr remaining) new-prev-x + (cons stencil stencils) + circled spaceafterdivider))) ((#\o) ; Next pedal should be circled (process-pedal (cdr remaining) prev-x stencils #t space)) (else - (ly:warning "Unhandled entry in harp-pedal: ~a" (car remaining)) - (process-pedal (cdr remaining) prev-x stencils circled space)))))) + (ly:warning "Unhandled entry in harp-pedal: ~a" + (car remaining)) + (process-pedal (cdr remaining) + prev-x stencils circled space)))))) (final-x (car result)) (stencils (cdr result))) ; Add the horizontal line and combine all stencils: @@ -172,3 +126,42 @@ divider) and @code{space-after-divider} (box spacing after the divider). (make-line-stencil line-width 0 0 final-x 0) stencils)))) +;; Parse the harp pedal definition string into list of directions (-1/0/1), #\o and #\| +(define (harp-pedals-parse-string definition-string) + "Parse a harp pedals diagram string and return a list containing 1, 0, -1, #\\o or #\\|" + (map (lambda (c) + (case c + ((#\^) 1) + ((#\v) -1) + ((#\-) 0) + ((#\| #\o) c) + (else c))) + (string->list definition-string))) + + +;; Analyze the pedal-list: Return (pedalcount . (divider positions)) +(define (harp-pedal-info pedal-list) + (let check ((pedals pedal-list) + (pedalcount 0) + (dividerpositions '())) + (if (null? pedals) + (cons pedalcount (reverse dividerpositions)) + + (case (car pedals) + ((-1 0 1) (check (cdr pedals) (+ pedalcount 1) dividerpositions)) + ((#\|) (check (cdr pedals) pedalcount (cons pedalcount dividerpositions))) + (else (check (cdr pedals) pedalcount dividerpositions)))))) + + +;; Sanity checks, spit out warning if pedal-list violates the conventions +(define (harp-pedal-check pedal-list) + "Perform some sanity checks for harp pedals (7 pedals, divider after third)" + (let ((info (harp-pedal-info pedal-list))) + ; 7 pedals: + (if (not (equal? (car info) 7)) + (ly:warning "Harp pedal diagram contains ~a pedals rather than the usual 7." (car info))) + ; One divider after third pedal: + (if (null? (cdr info)) + (ly:warning "Harp pedal diagram does not contain a divider (usually after third pedal).") + (if (not (equal? (cdr info) '(3))) + (ly:warning "Harp pedal diagram contains dividers at positions ~a. Normally, there is only one divider after the third pedal." (cdr info))))))