From ba3a5a6907fcf746a5a52cb6bf74e882b17bb656 Mon Sep 17 00:00:00 2001 From: contrapunctus Date: Sun, 12 Sep 2021 22:37:40 +0530 Subject: [PATCH] Initial template commit --- .gitignore | 2 + common.ly | 20 +++++ lsr952.ly | 184 +++++++++++++++++++++++++++++++++++++ lyrics.ly | 4 + main.ly | 33 +++++++ mkly | 235 ++++++++++++++++++++++++++++++++++++++++++++++++ music/guitar.ly | 41 +++++++++ music/voice.ly | 18 ++++ 8 files changed, 537 insertions(+) create mode 100644 .gitignore create mode 100755 common.ly create mode 100644 lsr952.ly create mode 100755 lyrics.ly create mode 100755 main.ly create mode 100755 mkly create mode 100644 music/guitar.ly create mode 100755 music/voice.ly diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a5d34c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pdf +output/ diff --git a/common.ly b/common.ly new file mode 100755 index 0000000..f1c68bf --- /dev/null +++ b/common.ly @@ -0,0 +1,20 @@ +\version "2.18.2" + +common = { + \time 4/4 + \key e \minor +} + +copyright = \markup +\center-column { + \smaller { + "The author of this arrangement, contrapunctus/Kashish (xmpp:contrapunctus@jabber.fr), would like to release it into the" + \raise #1 + \concat { + \bold "public domain " + "using the Creative Commons CC0 License - " + \with-url #"http://creativecommons.org/publicdomain/zero/1.0/" + {http://creativecommons.org/publicdomain/zero/1.0/} + } + } +} diff --git a/lsr952.ly b/lsr952.ly new file mode 100644 index 0000000..c0eeaf9 --- /dev/null +++ b/lsr952.ly @@ -0,0 +1,184 @@ +%% http://lsr.di.unimi.it/LSR/Item?id=952 +% added by P.P.Schneider on Sept.2014. +% revised by Harm +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% LSR workaround: +% #(set! paper-alist (cons '("snippet" . (cons (* 70 mm) (* 140 mm))) paper-alist)) +% \paper { +% #(set-paper-size "snippet") +% tagline = ##f +% } +% \markup\vspace #.5 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Prefix = \markup { + %% uncomment/comment these lines for C, C slashed, B or B slashed prefix : + % \roman C + %\combine \roman C \translate #'(0.65 . -0.25) \override #'(thickness . 1.2) \draw-line #'(0 . 1.8) + \roman B + %\combine \roman B \translate #'(0.65 . -0.25) \override #'(thickness . 1.2) \draw-line #'(0 . 1.8) + %%%%%%%%%%%% + \hspace #0.2 +} + +#(define-markup-command (prefix layout props string-qty) (integer?) + (interpret-markup layout props + (if (member string-qty (iota 4 2 1)) + #{ + \markup { + \override #'(font-family . typewriter) + \concat { + \fontsize #-4 { + \raise #.5 #(number->string string-qty) + \hspace #-.2 + \raise #.2 "/" + \hspace #-.2 + "6" + } + \Prefix + } + } + #} + #{ \markup\Prefix #}))) + +startBarre = +#(define-event-function (parser location arg-string-qty str) + ((integer?) markup?) + (let* ((pre-fix + (if arg-string-qty #{ \markup \prefix #arg-string-qty #} Prefix)) + (mrkp (markup #:upright #:concat (pre-fix str #:hspace 0.3)))) + + (define (width grob text-string) + (let* ((layout (ly:grob-layout grob)) + (props (ly:grob-alist-chain + grob + (ly:output-def-lookup layout 'text-font-defaults)))) + (interval-length + (ly:stencil-extent + (interpret-markup layout props (markup text-string)) + X)))) + #{ + \tweak after-line-breaking + #(lambda (grob) + (let* ((mrkp-width (width grob mrkp)) + (line-thickness (ly:staff-symbol-line-thickness grob))) + (ly:grob-set-nested-property! + grob + '(bound-details left padding) + (+ (/ mrkp-width -4) (* line-thickness 2))))) + \tweak font-size -2 + \tweak style #'line + \tweak bound-details.left.text #mrkp + \tweak bound-details.left.attach-dir -1 + \tweak bound-details.left-broken.text ##f + \tweak bound-details.left-broken.attach-dir -1 + %% adjust the numeric values to fit your needs: + \tweak bound-details.left-broken.padding 1.5 + \tweak bound-details.right-broken.padding 0 + \tweak bound-details.right.padding 0.25 + \tweak bound-details.right.attach-dir 2 + \tweak bound-details.right-broken.text ##f + \tweak bound-details.right.text + \markup + \with-dimensions #'(0 . 0) #'(-.3 . 0) + \draw-line #'(0 . -1) + \startTextSpan + #})) + +#(define startHalfBarre startBarre) + +startModernBarre = +#(define-event-function (parser location fretnum partial) + (number? number?) + #{ + \tweak bound-details.left.text + \markup + \small \bold \concat { + %\Prefix + #(format #f "~@r" fretnum) + \hspace #.2 + \lower #.3 \fontsize #-2 #(number->string partial) + \hspace #.5 + } + \tweak font-size -1 + \tweak font-shape #'upright + \tweak style #'dashed-line + \tweak dash-fraction #0.3 + \tweak dash-period #1 + \tweak bound-details.left.stencil-align-dir-y #0.35 + \tweak bound-details.left.padding 0.25 + \tweak bound-details.left.attach-dir -1 + \tweak bound-details.left-broken.text ##f + \tweak bound-details.left-broken.attach-dir -1 + %% adjust the numeric values to fit your needs: + \tweak bound-details.left-broken.padding 1.5 + \tweak bound-details.right-broken.padding 0 + \tweak bound-details.right.padding 0.25 + \tweak bound-details.right.attach-dir 2 + \tweak bound-details.right-broken.text ##f + \tweak bound-details.right.text + \markup + \with-dimensions #'(0 . 0) #'(-.3 . 0) + \draw-line #'(0 . -1) + \startTextSpan + #}) + +stopBarre = \stopTextSpan + +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% %% EXAMPLES +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% %%%%%%%%%%%%%%%%% Standard Barré function + +% %% Syntax: note \startBarre "text" notes \stopBarre (text = any fret number) + +% \markup \column \italic { "Standard notation:" \vspace #.5 } + +% { +% \clef "G_8" +% \key d\minor +% << +% \new Voice { +% \voiceOne a'16[ \startBarre "III" bes d' bes f'8] \stopBarre +% } +% \new Voice { \voiceTwo d2 } +% >> +% } + +% %%%%%%%%%%%%%%%%% Half Barré function with prefix + +% %% Syntax: note \startHalfBarre #'string quantity' "text" notes \stopBarre (text = any fret number) + +% \markup +% \column \italic { \vspace #1 "With string position prefix:" \vspace #.5 } + +% { +% \clef "G_8" +% \key d\minor +% << +% \new Voice { +% \voiceOne a'16[ \startHalfBarre #3 "III" bes d' bes f'8] \stopBarre +% } +% \new Voice { \voiceTwo d2 } +% >> +% } + +% %%%%%%%%%%%%%%%%% Modern Barré function + +% %% Syntax: note \startModernBarre fret-number string-number notes \stopBarre + +% \markup \column \italic { \vspace #1 "A more modern approach:" \vspace #.5 } +% { +% \clef "G_8" +% \key d\minor +% << +% \new Voice { +% \voiceOne a'16[ \startModernBarre #3 #3 bes d' bes f'8] \stopBarre +% } +% \new Voice { \voiceTwo d2 } +% >> +% } + +% % LSR workaround: +% \markup\vspace #.5 diff --git a/lyrics.ly b/lyrics.ly new file mode 100755 index 0000000..51f646b --- /dev/null +++ b/lyrics.ly @@ -0,0 +1,4 @@ +voiceLyrics = \lyricsto "voice" { + + +} diff --git a/main.ly b/main.ly new file mode 100755 index 0000000..a640066 --- /dev/null +++ b/main.ly @@ -0,0 +1,33 @@ +\version "2.18.2" + +\include "common.ly" + +\include "music/voice.ly" +\include "lyrics.ly" + +\include "lsr952.ly" +\include "music/guitar.ly" + +\header { + title = \markup \fontsize #2 "Songs of Travel" + composer = "Ralph Vaughan Williams" + poet = "Robert Louis Stevenson" + arranger = "arr. Kashish" + copyright = \copyright + +} + +\score { + << + \new Staff << \new Voice = "voice" { \voice } >> + \new Lyrics \voiceLyrics + \new Staff << \new Voice { \guitar } >> + \new Dynamics { \guitarDynamics } + >> + + \layout { + \context { + \Staff \RemoveEmptyStaves + } + } +} diff --git a/mkly b/mkly new file mode 100755 index 0000000..1fd78ad --- /dev/null +++ b/mkly @@ -0,0 +1,235 @@ +#!/usr/bin/guile -s +!# +(use-modules + (ice-9 match) + (srfi srfi-1) + (ice-9 format) + (ice-9 regex) + (ice-9 popen) + (ice-9 rdelim) + (ice-9 getopt-long)) +(define rest cdr) + +;; (define (debug . args) +;; (format +;; (current-error-port) "~%~{~a - ~s~%~}~%" +;; (list 'command-line (command-line) +;; 'target target +;; 'rules rules +;; 'selected-rule selected-rule +;; 'action action))) + +(define option-spec + '((version (single-char #\v)) + (help (single-char #\h)) + (debug (single-char #\d)) + (load (single-char #\l) (value #t) ;; (predicate file-exists?) + ))) + +(define options (getopt-long (command-line) option-spec)) + +(format (current-error-port) + "debug ~s~%" + (option-ref options 'debug #f)) + +(define (debug format-string . args) + (when (option-ref options 'debug #f) + (apply format (current-error-port) format-string args))) + +;; Return the parent directory component of PATH, or #f if none is present. +(define (parent path) + (if path + (let ((match (string-match (format #f "/~a$" (basename path)) path))) + (if match (regexp-substitute #f match 'pre "/") #f)) + #f)) + +;; Return the basename of the current working directory. +(define (getcwd-base) (basename (getcwd))) + +;; If ARG is truthy, return "-", else return "". +(define (file-name-part arg) + (if arg (format #f "-~a" arg) "")) + +;; Return FILE name without the extension, or FILE if there is no extension. +(define (file-name-no-extension file) + (let ((rindex (string-rindex file #\.))) + (if rindex + (xsubstring file 0 rindex) + file))) + +;; Create DIR if it does not exist. +;; Raise an error if DIR does exist, but is not a directory. +;; Return DIR. +(define (use-dir! dir) + (unless (file-exists? dir) + (mkdir dir)) + (unless (file-is-directory? dir) + (error (format #f "File ~s already exists and is not a directory" dir))) + dir) + +;; Return the output of running COMMAND with ARGS in the system shell. +(define (shell-result command . args) + (let* ((port (apply open-pipe* (append `("open_read" ,command) args))) + (output (read-line port))) + (close-pipe port) + output)) + +;; Return the current branch of the project's version control system, +;; or #f if no version control system was detected. +(define (vcs-current-branch) + (cond ((file-exists? ".git") + ;; we were using `git rev-parse --abbrev-ref HEAD' before, + ;; but that sometimes resulted in an error - `fatal: + ;; ambiguous argument 'HEAD': unknown revision or path not in + ;; the working tree.' + (shell-result "git" "symbolic-ref" "--short" "HEAD")) + ((file-exists? ".hg") + (shell-result "hg" "identify" "-b")) + ;; ((or (file-exists? ".fslckout") + ;; (file-exists? "_FOSSIL_"))) + ;; ((file-exists? ".bzr")) + ;; ((file-exists? "_darcs")) + ;; ((file-exists? ".svn")) + (else #f))) + +(define (flatten seq) + (cond ((null? seq) '()) + ((not (pair? seq)) (list seq)) + (else (append (flatten (car seq)) + (flatten (rest seq)))))) + +;; Flatten and convert list ARG to a string, with each element +;; separated by spaces. +(define (list->command-line arg) + (format #f "~{~s ~}" (flatten arg))) + +;; Run ARG in the system shell. ARG must be a list with elements of +;; any type. Return the exit status. +(define (run arg) + ;; (format (current-error-port) "~%mkly: run: ~s~2%" (list->command-line arg)) + (system (list->command-line arg))) + +(let ((load-values (option-ref options 'load #f))) + (cond ((not load-values) #f) + ((pair? load-values) + (debug "loading files ~s~%" load-values) + (map load load-values)) + (else + (load load-values) + (debug "loading file ~s~%" load-values)))) + +(define shell-path "/usr/bin/bash") +(define project-root (getcwd)) +(define project-name (getcwd-base)) + +;; Return a list of build rules. +;; +;; TARGET is a single target passed on the command line, or "" if none +;; was supplied. (If multiple targets are passed on the command line, +;; this function will be called once with each target.) +;; +;; Return value is a list of rules, where each rule is a list in +;; the form (PATTERN COMMAND [ARG ...]) +;; +;; PATTERN can be +;; * a symbol - COMMAND will be run when the target passed on the +;; command line matches this symbol; +;; * a string - treated as a regular expression; COMMAND will be run +;; when it matches the target passed on the command line +;; +;; COMMAND and arguments can be any value - lists will be flattened, +;; all values will be converted to strings, and spaces will be added. +;; String values will be quoted, which is useful for escaping file +;; names in the final command to be run. +(define (rules target) + ;; if TARGET is a subdirectory in the project root, descend to it + ;; before executing the action + (let* ((subdir (parent target)) + (branch (vcs-current-branch)) + (dest (begin + (when subdir + (chdir subdir) + (set! project-name (getcwd-base))) + (use-dir! (format #f "~:[output-~a~;output/~]" branch branch))))) + ;; A main.ly could also exist both in the root and in the + ;; sub-directories, but this will just compile the root main.ly regardless. + `((all main.ly part-*.ly) + (dev lilypond + -o ,(string-append dest project-name "-pacON") + main.ly) + (main.ly lilypond -dno-point-and-click + -o ,(string-append dest project-name) + ,target) + ("part-.*\\.ly" lilypond -dno-point-and-click + -o ,(string-append + dest project-name "-" (file-name-no-extension target)) + ,target)))) + +;; Return a rule from RULES which matches TARGET +;; +;; RULES must be a list (see procedure `rules'), where each element is +;; in the form (PATTERN COMMAND [ARGS ...]) +;; +;; TARGET must be a string. +;; If it is empty, return the first rule in RULES. +;; If it is `equal?' to a PATTERN string or to the name of a PATTERN +;; symbol, or if TARGET is matched by a PATTERN regular expression, +;; return the rule whose TARGET matched. +(define (select-rule rules target) + (if (null? rules) + (begin (debug "mkly: no matching rule") #f) + (let* ((rule (first rules)) + (pattern (first rule)) + (rule-command (rest rule))) + ;; (format (current-error-port) "~%rule - ~s~%pattern - ~s~%" rule target) + (cond ((equal? "" target) rule) + ((and (string? pattern) + (string-match pattern target)) + ;; (format #t "~%mkly: running ~s~%" rule-command) + rule) + ((and (symbol? pattern) + (equal? target (symbol->string pattern))) + ;; (format #t "~%mkly: running ~s~%" rule-command) + rule) + (else (select-rule (rest rules) target)))))) + +;; target ::= action -> run +;; | target -> for each target, recurse with new target +(define (run-rule-for target) + (let* ((rules (rules target)) + (selected-rule (flatten (select-rule rules target))) + ;; Support for actions which call mkly itself. Do we really want this? + (action (if (equal? "./mkly" (first (command-line))) + (map (lambda (it) + (if (or (eq? it 'mkly) + (equal? it "mkly")) + (string-append (getcwd) "/mkly") + it)) + (rest selected-rule)) + (rest selected-rule)))) + (debug "~%~{~a - ~s~%~}~%" + (list 'command-line (command-line) + 'rules rules + 'selected-rule selected-rule + 'action action)) + (system (list->command-line action)))) + +;; Run the associated action for each element of TARGETS. +;; +;; TARGETS must be a list of strings, representing all non-option +;; arguments passed by the user to the script on the command line. +(define (main targets) + (debug "targets - ~s~%" targets) + (let loop ((targets targets)) + (let ((target (if (null? targets) "" (first targets)))) + (debug "running rule ~a for target ~s~%" + (select-rule (rules target) target) target) + (if (and (file-exists? target) + (file-is-directory? target)) + (begin (chdir project-root) + (chdir target)) + (run-rule-for target)) + (when (pair? targets) + (loop (rest targets)))))) + +(main (option-ref options '() #f)) diff --git a/music/guitar.ly b/music/guitar.ly new file mode 100644 index 0000000..a2e15d7 --- /dev/null +++ b/music/guitar.ly @@ -0,0 +1,41 @@ +\version "2.20.0" + +pos = +#(define-event-function + (parser location position) + (markup?) + #{ + \markup \small \bold #position + #} +) + +posI = \markup \small \bold "I" +posIII = \markup \small \bold "III" +posIV = \markup \small \bold "IV" +posVI = \markup \small \bold "VI" + +ottavaStart = { + \set Staff.ottavation = #"8vb" + \once \override Staff.OttavaBracket.direction = #DOWN + \set Voice.middleCPosition = #1 +} + +ottavaStop = { + \unset Staff.ottavation + \unset Voice.middleCPosition +} + +guitarDynamics = { + + \barNumberCheck #1 + +} + +guitar = { + \clef "treble_8" + % \mergeDifferentlyHeadedOn + + \barNumberCheck #1 + s1 | + +} diff --git a/music/voice.ly b/music/voice.ly new file mode 100755 index 0000000..c0eb02f --- /dev/null +++ b/music/voice.ly @@ -0,0 +1,18 @@ +\version "2.18.2" + +voice = \relative c'' { + \set Staff.instrumentName = "Voice" + \common + + \barNumberCheck #1 + s1 | + + \barNumberCheck #4 + + \barNumberCheck #6 + + \barNumberCheck #8 + + \barNumberCheck #11 + +}