From 051580bb49085240f446cd1e2a856de2a0649221 Mon Sep 17 00:00:00 2001 From: fred Date: Wed, 27 Mar 2002 00:59:36 +0000 Subject: [PATCH] lilypond-1.3.144 --- CHANGES | 57 ++++++++++- Documentation/regression-test.tely | 6 +- Documentation/user/refman.itely | 146 +++++++++++++++++++++------- flower/include/interval.hh | 5 +- input/regression/mensural.ly | 9 ++ input/regression/note-head-style.ly | 63 ++++++++++++ lily/hairpin.cc | 3 + lily/include/note-head.hh | 1 + lily/note-head.cc | 26 ++++- lily/stem.cc | 38 ++++++-- scm/generic-property.scm | 1 - scm/grob-description.scm | 10 +- scm/grob-property-description.scm | 7 +- scm/interface-description.scm | 9 +- scm/output-lib.scm | 17 ++++ 15 files changed, 333 insertions(+), 65 deletions(-) create mode 100644 input/regression/mensural.ly create mode 100644 input/regression/note-head-style.ly diff --git a/CHANGES b/CHANGES index 242f08f6d7..61b66fd970 100644 --- a/CHANGES +++ b/CHANGES @@ -1,9 +1,58 @@ -1.3.142.hwn2 +1.3.143.jcn3 ============ +* LilyPond-mode: show what's going on (font building) in *view* buffer. + +* Added environment settings to ly2dvi and lilypond-book. + +* Bugfix: make diff links diff into patch-dir, like make release. + +* Bugfix: make diff/release for different configs. + +* Bugfix: convert-ly: don't change item name ChordName to ChordNames. + +* Added flag (LilyPond-kick-xdvi) to LilyPond emacs mode to allow +simultaneous view processes. + +* Small doco fixes. + +* Cosmetic bugfixes to chord names. + +* Fixed order of piano pedal strings (Amelie). + +* Changed embarrassing 'chorda' to corda (Thanks, Amelie). + +* Bugfixes: ly2dvi: empty tagline, don't fail if gettext.py can't be +imported, check for linewidth before indexing, copy midi output. + +1.3.142.rz1 +=========== + +* Added "hacky" drum notation/midi. See input/tricks/drums.ly and + ly/drumpitch.ly. Moved midi-instruments to scm. + +* Added temporary nested staffgroups/choirstaffs support + use Context InnerStaffGroup / InnerChoirStaff. + +1.3.143.uu1 +=========== + +* Bugfix: hairpin that hangs on otherwise empty column should not +collapse into flat line. Inserted sanity check in Interval::center(). + +* Programmable stem-attachments for note heads. + +* Set default empty instrument name for Staff, to avoid weird effects for +named grand staffs. + +* remove various entries from mutopia/ + +1.3.143 +======= + * Glossary bugfixes for lilypond code. -* Bugfix: don't crash if dy or y not set. +* Bugfix: don't crash if dy or y not set in Beam. * Doco updates: moved contents of tricks chapter to input/tricks, inserted lilypond-book tutorial, added polyphony section. @@ -64,7 +113,7 @@ from the font (WARNING: FONT CHANGED). * Cleanups in (de)crescendo code, fixed continued (de)crescendi. -* German chords (Rune Zedler) +* German chords (Rune Zedeler) 1.3.141 ======= @@ -132,6 +181,8 @@ Slur::set_spacing_rods into Spanner::set_spacing_rods 1.3.140 ======= + + 1.3.139.jcn5 ============ diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely index 8125c6cf66..1f9b51238b 100644 --- a/Documentation/regression-test.tely +++ b/Documentation/regression-test.tely @@ -23,7 +23,9 @@ and documenting bugfixes. @lilypondfile[printfilename]{rest-ledger.ly} -@lilypondfile[printfilename]{noteheadstyle.ly} +@lilypondfile[printfilename]{note-head-style.ly} + +@lilypondfile[printfilename]{mensural.ly} @lilypondfile[printfilename]{easy-notation.ly} @@ -158,6 +160,8 @@ and documenting bugfixes. @lilypondfile[printfilename]{lyrics-multi-stanza.ly} +@lilypondfile[printfilename]{lyric-phrasing.ly} + @section Multiple notes diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 8ce5bf8e23..4f3e0a3fab 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -820,9 +820,11 @@ note they contain. For a beam ending rule that only applies to beams with 32nd notes (and no shorter notes), you would use @code{(end * * 1 32)}. -[say something about irregular meters. eg 5/8 = 2+3/8, 3+2/8] +@c not true +@c Automatic beams can not be put on the last note in a score. -Automatic beams can not be put on the last note in a score. +If a score ends while an automatic beam has not been ended and is still +accepting notes, this last beam will not be typeset at all. @cindex automatic beam generation @cindex autobeam @@ -834,15 +836,19 @@ a melody that goes with lyrics. @refbugs -It is not possible to specify beaming for beams with mixed durations, -that differs from the beaming of all separate durations, ie, you'll -have to specify manual beams to get: +It is not possible to specify beaming parameters for beams with mixed +durations, that differ from the beaming parameters of all separate +durations, ie, you'll have to specify manual beams to get: @lilypond[fragment,singleline,relative] \property Voice.autoBeamSettings - \override #'(end * * * *) = #(make-moment 3 8) - \time 12/8; c'8 c c c16 c c c c c [c c c c] c8 c c4 + \override #'(end * * * *) = #(make-moment 3 8) + \time 12/8; c'8 c c c16 c c c c c [c c c c] c8 c c4 @end lilypond +It is not possible to specify beaming parameters that act differently in +different parts of a measure, eg, in irregular meters such as @code{5/8} +that breaks down to @code{2/8 +3/8} or @code{3/8 + 2/8}, automatic beams +won't act according to the broken down parts @code{2/8} and @code{3/8}. @c . {Manual beams} @cindex Automatic beams @@ -1379,13 +1385,6 @@ is an example how to do it: @end lilypond -@refbugs - -When using spacer notes to subdivide note dynamics and @code{linewidth = --1}, starting a hairpin on the first spacer note (the one coinciding -with the real note) exposes an embarassing bug. - - @c . {Repeats} @node Repeats @@ -1695,11 +1694,11 @@ context which is a direct child of the a context of type @cindex Pedals Piano pedal instruction can be expressed using -@code{\sustainDown}, @code{\sustainUp}, @code{\unaChorda}, -@code{\treChorde}, @code{\sostenutoDown} and @code{\sostenutoUp}. +@code{\sustainDown}, @code{\sustainUp}, @code{\unaCorda}, +@code{\treCorde}, @code{\sostenutoDown} and @code{\sostenutoUp}. These identifiers are shorthands for spanner commands of the types -@code{Sustain}, @code{UnaChorda} and @code{Sostenuto}: +@code{Sustain}, @code{UnaCorda} and @code{Sostenuto}: @lilypond[fragment,verbatim] c''4 \spanrequest \start "Sustain" c''4 c''4 \spanrequest \stop "Sustain" @@ -2159,10 +2158,8 @@ scheme = \chords { LilyPond examines chords specified as lists of notes to determine a name to give the chord. LilyPond will not try to identify chord inversions or -added base, which may result in strange chord names when chords are -entered as a list of pitches: - -[base vs. bass ?] +an added bass note, which may result in strange chord names when chords +are entered as a list of pitches: @lilypond[verbatim,center,singleline] scheme = \notes { @@ -2189,9 +2186,33 @@ chordnames. Routines that determine the names to be printed are written in Scheme, and may be customized by the user. The code can be found in -@file{scm/chord-name.scm}. +@file{scm/chord-name.scm}. Here's an example showing the differences in +chord name styles: + +@c too long? +@c maybe just junk verbatim option? +@lilypond[verbatim,singleline] +scheme = \chords { + c1 c:5^3 c:4^3 c:5+ + c:m7+ c:m5-.7 + c:5-.7 c:5+.7 + c:9^7 +} + +\score { + \notes < + \context ChordNames = banter \scheme + \context ChordNames = american { + \property ChordNames.ChordName \override + #'style = #'american \scheme } + \context ChordNames = jazz { + \property ChordNames.ChordName \override + #'style = #'jazz \scheme } + \context Staff \transpose c'' \scheme + > +} +@end lilypond -[3 short examples showing differences between american, banter and jazz] @node Writing parts @section Writing parts @@ -2272,7 +2293,8 @@ used, for the next ones @code{instr} is used. @end lilypond This requires that you add the @code{Instrument_name_engraver} to the -staff context. You can also use markup texts: +staff context. You can also use markup texts to construct more +complicated instrument names: @lilypond[verbatim,singleline] @@ -2289,6 +2311,14 @@ staff context. You can also use markup texts: @end lilypond +@refbugs + +When you put a name on a grand staff or piano staff (By adding an +@code{Instrument_name_engraver} to that context and setting +e.g. @code{\property GrandStaff.instrument}), the width of the brace is +not taken into account. You must add extra spaces to the end of the name +to avoid a collision. + @node Transpose @subsection Transpose @cindex Transpose @@ -2381,11 +2411,9 @@ The syntax for part combining is @end example where the pieces of music @var{musicexpr1} and @var{musicexpr2} will be -combined into one context @var{context}. The names of the music +combined into one context @var{context}. The context names of the music expressions must start with the prefixes @code{one} and @code{two}. -[Name of music expressions? is that context name? ] - The most useful function of the part combiner to combining threads into one voice, as common for wind parts in orchestral scores: @@ -2567,6 +2595,7 @@ grob property. * What to tune?:: * Font selection:: * Text markup:: +* Embedded @TeX{}:: @end menu @node Tuning groups of grobs @@ -2948,6 +2977,42 @@ marking: } @end lilypond +@node Embedded @TeX{} +@subsection Embeded @TeX{} +@cindex embedded tex +@cindex embedded tex + +You can use @TeX{} commands in text scripts, but this should be avoided +because this makes it impossible for LilyPond to compute the exact +length of the string, which may lead to collisions. Also, @TeX{} +commands won't work with direct PostScript output. + +@lilypond[fragment,relative,verbatim] + a''^"3 $\\times$ \\`a deux" +@end lilypond + +@subsection Embedded PostScript +@cindex embedded postscript +@cindex embedded postscript + +You can also use raw PostScript commands embedded in text scripts. This +offers ultimate flexibitily, but you'll have to learn the arcane +PostScript language. Currently, embedded PostScript will @strong{not} +work with direct PostScript output. Note that all dimensions that you +use are in @code{staff-space}s. + +@lilypond[verbatim] +\score { + \notes \relative c'' { + a-#"\\embeddedps{3 4 moveto 5 3 rlineto stroke}" + -#"\\embeddedps{ [ 0 1 ] 0 setdash 3 5 moveto 5 -3 rlineto stroke}" + b-#"\\embeddedps{3 4 moveto 0 0 1 2 8 4 20 3.5 rcurveto stroke}" + s2 + a'1 + } + \paper { linewidth = 70 * \staffspace; } +} +@end lilypond @c . {Page layout} @@ -3175,13 +3240,25 @@ details, see the example file @file{input/test/between-systems.ly} @cindex Sound LilyPond can produce MIDI output. The performance lacks lots of -interesting effects, such as swing, articulation, slurring, tieing, -etc., but it is good enough for proof-hearing the music you enter. - -Dynamics and tempo changes are interpreted. - -[TODO: mention volume control/Instrument Equaliser] - +interesting effects, such as swing, articulation, slurring, etc., but it +is good enough for proof-hearing the music you have entered. Ties, +dynamics and tempo changes are interpreted. + +The MIDI volume is composed of two elements: the current dynamics of the +voice and the type of musical instrument. + +Dynamic marks, crescendi and decrescendi translate into MIDI volume +levels. Dynamic marks translate to a fixed fraction of the available +MIDI volume range, crescendi and decrescendi make the the volume vary +linearly between their two extremities. The fractions be adjusted by +overriding the @code{absolute-volume-alist} defined in +@file{scm/midi.scm}. + +For each type of musical instrument (that MIDI supports), a volume range +can be defined. This gives you basic equaliser control, which can +enhance the quality of the MIDI output remarkably. You can add +instruments and ranges or change the default settings by overriding +the @code{instrument-equaliser-alist} defined in @file{scm/midi.scm}. @refbugs @@ -3364,7 +3441,6 @@ Xdvi} version 22.36 or newer. @item emacs @end itemize - Add one these lines to the top of your .ly file. The first one is for line location only. The second one is more convenient, but requires patching @code{emacsclient}. diff --git a/flower/include/interval.hh b/flower/include/interval.hh index 849a76e8e8..69b14e891f 100644 --- a/flower/include/interval.hh +++ b/flower/include/interval.hh @@ -24,7 +24,10 @@ struct Interval_t : public Drul_array { static T infinity () ; static String T_to_str (T arg); - T center () { return (elem (LEFT) + elem (RIGHT)) / T (2);} + T center () { + assert (!empty_b ()); + return (elem (LEFT) + elem (RIGHT)) / T (2); + } void translate (T t) { elem (LEFT) += t; diff --git a/input/regression/mensural.ly b/input/regression/mensural.ly new file mode 100644 index 0000000000..4ed65a571f --- /dev/null +++ b/input/regression/mensural.ly @@ -0,0 +1,9 @@ +\header { +texidoc = "There is limited support for mensural notation: note head shapes are available. Mensural stems are centered on the note heads, both for up and down stems."; +} + +\score {\notes { \context Voice { +\property Voice.NoteHead \override #'style = #'mensural +\transpose d''' { c4 c2 c8 c16 c16 c1 c\breve c\longa } +\transpose c'' { c4 c2 c8 c16 c16 c1 c\breve c\longa } +}}} diff --git a/input/regression/note-head-style.ly b/input/regression/note-head-style.ly new file mode 100644 index 0000000000..32f660bd08 --- /dev/null +++ b/input/regression/note-head-style.ly @@ -0,0 +1,63 @@ +\header{ +texidoc=" +Note head shapes are settable. The stem endings should be adjusted +per note head. If you want different note head styles on one stem, +you must create a special context called Thread. + +Harmonic notes have a different shape and different +dimensions. Nevertheless, noteheads in both styles can be combined, on +either up or down stems. +"; +} + + + + +\score { \notes \relative c{ + +c''4 c2 c8 c16 c16 c1 c\breve +\property Voice.NoteHead \set #'style = #'diamond +c4 c2 c8 c16 c16 c1 c\breve +\property Voice.NoteHead \set #'style = #'transparent +c4 c2 c8 c16 c16 c1 c\breve +\property Voice.NoteHead \set #'style = #'cross +c4 c2 c8 c16 c16 c1 c\breve +\property Voice.NoteHead \set #'style = #'mensural +c4 c2 c8 c16 c16 c1 c\breve c\longa +\property Voice.NoteHead \set #'style = #'harmonic +c4 c2 c8 c16 c16 c1 c\breve +\property Voice.NoteHead \set #'style = #'baroque +c4 c2 c8 c16 c16 c1 c\breve c\longa + + + \context Voice < + \context Thread = TA + { + \property Thread.NoteHead \set #'style = #'cross + \property Voice.Stem \set #'direction = #1 + c16 + } + \context Thread = TB + { \property Thread.NoteHead \set #'style = #'default a16 } + + \context Thread = TC + { \property Thread.NoteHead \set #'style = #'mensural d16 } + + > + + + \context Voice <\context Thread = TA { + \property Thread.NoteHead \set #'style = #'default + c4 c4 } +\context Thread = TB { + \property Thread.NoteHead \set #'style = #'mensural + c'4 \stemDown c +} > + +} + + \paper { + + +} +} diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 6471957ecf..c3b9fe33f9 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -70,6 +70,9 @@ Hairpin::brew_molecule (SCM smob) make the padding a little smaller, here. */ Interval e =b->extent (common, X_AXIS); + if (e.empty_b ()) + e = Interval (0,0) + b->relative_coordinate (common, X_AXIS); + x_points[d] = e.center () - d * padding /3; // ugh. } else diff --git a/lily/include/note-head.hh b/lily/include/note-head.hh index 99404f4d8e..833a86f6ac 100644 --- a/lily/include/note-head.hh +++ b/lily/include/note-head.hh @@ -24,6 +24,7 @@ public: static Molecule ledger_line (Interval, Grob*) ; DECLARE_SCHEME_CALLBACK (brew_ez_molecule, (SCM )); static bool has_interface (Grob*); + static Real stem_attachment_coordinate (Grob *, Axis a); }; #endif // NOTEHEAD_HH diff --git a/lily/note-head.cc b/lily/note-head.cc index fe74fcbb82..37b75e13a6 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -72,7 +72,11 @@ Note_head::brew_molecule (SCM smob) return SCM_EOL; } - // ugh: use gh_call () + /* + ugh: use gh_call () + + UGH: use grob-property. + */ Molecule out = Font_interface::get_default_font (me)->find_by_name (String ("noteheads-") + ly_scm2string (scm_eval2 (gh_list (ly_symbol2scm ("find-notehead-symbol"), me->get_grob_property ("duration-log"), @@ -131,3 +135,23 @@ Note_head::brew_ez_molecule (SCM smob) return m.smobbed_copy (); } + + +Real +Note_head::stem_attachment_coordinate (Grob *me, Axis a) +{ + SCM v = me->get_grob_property ("stem-attachment-function"); + + if (!gh_procedure_p (v)) + return 0.0; + + SCM st = me->get_grob_property ("style"); + SCM result = gh_apply (v, gh_list (st, SCM_UNDEFINED)); + + if (!gh_pair_p (result)) + return 0.0; + + result = (a == X_AXIS) ? gh_car (result) : gh_cdr (result); + + return gh_number_p (result) ? gh_scm2double (result) : 0.0; +} diff --git a/lily/stem.cc b/lily/stem.cc index 13272bc71b..2b965b1c25 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -503,14 +503,17 @@ TODO: */ - Real slope =0.0; if (Grob *hed = support_head (me)) { - head_wid = hed->extent (hed,X_AXIS).length (); + Real slope =0.0; + + Interval head_height = hed->extent (hed,Y_AXIS); + Real y_attach = Note_head::stem_attachment_coordinate ( hed, Y_AXIS); - slope = gh_scm2double (hed->get_grob_property ("attachment-slope")); + y_attach = head_height.linear_combination (y_attach); + stem_y[Direction (-d)] += d * y_attach; } - stem_y[Direction (-d)] += d * head_wid * slope/ (2*dy); + if (!invisible_b (me)) { @@ -542,14 +545,29 @@ Stem::off_callback (SCM element_smob, SCM) Real r=0; if (Grob * f = first_head (me)) { - Interval head_wid (0, f->extent (f,X_AXIS).length ()); + Interval head_wid = f->extent (f,X_AXIS); + + Real attach = + Note_head::stem_attachment_coordinate(f, X_AXIS); - if (to_boolean (me->get_grob_property ("stem-centered"))) - return gh_double2scm (head_wid.center ()); - - Real rule_thick = gh_scm2double (me->get_grob_property ("thickness")) * me->paper_l ()->get_var ("stafflinethickness"); Direction d = get_direction (me); - r = head_wid[d] - d * rule_thick * 0.5; + + Real real_attach = head_wid.linear_combination (d * attach); + + r = real_attach; + + /* + If not centered: correct for stem thickness. + */ + if (attach) + { + Real rule_thick + = gh_scm2double (me->get_grob_property ("thickness")) + * me->paper_l ()->get_var ("stafflinethickness"); + + + r += - d * rule_thick * 0.5; + } } return gh_double2scm (r); } diff --git a/scm/generic-property.scm b/scm/generic-property.scm index 81b181683d..740f0a641a 100644 --- a/scm/generic-property.scm +++ b/scm/generic-property.scm @@ -39,7 +39,6 @@ (list 'verticalDirection dir? 'direction) (list 'stemLength number? 'length) (list 'flagStyle string? 'flag-style) - (list 'stemCentered boolean? 'stem-centered) (list 'noStemExtend boolean? 'no-stem-extend) (list 'stemShorten number? 'shorten) )) diff --git a/scm/grob-description.scm b/scm/grob-description.scm index 0ad01c0ff7..e2bfae8305 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -178,6 +178,9 @@ (DynamicText . ( (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) (molecule-callback . ,Text_item::brew_molecule) +(X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (self-alignment-X . 0) + (no-spacing-rods . #t) (script-priority . 100) (font-series . bold) @@ -345,7 +348,8 @@ (style . default) (molecule-callback . ,Note_head::brew_molecule) (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (attachment-slope . 0.17) + (stem-attachment-function + . ,note-head-style->attachment-coordinates) (meta . ,(grob-description "NoteHead" rhythmic-head-interface font-interface note-head-interface )) @@ -693,7 +697,7 @@ tuplet-bracket-interface font-interface)) )) - (UnaChordaPedal . ( + (UnaCordaPedal . ( (molecule-callback . ,Text_item::brew_molecule) (font-shape . italic) (no-spacing-rods . #t) @@ -703,7 +707,7 @@ (Y-offset-callbacks . (,Side_position_interface::aligned_side ,Side_position_interface::centered_on_parent)) - (meta . ,(grob-description "UnaChordaPedal" text-interface font-interface)) + (meta . ,(grob-description "UnaCordaPedal" text-interface font-interface)) )) (VoltaBracket . ( diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index b85ec0a97a..223ab00584 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -43,8 +43,10 @@ This procedure is called (using dependency resolution) after line breaking. Retu (grob-property-description 'arithmetic-multiplier number? "see @ref{spacing-spanner-interface}.") (grob-property-description 'attachment pair? "cons of symbols, '(LEFT-TYPE . RIGHT-TYPE), where both types may be alongside-stem, stem, head or loose-end.") -(grob-property-description 'attachment-slope number? "Where does the stem -attach to the notehead?") +(grob-property-description 'stem-attachment-function procedure? "Where +does the stem attach to the notehead? Function takes a symbol argument +being the style. It returns a (X . Y) pair, specifying location in +terms of note head bounding box.") (grob-property-description 'attachment-offset pair? "cons of offsets, '(LEFT-offset . RIGHT-offset). This offset is added to the attachments to prevent ugly slurs. [fixme: we need more documentation here]. @@ -267,7 +269,6 @@ itself. Return value is ignored.") (grob-property-description 'staff-symbol boolean? "the staff symbol grob that we're in.") (grob-property-description 'staffline-clearance number? "don't get closer than this to stafflines.") (grob-property-description 'stem ly-grob? "pointer to Stem object.") -(grob-property-description 'stem-centered boolean? "Center stems on note heads. Useful for mensural notation.") (grob-property-description 'stem-end-position number? "Where does the stem end (the end is opposite to the support-head.") (grob-property-description 'stem-length number? "length of stem.") (grob-property-description 'stem-shorten list? "shorten stems in forced directions given flag multiplicity.") diff --git a/scm/interface-description.scm b/scm/interface-description.scm index ef657ad6a4..ee1b65a218 100644 --- a/scm/interface-description.scm +++ b/scm/interface-description.scm @@ -124,7 +124,6 @@ thickness beamed-lengths beamed-minimum-lengths - stem-centered lengths beam stem-shorten @@ -216,17 +215,13 @@ object." (lily-interface 'note-head-interface "Note head" - '( - style attachment-slope note-character - )) + '( style stem-attachment-function note-character )) (lily-interface 'note-name-interface "Note name" - '( - style - )) + '( style )) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 941eb94ee7..d6d57b3765 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -73,6 +73,23 @@ (string-append (number->string duration) (symbol->string style))))) +(define (note-head-style->attachment-coordinates style) + "Return pair (X . Y), containing multipliers for the note head +bounding box, where to attach the stem. e.g.: X==0 means horizontally +centered, X==1 is at the right, X == -1 is at the left." + + (case style + ((default) '(1.0 . 0.8)) + ((cross) '(1.0 . -1.0)) + ((mensural) '(0.0 . 1.0)) + ((diamond) '(1.0 . 0.8)) + ((transparent) '(1.0 . 1.0)) + ((slash) '(1.0 . 1.0)) + ((harmonic) '(1.0 0.0)) + (else + '(1.0 . 0.0) + ))) + (define (string-encode-integer i) (cond ((= i 0) "o") -- 2.39.5