\version "2.23.0" % You can play around with these parameters. line-count = 12 stem-end-position = 17 inter-line-gap = 2 min-grey = 0 max-grey = 0.7 min-thickness = 0.1 thickness-increment = 0.013 stem-thickness = 2 staff-line-blot = 0.2 light-blue = "CornflowerBlue" note-head-base = \markup \filled-box #'(-0.6 . 0.6) #'(-0.5 . 0.5) #0.9 #(define-markup-command (whiteout-outline-with-color layout props thickness color arg) (number? color? markup?) (stencil-whiteout-outline (interpret-markup layout props arg) thickness color)) note-head-part-one = \markup % Strange that \whiteout-outline-with-color #0.1 #black \with-color #blue \note-head % doesn't work here. Let's work around. \combine \whiteout-outline-with-color #0.15 #black \with-color #black \note-head-base \with-color #light-blue \note-head-base note-head-part-two = \markup \whiteout-outline-with-color #0.15 #black \note-head-base note-head-combined = \markup \overlay { \note-head-part-one \translate #'(-0.5 . 0) \note-head-part-two \translate #'(-0.7 . -0.4) \rotate #-150 \fontsize #-9 \with-color #white \number "2" } #(define (calc-note-head-text grob) (if (ly:grob-property grob 'has-headphones) note-head-combined note-head-part-two)) % Not defined? #(define pi (acos -1)) #(define (greyscale x) (let* ((value (+ (* (+ (/ (atan x) pi) 0.5) (- max-grey min-grey)) min-grey))) (rgb-color value value value))) #(define (calc-thickness x) (+ min-thickness (* thickness-increment (abs x)))) #(define (calc-stem-position grob) (- stem-end-position (ly:grob-property grob 'stem-begin-position))) % From lily/staff-symbol.cc #(define (calc-staff-symbol-line-positions grob) (let* ((line-count (ly:grob-property grob 'line-count)) (height (- line-count 1))) (map (lambda (i) (- height (* 2 i))) (iota line-count)))) #(define (calc-staff-symbol-stencil grob) (let ((x-extent (ly:stencil-extent (ly:staff-symbol::print grob) X))) (apply ly:stencil-add (map (lambda (x) (let ((thickness (calc-thickness x))) (ly:stencil-translate-axis (grob-interpret-markup grob #{ \markup \with-color #(greyscale x) \filled-box #x-extent #(cons (- thickness) thickness) #staff-line-blot #}) (* (ly:grob-property grob 'staff-space 1) 0.5 x) Y))) (ly:grob-property grob 'line-positions))))) % Borrowed from Pierre % https://www.mail-archive.com/lilypond-user@gnu.org/msg140189.html #(define (define-grob-property symbol type? description) "Define a new grob property. `symbol': the property name `type?': the type predicate for this property `description': the type documentation" (set-object-property! symbol 'backend-type? type?) (set-object-property! symbol 'backend-doc description) symbol) #(define-grob-property 'has-headphones boolean? "Should this note be printed with headphones?") \paper { page-breaking = #ly:one-line-auto-height-breaking } \layout { \context { \Score \remove System_start_delimiter_engraver } \context { \Staff \remove Bar_engraver \remove Clef_engraver \remove Time_signature_engraver \override Stem.thickness = #stem-thickness \override Stem.direction = #UP \override NoteHead.stencil = #ly:text-interface::print \override NoteHead.text = #calc-note-head-text \override Stem.length = #calc-stem-position \override Stem.X-offset = 0.63 \override StaffSymbol.line-count = #line-count \override StaffSymbol.line-positions = #calc-staff-symbol-line-positions \override StaffSymbol.stencil = #calc-staff-symbol-stencil \override NoteHead.has-headphones = ##f } } headphones = \tweak has-headphones ##t \etc move = \tweak NoteHead.extra-offset #(lambda (grob) (if (ly:grob-property grob 'has-headphones) '(1.78 . 0) '(1.30 . 0))) \etc addSmallSpacing = { \once \override Score.SpacingSpanner.spacing-increment = 0.4 s \newSpacingSection } \relative { \addSmallSpacing e''' c a f \headphones f d \headphones b b \headphones g g e e a f }