From 7a12ad94b16c45bdac527d2a75df23a369799712 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Fri, 19 Mar 2004 22:34:59 +0000 Subject: [PATCH] * scripts/lilypond-book.py (compose_ly): bugfix for relative < 0. (compose_ly): default octave should be middle C. * Documentation/user/changing-defaults.itely (Layout tunings within contexts): new node. * lily/include/smobs.hh: document C++ smob interface. * lily/function-documentation.cc: don't doc functions without docstring. --- ChangeLog | 14 ++- Documentation/user/changing-defaults.itely | 95 +++++++++++++- Documentation/user/lilypond-book.itely | 6 +- flower/include/virtual-methods.hh | 2 + input/test/header-ifelse.ly | 5 +- lily/function-documentation.cc | 3 + lily/include/grace-music.hh | 2 +- lily/include/grob.hh | 2 +- lily/include/interpretation-context-handle.hh | 2 +- lily/include/lily-guile.hh | 8 ++ lily/include/smobs.hh | 116 ++++++++---------- lily/staff-symbol.cc | 2 +- scripts/lilypond-book.py | 4 +- 13 files changed, 178 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8150386abe..46bb2049a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-03-19 Han-Wen Nienhuys + + * scripts/lilypond-book.py (compose_ly): bugfix for relative < 0. + (compose_ly): default octave should be middle C. + + * Documentation/user/changing-defaults.itely (Layout tunings + within contexts): new node. + + * lily/include/smobs.hh: document C++ smob interface. + + * lily/function-documentation.cc: don't doc functions without docstring. + 2004-03-19 Jan Nieuwenhuizen * Documentation/user/lilypond.tely: Remove `* lilypond' node from @@ -34,7 +46,7 @@ * lily/context-specced-music-iterator.cc (construct_children): add support for descend-only context spec. - * lily/note-head.cc (brew_ez_stencil): read vector note-names to + * lily/note-head.cc (brew_ez_stencil): read vector #'note-names to determine ez-notation letter. * lily/system.cc (get_line): start with dumping layer 3. This diff --git a/Documentation/user/changing-defaults.itely b/Documentation/user/changing-defaults.itely index 4f8b824ca1..336b4c9d23 100644 --- a/Documentation/user/changing-defaults.itely +++ b/Documentation/user/changing-defaults.itely @@ -266,8 +266,9 @@ Translation @arrow{} Context. * Creating contexts:: * Changing context properties on the fly :: * Modifying context plug-ins:: +* Layout tunings within contexts:: * Defining context defaults :: -* which properties to change:: +* Which properties to change:: @end menu @node Creating contexts @@ -556,6 +557,91 @@ have score where each staff has its own time signature. @end lilypond +@node Layout tunings within contexts +@subsection Layout tunings within contexts + +Each context is responsible for creating certain types of graphical +objects. The settings used for printing these objects are also stored by +context. By changing these settings, the appearance of objects can be +altered. + +The syntax for this is + +@example + \override @var{context}.@var{name}@code{ #'}@var{property} = #@var{value} +@end example + +Here @var{name} is the name of a graphical object, like @code{Stem} or +@code{NoteHead}. @var{property} is an internal variable of the +formatting system (`grob property' or `layout property'). It is a +symbol, so it must be quoted. The subsection refTODO explains what to +fill in for @var{name}, @var{property} and @var{value}. Here we only +discuss functionality of this command. + +The command + +@verbatim + \override Staff.Stem #'thickness = #4.0 +@end verbatim + +@noindent +makes stems thicker (the default is 1.3, with staff line thickness as a +unit). Since the command specifies @context{Staff} as context, it only +applies to the current staff. Other staves will keep their normal +appearance. Here we see the command in action: + +@lilypond[verbatim,relative=2] + c4 + \override Staff.Stem #'thickness = #4.0 + c4 + c4 + c4 +@end lilypond + +The @code{\override} command is executed during the interpreting phase, +and changes the definition of the @code{Stem} within +@context{Staff}. After the command all stems are thickened. + +Analogous to @code{\set}, the @var{context} argument may be left out, +causing it to default to @context{Voice} and adding @code{\once} applies +the change during only one timestep + +@lilypond[verbatim,relative=2] + c4 + \once \override Stem #'thickness = #4.0 + c4 + c4 +@end lilypond + +The @code{\override} must be done before the object is +started. Therefore, when altering @emph{Spanner} objects, like slurs or +beams, the @code{\override} command must be executed at the moment that +the object is created. In this example, + + + +@lilypond[verbatim,relative=2] + \override Slur #'thickness = #2.0 + c8[( c + \override Beam #'thickness = #0.6 + c8 c]) +@end lilypond + +@noindent +the slur is fatter and the beam is not. This is because the command for +@code{Beam} comes after the Beam is started. Therefore it has no effect. + +Analogous to @code{\unset}, the @code{\revert} command for a context +undoes a @code{\override} command; like with @code{\unset}, it only +affects settings that were made in the same context. In other words, the +@code{\revert} in the next example does not do anything. + +@verbatim + \override Voice.Stem #'thickness = #4.0 + \revert Staff.Stem #'thickness +@end verbatim + + @node Defining context defaults @subsection Defining context defaults @@ -574,11 +660,8 @@ Context properties can be set as defaults, within the @noindent will set skipBars default -When This score-wide - - -@node which properties to change -@subsection which properties to change +@node Which properties to change +@subsection Which properties to change There are many different properties. Not all of them are listed in diff --git a/Documentation/user/lilypond-book.itely b/Documentation/user/lilypond-book.itely index 92f1d8083d..cea6f98b9b 100644 --- a/Documentation/user/lilypond-book.itely +++ b/Documentation/user/lilypond-book.itely @@ -281,7 +281,7 @@ Sets the staff height to @var{ht}, which is measured in points. produces naturally spaced lines (i.e., @code{raggedright = ##t}); this works well for small music fragments. -@item linewidth=@var{size}\\@var{unit} +@item linewidth=@var{size}\@var{unit} sets linewidth to @var{size}, where @var{unit} = cm, mm, in, or pt. This option affects LilyPond output, not the text layout. @@ -293,7 +293,7 @@ prevents printing time signature. overrides @command{lilypond-book} auto detection of what type of code is in the LilyPond block, voice contents, or complete code. -@item indent=@var{size}\\@var{unit} +@item indent=@var{size}\@var{unit} sets indentation of the first music system to @var{size}, where @var{unit} = cm, mm, in, or pt. This option affects LilyPond, not the text layout. For single-line fragments, the default is to @@ -301,7 +301,7 @@ use no indentation. For example @example - \begin[indent=\\5cm,raggedright]@{lilypond@} + \begin[indent=5\cm,raggedright]@{lilypond@} ... \end@{lilypond@} @end example diff --git a/flower/include/virtual-methods.hh b/flower/include/virtual-methods.hh index d466eee89f..44cf1fcaab 100644 --- a/flower/include/virtual-methods.hh +++ b/flower/include/virtual-methods.hh @@ -25,6 +25,8 @@ demangle_classname (std::type_info const &); VIRTUAL_COPY_CONSTRUCTOR (Baseclass, Foo); }; */ +Base *clone () const { return new Name (*this); } + #define VIRTUAL_COPY_CONSTRUCTOR(base, name) \ /* Hack to fix constness: gcc >= 2.95 is correct in defining \ typeof (*this) in a const member function to be const. */ \ diff --git a/input/test/header-ifelse.ly b/input/test/header-ifelse.ly index f472e8e976..52bb9884fb 100644 --- a/input/test/header-ifelse.ly +++ b/input/test/header-ifelse.ly @@ -1,11 +1,8 @@ \version "2.1.30" -#(define (my-ly-version) - (list-head (ly:version) 3)) - #(if (not (defined? 'pieceTagLine)) - (define pieceTagLine (string-append "Jeremie " (ly:numbers->string (my-ly-version)) " was here"))) + (define pieceTagLine (string-append "Jeremie " (lilypond-version) " was here"))) \header{ tagline = \pieceTagLine diff --git a/lily/function-documentation.cc b/lily/function-documentation.cc index b68f53c70b..824efb8f9e 100644 --- a/lily/function-documentation.cc +++ b/lily/function-documentation.cc @@ -9,6 +9,9 @@ void ly_add_function_documentation (SCM func, char const * varlist, char const * doc) { + if (!strlen (doc)) + return ; + if (!gh_vector_p (doc_hash_table )) doc_hash_table = scm_make_vector (gh_int2scm (59), SCM_EOL); diff --git a/lily/include/grace-music.hh b/lily/include/grace-music.hh index 58548fe4ac..6ab3bb0251 100644 --- a/lily/include/grace-music.hh +++ b/lily/include/grace-music.hh @@ -15,7 +15,7 @@ class Grace_music : public Music_wrapper { public: - VIRTUAL_COPY_CONSTRUCTOR (Music, Grace_music); + Music *clone () const { return Grace_music (*this); } Grace_music (); protected: virtual Moment get_length () const; diff --git a/lily/include/grob.hh b/lily/include/grob.hh index fbe0211c98..16bc6c6a26 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -64,7 +64,7 @@ public: Grob (SCM basic_props); Grob (Grob const&); - VIRTUAL_COPY_CONSTRUCTOR (Grob, Grob); + Grob *clone () const { return Grob (*this); } String name () const; diff --git a/lily/include/interpretation-context-handle.hh b/lily/include/interpretation-context-handle.hh index fef9776023..3ba8ee5b4d 100644 --- a/lily/include/interpretation-context-handle.hh +++ b/lily/include/interpretation-context-handle.hh @@ -16,7 +16,7 @@ class Interpretation_context_handle public: ~Interpretation_context_handle (); Interpretation_context_handle (); - Interpretation_context_handle* clone () const; + void set_translator (Context *); bool try_music (Music *); void operator = (Interpretation_context_handle const&); diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 89fb6745e5..aa549f9590 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -267,10 +267,18 @@ typedef SCM (*Scheme_function_2) (...); typedef SCM (*Scheme_function_3) (...); #endif + +/* + Adds the NAME as a Scheme function, and a variable to store the SCM + version of the function. + */ #define DECLARE_SCHEME_CALLBACK(NAME,ARGS) \ static SCM NAME ARGS; \ static SCM NAME ## _proc +/* + Make TYPE::FUNC available as a Scheme function. + */ #define MAKE_SCHEME_CALLBACK(TYPE, FUNC, ARGCOUNT) \ SCM TYPE :: FUNC ## _proc;\ void \ diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index c9e96ae34a..e54fbd480a 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -14,89 +14,79 @@ /* + Smobs are GUILEs mechanism of exporting C(++) objects to the Scheme + world. They are documented in the GUILE manual. - Each smobbed C-object may only be interfaced by a single, unique - smob cell. Therefore NEVER provide a public function that will - create a smobcell for an existing object pointer. - There are two ways to reach this goal: + In LilyPond, smobs are created from C++ objects through macros. + There are two types of smob objects. - simple smobs: + 1. Simple smobs are intended for simple objects like numbers: + immutable objects that can be copied without change of meaning. - - Data structures that are encapsulated by GUILE. If constructed - through GUILE, you may only store them as protected SCMs, and may - not copy the pointer the object itself. Typical interface + To obtain an SCM version of a simple smob, use the member function + SCM smobbed_copy (). - struct Ssmob { - public: - SCM make_copy_scm () const { - Ssmob *sp = new Ssmob (*this); - return sp->smobbed_self (); - } - }; + Simple smobs are created by adding the + DECLARE_SIMPLE_SMOBS(Classname,) to the declaration - or + 2. Complex smobs are objects that have an identity. These objects + carry this identity in the form of a self_scm () method, which is a + SCM pointer to the object itself. - struct Ssmob { - public: - DECLARE_SIMPLE_SMOBS; - static SCM make_scm (void initdata) { - Ssmob * sp = new Ssmob (initdata); - return sp->smobbed_self (); - } - private: - Ssmob (initdata); - } - - Objets of type Ssmob may live on the stack, or on the heap, or as - part of other objects. However, as soon as the object is smobbed, - by definition (by definition of the constructors, in this example), - lives on the heap as a separate object - - - complex smobs: data structures whose identity is referenced and - stored both in C++ and in GUILE form. From going from C++ to GUILE, - you use smob_ptr->self_scm_ - - class Csmob { - DECLARE_SMOBS; - Csmob () { smobify_self (); } - Csmob (Csmob const & s) { - // don't copy self_scm_ + The constructor for a complex smob should have 3 steps: + + * initialize all SCM members to a non-immediate value (like SCM_EOL) + + * call smobify_self () + + * initialize SCM members + + For example, + + Complex_smob::Complex_smob () { + scm_member_ =SCM_EOL; smobify_self (); + scm_member_ = <..what you want to store..> } - }; - A complex smob is a C++ class with static member functions to glue - it with Scheme. Every instance carries SELF_SCM_, a pointer to the - unique Scheme smob cell of itself. + after creation, the self_scm() field of a complex smob is protected + from Garbage Collection. This protection should be removed once the + object is put into another (reachable) Scheme data structure, ie. - Upon creation, SELF_SCM_ is protected, so if you choose to store it - in C++ structures, you need to do + Complex_smob * p = new Complex_smob; + list = scm_cons (p->self_scm (), list); + scm_gc_unprotect_object (p->self_scm ()); - class Bla { - Csmob *ptr; - ~Bla () { scm_gc_unprotect_object (ptr->self_scm_); } - - }; + Complex smobs are made with DECLARE_SMOBS(Classname,) in the class + declaration. - If protection is done via GUILE, don't forget to unprotect AFTER putting - stuff into the GUILE datastructs + CALLING INTERFACE + + Common public methods to C++ smob objects: + unsmob (SCM x) - unpacks X and returns pointer to the C++ object, or 0 + if it has the wrong type. - guile_data = gh_cons (ptr->self_scm_, guile_data); - ptr->self_scm_ + SCM equal_p (SCM a, SCM b) - compare A and B. Returns a Scheme boolean - Since GUILE takes care of the freeing the object, the destructor - is private. + + IMPLEMENTATION + + For implementating a class, the following should be provided - DUMMY a thing to make sure compiles only work if this header - if this file is there. + - an equal_p() function (a default is in the + IMPLEMENT_DEFAULT_EQUAL_P macro in ly-smobs.icc) + - mark_smob () function, that calls scm_gc_mark () on all Scheme + objects in the class - WARNING: + - a print_smob () function, that displays a representation for + debugging purposes - smobify_self () might trigger a GC, so make sure that objects are - sane when you do smobify_self (). + - A call to one of the IMPLEMENT_SMOBS or IMPLEMENT_SIMPLE_SMOBS macros + from file "ly-smobs.icc" + */ #define DECLARE_SIMPLE_SMOBS(CL,dummy) \ diff --git a/lily/staff-symbol.cc b/lily/staff-symbol.cc index 4df7c43e0d..45a06981f5 100644 --- a/lily/staff-symbol.cc +++ b/lily/staff-symbol.cc @@ -63,7 +63,7 @@ Staff_symbol::print (SCM smob) } Real t = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness")); - t *= robust_scm2double ( me->get_property ("thickness"), 1.0); + t *= robust_scm2double (me->get_property ("thickness"), 1.0); int l = Staff_symbol::line_count (me); diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 6ff3f16faa..7d298fd518 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -314,7 +314,7 @@ def compose_ly (code, options): body = FULL_LY # defaults - relative = 0 + relative = 1 staffsize = 16 override = {} override.update (default_ly_options) @@ -357,7 +357,7 @@ def compose_ly (code, options): # 1 = central C if relative < 0: - relative_quotes += ',' * (- relative - 1) + relative_quotes += ',' * (- relative) elif relative > 0: relative_quotes += "'" * relative -- 2.39.5