=item B<-M,--midi>
-Do midi output only.
+do midi output only
=item B<-d,--debug>,
=over 5
=item *
-A fast computer (a full page of music typically takes 1 minute
+a fast computer (a full page of music typically takes 1 minute
on my 486/66, using the DEBUG compile. It's lot slower than most
MusiXTeX preprocessors)
You probably want to edit Variables.make to tailor the compilation
flags. If you're not into debugging C++, then you should go for no
-debugging and C<-O2>.
+debugging and C<-O2>
=head1 AUTHORS
Han-Wen Nienhuys <hanwen@stack.nl>, Main author
=item *
-Jan C. Nieuwenhuizen <jan@digicash.com>, Context errors, Lyrics, Midi
-output, m2m, bits of FlowerLib, general comments.
+Jan Nieuwenhuizen <jan@digicash.com>, Context errors, Lyrics,
+bits of FlowerLib, general comments.
=item *
-Mats Bengtsson <matsb@s3.kth.se>, bugfixes, testing, criticism, general comments.
+Mats Bengtsson <matsb@s3.kth.se>, bugfixes, testing, general comments.
=back
=head1 SEE ALSO
-There are some documentation files in the subdirectory
-F<Documentation/>, among others: lilygut, lilyinput, error, faq. There
-is a rudimentary webpage at the following URL:
-http://www.stack.nl/~hanwen/lilypond/index.html
+There are some documentation files in the subdirectory F<Documentation/>,
+among others: lilygut, lilyinput, error, faq,
=head1 REMARKS
Some questions that have been answered before.
-Q: Gee, I really like MPP, why would I want to switch to LilyPond?
-
-A: The design of MPP is broken beyond repair: it is very difficult to
-enhance MPP, and any working version is (probably) bug-ridden.
-
-Every once in a while, I have a major attack of hybris, and I go in to
-enhance MPP. I usually end up thoroughly frustated within an hour or
-so. I concur, it does work but extending MPP is a major pain.
-
-We will not sacrifice development time on something else than the most
-trivial bugfixes. If you insist on using MusiXTeX, then LilyPond is
-not for you, and you might try PMX which does also nice output.
-
-
Q: Why are [] around the notes, and () inbetween?
A: [] designate beams, a note can only be in one beam at the same
A0: Reconsider. Try Linux. It's fun!
A1: Currently (patchlevel 27), LilyPond (and flowerLib) compiles, links
-and runs on Windhoos-NT, using the CYGNUS GNU port (release b17.1).
+and runs on windhoos-nt, using the cygnus gnu port (release b17.1).
I (JCN) only had to make a minor workaround for missing library calls.
Have a look at http://www.cygnus.com/gnu-win32. To make LilyPond type
-C<make $OS>. (I am not promising to maintain this platform, it is just that
+make $OS. (I am not promising to maintain this platform, it is just that
when having to use doze, i-m sometimes too lazy to reboot.)
-A2: I haven't had time to find a GCC crosscompiler (I<with> g++, mind you) to
+A2: I haven't had time to find a GCC crosscompiler (*with* g++, mind you) to
DOS/win (in rpm, please :).
A: Yes.
-
Q: Why shouldn't I put all commands (\clef, \meter) inside the music?
A: You should do what you like, but at some time we will enable
Q: Why do I need g++ >= 2.7?
A: By using g++ LilyPond is portable to all platforms which support
-g++ (there are quite a few, more than platforms which have AT&T CC or
-Micro$oft C++). Not having to support other compilers saves us a I<lot>
-of trouble. You need a version better than 2.7 because LilyPond &
-FlowerLib uses:
+g++ (there are quite a few). Not having to support other compilers
+saves us a *lot* of trouble. LilyPond & FlowerLib uses:
=over 6
=back
-Q: Why do I have to tell LilyPond explictly that the lowest-line-note
-is "es" if I am using the key of "bes"?
-
-A: The goal of lilypond (and MPP) was to design a language which
-conveys the I<musical> message of a piece. That is the reason that it
-does not ask you to enter the line on which the note is is. (Or the
-"natural" note-name without any "es" or "is" postfix)
-
-We do realise it is a bit shortsighted of us to assume that any user could
-readily read the music he/she is entering. We might extend LilyPond to
-allow "programmable" intervals, keys and clefs (and thus give him a
-means to build his own scales, custom etc.).
-
-For now, you can program LilyPond to use custom notenames and do
-
- notenames { ces_key_notenames }
- music { $ % music in the key of ces
- ...
- $}
- notenames { dutch_notenames } % restore default
-
-as an ad-hoc solution.
-
--- /dev/null
+#!/bin/sh
+
+# unclobber current dir.
+rm -vf *.aux *.log `grep -li "^% Creator: LilyPond" *.out` *.orig *~
+
+# docxx mess
+rm -vf *.class HIER*.html dxxgifs.tex gifs.db icon?.gif logo.gif down.gif \
+ aindex.html index.html
--- /dev/null
+#!/bin/sh
+
+case $# in
+0) echo make_patch old new name
+ exit 1;;
+esac
+
+old=$1
+new=$2
+nm=$3-
+
+newarc=../releases/$nm$new.tar.gz
+oldarc=../releases/$nm$old.tar.gz
+
+
+if [ ! -x $nm$new ]
+then
+ echo untarring ..
+ if [ ! -f $newarc ]
+ then
+ echo cant find $newarc
+ exit
+ fi
+ tar zfxv $newarc
+fi
+if [ ! -x $nm$old ]
+then
+ echo untarring
+
+ if [ ! -f $oldarc ]
+ then
+ echo cant find oldarc
+ exit
+ fi
+ tar zfxv $oldarc
+fi
+
+#(cd $nm$old; touch depend; make clean)
+#(cd $nm$new; touch depend; make clean)
+(cd $nm$new; diff -urP ../$nm$old . > ../patch-$new)
+rm -rf $nm$old $nm$new
include "dutch.ini" # do not include init/ path
-include "script.ini"
-include "table_sixteen.ini" # not needed if doing MIDI
+include "script.ini"
+include "table_sixteen.ini"
melodie = music {
$\clef\violin
c c | g g | a a | g2
- f f | e e | d d8. e16 | c2 | % :|
+ f f | e e | d d8.( e16 | )c2 | % :|
$
}
commands {
meter { 2 * 4}
}
- paper{}
midi {
tempo 4:120
}
music{ $
\duration { 8 }
\octave{ }
- |[ a a a a a a a a a ]8/9
+ |[ a a a a a a a a a ]
\octave{ ' }
- |[ a a a a a a a a a ]8/9
+ |[ a a a a a a a a a ]
\octave { ` }
- [ `c `g d a 'e 'b ''f '''c '''g ] 8/9
- [ '''g '''c ''f 'b 'e a d `g `c ] 8/9
+ [ `c `g d a 'e 'b ''f '''c '''g ]
+ [ '''g '''c ''f 'b 'e a d `g `c ]
\octave{ ' }
- [ `c `g d a 'e 'b ''f '''c '''g ] 8/9
- [ '''g '''c ''f 'b 'e a d `g `c ] 8/9
+ [ `c `g d a 'e 'b ''f '''c '''g ]
+ [ '''g '''c ''f 'b 'e a d `g `c ]
\octave { }
[ c g 'd ]2/3
[ 'd g c ]2/3
}
commands {
meter {6*8}
- skip {36*8}
+ skip 36*8
meter {4*4}
}
}
--- /dev/null
+//
+// binary-source-file.hh -- declare Binary_source_file
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef BINARY_SOURCE_FILE_HH
+#define BINARY_SOURCE_FILE_HH
+
+class Binary_source_file : public Source_file {
+public:
+ Binary_source_file( String& filename_str );
+ virtual ~Binary_source_file();
+
+ virtual String error_str( char const* pos_ch_c_l );
+ virtual int line_i( char const* pos_ch_c_l );
+};
+
+#endif // BINARY_SOURCE_FILE_HH //
--- /dev/null
+#ifndef DEBUG_HH
+#define DEBUG_HH
+
+#include <assert.h>
+#include <iostream.h>
+#include "dstream.hh"
+#include "real.hh"
+#include "proto.hh"
+
+void message( String message_str, char const* context_ch_c_l );
+void warning( String message_str, char const* context_ch_c_l );
+void error( String message_str, char const* context_ch_c_l );
+void error(String s); // errors
+void error_t(const String& s, Time_description const & t_tdes);
+void error_t(String const &s, const Moment &when);
+// warnings
+//void warning(String s);
+#define WARN warnout << "warning: "<<__FUNCTION__ << "(): "
+extern ostream &warnout ;
+
+// progress
+extern ostream *mlog;
+
+// debugging
+extern Dstream *monitor; // monitor
+
+#ifdef NPRINT
+#define mtor if (0) *monitor // clever hack
+#else
+#define mtor if (check_debug) monitor->identify_as(__PRETTY_FUNCTION__)
+#endif
+
+extern bool check_debug;
+
+#endif
--- /dev/null
+/*
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef MOMENT_HH
+#define MOMENT_HH
+
+#include "rational.hh"
+class String;
+typedef Rational Moment;
+
+
+#endif //
+
--- /dev/null
+//
+// source.hh -- part of LilyPond
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef SOURCE_HH
+#define SOURCE_HH
+
+class Source
+{
+public:
+ Source();
+ ~Source();
+
+ void add( Source_file* sourcefile_p );
+ Source_file* sourcefile_l( char const* ch_c_l );
+
+private:
+ IPointerList<Source_file*> sourcefile_p_iplist_;
+};
+
+
+// ugh
+extern Source* source_l_g;
+
+#endif // SOURCE_HH //
--- /dev/null
+/*
+ some 2D geometrical concepts
+*/
+
+#ifndef BOXES_HH
+#define BOXES_HH
+
+#include "fproto.hh"
+#include "real.hh"
+#include "interval.hh"
+#include "offset.hh"
+
+/// a square subset of Real^2
+struct Box {
+ Interval x, y;
+
+ void translate(Offset o) {
+ x.translate(o.x);
+ y.translate(o.y);
+ }
+ /// smallest box enclosing #b#
+ void unite(Box b) {
+ x.unite(b.x);
+ y.unite(b.y);
+ }
+ Box();
+ Box(Interval ix, Interval iy);
+};
+
+
+#endif
--- /dev/null
+/*
+ break.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef BREAK_HH
+#define BREAK_HH
+#include "varray.hh"
+#include "proto.hh"
+#include "colhpos.hh"
+
+/** Class representation of an algorithm which decides where to put
+ the column, and where to break lines. */
+struct Break_algorithm {
+ PScore &pscore_;
+ Real linelength;
+
+ /* *************** */
+
+ Break_algorithm(PScore&);
+
+ /// check if the spacing/breaking problem is well-stated
+ void problem_OK()const;
+
+ /// search all pcols which are breakable.
+ Line_of_cols find_breaks() const;
+
+ /// helper: solve for the columns in #curline#.
+ Col_hpositions solve_line(Line_of_cols) const;
+
+ /// does curline fit on the paper?
+ bool feasible(Line_of_cols)const;
+
+ virtual Array<Col_hpositions> solve()=0;
+};
+
+/// wordwrap type algorithm: move to next line if current is optimal.
+struct Word_wrap : Break_algorithm {
+ virtual Array<Col_hpositions> solve();
+ Word_wrap(PScore&);
+};
+#endif // BREAK_HH
+
--- /dev/null
+/*
+ colhpos.hh -- part of LilyPond
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#ifndef COLHPOS_HH
+#define COLHPOS_HH
+#include "varray.hh"
+#include "proto.hh"
+
+typedef Array<PCol*> Line_of_cols;
+
+struct Col_hpositions {
+ Line_of_cols cols;
+ Array<Real> config;
+ Real energy;
+
+ /* ************** */
+ void OK()const;
+
+ Col_hpositions();
+ void add( PCol*c);
+ void print() const;
+};
+
+
+#endif // COLHPOS_HH
+
--- /dev/null
+/*
+ commandrequest.hh -- declare Non musical requests
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef COMMANDREQUEST_HH
+#define COMMANDREQUEST_HH
+
+#include "request.hh"
+#include "varray.hh"
+
+/** Request which are assumed to be "happening" before the
+ musical requests. */
+struct Command_req : virtual Request {
+ REQUESTMETHODS(Command_req, command);
+
+ virtual Measure_grouping_req * measuregrouping() { return 0; }
+ virtual Clef_change_req * clefchange() { return 0; }
+ virtual Key_change_req * keychange() { return 0; }
+ virtual Partial_measure_req * partial() { return 0; }
+ virtual Meter_change_req * meterchange() { return 0; }
+ virtual Bar_req *bar() { return 0; }
+ virtual Cadenza_req *cadenza() { return 0; }
+ virtual Timing_req*timing() { return 0; }
+};
+
+
+/** Baseclass for meter/partial req. It has to be handled by
+ Staff_{walker,column} baseclass. */
+struct Timing_req : Command_req {
+ REQUESTMETHODS(Timing_req, timing);
+};
+
+
+struct Partial_measure_req : Timing_req {
+ Moment duration_;
+
+ Partial_measure_req(Moment);
+ REQUESTMETHODS(Partial_measure_req, partial);
+};
+
+/**
+ todo: allow C meter
+ */
+struct Meter_change_req : Timing_req {
+ int beats_i_, one_beat_i_;
+
+ Meter_change_req();
+ void set(int,int);
+ REQUESTMETHODS(Meter_change_req, meterchange);
+};
+
+/// toggle Cadenza mode
+struct Cadenza_req : Timing_req {
+ /// turn on?
+ bool on_b_;
+ Cadenza_req(bool);
+ REQUESTMETHODS(Cadenza_req,cadenza);
+};
+
+/// check if we're at start of a measure.
+struct Barcheck_req : Timing_req {
+
+ REQUESTMETHODS(Barcheck_req,barcheck);
+};
+
+struct Measure_grouping_req: Timing_req {
+ Array<int> beat_i_arr_;
+ Array<Moment> elt_length_arr_;
+
+ REQUESTMETHODS(Measure_grouping_req, measuregrouping);
+};
+
+struct Group_change_req : Command_req {
+ String newgroup_str_;
+ REQUESTMETHODS(Group_change_req, groupchange);
+};
+
+/** draw a (repeat)-bar. This something different than #Barcheck_req#,
+ the latter should only happen at the start of a measure. */
+struct Bar_req : Command_req {
+ String type_str_;
+ Bar_req(String);
+ int compare(const Bar_req&)const;
+ REQUESTMETHODS(Bar_req,bar);
+};
+struct Terminate_voice_req : Command_req {
+ REQUESTMETHODS(Terminate_voice_req,terminate);
+};
+
+struct Group_feature_req : Command_req {
+ int stemdir_i_;
+ Group_feature_req();
+ REQUESTMETHODS(Group_feature_req, groupfeature);
+};
+
+
+struct Key_change_req : Command_req {
+ Array<Melodic_req*> melodic_p_arr_;
+
+ Key_change_req();
+ Key_change_req(Key_change_req const&);
+ ~Key_change_req();
+ REQUESTMETHODS(Key_change_req, keychange);
+};
+
+struct Clef_change_req : Command_req {
+ String clef_str_;
+ Clef_change_req(String);
+ REQUESTMETHODS(Clef_change_req, clefchange);
+};
+
+#endif // COMMANDREQUEST_HH
--- /dev/null
+/*
+ global constants
+ */
+#ifndef CONST_HH
+#define CONST_HH
+#include <math.h>
+#include "real.hh"
+
+const Real EPS=1e-7; // qlpsolve.hh
+const int MAXITER=100; // qlpsolve.hh
+const Real INFTY=HUGE_VAL;
+#endif
--- /dev/null
+#ifndef DIMEN_HH
+#define DIMEN_HH
+
+#include "real.hh"
+#include "string.hh"
+
+const Real INCH_TO_PT=72.0;
+const Real CM_TO_PT=INCH_TO_PT/2.54;
+const Real MM_TO_PT=CM_TO_PT/10;
+const Real PT_TO_PT =1.0;
+
+#define PT *PT_TO_PT
+#define MM *MM_TO_PT
+#define CM *CM_TO_PT
+#define INCH *INCH_TO_PT
+
+Real parse_dimen(String);
+String print_dimen(Real);
+Real convert_dimen(Real, String);
+#endif
+
--- /dev/null
+#ifndef GLOB_HH
+#define GLOB_HH
+#include <assert.h>
+#include <math.h>
+#include "real.hh"
+
+#include "proto.hh"
+#include "const.hh"
+#endif
--- /dev/null
+/*
+ headreg.hh -- part of LilyPond
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef HEADREG_HH
+#define HEADREG_HH
+#include "register.hh"
+
+struct Notehead_register : Request_register {
+ Item* note_p_;
+ int dir_i_;
+ /* *************** */
+ Notehead_register(Complex_walker*);
+ virtual bool try_request(Request *req_l) ;
+ virtual void process_request();
+ virtual void do_pre_move_process();
+ void set_dir(int);
+};
+
+
+#endif // HEADREG_HH
--- /dev/null
+/*
+ idealspacing.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef IDEALSPACING_HH
+#define IDEALSPACING_HH
+#include "proto.hh"
+
+/// ideal spacing between two columns
+struct Idealspacing {
+
+ /// the ideal distance
+ Real space;
+
+ /// Hooke's constant: how strong are the "springs" attached to columns
+ Real hooke;
+
+ /// the two columns
+ const PCol *left, *right;
+
+ void print()const;
+ void OK() const ;
+ Idealspacing(const PCol *left,const PCol *right);
+};
+
+
+#endif // IDEALSPACING_HH
+
--- /dev/null
+/*
+ key.hh -- declare Key
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef KEY_HH
+#define KEY_HH
+
+#include "varray.hh"
+#include "scalar.hh"
+
+/// administration of current key
+class Key {
+ Array<int> accidental_i_arr_;
+
+ /* *************** */
+
+public:
+
+ Key();
+ void set(int i, int acc);
+ int acc(int i)const { return accidental_i_arr_[i]; }
+};
+
+/// administration of accidentals
+struct Local_key
+{
+ void reset(Key);
+ Key& oct(int);
+ Local_key();
+
+private:
+ Array<Key> octaves;
+};
+
+#endif // KEY_HH
+
+
--- /dev/null
+/*
+ keyword.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef KEYWORD_HH
+#define KEYWORD_HH
+
+/* for the keyword table */
+struct Keyword_ent
+{
+ const char *name;
+ int tokcode;
+};
+
+struct Keyword_table
+{
+ Keyword_ent *table;
+ int maxkey;
+ Keyword_table(Keyword_ent *);
+ int lookup(const char *s) const;
+};
+
+
+#endif // KEYWORD_HH
+
--- /dev/null
+/*
+ leastsquare.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef LEASTSQUARE_HH
+#define LEASTSQUARE_HH
+#include "varray.hh"
+#include "offset.hh"
+
+
+/**
+ Least squares minimisation in 2 variables.
+ */
+struct Least_squares {
+ Array<Offset> input;
+ void minimise(Real &coef, Real &offset);
+ void OK() const;
+};
+
+
+#endif // LEASTSQUARE_HH
+
--- /dev/null
+#ifndef PROBLEM_HH
+#define PROBLEM_HH
+
+#include "glob.hh"
+#include "plist.hh"
+#include "varray.hh"
+#include "vector.hh"
+#include "interval.hh"
+
+/// helper struct for #Spacing_problem#
+struct Colinfo {
+ const PCol *pcol_;
+ const Real* fixpos;
+ Interval width;
+
+ /* *************** */
+ Colinfo();
+ void operator=(Colinfo const&);
+ Colinfo(Colinfo const&);
+ ~Colinfo();
+ Colinfo(const PCol*,const Real*);
+ void print() const;
+ bool fixed() const { return fixpos;}
+ Real fixed_position()const { return *fixpos; }
+ Real minright() const { return width.right; }
+ Real minleft() const { return -width.left; }
+};
+
+
+/** the problem, given by the columns (which include constraints) and
+ intercolumn spacing. The problem is:
+
+ Generate a spacing which
+ \begin{itemize}
+ \item
+ Satisfies spacing constraints (notes can't be printed through each other)
+ \item
+ Looks good, ie tries to conform to an ideal spacing as much as possible.
+ \end{itemize}
+ This is converted by regarding idealspacing as "springs" attached
+ to columns. The equilibrium of one spring is the ideal
+ distance. The columns have a size, this imposes "hard" constraints
+ on the distances. This transforms the problem into a quadratic
+ programming problem with linear constraints.
+
+ The quality is given by the total potential energy in the
+ springs. The lower the energy, the better the configuration.
+*/
+class Spacing_problem {
+ Array<const Idealspacing*> ideals;
+ Array<Colinfo> cols;
+
+ /// the index of #c# in #cols#
+ int col_id(const PCol *c) const;
+
+ /// generate an (nonoptimal) solution
+ Vector find_initial_solution() const;
+
+ /// check if problem is too tight
+ bool check_feasible() const;
+
+ /// does #this# contain the column #w#?
+ bool contains(const PCol *w);
+
+ /// make the energy function
+ void make_matrices(Matrix &quad, Vector &lin,Real&) const;
+
+ /// generate the LP constraints
+ void make_constraints(Mixed_qp& lp) const;
+
+public:
+ /** solve the spacing problem
+
+ @return the column positions, and the energy (last element)
+
+ */
+ Array<Real> solve() const;
+
+
+ /**
+ add a idealspacing to the problem.
+
+ One pair of columns can have no, one or more idealspacings,
+ since they can be "summed" if the columns to which #i# refers are
+ not in this problem, the spacing is ignored.
+ */
+ void add_ideal(const Idealspacing *i);
+
+
+ /** add a col to the problem. columns have to be added left to right. The column contains
+ info on it's minimum width.
+ */
+ void add_column(const PCol *, bool fixed=false, Real fixpos=0.0);
+
+
+
+ bool check_constraints(Vector v) const;
+
+ Vector try_initial_solution() const;
+ void OK() const;
+ void print() const;
+ void print_ideal(const Idealspacing*)const;
+};
+
+
+#endif
--- /dev/null
+/*
+ lyricstaff.hh -- part of LilyPond
+
+ copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+ */
+
+#ifndef LYRICSTAFF_HH
+#define LYRICSTAFF_HH
+
+#include "staff.hh"
+
+/**
+ Hungarian prefix lstaff
+ */
+struct Lyric_staff : Staff {
+ virtual void set_output(PScore *);
+ virtual Staff_walker *get_walker_p();
+};
+
+#endif // LYRICSTAFF_HH
+
+
+
+
--- /dev/null
+#ifndef MISC_HH
+#define MISC_HH
+
+#include "proto.hh"
+#include "real.hh"
+#include "moment.hh"
+#include "scalar.hh"
+#include "grouping.hh"
+
+Moment wholes(int dur, int dots);
+double log_2(double x) ;
+int intlog2(int d);
+inline int
+abs(int i){
+ return (i < 0)?-i:i;
+}
+inline int
+sign(int i) {
+ if (i<0) return -1;
+ else if (i) return 1;
+ else return 0;
+}
+
+Interval itemlist_width(const Array<Item*> &its);
+
+#endif
--- /dev/null
+#ifndef MOLECULE_HH
+#define MOLECULE_HH
+
+#include "proto.hh"
+#include "plist.hh"
+#include "boxes.hh"
+#include "symbol.hh"
+
+/// a symbol which can be translated, and freely copied
+struct Atom {
+ Offset off;
+ Symbol sym;
+
+ /* *************** */
+
+ void translate(Offset o) {
+ off += o;
+ }
+
+ /// how big is #this#?
+ Box extent() const;
+ Atom(Symbol s);
+
+ void print() const;
+
+ String TeXstring() const;
+};
+
+
+/** a group of individually translated symbols. You can add molecules
+ to the top, to the right, etc. */
+struct Molecule {
+ IPointerList<Atom*> ats; // change to List<Atom>?
+
+ /* *************** */
+
+ Molecule() { }
+ Molecule(Atom a) { add(a) ; }
+
+ void add_right(const Molecule &m);
+ void add_left(const Molecule &m);
+ void add_top(const Molecule &m);
+ void add_bottom(const Molecule &m);
+ void add(Molecule const &m);
+ void translate(Offset);
+ void add(Atom a) { ats.bottom().add(new Atom(a)); }
+ /// how big is #this#?
+ Box extent() const;
+
+ String TeXstring() const;
+
+ Molecule(const Molecule&s);
+ void print() const;
+private:
+ void operator=(const Molecule&);
+};
+#endif
--- /dev/null
+/*
+ musicalrequests.hh -- declare Musical requests
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef MUSICALREQUESTS_HH
+#define MUSICALREQUESTS_HH
+
+#include "request.hh"
+
+
+/**
+ A request which is coupled to a #Voice_element# with nonzero duration.
+ Base class only
+ */
+struct Musical_req : virtual Request {
+ virtual Skip_req* skip() { return 0; }
+ REQUESTMETHODS(Musical_req, musical);
+};
+
+
+struct Skip_req : Musical_req {
+ Moment duration_;
+
+ virtual Moment duration() const;
+ REQUESTMETHODS(Skip_req, skip);
+};
+/** a request with a duration.
+ This request is used only a base class.
+ */
+struct Rhythmic_req : virtual Musical_req {
+ int balltype;
+ int dots;
+ Moment plet_factor;
+ /* *************** */
+ static int compare(const Rhythmic_req &, const Rhythmic_req &);
+ virtual Moment duration() const;
+ Rhythmic_req();
+ Rhythmic_req(int,int);
+ REQUESTMETHODS(Rhythmic_req, rhythmic);
+};
+
+struct Spacing_req :virtual Request {
+ Moment next;
+ Real distance;
+ Real strength;
+ /* *************** */
+ Spacing_req();
+ REQUESTMETHODS(Spacing_req, spacing);
+};
+
+struct Blank_req : Spacing_req, Rhythmic_req {
+ REQUESTMETHODS(Spacing_req, spacing);
+
+};
+
+/// Put a text above or below (?) this staff.
+struct Text_req : virtual Musical_req {
+ /// preferred position (above/below)
+ int dir_i_;
+ /// the characteristics of the text
+ Text_def *tdef_p_;
+ /* *************** */
+ Text_req(int d, Text_def*);
+ ~Text_req();
+ Text_req(Text_req const&);
+ static int compare(const Text_req&,const Text_req&);
+ REQUESTMETHODS(Text_req,text);
+};
+
+/** Put a text in lyric_staff
+ @see Lyric_staff
+ */
+struct Lyric_req : public Rhythmic_req, Text_req {
+ Lyric_req(Text_def* t_p);
+ REQUESTMETHODS(Lyric_req, lreq_l);
+};
+
+/// request which has some kind of pitch
+struct Melodic_req :virtual Musical_req
+{
+ /// 0 is c, 6 is b
+ int notename_i_;
+ /// 0 is central c
+ int octave_i_;
+
+ /// 0 natural, 1 sharp, etc
+ int accidental_i_;
+
+ /// force/supress printing of accidental.
+ bool forceacc_b_;
+
+ /// return height from central c (in halflines)
+ int height()const;
+ /// return pitch from central c (in halfnotes)
+ int pitch()const;
+ Melodic_req();
+
+ REQUESTMETHODS(Melodic_req,melodic);
+};
+
+/// Put a note of specified type, height, and with accidental on the staff.
+struct Note_req : Rhythmic_req, virtual Melodic_req {
+
+
+ Rhythmic_req* rhythmic() { return Rhythmic_req::rhythmic(); }
+ REQUESTMETHODS(Note_req, note);
+ };
+
+/**
+Put a rest on the staff. Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
+*/
+class Rest_req : public Rhythmic_req {
+public:
+ REQUESTMETHODS(Rest_req,rest);
+};
+
+/**
+ attach a stem to the noteball.
+ Rhythmic_req parent needed to determine if it will fit inside a beam.
+ */
+struct Stem_req : Rhythmic_req {
+ /// preferred direction for the stem
+ int dir_i_;
+ Stem_req(int s, int dots);
+ REQUESTMETHODS(Stem_req,stem);
+};
+
+/**
+ Requests to start or stop something.
+ This type of request typically results in the creation of a #Spanner#
+*/
+struct Span_req : Musical_req {
+ /// should the spanner start or stop, or is it unwanted?
+ enum {
+ NOSPAN, START, STOP
+ } spantype ;
+ static int compare(const Span_req &r1, const Span_req &r2);
+ REQUESTMETHODS(Span_req,span);
+
+ Span_req();
+
+};
+
+/// request for backward plet generation
+struct Plet_req : Request {
+ char type_c_;
+ int dur_i_;
+ int type_i_;
+ Plet_req();
+
+ REQUESTMETHODS(Plet_req,plet);
+};
+/**
+*/
+
+/** Start / stop a beam at this note. if #nplet# is set, the staff will try to put an
+appropriate number over the beam
+ */
+struct Beam_req : Span_req {
+ int nplet;
+
+ /* *************** */
+ REQUESTMETHODS(Beam_req,beam);
+
+ Beam_req();
+};
+
+/// a slur
+struct Slur_req : Span_req {
+ REQUESTMETHODS(Slur_req,slur);
+
+};
+
+
+/**Put a script above or below this ``note''. eg upbow, downbow. Why a
+request? These symbols may conflict with slurs and brackets, so this
+also a request */
+struct Script_req : Musical_req {
+ int dir_i_;
+ Script_def *scriptdef_p_;
+
+ /* *************** */
+ static int compare(const Script_req &, const Script_req &);
+ Script_req(int d, Script_def*);
+ REQUESTMETHODS(Script_req,script);
+ ~Script_req();
+ Script_req(Script_req const&);
+};
+
+
+
+
+#endif // MUSICALREQUESTS_HH
--- /dev/null
+/*
+ notename.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef NOTENAME_HH
+#define NOTENAME_HH
+
+#include "string.hh"
+
+struct Notename_tab {
+ String notetab[7*5];
+
+ void set(int l, int s, String nm);
+ void lookup(int &large, int &small, String s);
+};
+
+void set_notename_tab(Notename_tab*n);
+void lookup_notename(int &large, int &small, String s);
+
+
+#endif // NOTENAME_HH
+
--- /dev/null
+/*
+ offset.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef OFFSET_HH
+#define OFFSET_HH
+#include "real.hh"
+
+/// 2d vector
+struct Offset {
+ Real x,y;
+
+ Offset operator+(Offset o)const {
+ Offset r(*this);
+ r+=o;
+ return r;
+ }
+
+ Offset operator+=(Offset o) {
+ x+=o.x;
+ y+=o.y;
+ return *this;
+ }
+ Offset(Real ix , Real iy) {
+ x=ix;
+ y=iy;
+ }
+ Offset() {
+ x=0.0;
+ y=0.0;
+ }
+};
+
+#endif // OFFSET_HH
+
+
--- /dev/null
+#ifndef PSTAFF_HH
+#define PSTAFF_HH
+
+#include "proto.hh"
+#include "plist.hh"
+#include "item.hh"
+#include "symbol.hh"
+
+/// items grouped horizontally
+struct PStaff {
+ PScore * pscore_l_;
+
+
+ PointerList<const Spanner*> spans;
+ PointerList<Item*> its;
+
+ /* *************** */
+ void add(Item*i);
+ PStaff(PScore*);
+
+private:
+ PStaff(PStaff const&);
+};
+
+#endif
--- /dev/null
+/*
+ parseconstruct.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef PARSECONSTRUCT_HH
+#define PARSECONSTRUCT_HH
+
+#include "proto.hh"
+
+extern char const* defined_ch_c_l;
+extern char const* req_defined_ch_c_l;
+void set_default_duration(int *);
+void last_duration(int n);
+void set_duration_mode(String s);
+void get_default_duration(int *);
+void set_default_octave(String);
+void set_plet(int,int);
+Voice_element * get_note_element(String,int * ,int *);
+Voice_element* get_rest_element(String,int *);
+Voice_element* get_word_element(Text_def*, int*);
+void add_requests( Voice_element*v, Array<Request*>&req);
+Request* get_request(char);
+void set_text_style(String);
+Script_def* get_scriptdef(char);
+Text_def*get_text(String s);
+Request* get_plet_request( char c, int dur_i, int type_i );
+Request*get_script_req(int d , Script_def*def);
+Request*get_text_req(int d , Text_def*def);
+Request* get_stemdir_req(int);
+
+
+
+
+Request*get_grouping_req(Array<int> i_arr);
+
+#endif // PARSECONSTRUCT_HH
+
--- /dev/null
+#ifndef COLS_HH
+#define COLS_HH
+
+#include "glob.hh"
+#include "boxes.hh"
+#include "plist.hh"
+#include "item.hh"
+
+
+/**
+ stuff grouped vertically.
+ This is a class to address items vertically. It contains the data for:
+ \begin{itemize}
+ \item
+ unbroken score
+ \item
+ broken score
+ \item
+ the linespacing problem
+ \end{itemize}
+ */
+
+struct PCol {
+ PointerList<const Item*> its;
+ PointerList<const Spanner*> stoppers, starters;
+
+
+
+ /** prebreak is put before end of line.
+ if broken here, then (*this) column is discarded, and prebreak
+ is put at end of line, owned by Col
+ */
+ PCol *prebreak_p_;
+
+ /// postbreak at beginning of the new line
+ PCol *postbreak_p_;
+
+ /** if this column is pre or postbreak, then this field points to
+ the parent. */
+ PCol *daddy_l_;
+
+ /// if lines are broken then this column is in #line#
+ const Line_of_score *line_l_;
+
+ /// if lines are broken then this column x-coord #hpos#
+ Real hpos;
+
+ PScore * pscore_l_;
+
+ /* *************** */
+ /// which one (left =0)
+ int rank() const;
+
+ /// does this column have items
+ bool used_b() const;
+
+ void add(Item *i);
+
+ /// Can this be broken? true eg. for bars.
+ bool breakable_b()const;
+
+ Interval width() const;
+ ~PCol();
+ PCol(PCol * parent);
+
+ /**
+ which col comes first?.
+ signed compare on columns.
+
+ @return < 0 if c1 < c2.
+ */static int compare(const PCol &c1, const PCol &c2);
+
+
+ void OK() const;
+ void set_breakable();
+ void print()const;
+private:
+ PCol(PCol const&){}
+};
+
+
+#include "compare.hh"
+instantiate_compare(PCol &, PCol::compare);
+
+
+#endif
--- /dev/null
+/*
+ qlp.hh -- declare Ineq_constrained_qp, Mixed_qp
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#ifndef QLP_HH
+#define QLP_HH
+
+#include "matrix.hh"
+
+/// inequality constrained quadratic program
+class Ineq_constrained_qp {
+ friend class Active_constraints;
+
+ Array<Vector> cons;
+ Array<Real> consrhs;
+public:
+ Matrix quad;
+ Vector lin;
+ Real const_term;
+
+
+ /**
+ use a KKT method to assert optimality of sol
+ */
+ void assert_solution(Vector sol) const;
+ /// solve the problem using a projected gradient method
+ Vector solve(Vector start) const;
+
+ /**
+ @return the number of variables in the problem
+ */
+ int dim() const{
+ return lin.dim();
+ }
+
+ /**
+ add a constraint
+
+
+ c*vars >= r
+
+ PRE
+ c.dim() == dim();
+
+ */
+ void add_inequality_cons(Vector c, double r);
+
+ /** set up matrices to go with the problem. */
+ Ineq_constrained_qp(int novars);
+
+ /**
+ evaluate the quadratic function for input #v#
+ */
+ Real eval(Vector v);
+
+ void eliminate_var(int idx, Real value);
+ void OK()const;
+ void print() const;
+
+};
+
+
+/**
+ Quadratic programming with mixed linear constraints.
+ problem definition of a quadratic optimisation problem with linear
+ inequality and equality constraints
+
+
+ x^T QUAD x /2 + b^T x
+*/
+class Mixed_qp :public Ineq_constrained_qp {
+ Array<int> eq_cons;
+ Array<Real> eq_consrhs;
+public:
+ Mixed_qp(int n);
+ void OK() const;
+ void print() const;
+
+ Vector solve(Vector start) const;
+ void add_fixed_var(int i , Real value);
+
+
+ /**
+ add a constraint,
+
+ c*vars == r
+
+ PRE
+ c.dim()==dim();
+ */
+ void add_equality_cons(Vector c, double r);
+};
+#endif
--- /dev/null
+/*
+ qlpsolve.hh -- declare Active_constraints, Inactive_iter
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef QLPSOLVE_HH
+#define QLPSOLVE_HH
+#include "qlp.hh"
+#include "matrix.hh"
+
+
+/**
+ This class represents the set of active (binding) constraints
+ which can be active while the QLP algorithm is in a feasible
+ point. The active constraints are numbered.
+ If the constraints are of the form
+
+ A^T*x >= b
+
+ then the binding constraints are those where the >= is equality.
+
+ */
+
+class Active_constraints {
+ friend class Inactive_iter;
+
+
+ Matrix A,H;
+ Array<int> active;
+ Array<int> inactive; // actually this is a set, not an array.
+ const Ineq_constrained_qp *opt;
+
+public:
+ String status()const;
+
+ Vector vec(int k) const { return opt->cons[k]; }
+ Real rhs(int k) const { return opt->consrhs[k]; }
+
+
+ /** drop constraint. drop constraint k from the active set. k is the index of the
+ constraint in #active#
+
+ */
+ void drop (int k);
+
+
+ /** add constraint j.
+ add constraint j to the active set j is the index of the
+ constraint in #inactive#
+ */
+ void add(int j);
+
+ /// exchange in and out.
+ void exchange(int in, int out) { add(in); drop (out); }
+
+
+ Vector find_active_optimum(Vector g);
+
+ /// get lagrange multipliers.
+ Vector get_lagrange(Vector v);
+
+ Active_constraints(Ineq_constrained_qp const *op);
+ /** construct: no constraints active, n vars. Put the equalities
+ into the constraints. */
+
+ /// check invariants
+ void OK();
+};
+
+
+/**
+ loop through the inactive constraints.
+ */
+class Inactive_iter {
+ int j;
+ Active_constraints const* ac;
+public:
+ Inactive_iter(Active_constraints const &c) { ac=&c; j=0; }
+ int idx() const { return j; }
+ void operator ++(int) { j++; }
+ int constraint_id() const { return ac->inactive[j]; }
+ Vector vec() const { return ac->vec(constraint_id()); }
+ Real rhs() const { return ac->rhs(constraint_id()); }
+ bool ok() const { return j < ac->inactive.size(); }
+};
+
+#endif // QLPSOLVE_HH
--- /dev/null
+#if 0
+
+
+
+/**Draw a (Guitar) chord above or below this ``note''.
+Why a request?
+Because everything else is done in requests.
+*/
+struct Chord : Request {
+ // don't know how this looks.
+};
+
+
+/// for absolute dynamics
+enum Loudness {
+ FFF, FF, F, MF, MP, P, PP, PPP
+} ;
+
+
+/**
+Start/stop a bracket at this note. if #nplet# is set, the staff will
+try to put an appropriate number over the bracket
+*/
+struct Bracket_req : Span_req {
+ int nplet; // print a number over the beam.
+};
+
+struct Subtle_req {
+ Moment subtime;
+};
+
+
+/** helper in the hierarchy. Each dynamic is bound to one note ( a
+ crescendo spanning multiple notes is thought to be made of two
+ "dynamics": a start and a stop). Dynamic changes can occur in a
+ smaller time than the length of its note, therefore fore each
+ Dynamic request carries a time, measured from the start of its
+ note.
+
+ This subfield would come in handy, if mpp96 was adapted for midi
+ support.
+
+ Dynamic should have been derived from request, but I don't want to
+ fuss with virtual baseclasses. */
+
+struct Dynamic:Subtle_req {
+
+};
+/// do a crescendo
+struct Cresc_req : Span_req, Dynamic {
+
+};
+
+/// do a decrescendo
+struct Decresc_req : Span_req, Dynamic {
+
+};
+
+/// do a dynamic like "fff" or "mp"
+struct Absdynamic_req : Request, Dynamic {
+ Loudness loudness;
+};
+
+struct Grace_req : Subtle_req {
+
+};
+
+struct Grace_turn_req : Grace_turn {
+
+};
+
+struct Grace_note : Melodic_req {
+
+};
+
+struct Grace_notes {
+
+};
+
+struct Glissando_req : Span_req {
+
+};
+#endif
--- /dev/null
+/*
+ sccol.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef SCCOL_HH
+#define SCCOL_HH
+#include "proto.hh"
+#include "varray.hh"
+#include "moment.hh"
+
+
+/**
+
+ When typesetting hasn't started on PScore yet, the columns which
+ contain data have a rhythmical position. Score_column is the type
+ with a rhythmical time attached to it. The calculation of
+ idealspacing is done with data in these columns. (notably: the
+ #durations# field)
+
+ */
+
+class Score_column {
+ friend class Score;
+ friend class Score_walker;
+
+ bool musical_b_;
+ Moment when_;
+ void set_breakable();
+public:
+ /// indirection to column
+ PCol * pcol_l_;
+
+ /// length of notes/rests in this column
+ Array<Moment> durations;
+
+ /* *************** */
+
+ Moment when() { return when_; }
+ Score_column(Moment when);
+ static int compare(Score_column & c1, Score_column &c2);
+ void add_duration(Moment );
+ void preprocess();
+ bool breakable_b();
+ bool musical_b() { return musical_b_; }
+ bool used_b();
+ void print() const;
+
+
+};
+
+instantiate_compare(Score_column&, Score_column::compare);
+
+#endif // SCCOL_HH
+
+
+
+
--- /dev/null
+/*
+ scoreline.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef SCORELINE_HH
+#define SCORELINE_HH
+#include "proto.hh"
+#include "plist.hh"
+#include "varray.hh"
+
+/// the columns of a score that form one line.
+struct
+Line_of_score {
+ PointerList<PCol *> cols;
+
+ // need to store height of each staff.
+ IPointerList<Line_of_staff*> staffs;
+ PScore * pscore_l_; // needed to generate staffs
+
+ /* *************** */
+ void process() ;
+ Line_of_score(Array<PCol *> sv, PScore *);
+
+ String TeXstring() const;
+
+ // is #c# contained in #*this#?
+ bool element(const PCol *c);
+};
+
+#endif
+
--- /dev/null
+/*
+ staffelem.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef STAFFELEM_HH
+#define STAFFELEM_HH
+#include "varray.hh"
+#include "proto.hh"
+#include "offset.hh"
+#include "molecule.hh"
+
+/** Both Spanner and Item are Staff_elem's. Most Staff_elem's depend
+ on other Staff_elem's, eg, Beam needs to know and set direction of
+ Stem. So the Beam has to be calculated *before* Stem. This is
+ accomplished with the dependencies field of struct Staff_elem.
+
+ */
+struct Staff_elem {
+ enum Status {
+ ORPHAN, // not yet added to pstaff
+ VIRGIN, // added to pstaff
+ PRECALCING,
+ PRECALCED, // calcs before spacing done
+ POSTCALCING,
+ POSTCALCED, // after spacing calcs done
+ OUTPUT, // molecule has been output
+ } status;
+
+ /// the pstaff it is in
+ PStaff *pstaff_l_;
+
+ /* *************** */
+ Staff_elem(Staff_elem const&);
+ String TeXstring () const ;
+ virtual void print() const;
+ virtual Interval width() const;
+ virtual Interval height() const;
+ Paperdef *paper() const;
+ virtual ~Staff_elem();
+ Staff_elem();
+
+ void translate(Offset);
+ void add_processing();
+ void pre_processing();
+ void post_processing();
+ void molecule_processing();
+ virtual const char *name() const; // to find out derived classes.
+ virtual Spanner* spanner() { return 0; }
+ virtual Item * item() { return 0; }
+ void add_depedency(Staff_elem* );
+ void substitute_dependency(Staff_elem* old, Staff_elem * newdep);
+protected:
+
+ /// do printing of derived info.
+ virtual void do_print() const=0;
+ /// generate the molecule
+ virtual Molecule* brew_molecule_p()const=0;
+ ///executed directly after the item is added to the PScore
+ virtual void do_add_processing();
+ /// do calculations before determining horizontal spacing
+ virtual void do_pre_processing();
+
+ /// do calculations after determining horizontal spacing
+ virtual void do_post_processing();
+
+ Array<Staff_elem*> dependants;
+
+private:
+ /// member: the symbols
+ Molecule *output; // should scrap, and use temp var?
+
+
+ /**
+ This is needed, because #output# may still be
+ NULL.
+ */
+ Offset offset_;
+ Array<Staff_elem*> dependencies;
+};
+#define NAME_METHOD(c) const char *c::name()const{ return #c; } struct c
+#endif // STAFFELEM_HH
+
--- /dev/null
+/*
+ staffeleminfo.hh -- declare Staff_elem_info
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef STAFFELEMINFO_HH
+#define STAFFELEMINFO_HH
+
+#include "proto.hh"
+
+/// data container.
+struct Staff_elem_info {
+ Staff_elem * elem_p_;
+ Request*req_l_;
+ const Voice * voice_l_;
+ Voice_group_registers * group_regs_l_;
+ Request_register * origin_reg_l_;
+
+ /* *** */
+ Staff_elem_info(Staff_elem*, Request*, Request_register*);
+ Staff_elem_info();
+};
+
+#endif // STAFFELEMINFO_HH
--- /dev/null
+/*
+ staffline.hh -- horizontal structures for broken scores.
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef STAFFLINE_HH
+#define STAFFLINE_HH
+
+#include "proto.hh"
+#include "real.hh"
+#include "plist.hh"
+#include "varray.hh"
+#include "glob.hh"
+#include "pstaff.hh"
+
+/// one broken line of staff.
+struct Line_of_staff {
+
+ Line_of_score * line_of_score_l_;
+ PStaff *pstaff_l_;
+
+ /* *************** */
+
+ String TeXstring() const;
+ Line_of_staff(Line_of_score*, PStaff *);
+ Interval height() const;
+ void process();
+};
+
+#endif
--- /dev/null
+#ifndef TSTREAM__HH
+#define TSTREAM__HH
+
+#include <iostream.h>
+#include "string.hh"
+
+
+/** TeX output.
+ Use this class for writing to a TeX file.
+ It counts braces to prevent nesting errors, and
+ it will add a comment sign before each newline.
+ */
+struct Tex_stream {
+ bool outputting_comment;
+ ostream *os;
+ int nest_level;
+
+ /// open a file for writing
+ Tex_stream(String filename);
+ void header();
+ /// delegate conversion to string class.
+ Tex_stream &operator<<(String);
+
+ /// close the file
+ ~Tex_stream();
+private:
+ Tex_stream(Tex_stream const&);
+};
+#endif
--- /dev/null
+#ifndef TEX_HH
+#define TEX_HH
+
+#include "string.hh"
+#include "boxes.hh"
+#include "scalar.hh"
+
+/** parameter substitution in TeXstrings.
+ this function provides a simple macro mechanism:
+
+ if source == "tex%bla%", then
+ substitute_args(source, {"X","Y"}) == "texXblaY"
+ */
+String
+substitute_args(String source, Array<String> args);
+
+/// parameter substitution in TeXstrings
+String
+substitute_args(String source, Array<Scalar> args);
+
+/// #h# is in points
+String vstrut(Real h);
+
+
+#endif
--- /dev/null
+/*
+ moment.hh -- part of LilyPond
+
+ (c) 1996,97 Han-Wen Nienhuys
+*/
+
+#ifndef tdes_HH
+#define tdes_HH
+
+#include "moment.hh"
+
+/// full info on where we are
+struct Time_description {
+ Moment when_;
+
+ /// if true, no bars needed, no reduction of whole_in_measure
+ bool cadenza_b_;
+
+ /// current measure info
+ Moment whole_per_measure_;
+
+ /// where am i
+ Moment whole_in_measure_;
+
+ /// how long is one beat?
+ Moment one_beat_;
+
+ /// idem
+ int bars_i_;
+
+ /* *************** */
+ void set_cadenza(bool);
+ void OK() const;
+ Time_description();
+ void add(Moment dt);
+ String str()const;
+ void print() const;
+ void setpartial(Moment p);
+ Moment barleft();
+ void set_meter(int,int);
+ static int compare (Time_description&, Time_description&);
+};
+
+#include "compare.hh"
+
+
+instantiate_compare(Time_description&,Time_description::compare);
+
+#endif // Time_description_HH
+
--- /dev/null
+//
+// track-column.hh -- declare Track_column
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef TRACK_COLUMN_HH
+#define TRACK_COLUMN_HH
+
+/// (tcol)
+class Track_column {
+public:
+ Track_column( Moment mom );
+
+ void add_event( Midi_event* midi_event_p );
+ Moment mom();
+
+//private:
+ IPointerList<Midi_event*> midi_event_p_list_;
+ Moment mom_;
+};
+
+#endif // TRACK_COLUMN_HH
+
--- /dev/null
+\font\musicfont=musixsps
+\font\slurfont=xslu16
+\def\thefont{\musicfont}
+
+\def\mb#1{{\thefont\char#1}}
+
+\newdimen\wid
+\newdimen\inc
+\newdimen\here
+\def\hruler#1{%
+ \wid=#1pt
+ \inc=\wid
+ \divide\inc by #1
+ \divide\wid by 2
+ \here=-\wid
+ \loop\ifdim\here<\wid\advance\here by\inc
+ \hbox to0pt{\kern\here\vrule width0.05pt height 2pt\hss}%
+ \repeat%
+}
+
+\def\vruler#1{%
+ \wid=#1pt
+ \inc=\wid
+ \divide\inc by #1
+ \divide\wid by 2
+ \here=-\wid
+ \loop\ifdim\here<\wid\advance\here by\inc
+ \vbox to0pt{\vskip\here\vrule width2pt height 0.05pt\vss}%
+ \repeat%
+}
+\def\twhrul{\hbox to 0pt{\hbox{\hruler{20}\vrule
+ width0.1pt height 3ptdepth 1pt}}}
+\def\twvrul{\hbox{\vbox to 20pt{\vruler{20}\vrule
+ width3pt height 0.1pt}}}
+
+\def\doitem#1{
+ #1 %
+ %\twvrul%doesn't work
+ \hbox to 50pt{\qquad\twhrul\mb{#1}\hss}\setbox0=\hbox{\mb{#1}} width \the\wd0\ depth \the\dp0 \ height \the\ht0}
+
+\newcount\n
+\def\charn{\n=-1
+ \loop\ifnum\n<255\advance\n by1
+ \doitem{\number\n}\endgraf\repeat}
+
+
+ \charn
+
+\bye
\ No newline at end of file
--- /dev/null
+%%
+%% include file for LilyPond
+
+\def\mdef#1#2{\def#1{\mchar{#2}}}
+\def\mchar#1{\musicfnt\char#1}
+\def\rationalmultiply#1*#2/#3{\multiply #1 by #2 \divide #1 by #3}
+\def\maccentraise#1#2{\dimen0=\noteheight
+ \rationalmultiply\dimen0*#2%
+ \raise\dimen0\hbox{#1}}
+\def\maccentdef#1#2#3{\def#1{\maccentraise{\mchar{#2}}{#3}}}
+\def\vcenter#1{\vbox to 0pt{\vss #1\vss}}
+
+\def\topalign#1{\vbox to 0pt{#1\vss}}
+\def\botalign#1{\vbox to 0pt{\vss #1}}
+
+\def\centeralign#1{\hbox to 0pt{\hss#1\hss}}
+\def\leftalign#1{\hbox to 0pt{#1\hss}}
+\def\rightalign#1{\hbox to 0pt{\hss#1}}
+
+
+%% musix defs
+\parindent=0pt
+\newdimen\smallspace
+\newdimen\interlinedist
+ \newcount\n
+ \newdimen\balkhoog
+ \newdimen\notewidth
+ \newdimen\noteheight
+ \newdimen\notewidthhalf
+ \newdimen\notewidthdouble
+ \newdimen\staffrulethickness
+ \newdimen\interstaffrule
+\newdimen\balkhalf
+\def\musixtwentydefs{
+ \font\textfont=cmr10
+ \font\meterfont=cmbx12
+ \font\slurufont=xslu20
+ \font\slurdfont=xsld20
+ \font\slurhfont=xslz20
+ \font\hslurufont=xslhu20
+ \font\hslurdfont=xslhd20
+ \font\hslurhfont=xslhz20
+ \font\musicfnt=musix20
+ \font\italicfont=cmti10
+ \font\dynfont=cmbxti10 scaled \magstep1
+ \balkhoog=20pt
+ \notewidth=6pt
+ \noteheight=5pt
+ \staffrulethickness=0.4pt
+ \musixcalc
+}
+
+
+\def\musixsixteendefs{
+ \font\textfont=cmr8
+ \font\meterfont=cmbx12
+ \font\italicfont=cmti8
+ \font\slurufont=xslu16
+ \font\slurdfont=xsld16
+ \font\slurhfont=xslz20 % sigh
+ \font\hslurufont=xslhu16
+ \font\hslurdfont=xslhd16
+ \font\hslurhfont=xslhz20
+ \font\musicfnt=musix16
+ \font\dynfont=cmbxti10
+ \balkhoog=16pt
+ \staffrulethickness=0.4pt
+ \notewidth=5pt
+ \noteheight=4pt
+ \musixcalc
+}
+
+\def\musixcalc{
+ \interlinedist=\fontdimen5\musicfnt
+ \smallspace=.3\interlinedist
+ \interstaffrule=\balkhoog
+ \advance\interstaffrule by-\staffrulethickness
+ \divide\interstaffrule by 4
+ \advance\interstaffrule by -\staffrulethickness
+ \notewidthhalf=\notewidth
+ \notewidthdouble=\notewidth
+ \rationalmultiply \notewidthhalf*1/2
+ \multiply \notewidthdouble by 2
+ \balkhalf=\balkhoog
+ \rationalmultiply\balkhalf*1/2
+}
+% \def\dyn{\italicfont}
+\def\dyn{\dynfont}
+\def\dynf{f\kern-.1ex}
+\def\dynm{f\kern-.15ex}
+\def\dynp{p\kern-.15ex}
+\def\ppp{\dynfont\dynp\dynp p}
+\def\pp{\dynfont\dynp p}
+\def\p{\dynfont p}
+\def\mp{\dynfont\dynm p}
+\def\mf{\dynfont\dynm f}
+\def\f{\dynfont f}
+\def\ff{\dynfont\dynf f}
+\def\fff{\dynfont\dynf\dynf f}
+
+\def\slurcharh#1{{\slurhfont\char#1}}
+\def\slurcharu#1{{\slurufont\char#1}}
+\def\slurchard#1{{\slurdfont\char#1}}
+\def\hslurcharh#1{{\hslurhfont\char#1}}
+\def\hslurcharu#1{{\hslurufont\char#1}}
+\def\hslurchard#1{{\hslurdfont\char#1}}
+
+\mdef\quartball{'007}
+\mdef\halfball{'010}
+\mdef\wholeball{'011}
+\mdef\halfrest{'074}
+\mdef\wholerest{'075}
+\mdef\quartrest{62}
+\mdef\eighthrest{63}
+\mdef\sixteenthrest{64}
+\mdef\thirtysecondrest{65}
+\mdef\sharp{52}
+\mdef\flat{50}
+\mdef\natural{54}
+\mdef\sharpsharp{53}
+\mdef\flatflat{51}
+
+\mdef\singledot{'00}
+\mdef\doubledot{'01}
+\mdef\tripledot{'02}
+\mdef\mussepline{155}
+
+\mdef\violinclef{71}
+\mdef\bassclef{73}
+\mdef\altoclef{75}
+\mdef\cviolinclef{72}
+\mdef\cbassclef{74}
+\mdef\caltoclef{76}
+
+\mdef\deigthflag{45}
+\mdef\dsixteenthflag{46}
+\mdef\dthirtysecondflag{47}
+
+% pointing up
+\mdef\ueigthflag{40}
+\mdef\usixteenthflag{41}
+\mdef\uthirtysecondflag{42}
+
+\maccentdef\repeatcolon{55}{2/1}
+\def\emptybar{}
+
+\def\thinbar{\vrule height\balkhoog}
+%? what-s wrong with rightalign?
+\def\thickbar{\vrule height\balkhoog width 2\smallspace}
+\def\maatstreep{\thinbar}
+% \def\finishbar{\rightalign{\thinbar\kern\smallspace\thickbar}}
+\def\finishbar{\hss\rightalign{\thinbar\kern\smallspace\thickbar}}
+% \def\repeatstopbar{\rightalign{\repeatcolon\hskip2\smallspace\thinbar\hskip\smallspace\thickbar}}
+\def\repeatstopbar{\hss\rightalign{\repeatcolon\hskip2\smallspace\thinbar\hskip\smallspace\thickbar}}
+% \def\repeatstopbar{\kern-3\smallspace\rightalign{\repeatcolon\kern2\smallspace\thinbar\kern\smallspace\thickbar}\kern3\smallspace}
+\def\repeatstartbar{\hbox{\thickbar\kern\smallspace\thinbar\kern2\smallspace\repeatcolon}}
+\def\repeatstopstart{\hbox{\repeatcolon\kern2\smallspace\thinbar\kern\smallspace\thickbar\kern\smallspace\thickbar\kern\smallspace\thinbar\kern2\smallspace\repeatcolon}}
+\def\doublebar{\hbox{\thinbar\hskip\smallspace\thinbar}}
+
+%compatability
+\def\repeatbar{\repeatstopbar}
+\def\startrepeat{\repeatstartbar}
+\def\repeatbarstartrepeat{\repeatstopstart}
+
+\def\generalmeter#1#2{\botalign{\vbox to\balkhalf{\vss \meterfont#1}%
+ \nointerlineskip
+ \vbox to \balkhalf{\vss\meterfont #2}}}
+\def\defaultlineseparator{\vbox{\mussepline\vskip -5pt\mussepline}}
+\def\lineseparator{\defaultlineseparator}
+\def\beauty{%
+ \par\vskip 10pt plus 30pt minus 10pt\par
+ \hskip -5pt\lineseparator
+ \par\vskip 10pt plus 30pt minus 10pt\par
+}
+
+\def\interstaffline{%
+ \vskip 10pt
+}
+\def\ugly{\nointerlineskip\par
+\vskip 40pt\par\vbox{\leftalign{\vrule width30pt height1pt}}\par\vskip 40pt
+}
+\def\interscoreline{\beauty}
+
+
+\def\lines#1#2{%
+ \vbox{\kern-\interstaffrule
+ \n=0\nointerlineskip%
+ \loop\ifnum\n<#1\advance\n by1%
+ \kern\interstaffrule
+ \hrule height \staffrulethickness width#2
+ \repeat
+ }}
+
+\def\toplines#1{ % why space needed here?
+ \topalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
+\def\botlines#1{ % idem ditto
+ \botalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
+
+%
+% a staffsymbol with #1 lines, width #2
+% bottom at baseline
+\def\linestafsym#1#2{\leftalign{\botalign{\lines{#1}{#2}}}}
+
+\def\eigthflag{\topalign{\ueigthflag}}
+\def\sixteenthflag{\topalign{\usixteenthflag}}
+\def\thirtysecondflag{\topalign{\uthirtysecondflag}}
+
+\def\cquartrest{\vcenter\quartrest}
+\def\ceighthrest{\vcenter\eighthrest}
+\def\csixteenthrest{\vcenter\sixteenthrest}
+\def\cthirtysecondrest{\vcenter\thirtysecondrest}
+
+\def\lsingledot{\kern-\notewidth\singledot}
+\def\ldoubledot{\kern-\notewidth\doubledot}
+\def\ltripledot{\kern-\notewidth\tripledot}
+
+\maccentdef\sforzato{30}{-3/2}
+\maccentdef\marcato{20}{-1/1}
+\maccentdef\imarcato{21}{1/1}
+\maccentdef\staccato{24}{-1/1}
+\maccentdef\istaccato{25}{1/1}
+\maccentdef\staccatissimo{28}{-1/1}
+\maccentdef\istaccatissimo{29}{1/1}
+\maccentdef\portato{18}{-9/10}
+\maccentdef\iportato{19}{9/10}
+\maccentdef\tenuto{26}{0/1}
+\maccentdef\itenuto{27}{0/1}
+\maccentdef\fermata{80}{-1/1}
+\maccentdef\ifermata{81}{1/1}
+
+
+
+\mdef\spicato{28}
+\mdef\ispicato{29}
+\mdef\upbow{23}
+\mdef\downbow{22}
+\mdef\portato{26}
+
+\def\stem#1#2{\vrule height#2 depth-#1}
+
+\def\placebox#1#2#3{%
+ \botalign{\hbox{\raise #1\leftalign{\kern #2{}#3}}}%
+}
+
+
+\def\beamslope#1#2{{\count0=#2\advance\count0 by#1\musicfnt\char\count0}}
+\def\rulesym#1#2{\vrule height #1 width #2}
+\def\crescendosym#1{\count0=84\advance\count0 by #1}
+\def\decrescendosym#1{\count0=116\advance\count0 by #1}
+\def\settext#1{\textfont #1}
+\def\setitalic#1{\italicfont #1}
--- /dev/null
+% Mats Bengtsson
+\documentclass[a4paper, 10pt]{article}
+
+% Allow for 8-bit characters:
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+
+\begin{document}
+\input lilyponddefs
+\input titledefs
+
+\def\settext#1{\normalfont #1} % Allow for 8-bit characters
+
+\input lelie.out
+\end{document}
--- /dev/null
+\input lilyponddefs
+\input lelie.out
+\vfil\bye
\ No newline at end of file
--- /dev/null
+\def\thetitle{}
+\def\thecomposer{}
+\def\theinstrument{}
+\def\title#1{\def\thetitle{#1}}
+\def\composer#1{\def\thecomposer{#1}}
+\def\instrument#1{\def\theinstrument{#1}}
+
+\def\maketit{
+ \begin{center}
+ {\Large\bfseries\thetitle}\\
+ \vskip12pt
+ {\bfseries\theinstrument}\hfill{\scshape\thecomposer}
+ \end{center}
+ \bigskip
+ }
\ No newline at end of file