#
# For now let people define these in their environments
#
- : ${MFPLAIN_MP=`kpsewhich mp mfplain.mp`}
+ : ${MFPLAIN_MP=`kpsewhich --format mp mfplain.mp`}
AC_MSG_RESULT($MFPLAIN_MP)
AC_MSG_CHECKING(for inimetapost flags)
public:
void set_infinite (int sign);
- bool infty_b () const;
+ bool infty_b () const
+ {
+ return sign_ == 2 || sign_ == -2;
+ }
void invert ();
int num () const { return sign_ * num_; }
int den () const { return den_; }
Initialize to 0.
*/
Rational ();
- Rational (int, int =1);
+ Rational (int);
+ Rational (int, int);
Rational (double);
Rational (Rational const&r) { copy (r);}
-\version "1.3.146"
-% Example of figured bass, using text scripts.
-% (An alternative is to use a lyrics line if you want the figures
-% aligned vertically.)
-
-
-
-% Scheme macros for accidentals. Note how they can be combined
-% with other strings, for example in: d^#`(columns ,sharp "4")
-
-#(define sharp '((raise . 0.2) (music (named "accidentals-1"))))
-#(define natural '((raise . 0.2) (music (named "accidentals-0"))))
-#(define flat '((raise . 0.2) (music (named "accidentals--1"))))
-
-
-\score{
- \notes \relative c'{
- \clef bass
-
- c^"5" d^#natural g,^"7 6" [a8 e] |
- fis4^"7 6" [g8 d] e4^"7 6" [f?8 c] |
- [d^#sharp d b g][c^"7" c^"5" a^"6" f] |
- [bes^"7" bes^"5" g^"6" e] a4^#sharp d^"6" ~ |
- d^#`(columns ,sharp "4") c^"6" d e^#sharp |
+\header {
+texidoc = "Test figured bass.
+
+Figured bass is created by the FiguredBass context which eats
+note-requests and rest-requests. You can enter these either using
+standard @code{< >} notation, or using the special @code{\figures { }}
+mode, which allows you to type numbers, like @code{<4 6+>}.
+
+" }
+
+\score { \notes <
+\context FiguredBass \transpose c'' {
+ <e! g >
+ <f8 ais >
+ \figures {
+ r
+ <1 3 5>4 <3- 5+ 6!> <5>
+ }
+ }
+ \context Voice {
+ c
+ g8 g
+ f4
+ d
+ c
}
-}
-
+
+>
+ }
*/
Molecule
Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev,
- Real dy, Real dydx
+ Real /* dy */ , Real dydx
)
{
// ugh -> use commonx
#include "engraver.hh"
#include "engraver-group-engraver.hh"
#include "grob.hh"
+#include "main.hh"
void
void
Engraver::announce_grob (Grob* e, Music *m)
{
- if (m && m->origin ()->location_str ().length_i ())
+ if (m && store_locations_global_b
+ && m->origin ()->location_str ().length_i ())
{
e->set_grob_property ("origin", m->get_mus_property ("origin"));
}
--- /dev/null
+#include "engraver.hh"
+#include "text-item.hh"
+#include "musical-request.hh"
+#include "item.hh"
+
+class Figured_bass_engraver : public Engraver
+{
+public:
+ VIRTUAL_COPY_CONS(Translator);
+ Figured_bass_engraver();
+
+protected:
+ Link_array<Note_req> figures_;
+ Rest_req * rest_req_;
+
+ Grob * figure_;
+
+ virtual bool try_music (Music*);
+ virtual void stop_translation_timestep ();
+ virtual void process_music ();
+};
+
+
+Figured_bass_engraver::Figured_bass_engraver()
+{
+ figure_ = 0;
+ rest_req_ = 0;
+}
+
+void
+Figured_bass_engraver::stop_translation_timestep ()
+{
+ if (figure_)
+ {
+ typeset_grob (figure_);
+ figure_ =00;
+ }
+
+ figures_.clear ();
+}
+
+bool
+Figured_bass_engraver::try_music (Music*m)
+{
+ if (Note_req* n = dynamic_cast<Note_req*> (m))
+ {
+ figures_.push (n);
+ return true;
+ }
+ else if (Rest_req * r = dynamic_cast<Rest_req*> (m))
+ {
+ rest_req_ = r;
+ return true;
+ }
+ return false;
+}
+
+void
+Figured_bass_engraver::process_music ()
+{
+ if (rest_req_)
+ {
+ figure_ = new Item (get_property ("BassFigure"));
+ announce_grob (figure_, rest_req_); // todo
+ figure_->set_grob_property ("text" , gh_str02scm ("-"));
+ }
+ else if (figures_.size ())
+ {
+ figure_ = new Item (get_property ("BassFigure"));
+ announce_grob (figure_, figures_[0]); // todo
+ SCM flist = SCM_EOL;
+ for (int i = 0; i < figures_.size (); i++)
+ {
+ Note_req * n = figures_[i];
+ Pitch *p = unsmob_pitch (n->get_mus_property ("pitch"));
+
+ String fstr = to_str (p->steps ()+ 1);
+
+ SCM one_fig = ly_str02scm(fstr.ch_C ());
+
+ if (p->alteration_i_ || to_boolean (n->get_mus_property ("force-accidental") ))
+ {
+ SCM alter = scm_assoc (gh_int2scm (p->alteration_i_),
+ figure_->get_grob_property ("accidental-alist"));
+ if (gh_pair_p (alter))
+ {
+ one_fig = gh_list (ly_symbol2scm ("columns"),
+ one_fig,
+ gh_cdr(alter),
+ SCM_UNDEFINED);
+ }
+ }
+
+ flist = gh_cons (one_fig, flist);
+ }
+
+ flist = gh_cons (ly_symbol2scm ("lines"), flist);
+
+ figure_-> set_grob_property ("text", flist);
+ }
+}
+
+
+ADD_THIS_TRANSLATOR(Figured_bass_engraver);
Do break substitution in S, using CRITERION. Return new value.
CRITERION is either a SMOB pointer to the desired line, or a number
representing the break direction. Do not modify SRC.
+
+ It is rather tightly coded, since it takes a lot of time.
*/
SCM
Grob::handle_broken_grobs (SCM src, SCM criterion)
extern String output_name_global;
extern bool safe_global_b;
extern bool verbose_global_b;
+extern bool store_locations_global_b;
/* misc */
extern All_font_metrics *all_fonts_global_p;
SCM lookup_identifier (String s);
void push_note_state ();
+ void push_figuredbass_state ();
void push_chord_state ();
void push_lyric_state ();
void pop_state ();
bool note_state_b () const;
bool chord_state_b () const;
bool lyric_state_b () const;
-
+ bool figure_state_b () const;
private:
int lookup_keyword (String);
int scan_bare_word (String);
--- /dev/null
+
+/*
+untransposable-music.hh -- declare
+
+source file of the GNU LilyPond music typesetter
+
+(c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#ifndef UNTRANSPOSABLE_MUSIC_HH
+#define UNTRANSPOSABLE_MUSIC_HH
+#include "music-wrapper.hh"
+
+class Untransposable_music : public Music_wrapper
+{
+public:
+ Untransposable_music ();
+ virtual Pitch to_relative_octave (Pitch);
+ virtual void transpose (Pitch);
+ VIRTUAL_COPY_CONS(Music);
+};
+
+
+#endif /* UNTRANSPOSABLE_MUSIC_HH */
+
%x incl
%x lyrics
%x notes
+%x figures
%x quote
%x longcomment
// windows-suck-suck-suck
}
-<INITIAL,chords,incl,lyrics,notes>{
+<INITIAL,chords,incl,lyrics,notes,figures>{
"%{" {
yy_push_state (longcomment);
}
}
}
-<INITIAL,chords,lyrics,notes>\\version{WHITE}* {
+<INITIAL,chords,lyrics,notes,figures>\\version{WHITE}* {
yy_push_state (version);
}
<version>\"[^"]*\" { /* got the version number */
}
-<INITIAL,chords,lyrics,notes>\\maininput {
+<INITIAL,chords,lyrics,notes,figures>\\maininput {
if (!main_input_b_)
{
start_main_input ();
error (_ ("\\maininput disallowed outside init files"));
}
-<INITIAL,chords,lyrics,notes>\\include {
+<INITIAL,chords,lyrics,figures,notes>\\include {
yy_push_state (incl);
}
<incl>\"[^"]*\";? { /* got the include file name */
cerr << _ ("Missing end quote") << endl;
exit (1);
}
-<chords,notes>{RESTNAME} {
+<chords,notes,figures>{RESTNAME} {
const char *s = YYText ();
yylval.scm = ly_str02scm (s);
return RESTNAME;
}
-<chords,notes>R {
+<chords,notes,figures>R {
return MULTI_MEASURE_REST;
}
-<INITIAL,chords,lyrics,notes>\\\${BLACK}*{WHITE} {
+<INITIAL,chords,lyrics,notes,figures>\\\${BLACK}*{WHITE} {
String s=YYText () + 2;
s=s.left_str (s.length_i () - 1);
return scan_escaped_word (s);
}
-<INITIAL,chords,lyrics,notes>\${BLACK}*{WHITE} {
+<INITIAL,chords,lyrics,notes,figures>\${BLACK}*{WHITE} {
String s=YYText () + 1;
s=s.left_str (s.length_i () - 1);
return scan_bare_word (s);
}
-<INITIAL,chords,lyrics,notes>\\\${BLACK}* { // backup rule
+<INITIAL,chords,lyrics,notes,figures>\\\${BLACK}* { // backup rule
cerr << _ ("white expected") << endl;
exit (1);
}
-<INITIAL,chords,lyrics,notes>\${BLACK}* { // backup rule
+<INITIAL,chords,lyrics,notes,figures>\${BLACK}* { // backup rule
cerr << _ ("white expected") << endl;
exit (1);
}
-<INITIAL,chords,lyrics,notes># { //embedded scm
+<INITIAL,chords,lyrics,notes,figures># { //embedded scm
//char const* s = YYText () + 1;
char const* s = here_ch_C ();
int n = 0;
return SCM_T;
}
-<notes>{
+<figures>{
+ \> {
+ return FIGURE_CLOSE;
+ }
+ \< {
+ return FIGURE_OPEN;
+ }
+}
+<notes,figures>{
{ALPHAWORD} {
return scan_bare_word (YYText ());
}
return c;
}
-<INITIAL,notes>. {
+<INITIAL,notes,figures>. {
return YYText ()[0];
}
-<INITIAL,lyrics,notes>\\. {
+<INITIAL,lyrics,notes,figures>\\. {
char c= YYText ()[1];
switch (c) {
yy_push_state (notes);
}
+void
+My_lily_lexer::push_figuredbass_state()
+{
+ yy_push_state (figures);
+}
void
My_lily_lexer::push_chord_state ()
{
return YY_START == lyrics;
}
+bool
+My_lily_lexer::figure_state_b () const
+{
+ return YY_START == figures;
+}
+
/*
urg, belong to String (_convert)
and should be generalised
Moment
Rhythmic_req::length_mom () const
{
- return unsmob_duration (get_mus_property ("duration"))->length_mom ();
-
+ Duration* d = unsmob_duration (get_mus_property ("duration"));
+ return d ? d->length_mom () : Moment (0);
}
void
Rhythmic_req::compress (Moment m)
{
Duration *d = unsmob_duration (get_mus_property ("duration"));
-
- set_mus_property ("duration", d ->compressed (m.main_part_).smobbed_copy ());
+ if (d)
+ set_mus_property ("duration", d ->compressed (m.main_part_).smobbed_copy ());
}
bool
-
-
-
{"duration", DURATION},
{"dynamicscript", DYNAMICSCRIPT},
{"elementdescriptions", ELEMENTDESCRIPTIONS},
- {"font", FONT},
+ {"figures",FIGURES},
{"grace", GRACE},
- {"ngrace", NGRACE},
{"glissando", GLISSANDO},
{"header", HEADER},
{"in", IN_T},
{"repeat", REPEAT},
{"addlyrics", ADDLYRICS},
{"partcombine", PARTCOMBINE},
+ {"porrectus", PORRECTUS},
{"score", SCORE},
{"script", SCRIPT},
{"stylesheet", STYLESHEET},
-
*/
+/*
+
+the rules for who is protecting what are very shady. TODO: uniformise
+this.
+
+
+*/
+
#include <ctype.h>
#include <iostream.h>
#include "transposed-music.hh"
#include "time-scaled-music.hh"
#include "repeated-music.hh"
-
+#include "untransposable-music.hh"
#include "lilypond-input-version.hh"
#include "grace-music.hh"
#include "part-combine-music.hh"
%token DENIES
%token DURATION
%token EXTENDER
-%token FONT
+%token FIGURES FIGURE_OPEN FIGURE_CLOSE
%token GLISSANDO
-%token GRACE NGRACE
+%token GRACE
%token HEADER
%token HYPHEN
%token IN_T
%token PAPER
%token PARTIAL
%token PENALTY
+%token PORRECTUS
%token PROPERTY
%token OVERRIDE SET REVERT
%token PT_T
%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET
%type <i> exclamations questions dots
+%type <i> bass_number bass_mod
+%type <scm> bass_figure figure_list figure_spec
%token <i> DIGIT
%token <scm> NOTENAME_PITCH
%token <scm> TONICNAME_PITCH
{ $$ = $3;
THIS->lexer_p_->pop_state ();
}
+ | FIGURES
+ { THIS->lexer_p_->push_figuredbass_state (); }
+ Music
+ {
+ Music * chm = new Untransposable_music () ;
+ chm->set_mus_property ("element", $3->self_scm ());
+ $$ = chm;
+
+ THIS->lexer_p_->pop_state ();
+ }
| CHORDS
{ THIS->lexer_p_->push_chord_state (); }
Music
| BREATHE {
$$ = new Breathing_sign_req;
}
+ | PORRECTUS {
+ $$ = new Porrectus_req;
+ }
;
;
+bass_number:
+ DIGIT
+ | UNSIGNED
+ ;
+
+bass_mod:
+ '-' { $$ = -1; }
+ | '+' { $$ = 1; }
+ | '!' { $$ = 0; }
+ ;
+
+bass_figure:
+ bass_number {
+ Pitch p ;
+ p .notename_i_ = $1 - 1;
+ p.normalise();
+
+ Note_req * nr = new Note_req;
+ $$ = nr->self_scm ();
+ nr->set_mus_property ("pitch", p.smobbed_copy ());
+ scm_unprotect_object ($$);
+ }
+ | bass_figure bass_mod {
+ if ($2) {
+ SCM sp = unsmob_music ($1)->get_mus_property ("pitch");
+ unsmob_pitch (sp)->alteration_i_ += $2;
+ } else {
+ unsmob_music ($1)->set_mus_property ("force-accidental", SCM_BOOL_T);
+ }
+ }
+ ;
+
+figure_list:
+ /**/ {
+ $$ = SCM_EOL;
+ }
+ | figure_list bass_figure {
+ $$ = gh_cons ($2, $1);
+ }
+ ;
+
+figure_spec:
+ FIGURE_OPEN figure_list FIGURE_CLOSE {
+ Music * m = new Request_chord (SCM_EOL);
+ $2 = scm_reverse_x ($2, SCM_EOL);
+ m->set_mus_property ("elements", $2);
+ $$ = m->self_scm ();
+ }
+ ;
+
simple_element:
pitch exclamations questions optional_notemode_duration {
n->set_spot (i);
$$ = v;
}
- | RESTNAME optional_notemode_duration {
+ | figure_spec optional_notemode_duration {
+ Music * m = unsmob_music ($1);
+ Input i = THIS->pop_spot ();
+ m->set_spot (i);
+ for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = gh_cdr (s))
+ {
+ unsmob_music (gh_car (s))->set_mus_property ("duration", $2);
+ }
+ $$ = m;
+ }
+ | RESTNAME optional_notemode_duration {
Input i = THIS->pop_spot ();
SCM e = SCM_UNDEFINED;
smobify_self ();
}
+/*
+ store point & click locations.
+ Global to save some time. (Sue us!)
+ */
+bool store_locations_global_b;
+
Score::Score (Score const &s)
: Input (s)
{
music_ = SCM_EOL;
header_p_ = 0;
smobify_self ();
-
+
+ /*
+ TODO: this is not very elegant....
+ */
+ store_locations_global_b = (gh_eval_str ("point-and-click") != SCM_BOOL_F);
+
Music * m =unsmob_music (s.music_);
music_ = m?m->clone ()->self_scm () : SCM_EOL;
scm_gc_unprotect_object (music_);
def_p_arr_.push (s.def_p_arr_[i]->clone ());
errorlevel_i_ = s.errorlevel_i_;
if (s.header_p_)
- {
- header_p_ = (s.header_p_) ? new Scheme_hash_table (*s.header_p_): 0;
+ {
+ header_p_ = (s.header_p_) ? new Scheme_hash_table (*s.header_p_): 0;
- scm_gc_unprotect_object (header_p_->self_scm ());
- }
-
+ scm_gc_unprotect_object (header_p_->self_scm ());
+ }
}
Score::~Score ()
--- /dev/null
+/*
+untransposable-music.cc -- implement Untransposable_music
+
+source file of the GNU LilyPond music typesetter
+
+(c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#include "untransposable-music.hh"
+
+void
+Untransposable_music::transpose (Pitch )
+{
+}
+
+Pitch
+Untransposable_music::to_relative_octave (Pitch p)
+{
+ return p;
+}
+
+ADD_MUSIC(Untransposable_music);
+
+Untransposable_music::Untransposable_music()
+{
+
+}
{
if (volta_span_p_)
Volta_spanner::add_column (volta_span_p_,item);
- if (end_volta_span_p_)
- Volta_spanner::add_column (end_volta_span_p_,item);
}
if (Bar::has_interface (item))
{
\consists "Phrasing_slur_engraver"
\consists "Slur_engraver"
\consists "Tie_engraver"
+ \consists "Porrectus_engraver"
\consists "Tuplet_engraver"
\consists "A2_engraver"
\accepts "InnerChoirStaff"
\accepts "ChoirStaff"
\accepts "InnerStaffGroup"
+ \accepts "FiguredBass"
}
\accepts "ChoirStaff"
\accepts "PianoStaff"
\accepts "NoteNames"
+ \accepts "FiguredBass"
soloText = #"Solo"
soloIIText = #"Solo II"
GraceContext = \translator {
\type "Engraver_group_engraver"
}
+
+FiguredBassContext = \translator {
+ \type "Engraver_group_engraver"
+ \name FiguredBass
+ \consists "Figured_bass_engraver"
+ \consistsend "Axis_group_engraver"
+}
#
# For now let people define these in their environments
#
- : ${MFPLAIN_MP=`kpsewhich mp mfplain.mp`}
+ : ${MFPLAIN_MP=`kpsewhich --format mp mfplain.mp`}
AC_MSG_RESULT($MFPLAIN_MP)
AC_MSG_CHECKING(for inimetapost flags)