\override TextScript #'font-family = #'typewriter
\override TextScript #'font-shape = #'upright
\override Script #'padding = #-0.1
- a\ictus_"ictus " \break
- a\circulus_"circulus " \break
- a\semicirculus_"semicirculus " \break
- a\accentus_"accentus " \break
+ a\ictus_"ictus " \bar "" \break
+ a\circulus_"circulus " \bar "" \break
+ a\semicirculus_"semicirculus " \bar "" \break
+ a\accentus_"accentus " \bar "" \break
\[ a_"episema" \episemInitium \pes b \flexa a b \episemFinis \flexa a \]
}
}
@end lilypond
-@c @seealso
-@c TODO: nothing here yet ...
+Snippets:
+@rlsr{Ancient notation}.
+
+Internals Reference:
+@rinternals{Episema},
+@rinternals{EpisemaEvent},
+@rinternals{Episema_engraver},
+@rinternals{Script},
+@rinternals{ScriptEvent},
+@rinternals{Script_engraver}.
@knownissues
Some articulations are vertically placed too closely to the
corresponding note heads.
-The episema line is not displayed in many cases. If it is displayed,
-the right end of the episema line is often too far to the right.
-
@c {{{2Augmentum dots (@emph{morae})
@node Augmentum dots (@emph{morae})
\test "" ##[ { c( c) c^( c^) c_( c_) } #] % SlurEvent
\test "" ##[ { c\< c\! c^\< c^\! c_\< c_\! } #] % CrescendoEvent
\test "" ##[ { c\> c\! c^\> c^\! c_\> c_\! } #] % DecrescendoEvent
+\test "" ##[ { c\episemInitium c\episemFinis } #] % EpisemaEvent
\test "" ##[ { c\( c\) c^\( c^\) c_\( c_\) } #] % PhrasingSlurEvent
\test "" ##[ { c\sustainOn c\sustainOff } #] % SustainEvent
\test "" ##[ { c\sostenutoOn c\sostenutoOff } #] % SostenutoEvent
--- /dev/null
+\version "2.13.15"
+
+\header {
+ texidoc = "An episema can be typeset over a single neume or a
+melisma. Its position is quantized between staff lines."
+}
+
+#(set-global-staff-size 26)
+\include "gregorian.ly"
+
+\new VaticanaVoice {
+ \revert Score.SpacingSpanner #'packed-spacing
+ a\episemInitium\episemFinis
+ \[ a\episemInitium \pes b \flexa a\episemFinis \]
+ \[ a\episemInitium \pes b \flexa a b\episemFinis \flexa a \]
+}
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2010 Neil Puttock <n.puttock@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "engraver.hh"
+#include "international.hh"
+#include "note-column.hh"
+#include "pointer-group-interface.hh"
+#include "side-position-interface.hh"
+#include "spanner.hh"
+#include "stream-event.hh"
+
+#include "translator.icc"
+
+class Episema_engraver : public Engraver
+{
+public:
+ TRANSLATOR_DECLARATIONS (Episema_engraver);
+protected:
+ virtual void finalize ();
+ DECLARE_TRANSLATOR_LISTENER (episema);
+ DECLARE_ACKNOWLEDGER (note_column);
+ DECLARE_ACKNOWLEDGER (note_head);
+ void stop_translation_timestep ();
+ void process_music ();
+
+private:
+ Spanner *span_;
+ Spanner *finished_;
+ Stream_event *current_event_;
+ Drul_array<Stream_event *> event_drul_;
+ vector<Grob *> note_columns_;
+ void typeset_all ();
+};
+
+Episema_engraver::Episema_engraver ()
+{
+ finished_ = 0;
+ current_event_ = 0;
+ span_ = 0;
+ event_drul_.set (0, 0);
+}
+
+IMPLEMENT_TRANSLATOR_LISTENER (Episema_engraver, episema);
+void
+Episema_engraver::listen_episema (Stream_event *ev)
+{
+ Direction d = to_dir (ev->get_property ("span-direction"));
+ // Must not ASSIGN_EVENT_ONCE here, since episema
+ // can be typeset over a single neume
+ event_drul_[d] = ev;
+}
+
+void
+Episema_engraver::process_music ()
+{
+ if (event_drul_[START])
+ {
+ if (current_event_)
+ event_drul_[START]->origin ()->warning (_ ("already have an episema"));
+ else
+ {
+ current_event_ = event_drul_[START];
+ span_ = make_spanner ("Episema", event_drul_[START]->self_scm ());
+
+ event_drul_[START] = 0;
+ }
+ }
+ if (event_drul_[STOP])
+ {
+ if (!span_)
+ event_drul_[STOP]
+ ->origin ()->warning (_ ("cannot find start of episema"));
+ else
+ {
+ finished_ = span_;
+ announce_end_grob (finished_, SCM_EOL);
+ span_ = 0;
+ current_event_ = 0;
+ note_columns_.clear ();
+ }
+ }
+}
+
+void
+Episema_engraver::typeset_all ()
+{
+ if (finished_)
+ {
+ if (!finished_->get_bound (RIGHT))
+ {
+ Grob *col = (note_columns_.size ()
+ ? note_columns_.back ()
+ : unsmob_grob (get_property ("currentMusicalColumn")));
+ finished_->set_bound (RIGHT, col);
+ }
+ finished_ = 0;
+ }
+}
+
+void
+Episema_engraver::stop_translation_timestep ()
+{
+ if (span_ && !span_->get_bound (LEFT))
+ {
+ Grob *col = (note_columns_.size ()
+ ? note_columns_.front ()
+ : unsmob_grob (get_property ("currentMusicalColumn")));
+ span_->set_bound (LEFT, col);
+ }
+
+ typeset_all ();
+ event_drul_.set (0, 0);
+}
+
+void
+Episema_engraver::finalize ()
+{
+ typeset_all ();
+ if (span_)
+ {
+ current_event_->origin ()->warning (_ ("unterminated episema"));
+ span_->suicide ();
+ span_ = 0;
+ }
+}
+
+void
+Episema_engraver::acknowledge_note_column (Grob_info info)
+{
+ note_columns_.push_back (info.grob ());
+}
+
+void
+Episema_engraver::acknowledge_note_head (Grob_info info)
+{
+ if (span_)
+ {
+ Side_position_interface::add_support (span_, info.grob ());
+ add_bound_item (span_, info.grob ());
+ }
+ else if (finished_)
+ {
+ Side_position_interface::add_support (finished_, info.grob ());
+ add_bound_item (finished_, info.grob ());
+ }
+}
+
+ADD_ACKNOWLEDGER (Episema_engraver, note_column);
+ADD_ACKNOWLEDGER (Episema_engraver, note_head);
+
+ADD_TRANSLATOR (Episema_engraver,
+ /* doc */
+ "Create an @emph{Editio Vaticana}-style episema line.",
+
+ /* create */
+ "Episema ",
+
+ /* read */
+ "",
+
+ /* write */
+ ""
+ );
\remove "Stem_engraver"
\remove "Ligature_bracket_engraver"
\consists "Vaticana_ligature_engraver"
+ \remove "Text_spanner_engraver"
+ \consists "Episema_engraver"
%% Set default head for notes outside of \[ \].
\override NoteHead #'style = #'vaticana.punctum
%% There are no beams in Gregorian Chant notation.
autoBeaming = ##f
-
- %% Prepare TextSpanner for \episem{Initium|Finis} use.
- %%
- %% FIXME: The line @code{\override TextSpanner #'padding = #-0.1} is
- %% required to force the articulation signs being placed vertically
- %% tightly to the correpsonding note heads.
- %%
- \override TextSpanner #'style = #'line
- \override TextSpanner #'padding = #-0.1
}
\context {
\Voice
\name "GregorianTranscriptionVoice"
\alias "Voice"
+ \consists "Episema_engraver"
%% Removing ligature bracket engraver without replacing it by some
%% other ligature engraver would cause a "Junking event: `LigatureEvent'"
%% There are no beams in Gregorian Chant notation.
autoBeaming = ##f
- %% Prepare TextSpanner for \episem{Initium|Finis} use.
- %%
- %% N.B.: dash-fraction MUST be unset; otherwise, TextSpanner will
- %% always produce dashed lines, regardless of the style property.
- %%
- %% FIXME: The line @code{\override TextSpanner #'padding = #-0.1} is
- %% required to force the articulation signs being placed vertically
- %% tightly to the correpsonding note heads.
- %%
- \override TextSpanner #'dash-fraction = #'()
- \override TextSpanner #'style = #'line
- \override TextSpanner #'padding = #-0.1
}
\context {
ictus = #(make-articulation "ictus")
semicirculus = #(make-articulation "semicirculus")
circulus = #(make-articulation "circulus")
-episemInitium = \startTextSpan
-episemFinis = \stopTextSpan
%
% \augmentum increases the dot-count value of all note heads to which
\layout {
indent = 0.0
- %%% TODO: should raggedright be the default?
+ %%% TODO: should ragged-right be the default?
%ragged-right = ##t
ragged-last = ##t
stopTrillSpan = #(make-span-event 'TrillSpanEvent STOP)
+episemInitium = #(make-span-event 'EpisemaEvent START)
+episemFinis = #(make-span-event 'EpisemaEvent STOP)
+
+
% STOP: junkme!
cresc = {
#(ly:export (make-event-chord (list cr)))
(part-combine-event . (solo-one-event solo-two-event unisono-event))
(break-event . (line-break-event page-break-event page-turn-event))
(dynamic-event . (absolute-dynamic-event))
- (span-event . (span-dynamic-event beam-event ligature-event
+ (span-event . (span-dynamic-event beam-event episema-event ligature-event
pedal-event phrasing-slur-event slur-event staff-span-event
text-span-event trill-span-event tremolo-span-event
tuplet-span-event))
"Dynamic text spanner."
'(text))
+(ly:add-interface
+ 'episema-interface
+ "An episema line."
+ '())
+
(ly:add-interface
'finger-interface
"A fingering instruction."
text-interface))))))
+ (Episema
+ . (
+ (bound-details . ((left . ((Y . 0)
+ (padding . 0)
+ (attach-dir . ,LEFT)
+ ))
+ (right . ((Y . 0)
+ (padding . 0)
+ (attach-dir . ,RIGHT)
+ ))
+ ))
+ (direction . ,UP)
+ (left-bound-info . ,ly:line-spanner::calc-left-bound-info)
+ (quantize-position . #t)
+ (right-bound-info . ,ly:line-spanner::calc-right-bound-info)
+ (side-axis . ,Y)
+ (stencil . ,ly:line-spanner::print)
+ (style . line)
+ (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (meta . ((class . Spanner)
+ (interfaces . (episema-interface
+ font-interface
+ line-interface
+ line-spanner-interface
+ side-position-interface))))))
+
+
(Fingering
. (
'BeamForbidEvent
'CrescendoEvent
'DecrescendoEvent
+ 'EpisemaEvent
'ExtenderEvent
'FingeringEvent
'GlissandoEvent
(define-span-event-display-method SlurEvent (event parser) #f "(" ")")
(define-span-event-display-method CrescendoEvent (event parser) #f "\\<" "\\!")
(define-span-event-display-method DecrescendoEvent (event parser) #f "\\>" "\\!")
+(define-span-event-display-method EpisemaEvent (event parser) #f "\\episemInitium" "\\episemFinis")
(define-span-event-display-method PhrasingSlurEvent (event parser) #f "\\(" "\\)")
(define-span-event-display-method SustainEvent (event parser) #f "\\sustainOn" "\\sustainOff")
(define-span-event-display-method SostenutoEvent (event parser) #f "\\sostenutoOn" "\\sostenutoOff")
event))
))
+ (EpisemaEvent
+ . ((description . "Begin or end an episema.")
+ (types . (general-music span-event event episema-event))
+ ))
+
(Event
. ((description . "Atomic music event.")
(types . (general-music event))